tuxcmd-modules-0.6.70+ds/0000755000175000017500000000000011300615216014171 5ustar salvisalvituxcmd-modules-0.6.70+ds/gvfs/0000755000175000017500000000000011300613427015140 5ustar salvisalvituxcmd-modules-0.6.70+ds/gvfs/gvfs.c0000644000175000017500000012041511300022650016244 0ustar salvisalvi/* GVFS plugin for Tux Commander * Copyright (C) 2008 Tomas Bzatek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include "vfs_types.h" #define VERSION "0.1.10" #define BUILD_DATE "2009-10-25" #define DEFAULT_BLOCK_SIZE 0x10000 /* 64kB */ #define CONST_DEFAULT_QUERY_INFO_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_NAME "," \ G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," G_FILE_ATTRIBUTE_STANDARD_SIZE "," \ G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET "," G_FILE_ATTRIBUTE_TIME_MODIFIED "," \ G_FILE_ATTRIBUTE_TIME_ACCESS "," G_FILE_ATTRIBUTE_TIME_CHANGED "," \ G_FILE_ATTRIBUTE_UNIX_MODE "," G_FILE_ATTRIBUTE_UNIX_UID "," \ G_FILE_ATTRIBUTE_UNIX_GID struct TVFSGlobs { TVFSLogFunc log_func; GFile *file; GFileEnumerator *enumerator; GCancellable *cancellable; GMainLoop *mount_main_loop; TVFSResult mount_result; int mount_try; gboolean ftp_anonymous; gboolean break_get_dir_size; guint32 block_size; TVFSAskQuestionCallback callback_ask_question; TVFSAskPasswordCallback callback_ask_password; TVFSProgressCallback callback_progress; void *callback_data; }; static TVFSResult g_error_to_TVFSResult (GError *error) { g_print ("g_error_to_TVFSResult: code = %d\n", error->code); switch (error->code) { case G_IO_ERROR_FAILED: case G_IO_ERROR_NOT_FOUND: return cVFS_Failed; break; case G_IO_ERROR_PERMISSION_DENIED: return cVFS_PermissionDenied; break; case G_IO_ERROR_CANCELLED: return cVFS_Cancelled; break; case G_IO_ERROR_NOT_SUPPORTED: case G_IO_ERROR_FILENAME_TOO_LONG: return cVFS_Not_Supported; break; case G_IO_ERROR_NO_SPACE: return cVFS_NoSpaceLeft; break; case G_IO_ERROR_IS_DIRECTORY: case G_IO_ERROR_NOT_REGULAR_FILE: case G_IO_ERROR_NOT_SYMBOLIC_LINK: case G_IO_ERROR_NOT_MOUNTABLE_FILE: case G_IO_ERROR_INVALID_FILENAME: case G_IO_ERROR_TOO_MANY_LINKS: case G_IO_ERROR_INVALID_ARGUMENT: case G_IO_ERROR_NOT_DIRECTORY: case G_IO_ERROR_NOT_MOUNTED: case G_IO_ERROR_ALREADY_MOUNTED: case G_IO_ERROR_WRONG_ETAG: case G_IO_ERROR_TIMED_OUT: case G_IO_ERROR_WOULD_RECURSE: case G_IO_ERROR_HOST_NOT_FOUND: return cVFS_ReadErr; break; case G_IO_ERROR_EXISTS: case G_IO_ERROR_NOT_EMPTY: case G_IO_ERROR_CLOSED: case G_IO_ERROR_PENDING: case G_IO_ERROR_READ_ONLY: case G_IO_ERROR_CANT_CREATE_BACKUP: case G_IO_ERROR_BUSY: case G_IO_ERROR_WOULD_BLOCK: case G_IO_ERROR_WOULD_MERGE: return cVFS_WriteErr; break; case G_IO_ERROR_FAILED_HANDLED: default: return cVFS_Failed; } } static void ask_password_cb (GMountOperation *op, const char *message, const char *default_user, const char *default_domain, GAskPasswordFlags flags, gpointer user_data) { struct TVFSGlobs *globs; char *username; char *password; int anonymous; char *domain; TVFSPasswordSave password_save; int result; globs = (struct TVFSGlobs*) user_data; g_assert (globs != NULL); globs->mount_try++; /* First pass, look if we have a password to supply */ if (globs->mount_try == 1) { if ((flags & G_ASK_PASSWORD_ANONYMOUS_SUPPORTED) && globs->ftp_anonymous) { printf ("(WW) ask_password_cb: mount_try = %d, trying FTP anonymous login...\n", globs->mount_try); g_mount_operation_set_anonymous (op, TRUE); g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED); return; } } /* Ask user for password */ g_print ("(WW) ask_password_cb: mount_try = %d, message = '%s'\n", globs->mount_try, message); /* Handle abort message from certain backends properly */ /* - e.g. SMB backends use this to mask multiple auth callbacks from smbclient */ if (default_user && strcmp (default_user, "ABORT") == 0) { g_print ("(WW) default_user == \"ABORT\", aborting\n"); g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); return; } username = NULL; domain = NULL; password = NULL; anonymous = FALSE; password_save = VFS_PASSWORD_SAVE_NEVER; if (globs->callback_ask_password) { fprintf (stderr, " (II) Spawning callback_ask_password (%p)...\n", globs->callback_ask_password); result = globs->callback_ask_password (message, default_user, default_domain, NULL, flags, &username, &password, &anonymous, &domain, &password_save, globs->callback_data); fprintf (stderr, " (II) Received result = %d\n", result); if (result) { if (flags & G_ASK_PASSWORD_NEED_USERNAME) g_mount_operation_set_username (op, username); if (flags & G_ASK_PASSWORD_NEED_DOMAIN) g_mount_operation_set_domain (op, domain); if (flags & G_ASK_PASSWORD_NEED_PASSWORD) g_mount_operation_set_password (op, password); if (flags & G_ASK_PASSWORD_ANONYMOUS_SUPPORTED) g_mount_operation_set_anonymous (op, anonymous); if (flags & G_ASK_PASSWORD_SAVING_SUPPORTED) g_mount_operation_set_password_save (op, password_save); g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED); } else g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); return; } /* Unhandled, abort */ g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); } static void ask_question_cb (GMountOperation *op, const gchar *message, const gchar *choices[], gpointer user_data) { struct TVFSGlobs *globs; int len; int choice; globs = (struct TVFSGlobs*) user_data; g_assert (globs != NULL); g_print ("(WW) ask_question_cb: message = '%s'\n", message); len = 0; while (choices[len] != NULL) { g_print ("(WW) ask_question_cb: choice[%d] = '%s'\n", len, choices[len]); len++; } choice = -1; if (globs->callback_ask_question) { fprintf (stderr, " (II) Spawning callback_ask_question (%p)...\n", globs->callback_ask_question); /* At this moment, only SFTP uses ask_question and the second button is cancellation */ globs->callback_ask_question (message, choices, &choice, 1, globs->callback_data); fprintf (stderr, " (II) Received choice = %d\n", choice); if (choice >= 0) { g_mount_operation_set_choice (op, choice); g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED); } else { g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); } return; } g_mount_operation_reply (op, G_MOUNT_OPERATION_UNHANDLED); } static void mount_done_cb (GObject *object, GAsyncResult *res, gpointer user_data) { struct TVFSGlobs *globs; gboolean succeeded; GError *error = NULL; globs = (struct TVFSGlobs*) user_data; g_assert (globs != NULL); succeeded = g_file_mount_enclosing_volume_finish (G_FILE (object), res, &error); if (! succeeded) { g_print ("(EE) Error mounting location: %s\n", error->message); globs->mount_result = g_error_to_TVFSResult (error); g_error_free (error); } else { globs->mount_result = cVFS_OK; g_print ("(II) Mount successful.\n"); } g_main_loop_quit (globs->mount_main_loop); } static TVFSResult vfs_handle_mount (struct TVFSGlobs *globs, GFile *file) { GMountOperation *op; g_print ("(II) Mounting location...\n"); op = g_mount_operation_new (); g_signal_connect (op, "ask-password", (GCallback)ask_password_cb, globs); g_signal_connect (op, "ask-question", (GCallback)ask_question_cb, globs); globs->mount_result = cVFS_Failed; globs->mount_try = 0; /* Inspiration taken from Bastien Nocera's http://svn.gnome.org/viewvc/totem-pl-parser/trunk/plparse/totem-disc.c?view=markup */ globs->mount_main_loop = g_main_loop_new (NULL, FALSE); g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE, op, NULL, mount_done_cb, globs); g_main_loop_run (globs->mount_main_loop); g_main_loop_unref (globs->mount_main_loop); globs->mount_main_loop = NULL; g_object_unref (op); return globs->mount_result; } struct TVFSGlobs * VFSNew (TVFSLogFunc log_func) { struct TVFSGlobs * globs; globs = (struct TVFSGlobs *) malloc (sizeof (struct TVFSGlobs)); memset (globs, 0, sizeof (struct TVFSGlobs)); globs->log_func = log_func; globs->log_func ("GVFS plugin: VFSInit"); globs->file = NULL; globs->enumerator = NULL; globs->cancellable = NULL; globs->break_get_dir_size = FALSE; globs->block_size = DEFAULT_BLOCK_SIZE; globs->callback_data = NULL; globs->callback_ask_question = NULL; globs->callback_ask_password = NULL; globs->callback_progress = NULL; return globs; } void VFSSetCallbacks (struct TVFSGlobs *globs, TVFSAskQuestionCallback ask_question_callback, TVFSAskPasswordCallback ask_password_callback, TVFSProgressCallback progress_func, void *data) { globs->callback_ask_question = ask_question_callback; globs->callback_ask_password = ask_password_callback; globs->callback_progress = progress_func; globs->callback_data = data; } void VFSFree (struct TVFSGlobs *globs) { globs->log_func ("GVFS plugin: VFSDestroy"); free (globs); } int VFSVersion () { return cVFSVersion; } struct TVFSInfo * VFSGetInfo () { struct TVFSInfo *module_info = g_malloc0 (sizeof (struct TVFSInfo)); module_info->ID = g_strdup ("gvfs_plugin"); module_info->Name = g_strdup ("GVFS plugin"); module_info->About = g_strdup_printf ("version %s, build date: %s", VERSION, BUILD_DATE); module_info->Copyright = g_strdup ("Copyright (C) 2008-2009 Tomáš Bžatek"); return module_info; } #if 0 char * VFSGetArchiveExts () { return NULL; } #endif char * VFSGetNetworkServices () { GVfs *gvfs; const gchar* const * schemes; char *l = NULL; char *s; gvfs = g_vfs_get_default (); g_print ("(II) GVFS: is_active = %d\n", g_vfs_is_active (gvfs)); schemes = g_vfs_get_supported_uri_schemes (gvfs); for (; *schemes; schemes++) { if (l) { s = g_strdup_printf ("%s;%s", l, *schemes); g_free (l); l = s; } else l = g_strdup (*schemes); } g_print ("(II) GVFS: supported schemes: %s\n", l); return l; } TVFSResult VFSOpenURI (struct TVFSGlobs *globs, char *sURI) { GFile *f, *f2; GFileInfo *info; GError *error; TVFSResult res; globs->file = NULL; globs->ftp_anonymous = FALSE; if (strstr (sURI, "@") == NULL) { /* test for FTP protocol (we only enable anonymous here) */ globs->ftp_anonymous = strcasestr (sURI, "ftp://") == sURI; } g_print ("(II) VFSOpenURI: opening URI '%s'\n", sURI); f = g_file_new_for_commandline_arg (sURI); while (1) { error = NULL; info = g_file_query_info (f, CONST_DEFAULT_QUERY_INFO_ATTRIBUTES, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error); /* Fallback to parent directory if specified path doesn't exist */ if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { f2 = g_file_get_parent (f); if (f2) { g_object_unref (f); f = f2; g_error_free (error); continue; } } /* Mount the target */ if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED)) { g_error_free (error); error = NULL; res = vfs_handle_mount (globs, f); if (res != cVFS_OK) return res; else continue; } /* Any other errors --> report */ if (error) { g_print ("(EE) VFSOpenURI: g_file_query_info() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); g_object_unref (f); return res; } /* everything ok? */ break; } globs->file = f; return cVFS_OK; } TVFSResult VFSClose (struct TVFSGlobs *globs) { g_print ("(II) VFSClose\n"); if (globs->file) g_object_unref (globs->file); globs->file = NULL; return cVFS_OK; } char * VFSGetPath (struct TVFSGlobs *globs) { GFile *root; char *path, *s; if (globs->file) { root = g_file_resolve_relative_path (globs->file, "/"); if (root == NULL) return NULL; path = g_file_get_relative_path (root, globs->file); if (path == NULL) { g_object_unref (root); return NULL; } if (! g_path_is_absolute (path)) s = g_strdup_printf ("/%s", path); else s = g_strdup (path); g_print ("(II) VFSGetPath: '%s'\n", s); g_free (path); g_object_unref (root); return s; } else return NULL; } char * VFSGetPathURI (struct TVFSGlobs *globs) { if (globs->file) return g_file_get_uri (globs->file); else return NULL; } guint64 VFSGetFileSystemFree (struct TVFSGlobs *globs, char *APath) { GFileInfo *info; GError *error; guint64 res; if (globs->file == NULL) return 0; error = NULL; info = g_file_query_filesystem_info (globs->file, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, NULL, &error); if (error) { g_print ("(EE) VFSGetFileSystemFree: %s\n", error->message); g_error_free (error); return 0; } res = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE); g_object_unref (info); return res; } guint64 VFSGetFileSystemSize (struct TVFSGlobs *globs, char *APath) { GFileInfo *info; GError *error; guint64 res; if (globs->file == NULL) return 0; error = NULL; info = g_file_query_filesystem_info (globs->file, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE, NULL, &error); if (error) { g_print ("(EE) VFSGetFileSystemSize: %s\n", error->message); g_error_free (error); return 0; } res = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE); g_object_unref (info); return res; } /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ TVFSResult VFSChangeDir (struct TVFSGlobs *globs, char *NewPath) { GFile *f; GFileEnumerator *en; GError *error, *error_shortcut; TVFSResult res; GFileInfo *info; gchar *target_uri; if (globs->file == NULL) { g_print ("(EE) VFSChangeDir: globs->file == NULL !\n"); return cVFS_Failed; } g_print ("(II) VFSChangeDir: changing dir to '%s'\n", NewPath); f = g_file_resolve_relative_path (globs->file, NewPath); if (f == NULL) { g_print ("(EE) VFSChangeDir: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } res = cVFS_OK; while (1) { error = NULL; en = g_file_enumerate_children (f, CONST_DEFAULT_QUERY_INFO_ATTRIBUTES, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error); /* if the target is shortcut, change the URI */ if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY)) { error_shortcut = NULL; info = g_file_query_info (f, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error_shortcut); if (info) { target_uri = g_strdup (g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI)); g_object_unref (info); if (target_uri) { g_print ("(WW) VFSChangeDir: following shortcut, changing URI to '%s'\n", target_uri); g_object_unref (f); f = g_file_new_for_uri (target_uri); g_free (target_uri); g_error_free (error); continue; } } if (error_shortcut) g_error_free (error_shortcut); } /* Mount the target */ if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED)) { g_error_free (error); res = vfs_handle_mount (globs, f); if (res != cVFS_OK) { g_object_unref (f); return res; } else continue; } /* Any other errors --> report */ if (error) { g_print ("(EE) VFSChangeDir: g_file_enumerate_children() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); g_object_unref (f); return res; } /* everything ok? */ break; } globs->enumerator = en; g_object_unref (globs->file); globs->file = f; return res; } /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ static void g_file_info_to_TVFSItem (GFileInfo *info, struct TVFSItem *Item) { g_assert (info != NULL); g_assert (Item != NULL); Item->FName = g_strdup (g_file_info_get_name (info)); Item->FDisplayName = g_strdup (g_file_info_get_display_name (info)); Item->sLinkTo = g_file_info_get_symlink_target (info) == NULL ? NULL : g_strdup (g_file_info_get_symlink_target (info)); Item->iSize = g_file_info_get_size (info); Item->iPackedSize = -1; Item->iMode = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE); Item->m_time = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED); Item->a_time = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS); Item->c_time = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_CHANGED); Item->iUID = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_UID); Item->iGID = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_GID); // g_print ("(II) g_file_info_to_TVFSItem: type = %d\n", g_file_info_get_file_type (info)); // g_print ("(II) g_file_info_to_TVFSItem: UNIX_MODE = %d\n", Item->iMode); if (g_file_info_get_is_symlink (info)) { Item->ItemType = vSymlink; } else { switch (g_file_info_get_file_type (info)) { case G_FILE_TYPE_REGULAR: Item->ItemType = vRegular; break; case G_FILE_TYPE_DIRECTORY: case G_FILE_TYPE_SHORTCUT: /* Used in network:/// */ case G_FILE_TYPE_MOUNTABLE: Item->ItemType = vDirectory; break; case G_FILE_TYPE_SYMBOLIC_LINK: Item->ItemType = vSymlink; break; case G_FILE_TYPE_SPECIAL: /* socket, fifo, blockdev, chardev */ Item->ItemType = vBlockdev; break; case G_FILE_TYPE_UNKNOWN: default: Item->ItemType = vRegular; } } /* fallback to default file mode if read fails */ if (Item->iMode == 0) { if (Item->ItemType == vDirectory) Item->iMode = S_IFDIR + S_IRWXU + S_IRGRP + S_IXGRP + S_IROTH + S_IXOTH; else Item->iMode = S_IRUSR + S_IWUSR + S_IRGRP + S_IROTH; } } TVFSResult VFSListNext (struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) { GError *error; GFileInfo *info; TVFSResult res; if (globs->file == NULL) { g_print ("(EE) VFSListNext: globs->file == NULL !\n"); return cVFS_Failed; } if (globs->enumerator == NULL) { g_print ("(EE) VFSListNext: globs->enumerator == NULL !\n"); return cVFS_Failed; } error = NULL; info = g_file_enumerator_next_file (globs->enumerator, NULL, &error); if (error) { g_print ("(EE) VFSListNext: g_file_enumerator_next_file() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); return res; } if (! error && ! info) return cVFS_No_More_Files; g_file_info_to_TVFSItem (info, Item); g_object_unref (info); return cVFS_OK; } TVFSResult VFSListFirst (struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) { return VFSListNext (globs, sDir, Item); } TVFSResult VFSListClose (struct TVFSGlobs *globs) { GError *error; TVFSResult res; if (globs->file == NULL) { g_print ("(EE) VFSListClose: globs->file == NULL !\n"); return cVFS_Failed; } if (globs->enumerator == NULL) { g_print ("(EE) VFSListClose: globs->enumerator == NULL !\n"); return cVFS_Failed; } g_print ("(II) VFSListClose\n"); error = NULL; g_file_enumerator_close (globs->enumerator, NULL, &error); g_object_unref (globs->enumerator); globs->enumerator = NULL; if (error) { g_print ("(EE) VFSListClose: g_file_enumerator_close() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); return res; } return cVFS_OK; } /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ long VFSFileExists (struct TVFSGlobs *globs, const char *FileName, const long Use_lstat) { GFile *f; GError *error; GFileInfo *info; if (globs->file == NULL) { g_print ("(EE) VFSFileExists: globs->file == NULL !\n"); return cVFS_Failed; } f = g_file_resolve_relative_path (globs->file, FileName); if (f == NULL) { g_print ("(EE) VFSMkDir: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } error = NULL; info = g_file_query_info (f, G_FILE_ATTRIBUTE_STANDARD_NAME, Use_lstat ? G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS : G_FILE_QUERY_INFO_NONE, NULL, &error); g_object_unref (f); if (error) { // g_print ("(EE) VFSFileExists: g_file_query_info() error: %s\n", error->message); g_error_free (error); return FALSE; } g_object_unref (info); return TRUE; } TVFSResult VFSFileInfo (struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item) { GFile *f; GError *error; GFileInfo *info; TVFSResult res; if (globs->file == NULL) { g_print ("(EE) VFSFileInfo: globs->file == NULL !\n"); return cVFS_Failed; } f = g_file_resolve_relative_path (globs->file, AFileName); if (f == NULL) { g_print ("(EE) VFSMkDir: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } error = NULL; info = g_file_query_info (f, CONST_DEFAULT_QUERY_INFO_ATTRIBUTES, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error); g_object_unref (f); if (error) { g_print ("(EE) VFSFileInfo: g_file_query_info() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); return res; } g_file_info_to_TVFSItem (info, Item); g_object_unref (info); return cVFS_OK; } TVFSResult VFSMkDir (struct TVFSGlobs *globs, const char *sDirName) { GFile *f; GError *error; TVFSResult res; if (globs->file == NULL) { g_print ("(EE) VFSMkDir: globs->file == NULL !\n"); return cVFS_Failed; } f = g_file_resolve_relative_path (globs->file, sDirName); if (f == NULL) { g_print ("(EE) VFSMkDir: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } error = NULL; g_file_make_directory (f, NULL, &error); g_object_unref (f); if (error) { g_print ("(EE) VFSMkDir: g_file_make_directory() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); return res; } return cVFS_OK; } TVFSResult VFSRemove (struct TVFSGlobs *globs, const char *APath) { GFile *f; GError *error; TVFSResult res; if (globs->file == NULL) { g_print ("(EE) VFSRemove: globs->file == NULL !\n"); return cVFS_Failed; } f = g_file_resolve_relative_path (globs->file, APath); if (f == NULL) { g_print ("(EE) VFSRemove: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } error = NULL; g_file_delete (f, NULL, &error); g_object_unref (f); if (error) { g_print ("(EE) VFSRemove: g_file_delete() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); return res; } return cVFS_OK; } TVFSResult VFSRename (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName) { GFile *src, *dst; GError *error; TVFSResult res; if (globs->file == NULL) { g_print ("(EE) VFSRename: globs->file == NULL !\n"); return cVFS_Failed; } src = g_file_resolve_relative_path (globs->file, sSrcName); if (src == NULL) { g_print ("(EE) VFSRename: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } g_print ("VFSRename: '%s' --> '%s'\n", sSrcName, sDstName); error = NULL; g_file_set_display_name (src, sDstName, NULL, &error); if (error) { g_print ("(WW) VFSRename: g_file_set_display_name() failed (\"%s\"), using fallback g_file_move()\n", error->message); g_error_free (error); dst = g_file_resolve_relative_path (src, sDstName); if (dst == NULL) { g_print ("(EE) VFSRename: g_file_resolve_relative_path() failed.\n"); g_object_unref (src); return cVFS_Failed; } error = NULL; g_file_move (src, dst, G_FILE_COPY_NO_FALLBACK_FOR_MOVE, NULL, NULL, NULL, &error); if (error) { g_print ("(EE) VFSRename: g_file_move() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); g_object_unref (src); g_object_unref (dst); return res; } g_object_unref (dst); } g_object_unref (src); return cVFS_OK; } TVFSResult VFSMakeSymLink (struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo) { GFile *f; GError *error; TVFSResult res; if (globs->file == NULL) { g_print ("(EE) VFSMakeSymLink: globs->file == NULL !\n"); return cVFS_Failed; } f = g_file_resolve_relative_path (globs->file, NewFileName); if (f == NULL) { g_print ("(EE) VFSMakeSymLink: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } error = NULL; g_file_make_symbolic_link (f, PointTo, NULL, &error); g_object_unref (f); if (error) { g_print ("(EE) VFSMakeSymLink: g_file_make_symbolic_link() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); return res; } return cVFS_OK; } TVFSResult VFSChmod (struct TVFSGlobs *globs, const char *FileName, const uint Mode) { GFile *f; GError *error; TVFSResult res; if (globs->file == NULL) { g_print ("(EE) VFSChmod: globs->file == NULL !\n"); return cVFS_Failed; } f = g_file_resolve_relative_path (globs->file, FileName); if (f == NULL) { g_print ("(EE) VFSChmod: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } // g_print ("(II) VFSChmod (%s, %d): Going to set permissions on '%s'\n", FileName, Mode, g_file_get_uri (f)); error = NULL; g_file_set_attribute_uint32 (f, G_FILE_ATTRIBUTE_UNIX_MODE, Mode, G_FILE_QUERY_INFO_NONE, NULL, &error); g_object_unref (f); if (error) { g_print ("(EE) VFSChmod: g_file_set_attribute_uint32() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); return res; } return cVFS_OK; } TVFSResult VFSChown (struct TVFSGlobs *globs, const char *FileName, const uint UID, const uint GID) { GFile *f; GError *error; TVFSResult res; if (globs->file == NULL) { g_print ("(EE) VFSChown: globs->file == NULL !\n"); return cVFS_Failed; } f = g_file_resolve_relative_path (globs->file, FileName); if (f == NULL) { g_print ("(EE) VFSChown: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } error = NULL; g_file_set_attribute_uint32 (f, G_FILE_ATTRIBUTE_UNIX_UID, UID, G_FILE_QUERY_INFO_NONE, NULL, &error); if (error) { g_print ("(EE) VFSChown: g_file_set_attribute_uint32() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); g_object_unref (f); return res; } error = NULL; g_file_set_attribute_uint32 (f, G_FILE_ATTRIBUTE_UNIX_GID, GID, G_FILE_QUERY_INFO_NONE, NULL, &error); if (error) { g_print ("(EE) VFSChown: g_file_set_attribute_uint32() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); g_object_unref (f); return res; } g_object_unref (f); return cVFS_OK; } TVFSResult VFSChangeTimes (struct TVFSGlobs *globs, char *APath, long mtime, long atime) { GFile *f; GError *error; TVFSResult res; if (globs->file == NULL) { g_print ("(EE) VFSChangeTimes: globs->file == NULL !\n"); return cVFS_Failed; } f = g_file_resolve_relative_path (globs->file, APath); if (f == NULL) { g_print ("(EE) VFSChangeTimes: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } error = NULL; g_file_set_attribute_uint64 (f, G_FILE_ATTRIBUTE_TIME_MODIFIED, mtime, G_FILE_QUERY_INFO_NONE, NULL, &error); if (error) { g_print ("(EE) VFSChangeTimes: g_file_set_attribute_uint64() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); g_object_unref (f); return res; } error = NULL; g_file_set_attribute_uint64 (f, G_FILE_ATTRIBUTE_TIME_ACCESS, atime, G_FILE_QUERY_INFO_NONE, NULL, &error); if (error) { g_print ("(EE) VFSChangeTimes: g_file_set_attribute_uint64() error: %s\n", error->message); g_error_free (error); /* Silently drop the error, atime is not commonly supported on most systems */ } g_object_unref (f); return cVFS_OK; } /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ static void VFSGetDirSize_recurse (struct TVFSGlobs *globs, GFile *file, guint64 *size) { GFile *f; GFileEnumerator *en; GError *error; GFileInfo *info; if (globs->break_get_dir_size) return; error = NULL; en = g_file_enumerate_children (file, G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error); if (error) { g_print ("(EE) VFSGetDirSize_recurse: g_file_enumerate_children() error: %s\n", error->message); g_error_free (error); return; } error = NULL; while ((info = g_file_enumerator_next_file (en, NULL, &error))) { if (globs->break_get_dir_size) break; if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { f = g_file_resolve_relative_path (file, g_file_info_get_name (info)); if (f == NULL) { g_print ("(EE) VFSGetDirSize_recurse: g_file_resolve_relative_path() failed.\n"); return; } VFSGetDirSize_recurse (globs, f, size); g_object_unref (f); } else *size += g_file_info_get_size (info); g_object_unref (info); } if (error) { g_print ("(EE) VFSGetDirSize_recurse: g_file_enumerator_next_file() error: %s\n", error->message); g_error_free (error); } g_file_enumerator_close (en, NULL, &error); g_object_unref (en); if (error) { g_print ("(EE) VFSGetDirSize_recurse: g_file_enumerator_close() error: %s\n", error->message); g_error_free (error); } } guint64 VFSGetDirSize (struct TVFSGlobs *globs, char *APath) { GFile *f; guint64 size; if (globs == NULL) return 0; if (globs->file == NULL) { g_print ("(EE) VFSGetDirSize: globs->file == NULL !\n"); return 0; } f = g_file_resolve_relative_path (globs->file, APath); if (f == NULL) { g_print ("(EE) VFSGetDirSize: g_file_resolve_relative_path() failed.\n"); return 0; } size = 0; globs->break_get_dir_size = FALSE; VFSGetDirSize_recurse (globs, f, &size); globs->break_get_dir_size = FALSE; g_object_unref (f); return size; } void VFSBreakGetDirSize (struct TVFSGlobs *globs) { g_print ("(WW) VFSBreakGetDirSize: ################################### calling Break\n"); if (globs) globs->break_get_dir_size = TRUE; } /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ TVFSFileDes VFSOpenFile (struct TVFSGlobs *globs, const char *APath, int Mode, int *Error) { printf("(WW) VFSOpenFile: Not supported in GVFS plugin.\n"); return NULL; } TVFSResult VFSCloseFile (struct TVFSGlobs *globs, TVFSFileDes FileDescriptor) { printf("(WW) VFSCloseFile: Not supported in GVFS plugin.\n"); return cVFS_Not_Supported; } guint64 VFSFileSeek (struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, guint64 AbsoluteOffset, int *Error) { printf("(WW) VFSFileSeek: Not supported in GVFS plugin.\n"); return -1; } int VFSReadFile (struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, gpointer Buffer, int ABlockSize, int *Error) { printf("(WW) VFSReadFile: Not supported in GVFS plugin.\n"); return cVFS_Not_Supported; } int VFSWriteFile (struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, gpointer Buffer, int BytesCount, int *Error) { printf("(WW) VFSWriteFile: Not supported in GVFS plugin.\n"); return cVFS_Not_Supported; } void VFSSetBlockSize (struct TVFSGlobs *globs, int Value) { if (globs) globs->block_size = Value; } gboolean VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2) { GFile *file1, *file2; GFileInfo *info1, *info2; GError *error; gboolean res; if (globs->file == NULL) { g_print ("(EE) VFSIsOnSameFS: globs->file == NULL !\n"); return FALSE; } file1 = g_file_resolve_relative_path (globs->file, Path1); file2 = g_file_resolve_relative_path (globs->file, Path2); if (file1 == NULL) { g_print ("(EE) VFSIsOnSameFS: g_file_resolve_relative_path() failed.\n"); return FALSE; } if (file2 == NULL) { g_print ("(EE) VFSIsOnSameFS: g_file_resolve_relative_path() failed.\n"); return FALSE; } error = NULL; info1 = g_file_query_info (file1, G_FILE_ATTRIBUTE_ID_FILESYSTEM, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error); if (error) { g_print ("(EE) VFSIsOnSameFS: g_file_query_info() error: %s\n", error->message); g_error_free (error); g_object_unref (file1); g_object_unref (file2); return FALSE; } info2 = g_file_query_info (file2, G_FILE_ATTRIBUTE_ID_FILESYSTEM, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error); if (error) { g_print ("(EE) VFSIsOnSameFS: g_file_query_info() error: %s\n", error->message); g_error_free (error); g_object_unref (info1); g_object_unref (file1); g_object_unref (file2); return FALSE; } g_print ("(II) VFSIsOnSameFS: '%s' vs. '%s'\n", g_file_info_get_attribute_string (info1, G_FILE_ATTRIBUTE_ID_FILESYSTEM), g_file_info_get_attribute_string (info2, G_FILE_ATTRIBUTE_ID_FILESYSTEM)); res = strcmp (g_file_info_get_attribute_string (info1, G_FILE_ATTRIBUTE_ID_FILESYSTEM), g_file_info_get_attribute_string (info2, G_FILE_ATTRIBUTE_ID_FILESYSTEM)) == 0; g_object_unref (file1); g_object_unref (file2); g_object_unref (info1); g_object_unref (info2); return res; } gboolean VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2) { GFile *file1, *file2; gboolean res; if (globs->file == NULL) { g_print ("(EE) VFSTwoSameFiles: globs->file == NULL !\n"); return FALSE; } file1 = g_file_resolve_relative_path (globs->file, Path1); file2 = g_file_resolve_relative_path (globs->file, Path2); if (file1 == NULL) { g_print ("(EE) VFSTwoSameFiles: g_file_resolve_relative_path() failed.\n"); return FALSE; } if (file2 == NULL) { g_print ("(EE) VFSTwoSameFiles: g_file_resolve_relative_path() failed.\n"); return FALSE; } /* FIXME: we should do some I/O test, we're esentially comparing strings at the moment */ res = g_file_equal (file1, file2); g_object_unref (file1); g_object_unref (file2); return res; } /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ static void vfs_copy_progress_callback (goffset current_num_bytes, goffset total_num_bytes, gpointer user_data) { struct TVFSGlobs *globs; // g_print ("(II) vfs_copy_progress_callback spawned: current_num_bytes = %lu, total_num_bytes = %lu\n", current_num_bytes, total_num_bytes); if (! user_data) return; globs = (struct TVFSGlobs *)user_data; if (globs->callback_progress) { if (! globs->callback_progress (current_num_bytes, total_num_bytes, globs->callback_data)) g_cancellable_cancel (globs->cancellable); } } #define TUXCMD_DEFAULT_COPY_FLAGS G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA TVFSResult VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append) { GFile *src, *dst; GError *error; TVFSResult res; if (globs->file == NULL) { g_print ("(EE) VFSCopyToLocal: globs->file == NULL !\n"); return cVFS_Failed; } g_print ("(II) VFSCopyToLocal: '%s' --> '%s'\n", sSrcName, sDstName); src = g_file_resolve_relative_path (globs->file, sSrcName); if (src == NULL) { g_print ("(EE) VFSCopyToLocal: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } dst = g_file_new_for_path (sDstName); if (dst == NULL) { g_print ("(EE) VFSCopyToLocal: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } globs->cancellable = g_cancellable_new (); res = cVFS_OK; error = NULL; g_file_copy (src, dst, TUXCMD_DEFAULT_COPY_FLAGS, globs->cancellable, vfs_copy_progress_callback, globs, &error); if (error) { g_print ("(EE) VFSCopyToLocal: g_file_copy() error: %s\n", error->message); // res = g_error_to_TVFSResult (error); if (error->code == G_IO_ERROR_CANCELLED) res = cVFS_Cancelled; else res = cVFS_ReadErr; g_error_free (error); } g_object_unref (globs->cancellable); g_object_unref (src); g_object_unref (dst); return res; } TVFSResult VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append) { GFile *src, *dst; GError *error; TVFSResult res; if (globs->file == NULL) { g_print ("(EE) VFSCopyFromLocal: globs->file == NULL !\n"); return cVFS_Failed; } g_print ("(II) VFSCopyFromLocal: '%s' --> '%s'\n", sSrcName, sDstName); src = g_file_new_for_path (sSrcName); if (src == NULL) { g_print ("(EE) VFSCopyFromLocal: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } dst = g_file_resolve_relative_path (globs->file, sDstName); if (dst == NULL) { g_print ("(EE) VFSCopyFromLocal: g_file_resolve_relative_path() failed.\n"); return cVFS_Failed; } globs->cancellable = g_cancellable_new (); res = cVFS_OK; error = NULL; /* FIXME: Appending not supported */ g_file_copy (src, dst, TUXCMD_DEFAULT_COPY_FLAGS, globs->cancellable, vfs_copy_progress_callback, globs, &error); if (error) { g_print ("(EE) VFSCopyFromLocal: g_file_copy() error: %s\n", error->message); // res = g_error_to_TVFSResult (error); if (error->code == G_IO_ERROR_CANCELLED) res = cVFS_Cancelled; else res = cVFS_WriteErr; g_error_free (error); } g_object_unref (globs->cancellable); g_object_unref (src); g_object_unref (dst); return res; } /********** * TODO: * NOT NEEDED - block size settings for GIO subsystem * NOT NEEDED - variable block size for different protocols? * - support for appending in VFSCopyFromLocal * DONE- authentication improvements (needs new VFS API) * ***/ tuxcmd-modules-0.6.70+ds/gvfs/vfs_types.h0000777000175000017500000000000011300603570023224 2../common/vfs_types.hustar salvisalvituxcmd-modules-0.6.70+ds/gvfs/COPYING0000644000175000017500000004310311300022650016164 0ustar salvisalvi GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. tuxcmd-modules-0.6.70+ds/gvfs/Makefile0000644000175000017500000000202011300613427016572 0ustar salvisalvi# path definitions DESTDIR = /usr INSTALL=install -c INSTALL_DATA = ${INSTALL} -m 644 # compiler options CC = gcc CFLAGS =-I. -I/usr/include \ -Wall -fPIC -O2 -g \ -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE LIB_SUFFIX=`if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi` # VFS_COMMON_OBJECTS=strutils.o treepathutils.o treepath_vfs.o vfsutils.o VFS_COMMON_OBJECTS= VFS_OBJECTS=gvfs.o .SUFFIXES: .c .c.o: $(CC) $(CFLAGS) `pkg-config glib-2.0 gio-2.0 --cflags` -c $< all shared static: libgvfs_plugin.so libgvfs_plugin.so: $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS) $(CC) -shared -o libgvfs_plugin.so $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS) $(CFLAGS) `pkg-config glib-2.0 gio-2.0 --libs` strutils.o: strutils.c strutils.h treepathutils.o: treepathutils.c treepathutils.h vfsutils.o: vfsutils.c vfsutils.h treepath_vfs.o: treepath_vfs.c treepath_vfs.h install:: $(INSTALL) ./libgvfs_plugin.so $(DESTDIR)/lib$(LIB_SUFFIX)/tuxcmd/ clean: rm -f *.o *.d *.gch libgvfs_plugin.so tuxcmd-modules-0.6.70+ds/gvfs/README0000644000175000017500000000243211300022650016011 0ustar salvisalviGVFS plugin for Tux Commander Version: 0.1.10 Release date: 2009-Oct-25 Copyright (C) 2008-2009 Tomas Bzatek http://tuxcmd.sourceforge.net Requirements: - glib2 library at least version 2.16.0 - gvfs daemon and backends available in the system (check your distribution for gvfs packages) This is the GVFS module for Tux Commander file manager. It's built on top of the GVFS daemon, which is an integral part of Gnome Desktop since version 2.22. It provides access to many type of resources such as network shares (FTP, SSH/SFTP, SMB, WebDAV), bluetooth devices (ObexFTP), cameras and portable players (gphoto2) and others. Both plugin and the gvfs library are pretty stable for production use at their current versions. Feature highlights: * read/write access to network resources (FTP, SSH/SFTP, SMB, WebDAV) To be implemented: * support for appending * authentication improvements (needs new VFS API) The current VFS implementation in Tux Commander lacks some extended features for both archiving and remote filesystems. This is one of the main goals for the 0.6.x series. For successful compilation you will need working gcc compiler and glib2 library installed with development files. Compilation has been tested with gcc compiler v4.4.2 tuxcmd-modules-0.6.70+ds/zip/0000755000175000017500000000000011300613427014775 5ustar salvisalvituxcmd-modules-0.6.70+ds/zip/Makefile.ziparch0000644000175000017500000001203711300022650020067 0ustar salvisalvi# Makefile for ZipArchive library # Copyright (C) 2000 - 2007 Artpol Software - Tadeusz Dracz # For conditions of distribution and use, see copyright notice in License.txt # To install to /usr/lib and /usr/include, type: # make install # to install to a different directory change prefix #Define this variable to use the bzip2 library provided with the ZipArchive Library #otherwise, the system's bzip2 library will be used #INTERNAL_BZIP2 = 1 CC=g++ CCC=cc #CCC=gcc CFLAGS = -D ZIP_ARCHIVE_LNX -fPIC -g -O2 #CFLAGS = ifdef INTERNAL_BZIP2 CFLAGS += -D ZIP_ARCHIVE_BZIP2_INTERNAL endif ZIPARCHLIB = libziparch.a ZIPPIELOCATION = ../Zippie/ ZLIBLOCATION = zlib/ ifdef INTERNAL_BZIP2 BZIP2LOCATION = bzip2/ endif INCLUDES = -I. -Izlib ifdef INTERNAL_BZIP2 INCLUDES += -Ibzip2 endif prefix = /usr #prefix = libdir = ${prefix}/lib includedir = ${prefix}/include zipardir = $(includedir)/ziparchive zlibdir = $(zipardir)/zlib ifdef INTERNAL_BZIP2 bzip2dir = $(zipardir)/bzip2 endif AR=ar rc RANLIB=ranlib .SUFFIXES: .c .cpp .c.o: $(CCC) $(CFLAGS) $(INCLUDES) -c -o $*.o $< .cpp.o: $(CC) $(CFLAGS) $(INCLUDES) -c $< OBJS = $(ZLIBLOCATION)adler32.o $(ZLIBLOCATION)compress.o $(ZLIBLOCATION)crc32.o $(ZLIBLOCATION)uncompr.o $(ZLIBLOCATION)deflate.o $(ZLIBLOCATION)trees.o \ $(ZLIBLOCATION)zutil.o $(ZLIBLOCATION)inflate.o $(ZLIBLOCATION)infback.o $(ZLIBLOCATION)inftrees.o $(ZLIBLOCATION)inffast.o\ ZipArchive.o ZipAutoBuffer.o ZipCentralDir.o \ ZipCompressor.o BaseLibCompressor.o Bzip2Compressor.o DeflateCompressor.o ZipCompatibility.o ZipException.o ZipFile_stl.o ZipFileHeader.o \ ZipMemFile.o ZipPlatformComm.o \ ZipStorage.o ZipString.o ZipExtraData.o ZipExtraField.o \ DirEnumerator.o FileFilter.o Wildcard.o \ ZipCryptograph.o ZipCrc32Cryptograph.o \ Aes.o Hmac.o RandomPool.o ZipAesCryptograph.o Sha1.o ifdef INTERNAL_BZIP2 OBJS += $(BZIP2LOCATION)bzlib.o $(BZIP2LOCATION)blocksort.o $(BZIP2LOCATION)bzcompress.o $(BZIP2LOCATION)crctable.o\ $(BZIP2LOCATION)decompress.o $(BZIP2LOCATION)huffman.o $(BZIP2LOCATION)randtable.o endif OBJP = ZipPathComponent_lnx.o ZipPlatform_lnx.o #OBJP = ZipPathComponent_win.o ZipPlatform_win.o $(ZIPARCHLIB): $(OBJS) $(OBJP) $(AR) $@ $(OBJS) $(OBJP) -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 adler32.o: zlib.h zconf.h compress.o: zlib.h zconf.h crc32.o: crc32.h zlib.h zconf.h deflate.o: deflate.h zutil.h zlib.h zconf.h inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inftrees.o: zutil.h zlib.h zconf.h inftrees.h trees.o: deflate.h zutil.h zlib.h zconf.h trees.h uncompr.o: zlib.h zconf.h zutil.o: zutil.h zlib.h zconf.h ifdef INTERNAL_BZIP2 bzlib.o: bzlib.h bzlib_private.h blocksort.o: bzlib_private.h bzcompress.o: bzlib_private.h crctable.o: bzlib_private.h decompress.o: bzlib_private.h huffman.o: bzlib_private.h randtable.o: bzlib_private.h endif ZipArchive.o: ZipArchive.h ZipAutoBuffer.o: ZipAutoBuffer.h ZipCentralDir.o: ZipCentralDir.h ZipCompressor.o: ZipCompressor.h BaseLibCompressor.o: BaseLibCompressor.h Bzip2Compressor.o: Bzip2Compressor.h DeflateCompressor.o: DeflateCompressor.h ZipCompatibility.o: ZipCompatibility.h ZipException.o: ZipException.h ZipFile_stl.o: ZipFile.h ZipFileHeader.o: ZipFileHeader.h ZipMemFile.o: ZipMemFile.h ZipStorage.o: ZipStorage.h ZipString.o: ZipString.h ZipExtraData.o: ZipExtraData.h ZipExtraField.o: ZipExtraField.h DirEnumerator.o: DirEnumerator.cpp FileFilter.o: FileFilter.cpp Wildcard.o: Wildcard.cpp ZipCryptograph.o: ZipCryptograph.h ZipCrc32Cryptograph.o: ZipCrc32Cryptograph.h Aes.o: Aes.h Hmac.o: Hmac.h RandomPool.o: RandomPool.h ZipAesCryptograph.o: ZipAesCryptograph.h Sha1.o: Sha1.h ZipPathComponent_lnx.o: ZipPathComponent.h #ZipPathComponent_win.o: ZipPathComponent.h ZipPlatform_lnx.o: ZipPlatform.h #ZipPlatform_win.o: ZipPlatform.h LIBS = -lstdc++ -lziparch ifndef INTERNAL_BZIP2 LIBS += -lbz2 endif clean: -rm -f *.o *~ $(ZIPARCHLIB) $(ZLIBLOCATION)*.o $(ZLIBLOCATION)*~ $(BZIP2LOCATION)*.o $(BZIP2LOCATION)*~ zippie: $(CC) -I$(zipardir) $(CFLAGS) -o zippie $(ZIPPIELOCATION)zippie.cpp $(ZIPPIELOCATION)CmdLine.cpp $(LIBS) #$(CC) -I$(zipardir) -L$(libdir) $(CFLAGS) -o zippie $(ZIPPIELOCATION)zippie.cpp $(ZIPPIELOCATION)CmdLine.cpp $(LIBS) cleanzippie: -rm -f zippie #-rm -f zippie.exe install: -@if [ ! -d $(includedir) ]; then mkdir $(includedir); fi -@if [ ! -d $(libdir) ]; then mkdir $(libdir); fi -@if [ ! -d $(zipardir) ]; then mkdir $(zipardir); fi -@if [ ! -d $(zlibdir) ]; then mkdir $(zlibdir); fi cp libziparch.a $(libdir) chmod 755 $(libdir)/$(ZIPARCHLIB) cp *.h $(zipardir) chmod 644 $(zipardir)/*h cp $(ZLIBLOCATION)*.h $(zlibdir) chmod 644 $(zlibdir)/*h ifdef INTERNAL_BZIP2 -@if [ ! -d $(bzip2dir) ]; then mkdir $(bzip2dir); fi cp $(BZIP2LOCATION)*.h $(bzip2dir) chmod 644 $(bzip2dir)/*h endif uninstall: rm -f $(zlibdir)/*h rm -f $(zipardir)/*h rm -f $(libdir)/$(ZIPARCHLIB) rmdir $(zlibdir) ifdef INTERNAL_BZIP2 rm -f $(bzip2dir)/*h rmdir $(bzip2dir) endif rmdir $(zipardir) tuxcmd-modules-0.6.70+ds/zip/vfs_types.h0000777000175000017500000000000011300603570023061 2../common/vfs_types.hustar salvisalvituxcmd-modules-0.6.70+ds/zip/strutils.h0000777000175000017500000000000011300603570022577 2../common/strutils.hustar salvisalvituxcmd-modules-0.6.70+ds/zip/treepathutils.h0000777000175000017500000000000011300603570024607 2../common/treepathutils.hustar salvisalvituxcmd-modules-0.6.70+ds/zip/ZipArchive/0000755000175000017500000000000011300610031017025 5ustar salvisalvituxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipExport.h0000644000175000017500000000215111300022650021145 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipExport.h * Contains the Windows DLL exports definitions. * */ #if !defined (ZIPARCHIVE_ZIPEXPORT_DOT_H) #define ZIPARCHIVE_ZIPEXPORT_DOT_H #if defined (ZIP_HAS_DLL) # if defined (ZIP_BUILD_DLL) # define ZIP_API __declspec (dllexport) # else # define ZIP_API __declspec (dllimport) # endif #else # define ZIP_API #endif /* ZIP_HAS_DLL */ #endif /* ZIPARCHIVE_ZIPEXPORT_DOT_H */ tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCrc32Cryptograph.cpp0000644000175000017500000000517511300022650023327 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipCrc32Cryptograph.h" bool CZipCrc32Cryptograph::InitDecode(CZipAutoBuffer& password, CZipFileHeader& currentFile, CZipStorage& storage) { CryptInitKeys(password); CZipAutoBuffer buf(ZIPARCHIVE_ENCR_HEADER_LEN); storage.Read(buf, ZIPARCHIVE_ENCR_HEADER_LEN, false); BYTE b = 0; for (int i = 0; i < ZIPARCHIVE_ENCR_HEADER_LEN; i++) { b = buf[i]; // only temporary CryptDecode((char&)b); } // check the last byte return currentFile.IsDataDescriptor() ? (BYTE(currentFile.m_uModTime >> 8) == b) : (BYTE(currentFile.m_uCrc32 >> 24) == b); } void CZipCrc32Cryptograph::InitEncode(CZipAutoBuffer& password, CZipFileHeader& currentFile, CZipStorage& storage) { CZipAutoBuffer buf(ZIPARCHIVE_ENCR_HEADER_LEN); // use pseudo-crc since we don't know it yet CryptInitKeys(password); srand(UINT(time(NULL))); // genereate pseudo-random sequence char c; char* buffer = (char*)buf; for (int i = 0; i < ZIPARCHIVE_ENCR_HEADER_LEN - 2; i++) { int t1 = rand(); c = (char)((t1 >> 6) & 0xFF); if (!c) c = (char)(t1 & 0xFF); CryptEncode(c); buffer[i] = c; } long iCrc = (long)currentFile.m_uModTime << 16; c = (char)((iCrc >> 16) & 0xFF); CryptEncode(c); buffer[ZIPARCHIVE_ENCR_HEADER_LEN - 2] = c; c = (char)((iCrc >> 24) & 0xFF); CryptEncode(c); buffer[ZIPARCHIVE_ENCR_HEADER_LEN - 1] = c; storage.Write(buf, ZIPARCHIVE_ENCR_HEADER_LEN, false); currentFile.m_uComprSize += ZIPARCHIVE_ENCR_HEADER_LEN; } void CZipCrc32Cryptograph::CryptInitKeys(CZipAutoBuffer& password) { m_keys[0] = 305419896L; m_keys[1] = 591751049L; m_keys[2] = 878082192L; for (DWORD i = 0; i < password.GetSize(); i++) CryptUpdateKeys(password[i]); } void CZipCrc32Cryptograph::CryptUpdateKeys(char c) { m_keys[0] = CryptCRC32(m_keys[0], c); m_keys[1] += m_keys[0] & 0xff; m_keys[1] = m_keys[1] * 134775813L + 1; c = char(m_keys[1] >> 24); m_keys[2] = CryptCRC32(m_keys[2], c); } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/0000755000175000017500000000000011300022650017771 5ustar salvisalvituxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/trees.c0000644000175000017500000013034411300022650021264 0ustar salvisalvi/* trees.c -- output deflated data using Huffman coding * Copyright (C) 1995-2005 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process uses several Huffman trees. The more * common source values are represented by shorter bit sequences. * * Each code tree is stored in a compressed form which is itself * a Huffman encoding of the lengths of all the code strings (in * ascending order by source values). The actual code strings are * reconstructed from the lengths in the inflate process, as described * in the deflate specification. * * REFERENCES * * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc * * Storer, James A. * Data Compression: Methods and Theory, pp. 49-50. * Computer Science Press, 1988. ISBN 0-7167-8156-5. * * Sedgewick, R. * Algorithms, p290. * Addison-Wesley, 1983. ISBN 0-201-06672-6. */ /* @(#) $Id$ */ /* #define GEN_TREES_H */ #include "deflate.h" #ifdef DEBUG # include #endif /* =========================================================================== * Constants */ #define MAX_BL_BITS 7 /* Bit length codes must not exceed MAX_BL_BITS bits */ #define END_BLOCK 256 /* end of block literal code */ #define REP_3_6 16 /* repeat previous bit length 3-6 times (2 bits of repeat count) */ #define REPZ_3_10 17 /* repeat a zero length 3-10 times (3 bits of repeat count) */ #define REPZ_11_138 18 /* repeat a zero length 11-138 times (7 bits of repeat count) */ local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; local const int extra_dbits[D_CODES] /* extra bits for each distance code */ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; local const uch bl_order[BL_CODES] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; /* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. */ #define Buf_size (8 * 2*sizeof(char)) /* Number of bits used within bi_buf. (bi_buf might be implemented on * more than 16 bits on some systems.) */ /* =========================================================================== * Local data. These are initialized only once. */ #define DIST_CODE_LEN 512 /* see definition of array dist_code below */ #if defined(GEN_TREES_H) || !defined(STDC) /* non ANSI compilers may not accept trees.h */ local ct_data static_ltree[L_CODES+2]; /* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However * The codes 286 and 287 are needed to build a canonical tree (see _tr_init * below). */ local ct_data static_dtree[D_CODES]; /* The static distance tree. (Actually a trivial tree since all codes use * 5 bits.) */ uch _dist_code[DIST_CODE_LEN]; /* Distance codes. The first 256 values correspond to the distances * 3 .. 258, the last 256 values correspond to the top 8 bits of * the 15 bit distances. */ uch _length_code[MAX_MATCH-MIN_MATCH+1]; /* length code for each normalized match length (0 == MIN_MATCH) */ local int base_length[LENGTH_CODES]; /* First normalized length for each code (0 = MIN_MATCH) */ local int base_dist[D_CODES]; /* First normalized distance for each code (0 = distance of 1) */ #else # include "trees.h" #endif /* GEN_TREES_H */ struct static_tree_desc_s { const ct_data *static_tree; /* static tree or NULL */ const intf *extra_bits; /* extra bits for each code or NULL */ int extra_base; /* base index for extra_bits */ int elems; /* max number of elements in the tree */ int max_length; /* max bit length for the codes */ }; local static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; local static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; local static_tree_desc static_bl_desc = {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== * Local (static) routines in this file. */ local void tr_static_init OF((void)); local void init_block OF((deflate_state *s)); local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); local void build_tree OF((deflate_state *s, tree_desc *desc)); local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); local int build_bl_tree OF((deflate_state *s)); local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, int blcodes)); local void compress_block OF((deflate_state *s, ct_data *ltree, ct_data *dtree)); local void set_data_type OF((deflate_state *s)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((deflate_state *s)); local void bi_flush OF((deflate_state *s)); local void copy_block OF((deflate_state *s, charf *buf, unsigned len, int header)); #ifdef GEN_TREES_H local void gen_trees_header OF((void)); #endif #ifndef DEBUG # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) /* Send a code of the given tree. c and tree must not have side effects */ #else /* DEBUG */ # define send_code(s, c, tree) \ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ send_bits(s, tree[c].Code, tree[c].Len); } #endif /* =========================================================================== * Output a short LSB first on the stream. * IN assertion: there is enough room in pendingBuf. */ #define put_short(s, w) { \ put_byte(s, (uch)((w) & 0xff)); \ put_byte(s, (uch)((ush)(w) >> 8)); \ } /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ #ifdef DEBUG local void send_bits OF((deflate_state *s, int value, int length)); local void send_bits(s, value, length) deflate_state *s; int value; /* value to send */ int length; /* number of bits */ { Tracevv((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); s->bits_sent += (ulg)length; /* If not enough room in bi_buf, use (valid) bits from bi_buf and * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) * unused bits in value. */ if (s->bi_valid > (int)Buf_size - length) { s->bi_buf |= ((value << s->bi_valid) & 0xFFFF); put_short(s, s->bi_buf); s->bi_buf = (ush)((ush)value >> (Buf_size - s->bi_valid)); s->bi_valid += length - Buf_size; } else { s->bi_buf |= (value << s->bi_valid); s->bi_valid += length; } } #else /* !DEBUG */ #define send_bits(s, value, length) \ { int len = length;\ if (s->bi_valid > (int)Buf_size - len) {\ int val = value;\ s->bi_buf |= (((value) << s->bi_valid) & 0xFFFF);\ put_short(s, s->bi_buf);\ s->bi_buf = (ush)((ush)val >> (Buf_size - s->bi_valid));\ s->bi_valid += len - Buf_size;\ } else {\ s->bi_buf |= ((value) << s->bi_valid);\ s->bi_valid += len;\ }\ } #endif /* DEBUG */ /* the arguments must not have side effects */ /* =========================================================================== * Initialize the various 'constant' tables. */ local void tr_static_init() { #if defined(GEN_TREES_H) || !defined(STDC) static int static_init_done = 0; int n; /* iterates over tree elements */ int bits; /* bit counter */ int length; /* length value */ int code; /* code value */ int dist; /* distance index */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ if (static_init_done) return; /* For some embedded targets, global variables are not initialized: */ static_l_desc.static_tree = static_ltree; static_l_desc.extra_bits = extra_lbits; static_d_desc.static_tree = static_dtree; static_d_desc.extra_bits = extra_dbits; static_bl_desc.extra_bits = extra_blbits; /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0; for (code = 0; code < LENGTH_CODES-1; code++) { base_length[code] = length; for (n = 0; n < (1< dist code (0..29) */ dist = 0; for (code = 0 ; code < 16; code++) { base_dist[code] = dist; for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ for ( ; code < D_CODES; code++) { base_dist[code] = dist << 7; for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { _dist_code[256 + dist++] = (uch)code; } } Assert (dist == 256, "tr_static_init: 256+dist != 512"); /* Construct the codes of the static literal tree */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; n = 0; while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; /* Codes 286 and 287 do not exist, but we must include them in the * tree construction to get a canonical Huffman tree (longest code * all ones) */ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); /* The static distance tree is trivial: */ for (n = 0; n < D_CODES; n++) { static_dtree[n].Len = 5; static_dtree[n].Code = bi_reverse((unsigned)n, 5); } static_init_done = 1; # ifdef GEN_TREES_H gen_trees_header(); # endif #endif /* defined(GEN_TREES_H) || !defined(STDC) */ } /* =========================================================================== * Genererate the file trees.h describing the static trees. */ #ifdef GEN_TREES_H # ifndef DEBUG # include # endif # define SEPARATOR(i, last, width) \ ((i) == (last)? "\n};\n\n" : \ ((i) % (width) == (width)-1 ? ",\n" : ", ")) void gen_trees_header() { FILE *header = fopen("trees.h", "w"); int i; Assert (header != NULL, "Can't open trees.h"); fprintf(header, "/* header created automatically with -DGEN_TREES_H */\n\n"); fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); for (i = 0; i < L_CODES+2; i++) { fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); } fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); for (i = 0; i < D_CODES; i++) { fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); } fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); for (i = 0; i < DIST_CODE_LEN; i++) { fprintf(header, "%2u%s", _dist_code[i], SEPARATOR(i, DIST_CODE_LEN-1, 20)); } fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { fprintf(header, "%2u%s", _length_code[i], SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); } fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); for (i = 0; i < LENGTH_CODES; i++) { fprintf(header, "%1u%s", base_length[i], SEPARATOR(i, LENGTH_CODES-1, 20)); } fprintf(header, "local const int base_dist[D_CODES] = {\n"); for (i = 0; i < D_CODES; i++) { fprintf(header, "%5u%s", base_dist[i], SEPARATOR(i, D_CODES-1, 10)); } fclose(header); } #endif /* GEN_TREES_H */ /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ void _tr_init(s) deflate_state *s; { tr_static_init(); s->l_desc.dyn_tree = s->dyn_ltree; s->l_desc.stat_desc = &static_l_desc; s->d_desc.dyn_tree = s->dyn_dtree; s->d_desc.stat_desc = &static_d_desc; s->bl_desc.dyn_tree = s->bl_tree; s->bl_desc.stat_desc = &static_bl_desc; s->bi_buf = 0; s->bi_valid = 0; s->last_eob_len = 8; /* enough lookahead for inflate */ #ifdef DEBUG s->compressed_len = 0L; s->bits_sent = 0L; #endif /* Initialize the first block of the first file: */ init_block(s); } /* =========================================================================== * Initialize a new block. */ local void init_block(s) deflate_state *s; { int n; /* iterates over tree elements */ /* Initialize the trees. */ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; s->dyn_ltree[END_BLOCK].Freq = 1; s->opt_len = s->static_len = 0L; s->last_lit = s->matches = 0; } #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ /* =========================================================================== * Remove the smallest element from the heap and recreate the heap with * one less element. Updates heap and heap_len. */ #define pqremove(s, tree, top) \ {\ top = s->heap[SMALLEST]; \ s->heap[SMALLEST] = s->heap[s->heap_len--]; \ pqdownheap(s, tree, SMALLEST); \ } /* =========================================================================== * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */ #define smaller(tree, n, m, depth) \ (tree[n].Freq < tree[m].Freq || \ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) /* =========================================================================== * Restore the heap property by moving down the tree starting at node k, * exchanging a node with the smallest of its two sons if necessary, stopping * when the heap property is re-established (each father smaller than its * two sons). */ local void pqdownheap(s, tree, k) deflate_state *s; ct_data *tree; /* the tree to restore */ int k; /* node to move down */ { int v = s->heap[k]; int j = k << 1; /* left son of k */ while (j <= s->heap_len) { /* Set j to the smallest of the two sons: */ if (j < s->heap_len && smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { j++; } /* Exit if v is smaller than both sons */ if (smaller(tree, v, s->heap[j], s->depth)) break; /* Exchange v with the smallest son */ s->heap[k] = s->heap[j]; k = j; /* And continue down the tree, setting j to the left son of k */ j <<= 1; } s->heap[k] = v; } /* =========================================================================== * Compute the optimal bit lengths for a tree and update the total bit length * for the current block. * IN assertion: the fields freq and dad are set, heap[heap_max] and * above are the tree nodes sorted by increasing frequency. * OUT assertions: the field len is set to the optimal bit length, the * array bl_count contains the frequencies for each bit length. * The length opt_len is updated; static_len is also updated if stree is * not null. */ local void gen_bitlen(s, desc) deflate_state *s; tree_desc *desc; /* the tree descriptor */ { ct_data *tree = desc->dyn_tree; int max_code = desc->max_code; const ct_data *stree = desc->stat_desc->static_tree; const intf *extra = desc->stat_desc->extra_bits; int base = desc->stat_desc->extra_base; int max_length = desc->stat_desc->max_length; int h; /* heap index */ int n, m; /* iterate over the tree elements */ int bits; /* bit length */ int xbits; /* extra bits */ ush f; /* frequency */ int overflow = 0; /* number of elements with bit length too large */ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; /* In a first pass, compute the optimal bit lengths (which may * overflow in the case of the bit length tree). */ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ for (h = s->heap_max+1; h < HEAP_SIZE; h++) { n = s->heap[h]; bits = tree[tree[n].Dad].Len + 1; if (bits > max_length) bits = max_length, overflow++; tree[n].Len = (ush)bits; /* We overwrite tree[n].Dad which is no longer needed */ if (n > max_code) continue; /* not a leaf node */ s->bl_count[bits]++; xbits = 0; if (n >= base) xbits = extra[n-base]; f = tree[n].Freq; s->opt_len += (ulg)f * (bits + xbits); if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); } if (overflow == 0) return; Trace((stderr,"\nbit length overflow\n")); /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ do { bits = max_length-1; while (s->bl_count[bits] == 0) bits--; s->bl_count[bits]--; /* move one leaf down the tree */ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ s->bl_count[max_length]--; /* The brother of the overflow item also moves one step up, * but this does not affect bl_count[max_length] */ overflow -= 2; } while (overflow > 0); /* Now recompute all bit lengths, scanning in increasing frequency. * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all * lengths instead of fixing only the wrong ones. This idea is taken * from 'ar' written by Haruhiko Okumura.) */ for (bits = max_length; bits != 0; bits--) { n = s->bl_count[bits]; while (n != 0) { m = s->heap[--h]; if (m > max_code) continue; if ((unsigned) tree[m].Len != (unsigned) bits) { Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); s->opt_len += ((long)bits - (long)tree[m].Len) *(long)tree[m].Freq; tree[m].Len = (ush)bits; } n--; } } } /* =========================================================================== * Generate the codes for a given tree and bit counts (which need not be * optimal). * IN assertion: the array bl_count contains the bit length statistics for * the given tree and the field len is set for all tree elements. * OUT assertion: the field code is set for all tree elements of non * zero code length. */ local void gen_codes (tree, max_code, bl_count) ct_data *tree; /* the tree to decorate */ int max_code; /* largest code with non zero frequency */ ushf *bl_count; /* number of codes at each bit length */ { ush next_code[MAX_BITS+1]; /* next code value for each bit length */ ush code = 0; /* running code value */ int bits; /* bit index */ int n; /* code index */ /* The distribution counts are first used to generate the code values * without bit reversal. */ for (bits = 1; bits <= MAX_BITS; bits++) { next_code[bits] = code = (code + bl_count[bits-1]) << 1; } /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. */ Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; const ct_data *stree = desc->stat_desc->static_tree; int elems = desc->stat_desc->elems; int n, m; /* iterate over heap elements */ int max_code = -1; /* largest code with non zero frequency */ int node; /* new node being created */ /* Construct the initial heap, with least frequent element in * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. * heap[0] is not used. */ s->heap_len = 0, s->heap_max = HEAP_SIZE; for (n = 0; n < elems; n++) { if (tree[n].Freq != 0) { s->heap[++(s->heap_len)] = max_code = n; s->depth[n] = 0; } else { tree[n].Len = 0; } } /* The pkzip format requires that at least one distance code exists, * and that at least one bit should be sent even if there is only one * possible code. So to avoid special checks later on we force at least * two codes of non zero frequency. */ while (s->heap_len < 2) { node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); tree[node].Freq = 1; s->depth[node] = 0; s->opt_len--; if (stree) s->static_len -= stree[node].Len; /* node is 0 or 1 so it does not have extra bits */ } desc->max_code = max_code; /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, * establish sub-heaps of increasing lengths: */ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); /* Construct the Huffman tree by repeatedly combining the least two * frequent nodes. */ node = elems; /* next internal node of the tree */ do { pqremove(s, tree, n); /* n = node of least frequency */ m = s->heap[SMALLEST]; /* m = node of next least frequency */ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ s->heap[--(s->heap_max)] = m; /* Create a new node father of n and m */ tree[node].Freq = tree[n].Freq + tree[m].Freq; s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? s->depth[n] : s->depth[m]) + 1); tree[n].Dad = tree[m].Dad = (ush)node; #ifdef DUMP_BL_TREE if (tree == s->bl_tree) { fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); } #endif /* and insert the new node in the heap */ s->heap[SMALLEST] = node++; pqdownheap(s, tree, SMALLEST); } while (s->heap_len >= 2); s->heap[--(s->heap_max)] = s->heap[SMALLEST]; /* At this point, the fields freq and dad are set. We can now * generate the bit lengths. */ gen_bitlen(s, (tree_desc *)desc); /* The field len is now set, we can generate the bit codes */ gen_codes ((ct_data *)tree, max_code, s->bl_count); } /* =========================================================================== * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */ local void scan_tree (s, tree, max_code) deflate_state *s; ct_data *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ if (nextlen == 0) max_count = 138, min_count = 3; tree[max_code+1].Len = (ush)0xffff; /* guard */ for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { s->bl_tree[curlen].Freq += count; } else if (curlen != 0) { if (curlen != prevlen) s->bl_tree[curlen].Freq++; s->bl_tree[REP_3_6].Freq++; } else if (count <= 10) { s->bl_tree[REPZ_3_10].Freq++; } else { s->bl_tree[REPZ_11_138].Freq++; } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ local void send_tree (s, tree, max_code) deflate_state *s; ct_data *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ /* tree[max_code+1].Len = -1; */ /* guard already set */ if (nextlen == 0) max_count = 138, min_count = 3; for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { do { send_code(s, curlen, s->bl_tree); } while (--count != 0); } else if (curlen != 0) { if (curlen != prevlen) { send_code(s, curlen, s->bl_tree); count--; } Assert(count >= 3 && count <= 6, " 3_6?"); send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); } else if (count <= 10) { send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); } else { send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */ local int build_bl_tree(s) deflate_state *s; { int max_blindex; /* index of last bit length code of non zero freq */ /* Determine the bit length frequencies for literal and distance trees */ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); /* Build the bit length tree: */ build_tree(s, (tree_desc *)(&(s->bl_desc))); /* opt_len now includes the length of the tree representations, except * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. */ /* Determine the number of bit length codes to send. The pkzip format * requires that at least 4 bit length codes be sent. (appnote.txt says * 3 but the actual value used is 4.) */ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; } /* Update opt_len to include the bit length tree and counts */ s->opt_len += 3*(max_blindex+1) + 5+5+4; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); return max_blindex; } /* =========================================================================== * Send the header for a block using dynamic Huffman trees: the counts, the * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ local void send_all_trees(s, lcodes, dcodes, blcodes) deflate_state *s; int lcodes, dcodes, blcodes; /* number of codes for each tree */ { int rank; /* index in bl_order */ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); Tracev((stderr, "\nbl counts: ")); send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ send_bits(s, dcodes-1, 5); send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ for (rank = 0; rank < blcodes; rank++) { Tracev((stderr, "\nbl code %2d ", bl_order[rank])); send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); } Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); } /* =========================================================================== * Send a stored block */ void _tr_stored_block(s, buf, stored_len, eof) deflate_state *s; charf *buf; /* input block */ ulg stored_len; /* length of input block */ int eof; /* true if this is the last block for a file */ { send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ #ifdef DEBUG s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; #endif copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ } /* =========================================================================== * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. * The current inflate code requires 9 bits of lookahead. If the * last two codes for the previous block (real code plus EOB) were coded * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode * the last real code. In this case we send two empty static blocks instead * of one. (There are no problems if the previous block is stored or fixed.) * To simplify the code, we assume the worst case of last real code encoded * on one bit only. */ void _tr_align(s) deflate_state *s; { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); #ifdef DEBUG s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ #endif bi_flush(s); /* Of the 10 bits for the empty block, we have already sent * (10 - bi_valid) bits. The lookahead for the last real code (before * the EOB of the previous block) was thus at least one plus the length * of the EOB plus what we have just sent of the empty static block. */ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); #ifdef DEBUG s->compressed_len += 10L; #endif bi_flush(s); } s->last_eob_len = 7; } /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. */ void _tr_flush_block(s, buf, stored_len, eof) deflate_state *s; charf *buf; /* input block, or NULL if too old */ ulg stored_len; /* length of input block */ int eof; /* true if this is the last block for a file */ { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex = 0; /* index of last bit length code of non zero freq */ /* Build the Huffman trees unless a stored block is forced */ if (s->level > 0) { /* Check if the file is binary or text */ if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) set_data_type(s); /* Construct the literal and distance trees */ build_tree(s, (tree_desc *)(&(s->l_desc))); Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, s->static_len)); build_tree(s, (tree_desc *)(&(s->d_desc))); Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, s->static_len)); /* At this point, opt_len and static_len are the total bit lengths of * the compressed block data, excluding the tree representations. */ /* Build the bit length tree for the above two trees, and get the index * in bl_order of the last bit length code to send. */ max_blindex = build_bl_tree(s); /* Determine the best encoding. Compute the block lengths in bytes. */ opt_lenb = (s->opt_len+3+7)>>3; static_lenb = (s->static_len+3+7)>>3; Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, s->last_lit)); if (static_lenb <= opt_lenb) opt_lenb = static_lenb; } else { Assert(buf != (char*)0, "lost buf"); opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ } #ifdef FORCE_STORED if (buf != (char*)0) { /* force stored block */ #else if (stored_len+4 <= opt_lenb && buf != (char*)0) { /* 4: two words for the lengths */ #endif /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. * Otherwise we can't have processed more than WSIZE input bytes since * the last block flush, because compression would have been * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ _tr_stored_block(s, buf, stored_len, eof); #ifdef FORCE_STATIC } else if (static_lenb >= 0) { /* force static trees */ #else } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { #endif send_bits(s, (STATIC_TREES<<1)+eof, 3); compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); #ifdef DEBUG s->compressed_len += 3 + s->static_len; #endif } else { send_bits(s, (DYN_TREES<<1)+eof, 3); send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); #ifdef DEBUG s->compressed_len += 3 + s->opt_len; #endif } Assert (s->compressed_len == s->bits_sent, "bad compressed size"); /* The above check is made mod 2^32, for files larger than 512 MB * and uLong implemented on 32 bits. */ init_block(s); if (eof) { bi_windup(s); #ifdef DEBUG s->compressed_len += 7; /* align on byte boundary */ #endif } Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, s->compressed_len-7*eof)); } /* =========================================================================== * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ int _tr_tally (s, dist, lc) deflate_state *s; unsigned dist; /* distance of matched string */ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ { s->d_buf[s->last_lit] = (ush)dist; s->l_buf[s->last_lit++] = (uch)lc; if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; } else { s->matches++; /* Here, lc is the match length - MIN_MATCH */ dist--; /* dist = match distance - 1 */ Assert((ush)dist < (ush)MAX_DIST(s) && (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; s->dyn_dtree[d_code(dist)].Freq++; } #ifdef TRUNCATE_BLOCK /* Try to guess if it is profitable to stop the current block here */ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { /* Compute an upper bound for the compressed length */ ulg out_length = (ulg)s->last_lit*8L; ulg in_length = (ulg)((long)s->strstart - s->block_start); int dcode; for (dcode = 0; dcode < D_CODES; dcode++) { out_length += (ulg)s->dyn_dtree[dcode].Freq * (5L+extra_dbits[dcode]); } out_length >>= 3; Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", s->last_lit, in_length, out_length, 100L - out_length*100L/in_length)); if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; } #endif return (s->last_lit == s->lit_bufsize-1); /* We avoid equality with lit_bufsize because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. */ } /* =========================================================================== * Send the block data compressed using the given Huffman trees */ local void compress_block(s, ltree, dtree) deflate_state *s; ct_data *ltree; /* literal tree */ ct_data *dtree; /* distance tree */ { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ unsigned lx = 0; /* running index in l_buf */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->last_lit != 0) do { dist = s->d_buf[lx]; lc = s->l_buf[lx++]; if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); } else { /* Here, lc is the match length - MIN_MATCH */ code = _length_code[lc]; send_code(s, code+LITERALS+1, ltree); /* send the length code */ extra = extra_lbits[code]; if (extra != 0) { lc -= base_length[code]; send_bits(s, lc, extra); /* send the extra length bits */ } dist--; /* dist is now the match distance - 1 */ code = d_code(dist); Assert (code < D_CODES, "bad d_code"); send_code(s, code, dtree); /* send the distance code */ extra = extra_dbits[code]; if (extra != 0) { dist -= base_dist[code]; send_bits(s, dist, extra); /* send the extra distance bits */ } } /* literal or match pair ? */ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, "pendingBuf overflow"); } while (lx < s->last_lit); send_code(s, END_BLOCK, ltree); s->last_eob_len = ltree[END_BLOCK].Len; } /* =========================================================================== * Set the data type to BINARY or TEXT, using a crude approximation: * set it to Z_TEXT if all symbols are either printable characters (33 to 255) * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. * IN assertion: the fields Freq of dyn_ltree are set. */ local void set_data_type(s) deflate_state *s; { int n; for (n = 0; n < 9; n++) if (s->dyn_ltree[n].Freq != 0) break; if (n == 9) for (n = 14; n < 32; n++) if (s->dyn_ltree[n].Freq != 0) break; s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; } /* =========================================================================== * Reverse the first len bits of a code, using straightforward code (a faster * method would use a table) * IN assertion: 1 <= len <= 15 */ local unsigned bi_reverse(code, len) unsigned code; /* the value to invert */ int len; /* its bit length */ { register unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; } while (--len > 0); return res >> 1; } /* =========================================================================== * Flush the bit buffer, keeping at most 7 bits in it. */ local void bi_flush(s) deflate_state *s; { if (s->bi_valid == 16) { put_short(s, s->bi_buf); s->bi_buf = 0; s->bi_valid = 0; } else if (s->bi_valid >= 8) { put_byte(s, (Byte)s->bi_buf); s->bi_buf >>= 8; s->bi_valid -= 8; } } /* =========================================================================== * Flush the bit buffer and align the output on a byte boundary */ local void bi_windup(s) deflate_state *s; { if (s->bi_valid > 8) { put_short(s, s->bi_buf); } else if (s->bi_valid > 0) { put_byte(s, (Byte)s->bi_buf); } s->bi_buf = 0; s->bi_valid = 0; #ifdef DEBUG s->bits_sent = (s->bits_sent+7) & ~7; #endif } /* =========================================================================== * Copy a stored block, storing first the length and its * one's complement if requested. */ local void copy_block(s, buf, len, header) deflate_state *s; charf *buf; /* the input data */ unsigned len; /* its length */ int header; /* true if block header must be written */ { bi_windup(s); /* align on byte boundary */ s->last_eob_len = 8; /* enough lookahead for inflate */ if (header) { put_short(s, (ush)len); put_short(s, (ush)~len); #ifdef DEBUG s->bits_sent += 2*16; #endif } #ifdef DEBUG s->bits_sent += (ulg)len<<3; #endif while (len--) { put_byte(s, *buf++); } } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/zlib.h0000644000175000017500000020410711300022650021106 0ustar salvisalvi/* zlib.h -- interface of the 'zlib' general purpose compression library version 1.2.3, July 18th, 2005 Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ #ifndef ZLIB_H #define ZLIB_H #define Z_PREFIX 1 #define NO_GZIP 1 #define NO_DUMMY_DECL 1 #include "zconf.h" #ifdef __cplusplus extern "C" { #endif #define ZLIB_VERSION "1.2.3" #define ZLIB_VERNUM 0x1230 #define PKZIP_BUG_WORKAROUND 1 /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms will be added later and will have the same stream interface. Compression can be done in a single step if the buffers are large enough (for example if an input file is mmap'ed), or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. The compressed data format used by default by the in-memory functions is the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped around a deflate stream, which is itself documented in RFC 1951. The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. This library can optionally read and write gzip streams in memory as well. The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single- file compression on file systems, has a larger header than zlib to maintain directory information, and uses a different, slower check method than zlib. The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in case of corrupted input. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); typedef void (*free_func) OF((voidpf opaque, voidpf address)); //struct internal_state; typedef struct z_stream_s { Bytef *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLongLong total_in; /* total nb of input bytes read so far */ Bytef *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ uLongLong total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULL if no error */ struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ free_func zfree; /* used to free the internal state */ voidpf opaque; /* private data object passed to zalloc and zfree */ int data_type; /* best guess about the data type: binary or text */ uLong adler; /* adler32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; typedef z_stream FAR *z_streamp; /* gzip header information passed to and from zlib routines. See RFC 1952 for more details on the meanings of these fields. */ typedef struct gz_header_s { int text; /* true if compressed data believed to be text */ uLong time; /* modification time */ int xflags; /* extra flags (not used when writing a gzip file) */ int os; /* operating system */ Bytef *extra; /* pointer to extra field or Z_NULL if none */ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ uInt extra_max; /* space at extra (only when reading header) */ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ uInt name_max; /* space at name (only when reading header) */ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ uInt comm_max; /* space at comment (only when reading header) */ int hcrc; /* true if there was or will be a header crc */ int done; /* true when done reading gzip header (not used when writing a gzip file) */ } gz_header; typedef gz_header FAR *gz_headerp; /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before calling the init function. All other fields are set by the compression library and must not be updated by the application. The opaque value provided by the application will be passed as the first parameter for calls of zalloc and zfree. This can be useful for custom memory management. The compression library attaches no meaning to the opaque value. zalloc must return Z_NULL if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be thread safe. On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers returned by zalloc for objects of exactly 65536 bytes *must* have their offset normalized to zero. The default allocation function provided by this library ensures this (see zutil.c). To reduce memory requirements and avoid any allocation of 64K objects, at the expense of compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the uncompressed data and may be saved for use in the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ /* constants */ #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ #define Z_SYNC_FLUSH 2 #define Z_FULL_FLUSH 3 #define Z_FINISH 4 #define Z_BLOCK 5 /* Allowed flush values; see deflate() and inflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative * values are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_RLE 3 #define Z_FIXED 4 #define Z_DEFAULT_STRATEGY 0 /* compression strategy; see deflateInit2() below for details */ #define Z_BINARY 0 #define Z_TEXT 1 #define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ #define Z_UNKNOWN 2 /* Possible values of the data_type field (though see inflate()) */ #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ #define zlib_version zlibVersion() /* for compatibility with versions < 1.0.2 */ /* basic functions */ ZEXTERN const char * ZEXPORT zlibVersion OF((void)); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. */ /* ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default allocation functions. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION requests a default compromise between speed and compression (currently equivalent to level 6). deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if level is not a valid compression level, Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); /* deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. deflate performs one or both of the following actions: - Compress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter should be set only when necessary (in interactive applications). Some output may be provided even if flush is not set. Before the call of deflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating avail_in or avail_out accordingly; avail_out should never be zero before the call. The application can consume the compressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to decide how much data to accumualte before producing output, in order to maximize compression. If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. (In particular avail_in is zero after the call if enough output space has been provided before the call.) Flushing may degrade compression for some compression algorithms and so it should be used only when necessary. If flush is set to Z_FULL_FLUSH, all output is flushed as with Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Using Z_FULL_FLUSH too often can seriously degrade compression. If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out is greater than six to avoid repeated flush markers due to avail_out == 0 on return. If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was enough output space; if deflate returns with Z_OK, this function must be called again with Z_FINISH and more output space (updated avail_out) but no more input data, until it returns with Z_STREAM_END or an error. After deflate has returned Z_STREAM_END, the only possible operations on the stream are deflateReset or deflateEnd. Z_FINISH can be used immediately after deflateInit if all the compression is to be done in a single step. In this case, avail_out must be at least the value returned by deflateBound (see below). If deflate does not return Z_STREAM_END, then it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read so far (that is, total_in bytes). deflate() may update strm->data_type if it can make a good guess about the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered binary. This field is only for information purposes and does not affect the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and deflate() can be called again with more input and more output space to continue compressing. */ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent, Z_DATA_ERROR if the stream was freed prematurely (some input or output was discarded). In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. If next_in is not Z_NULL and avail_in is large enough (the exact value depends on the compression method), inflateInit determines the compression method from the zlib header and allocates all data structures accordingly; otherwise the allocation will be deferred to the first call of inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to use default allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller. msg is set to null if there is no error message. inflateInit does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) */ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); /* inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. inflate performs one or both of the following actions: - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in is updated and processing will resume at this point for the next call of inflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating the next_* and avail_* values accordingly. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of inflate(). If inflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much output as possible to the output buffer. Z_BLOCK requests that inflate() stop if and when it gets to the next deflate block boundary. When decoding the zlib or gzip format, this will cause inflate() to return immediately after the header and before the first block. When doing a raw inflate, inflate() will go ahead and process the first block, and will return when it gets to the end of that block, or when it runs out of data. The Z_BLOCK option assists in appending to or combining deflate streams. Also to assist in this, on return inflate() will set strm->data_type to the number of unused bits in the last byte taken from strm->next_in, plus 64 if inflate() is currently decoding the last block in the deflate stream, plus 128 if inflate() returned immediately after decoding an end-of-block code or decoding the complete header up to just before the first byte of the deflate stream. The end-of-block will not be indicated until all of the uncompressed data from that block has been written to strm->next_out. The number of unused bits may in general be greater than seven, except when bit 7 of data_type is set, in which case the number of unused bits will be less than eight. inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all the uncompressed data. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The next operation on this stream must be inflateEnd to deallocate the decompression state. The use of Z_FINISH is never required, but can be used to inform inflate that a faster approach may be used for the single inflate() call. In this implementation, inflate() always flushes as much output as possible to the output buffer, and always uses the faster approach on the first call. So the only effect of the flush parameter in this implementation is on the return value of inflate(), as noted below, or when it returns early because Z_BLOCK is used. If a preset dictionary is needed after this call (see inflateSetDictionary below), inflate sets strm->adler to the adler32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the adler32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described below. At the end of the stream, inflate() checks that its computed adler32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct. inflate() will decompress and check either zlib-wrapped or gzip-wrapped deflate data. The header type is detected automatically. Any information contained in the gzip header is not retained, so applications that need that information should instead use raw inflate, see inflateInit2() below, or inflateBack() and perform their own processing of the gzip header and trailer. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect check value), Z_STREAM_ERROR if the stream structure was inconsistent (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress is possible or if there was not enough room in the output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and inflate() can be called again with more input and more output space to continue decompressing. If Z_DATA_ERROR is returned, the application may then call inflateSync() to look for a good compression block if a partial recovery of the data is desired. */ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* Advanced functions */ /* The following functions are needed only in some special applications. */ /* ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy)); This is another version of deflateInit with more compression options. The fields next_in, zalloc, zfree and opaque must be initialized before by the caller. The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. The windowBits parameter is the base two logarithm of the window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. Larger values of this parameter result in better compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. windowBits can also be -8..-15 for raw deflate. In this case, -windowBits determines the window size. deflate() will then generate raw deflate data with no zlib header or trailer, and will not compute an adler32 check value. windowBits can also be greater than 15 for optional gzip encoding. Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper. The gzip header will have no file name, no extra data, no comment, no modification time (set to zero), no header crc, and the operating system will be set to 255 (unknown). If a gzip stream is being written, strm->adler is a crc32 instead of an adler32. The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is slow and reduces compression ratio; memLevel=9 uses maximum memory for optimal speed. The default value is 8. See zconf.h for total memory usage as a function of windowBits and memLevel. The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no string match), or Z_RLE to limit match distances to one (run-length encoding). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications. deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid method). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. This function must be called immediately after deflateInit, deflateInit2 or deflateReset, before any call of deflate. The compressor and decompressor must use exactly the same dictionary (see inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly used strings preferably put towards the end of the dictionary. Using a dictionary is most useful when the data to be compressed is short and can be predicted with good accuracy; the data can then be compressed better than with the default empty dictionary. Depending on the size of the compression data structures selected by deflateInit or deflateInit2, a part of the dictionary may in effect be discarded, for example if the dictionary is larger than the window size in deflate or deflate2. Thus the strings most likely to be useful should be put at the end of the dictionary, not at the front. In addition, the current implementation of deflate will use at most the window size minus 262 bytes of the provided dictionary. Upon return of this function, strm->adler is set to the adler32 value of the dictionary; the decompressor may later use this value to determine which dictionary has been used by the compressor. (The adler32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) If a raw deflate was requested, then the adler32 value is not computed and strm->adler is not set. deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (such as NULL dictionary) or the stream state is inconsistent (for example if deflate has already been called for this stream or if the compression method is bsort). deflateSetDictionary does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal compression state which can be quite large, so this strategy is slow and can consume lots of memory. deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate all the internal compression state. The stream will keep the same compression level and any other attributes that may have been set by deflateInit2. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULL). */ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, int level, int strategy)); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2. This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression level is changed, the input available so far is compressed with the old level (and may be flushed); the new level will take effect only at the next call of deflate(). Before the call of deflateParams, the stream state must be set as for a call of deflate(), since the currently available input may have to be compressed and flushed. In particular, strm->avail_out must be non-zero. deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if strm->avail_out was zero. */ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, int good_length, int max_lazy, int nice_length, int max_chain)); /* Fine tune deflate's internal compression parameters. This should only be used by someone who understands the algorithm used by zlib's deflate for searching for the best matching string, and even then only by the most fanatic optimizer trying to squeeze out the last compressed bit for their specific input data. Read the deflate.c source code for the meaning of the max_lazy, good_length, nice_length, and max_chain parameters. deflateTune() can be called after deflateInit() or deflateInit2(), and returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. */ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, uLong sourceLen)); /* deflateBound() returns an upper bound on the compressed size after deflation of sourceLen bytes. It must be called after deflateInit() or deflateInit2(). This would be used to allocate an output buffer for deflation in a single pass, and so would be called before deflate(). */ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, int bits, int value)); /* deflatePrime() inserts bits in the deflate output stream. The intent is that this function is used to start off the deflate output with the bits leftover from a previous deflate stream when appending to it. As such, this function can only be used for raw deflate, and must be used before the first deflate() call after a deflateInit2() or deflateReset(). bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the output. deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, gz_headerp head)); /* deflateSetHeader() provides gzip header information for when a gzip stream is requested by deflateInit2(). deflateSetHeader() may be called after deflateInit2() or deflateReset() and before the first call of deflate(). The text, time, os, extra field, name, and comment information in the provided gz_header structure are written to the gzip header (xflag is ignored -- the extra flags are set according to the compression level). The caller must assure that, if not Z_NULL, name and comment are terminated with a zero byte, and that if extra is not Z_NULL, that extra_len bytes are available there. If hcrc is true, a gzip header crc is included. Note that the current versions of the command-line version of gzip (up through version 1.3.x) do not support header crc's, and will report that it is a "multi-part gzip file" and give up. If deflateSetHeader is not used, the default gzip header has text false, the time set to zero, and os set to 255, with no extra, name, or comment fields. The gzip header is returned to the default state by deflateReset(). deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, int windowBits)); This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. The default value is 15 if inflateInit is used instead. windowBits must be greater than or equal to the windowBits value provided to deflateInit2() while compressing, or it must be equal to 15 if deflateInit2() was not used. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window. windowBits can also be -8..-15 for raw inflate. In this case, -windowBits determines the window size. inflate() will then process raw deflate data, not looking for a zlib or gzip header, not generating a check value, and not looking for any check values for comparison at the end of the stream. This is for use with other formats that use the deflate compressed data format such as zip. Those formats provide their own check values. If a custom format is developed using the raw deflate format for compressed data, it is recommended that a check value such as an adler32 or a crc32 be applied to the uncompressed data as is done in the zlib, gzip, and zip formats. For most applications, the zlib format should be used as is. Note that comments above on the use in deflateInit2() applies to the magnitude of windowBits. windowBits can also be greater than 15 for optional gzip decoding. Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection, or add 16 to decode only the gzip format (the zlib format will return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a crc32 instead of an adler32. inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg is set to null if there is no error message. inflateInit2 does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) */ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate, if that call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the adler32 value returned by that call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). For raw inflate, this function can be called immediately after inflateInit2() or inflateReset() and before any call of inflate() to set the dictionary. The application must insure that the dictionary that was used for compression is provided. inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (such as NULL dictionary) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the expected one (incorrect adler32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); /* Skips invalid compressed data until a full flush point (see above the description of deflate with Z_FULL_FLUSH) can be found, or until all available input is skipped. No output is provided. inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the success case, the application may save the current current value of total_in which indicates where valid compressed data was found. In the error case, the application may repeatedly call inflateSync, providing more input each time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when randomly accessing a large stream. The first pass through the stream can periodically record the inflate state, allowing restarting inflate at those points when randomly accessing the stream. inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate all the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULL). */ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, int bits, int value)); /* This function inserts bits in the inflate input stream. The intent is that this function is used to start inflating at a bit position in the middle of a byte. The provided bits will be used before any bytes are used from next_in. This function should only be used with raw inflate, and should be used before the first inflate() call after inflateInit2() or inflateReset(). bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the input. inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, gz_headerp head)); /* inflateGetHeader() requests that gzip header information be stored in the provided gz_header structure. inflateGetHeader() may be called after inflateInit2() or inflateReset(), and before the first call of inflate(). As inflate() processes the gzip stream, head->done is zero until the header is completed, at which time head->done is set to one. If a zlib stream is being decoded, then head->done is set to -1 to indicate that there will be no gzip header information forthcoming. Note that Z_BLOCK can be used to force inflate() to return immediately after header processing is complete and before any actual data is decompressed. The text, time, xflags, and os fields are filled in with the gzip header contents. hcrc is set to true if there is a header CRC. (The header CRC was valid if done is set to one.) If extra is not Z_NULL, then extra_max contains the maximum number of bytes to write to extra. Once done is true, extra_len contains the actual extra field length, and extra contains the extra field, or that field truncated if extra_max is less than extra_len. If name is not Z_NULL, then up to name_max characters are written there, terminated with a zero unless the length is greater than name_max. If comment is not Z_NULL, then up to comm_max characters are written there, terminated with a zero unless the length is greater than comm_max. When any of extra, name, or comment are not Z_NULL and the respective field is not present in the header, then that field is set to Z_NULL to signal its absence. This allows the use of deflateSetHeader() with the returned structure to duplicate the header. However if those fields are set to allocated memory, then the application will need to save those pointers elsewhere so that they can be eventually freed. If inflateGetHeader is not used, then the header information is simply discarded. The header is always checked for validity, including the header CRC if present. inflateReset() will reset the process to discard the header information. The application would need to call inflateGetHeader() again to retrieve the header from the next gzip stream. inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, unsigned char FAR *window)); Initialize the internal stream state for decompression using inflateBack() calls. The fields zalloc, zfree and opaque in strm must be initialized before the call. If zalloc and zfree are Z_NULL, then the default library- derived memory allocation routines are used. windowBits is the base two logarithm of the window size, in the range 8..15. window is a caller supplied buffer of that size. Except for special applications where it is assured that deflate was used with small window sizes, windowBits must be 15 and a 32K byte window must be supplied to be able to decompress general deflate streams. See inflateBack() for the usage of these routines. inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of the paramaters are invalid, Z_MEM_ERROR if the internal state could not be allocated, or Z_VERSION_ERROR if the version of the library does not match the version of the header file. */ typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc)); /* inflateBack() does a raw inflate with a single call using a call-back interface for input and output. This is more efficient than inflate() for file i/o applications in that it avoids copying between the output and the sliding window by simply making the window itself the output buffer. This function trusts the application to not change the output buffer passed by the output function, at least until inflateBack() returns. inflateBackInit() must be called first to allocate the internal state and to initialize the state with the user-provided window buffer. inflateBack() may then be used multiple times to inflate a complete, raw deflate stream with each call. inflateBackEnd() is then called to free the allocated state. A raw deflate stream is one with no zlib or gzip header or trailer. This routine would normally be used in a utility that reads zip or gzip files and writes out uncompressed files. The utility would decode the header and process the trailer on its own, hence this routine expects only the raw deflate stream to decompress. This is different from the normal behavior of inflate(), which expects either a zlib or gzip header and trailer around the deflate stream. inflateBack() uses two subroutines supplied by the caller that are then called by inflateBack() for input and output. inflateBack() calls those routines until it reads a complete deflate stream and writes out all of the uncompressed data, or until it encounters an error. The function's parameters and return types are defined above in the in_func and out_func typedefs. inflateBack() will call in(in_desc, &buf) which should return the number of bytes of provided input, and a pointer to that input in buf. If there is no input available, in() must return zero--buf is ignored in that case--and inflateBack() will return a buffer error. inflateBack() will call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() should return zero on success, or non-zero on failure. If out() returns non-zero, inflateBack() will return with an error. Neither in() nor out() are permitted to change the contents of the window provided to inflateBackInit(), which is also the buffer that out() uses to write from. The length written by out() will be at most the window size. Any non-zero amount of input may be provided by in(). For convenience, inflateBack() can be provided input on the first call by setting strm->next_in and strm->avail_in. If that input is exhausted, then in() will be called. Therefore strm->next_in must be initialized before calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in must also be initialized, and then if strm->avail_in is not zero, input will initially be taken from strm->next_in[0 .. strm->avail_in - 1]. The in_desc and out_desc parameters of inflateBack() is passed as the first parameter of in() and out() respectively when they are called. These descriptors can be optionally used to pass any information that the caller- supplied in() and out() functions need to do their job. On return, inflateBack() will set strm->next_in and strm->avail_in to pass back any unused input that was provided by the last in() call. The return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR if in() or out() returned an error, Z_DATA_ERROR if there was a format error in the deflate stream (in which case strm->msg is set to indicate the nature of the error), or Z_STREAM_ERROR if the stream was not properly initialized. In the case of Z_BUF_ERROR, an input or output error can be distinguished using strm->next_in which will be Z_NULL only if in() returned an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to out() returning non-zero. (in() will always be called before out(), so strm->next_in is assured to be defined if out() returns non-zero.) Note that inflateBack() cannot return Z_OK. */ ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); /* All memory allocated by inflateBackInit() is freed. inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream state was inconsistent. */ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); /* Return flags indicating compile-time options. Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: 1.0: size of uInt 3.2: size of uLong 5.4: size of voidpf (pointer) 7.6: size of z_off_t Compiler, assembler, and debug options: 8: DEBUG 9: ASMV or ASMINF -- use ASM code 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention 11: 0 (reserved) One-time table building (smaller code, but not thread-safe if true): 12: BUILDFIXED -- build static block decoding tables when needed 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed 14,15: 0 (reserved) Library content (indicates missing functionality): 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking deflate code when not needed) 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect and decode gzip streams (to avoid linking crc code) 18-19: 0 (reserved) Operation variations (changes in library functionality): 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate 21: FASTEST -- deflate algorithm with only one, lowest compression level 22,23: 0 (reserved) The sprintf variant used by gzprintf (zero is best): 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! 26: 0 = returns value, 1 = void -- 1 means inferred string length returned Remainder: 27-31: 0 (reserved) */ /* utility functions */ /* The following utility functions are implemented on top of the basic stream-oriented functions. To simplify the interface, some default options are assumed (compression level and memory usage, standard memory allocation functions). The source code of these utility functions can easily be modified if you need special options. */ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. This function can be used to compress a whole file at once if the input file is mmap'ed. compress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer. */ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); /* compressBound() returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before a compress() or compress2() call to allocate the destination buffer. */ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the compressed buffer. This function can be used to decompress a whole file at once if the input file is mmap'ed. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. */ typedef voidp gzFile; ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); /* Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb") but can also include a compression level ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman only compression as in "wb1h", or 'R' for run-length encoding as in "wb1R". (See the description of deflateInit2 for more information about the strategy parameter.) gzopen can be used to read a file which is not in gzip format; in this case gzread will directly read from the file without decompression. gzopen returns NULL if the file could not be opened or if there was insufficient memory to allocate the (de)compression state; errno can be checked to distinguish the two cases (if errno is zero, the zlib error is Z_MEM_ERROR). */ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); /* gzdopen() associates a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or fileno (in the file has been previously opened with fopen). The mode parameter is as in gzopen. The next call of gzclose on the returned gzFile will also close the file descriptor fd, just like fclose(fdopen(fd), mode) closes the file descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). gzdopen returns NULL if there was insufficient memory to allocate the (de)compression state. */ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); /* Dynamically update the compression level or strategy. See the description of deflateInit2 for the meaning of these parameters. gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not opened for writing. */ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); /* Reads the given number of uncompressed bytes from the compressed file. If the input file was not in gzip format, gzread copies the given number of bytes into the buffer. gzread returns the number of uncompressed bytes actually read (0 for end of file, -1 for error). */ ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len)); /* Writes the given number of uncompressed bytes into the compressed file. gzwrite returns the number of uncompressed bytes actually written (0 in case of error). */ ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); /* Converts, formats, and writes the args to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of uncompressed bytes actually written (0 in case of error). The number of uncompressed bytes written is limited to 4095. The caller should assure that this limit is not exceeded. If it is exceeded, then gzprintf() will return return an error (0) with nothing written. In this case, there may also be a buffer overflow with unpredictable consequences, which is possible only if zlib was compiled with the insecure functions sprintf() or vsprintf() because the secure snprintf() or vsnprintf() functions were not available. */ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); /* Writes the given null-terminated string to the compressed file, excluding the terminating null character. gzputs returns the number of characters written, or -1 in case of error. */ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); /* Reads bytes from the compressed file until len-1 characters are read, or a newline character is read and transferred to buf, or an end-of-file condition is encountered. The string is then terminated with a null character. gzgets returns buf, or Z_NULL in case of error. */ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); /* Writes c, converted to an unsigned char, into the compressed file. gzputc returns the value that was written, or -1 in case of error. */ ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); /* Reads one byte from the compressed file. gzgetc returns this byte or -1 in case of end of file or error. */ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); /* Push one character back onto the stream to be read again later. Only one character of push-back is allowed. gzungetc() returns the character pushed, or -1 on failure. gzungetc() will fail if a character has been pushed but not read yet, or if c is -1. The pushed character will be discarded if the stream is repositioned with gzseek() or gzrewind(). */ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); /* Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function gzerror below). gzflush returns Z_OK if the flush parameter is Z_FINISH and all output could be flushed. gzflush should be called only when strictly necessary because it can degrade compression. */ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, z_off_t offset, int whence)); /* Sets the starting position for the next gzread or gzwrite on the given compressed file. The offset represents a number of bytes in the uncompressed data stream. The whence parameter is defined as in lseek(2); the value SEEK_END is not supported. If the file is opened for reading, this function is emulated but can be extremely slow. If the file is opened for writing, only forward seeks are supported; gzseek then compresses a sequence of zeroes up to the new starting position. gzseek returns the resulting offset location as measured in bytes from the beginning of the uncompressed stream, or -1 in case of error, in particular if the file is opened for writing and the new starting position would be before the current position. */ ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); /* Rewinds the given file. This function is supported only for reading. gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) */ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); /* Returns the starting position for the next gzread or gzwrite on the given compressed file. This position represents a number of bytes in the uncompressed data stream. gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) */ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); /* Returns 1 when EOF has previously been detected reading the given input stream, otherwise zero. */ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); /* Returns 1 if file is being read directly without decompression, otherwise zero. */ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); /* Flushes all pending output if necessary, closes the compressed file and deallocates all the (de)compression state. The return value is the zlib error number (see function gzerror below). */ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); /* Returns the error message for the last error which occurred on the given compressed file. errnum is set to zlib error number. If an error occurred in the file system and not in the compression library, errnum is set to Z_ERRNO and the application may consult errno to get the exact error code. */ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); /* Clears the error and end-of-file flags for file. This is analogous to the clearerr() function in stdio. This is useful for continuing to read a gzip file that is being written concurrently. */ /* checksum functions */ /* These functions are not related to compression but are exported anyway because they might be useful in applications using the compression library. */ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. If buf is NULL, this function returns the required initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much faster. Usage example: uLong adler = adler32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { adler = adler32(adler, buffer, length); } if (adler != original_adler) error(); */ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, z_off_t len2)); /* Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. */ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the updated CRC-32. If buf is NULL, this function returns the required initial value for the for the crc. Pre- and post-conditioning (one's complement) is performed within this function so it shouldn't be done by the application. Usage example: uLong crc = crc32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { crc = crc32(crc, buffer, length); } if (crc != original_crc) error(); */ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); /* Combine two CRC-32 check values into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and len2. */ /* various hacks, don't look :) */ /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, const char *version, int stream_size)); ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, unsigned char FAR *window, const char *version, int stream_size)); #define deflateInit(strm, level) \ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) #define inflateInit(strm) \ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ (strategy), ZLIB_VERSION, sizeof(z_stream)) #define inflateInit2(strm, windowBits) \ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) #define inflateBackInit(strm, windowBits, window) \ inflateBackInit_((strm), (windowBits), (window), \ ZLIB_VERSION, sizeof(z_stream)) #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) struct internal_state {int dummy;}; /* hack for buggy compilers */ #endif ZEXTERN const char * ZEXPORT zError OF((int)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); #ifdef __cplusplus } #endif #endif /* ZLIB_H */ tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/inffast.c0000644000175000017500000003112611300022650021572 0ustar salvisalvi/* inffast.c -- fast decoding * Copyright (C) 1995-2004 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" #ifndef ASMINF /* Allow machine dependent optimization for post-increment or pre-increment. Based on testing to date, Pre-increment preferred for: - PowerPC G3 (Adler) - MIPS R5000 (Randers-Pehrson) Post-increment preferred for: - none No measurable difference: - Pentium III (Anderson) - M68060 (Nikl) */ #ifdef POSTINC # define OFF 0 # define PUP(a) *(a)++ #else # define OFF 1 # define PUP(a) *++(a) #endif /* Decode literal, length, and distance codes and write out the resulting literal and match bytes until either not enough input or output is available, an end-of-block is encountered, or a data error is encountered. When large enough input and output buffers are supplied to inflate(), for example, a 16K input buffer and a 64K output buffer, more than 95% of the inflate execution time is spent in this routine. Entry assumptions: state->mode == LEN strm->avail_in >= 6 strm->avail_out >= 258 start >= strm->avail_out state->bits < 8 On return, state->mode is one of: LEN -- ran out of enough output space or enough available input TYPE -- reached end of block code, inflate() to interpret next block BAD -- error in block data Notes: - The maximum input bits used by a length/distance pair is 15 bits for the length code, 5 bits for the length extra, 15 bits for the distance code, and 13 bits for the distance extra. This totals 48 bits, or six bytes. Therefore if strm->avail_in >= 6, then there is enough input to avoid checking for available input while decoding. - The maximum bytes that a single length/distance pair can output is 258 bytes, which is the maximum length that can be coded. inflate_fast() requires strm->avail_out >= 258 for each loop to avoid checking for output space. */ void inflate_fast(strm, start) z_streamp strm; unsigned start; /* inflate()'s starting value for strm->avail_out */ { struct inflate_state FAR *state; unsigned char FAR *in; /* local strm->next_in */ unsigned char FAR *last; /* while in < last, enough input available */ unsigned char FAR *out; /* local strm->next_out */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ unsigned char FAR *end; /* while out < end, enough space available */ #ifdef INFLATE_STRICT unsigned dmax; /* maximum distance from zlib header */ #endif unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned write; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ unsigned long hold; /* local strm->hold */ unsigned bits; /* local strm->bits */ code const FAR *lcode; /* local strm->lencode */ code const FAR *dcode; /* local strm->distcode */ unsigned lmask; /* mask for first level of length codes */ unsigned dmask; /* mask for first level of distance codes */ code this; /* retrieved table entry */ unsigned op; /* code bits, operation, extra bits, or */ /* window position, window bytes to copy */ unsigned len; /* match length, unused bytes */ unsigned dist; /* match distance */ unsigned char FAR *from; /* where to copy match from */ /* copy state to local variables */ state = (struct inflate_state FAR *)strm->state; in = strm->next_in - OFF; last = in + (strm->avail_in - 5); out = strm->next_out - OFF; beg = out - (start - strm->avail_out); end = out + (strm->avail_out - 257); #ifdef INFLATE_STRICT dmax = state->dmax; #endif wsize = state->wsize; whave = state->whave; write = state->write; window = state->window; hold = state->hold; bits = state->bits; lcode = state->lencode; dcode = state->distcode; lmask = (1U << state->lenbits) - 1; dmask = (1U << state->distbits) - 1; /* decode literals and length/distances until end-of-block or not enough input data or output space */ do { if (bits < 15) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; hold += (unsigned long)(PUP(in)) << bits; bits += 8; } this = lcode[hold & lmask]; dolen: op = (unsigned)(this.bits); hold >>= op; bits -= op; op = (unsigned)(this.op); if (op == 0) { /* literal */ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", this.val)); PUP(out) = (unsigned char)(this.val); } else if (op & 16) { /* length base */ len = (unsigned)(this.val); op &= 15; /* number of extra bits */ if (op) { if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; } len += (unsigned)hold & ((1U << op) - 1); hold >>= op; bits -= op; } Tracevv((stderr, "inflate: length %u\n", len)); if (bits < 15) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; hold += (unsigned long)(PUP(in)) << bits; bits += 8; } this = dcode[hold & dmask]; dodist: op = (unsigned)(this.bits); hold >>= op; bits -= op; op = (unsigned)(this.op); if (op & 16) { /* distance base */ dist = (unsigned)(this.val); op &= 15; /* number of extra bits */ if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; } } dist += (unsigned)hold & ((1U << op) - 1); #ifdef INFLATE_STRICT if (dist > dmax) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #endif hold >>= op; bits -= op; Tracevv((stderr, "inflate: distance %u\n", dist)); op = (unsigned)(out - beg); /* max distance in output */ if (dist > op) { /* see if copy from window */ op = dist - op; /* distance back in window */ if (op > whave) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } from = window - OFF; if (write == 0) { /* very common case */ from += wsize - op; if (op < len) { /* some from window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } else if (write < op) { /* wrap around window */ from += wsize + write - op; op -= write; if (op < len) { /* some from end of window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = window - OFF; if (write < len) { /* some from start of window */ op = write; len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } } else { /* contiguous in window */ from += write - op; if (op < len) { /* some from window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } while (len > 2) { PUP(out) = PUP(from); PUP(out) = PUP(from); PUP(out) = PUP(from); len -= 3; } if (len) { PUP(out) = PUP(from); if (len > 1) PUP(out) = PUP(from); } } else { from = out - dist; /* copy direct from output */ do { /* minimum length is three */ PUP(out) = PUP(from); PUP(out) = PUP(from); PUP(out) = PUP(from); len -= 3; } while (len > 2); if (len) { PUP(out) = PUP(from); if (len > 1) PUP(out) = PUP(from); } } } else if ((op & 64) == 0) { /* 2nd level distance code */ this = dcode[this.val + (hold & ((1U << op) - 1))]; goto dodist; } else { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } } else if ((op & 64) == 0) { /* 2nd level length code */ this = lcode[this.val + (hold & ((1U << op) - 1))]; goto dolen; } else if (op & 32) { /* end-of-block */ Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } else { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } } while (in < last && out < end); /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ len = bits >> 3; in -= len; bits -= len << 3; hold &= (1U << bits) - 1; /* update state and return */ strm->next_in = in + OFF; strm->next_out = out + OFF; strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); strm->avail_out = (unsigned)(out < end ? 257 + (end - out) : 257 - (out - end)); state->hold = hold; state->bits = bits; return; } /* inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - Using bit fields for code structure - Different op definition to avoid & for extra bits (do & for table bits) - Three separate decoding do-loops for direct, window, and write == 0 - Special case for distance > 1 copies to do overlapped load and store copy - Explicit branch predictions (based on measured branch probabilities) - Deferring match copy and interspersed it with decoding subsequent codes - Swapping literal/length else - Swapping window/direct else - Larger unrolled copy loops (three is about right) - Moving len -= 3 statement into middle of loop */ #endif /* !ASMINF */ tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/crc32.h0000644000175000017500000007444111300022650021070 0ustar salvisalvi/* crc32.h -- tables for rapid CRC calculation * Generated automatically by crc32.c */ local const unsigned long FAR crc_table[TBLS][256] = { { 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, 0x2d02ef8dUL #ifdef BYFOUR }, { 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, 0x9324fd72UL }, { 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, 0xbe9834edUL }, { 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, 0xde0506f1UL }, { 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, 0x8def022dUL }, { 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, 0x72fd2493UL }, { 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, 0xed3498beUL }, { 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, 0xf10605deUL #endif } }; tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/uncompr.c0000644000175000017500000000414411300022650021623 0ustar salvisalvi/* uncompr.c -- decompress a memory buffer * Copyright (C) 1995-2003 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #define ZLIB_INTERNAL #include "zlib.h" /* =========================================================================== Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the compressed buffer. This function can be used to decompress a whole file at once if the input file is mmap'ed. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted. */ int ZEXPORT uncompress (dest, destLen, source, sourceLen) Bytef *dest; uLongf *destLen; const Bytef *source; uLong sourceLen; { z_stream stream; int err; stream.next_in = (Bytef*)source; stream.avail_in = (uInt)sourceLen; /* Check for source > 64K on 16-bit machine: */ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; stream.next_out = dest; stream.avail_out = (uInt)*destLen; if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; err = inflateInit(&stream); if (err != Z_OK) return err; err = inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { inflateEnd(&stream); if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) return Z_DATA_ERROR; return err; } *destLen = stream.total_out; err = inflateEnd(&stream); return err; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/zconf.h0000644000175000017500000002704411300022650021270 0ustar salvisalvi/* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-2005 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #ifndef ZCONF_H #define ZCONF_H #if _MSC_VER > 1000 #pragma warning (disable : 4131) #pragma warning (disable : 4115) #pragma warning (disable : 4127) #pragma warning (disable : 4100) #pragma warning (disable : 4244) #pragma warning (disable : 4702) #pragma warning (disable : 4206) #endif /* * If you *really* need a unique prefix for all types and library functions, * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. */ #ifdef Z_PREFIX //# define deflateInit zarch_deflateInit # define deflateInit_ zarch_deflateInit_ # define deflate zarch_deflate # define deflateEnd zarch_deflateEnd //# define deflateInit2 zarch_deflateInit2 # define deflateInit2_ zarch_deflateInit2_ # define deflateSetDictionary zarch_deflateSetDictionary # define deflateCopy zarch_deflateCopy # define deflateReset zarch_deflateReset # define deflateParams zarch_deflateParams # define deflateBound zarch_deflateBound # define deflatePrime zarch_deflatePrime # define deflateSetHeader zarch_deflateSetHeader # define deflateTune zarch_deflateTune //# define inflateInit zarch_inflateInit //# define inflateInit2 zarch_inflateInit2 # define inflateInit2_ zarch_inflateInit2_ # define inflateInit_ zarch_inflateInit_ # define inflate zarch_inflate # define inflateEnd zarch_inflateEnd # define inflateSetDictionary zarch_inflateSetDictionary # define inflateSync zarch_inflateSync # define inflateSyncPoint zarch_inflateSyncPoint # define inflateCopy zarch_inflateCopy # define inflateReset zarch_inflateReset //# define inflateBackInit zarch_inflateBackInit # define inflateBackInit_ zarch_inflateBackInit_ # define inflateBack zarch_inflateBack # define inflateBackEnd zarch_inflateBackEnd # define inflatePrime zarch_inflatePrime # define inflateGetHeader zarch_inflateGetHeader # define compress zarch_compress # define compress2 zarch_compress2 # define compressBound zarch_compressBound # define uncompress zarch_uncompress # define adler32 zarch_adler32 # define adler32_combine zarch_adler32_combine # define crc32_combine zarch_crc32_combine # define deflate_copyright zarch_deflate_copyright # define inflate_copyright zarch_inflate_copyright # define crc32 zarch_crc32 # define get_crc_table zarch_get_crc_table # define zError zarch_zError # define z_stream zarch_z_stream # define z_stream_s zarch_z_stream_s # define alloc_func zarch_alloc_func # define free_func zarch_free_func # define in_func zarch_in_func # define out_func zarch_out_func # define Byte zarch_Byte # define uInt zarch_uInt # define uLong zarch_uLong # define uLongLong zarch_uLongLong # define Bytef zarch_Bytef # define charf zarch_charf # define intf zarch_intf # define uIntf zarch_uIntf # define uLongf zarch_uLongf # define voidpf zarch_voidpf # define voidp zarch_voidp # define deflate_state zarch_deflate_state # define deflate_slow zarch_deflate_slow # define deflate_fast zarch_deflate_fast # define deflate_stored zarch_deflate_stored # define z_streamp zarch_z_streamp # define deflate_rle zarch_deflate_rle # define inflate_state zarch_inflate_state # define inflate_fast zarch_inflate_fast # define inflate_table zarch_inflate_table # define updatewindow zarch_updatewindow //# define inflate_mode zarch_inflate_mode //# define send_bits zarch_send_bits # define zlibVersion zarch_zlibVersion # define zlibCompileFlags zarch_zlibCompileFlags # define zError zarch_zError # define _tr_init zarch_tr_init # define _tr_tally zarch_tr_tally # define _tr_flush_block zarch_tr_flush_block # define _tr_align zarch_tr_align # define _tr_stored_block zarch_tr_stored_block # define _dist_code zarch_dist_code # define _length_code zarch_length_code #endif #if defined(__MSDOS__) && !defined(MSDOS) # define MSDOS #endif #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) # define OS2 #endif #if defined(_WINDOWS) && !defined(WINDOWS) # define WINDOWS #endif #if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) # ifndef WIN32 # define WIN32 # endif #endif #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) # ifndef SYS16BIT # define SYS16BIT # endif # endif #endif /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). */ #ifdef SYS16BIT # define MAXSEG_64K #endif #ifdef MSDOS # define UNALIGNED_OK #endif #ifdef __STDC_VERSION__ # ifndef STDC # define STDC # endif # if __STDC_VERSION__ >= 199901L # ifndef STDC99 # define STDC99 # endif # endif #endif #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) # define STDC #endif #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) # define STDC #endif #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) # define STDC #endif #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) # define STDC #endif #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ # define STDC #endif #ifndef STDC # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # define const /* note: need a more gentle solution here */ # endif #endif /* Some Mac compilers merge all .h files incorrectly: */ #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) # define NO_DUMMY_DECL #endif /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL # ifdef MAXSEG_64K # define MAX_MEM_LEVEL 8 # else # define MAX_MEM_LEVEL 9 # endif #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2. * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files * created by gzip. (Files created by minigzip can still be extracted by * gzip.) */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. */ /* Type declarations */ #ifndef OF /* function prototypes */ # ifdef STDC # define OF(args) args # else # define OF(args) () # endif #endif /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * just define FAR to be empty. */ #ifdef SYS16BIT # if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */ # define SMALL_MEDIUM # ifdef _MSC_VER # define FAR _far # else # define FAR far # endif # endif # if (defined(__SMALL__) || defined(__MEDIUM__)) /* Turbo C small or medium model */ # define SMALL_MEDIUM # ifdef __BORLANDC__ # define FAR _far # else # define FAR far # endif # endif #endif #if defined(WINDOWS) || defined(WIN32) /* If building or using zlib as a DLL, define ZLIB_DLL. * This is not mandatory, but it offers a little performance increase. */ # ifdef ZLIB_DLL # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) # ifdef ZLIB_INTERNAL # define ZEXTERN extern __declspec(dllexport) # else # define ZEXTERN extern __declspec(dllimport) # endif # endif # endif /* ZLIB_DLL */ /* If building or using zlib with the WINAPI/WINAPIV calling convention, * define ZLIB_WINAPI. * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. */ # ifdef ZLIB_WINAPI # ifdef FAR # undef FAR # endif # include /* No need for _export, use ZLIB.DEF instead. */ /* For complete Windows compatibility, use WINAPI, not __stdcall. */ # define ZEXPORT WINAPI # ifdef WIN32 # define ZEXPORTVA WINAPIV # else # define ZEXPORTVA FAR CDECL # endif # endif #endif #if defined (__BEOS__) # ifdef ZLIB_DLL # ifdef ZLIB_INTERNAL # define ZEXPORT __declspec(dllexport) # define ZEXPORTVA __declspec(dllexport) # else # define ZEXPORT __declspec(dllimport) # define ZEXPORTVA __declspec(dllimport) # endif # endif #endif #ifndef ZEXTERN # define ZEXTERN extern #endif #ifndef ZEXPORT # define ZEXPORT #endif #ifndef ZEXPORTVA # define ZEXPORTVA #endif #ifndef FAR # define FAR #endif #if !defined(__MACTYPES__) typedef unsigned char Byte; /* 8 bits */ #endif typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ #include "../_features.h" #ifdef _ZIP64 typedef unsigned __int64 uLongLong; #else typedef unsigned long uLongLong; #endif #ifdef SMALL_MEDIUM /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ # define Bytef Byte FAR #else typedef Byte FAR Bytef; #endif typedef char FAR charf; typedef int FAR intf; typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC typedef void const *voidpc; typedef void FAR *voidpf; typedef void *voidp; #else typedef Byte const *voidpc; typedef Byte FAR *voidpf; typedef Byte *voidp; #endif #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ # include /* for off_t */ # include /* for SEEK_* and off_t */ # ifdef VMS # include /* for off_t */ # endif # define z_off_t off_t #endif #ifndef SEEK_SET # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif #ifndef z_off_t # define z_off_t long #endif #if defined(__OS400__) #define NO_vsnprintf #endif #if defined(__MVS__) # define NO_vsnprintf # ifdef FAR # undef FAR # endif #endif /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) # pragma map(deflateInit_,"DEIN") # pragma map(deflateInit2_,"DEIN2") # pragma map(deflateEnd,"DEEND") # pragma map(deflateBound,"DEBND") # pragma map(inflateInit_,"ININ") # pragma map(inflateInit2_,"ININ2") # pragma map(inflateEnd,"INEND") # pragma map(inflateSync,"INSY") # pragma map(inflateSetDictionary,"INSEDI") # pragma map(compressBound,"CMBND") # pragma map(inflate_table,"INTABL") # pragma map(inflate_fast,"INFA") # pragma map(inflate_copyright,"INCOPY") #endif #endif /* ZCONF_H */ tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/inftrees.h0000644000175000017500000000457411300022650021773 0ustar salvisalvi/* inftrees.h -- header to use inftrees.c * Copyright (C) 1995-2005 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* Structure for decoding tables. Each entry provides either the information needed to do the operation requested by the code that indexed that table entry, or it provides a pointer to another table that indexes more bits of the code. op indicates whether the entry is a pointer to another table, a literal, a length or distance, an end-of-block, or an invalid code. For a table pointer, the low four bits of op is the number of index bits of that table. For a length or distance, the low four bits of op is the number of extra bits to get after the code. bits is the number of bits in this code or part of the code to drop off of the bit buffer. val is the actual byte to output in the case of a literal, the base length or distance, or the offset from the current table to the next table. Each entry is four bytes. */ typedef struct { unsigned char op; /* operation, extra bits, table bits */ unsigned char bits; /* bits in this part of the code */ unsigned short val; /* offset in table or code value */ } code; /* op values as set by inflate_table(): 00000000 - literal 0000tttt - table link, tttt != 0 is the number of table index bits 0001eeee - length or distance, eeee is the number of extra bits 01100000 - end of block 01000000 - invalid code */ /* Maximum size of dynamic tree. The maximum found in a long but non- exhaustive search was 1444 code structures (852 for length/literals and 592 for distances, the latter actually the result of an exhaustive search). The true maximum is not known, but the value below is more than safe. */ #define ENOUGH 2048 #define MAXD 592 /* Type of code to build for inftable() */ typedef enum { CODES, LENS, DISTS } codetype; extern int inflate_table OF((codetype type, unsigned short FAR *lens, unsigned codes, code FAR * FAR *table, unsigned FAR *bits, unsigned short FAR *work)); tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/infback.c0000644000175000017500000005440311300022650021540 0ustar salvisalvi/* infback.c -- inflate using a call-back interface * Copyright (C) 1995-2005 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* This code is largely copied from inflate.c. Normally either infback.o or inflate.o would be linked into an application--not both. The interface with inffast.c is retained so that optimized assembler-coded versions of inflate_fast() can be used with either inflate.c or infback.c. */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" /* function prototypes */ local void fixedtables OF((struct inflate_state FAR *state)); /* strm provides memory allocation functions in zalloc and zfree, or Z_NULL to use the library memory allocation functions. windowBits is in the range 8..15, and window is a user-supplied window and output buffer that is 2**windowBits bytes. */ int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) z_streamp strm; int windowBits; unsigned char FAR *window; const char *version; int stream_size; { struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) return Z_VERSION_ERROR; if (strm == Z_NULL || window == Z_NULL || windowBits < 8 || windowBits > 15) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { strm->zalloc = zcalloc; strm->opaque = (voidpf)0; } if (strm->zfree == (free_func)0) strm->zfree = zcfree; state = (struct inflate_state FAR *)ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; state->dmax = 32768U; state->wbits = windowBits; state->wsize = 1U << windowBits; state->window = window; state->write = 0; state->whave = 0; return Z_OK; } /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. If BUILDFIXED is defined, then instead this routine builds the tables the first time it's called, and returns those tables the first time and thereafter. This reduces the size of the code by about 2K bytes, in exchange for a little execution time. However, BUILDFIXED should not be used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ local void fixedtables(state) struct inflate_state FAR *state; { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; static code fixed[544]; /* build fixed huffman tables if first call (may not be thread safe) */ if (virgin) { unsigned sym, bits; static code *next; /* literal/length table */ sym = 0; while (sym < 144) state->lens[sym++] = 8; while (sym < 256) state->lens[sym++] = 9; while (sym < 280) state->lens[sym++] = 7; while (sym < 288) state->lens[sym++] = 8; next = fixed; lenfix = next; bits = 9; inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); /* distance table */ sym = 0; while (sym < 32) state->lens[sym++] = 5; distfix = next; bits = 5; inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); /* do this just once */ virgin = 0; } #else /* !BUILDFIXED */ # include "inffixed.h" #endif /* BUILDFIXED */ state->lencode = lenfix; state->lenbits = 9; state->distcode = distfix; state->distbits = 5; } /* Macros for inflateBack(): */ /* Load returned state from inflate_fast() */ #define LOAD() \ do { \ put = strm->next_out; \ left = strm->avail_out; \ next = strm->next_in; \ have = strm->avail_in; \ hold = state->hold; \ bits = state->bits; \ } while (0) /* Set state from registers for inflate_fast() */ #define RESTORE() \ do { \ strm->next_out = put; \ strm->avail_out = left; \ strm->next_in = next; \ strm->avail_in = have; \ state->hold = hold; \ state->bits = bits; \ } while (0) /* Clear the input bit accumulator */ #define INITBITS() \ do { \ hold = 0; \ bits = 0; \ } while (0) /* Assure that some input is available. If input is requested, but denied, then return a Z_BUF_ERROR from inflateBack(). */ #define PULL() \ do { \ if (have == 0) { \ have = in(in_desc, &next); \ if (have == 0) { \ next = Z_NULL; \ ret = Z_BUF_ERROR; \ goto inf_leave; \ } \ } \ } while (0) /* Get a byte of input into the bit accumulator, or return from inflateBack() with an error if there is no input available. */ #define PULLBYTE() \ do { \ PULL(); \ have--; \ hold += (unsigned long)(*next++) << bits; \ bits += 8; \ } while (0) /* Assure that there are at least n bits in the bit accumulator. If there is not enough available input to do that, then return from inflateBack() with an error. */ #define NEEDBITS(n) \ do { \ while (bits < (unsigned)(n)) \ PULLBYTE(); \ } while (0) /* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \ ((unsigned)hold & ((1U << (n)) - 1)) /* Remove n bits from the bit accumulator */ #define DROPBITS(n) \ do { \ hold >>= (n); \ bits -= (unsigned)(n); \ } while (0) /* Remove zero to seven bits as needed to go to a byte boundary */ #define BYTEBITS() \ do { \ hold >>= bits & 7; \ bits -= bits & 7; \ } while (0) /* Assure that some output space is available, by writing out the window if it's full. If the write fails, return from inflateBack() with a Z_BUF_ERROR. */ #define ROOM() \ do { \ if (left == 0) { \ put = state->window; \ left = state->wsize; \ state->whave = left; \ if (out(out_desc, put, left)) { \ ret = Z_BUF_ERROR; \ goto inf_leave; \ } \ } \ } while (0) /* strm provides the memory allocation functions and window buffer on input, and provides information on the unused input on return. For Z_DATA_ERROR returns, strm will also provide an error message. in() and out() are the call-back input and output functions. When inflateBack() needs more input, it calls in(). When inflateBack() has filled the window with output, or when it completes with data in the window, it calls out() to write out the data. The application must not change the provided input until in() is called again or inflateBack() returns. The application must not change the window/output buffer until inflateBack() returns. in() and out() are called with a descriptor parameter provided in the inflateBack() call. This parameter can be a structure that provides the information required to do the read or write, as well as accumulated information on the input and output such as totals and check values. in() should return zero on failure. out() should return non-zero on failure. If either in() or out() fails, than inflateBack() returns a Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it was in() or out() that caused in the error. Otherwise, inflateBack() returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format error, or Z_MEM_ERROR if it could not allocate memory for the state. inflateBack() can also return Z_STREAM_ERROR if the input parameters are not correct, i.e. strm is Z_NULL or the state was not initialized. */ int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) z_streamp strm; in_func in; void FAR *in_desc; out_func out; void FAR *out_desc; { struct inflate_state FAR *state; unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ unsigned bits; /* bits in bit buffer */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ code this; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* Check that the strm exists and that the state was initialized */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* Reset the state */ strm->msg = Z_NULL; state->mode = TYPE; state->last = 0; state->whave = 0; next = strm->next_in; have = next != Z_NULL ? strm->avail_in : 0; hold = 0; bits = 0; put = state->window; left = state->wsize; /* Inflate until end of block marked as last */ for (;;) switch (state->mode) { case TYPE: /* determine and dispatch block type */ if (state->last) { BYTEBITS(); state->mode = DONE; break; } NEEDBITS(3); state->last = BITS(1); DROPBITS(1); switch (BITS(2)) { case 0: /* stored block */ Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); state->mode = STORED; break; case 1: /* fixed block */ fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN; /* decode codes */ break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); state->mode = TABLE; break; case 3: strm->msg = (char *)"invalid block type"; state->mode = BAD; } DROPBITS(2); break; case STORED: /* get and verify stored block length */ BYTEBITS(); /* go to byte boundary */ NEEDBITS(32); if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { strm->msg = (char *)"invalid stored block lengths"; state->mode = BAD; break; } state->length = (unsigned)hold & 0xffff; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); /* copy stored block from input to output */ while (state->length != 0) { copy = state->length; PULL(); ROOM(); if (copy > have) copy = have; if (copy > left) copy = left; zmemcpy(put, next, copy); have -= copy; next += copy; left -= copy; put += copy; state->length -= copy; } Tracev((stderr, "inflate: stored end\n")); state->mode = TYPE; break; case TABLE: /* get dynamic table entries descriptor */ NEEDBITS(14); state->nlen = BITS(5) + 257; DROPBITS(5); state->ndist = BITS(5) + 1; DROPBITS(5); state->ncode = BITS(4) + 4; DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND if (state->nlen > 286 || state->ndist > 30) { strm->msg = (char *)"too many length or distance symbols"; state->mode = BAD; break; } #endif Tracev((stderr, "inflate: table sizes ok\n")); /* get code length code lengths (not a typo) */ state->have = 0; while (state->have < state->ncode) { NEEDBITS(3); state->lens[order[state->have++]] = (unsigned short)BITS(3); DROPBITS(3); } while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid code lengths set"; state->mode = BAD; break; } Tracev((stderr, "inflate: code lengths ok\n")); /* get length and distance code code lengths */ state->have = 0; while (state->have < state->nlen + state->ndist) { for (;;) { this = state->lencode[BITS(state->lenbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if (this.val < 16) { NEEDBITS(this.bits); DROPBITS(this.bits); state->lens[state->have++] = this.val; } else { if (this.val == 16) { NEEDBITS(this.bits + 2); DROPBITS(this.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } len = (unsigned)(state->lens[state->have - 1]); copy = 3 + BITS(2); DROPBITS(2); } else if (this.val == 17) { NEEDBITS(this.bits + 3); DROPBITS(this.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { NEEDBITS(this.bits + 7); DROPBITS(this.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); } if (state->have + copy > state->nlen + state->ndist) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } while (copy--) state->lens[state->have++] = (unsigned short)len; } } /* handle error breaks in while */ if (state->mode == BAD) break; /* build code tables */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid literal/lengths set"; state->mode = BAD; break; } state->distcode = (code const FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); if (ret) { strm->msg = (char *)"invalid distances set"; state->mode = BAD; break; } Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN; case LEN: /* use inflate_fast() if we have enough input and output */ if (have >= 6 && left >= 258) { RESTORE(); if (state->whave < state->wsize) state->whave = state->wsize - left; inflate_fast(strm, state->wsize); LOAD(); break; } /* get a literal, length, or end-of-block code */ for (;;) { this = state->lencode[BITS(state->lenbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if (this.op && (this.op & 0xf0) == 0) { last = this; for (;;) { this = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + this.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(this.bits); state->length = (unsigned)this.val; /* process literal */ if (this.op == 0) { Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", this.val)); ROOM(); *put++ = (unsigned char)(state->length); left--; state->mode = LEN; break; } /* process end of block */ if (this.op & 32) { Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } /* invalid code */ if (this.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } /* length code -- get extra bits, if any */ state->extra = (unsigned)(this.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); } Tracevv((stderr, "inflate: length %u\n", state->length)); /* get distance code */ for (;;) { this = state->distcode[BITS(state->distbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if ((this.op & 0xf0) == 0) { last = this; for (;;) { this = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + this.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(this.bits); if (this.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } state->offset = (unsigned)this.val; /* get distance extra bits, if any */ state->extra = (unsigned)(this.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); } if (state->offset > state->wsize - (state->whave < state->wsize ? left : 0)) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } Tracevv((stderr, "inflate: distance %u\n", state->offset)); /* copy match from window to output */ do { ROOM(); copy = state->wsize - state->offset; if (copy < left) { from = put + copy; copy = left - copy; } else { from = put - state->offset; copy = left; } if (copy > state->length) copy = state->length; state->length -= copy; left -= copy; do { *put++ = *from++; } while (--copy); } while (state->length != 0); break; case DONE: /* inflate stream terminated properly -- write leftover output */ ret = Z_STREAM_END; if (left < state->wsize) { if (out(out_desc, state->window, state->wsize - left)) ret = Z_BUF_ERROR; } goto inf_leave; case BAD: ret = Z_DATA_ERROR; goto inf_leave; default: /* can't happen, but makes compilers happy */ ret = Z_STREAM_ERROR; goto inf_leave; } /* Return unused input */ inf_leave: strm->next_in = next; strm->avail_in = have; return ret; } int ZEXPORT inflateBackEnd(strm) z_streamp strm; { if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; ZFREE(strm, strm->state); strm->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/trees.h0000644000175000017500000002057411300022650021274 0ustar salvisalvi/* header created automatically with -DGEN_TREES_H */ local const ct_data static_ltree[L_CODES+2] = { {{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, {{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, {{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, {{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, {{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, {{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, {{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, {{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, {{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, {{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, {{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, {{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, {{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, {{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, {{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, {{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, {{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, {{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, {{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, {{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, {{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, {{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, {{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, {{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, {{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, {{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, {{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, {{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, {{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, {{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, {{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, {{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, {{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, {{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, {{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, {{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, {{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, {{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, {{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, {{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, {{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, {{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, {{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, {{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, {{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, {{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, {{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, {{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, {{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, {{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, {{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, {{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, {{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, {{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, {{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, {{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, {{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, {{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} }; local const ct_data static_dtree[D_CODES] = { {{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, {{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, {{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, {{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, {{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, {{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} }; const uch _dist_code[DIST_CODE_LEN] = { 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 }; const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 }; local const int base_length[LENGTH_CODES] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 }; local const int base_dist[D_CODES] = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 }; tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/deflate.c0000644000175000017500000020055311300022650021546 0ustar salvisalvi/* deflate.c -- compress data using the deflation algorithm * Copyright (C) 1995-2005 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process depends on being able to identify portions * of the input text which are identical to earlier input (within a * sliding window trailing behind the input currently being processed). * * The most straightforward technique turns out to be the fastest for * most input files: try all possible matches and select the longest. * The key feature of this algorithm is that insertions into the string * dictionary are very simple and thus fast, and deletions are avoided * completely. Insertions are performed at each input character, whereas * string matches are performed only when the previous match ends. So it * is preferable to spend more time in matches to allow very fast string * insertions and avoid deletions. The matching algorithm for small * strings is inspired from that of Rabin & Karp. A brute force approach * is used to find longer strings when a small match has been found. * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze * (by Leonid Broukhis). * A previous version of this file used a more sophisticated algorithm * (by Fiala and Greene) which is guaranteed to run in linear amortized * time, but has a larger average cost, uses more memory and is patented. * However the F&G algorithm may be faster for some highly redundant * files if the parameter max_chain_length (described below) is too large. * * ACKNOWLEDGEMENTS * * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and * I found it in 'freeze' written by Leonid Broukhis. * Thanks to many people for bug reports and testing. * * REFERENCES * * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". * Available in http://www.ietf.org/rfc/rfc1951.txt * * A description of the Rabin and Karp algorithm is given in the book * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. * * Fiala,E.R., and Greene,D.H. * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 * */ /* @(#) $Id$ */ #include "deflate.h" const char deflate_copyright[] = " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ /* =========================================================================== * Function prototypes. */ typedef enum { need_more, /* block not completed, need more input or more output */ block_done, /* block flush performed */ finish_started, /* finish started, need only more output at next deflate */ finish_done /* finish done, accept no more input or output */ } block_state; typedef block_state (*compress_func) OF((deflate_state *s, int flush)); /* Compression function. Returns the block state after the call. */ local void fill_window OF((deflate_state *s)); local block_state deflate_stored OF((deflate_state *s, int flush)); local block_state deflate_fast OF((deflate_state *s, int flush)); #ifndef FASTEST local block_state deflate_slow OF((deflate_state *s, int flush)); #endif local void lm_init OF((deflate_state *s)); local void putShortMSB OF((deflate_state *s, uInt b)); local void flush_pending OF((z_streamp strm)); local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); #ifndef FASTEST #ifdef ASMV void match_init OF((void)); /* asm code initialization */ uInt longest_match OF((deflate_state *s, IPos cur_match)); #else local uInt longest_match OF((deflate_state *s, IPos cur_match)); #endif #endif local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); #ifdef DEBUG local void check_match OF((deflate_state *s, IPos start, IPos match, int length)); #endif /* =========================================================================== * Local data */ #define NIL 0 /* Tail of hash chains */ #ifndef TOO_FAR # define TOO_FAR 4096 #endif /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ /* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be * found for specific files. */ typedef struct config_s { ush good_length; /* reduce lazy search above this match length */ ush max_lazy; /* do not perform lazy search above this match length */ ush nice_length; /* quit search above this match length */ ush max_chain; compress_func func; } config; #ifdef FASTEST local const config configuration_table[2] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ #else local const config configuration_table[10] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ /* 2 */ {4, 5, 16, 8, deflate_fast}, /* 3 */ {4, 6, 32, 32, deflate_fast}, /* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ /* 5 */ {8, 16, 32, 32, deflate_slow}, /* 6 */ {8, 16, 128, 128, deflate_slow}, /* 7 */ {8, 32, 128, 256, deflate_slow}, /* 8 */ {32, 128, 258, 1024, deflate_slow}, /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ #endif /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different * meaning. */ #define EQUAL 0 /* result of memcmp for equal strings */ #ifndef NO_DUMMY_DECL struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ #endif /* =========================================================================== * Update a hash value with the given input byte * IN assertion: all calls to to UPDATE_HASH are made with consecutive * input characters, so that a running hash key can be computed from the * previous key instead of complete recalculation each time. */ #define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) /* =========================================================================== * Insert string str in the dictionary and set match_head to the previous head * of the hash chain (the most recent string with same hash key). Return * the previous length of the hash chain. * If this file is compiled with -DFASTEST, the compression level is forced * to 1, and no hash chains are maintained. * IN assertion: all calls to to INSERT_STRING are made with consecutive * input characters and the first MIN_MATCH bytes of str are valid * (except for the last MIN_MATCH-1 bytes of the input file). */ #ifdef FASTEST #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ match_head = s->head[s->ins_h], \ s->head[s->ins_h] = (Pos)(str)) #else #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ s->head[s->ins_h] = (Pos)(str)) #endif /* =========================================================================== * Initialize the hash table (avoiding 64K overflow for 16 bit systems). * prev[] will be initialized on the fly. */ #define CLEAR_HASH(s) \ s->head[s->hash_size-1] = NIL; \ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); /* ========================================================================= */ int ZEXPORT deflateInit_(strm, level, version, stream_size) z_streamp strm; int level; const char *version; int stream_size; { return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size); /* To do: ignore strm->next_in if we use it as window */ } /* ========================================================================= */ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, version, stream_size) z_streamp strm; int level; int method; int windowBits; int memLevel; int strategy; const char *version; int stream_size; { deflate_state *s; int wrap = 1; static const char my_version[] = ZLIB_VERSION; ushf *overlay; /* We overlay pending_buf and d_buf+l_buf. This works since the average * output size for (length,distance) codes is <= 24 bits. */ if (version == Z_NULL || version[0] != my_version[0] || stream_size != sizeof(z_stream)) { return Z_VERSION_ERROR; } if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; if (strm->zalloc == (alloc_func)0) { strm->zalloc = zcalloc; strm->opaque = (voidpf)0; } if (strm->zfree == (free_func)0) strm->zfree = zcfree; #ifdef FASTEST if (level != 0) level = 1; #else if (level == Z_DEFAULT_COMPRESSION) level = 6; #endif if (windowBits < 0) { /* suppress zlib wrapper */ wrap = 0; windowBits = -windowBits; } #ifdef GZIP else if (windowBits > 15) { wrap = 2; /* write gzip wrapper instead */ windowBits -= 16; } #endif if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { return Z_STREAM_ERROR; } if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); if (s == Z_NULL) return Z_MEM_ERROR; strm->state = (struct internal_state FAR *)s; s->strm = strm; s->wrap = wrap; s->gzhead = Z_NULL; s->w_bits = windowBits; s->w_size = 1 << s->w_bits; s->w_mask = s->w_size - 1; s->hash_bits = memLevel + 7; s->hash_size = 1 << s->hash_bits; s->hash_mask = s->hash_size - 1; s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); s->pending_buf = (uchf *) overlay; s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || s->pending_buf == Z_NULL) { s->status = FINISH_STATE; strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); deflateEnd (strm); return Z_MEM_ERROR; } s->d_buf = overlay + s->lit_bufsize/sizeof(ush); s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; s->level = level; s->strategy = strategy; s->method = (Byte)method; return deflateReset(strm); } /* ========================================================================= */ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; uInt dictLength; { deflate_state *s; uInt length = dictLength; uInt n; IPos hash_head = 0; if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || strm->state->wrap == 2 || (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) return Z_STREAM_ERROR; s = strm->state; if (s->wrap) strm->adler = adler32(strm->adler, dictionary, dictLength); if (length < MIN_MATCH) return Z_OK; if (length > MAX_DIST(s)) { length = MAX_DIST(s); dictionary += dictLength - length; /* use the tail of the dictionary */ } zmemcpy(s->window, dictionary, length); s->strstart = length; s->block_start = (long)length; /* Insert all strings in the hash table (except for the last two bytes). * s->lookahead stays null, so s->ins_h will be recomputed at the next * call of fill_window. */ s->ins_h = s->window[0]; UPDATE_HASH(s, s->ins_h, s->window[1]); for (n = 0; n <= length - MIN_MATCH; n++) { INSERT_STRING(s, n, hash_head); } if (hash_head) hash_head = 0; /* to make compiler happy */ return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateReset (strm) z_streamp strm; { deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { return Z_STREAM_ERROR; } strm->total_in = strm->total_out = 0; strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ strm->data_type = Z_UNKNOWN; s = (deflate_state *)strm->state; s->pending = 0; s->pending_out = s->pending_buf; if (s->wrap < 0) { s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ } s->status = s->wrap ? INIT_STATE : BUSY_STATE; strm->adler = #ifdef GZIP s->wrap == 2 ? crc32(0L, Z_NULL, 0) : #endif adler32(0L, Z_NULL, 0); s->last_flush = Z_NO_FLUSH; _tr_init(s); lm_init(s); return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateSetHeader (strm, head) z_streamp strm; gz_headerp head; { if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (strm->state->wrap != 2) return Z_STREAM_ERROR; strm->state->gzhead = head; return Z_OK; } /* ========================================================================= */ int ZEXPORT deflatePrime (strm, bits, value) z_streamp strm; int bits; int value; { if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; strm->state->bi_valid = bits; strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateParams(strm, level, strategy) z_streamp strm; int level; int strategy; { deflate_state *s; compress_func func; int err = Z_OK; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; s = strm->state; #ifdef FASTEST if (level != 0) level = 1; #else if (level == Z_DEFAULT_COMPRESSION) level = 6; #endif if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { return Z_STREAM_ERROR; } func = configuration_table[s->level].func; if (func != configuration_table[level].func && strm->total_in != 0) { /* Flush the last buffer: */ err = deflate(strm, Z_PARTIAL_FLUSH); } if (s->level != level) { s->level = level; s->max_lazy_match = configuration_table[level].max_lazy; s->good_match = configuration_table[level].good_length; s->nice_match = configuration_table[level].nice_length; s->max_chain_length = configuration_table[level].max_chain; } s->strategy = strategy; return err; } /* ========================================================================= */ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) z_streamp strm; int good_length; int max_lazy; int nice_length; int max_chain; { deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; s = strm->state; s->good_match = good_length; s->max_lazy_match = max_lazy; s->nice_match = nice_length; s->max_chain_length = max_chain; return Z_OK; } /* ========================================================================= * For the default windowBits of 15 and memLevel of 8, this function returns * a close to exact, as well as small, upper bound on the compressed size. * They are coded as constants here for a reason--if the #define's are * changed, then this function needs to be changed as well. The return * value for 15 and 8 only works for those exact settings. * * For any setting other than those defaults for windowBits and memLevel, * the value returned is a conservative worst case for the maximum expansion * resulting from using fixed blocks instead of stored blocks, which deflate * can emit on compressed data for some combinations of the parameters. * * This function could be more sophisticated to provide closer upper bounds * for every combination of windowBits and memLevel, as well as wrap. * But even the conservative upper bound of about 14% expansion does not * seem onerous for output buffer allocation. */ uLong ZEXPORT deflateBound(strm, sourceLen) z_streamp strm; uLong sourceLen; { deflate_state *s; uLong destLen; /* conservative upper bound */ destLen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; /* if can't get parameters, return conservative bound */ if (strm == Z_NULL || strm->state == Z_NULL) return destLen; /* if not default parameters, return conservative bound */ s = strm->state; if (s->w_bits != 15 || s->hash_bits != 8 + 7) return destLen; /* default settings: return tight bound for that case */ return compressBound(sourceLen); } /* ========================================================================= * Put a short in the pending buffer. The 16-bit value is put in MSB order. * IN assertion: the stream state is correct and there is enough room in * pending_buf. */ local void putShortMSB (s, b) deflate_state *s; uInt b; { put_byte(s, (Byte)(b >> 8)); put_byte(s, (Byte)(b & 0xff)); } /* ========================================================================= * Flush as much pending output as possible. All deflate() output goes * through this function so some applications may wish to modify it * to avoid allocating a large strm->next_out buffer and copying into it. * (See also read_buf()). */ local void flush_pending(strm) z_streamp strm; { unsigned len = strm->state->pending; if (len > strm->avail_out) len = strm->avail_out; if (len == 0) return; zmemcpy(strm->next_out, strm->state->pending_out, len); strm->next_out += len; strm->state->pending_out += len; strm->total_out += len; strm->avail_out -= len; strm->state->pending -= len; if (strm->state->pending == 0) { strm->state->pending_out = strm->state->pending_buf; } } /* ========================================================================= */ int ZEXPORT deflate (strm, flush) z_streamp strm; int flush; { int old_flush; /* value of flush param for previous deflate call */ deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL || flush > Z_FINISH || flush < 0) { return Z_STREAM_ERROR; } s = strm->state; if (strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0) || (s->status == FINISH_STATE && flush != Z_FINISH)) { ERR_RETURN(strm, Z_STREAM_ERROR); } if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); s->strm = strm; /* just in case */ old_flush = s->last_flush; s->last_flush = flush; /* Write the header */ if (s->status == INIT_STATE) { #ifdef GZIP if (s->wrap == 2) { strm->adler = crc32(0L, Z_NULL, 0); put_byte(s, 31); put_byte(s, 139); put_byte(s, 8); if (s->gzhead == NULL) { put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); put_byte(s, OS_CODE); s->status = BUSY_STATE; } else { put_byte(s, (s->gzhead->text ? 1 : 0) + (s->gzhead->hcrc ? 2 : 0) + (s->gzhead->extra == Z_NULL ? 0 : 4) + (s->gzhead->name == Z_NULL ? 0 : 8) + (s->gzhead->comment == Z_NULL ? 0 : 16) ); put_byte(s, (Byte)(s->gzhead->time & 0xff)); put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); put_byte(s, s->gzhead->os & 0xff); if (s->gzhead->extra != NULL) { put_byte(s, s->gzhead->extra_len & 0xff); put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); } if (s->gzhead->hcrc) strm->adler = crc32(strm->adler, s->pending_buf, s->pending); s->gzindex = 0; s->status = EXTRA_STATE; } } else #endif { uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; uInt level_flags; if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) level_flags = 0; else if (s->level < 6) level_flags = 1; else if (s->level == 6) level_flags = 2; else level_flags = 3; header |= (level_flags << 6); if (s->strstart != 0) header |= PRESET_DICT; header += 31 - (header % 31); s->status = BUSY_STATE; putShortMSB(s, header); /* Save the adler32 of the preset dictionary: */ if (s->strstart != 0) { putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); } strm->adler = adler32(0L, Z_NULL, 0); } } #ifdef GZIP if (s->status == EXTRA_STATE) { if (s->gzhead->extra != NULL) { uInt beg = s->pending; /* start of bytes to update crc */ while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { if (s->pending == s->pending_buf_size) { if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); flush_pending(strm); beg = s->pending; if (s->pending == s->pending_buf_size) break; } put_byte(s, s->gzhead->extra[s->gzindex]); s->gzindex++; } if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); if (s->gzindex == s->gzhead->extra_len) { s->gzindex = 0; s->status = NAME_STATE; } } else s->status = NAME_STATE; } if (s->status == NAME_STATE) { if (s->gzhead->name != NULL) { uInt beg = s->pending; /* start of bytes to update crc */ int val; do { if (s->pending == s->pending_buf_size) { if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); flush_pending(strm); beg = s->pending; if (s->pending == s->pending_buf_size) { val = 1; break; } } val = s->gzhead->name[s->gzindex++]; put_byte(s, val); } while (val != 0); if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); if (val == 0) { s->gzindex = 0; s->status = COMMENT_STATE; } } else s->status = COMMENT_STATE; } if (s->status == COMMENT_STATE) { if (s->gzhead->comment != NULL) { uInt beg = s->pending; /* start of bytes to update crc */ int val; do { if (s->pending == s->pending_buf_size) { if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); flush_pending(strm); beg = s->pending; if (s->pending == s->pending_buf_size) { val = 1; break; } } val = s->gzhead->comment[s->gzindex++]; put_byte(s, val); } while (val != 0); if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); if (val == 0) s->status = HCRC_STATE; } else s->status = HCRC_STATE; } if (s->status == HCRC_STATE) { if (s->gzhead->hcrc) { if (s->pending + 2 > s->pending_buf_size) flush_pending(strm); if (s->pending + 2 <= s->pending_buf_size) { put_byte(s, (Byte)(strm->adler & 0xff)); put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); strm->adler = crc32(0L, Z_NULL, 0); s->status = BUSY_STATE; } } else s->status = BUSY_STATE; } #endif /* Flush as much pending output as possible */ if (s->pending != 0) { flush_pending(strm); if (strm->avail_out == 0) { /* Since avail_out is 0, deflate will be called again with * more output space, but possibly with both pending and * avail_in equal to zero. There won't be anything to do, * but this is not an error situation so make sure we * return OK instead of BUF_ERROR at next call of deflate: */ s->last_flush = -1; return Z_OK; } /* Make sure there is something to do and avoid duplicate consecutive * flushes. For repeated and useless calls with Z_FINISH, we keep * returning Z_STREAM_END instead of Z_BUF_ERROR. */ } else if (strm->avail_in == 0 && flush <= old_flush && flush != Z_FINISH) { ERR_RETURN(strm, Z_BUF_ERROR); } /* User must not provide more input after the first FINISH: */ if (s->status == FINISH_STATE && strm->avail_in != 0) { ERR_RETURN(strm, Z_BUF_ERROR); } /* Start a new block or continue the current one. */ if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; bstate = (*(configuration_table[s->level].func))(s, flush); if (bstate == finish_started || bstate == finish_done) { s->status = FINISH_STATE; } if (bstate == need_more || bstate == finish_started) { if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ } return Z_OK; /* If flush != Z_NO_FLUSH && avail_out == 0, the next call * of deflate should use the same flush parameter to make sure * that the flush is complete. So we don't have to output an * empty block here, this will be done at next call. This also * ensures that for a very small output buffer, we emit at most * one empty block. */ } if (bstate == block_done) { if (flush == Z_PARTIAL_FLUSH) { _tr_align(s); } else { /* FULL_FLUSH or SYNC_FLUSH */ _tr_stored_block(s, (char*)0, 0L, 0); /* For a full flush, this empty block will be recognized * as a special marker by inflate_sync(). */ if (flush == Z_FULL_FLUSH) { CLEAR_HASH(s); /* forget history */ } } flush_pending(strm); if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ return Z_OK; } } } Assert(strm->avail_out > 0, "bug2"); if (flush != Z_FINISH) return Z_OK; if (s->wrap <= 0) return Z_STREAM_END; /* Write the trailer */ #ifdef GZIP if (s->wrap == 2) { put_byte(s, (Byte)(strm->adler & 0xff)); put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); put_byte(s, (Byte)(strm->total_in & 0xff)); put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); } else #endif { putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); } flush_pending(strm); /* If avail_out is zero, the application will call deflate again * to flush the rest. */ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ return s->pending != 0 ? Z_OK : Z_STREAM_END; } /* ========================================================================= */ int ZEXPORT deflateEnd (strm) z_streamp strm; { int status; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; status = strm->state->status; if (status != INIT_STATE && status != EXTRA_STATE && status != NAME_STATE && status != COMMENT_STATE && status != HCRC_STATE && status != BUSY_STATE && status != FINISH_STATE) { return Z_STREAM_ERROR; } /* Deallocate in reverse order of allocations: */ TRY_FREE(strm, strm->state->pending_buf); TRY_FREE(strm, strm->state->head); TRY_FREE(strm, strm->state->prev); TRY_FREE(strm, strm->state->window); ZFREE(strm, strm->state); strm->state = Z_NULL; return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } /* ========================================================================= * Copy the source state to the destination state. * To simplify the source, this is not supported for 16-bit MSDOS (which * doesn't have enough memory anyway to duplicate compression states). */ int ZEXPORT deflateCopy (dest, source) z_streamp dest; z_streamp source; { #ifdef MAXSEG_64K return Z_STREAM_ERROR; #else deflate_state *ds; deflate_state *ss; ushf *overlay; if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { return Z_STREAM_ERROR; } ss = source->state; zmemcpy(dest, source, sizeof(z_stream)); ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); if (ds == Z_NULL) return Z_MEM_ERROR; dest->state = (struct internal_state FAR *) ds; zmemcpy(ds, ss, sizeof(deflate_state)); ds->strm = dest; ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); ds->pending_buf = (uchf *) overlay; if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { deflateEnd (dest); return Z_MEM_ERROR; } /* following zmemcpy do not work for 16-bit MSDOS */ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; ds->bl_desc.dyn_tree = ds->bl_tree; return Z_OK; #endif /* MAXSEG_64K */ } /* =========================================================================== * Read a new buffer from the current input stream, update the adler32 * and total number of bytes read. All deflate() input goes through * this function so some applications may wish to modify it to avoid * allocating a large strm->next_in buffer and copying from it. * (See also flush_pending()). */ local int read_buf(strm, buf, size) z_streamp strm; Bytef *buf; unsigned size; { unsigned len = strm->avail_in; if (len > size) len = size; if (len == 0) return 0; strm->avail_in -= len; if (strm->state->wrap == 1) { strm->adler = adler32(strm->adler, strm->next_in, len); } #ifdef GZIP else if (strm->state->wrap == 2) { strm->adler = crc32(strm->adler, strm->next_in, len); } #endif zmemcpy(buf, strm->next_in, len); strm->next_in += len; strm->total_in += len; return (int)len; } /* =========================================================================== * Initialize the "longest match" routines for a new zlib stream */ local void lm_init (s) deflate_state *s; { s->window_size = (ulg)2L*s->w_size; CLEAR_HASH(s); /* Set the default configuration parameters: */ s->max_lazy_match = configuration_table[s->level].max_lazy; s->good_match = configuration_table[s->level].good_length; s->nice_match = configuration_table[s->level].nice_length; s->max_chain_length = configuration_table[s->level].max_chain; s->strstart = 0; s->block_start = 0L; s->lookahead = 0; s->match_length = s->prev_length = MIN_MATCH-1; s->match_available = 0; s->ins_h = 0; #ifndef FASTEST #ifdef ASMV match_init(); /* initialize the asm code */ #endif #endif } #ifndef FASTEST /* =========================================================================== * Set match_start to the longest match starting at the given string and * return its length. Matches shorter or equal to prev_length are discarded, * in which case the result is equal to prev_length and match_start is * garbage. * IN assertions: cur_match is the head of the hash chain for the current * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 * OUT assertion: the match length is not greater than s->lookahead. */ #ifndef ASMV /* For 80x86 and 680x0, an optimized version will be provided in match.asm or * match.S. The code will be functionally equivalent. */ local uInt longest_match(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ int best_len = s->prev_length; /* best match length so far */ int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? s->strstart - (IPos)MAX_DIST(s) : NIL; /* Stop when cur_match becomes <= limit. To simplify the code, * we prevent matches with the string of window index 0. */ Posf *prev = s->prev; uInt wmask = s->w_mask; #ifdef UNALIGNED_OK /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; register ush scan_start = *(ushf*)scan; register ush scan_end = *(ushf*)(scan+best_len-1); #else register Bytef *strend = s->window + s->strstart + MAX_MATCH; register Byte scan_end1 = scan[best_len-1]; register Byte scan_end = scan[best_len]; #endif /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); /* Do not waste too much time if we already have a good match: */ if (s->prev_length >= s->good_match) { chain_length >>= 2; } /* Do not look for matches beyond the end of the input. This is necessary * to make deflate deterministic. */ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); do { Assert(cur_match < s->strstart, "no future"); match = s->window + cur_match; /* Skip to next match if the match length cannot increase * or if the match length is less than 2. Note that the checks below * for insufficient lookahead only occur occasionally for performance * reasons. Therefore uninitialized memory will be accessed, and * conditional jumps will be made that depend on those values. * However the length of the match is limited to the lookahead, so * the output of deflate is not affected by the uninitialized values. */ #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) /* This code assumes sizeof(unsigned short) == 2. Do not use * UNALIGNED_OK if your compiler uses a different size. */ if (*(ushf*)(match+best_len-1) != scan_end || *(ushf*)match != scan_start) continue; /* It is not necessary to compare scan[2] and match[2] since they are * always equal when the other bytes match, given that the hash keys * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at * strstart+3, +5, ... up to strstart+257. We check for insufficient * lookahead only every 4th comparison; the 128th check will be made * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is * necessary to put more guard bytes at the end of the window, or * to check more often for insufficient lookahead. */ Assert(scan[2] == match[2], "scan[2]?"); scan++, match++; do { } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && scan < strend); /* The funny "do {}" generates better code on most compilers */ /* Here, scan <= window+strstart+257 */ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); if (*scan == *match) scan++; len = (MAX_MATCH - 1) - (int)(strend-scan); scan = strend - (MAX_MATCH-1); #else /* UNALIGNED_OK */ if (match[best_len] != scan_end || match[best_len-1] != scan_end1 || *match != *scan || *++match != scan[1]) continue; /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match++; Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); scan = strend - MAX_MATCH; #endif /* UNALIGNED_OK */ if (len > best_len) { s->match_start = cur_match; best_len = len; if (len >= nice_match) break; #ifdef UNALIGNED_OK scan_end = *(ushf*)(scan+best_len-1); #else scan_end1 = scan[best_len-1]; scan_end = scan[best_len]; #endif } } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length != 0); if ((uInt)best_len <= s->lookahead) return (uInt)best_len; return s->lookahead; } #endif /* ASMV */ #endif /* FASTEST */ /* --------------------------------------------------------------------------- * Optimized version for level == 1 or strategy == Z_RLE only */ local uInt longest_match_fast(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ { register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ register Bytef *strend = s->window + s->strstart + MAX_MATCH; /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); Assert(cur_match < s->strstart, "no future"); match = s->window + cur_match; /* Return failure if the match length is less than 2: */ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match += 2; Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); if (len < MIN_MATCH) return MIN_MATCH - 1; s->match_start = cur_match; return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; } #ifdef DEBUG /* =========================================================================== * Check that the match at match_start is indeed a match. */ local void check_match(s, start, match, length) deflate_state *s; IPos start, match; int length; { /* check that the match is indeed a match */ if (zmemcmp(s->window + match, s->window + start, length) != EQUAL) { fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); do { fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); } while (--length != 0); z_error("invalid match"); } if (z_verbose > 1) { fprintf(stderr,"\\[%d,%d]", start-match, length); do { putc(s->window[start++], stderr); } while (--length != 0); } } #else # define check_match(s, start, match, length) #endif /* DEBUG */ /* =========================================================================== * Fill the window when the lookahead becomes insufficient. * Updates strstart and lookahead. * * IN assertion: lookahead < MIN_LOOKAHEAD * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD * At least one byte has been read, or avail_in == 0; reads are * performed for at least two bytes (required for the zip translate_eol * option -- not supported here). */ local void fill_window(s) deflate_state *s; { register unsigned n, m; register Posf *p; unsigned more; /* Amount of free space at the end of the window. */ uInt wsize = s->w_size; do { more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); /* Deal with !@#$% 64K limit: */ if (sizeof(int) <= 2) { if (more == 0 && s->strstart == 0 && s->lookahead == 0) { more = wsize; } else if (more == (unsigned)(-1)) { /* Very unlikely, but possible on 16 bit machine if * strstart == 0 && lookahead == 1 (input done a byte at time) */ more--; } } /* If the window is almost full and there is insufficient lookahead, * move the upper half to the lower one to make room in the upper half. */ if (s->strstart >= wsize+MAX_DIST(s)) { zmemcpy(s->window, s->window+wsize, (unsigned)wsize); s->match_start -= wsize; s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ s->block_start -= (long) wsize; /* Slide the hash table (could be avoided with 32 bit values at the expense of memory usage). We slide even when level == 0 to keep the hash table consistent if we switch back to level > 0 later. (Using level 0 permanently is not an optimal usage of zlib, so we don't care about this pathological case.) */ /* %%% avoid this when Z_RLE */ n = s->hash_size; p = &s->head[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); } while (--n); n = wsize; #ifndef FASTEST p = &s->prev[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); /* If n is not on any hash chain, prev[n] is garbage but * its value will never be used. */ } while (--n); #endif more += wsize; } if (s->strm->avail_in == 0) return; /* If there was no sliding: * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && * more == window_size - lookahead - strstart * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) * => more >= window_size - 2*WSIZE + 2 * In the BIG_MEM or MMAP case (not yet supported), * window_size == input_size + MIN_LOOKAHEAD && * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. * Otherwise, window_size == 2*WSIZE so more >= 2. * If there was sliding, more >= WSIZE. So in all cases, more >= 2. */ Assert(more >= 2, "more < 2"); n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); s->lookahead += n; /* Initialize the hash value now that we have some input: */ if (s->lookahead >= MIN_MATCH) { s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif } /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, * but this is not important since only literal bytes will be emitted. */ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); } /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ #define FLUSH_BLOCK_ONLY(s, eof) { \ _tr_flush_block(s, (s->block_start >= 0L ? \ (charf *)&s->window[(unsigned)s->block_start] : \ (charf *)Z_NULL), \ (ulg)((long)s->strstart - s->block_start), \ (eof)); \ s->block_start = s->strstart; \ flush_pending(s->strm); \ Tracev((stderr,"[FLUSH]")); \ } /* Same but force premature exit if necessary. */ #define FLUSH_BLOCK(s, eof) { \ FLUSH_BLOCK_ONLY(s, eof); \ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ } /* =========================================================================== * Copy without compression as much as possible from the input stream, return * the current block state. * This function does not insert new strings in the dictionary since * uncompressible data is probably not useful. This function is used * only for the level=0 compression option. * NOTE: this function should be optimized to avoid extra copying from * window to pending_buf. */ local block_state deflate_stored(s, flush) deflate_state *s; int flush; { /* Stored blocks are limited to 0xffff bytes, pending_buf is limited * to pending_buf_size, and each stored block has a 5 byte header: */ ulg max_block_size = 0xffff; ulg max_start; if (max_block_size > s->pending_buf_size - 5) { max_block_size = s->pending_buf_size - 5; } /* Copy as much as possible from input to output: */ for (;;) { /* Fill the window as much as possible: */ if (s->lookahead <= 1) { Assert(s->strstart < s->w_size+MAX_DIST(s) || s->block_start >= (long)s->w_size, "slide too late"); fill_window(s); if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; if (s->lookahead == 0) break; /* flush the current block */ } Assert(s->block_start >= 0L, "block gone"); s->strstart += s->lookahead; s->lookahead = 0; /* Emit a stored block if pending_buf will be full: */ max_start = s->block_start + max_block_size; if (s->strstart == 0 || (ulg)s->strstart >= max_start) { /* strstart == 0 is possible when wraparound on 16-bit machine */ s->lookahead = (uInt)(s->strstart - max_start); s->strstart = (uInt)max_start; FLUSH_BLOCK(s, 0); } /* Flush if we may have to slide, otherwise block_start may become * negative and the data will be gone: */ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { FLUSH_BLOCK(s, 0); } } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } /* =========================================================================== * Compress as much as possible from the input stream, return the current * block state. * This function does not perform lazy evaluation of matches and inserts * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ local block_state deflate_fast(s, flush) deflate_state *s; int flush; { IPos hash_head = NIL; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ #ifdef FASTEST if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { s->match_length = longest_match_fast (s, hash_head); } #else if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { s->match_length = longest_match (s, hash_head); } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { s->match_length = longest_match_fast (s, hash_head); } #endif /* longest_match() or longest_match_fast() sets match_start */ } if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->match_start, s->match_length); _tr_tally_dist(s, s->strstart - s->match_start, s->match_length - MIN_MATCH, bflush); s->lookahead -= s->match_length; /* Insert new strings in the hash table only if the match length * is not too large. This saves time but degrades compression. */ #ifndef FASTEST if (s->match_length <= s->max_insert_length && s->lookahead >= MIN_MATCH) { s->match_length--; /* string at strstart already in table */ do { s->strstart++; INSERT_STRING(s, s->strstart, hash_head); /* strstart never exceeds WSIZE-MAX_MATCH, so there are * always MIN_MATCH bytes ahead. */ } while (--s->match_length != 0); s->strstart++; } else #endif { s->strstart += s->match_length; s->match_length = 0; s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not * matter since it will be recomputed at next deflate call. */ } } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); _tr_tally_lit (s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; } if (bflush) FLUSH_BLOCK(s, 0); } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } #ifndef FASTEST /* =========================================================================== * Same as above, but achieves better compression. We use a lazy * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ local block_state deflate_slow(s, flush) deflate_state *s; int flush; { IPos hash_head = NIL; /* head of hash chain */ int bflush; /* set if current block must be flushed */ /* Process the input block. */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. */ s->prev_length = s->match_length, s->prev_match = s->match_start; s->match_length = MIN_MATCH-1; if (hash_head != NIL && s->prev_length < s->max_lazy_match && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { s->match_length = longest_match (s, hash_head); } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { s->match_length = longest_match_fast (s, hash_head); } /* longest_match() or longest_match_fast() sets match_start */ if (s->match_length <= 5 && (s->strategy == Z_FILTERED #if TOO_FAR <= 32767 || (s->match_length == MIN_MATCH && s->strstart - s->match_start > TOO_FAR) #endif )) { /* If prev_match is also MIN_MATCH, match_start is garbage * but we will ignore the current match anyway. */ s->match_length = MIN_MATCH-1; } } /* If there was a match at the previous step and the current * match is not better, output the previous match: */ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; /* Do not insert strings in hash table beyond this. */ check_match(s, s->strstart-1, s->prev_match, s->prev_length); _tr_tally_dist(s, s->strstart -1 - s->prev_match, s->prev_length - MIN_MATCH, bflush); /* Insert in hash table all strings up to the end of the match. * strstart-1 and strstart are already inserted. If there is not * enough lookahead, the last two strings are not inserted in * the hash table. */ s->lookahead -= s->prev_length-1; s->prev_length -= 2; do { if (++s->strstart <= max_insert) { INSERT_STRING(s, s->strstart, hash_head); } } while (--s->prev_length != 0); s->match_available = 0; s->match_length = MIN_MATCH-1; s->strstart++; if (bflush) FLUSH_BLOCK(s, 0); } else if (s->match_available) { /* If there was no match at the previous position, output a * single literal. If there was a match but the current match * is longer, truncate the previous match to a single literal. */ Tracevv((stderr,"%c", s->window[s->strstart-1])); _tr_tally_lit(s, s->window[s->strstart-1], bflush); if (bflush) { FLUSH_BLOCK_ONLY(s, 0); } s->strstart++; s->lookahead--; if (s->strm->avail_out == 0) return need_more; } else { /* There is no previous match to compare with, wait for * the next step to decide. */ s->match_available = 1; s->strstart++; s->lookahead--; } } Assert (flush != Z_NO_FLUSH, "no flush?"); if (s->match_available) { Tracevv((stderr,"%c", s->window[s->strstart-1])); _tr_tally_lit(s, s->window[s->strstart-1], bflush); s->match_available = 0; } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } #endif /* FASTEST */ #if 0 /* =========================================================================== * For Z_RLE, simply look for runs of bytes, generate matches only of distance * one. Do not maintain a hash table. (It will be regenerated if this run of * deflate switches away from Z_RLE.) */ local block_state deflate_rle(s, flush) deflate_state *s; int flush; { int bflush; /* set if current block must be flushed */ uInt run; /* length of run */ uInt max; /* maximum length of run */ uInt prev; /* byte at distance one to match */ Bytef *scan; /* scan for end of run */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the longest encodable run. */ if (s->lookahead < MAX_MATCH) { fill_window(s); if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* See how many times the previous byte repeats */ run = 0; if (s->strstart > 0) { /* if there is a previous byte, that is */ max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; scan = s->window + s->strstart - 1; prev = *scan++; do { if (*scan++ != prev) break; } while (++run < max); } /* Emit match if have run of MIN_MATCH or longer, else emit literal */ if (run >= MIN_MATCH) { check_match(s, s->strstart, s->strstart - 1, run); _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); s->lookahead -= run; s->strstart += run; } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); _tr_tally_lit (s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; } if (bflush) FLUSH_BLOCK(s, 0); } FLUSH_BLOCK(s, flush == Z_FINISH); return flush == Z_FINISH ? finish_done : block_done; } #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/adler32.c0000644000175000017500000001114411300022650021372 0ustar salvisalvi/* adler32.c -- compute the Adler-32 checksum of a data stream * Copyright (C) 1995-2004 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #define ZLIB_INTERNAL #include "zlib.h" #define BASE 65521UL /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO16(buf) DO8(buf,0); DO8(buf,8); /* use NO_DIVIDE if your processor does not do division in hardware */ #ifdef NO_DIVIDE # define MOD(a) \ do { \ if (a >= (BASE << 16)) a -= (BASE << 16); \ if (a >= (BASE << 15)) a -= (BASE << 15); \ if (a >= (BASE << 14)) a -= (BASE << 14); \ if (a >= (BASE << 13)) a -= (BASE << 13); \ if (a >= (BASE << 12)) a -= (BASE << 12); \ if (a >= (BASE << 11)) a -= (BASE << 11); \ if (a >= (BASE << 10)) a -= (BASE << 10); \ if (a >= (BASE << 9)) a -= (BASE << 9); \ if (a >= (BASE << 8)) a -= (BASE << 8); \ if (a >= (BASE << 7)) a -= (BASE << 7); \ if (a >= (BASE << 6)) a -= (BASE << 6); \ if (a >= (BASE << 5)) a -= (BASE << 5); \ if (a >= (BASE << 4)) a -= (BASE << 4); \ if (a >= (BASE << 3)) a -= (BASE << 3); \ if (a >= (BASE << 2)) a -= (BASE << 2); \ if (a >= (BASE << 1)) a -= (BASE << 1); \ if (a >= BASE) a -= BASE; \ } while (0) # define MOD4(a) \ do { \ if (a >= (BASE << 4)) a -= (BASE << 4); \ if (a >= (BASE << 3)) a -= (BASE << 3); \ if (a >= (BASE << 2)) a -= (BASE << 2); \ if (a >= (BASE << 1)) a -= (BASE << 1); \ if (a >= BASE) a -= BASE; \ } while (0) #else # define MOD(a) a %= BASE # define MOD4(a) a %= BASE #endif /* ========================================================================= */ uLong ZEXPORT adler32(adler, buf, len) uLong adler; const Bytef *buf; uInt len; { unsigned long sum2; unsigned n; /* split Adler-32 into component sums */ sum2 = (adler >> 16) & 0xffff; adler &= 0xffff; /* in case user likes doing a byte at a time, keep it fast */ if (len == 1) { adler += buf[0]; if (adler >= BASE) adler -= BASE; sum2 += adler; if (sum2 >= BASE) sum2 -= BASE; return adler | (sum2 << 16); } /* initial Adler-32 value (deferred check for len == 1 speed) */ if (buf == Z_NULL) return 1L; /* in case short lengths are provided, keep it somewhat fast */ if (len < 16) { while (len--) { adler += *buf++; sum2 += adler; } if (adler >= BASE) adler -= BASE; MOD4(sum2); /* only added so many BASE's */ return adler | (sum2 << 16); } /* do length NMAX blocks -- requires just one modulo operation */ while (len >= NMAX) { len -= NMAX; n = NMAX / 16; /* NMAX is divisible by 16 */ do { DO16(buf); /* 16 sums unrolled */ buf += 16; } while (--n); MOD(adler); MOD(sum2); } /* do remaining bytes (less than NMAX, still just one modulo) */ if (len) { /* avoid modulos if none remaining */ while (len >= 16) { len -= 16; DO16(buf); buf += 16; } while (len--) { adler += *buf++; sum2 += adler; } MOD(adler); MOD(sum2); } /* return recombined sums */ return adler | (sum2 << 16); } /* ========================================================================= */ uLong ZEXPORT adler32_combine(adler1, adler2, len2) uLong adler1; uLong adler2; z_off_t len2; { unsigned long sum1; unsigned long sum2; unsigned rem; /* the derivation of this formula is left as an exercise for the reader */ rem = (unsigned)(len2 % BASE); sum1 = adler1 & 0xffff; sum2 = rem * sum1; MOD(sum2); sum1 += (adler2 & 0xffff) + BASE - 1; sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; if (sum1 > BASE) sum1 -= BASE; if (sum1 > BASE) sum1 -= BASE; if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); if (sum2 > BASE) sum2 -= BASE; return sum1 | (sum2 << 16); } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/inflate.h0000644000175000017500000001361711300022650021574 0ustar salvisalvi/* inflate.h -- internal inflate state definition * Copyright (C) 1995-2004 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* define NO_GZIP when compiling if you want to disable gzip header and trailer decoding by inflate(). NO_GZIP would be used to avoid linking in the crc code when it is not needed. For shared libraries, gzip decoding should be left enabled. */ #ifndef NO_GZIP # define GUNZIP #endif /* Possible inflate modes between inflate() calls */ typedef enum { HEAD, /* i: waiting for magic header */ FLAGS, /* i: waiting for method and flags (gzip) */ TIME, /* i: waiting for modification time (gzip) */ OS, /* i: waiting for extra flags and operating system (gzip) */ EXLEN, /* i: waiting for extra length (gzip) */ EXTRA, /* i: waiting for extra bytes (gzip) */ NAME, /* i: waiting for end of file name (gzip) */ COMMENT, /* i: waiting for end of comment (gzip) */ HCRC, /* i: waiting for header crc (gzip) */ DICTID, /* i: waiting for dictionary check value */ DICT, /* waiting for inflateSetDictionary() call */ TYPE, /* i: waiting for type bits, including last-flag bit */ TYPEDO, /* i: same, but skip check to exit inflate on new block */ STORED, /* i: waiting for stored size (length and complement) */ COPY, /* i/o: waiting for input or output to copy stored block */ TABLE, /* i: waiting for dynamic block table lengths */ LENLENS, /* i: waiting for code length code lengths */ CODELENS, /* i: waiting for length/lit and distance code lengths */ LEN, /* i: waiting for length/lit code */ LENEXT, /* i: waiting for length extra bits */ DIST, /* i: waiting for distance code */ DISTEXT, /* i: waiting for distance extra bits */ MATCH, /* o: waiting for output space to copy string */ LIT, /* o: waiting for output space to write literal */ CHECK, /* i: waiting for 32-bit check value */ LENGTH, /* i: waiting for 32-bit length (gzip) */ DONE, /* finished check, done -- remain here until reset */ BAD, /* got a data error -- remain here until reset */ MEM, /* got an inflate() memory error -- remain here until reset */ SYNC /* looking for synchronization bytes to restart inflate() */ } inflate_mode; /* State transitions between above modes - (most modes can go to the BAD or MEM mode -- not shown for clarity) Process header: HEAD -> (gzip) or (zlib) (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME NAME -> COMMENT -> HCRC -> TYPE (zlib) -> DICTID or TYPE DICTID -> DICT -> TYPE Read deflate blocks: TYPE -> STORED or TABLE or LEN or CHECK STORED -> COPY -> TYPE TABLE -> LENLENS -> CODELENS -> LEN Read deflate codes: LEN -> LENEXT or LIT or TYPE LENEXT -> DIST -> DISTEXT -> MATCH -> LEN LIT -> LEN Process trailer: CHECK -> LENGTH -> DONE */ /* state maintained between inflate() calls. Approximately 7K bytes. */ struct inflate_state { inflate_mode mode; /* current inflate mode */ int last; /* true if processing last block */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ int havedict; /* true if dictionary provided */ int flags; /* gzip header method and flags (0 if zlib) */ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ unsigned long check; /* protected copy of check value */ unsigned long total; /* protected copy of output count */ gz_headerp head; /* where to save gzip header information */ /* sliding window */ unsigned wbits; /* log base 2 of requested window size */ unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned write; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if needed */ /* bit accumulator */ unsigned long hold; /* input bit accumulator */ unsigned bits; /* number of bits in "in" */ /* for string and stored block copying */ unsigned length; /* literal or length of data to copy */ unsigned offset; /* distance back to copy string from */ /* for table and code decoding */ unsigned extra; /* extra bits needed */ /* fixed and dynamic code tables */ code const FAR *lencode; /* starting table for length/literal codes */ code const FAR *distcode; /* starting table for distance codes */ unsigned lenbits; /* index bits for lencode */ unsigned distbits; /* index bits for distcode */ /* dynamic table building */ unsigned ncode; /* number of code length code lengths */ unsigned nlen; /* number of length code lengths */ unsigned ndist; /* number of distance code lengths */ unsigned have; /* number of code lengths in lens[] */ code FAR *next; /* next available space in codes[] */ unsigned short lens[320]; /* temporary storage for code lengths */ unsigned short work[288]; /* work area for code table building */ code codes[ENOUGH]; /* space for code tables */ }; tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/inffast.h0000644000175000017500000000064211300022650021576 0ustar salvisalvi/* inffast.h -- header to use inffast.c * Copyright (C) 1995-2003 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ void inflate_fast OF((z_streamp strm, unsigned start)); tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/inffixed.h0000644000175000017500000001444511300022650021746 0ustar salvisalvi /* inffixed.h -- table for decoding fixed codes * Generated automatically by makefixed(). */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ static const code lenfix[512] = { {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, {0,9,255} }; static const code distfix[32] = { {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, {22,5,193},{64,5,0} }; tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/zlib.def0000644000175000017500000000175011300022650021414 0ustar salvisalviLIBRARY ; zlib data compression library EXPORTS ; basic functions zlibVersion deflate deflateEnd inflate inflateEnd ; advanced functions deflateSetDictionary deflateCopy deflateReset deflateParams deflateBound deflatePrime inflateSetDictionary inflateSync inflateCopy inflateReset inflateBack inflateBackEnd zlibCompileFlags ; utility functions compress compress2 compressBound uncompress ; gzopen ; gzdopen ; gzsetparams ; gzread ; gzwrite ; gzprintf ; gzputs ; gzgets ; gzputc ; gzgetc ; gzungetc ; gzflush ; gzseek ; gzrewind ; gztell ; gzeof ; gzclose ; gzerror ; gzclearerr ; checksum functions adler32 crc32 ; various hacks, don't look :) deflateInit_ deflateInit2_ inflateInit_ inflateInit2_ inflateBackInit_ inflateSyncPoint get_crc_table zError tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/inflate.c0000644000175000017500000014225111300022650021564 0ustar salvisalvi/* inflate.c -- zlib decompression * Copyright (C) 1995-2005 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* * Change history: * * 1.2.beta0 24 Nov 2002 * - First version -- complete rewrite of inflate to simplify code, avoid * creation of window when not needed, minimize use of window when it is * needed, make inffast.c even faster, implement gzip decoding, and to * improve code readability and style over the previous zlib inflate code * * 1.2.beta1 25 Nov 2002 * - Use pointers for available input and output checking in inffast.c * - Remove input and output counters in inffast.c * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 * - Remove unnecessary second byte pull from length extra in inffast.c * - Unroll direct copy to three copies per loop in inffast.c * * 1.2.beta2 4 Dec 2002 * - Change external routine names to reduce potential conflicts * - Correct filename to inffixed.h for fixed tables in inflate.c * - Make hbuf[] unsigned char to match parameter type in inflate.c * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) * to avoid negation problem on Alphas (64 bit) in inflate.c * * 1.2.beta3 22 Dec 2002 * - Add comments on state->bits assertion in inffast.c * - Add comments on op field in inftrees.h * - Fix bug in reuse of allocated window after inflateReset() * - Remove bit fields--back to byte structure for speed * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths * - Change post-increments to pre-increments in inflate_fast(), PPC biased? * - Add compile time option, POSTINC, to use post-increments instead (Intel?) * - Make MATCH copy in inflate() much faster for when inflate_fast() not used * - Use local copies of stream next and avail values, as well as local bit * buffer and bit count in inflate()--for speed when inflate_fast() not used * * 1.2.beta4 1 Jan 2003 * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings * - Move a comment on output buffer sizes from inffast.c to inflate.c * - Add comments in inffast.c to introduce the inflate_fast() routine * - Rearrange window copies in inflate_fast() for speed and simplification * - Unroll last copy for window match in inflate_fast() * - Use local copies of window variables in inflate_fast() for speed * - Pull out common write == 0 case for speed in inflate_fast() * - Make op and len in inflate_fast() unsigned for consistency * - Add FAR to lcode and dcode declarations in inflate_fast() * - Simplified bad distance check in inflate_fast() * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new * source file infback.c to provide a call-back interface to inflate for * programs like gzip and unzip -- uses window as output buffer to avoid * window copying * * 1.2.beta5 1 Jan 2003 * - Improved inflateBack() interface to allow the caller to provide initial * input in strm. * - Fixed stored blocks bug in inflateBack() * * 1.2.beta6 4 Jan 2003 * - Added comments in inffast.c on effectiveness of POSTINC * - Typecasting all around to reduce compiler warnings * - Changed loops from while (1) or do {} while (1) to for (;;), again to * make compilers happy * - Changed type of window in inflateBackInit() to unsigned char * * * 1.2.beta7 27 Jan 2003 * - Changed many types to unsigned or unsigned short to avoid warnings * - Added inflateCopy() function * * 1.2.0 9 Mar 2003 * - Changed inflateBack() interface to provide separate opaque descriptors * for the in() and out() functions * - Changed inflateBack() argument and in_func typedef to swap the length * and buffer address return values for the input function * - Check next_in and next_out for Z_NULL on entry to inflate() * * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" #ifdef MAKEFIXED # ifndef BUILDFIXED # define BUILDFIXED # endif #endif /* function prototypes */ local void fixedtables OF((struct inflate_state FAR *state)); local int updatewindow OF((z_streamp strm, unsigned out)); #ifdef BUILDFIXED void makefixed OF((void)); #endif local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, unsigned len)); int ZEXPORT inflateReset(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; strm->total_in = strm->total_out = state->total = 0; strm->msg = Z_NULL; strm->adler = 1; /* to support ill-conceived Java test suite */ state->mode = HEAD; state->last = 0; state->havedict = 0; state->dmax = 32768U; state->head = Z_NULL; state->wsize = 0; state->whave = 0; state->write = 0; state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; Tracev((stderr, "inflate: reset\n")); return Z_OK; } int ZEXPORT inflatePrime(strm, bits, value) z_streamp strm; int bits; int value; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; value &= (1L << bits) - 1; state->hold += value << state->bits; state->bits += bits; return Z_OK; } int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) z_streamp strm; int windowBits; const char *version; int stream_size; { struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) return Z_VERSION_ERROR; if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { strm->zalloc = zcalloc; strm->opaque = (voidpf)0; } if (strm->zfree == (free_func)0) strm->zfree = zcfree; state = (struct inflate_state FAR *) ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; if (windowBits < 0) { state->wrap = 0; windowBits = -windowBits; } else { state->wrap = (windowBits >> 4) + 1; #ifdef GUNZIP if (windowBits < 48) windowBits &= 15; #endif } if (windowBits < 8 || windowBits > 15) { ZFREE(strm, state); strm->state = Z_NULL; return Z_STREAM_ERROR; } state->wbits = (unsigned)windowBits; state->window = Z_NULL; return inflateReset(strm); } int ZEXPORT inflateInit_(strm, version, stream_size) z_streamp strm; const char *version; int stream_size; { return inflateInit2_(strm, DEF_WBITS, version, stream_size); } /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. If BUILDFIXED is defined, then instead this routine builds the tables the first time it's called, and returns those tables the first time and thereafter. This reduces the size of the code by about 2K bytes, in exchange for a little execution time. However, BUILDFIXED should not be used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ local void fixedtables(state) struct inflate_state FAR *state; { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; static code fixed[544]; /* build fixed huffman tables if first call (may not be thread safe) */ if (virgin) { unsigned sym, bits; static code *next; /* literal/length table */ sym = 0; while (sym < 144) state->lens[sym++] = 8; while (sym < 256) state->lens[sym++] = 9; while (sym < 280) state->lens[sym++] = 7; while (sym < 288) state->lens[sym++] = 8; next = fixed; lenfix = next; bits = 9; inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); /* distance table */ sym = 0; while (sym < 32) state->lens[sym++] = 5; distfix = next; bits = 5; inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); /* do this just once */ virgin = 0; } #else /* !BUILDFIXED */ # include "inffixed.h" #endif /* BUILDFIXED */ state->lencode = lenfix; state->lenbits = 9; state->distcode = distfix; state->distbits = 5; } #ifdef MAKEFIXED #include /* Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also defines BUILDFIXED, so the tables are built on the fly. makefixed() writes those tables to stdout, which would be piped to inffixed.h. A small program can simply call makefixed to do this: void makefixed(void); int main(void) { makefixed(); return 0; } Then that can be linked with zlib built with MAKEFIXED defined and run: a.out > inffixed.h */ void makefixed() { unsigned low, size; struct inflate_state state; fixedtables(&state); puts(" /* inffixed.h -- table for decoding fixed codes"); puts(" * Generated automatically by makefixed()."); puts(" */"); puts(""); puts(" /* WARNING: this file should *not* be used by applications."); puts(" It is part of the implementation of this library and is"); puts(" subject to change. Applications should only use zlib.h."); puts(" */"); puts(""); size = 1U << 9; printf(" static const code lenfix[%u] = {", size); low = 0; for (;;) { if ((low % 7) == 0) printf("\n "); printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, state.lencode[low].val); if (++low == size) break; putchar(','); } puts("\n };"); size = 1U << 5; printf("\n static const code distfix[%u] = {", size); low = 0; for (;;) { if ((low % 6) == 0) printf("\n "); printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, state.distcode[low].val); if (++low == size) break; putchar(','); } puts("\n };"); } #endif /* MAKEFIXED */ /* Update the window with the last wsize (normally 32K) bytes written before returning. If window does not exist yet, create it. This is only called when a window is already in use, or when output has been written during this inflate call, but the end of the deflate stream has not been reached yet. It is also called to create a window for dictionary data when a dictionary is loaded. Providing output buffers larger than 32K to inflate() should provide a speed advantage, since only the last 32K of output is copied to the sliding window upon return from inflate(), and since all distances after the first 32K of output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ local int updatewindow(strm, out) z_streamp strm; unsigned out; { struct inflate_state FAR *state; unsigned copy, dist; state = (struct inflate_state FAR *)strm->state; /* if it hasn't been done already, allocate space for the window */ if (state->window == Z_NULL) { state->window = (unsigned char FAR *) ZALLOC(strm, 1U << state->wbits, sizeof(unsigned char)); if (state->window == Z_NULL) return 1; } /* if window not in use yet, initialize */ if (state->wsize == 0) { state->wsize = 1U << state->wbits; state->write = 0; state->whave = 0; } /* copy state->wsize or less output bytes into the circular window */ copy = out - strm->avail_out; if (copy >= state->wsize) { zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); state->write = 0; state->whave = state->wsize; } else { dist = state->wsize - state->write; if (dist > copy) dist = copy; zmemcpy(state->window + state->write, strm->next_out - copy, dist); copy -= dist; if (copy) { zmemcpy(state->window, strm->next_out - copy, copy); state->write = copy; state->whave = state->wsize; } else { state->write += dist; if (state->write == state->wsize) state->write = 0; if (state->whave < state->wsize) state->whave += dist; } } return 0; } /* Macros for inflate(): */ /* check function to use adler32() for zlib or crc32() for gzip */ #ifdef GUNZIP # define UPDATE(check, buf, len) \ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) #else # define UPDATE(check, buf, len) adler32(check, buf, len) #endif /* check macros for header crc */ #ifdef GUNZIP # define CRC2(check, word) \ do { \ hbuf[0] = (unsigned char)(word); \ hbuf[1] = (unsigned char)((word) >> 8); \ check = crc32(check, hbuf, 2); \ } while (0) # define CRC4(check, word) \ do { \ hbuf[0] = (unsigned char)(word); \ hbuf[1] = (unsigned char)((word) >> 8); \ hbuf[2] = (unsigned char)((word) >> 16); \ hbuf[3] = (unsigned char)((word) >> 24); \ check = crc32(check, hbuf, 4); \ } while (0) #endif /* Load registers with state in inflate() for speed */ #define LOAD() \ do { \ put = strm->next_out; \ left = strm->avail_out; \ next = strm->next_in; \ have = strm->avail_in; \ hold = state->hold; \ bits = state->bits; \ } while (0) /* Restore state from registers in inflate() */ #define RESTORE() \ do { \ strm->next_out = put; \ strm->avail_out = left; \ strm->next_in = next; \ strm->avail_in = have; \ state->hold = hold; \ state->bits = bits; \ } while (0) /* Clear the input bit accumulator */ #define INITBITS() \ do { \ hold = 0; \ bits = 0; \ } while (0) /* Get a byte of input into the bit accumulator, or return from inflate() if there is no input available. */ #define PULLBYTE() \ do { \ if (have == 0) goto inf_leave; \ have--; \ hold += (unsigned long)(*next++) << bits; \ bits += 8; \ } while (0) /* Assure that there are at least n bits in the bit accumulator. If there is not enough available input to do that, then return from inflate(). */ #define NEEDBITS(n) \ do { \ while (bits < (unsigned)(n)) \ PULLBYTE(); \ } while (0) /* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \ ((unsigned)hold & ((1U << (n)) - 1)) /* Remove n bits from the bit accumulator */ #define DROPBITS(n) \ do { \ hold >>= (n); \ bits -= (unsigned)(n); \ } while (0) /* Remove zero to seven bits as needed to go to a byte boundary */ #define BYTEBITS() \ do { \ hold >>= bits & 7; \ bits -= bits & 7; \ } while (0) /* Reverse the bytes in a 32-bit value */ #define REVERSE(q) \ ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) /* inflate() uses a state machine to process as much input data and generate as much output data as possible before returning. The state machine is structured roughly as follows: for (;;) switch (state) { ... case STATEn: if (not enough input data or output space to make progress) return; ... make progress ... state = STATEm; break; ... } so when inflate() is called again, the same case is attempted again, and if the appropriate resources are provided, the machine proceeds to the next state. The NEEDBITS() macro is usually the way the state evaluates whether it can proceed or should return. NEEDBITS() does the return if the requested bits are not available. The typical use of the BITS macros is: NEEDBITS(n); ... do something with BITS(n) ... DROPBITS(n); where NEEDBITS(n) either returns from inflate() if there isn't enough input left to load n bits into the accumulator, or it continues. BITS(n) gives the low n bits in the accumulator. When done, DROPBITS(n) drops the low n bits off the accumulator. INITBITS() clears the accumulator and sets the number of available bits to zero. BYTEBITS() discards just enough bits to put the accumulator on a byte boundary. After BYTEBITS() and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return if there is no input available. The decoding of variable length codes uses PULLBYTE() directly in order to pull just enough bytes to decode the next code, and no more. Some states loop until they get enough input, making sure that enough state information is maintained to continue the loop where it left off if NEEDBITS() returns in the loop. For example, want, need, and keep would all have to actually be part of the saved state in case NEEDBITS() returns: case STATEw: while (want < need) { NEEDBITS(n); keep[want++] = BITS(n); DROPBITS(n); } state = STATEx; case STATEx: As shown above, if the next state is also the next case, then the break is omitted. A state may also return if there is not enough output space available to complete that state. Those states are copying stored data, writing a literal byte, and copying a matching string. When returning, a "goto inf_leave" is used to update the total counters, update the check value, and determine whether any progress has been made during that inflate() call in order to return the proper return code. Progress is defined as a change in either strm->avail_in or strm->avail_out. When there is a window, goto inf_leave will update the window with the last output written. If a goto inf_leave occurs in the middle of decompression and there is no window currently, goto inf_leave will create one and copy output to the window for the next call of inflate(). In this implementation, the flush parameter of inflate() only affects the return code (per zlib.h). inflate() always writes as much as possible to strm->next_out, given the space available and the provided input--the effect documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers the allocation of and copying into a sliding window until necessary, which provides the effect documented in zlib.h for Z_FINISH when the entire input stream available. So the only thing the flush parameter actually does is: when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it will return Z_BUF_ERROR if it has not reached the end of the stream. */ int ZEXPORT inflate(strm, flush) z_streamp strm; int flush; { struct inflate_state FAR *state; unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ unsigned bits; /* bits in bit buffer */ unsigned in, out; /* save starting available input and output */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ code this; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ #ifdef GUNZIP unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ #endif static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ LOAD(); in = have; out = left; ret = Z_OK; for (;;) switch (state->mode) { case HEAD: if (state->wrap == 0) { state->mode = TYPEDO; break; } NEEDBITS(16); #ifdef GUNZIP if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ state->check = crc32(0L, Z_NULL, 0); CRC2(state->check, hold); INITBITS(); state->mode = FLAGS; break; } state->flags = 0; /* expect zlib header */ if (state->head != Z_NULL) state->head->done = -1; if (!(state->wrap & 1) || /* check if zlib header allowed */ #else if ( #endif ((BITS(8) << 8) + (hold >> 8)) % 31) { strm->msg = (char *)"incorrect header check"; state->mode = BAD; break; } if (BITS(4) != Z_DEFLATED) { strm->msg = (char *)"unknown compression method"; state->mode = BAD; break; } DROPBITS(4); len = BITS(4) + 8; if (len > state->wbits) { strm->msg = (char *)"invalid window size"; state->mode = BAD; break; } state->dmax = 1U << len; Tracev((stderr, "inflate: zlib header ok\n")); strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = hold & 0x200 ? DICTID : TYPE; INITBITS(); break; #ifdef GUNZIP case FLAGS: NEEDBITS(16); state->flags = (int)(hold); if ((state->flags & 0xff) != Z_DEFLATED) { strm->msg = (char *)"unknown compression method"; state->mode = BAD; break; } if (state->flags & 0xe000) { strm->msg = (char *)"unknown header flags set"; state->mode = BAD; break; } if (state->head != Z_NULL) state->head->text = (int)((hold >> 8) & 1); if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = TIME; case TIME: NEEDBITS(32); if (state->head != Z_NULL) state->head->time = hold; if (state->flags & 0x0200) CRC4(state->check, hold); INITBITS(); state->mode = OS; case OS: NEEDBITS(16); if (state->head != Z_NULL) { state->head->xflags = (int)(hold & 0xff); state->head->os = (int)(hold >> 8); } if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = EXLEN; case EXLEN: if (state->flags & 0x0400) { NEEDBITS(16); state->length = (unsigned)(hold); if (state->head != Z_NULL) state->head->extra_len = (unsigned)hold; if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); } else if (state->head != Z_NULL) state->head->extra = Z_NULL; state->mode = EXTRA; case EXTRA: if (state->flags & 0x0400) { copy = state->length; if (copy > have) copy = have; if (copy) { if (state->head != Z_NULL && state->head->extra != Z_NULL) { len = state->head->extra_len - state->length; zmemcpy(state->head->extra + len, next, len + copy > state->head->extra_max ? state->head->extra_max - len : copy); } if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; state->length -= copy; } if (state->length) goto inf_leave; } state->length = 0; state->mode = NAME; case NAME: if (state->flags & 0x0800) { if (have == 0) goto inf_leave; copy = 0; do { len = (unsigned)(next[copy++]); if (state->head != Z_NULL && state->head->name != Z_NULL && state->length < state->head->name_max) state->head->name[state->length++] = len; } while (len && copy < have); if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } else if (state->head != Z_NULL) state->head->name = Z_NULL; state->length = 0; state->mode = COMMENT; case COMMENT: if (state->flags & 0x1000) { if (have == 0) goto inf_leave; copy = 0; do { len = (unsigned)(next[copy++]); if (state->head != Z_NULL && state->head->comment != Z_NULL && state->length < state->head->comm_max) state->head->comment[state->length++] = len; } while (len && copy < have); if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } else if (state->head != Z_NULL) state->head->comment = Z_NULL; state->mode = HCRC; case HCRC: if (state->flags & 0x0200) { NEEDBITS(16); if (hold != (state->check & 0xffff)) { strm->msg = (char *)"header crc mismatch"; state->mode = BAD; break; } INITBITS(); } if (state->head != Z_NULL) { state->head->hcrc = (int)((state->flags >> 9) & 1); state->head->done = 1; } strm->adler = state->check = crc32(0L, Z_NULL, 0); state->mode = TYPE; break; #endif case DICTID: NEEDBITS(32); strm->adler = state->check = REVERSE(hold); INITBITS(); state->mode = DICT; case DICT: if (state->havedict == 0) { RESTORE(); return Z_NEED_DICT; } strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; case TYPE: if (flush == Z_BLOCK) goto inf_leave; case TYPEDO: if (state->last) { BYTEBITS(); state->mode = CHECK; break; } NEEDBITS(3); state->last = BITS(1); DROPBITS(1); switch (BITS(2)) { case 0: /* stored block */ Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); state->mode = STORED; break; case 1: /* fixed block */ fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN; /* decode codes */ break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); state->mode = TABLE; break; case 3: strm->msg = (char *)"invalid block type"; state->mode = BAD; } DROPBITS(2); break; case STORED: BYTEBITS(); /* go to byte boundary */ NEEDBITS(32); if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { strm->msg = (char *)"invalid stored block lengths"; state->mode = BAD; break; } state->length = (unsigned)hold & 0xffff; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); state->mode = COPY; case COPY: copy = state->length; if (copy) { if (copy > have) copy = have; if (copy > left) copy = left; if (copy == 0) goto inf_leave; zmemcpy(put, next, copy); have -= copy; next += copy; left -= copy; put += copy; state->length -= copy; break; } Tracev((stderr, "inflate: stored end\n")); state->mode = TYPE; break; case TABLE: NEEDBITS(14); state->nlen = BITS(5) + 257; DROPBITS(5); state->ndist = BITS(5) + 1; DROPBITS(5); state->ncode = BITS(4) + 4; DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND if (state->nlen > 286 || state->ndist > 30) { strm->msg = (char *)"too many length or distance symbols"; state->mode = BAD; break; } #endif Tracev((stderr, "inflate: table sizes ok\n")); state->have = 0; state->mode = LENLENS; case LENLENS: while (state->have < state->ncode) { NEEDBITS(3); state->lens[order[state->have++]] = (unsigned short)BITS(3); DROPBITS(3); } while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid code lengths set"; state->mode = BAD; break; } Tracev((stderr, "inflate: code lengths ok\n")); state->have = 0; state->mode = CODELENS; case CODELENS: while (state->have < state->nlen + state->ndist) { for (;;) { this = state->lencode[BITS(state->lenbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if (this.val < 16) { NEEDBITS(this.bits); DROPBITS(this.bits); state->lens[state->have++] = this.val; } else { if (this.val == 16) { NEEDBITS(this.bits + 2); DROPBITS(this.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } len = state->lens[state->have - 1]; copy = 3 + BITS(2); DROPBITS(2); } else if (this.val == 17) { NEEDBITS(this.bits + 3); DROPBITS(this.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { NEEDBITS(this.bits + 7); DROPBITS(this.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); } if (state->have + copy > state->nlen + state->ndist) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } while (copy--) state->lens[state->have++] = (unsigned short)len; } } /* handle error breaks in while */ if (state->mode == BAD) break; /* build code tables */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid literal/lengths set"; state->mode = BAD; break; } state->distcode = (code const FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); if (ret) { strm->msg = (char *)"invalid distances set"; state->mode = BAD; break; } Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN; case LEN: if (have >= 6 && left >= 258) { RESTORE(); inflate_fast(strm, out); LOAD(); break; } for (;;) { this = state->lencode[BITS(state->lenbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if (this.op && (this.op & 0xf0) == 0) { last = this; for (;;) { this = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + this.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(this.bits); state->length = (unsigned)this.val; if ((int)(this.op) == 0) { Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", this.val)); state->mode = LIT; break; } if (this.op & 32) { Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } if (this.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } state->extra = (unsigned)(this.op) & 15; state->mode = LENEXT; case LENEXT: if (state->extra) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); } Tracevv((stderr, "inflate: length %u\n", state->length)); state->mode = DIST; case DIST: for (;;) { this = state->distcode[BITS(state->distbits)]; if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } if ((this.op & 0xf0) == 0) { last = this; for (;;) { this = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + this.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(this.bits); if (this.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } state->offset = (unsigned)this.val; state->extra = (unsigned)(this.op) & 15; state->mode = DISTEXT; case DISTEXT: if (state->extra) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); } #ifdef INFLATE_STRICT if (state->offset > state->dmax) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #endif if (state->offset > state->whave + out - left) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } Tracevv((stderr, "inflate: distance %u\n", state->offset)); state->mode = MATCH; case MATCH: if (left == 0) goto inf_leave; copy = out - left; if (state->offset > copy) { /* copy from window */ copy = state->offset - copy; if (copy > state->write) { copy -= state->write; from = state->window + (state->wsize - copy); } else from = state->window + (state->write - copy); if (copy > state->length) copy = state->length; } else { /* copy from output */ from = put - state->offset; copy = state->length; } if (copy > left) copy = left; left -= copy; state->length -= copy; do { *put++ = *from++; } while (--copy); if (state->length == 0) state->mode = LEN; break; case LIT: if (left == 0) goto inf_leave; *put++ = (unsigned char)(state->length); left--; state->mode = LEN; break; case CHECK: if (state->wrap) { NEEDBITS(32); out -= left; strm->total_out += out; state->total += out; if (out) strm->adler = state->check = UPDATE(state->check, put - out, out); out = left; if (( #ifdef GUNZIP state->flags ? hold : #endif REVERSE(hold)) != state->check) { strm->msg = (char *)"incorrect data check"; state->mode = BAD; break; } INITBITS(); Tracev((stderr, "inflate: check matches trailer\n")); } #ifdef GUNZIP state->mode = LENGTH; case LENGTH: if (state->wrap && state->flags) { NEEDBITS(32); if (hold != (state->total & 0xffffffffUL)) { strm->msg = (char *)"incorrect length check"; state->mode = BAD; break; } INITBITS(); Tracev((stderr, "inflate: length matches trailer\n")); } #endif state->mode = DONE; case DONE: ret = Z_STREAM_END; goto inf_leave; case BAD: ret = Z_DATA_ERROR; goto inf_leave; case MEM: return Z_MEM_ERROR; case SYNC: default: return Z_STREAM_ERROR; } /* Return from inflate(), updating the total counts and the check value. If there was no progress during the inflate() call, return a buffer error. Call updatewindow() to create and/or update the window state. Note: a memory error from inflate() is non-recoverable. */ inf_leave: RESTORE(); if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) if (updatewindow(strm, out)) { state->mode = MEM; return Z_MEM_ERROR; } in -= strm->avail_in; out -= strm->avail_out; strm->total_in += in; strm->total_out += out; state->total += out; if (state->wrap && out) strm->adler = state->check = UPDATE(state->check, strm->next_out - out, out); strm->data_type = state->bits + (state->last ? 64 : 0) + (state->mode == TYPE ? 128 : 0); if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) ret = Z_BUF_ERROR; return ret; } int ZEXPORT inflateEnd(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->window != Z_NULL) ZFREE(strm, state->window); ZFREE(strm, strm->state); strm->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; } int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; uInt dictLength; { struct inflate_state FAR *state; unsigned long id; /* check state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->wrap != 0 && state->mode != DICT) return Z_STREAM_ERROR; /* check for correct dictionary id */ if (state->mode == DICT) { id = adler32(0L, Z_NULL, 0); id = adler32(id, dictionary, dictLength); if (id != state->check) return Z_DATA_ERROR; } /* copy dictionary to window */ if (updatewindow(strm, strm->avail_out)) { state->mode = MEM; return Z_MEM_ERROR; } if (dictLength > state->wsize) { zmemcpy(state->window, dictionary + dictLength - state->wsize, state->wsize); state->whave = state->wsize; } else { zmemcpy(state->window + state->wsize - dictLength, dictionary, dictLength); state->whave = dictLength; } state->havedict = 1; Tracev((stderr, "inflate: dictionary set\n")); return Z_OK; } int ZEXPORT inflateGetHeader(strm, head) z_streamp strm; gz_headerp head; { struct inflate_state FAR *state; /* check state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; /* save header structure */ state->head = head; head->done = 0; return Z_OK; } /* Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found or when out of input. When called, *have is the number of pattern bytes found in order so far, in 0..3. On return *have is updated to the new state. If on return *have equals four, then the pattern was found and the return value is how many bytes were read including the last byte of the pattern. If *have is less than four, then the pattern has not been found yet and the return value is len. In the latter case, syncsearch() can be called again with more data and the *have state. *have is initialized to zero for the first call. */ local unsigned syncsearch(have, buf, len) unsigned FAR *have; unsigned char FAR *buf; unsigned len; { unsigned got; unsigned next; got = *have; next = 0; while (next < len && got < 4) { if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) got++; else if (buf[next]) got = 0; else got = 4 - got; next++; } *have = got; return next; } int ZEXPORT inflateSync(strm) z_streamp strm; { unsigned len; /* number of bytes to look at or looked at */ unsigned long in, out; /* temporary to save total_in and total_out */ unsigned char buf[4]; /* to restore bit buffer to byte string */ struct inflate_state FAR *state; /* check parameters */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; state->hold <<= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { buf[len++] = (unsigned char)(state->hold); state->hold >>= 8; state->bits -= 8; } state->have = 0; syncsearch(&(state->have), buf, len); } /* search available input */ len = syncsearch(&(state->have), strm->next_in, strm->avail_in); strm->avail_in -= len; strm->next_in += len; strm->total_in += len; /* return no joy or set up to restart inflate() on a new block */ if (state->have != 4) return Z_DATA_ERROR; in = strm->total_in; out = strm->total_out; inflateReset(strm); strm->total_in = in; strm->total_out = out; state->mode = TYPE; return Z_OK; } /* Returns true if inflate is currently at the end of a block generated by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored block. When decompressing, PPP checks that at the end of input packet, inflate is waiting for these length bytes. */ int ZEXPORT inflateSyncPoint(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; return state->mode == STORED && state->bits == 0; } int ZEXPORT inflateCopy(dest, source) z_streamp dest; z_streamp source; { struct inflate_state FAR *state; struct inflate_state FAR *copy; unsigned char FAR *window; unsigned wsize; /* check input */ if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)source->state; /* allocate space */ copy = (struct inflate_state FAR *) ZALLOC(source, 1, sizeof(struct inflate_state)); if (copy == Z_NULL) return Z_MEM_ERROR; window = Z_NULL; if (state->window != Z_NULL) { window = (unsigned char FAR *) ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); if (window == Z_NULL) { ZFREE(source, copy); return Z_MEM_ERROR; } } /* copy state */ zmemcpy(dest, source, sizeof(z_stream)); zmemcpy(copy, state, sizeof(struct inflate_state)); if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { copy->lencode = copy->codes + (state->lencode - state->codes); copy->distcode = copy->codes + (state->distcode - state->codes); } copy->next = copy->codes + (state->next - state->codes); if (window != Z_NULL) { wsize = 1U << state->wbits; zmemcpy(window, state->window, wsize); } copy->window = window; dest->state = (struct internal_state FAR *)copy; return Z_OK; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/zutil.h0000644000175000017500000001573011300022650021317 0ustar salvisalvi/* zutil.h -- internal interface and configuration of the compression library * Copyright (C) 1995-2005 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* @(#) $Id$ */ #ifndef ZUTIL_H #define ZUTIL_H #define ZLIB_INTERNAL #include "zlib.h" #ifdef STDC # ifndef _WIN32_WCE # include # endif # include # include #endif #ifdef NO_ERRNO_H # ifdef _WIN32_WCE /* The Microsoft C Run-Time Library for Windows CE doesn't have * errno. We define it as a global variable to simplify porting. * Its value is always 0 and should not be used. We rename it to * avoid conflict with other libraries that use the same workaround. */ # define errno z_errno # endif extern int errno; #else # ifndef _WIN32_WCE # include # endif #endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ typedef unsigned char uch; typedef uch FAR uchf; typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] #define ERR_RETURN(strm,err) \ return (strm->msg = (char*)ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ /* common constants */ #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS #endif /* default windowBits for decompression. MAX_WBITS is for compression only */ #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default memLevel */ #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 /* The three kinds of block type */ #define MIN_MATCH 3 #define MAX_MATCH 258 /* The minimum and maximum match lengths */ #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ /* target dependencies */ #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) # define OS_CODE 0x00 # if defined(__TURBOC__) || defined(__BORLANDC__) # if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) /* Allow compilation with ANSI keywords only enabled */ void _Cdecl farfree( void *block ); void *_Cdecl farmalloc( unsigned long nbytes ); # else # include # endif # else /* MSC or DJGPP */ # include # endif #endif #ifdef AMIGA # define OS_CODE 0x01 #endif #if defined(VAXC) || defined(VMS) # define OS_CODE 0x02 # define F_OPEN(name, mode) \ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") #endif #if defined(ATARI) || defined(atarist) # define OS_CODE 0x05 #endif #ifdef OS2 # define OS_CODE 0x06 # ifdef M_I86 #include # endif #endif #if defined(MACOS) || defined(TARGET_OS_MAC) # define OS_CODE 0x07 # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os # include /* for fdopen */ # else # ifndef fdopen # define fdopen(fd,mode) NULL /* No fdopen() */ # endif # endif #endif #ifdef TOPS20 # define OS_CODE 0x0a #endif #ifdef WIN32 # ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ # define OS_CODE 0x0b # endif #endif #ifdef __50SERIES /* Prime/PRIMOS */ # define OS_CODE 0x0f #endif #if defined(_BEOS_) || defined(RISCOS) # define fdopen(fd,mode) NULL /* No fdopen() */ #endif #if (defined(_MSC_VER) && (_MSC_VER > 600)) # if defined(_WIN32_WCE) # define fdopen(fd,mode) NULL /* No fdopen() */ # ifndef _PTRDIFF_T_DEFINED typedef int ptrdiff_t; # define _PTRDIFF_T_DEFINED # endif # else # define fdopen(fd,type) _fdopen(fd,type) # endif #endif /* common defaults */ #ifndef OS_CODE # define OS_CODE 0x03 /* assume Unix */ #endif #ifndef F_OPEN # define F_OPEN(name, mode) fopen((name), (mode)) #endif /* functions */ #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #if defined(__CYGWIN__) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #ifndef HAVE_VSNPRINTF # ifdef MSDOS /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), but for now we just assume it doesn't. */ # define NO_vsnprintf # endif # ifdef __TURBOC__ # define NO_vsnprintf # endif # ifdef WIN32 /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ # if !defined(vsnprintf) && !defined(NO_vsnprintf) # define vsnprintf _vsnprintf # endif # endif # ifdef __SASC # define NO_vsnprintf # endif #endif #ifdef VMS # define NO_vsnprintf #endif #if defined(pyr) # define NO_MEMCPY #endif #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) /* Use our own functions for small and medium model with MSC <= 5.0. * You may have to use the same strategy for Borland C (untested). * The __SC__ check is for Symantec. */ # define NO_MEMCPY #endif #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) # define HAVE_MEMCPY #endif #ifdef HAVE_MEMCPY # ifdef SMALL_MEDIUM /* MSDOS small or medium model */ # define zmemcpy _fmemcpy # define zmemcmp _fmemcmp # define zmemzero(dest, len) _fmemset(dest, 0, len) # else # define zmemcpy memcpy # define zmemcmp memcmp # define zmemzero(dest, len) memset(dest, 0, len) # endif #else extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); extern void zmemzero OF((Bytef* dest, uInt len)); #endif /* Diagnostic functions */ #ifdef DEBUG # include extern int z_verbose; extern void z_error OF((char *m)); # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) {if (z_verbose>=0) fprintf x ;} # define Tracev(x) {if (z_verbose>0) fprintf x ;} # define Tracevv(x) {if (z_verbose>1) fprintf x ;} # define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} # define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} #else # define Assert(cond,msg) # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) #endif voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); void zcfree OF((voidpf opaque, voidpf ptr)); #define ZALLOC(strm, items, size) \ (*((strm)->zalloc))((strm)->opaque, (items), (size)) #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} #endif /* ZUTIL_H */ tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/crc32.c0000644000175000017500000003246011300022650021056 0ustar salvisalvi/* crc32.c -- compute the CRC-32 of a data stream * Copyright (C) 1995-2005 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h * * Thanks to Rodney Brown for his contribution of faster * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing * tables for updating the shift register in one step with three exclusive-ors * instead of four steps with four exclusive-ors. This results in about a * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. */ /* @(#) $Id$ */ /* Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore protection on the static variables used to control the first-use generation of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should first call get_crc_table() to initialize the tables before allowing more than one thread to use crc32(). */ #ifdef MAKECRCH # include # ifndef DYNAMIC_CRC_TABLE # define DYNAMIC_CRC_TABLE # endif /* !DYNAMIC_CRC_TABLE */ #endif /* MAKECRCH */ #include "zutil.h" /* for STDC and FAR definitions */ #define local static /* Find a four-byte integer type for crc32_little() and crc32_big(). */ #ifndef NOBYFOUR # ifdef STDC /* need ANSI C limits.h to determine sizes */ # include # define BYFOUR # if (UINT_MAX == 0xffffffffUL) typedef unsigned int u4; # else # if (ULONG_MAX == 0xffffffffUL) typedef unsigned long u4; # else # if (USHRT_MAX == 0xffffffffUL) typedef unsigned short u4; # else # undef BYFOUR /* can't find a four-byte integer type! */ # endif # endif # endif # endif /* STDC */ #endif /* !NOBYFOUR */ /* Definitions for doing the crc four data bytes at a time. */ #ifdef BYFOUR # define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ (((w)&0xff00)<<8)+(((w)&0xff)<<24)) local unsigned long crc32_little OF((unsigned long, const unsigned char FAR *, unsigned)); local unsigned long crc32_big OF((unsigned long, const unsigned char FAR *, unsigned)); # define TBLS 8 #else # define TBLS 1 #endif /* BYFOUR */ /* Local functions for crc concatenation */ local unsigned long gf2_matrix_times OF((unsigned long *mat, unsigned long vec)); local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); #ifdef DYNAMIC_CRC_TABLE local volatile int crc_table_empty = 1; local unsigned long FAR crc_table[TBLS][256]; local void make_crc_table OF((void)); #ifdef MAKECRCH local void write_table OF((FILE *, const unsigned long FAR *)); #endif /* MAKECRCH */ /* Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. Polynomials over GF(2) are represented in binary, one bit per coefficient, with the lowest powers in the most significant bit. Then adding polynomials is just exclusive-or, and multiplying a polynomial by x is a right shift by one. If we call the above polynomial p, and represent a byte as the polynomial q, also with the lowest power in the most significant bit (so the byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, where a mod b means the remainder after dividing a by b. This calculation is done using the shift-register method of multiplying and taking the remainder. The register is initialized to zero, and for each incoming bit, x^32 is added mod p to the register if the bit is a one (where x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x (which is shifting right by one and adding x^32 mod p if the bit shifted out is a one). We start with the highest power (least significant bit) of q and repeat for all eight bits of q. The first table is simply the CRC of all possible eight bit values. This is all the information needed to generate CRCs on data a byte at a time for all combinations of CRC register values and incoming bytes. The remaining tables allow for word-at-a-time CRC calculation for both big-endian and little- endian machines, where a word is four bytes. */ local void make_crc_table() { unsigned long c; int n, k; unsigned long poly; /* polynomial exclusive-or pattern */ /* terms of polynomial defining this crc (except x^32): */ static volatile int first = 1; /* flag to limit concurrent making */ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; /* See if another task is already doing this (not thread-safe, but better than nothing -- significantly reduces duration of vulnerability in case the advice about DYNAMIC_CRC_TABLE is ignored) */ if (first) { first = 0; /* make exclusive-or pattern from polynomial (0xedb88320UL) */ poly = 0UL; for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) poly |= 1UL << (31 - p[n]); /* generate a crc for every 8-bit value */ for (n = 0; n < 256; n++) { c = (unsigned long)n; for (k = 0; k < 8; k++) c = c & 1 ? poly ^ (c >> 1) : c >> 1; crc_table[0][n] = c; } #ifdef BYFOUR /* generate crc for each value followed by one, two, and three zeros, and then the byte reversal of those as well as the first table */ for (n = 0; n < 256; n++) { c = crc_table[0][n]; crc_table[4][n] = REV(c); for (k = 1; k < 4; k++) { c = crc_table[0][c & 0xff] ^ (c >> 8); crc_table[k][n] = c; crc_table[k + 4][n] = REV(c); } } #endif /* BYFOUR */ crc_table_empty = 0; } else { /* not first */ /* wait for the other guy to finish (not efficient, but rare) */ while (crc_table_empty) ; } #ifdef MAKECRCH /* write out CRC tables to crc32.h */ { FILE *out; out = fopen("crc32.h", "w"); if (out == NULL) return; fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); fprintf(out, "local const unsigned long FAR "); fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); write_table(out, crc_table[0]); # ifdef BYFOUR fprintf(out, "#ifdef BYFOUR\n"); for (k = 1; k < 8; k++) { fprintf(out, " },\n {\n"); write_table(out, crc_table[k]); } fprintf(out, "#endif\n"); # endif /* BYFOUR */ fprintf(out, " }\n};\n"); fclose(out); } #endif /* MAKECRCH */ } #ifdef MAKECRCH local void write_table(out, table) FILE *out; const unsigned long FAR *table; { int n; for (n = 0; n < 256; n++) fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); } #endif /* MAKECRCH */ #else /* !DYNAMIC_CRC_TABLE */ /* ======================================================================== * Tables of CRC-32s of all single-byte values, made by make_crc_table(). */ #include "crc32.h" #endif /* DYNAMIC_CRC_TABLE */ /* ========================================================================= * This function can be used by asm versions of crc32() */ const unsigned long FAR * ZEXPORT get_crc_table() { #ifdef DYNAMIC_CRC_TABLE if (crc_table_empty) make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ return (const unsigned long FAR *)crc_table; } /* ========================================================================= */ #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 /* ========================================================================= */ unsigned long ZEXPORT crc32(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { if (buf == Z_NULL) return 0UL; #ifdef DYNAMIC_CRC_TABLE if (crc_table_empty) make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ #ifdef BYFOUR if (sizeof(void *) == sizeof(ptrdiff_t)) { u4 endian; endian = 1; if (*((unsigned char *)(&endian))) return crc32_little(crc, buf, len); else return crc32_big(crc, buf, len); } #endif /* BYFOUR */ crc = crc ^ 0xffffffffUL; while (len >= 8) { DO8; len -= 8; } if (len) do { DO1; } while (--len); return crc ^ 0xffffffffUL; } #ifdef BYFOUR /* ========================================================================= */ #define DOLIT4 c ^= *buf4++; \ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 /* ========================================================================= */ local unsigned long crc32_little(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { register u4 c; register const u4 FAR *buf4; c = (u4)crc; c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); len--; } buf4 = (const u4 FAR *)(const void FAR *)buf; while (len >= 32) { DOLIT32; len -= 32; } while (len >= 4) { DOLIT4; len -= 4; } buf = (const unsigned char FAR *)buf4; if (len) do { c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); } while (--len); c = ~c; return (unsigned long)c; } /* ========================================================================= */ #define DOBIG4 c ^= *++buf4; \ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 /* ========================================================================= */ local unsigned long crc32_big(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { register u4 c; register const u4 FAR *buf4; c = REV((u4)crc); c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); len--; } buf4 = (const u4 FAR *)(const void FAR *)buf; buf4--; while (len >= 32) { DOBIG32; len -= 32; } while (len >= 4) { DOBIG4; len -= 4; } buf4++; buf = (const unsigned char FAR *)buf4; if (len) do { c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); } while (--len); c = ~c; return (unsigned long)(REV(c)); } #endif /* BYFOUR */ #define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ /* ========================================================================= */ local unsigned long gf2_matrix_times(mat, vec) unsigned long *mat; unsigned long vec; { unsigned long sum; sum = 0; while (vec) { if (vec & 1) sum ^= *mat; vec >>= 1; mat++; } return sum; } /* ========================================================================= */ local void gf2_matrix_square(square, mat) unsigned long *square; unsigned long *mat; { int n; for (n = 0; n < GF2_DIM; n++) square[n] = gf2_matrix_times(mat, mat[n]); } /* ========================================================================= */ uLong ZEXPORT crc32_combine(crc1, crc2, len2) uLong crc1; uLong crc2; z_off_t len2; { int n; unsigned long row; unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ /* degenerate case */ if (len2 == 0) return crc1; /* put operator for one zero bit in odd */ odd[0] = 0xedb88320L; /* CRC-32 polynomial */ row = 1; for (n = 1; n < GF2_DIM; n++) { odd[n] = row; row <<= 1; } /* put operator for two zero bits in even */ gf2_matrix_square(even, odd); /* put operator for four zero bits in odd */ gf2_matrix_square(odd, even); /* apply len2 zeros to crc1 (first square will put the operator for one zero byte, eight zero bits, in even) */ do { /* apply zeros operator for this bit of len2 */ gf2_matrix_square(even, odd); if (len2 & 1) crc1 = gf2_matrix_times(even, crc1); len2 >>= 1; /* if no more bits set, then done */ if (len2 == 0) break; /* another iteration of the loop with odd and even swapped */ gf2_matrix_square(odd, even); if (len2 & 1) crc1 = gf2_matrix_times(odd, crc1); len2 >>= 1; /* if no more bits set, then done */ } while (len2 != 0); /* return combined crc */ crc1 ^= crc2; return crc1; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/inftrees.c0000644000175000017500000003340511300022650021761 0ustar salvisalvi/* inftrees.c -- generate Huffman trees for efficient decoding * Copyright (C) 1995-2005 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "inftrees.h" #define MAXBITS 15 const char inflate_copyright[] = " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ /* Build a set of tables to decode the provided canonical Huffman code. The code lengths are lens[0..codes-1]. The result starts at *table, whose indices are 0..2^bits-1. work is a writable array of at least lens shorts, which is used as a work area. type is the type of code to be generated, CODES, LENS, or DISTS. On return, zero is success, -1 is an invalid code, and +1 means that ENOUGH isn't enough. table on return points to the next available entry's address. bits is the requested root table index bits, and on return it is the actual root table index bits. It will differ if the request is greater than the longest code or if it is less than the shortest code. */ int inflate_table(type, lens, codes, table, bits, work) codetype type; unsigned short FAR *lens; unsigned codes; code FAR * FAR *table; unsigned FAR *bits; unsigned short FAR *work; { unsigned len; /* a code's length in bits */ unsigned sym; /* index of code symbols */ unsigned min, max; /* minimum and maximum code lengths */ unsigned root; /* number of index bits for root table */ unsigned curr; /* number of index bits for current table */ unsigned drop; /* code bits to drop for sub-table */ int left; /* number of prefix codes available */ unsigned used; /* code entries in table used */ unsigned huff; /* Huffman code */ unsigned incr; /* for incrementing code, index */ unsigned fill; /* index for replicating entries */ unsigned low; /* low bits for current root entry */ unsigned mask; /* mask for low root bits */ code this; /* table entry for duplication */ code FAR *next; /* next available space in table */ const unsigned short FAR *base; /* base value table to use */ const unsigned short FAR *extra; /* extra bits table to use */ int end; /* use base and extra for symbol > end */ unsigned short count[MAXBITS+1]; /* number of codes of each length */ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ static const unsigned short lbase[31] = { /* Length codes 257..285 base */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0}; static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64}; /* Process a set of code lengths to create a canonical Huffman code. The code lengths are lens[0..codes-1]. Each length corresponds to the symbols 0..codes-1. The Huffman code is generated by first sorting the symbols by length from short to long, and retaining the symbol order for codes with equal lengths. Then the code starts with all zero bits for the first code of the shortest length, and the codes are integer increments for the same length, and zeros are appended as the length increases. For the deflate format, these bits are stored backwards from their more natural integer increment ordering, and so when the decoding tables are built in the large loop below, the integer codes are incremented backwards. This routine assumes, but does not check, that all of the entries in lens[] are in the range 0..MAXBITS. The caller must assure this. 1..MAXBITS is interpreted as that code length. zero means that that symbol does not occur in this code. The codes are sorted by computing a count of codes for each length, creating from that a table of starting indices for each length in the sorted table, and then entering the symbols in order in the sorted table. The sorted table is work[], with that space being provided by the caller. The length counts are used for other purposes as well, i.e. finding the minimum and maximum length codes, determining if there are any codes at all, checking for a valid set of lengths, and looking ahead at length counts to determine sub-table sizes when building the decoding tables. */ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ for (len = 0; len <= MAXBITS; len++) count[len] = 0; for (sym = 0; sym < codes; sym++) count[lens[sym]]++; /* bound code lengths, force root to be within code lengths */ root = *bits; for (max = MAXBITS; max >= 1; max--) if (count[max] != 0) break; if (root > max) root = max; if (max == 0) { /* no symbols to code at all */ this.op = (unsigned char)64; /* invalid code marker */ this.bits = (unsigned char)1; this.val = (unsigned short)0; *(*table)++ = this; /* make a table to force an error */ *(*table)++ = this; *bits = 1; return 0; /* no symbols, but wait for decoding to report error */ } for (min = 1; min <= MAXBITS; min++) if (count[min] != 0) break; if (root < min) root = min; /* check for an over-subscribed or incomplete set of lengths */ left = 1; for (len = 1; len <= MAXBITS; len++) { left <<= 1; left -= count[len]; if (left < 0) return -1; /* over-subscribed */ } if (left > 0 && (type == CODES || max != 1)) return -1; /* incomplete set */ /* generate offsets into symbol table for each length for sorting */ offs[1] = 0; for (len = 1; len < MAXBITS; len++) offs[len + 1] = offs[len] + count[len]; /* sort symbols by length, by symbol order within each length */ for (sym = 0; sym < codes; sym++) if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; /* Create and fill in decoding tables. In this loop, the table being filled is at next and has curr index bits. The code being used is huff with length len. That code is converted to an index by dropping drop bits off of the bottom. For codes where len is less than drop + curr, those top drop + curr - len bits are incremented through all values to fill the table with replicated entries. root is the number of index bits for the root table. When len exceeds root, sub-tables are created pointed to by the root entry with an index of the low root bits of huff. This is saved in low to check for when a new sub-table should be started. drop is zero when the root table is being filled, and drop is root when sub-tables are being filled. When a new sub-table is needed, it is necessary to look ahead in the code lengths to determine what size sub-table is needed. The length counts are used for this, and so count[] is decremented as codes are entered in the tables. used keeps track of how many table entries have been allocated from the provided *table space. It is checked when a LENS table is being made against the space in *table, ENOUGH, minus the maximum space needed by the worst case distance code, MAXD. This should never happen, but the sufficiency of ENOUGH has not been proven exhaustively, hence the check. This assumes that when type == LENS, bits == 9. sym increments through all symbols, and the loop terminates when all codes of length max, i.e. all codes, have been processed. This routine permits incomplete codes, so another loop after this one fills in the rest of the decoding tables with invalid code markers. */ /* set up for code type */ switch (type) { case CODES: base = extra = work; /* dummy value--not used */ end = 19; break; case LENS: base = lbase; base -= 257; extra = lext; extra -= 257; end = 256; break; default: /* DISTS */ base = dbase; extra = dext; end = -1; } /* initialize state for loop */ huff = 0; /* starting code */ sym = 0; /* starting code symbol */ len = min; /* starting code length */ next = *table; /* current table to fill in */ curr = root; /* current table index bits */ drop = 0; /* current bits to drop from code for index */ low = (unsigned)(-1); /* trigger new sub-table when len > root */ used = 1U << root; /* use root table entries */ mask = used - 1; /* mask for comparing low */ /* check available table space */ if (type == LENS && used >= ENOUGH - MAXD) return 1; /* process all codes and make table entries */ for (;;) { /* create table entry */ this.bits = (unsigned char)(len - drop); if ((int)(work[sym]) < end) { this.op = (unsigned char)0; this.val = work[sym]; } else if ((int)(work[sym]) > end) { this.op = (unsigned char)(extra[work[sym]]); this.val = base[work[sym]]; } else { this.op = (unsigned char)(32 + 64); /* end of block */ this.val = 0; } /* replicate for those indices with low len bits equal to huff */ incr = 1U << (len - drop); fill = 1U << curr; min = fill; /* save offset to next table */ do { fill -= incr; next[(huff >> drop) + fill] = this; } while (fill != 0); /* backwards increment the len-bit code huff */ incr = 1U << (len - 1); while (huff & incr) incr >>= 1; if (incr != 0) { huff &= incr - 1; huff += incr; } else huff = 0; /* go to next symbol, update count, len */ sym++; if (--(count[len]) == 0) { if (len == max) break; len = lens[work[sym]]; } /* create new sub-table if needed */ if (len > root && (huff & mask) != low) { /* if first time, transition to sub-tables */ if (drop == 0) drop = root; /* increment past last table */ next += min; /* here min is 1 << curr */ /* determine length of next table */ curr = len - drop; left = (int)(1 << curr); while (curr + drop < max) { left -= count[curr + drop]; if (left <= 0) break; curr++; left <<= 1; } /* check for enough space */ used += 1U << curr; if (type == LENS && used >= ENOUGH - MAXD) return 1; /* point entry in root table to sub-table */ low = huff & mask; (*table)[low].op = (unsigned char)curr; (*table)[low].bits = (unsigned char)root; (*table)[low].val = (unsigned short)(next - *table); } } /* Fill in rest of table for incomplete codes. This loop is similar to the loop above in incrementing huff for table indices. It is assumed that len is equal to curr + drop, so there is no loop needed to increment through high index bits. When the current sub-table is filled, the loop drops back to the root table to fill in any remaining entries there. */ this.op = (unsigned char)64; /* invalid code marker */ this.bits = (unsigned char)(len - drop); this.val = (unsigned short)0; while (huff != 0) { /* when done with sub-table, drop back to root table */ if (drop != 0 && (huff & mask) != low) { drop = 0; len = root; next = *table; this.bits = (unsigned char)len; } /* put invalid code marker in table */ next[huff >> drop] = this; /* backwards increment the len-bit code huff */ incr = 1U << (len - 1); while (huff & incr) incr >>= 1; if (incr != 0) { huff &= incr - 1; huff += incr; } else huff = 0; } /* set return parameters */ *table += used; *bits = root; return 0; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/zutil.c0000644000175000017500000001643611300022650021316 0ustar salvisalvi/* zutil.c -- target dependent utility functions for the compression library * Copyright (C) 1995-2005 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #include "zutil.h" #ifndef NO_DUMMY_DECL struct internal_state {int dummy;}; /* for buggy compilers */ #endif const char * const z_errmsg[10] = { "need dictionary", /* Z_NEED_DICT 2 */ "stream end", /* Z_STREAM_END 1 */ "", /* Z_OK 0 */ "file error", /* Z_ERRNO (-1) */ "stream error", /* Z_STREAM_ERROR (-2) */ "data error", /* Z_DATA_ERROR (-3) */ "insufficient memory", /* Z_MEM_ERROR (-4) */ "buffer error", /* Z_BUF_ERROR (-5) */ "incompatible version",/* Z_VERSION_ERROR (-6) */ ""}; const char * ZEXPORT zlibVersion() { return ZLIB_VERSION; } uLong ZEXPORT zlibCompileFlags() { uLong flags; flags = 0; switch (sizeof(uInt)) { case 2: break; case 4: flags += 1; break; case 8: flags += 2; break; default: flags += 3; } switch (sizeof(uLong)) { case 2: break; case 4: flags += 1 << 2; break; case 8: flags += 2 << 2; break; default: flags += 3 << 2; } switch (sizeof(voidpf)) { case 2: break; case 4: flags += 1 << 4; break; case 8: flags += 2 << 4; break; default: flags += 3 << 4; } switch (sizeof(z_off_t)) { case 2: break; case 4: flags += 1 << 6; break; case 8: flags += 2 << 6; break; default: flags += 3 << 6; } #ifdef DEBUG flags += 1 << 8; #endif #if defined(ASMV) || defined(ASMINF) flags += 1 << 9; #endif #ifdef ZLIB_WINAPI flags += 1 << 10; #endif #ifdef BUILDFIXED flags += 1 << 12; #endif #ifdef DYNAMIC_CRC_TABLE flags += 1 << 13; #endif #ifdef NO_GZCOMPRESS flags += 1L << 16; #endif #ifdef NO_GZIP flags += 1L << 17; #endif #ifdef PKZIP_BUG_WORKAROUND flags += 1L << 20; #endif #ifdef FASTEST flags += 1L << 21; #endif #ifdef STDC # ifdef NO_vsnprintf flags += 1L << 25; # ifdef HAS_vsprintf_void flags += 1L << 26; # endif # else # ifdef HAS_vsnprintf_void flags += 1L << 26; # endif # endif #else flags += 1L << 24; # ifdef NO_snprintf flags += 1L << 25; # ifdef HAS_sprintf_void flags += 1L << 26; # endif # else # ifdef HAS_snprintf_void flags += 1L << 26; # endif # endif #endif return flags; } #ifdef DEBUG # ifndef verbose # define verbose 0 # endif int z_verbose = verbose; void z_error (m) char *m; { fprintf(stderr, "%s\n", m); exit(1); } #endif /* exported to allow conversion of error code to string for compress() and * uncompress() */ const char * ZEXPORT zError(err) int err; { return ERR_MSG(err); } #if defined(_WIN32_WCE) /* The Microsoft C Run-Time Library for Windows CE doesn't have * errno. We define it as a global variable to simplify porting. * Its value is always 0 and should not be used. */ int errno = 0; #endif #ifndef HAVE_MEMCPY void zmemcpy(dest, source, len) Bytef* dest; const Bytef* source; uInt len; { if (len == 0) return; do { *dest++ = *source++; /* ??? to be unrolled */ } while (--len != 0); } int zmemcmp(s1, s2, len) const Bytef* s1; const Bytef* s2; uInt len; { uInt j; for (j = 0; j < len; j++) { if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; } return 0; } void zmemzero(dest, len) Bytef* dest; uInt len; { if (len == 0) return; do { *dest++ = 0; /* ??? to be unrolled */ } while (--len != 0); } #endif #ifdef SYS16BIT #ifdef __TURBOC__ /* Turbo C in 16-bit mode */ # define MY_ZCALLOC /* Turbo C malloc() does not allow dynamic allocation of 64K bytes * and farmalloc(64K) returns a pointer with an offset of 8, so we * must fix the pointer. Warning: the pointer must be put back to its * original form in order to free it, use zcfree(). */ #define MAX_PTR 10 /* 10*64K = 640K */ local int next_ptr = 0; typedef struct ptr_table_s { voidpf org_ptr; voidpf new_ptr; } ptr_table; local ptr_table table[MAX_PTR]; /* This table is used to remember the original form of pointers * to large buffers (64K). Such pointers are normalized with a zero offset. * Since MSDOS is not a preemptive multitasking OS, this table is not * protected from concurrent access. This hack doesn't work anyway on * a protected system like OS/2. Use Microsoft C instead. */ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) { voidpf buf = opaque; /* just to make some compilers happy */ ulg bsize = (ulg)items*size; /* If we allocate less than 65520 bytes, we assume that farmalloc * will return a usable pointer which doesn't have to be normalized. */ if (bsize < 65520L) { buf = farmalloc(bsize); if (*(ush*)&buf != 0) return buf; } else { buf = farmalloc(bsize + 16L); } if (buf == NULL || next_ptr >= MAX_PTR) return NULL; table[next_ptr].org_ptr = buf; /* Normalize the pointer to seg:0 */ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; *(ush*)&buf = 0; table[next_ptr++].new_ptr = buf; return buf; } void zcfree (voidpf opaque, voidpf ptr) { int n; if (*(ush*)&ptr != 0) { /* object < 64K */ farfree(ptr); return; } /* Find the original pointer */ for (n = 0; n < next_ptr; n++) { if (ptr != table[n].new_ptr) continue; farfree(table[n].org_ptr); while (++n < next_ptr) { table[n-1] = table[n]; } next_ptr--; return; } ptr = opaque; /* just to make some compilers happy */ Assert(0, "zcfree: ptr not found"); } #endif /* __TURBOC__ */ #ifdef M_I86 /* Microsoft C in 16-bit mode */ # define MY_ZCALLOC #if (!defined(_MSC_VER) || (_MSC_VER <= 600)) # define _halloc halloc # define _hfree hfree #endif voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) { if (opaque) opaque = 0; /* to make compiler happy */ return _halloc((long)items, size); } void zcfree (voidpf opaque, voidpf ptr) { if (opaque) opaque = 0; /* to make compiler happy */ _hfree(ptr); } #endif /* M_I86 */ #endif /* SYS16BIT */ #ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef STDC extern voidp malloc OF((uInt size)); extern voidp calloc OF((uInt items, uInt size)); extern void free OF((voidpf ptr)); #endif voidpf zcalloc (opaque, items, size) voidpf opaque; unsigned items; unsigned size; { if (opaque) items += size - size; /* make compiler happy */ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : (voidpf)calloc(items, size); } void zcfree (opaque, ptr) voidpf opaque; voidpf ptr; { free(ptr); if (opaque) return; /* make compiler happy */ } #endif /* MY_ZCALLOC */ tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/compress.c0000644000175000017500000000501011300022650021764 0ustar salvisalvi/* compress.c -- compress a memory buffer * Copyright (C) 1995-2003 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #define ZLIB_INTERNAL #include "zlib.h" /* =========================================================================== Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least 0.1% larger than sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) Bytef *dest; uLongf *destLen; const Bytef *source; uLong sourceLen; int level; { z_stream stream; int err; stream.next_in = (Bytef*)source; stream.avail_in = (uInt)sourceLen; #ifdef MAXSEG_64K /* Check for source > 64K on 16-bit machine: */ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; #endif stream.next_out = dest; stream.avail_out = (uInt)*destLen; if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; stream.opaque = (voidpf)0; err = deflateInit(&stream, level); if (err != Z_OK) return err; err = deflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { deflateEnd(&stream); return err == Z_OK ? Z_BUF_ERROR : err; } *destLen = stream.total_out; err = deflateEnd(&stream); return err; } /* =========================================================================== */ int ZEXPORT compress (dest, destLen, source, sourceLen) Bytef *dest; uLongf *destLen; const Bytef *source; uLong sourceLen; { return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); } /* =========================================================================== If the default memLevel or windowBits for deflateInit() is changed, then this function needs to be updated. */ uLong ZEXPORT compressBound (sourceLen) uLong sourceLen; { return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/zlib/deflate.h0000644000175000017500000003023511300022650021551 0ustar salvisalvi/* deflate.h -- internal compression state * Copyright (C) 1995-2004 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* @(#) $Id$ */ #ifndef DEFLATE_H #define DEFLATE_H #include "zutil.h" /* define NO_GZIP when compiling if you want to disable gzip header and trailer creation by deflate(). NO_GZIP would be used to avoid linking in the crc code when it is not needed. For shared libraries, gzip encoding should be left enabled. */ #ifndef NO_GZIP # define GZIP #endif /* =========================================================================== * Internal compression state. */ #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ #define LITERALS 256 /* number of literal bytes 0..255 */ #define L_CODES (LITERALS+1+LENGTH_CODES) /* number of Literal or Length codes, including the END_BLOCK code */ #define D_CODES 30 /* number of distance codes */ #define BL_CODES 19 /* number of codes used to transfer the bit lengths */ #define HEAP_SIZE (2*L_CODES+1) /* maximum heap size */ #define MAX_BITS 15 /* All codes must not exceed MAX_BITS bits */ #define INIT_STATE 42 #define EXTRA_STATE 69 #define NAME_STATE 73 #define COMMENT_STATE 91 #define HCRC_STATE 103 #define BUSY_STATE 113 #define FINISH_STATE 666 /* Stream status */ /* Data structure describing a single value and its code string. */ typedef struct ct_data_s { union { ush freq; /* frequency count */ ush code; /* bit string */ } fc; union { ush dad; /* father node in Huffman tree */ ush len; /* length of bit string */ } dl; } FAR ct_data; #define Freq fc.freq #define Code fc.code #define Dad dl.dad #define Len dl.len typedef struct static_tree_desc_s static_tree_desc; typedef struct tree_desc_s { ct_data *dyn_tree; /* the dynamic tree */ int max_code; /* largest code with non zero frequency */ static_tree_desc *stat_desc; /* the corresponding static tree */ } FAR tree_desc; typedef ush Pos; typedef Pos FAR Posf; typedef unsigned IPos; /* A Pos is an index in the character window. We use short instead of int to * save space in the various tables. IPos is used only for parameter passing. */ typedef struct internal_state { z_streamp strm; /* pointer back to this zlib stream */ int status; /* as the name implies */ Bytef *pending_buf; /* output still pending */ ulg pending_buf_size; /* size of pending_buf */ Bytef *pending_out; /* next pending byte to output to the stream */ uInt pending; /* nb of bytes in the pending buffer */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ gz_headerp gzhead; /* gzip header information to write */ uInt gzindex; /* where in extra, name, or comment */ Byte method; /* STORED (for zip only) or DEFLATED */ int last_flush; /* value of flush param for previous deflate call */ /* used by deflate.c: */ uInt w_size; /* LZ77 window size (32K by default) */ uInt w_bits; /* log2(w_size) (8..16) */ uInt w_mask; /* w_size - 1 */ Bytef *window; /* Sliding window. Input bytes are read into the second half of the window, * and move to the first half later to keep a dictionary of at least wSize * bytes. With this organization, matches are limited to a distance of * wSize-MAX_MATCH bytes, but this ensures that IO is always * performed with a length multiple of the block size. Also, it limits * the window size to 64K, which is quite useful on MSDOS. * To do: use the user input buffer as sliding window. */ ulg window_size; /* Actual size of window: 2*wSize, except when the user input buffer * is directly used as sliding window. */ Posf *prev; /* Link to older string with same hash index. To limit the size of this * array to 64K, this link is maintained only for the last 32K strings. * An index in this array is thus a window index modulo 32K. */ Posf *head; /* Heads of the hash chains or NIL. */ uInt ins_h; /* hash index of string to be inserted */ uInt hash_size; /* number of elements in hash table */ uInt hash_bits; /* log2(hash_size) */ uInt hash_mask; /* hash_size-1 */ uInt hash_shift; /* Number of bits by which ins_h must be shifted at each input * step. It must be such that after MIN_MATCH steps, the oldest * byte no longer takes part in the hash key, that is: * hash_shift * MIN_MATCH >= hash_bits */ long block_start; /* Window position at the beginning of the current output block. Gets * negative when the window is moved backwards. */ uInt match_length; /* length of best match */ IPos prev_match; /* previous match */ int match_available; /* set if previous match exists */ uInt strstart; /* start of string to insert */ uInt match_start; /* start of matching string */ uInt lookahead; /* number of valid bytes ahead in window */ uInt prev_length; /* Length of the best match at previous step. Matches not greater than this * are discarded. This is used in the lazy match evaluation. */ uInt max_chain_length; /* To speed up deflation, hash chains are never searched beyond this * length. A higher limit improves compression ratio but degrades the * speed. */ uInt max_lazy_match; /* Attempt to find a better match only when the current match is strictly * smaller than this value. This mechanism is used only for compression * levels >= 4. */ # define max_insert_length max_lazy_match /* Insert new strings in the hash table only if the match length is not * greater than this length. This saves time but degrades compression. * max_insert_length is used only for compression levels <= 3. */ int level; /* compression level (1..9) */ int strategy; /* favor or force Huffman coding*/ uInt good_match; /* Use a faster search when the previous match is longer than this */ int nice_match; /* Stop searching when current match exceeds this */ /* used by trees.c: */ /* Didn't use ct_data typedef below to supress compiler warning */ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ struct tree_desc_s l_desc; /* desc. for literal tree */ struct tree_desc_s d_desc; /* desc. for distance tree */ struct tree_desc_s bl_desc; /* desc. for bit length tree */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ int heap_len; /* number of elements in the heap */ int heap_max; /* element of largest frequency */ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. * The same heap array is used to build all trees. */ uch depth[2*L_CODES+1]; /* Depth of each subtree used as tie breaker for trees of equal frequency */ uchf *l_buf; /* buffer for literals or lengths */ uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for * limiting lit_bufsize to 64K: * - frequencies can be kept in 16 bit counters * - if compression is not successful for the first block, all input * data is still in the window so we can still emit a stored block even * when input comes from standard input. (This can also be done for * all blocks if lit_bufsize is not greater than 32K.) * - if compression is not successful for a file smaller than 64K, we can * even emit a stored file instead of a stored block (saving 5 bytes). * This is applicable only for zip (not gzip or zlib). * - creating new Huffman trees less frequently may not provide fast * adaptation to changes in the input data statistics. (Take for * example a binary file with poorly compressible code followed by * a highly compressible string table.) Smaller buffer sizes give * fast adaptation but have of course the overhead of transmitting * trees more frequently. * - I can't count above 4 */ uInt last_lit; /* running index in l_buf */ ushf *d_buf; /* Buffer for distances. To simplify the code, d_buf and l_buf have * the same number of elements. To use different lengths, an extra flag * array would be necessary. */ ulg opt_len; /* bit length of current block with optimal trees */ ulg static_len; /* bit length of current block with static trees */ uInt matches; /* number of string matches in current block */ int last_eob_len; /* bit length of EOB code for last block */ #ifdef DEBUG ulg compressed_len; /* total bit length of compressed file mod 2^32 */ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ #endif ush bi_buf; /* Output buffer. bits are inserted starting at the bottom (least * significant bits). */ int bi_valid; /* Number of valid bits in bi_buf. All bits above the last valid bit * are always zero. */ } FAR deflate_state; /* Output a byte on the stream. * IN assertion: there is enough room in pending_buf. */ #define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) /* In order to simplify the code, particularly on 16 bit machines, match * distances are limited to MAX_DIST instead of WSIZE. */ /* in trees.c */ void _tr_init OF((deflate_state *s)); int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof)); void _tr_align OF((deflate_state *s)); void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof)); #define d_code(dist) \ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and * must not have side effects. _dist_code[256] and _dist_code[257] are never * used. */ #ifndef DEBUG /* Inline versions of _tr_tally for speed: */ #if defined(GEN_TREES_H) || !defined(STDC) extern uch _length_code[]; extern uch _dist_code[]; #else extern const uch _length_code[]; extern const uch _dist_code[]; #endif # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->d_buf[s->last_lit] = 0; \ s->l_buf[s->last_lit++] = cc; \ s->dyn_ltree[cc].Freq++; \ flush = (s->last_lit == s->lit_bufsize-1); \ } # define _tr_tally_dist(s, distance, length, flush) \ { uch len = (length); \ ush dist = (distance); \ s->d_buf[s->last_lit] = dist; \ s->l_buf[s->last_lit++] = len; \ dist--; \ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->last_lit == s->lit_bufsize-1); \ } #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ flush = _tr_tally(s, distance, length) #endif #endif /* DEFLATE_H */ tuxcmd-modules-0.6.70+ds/zip/ZipArchive/DeflateCompressor.cpp0000644000175000017500000001533411300022650023164 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "DeflateCompressor.h" #include "zlib/deflate.h" namespace ZipArchiveLib { #ifndef DEF_MEM_LEVEL #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif #endif CDeflateCompressor::CDeflateCompressor(CZipStorage* pStorage) :CBaseLibCompressor(pStorage) { m_stream.zalloc = (zarch_alloc_func)_zipalloc; m_stream.zfree = (zarch_free_func)_zipfree; } void CDeflateCompressor::InitCompression(int iLevel, CZipFileHeader* pFile, CZipCryptograph* pCryptograph) { CZipCompressor::InitCompression(iLevel, pFile, pCryptograph); m_stream.avail_in = (zarch_uInt)0; m_stream.avail_out = (zarch_uInt)m_pBuffer.GetSize(); m_stream.next_out = (zarch_Bytef*)(char*)m_pBuffer; m_stream.total_in = 0; m_stream.total_out = 0; if (pFile->m_uMethod == methodDeflate) { SetOpaque(&m_stream.opaque, &m_options); int err = zarch_deflateInit2_(&m_stream, iLevel, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, ZLIB_VERSION, sizeof(zarch_z_stream)); CheckForError(err); } } void CDeflateCompressor::Compress(const void *pBuffer, DWORD uSize) { m_stream.next_in = (zarch_Bytef*)pBuffer; m_stream.avail_in = uSize; UpdateFileCrc(pBuffer, uSize); while (m_stream.avail_in > 0) { if (m_stream.avail_out == 0) { FlushWriteBuffer(); m_stream.avail_out = m_pBuffer.GetSize(); m_stream.next_out = (zarch_Bytef*)(char*)m_pBuffer; } if (m_pFile->m_uMethod == methodDeflate) { ZIP_ZLIB_TYPE uTotal = m_stream.total_out; CheckForError(zarch_deflate(&m_stream, Z_NO_FLUSH)); m_uComprLeft += m_stream.total_out - uTotal; } else { DWORD uToCopy = (m_stream.avail_in < m_stream.avail_out) ? m_stream.avail_in : m_stream.avail_out; memcpy(m_stream.next_out, m_stream.next_in, uToCopy); m_stream.avail_in -= uToCopy; m_stream.avail_out -= uToCopy; m_stream.next_in += uToCopy; m_stream.next_out += uToCopy; m_stream.total_in += uToCopy; m_stream.total_out += uToCopy; m_uComprLeft += uToCopy; } } } void CDeflateCompressor::FinishCompression(bool bAfterException) { m_stream.avail_in = 0; if (!bAfterException) { if (m_pFile->m_uMethod == methodDeflate) { int err; do { if (m_stream.avail_out == 0) { FlushWriteBuffer(); m_stream.avail_out = m_pBuffer.GetSize(); m_stream.next_out = (zarch_Bytef*)(char*)m_pBuffer; } ZIP_SIZE_TYPE uTotal = m_stream.total_out; err = zarch_deflate(&m_stream, Z_FINISH); m_uComprLeft += m_stream.total_out - uTotal; } while (err == Z_OK); if (err == Z_STREAM_END) err = Z_OK; CheckForError(err); } if (m_uComprLeft > 0) FlushWriteBuffer(); if (m_pFile->m_uMethod == methodDeflate) CheckForError(zarch_deflateEnd(&m_stream)); // it may be increased by the encrypted header size in CZipFileHeader::PrepareData m_pFile->m_uComprSize += m_stream.total_out; m_pFile->m_uUncomprSize = m_stream.total_in; } EmptyPtrList(); ReleaseBuffer(); } void CDeflateCompressor::InitDecompression(CZipFileHeader* pFile, CZipCryptograph* pCryptograph) { CBaseLibCompressor::InitDecompression(pFile, pCryptograph); if (m_pFile->m_uMethod == methodDeflate) { SetOpaque(&m_stream.opaque, &m_options); CheckForError(zarch_inflateInit2_(&m_stream, -MAX_WBITS, ZLIB_VERSION, sizeof(zarch_z_stream))); } m_stream.total_out = 0; m_stream.avail_in = 0; } DWORD CDeflateCompressor::Decompress(void *pBuffer, DWORD uSize) { if (m_bDecompressionDone) return 0; m_stream.next_out = (zarch_Bytef*)pBuffer; m_stream.avail_out = uSize > m_uUncomprLeft ? (DWORD)m_uUncomprLeft : uSize; DWORD uRead = 0; // may happen when the file is 0 sized bool bForce = m_stream.avail_out == 0 && m_uComprLeft > 0; while (m_stream.avail_out > 0 || (bForce && m_uComprLeft > 0)) { if ((m_stream.avail_in == 0) && (m_uComprLeft >= 0)) // Also when there are zero bytes left { DWORD uToRead = m_pBuffer.GetSize(); if (m_uComprLeft < uToRead) uToRead = (DWORD)m_uComprLeft; if (uToRead == 0) uToRead = 1; // Add dummy byte at end of compressed data. else { m_pStorage->Read(m_pBuffer, uToRead, false); if (m_pCryptograph) m_pCryptograph->Decode(m_pBuffer, uToRead); } m_uComprLeft -= uToRead; m_stream.next_in = (zarch_Bytef*)(char*)m_pBuffer; m_stream.avail_in = uToRead; } if (m_pFile->m_uMethod == methodStore) { DWORD uToCopy = m_stream.avail_out < m_stream.avail_in ? m_stream.avail_out : m_stream.avail_in; memcpy(m_stream.next_out, m_stream.next_in, uToCopy); UpdateCrc(m_stream.next_out, uToCopy); m_uUncomprLeft -= uToCopy; m_stream.avail_in -= uToCopy; m_stream.avail_out -= uToCopy; m_stream.next_out += uToCopy; m_stream.next_in += uToCopy; m_stream.total_out += uToCopy; uRead += uToCopy; } else { ZIP_SIZE_TYPE uTotal = m_stream.total_out; zarch_Bytef* pOldBuf = m_stream.next_out; int ret = zarch_inflate(&m_stream, Z_SYNC_FLUSH); // will not exceed DWORD DWORD uToCopy = (DWORD)(m_stream.total_out - uTotal); UpdateCrc(pOldBuf, uToCopy); m_uUncomprLeft -= uToCopy; uRead += uToCopy; if (ret == Z_STREAM_END) { m_bDecompressionDone = true; return uRead; } else CheckForError(ret); } } if (!uRead && m_options.m_bCheckLastBlock && uSize != 0 && m_pFile->m_uMethod == methodDeflate) { if (zarch_inflate(&m_stream, Z_SYNC_FLUSH) != Z_STREAM_END) // there were no more bytes to read and there was no ending block, // otherwise the method would return earlier ThrowError(CZipException::badZipFile); } return uRead; } void CDeflateCompressor::FinishDecompression(bool bAfterException) { if (!bAfterException && m_pFile->m_uMethod == methodDeflate) zarch_inflateEnd(&m_stream); EmptyPtrList(); ReleaseBuffer(); } } // namespace tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipString_stl.h0000644000175000017500000001763211300022650022026 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #ifndef ZIPARCHIVE_ZIPSTRING_DOT_H #error Do not include this file directly. Include ZipString.h instead #endif #include "stdafx.h" #if _MSC_VER > 1000 #pragma warning( push, 3 ) // STL requirements #endif #include #include #include #include #include #include #include "ZipExport.h" #ifndef __GNUC__ #ifndef _vsntprintf #ifdef _UNICODE #define _vsntprintf _vsnwprintf #else #define _vsntprintf _vsnprintf #endif #endif #elif !defined(_vsntprintf) #define _vsntprintf vsnprintf #endif typedef std::basic_string stdbs; /** It contains mostly the methods required by ZipArchive Library. */ class ZIP_API CZipString : public stdbs { void TrimInternalL(size_type iPos) { if (iPos == npos) erase (); if (iPos) erase(0, iPos); } void TrimInternalR(size_type iPos) { if (iPos == npos) erase (); erase(++iPos); } #ifndef __GNUC__ static int zslen(const TCHAR* lpsz) { if (!lpsz) return 0; // we want to take into account the locale stuff (by using standard templates) #ifdef _UNICODE return (int)std::wstring(lpsz).length(); #else return (int)std::string(lpsz).length(); #endif } #else static int zslen(const TCHAR* lpsz) { #if (__GNUC__ < 3) // I'm not sure which precisely version should be put here return lpsz ? std::string_char_traits::length(lpsz) : 0; #else return lpsz ? std::char_traits::length(lpsz) : 0; #endif } #endif static TCHAR tl(TCHAR c) { // use_facet doesn't work here well (doesn't convert all the local characters properly) return std::tolower(c, std::locale()); } static TCHAR tu(TCHAR c) { // use_facet doesn't work here well (doesn't convert all the local characters properly) return std::toupper(c, std::locale()); } public: CZipString(){} explicit CZipString (TCHAR ch, int nRepeat = 1):stdbs(nRepeat, ch){} CZipString( const CZipString& stringSrc ) {assign(stringSrc);} CZipString( const stdbs& stringSrc ) {assign(stringSrc);} CZipString( LPCTSTR lpsz ){if (!lpsz) Empty(); else assign(lpsz);} operator LPCTSTR() const{return c_str();} int GetLength() const {return (int) size();} bool IsEmpty() const {return empty();} void Empty() {erase(begin(), end());} TCHAR GetAt (int iIndex) const{return at(iIndex);} TCHAR operator[] (int iIndex) const{return at(iIndex);} void SetAt( int nIndex, TCHAR ch ) {at(nIndex) = ch;} LPTSTR GetBuffer(int nMinBufLength) { if ((int)size() < nMinBufLength) resize(nMinBufLength); return empty() ? const_cast(data()) : &(at(0)); } void ReleaseBuffer( int nNewLength = -1 ) { resize(nNewLength > -1 ? nNewLength : zslen(c_str()));} void TrimLeft( TCHAR chTarget ) { TrimInternalL(find_first_not_of(chTarget)); } void TrimLeft( LPCTSTR lpszTargets ) { TrimInternalL(find_first_not_of(lpszTargets)); } void TrimRight( TCHAR chTarget ) { TrimInternalR(find_last_not_of(chTarget)); } void TrimRight( LPCTSTR lpszTargets ) { TrimInternalR(find_last_not_of(lpszTargets)); } #if _MSC_VER >= 1300 #pragma warning( push ) #pragma warning (disable : 4793) // 'vararg' : causes native code generation for function 'void CZipString::Format(LPCTSTR,...)' #endif void Format(LPCTSTR lpszFormat, ...) { va_list arguments; va_start (arguments, lpszFormat); TCHAR* pBuf = NULL; int iCounter = 1, uTotal = 0; do { int nChars = iCounter * 1024; int nLen = sizeof(TCHAR) * nChars; TCHAR* pTempBuf = (TCHAR*)realloc((void*)pBuf, nLen); if (!pTempBuf) { if (pBuf != NULL) free(pBuf); va_end (arguments); return; } pBuf = pTempBuf; #if _MSC_VER >= 1400 uTotal = _vsntprintf_s(pBuf, nChars, nChars - 1, lpszFormat, arguments); #else uTotal = _vsntprintf(pBuf, nChars - 1, lpszFormat, arguments); #endif if (uTotal == -1 || (uTotal == nChars - 1) ) // for some implementations { pBuf[nChars - 1] = _T('\0'); if (iCounter == 7) break; } else { pBuf[uTotal] = _T('\0'); break; } iCounter++; } while (true); va_end (arguments); *this = pBuf; free(pBuf); } #if _MSC_VER >= 1300 #pragma warning( pop ) #endif void Insert( int nIndex, LPCTSTR pstr ){insert(nIndex, pstr, zslen(pstr));} void Insert( int nIndex, TCHAR ch ) {insert(nIndex, 1, ch);} int Delete( int nIndex, int nCount = 1 ) { int iSize = (int) size(); int iToDelete = iSize < nIndex + nCount ? iSize - nIndex : nCount; if (iToDelete > 0) { erase(nIndex, iToDelete); iSize -= iToDelete; } return iSize; } #ifndef __MINGW32__ void MakeLower() { std::transform(begin(),end(),begin(),tl); } void MakeUpper() { std::transform(begin(),end(),begin(),tu); } #else void MakeLower() { std::transform(begin(),end(),begin(),tolower); } void MakeUpper() { std::transform(begin(),end(),begin(),toupper); } #endif void MakeReverse() { std::reverse(begin(), end()); } CZipString Left( int nCount ) const { return substr(0, nCount);} CZipString Right( int nCount) const { nCount = (int)size() < nCount ? (int)size() : nCount; return substr(size() - nCount); } CZipString Mid( int nFirst ) const {return substr(nFirst);} CZipString Mid( int nFirst, int nCount ) const {return substr(nFirst, nCount);} int Collate( LPCTSTR lpsz ) const { #if !defined __GNUC__ || defined __MINGW32__ return _tcscoll(c_str(), lpsz); #else //return compare(lpsz); return strcoll(c_str(), lpsz); #endif } int CollateNoCase( LPCTSTR lpsz ) const { #if !defined __GNUC__ || defined __MINGW32__ return _tcsicoll(c_str(), lpsz); #else if (std::locale() == std::locale::classic()) return strcasecmp(c_str(), lpsz); else // this may be not case-insensitive !!! return strcoll(c_str(), lpsz); //return stricoll(c_str(), lpsz); #endif } int Compare( LPCTSTR lpsz ) const { return compare(lpsz); } int CompareNoCase( LPCTSTR lpsz ) const { #if !defined __GNUC__ || defined __MINGW32__ return _tcsicmp(c_str(), lpsz); #else return strcasecmp(c_str(), lpsz); //return stricmp(c_str(), lpsz); #endif } bool operator != (LPCTSTR lpsz) { return Compare(lpsz) != 0; } bool operator == (LPCTSTR lpsz) { return Compare(lpsz) == 0; } int Find( TCHAR ch, int nStart = 0) const { return (int) find(ch, nStart); } int Find( LPCTSTR pstr, int nStart = 0) const { return (int) find(pstr, nStart); } int Replace( TCHAR chOld, TCHAR chNew ) { int iCount = 0; for (iterator it = begin(); it != end(); ++it) if (*it == chOld) { *it = chNew; iCount++; } return iCount; } }; /** A poiter type to point to CZipString to Collate or CollateNoCase or Compare or CompareNoCase */ typedef int (CZipString::*ZIPSTRINGCOMPARE)( LPCTSTR ) const; /** return a pointer to the function in CZipString structure, used to compare elements depending on the arguments */ ZIP_API ZIPSTRINGCOMPARE GetCZipStrCompFunc(bool bCaseSensitive, bool bCollate = true); #if _MSC_VER > 1000 #pragma warning( pop) #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipString_mfc.h0000644000175000017500000000235111300022650021761 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #ifndef ZIPARCHIVE_ZIPSTRING_DOT_H #error Do not include this file directly. Include ZipString.h instead #endif #include "stdafx.h" #include "ZipExport.h" typedef CString CZipString; /** A pointer type to point to one of: Collate, CollateNoCase, Compare, CompareNoCase. */ typedef int (CZipString::*ZIPSTRINGCOMPARE)( LPCTSTR ) const; /** Return a pointer to a method in the CZipString structure, used to compare elements depending on the arguments. */ ZIP_API ZIPSTRINGCOMPARE GetCZipStrCompFunc(bool bCaseSensitive, bool bCollate = true); tuxcmd-modules-0.6.70+ds/zip/ZipArchive/FileInfo.h0000644000175000017500000000357111300022650020703 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file FileInfo.h * Includes the ZipArchiveLib::CFileInfo class. * */ #if !defined(ZIPARCHIVE_FILEINFO_DOT_H) #define ZIPARCHIVE_FILEINFO_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "stdafx.h" #include "ZipExport.h" #include "ZipPlatform.h" namespace ZipArchiveLib { /** A structure holding a file or a directory information. */ struct ZIP_API CFileInfo { public: /** Initializes a new instance of the CFileInfo class. */ CFileInfo() { m_uSize = 0; m_uAttributes = 0; m_uCreateTime = m_uModTime = m_uAccessTime = 0; } ZIP_FILE_USIZE m_uSize; ///< The file size. DWORD m_uAttributes; ///< The file system attributes. time_t m_uCreateTime; ///< Creation time. time_t m_uModTime; ///< Last modification time. time_t m_uAccessTime; ///< Last access time. /** Returns the value indicating whether the current CFileInfo object represents a directory or a regular file. \return \c true, if the current CFileInfo object represents a directory; \c false, if it represents a regular file. */ bool IsDirectory() const { return ZipPlatform::IsDirectory(m_uAttributes); } }; } #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipStringStoreSettings.h0000644000175000017500000001173111300022650023674 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipStringStoreSettings.h * Includes the CZipStringStoreSettings class. * */ #if !defined(ZIPARCHIVE_ZIPSTRINGSTRINGSTORESETTINGS_DOT_H) #define ZIPARCHIVE_ZIPSTRINGSTRINGSTORESETTINGS_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "stdafx.h" #include "ZipPlatform.h" #include "ZipCompatibility.h" /** Settings used in storing strings inside archives. \see 0610051525 \see CZipArchive::SetStringStoreSettings. */ class ZIP_API CZipStringStoreSettings { public: /** Gets the default filename code page for the given platform. \param iPlatform One of the ZipCompatibility::ZipPlatforms values. \return The default filename code page. */ static UINT GetDefaultNameCodePage(int iPlatform) { return iPlatform == ZipCompatibility::zcDosFat ? CP_OEMCP : CP_ACP; } /** Gets the default filename code page for the current platform. \return The default filename code page. */ static UINT GetDefaultNameCodePage() { return GetDefaultNameCodePage(ZipPlatform::GetSystemID()); } /** Gets the default comment code page. It is not platform-dependent. */ static UINT GetDefaultCommentCodePage() { return CP_ACP; } /** Initializes a new instance of the CZipStringStoreSettings class. */ CZipStringStoreSettings() { Reset(); } /** Sets the default filename code page depening on the given platform. \param iPlatform One of the ZipCompatibility::ZipPlatforms values. */ void SetDefaultNameCodePage(int iPlatform) { m_uNameCodePage = GetDefaultNameCodePage(iPlatform); } /** Gets a value indicating whether the current filename code page is standard for the current platform or not. \return \c true, if the current filename code page is standard; \c false otherwise. \see ZipPlatform::GetSystemID */ bool IsStandardNameCodePage() const { return m_uNameCodePage == GetDefaultNameCodePage(); } /** Gets a value indicating whether the current filename code page is standard for the given platform or not. \param iPlatform One of the ZipCompatibility::ZipPlatforms values. \return \c true, if the current filename code page is standard; \c false otherwise. */ bool IsStandardNameCodePage(int iPlatform) const { return m_uNameCodePage == GetDefaultNameCodePage(iPlatform); } /** Gets a value indicating whether the current comment code page is standard. \return \c true, if the current comment code page is standard; \c false otherwise. */ bool IsStandardCommentCodePage() const { return m_uCommentCodePage == GetDefaultCommentCodePage(); } /** Gets a value indicating whether the current settings are standard for the given platform or not. \param iPlatform One of the ZipCompatibility::ZipPlatforms values. \return \c true, if the current settings are standard; \c false otherwise. */ bool IsStandard(int iPlatform) const { return !m_bStoreNameInExtraData && IsStandardNameCodePage(iPlatform) && IsStandardCommentCodePage(); } /** Reset the settings to its default values for the given platform. \param iPlatform One of the ZipCompatibility::ZipPlatforms values. \see Reset */ void Reset(int iPlatform) { m_bStoreNameInExtraData = false; SetDefaultNameCodePage(iPlatform); m_uCommentCodePage = GetDefaultCommentCodePage(); } /** Reset the settings to its default values for the current platform. \see Reset(int) \see ZipPlatform::GetSystemID */ void Reset() { Reset(ZipPlatform::GetSystemID()); } /** Sets the string store settings. \see CZipArchive::SetStringStoreSettings(UINT, bool, UINT) */ void Set(UINT uFileNameCodePage, bool bStoreNameInExtraData, UINT uCommentCodePage) { m_uNameCodePage = uFileNameCodePage; m_bStoreNameInExtraData = bStoreNameInExtraData; m_uCommentCodePage = uCommentCodePage; } /** If \c true, the converted filenames are stored in extra field in the archive. */ bool m_bStoreNameInExtraData; /** The current filename code page. */ UINT m_uNameCodePage; /** The current comment code page. */ UINT m_uCommentCodePage; }; #endif // !defined(ZIPARCHIVE_ZIPSTRINGSTRINGSTORESETTINGS_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipExtraField.cpp0000644000175000017500000000427711300022650022261 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipExtraField.h" bool CZipExtraField::Read(CZipStorage *pStorage, WORD uSize) { if (uSize == 0) return true; Clear(); CZipAutoBuffer buffer; buffer.Allocate(uSize); pStorage->Read(buffer, uSize, true); char* position = (char*) buffer; do { CZipExtraData* pExtra = new CZipExtraData(); if (!pExtra->Read(position, uSize)) { delete pExtra; return false; } int totalSize = pExtra->GetTotalSize(); if (totalSize > uSize || totalSize < 0) return false; position += totalSize; uSize = (WORD)(uSize - totalSize); Add(pExtra); } while (uSize > 0); return true; } void CZipExtraField::Write(char* buffer)const { int offset = 0; for (int i = 0; i < GetCount(); i++) offset += GetAt(i)->Write(buffer + offset); } int CZipExtraField::GetTotalSize()const { int total = 0; for (int i = 0; i < GetCount(); i++) total += GetAt(i)->GetTotalSize(); return total; } void CZipExtraField::RemoveInternalHeaders() { for (int i = GetCount() - 1; i >= 0; i--) { WORD headerID = GetAt(i)->GetHeaderID(); if ( headerID == ZIP_EXTRA_ZARCH_NAME) RemoveAt(i); } } CZipExtraData* CZipExtraField::Lookup(WORD headerID, int& index) const { // we can do a non-efficient search here // usually the number of extra fields is low, if any for (int i = 0; i < GetCount(); i++) { CZipExtraData* pExtra = GetAt(i); if (pExtra->m_uHeaderID == headerID) { index = i; return pExtra; } } return NULL; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipMutex.h0000644000175000017500000000200311300022650020762 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipMutex.h * Includes the ZipArchiveLib::CZipMutex class. * */ #if !defined(ZIPARCHIVE_ZIPMUTEX_DOT_H) #define ZIPARCHIVE_ZIPMUTEX_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "_features.h" #ifdef ZIP_ARCHIVE_LNX #include "ZipMutex_lnx.h" #else #include "ZipMutex_win.h" #endif #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipMemFile.cpp0000644000175000017500000000572411300022650021546 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipMemFile.h" #include "ZipException.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// void CZipMemFile::Grow(size_t nGrowTo) { if (m_nBufSize < (UINT)nGrowTo) { if (m_nGrowBy == 0) CZipException::Throw(CZipException::memError); size_t nNewSize = m_nBufSize; while (nNewSize < nGrowTo) nNewSize += m_nGrowBy; BYTE* lpNew; if (m_lpBuf) lpNew = (BYTE*)realloc((void*) m_lpBuf, nNewSize); else lpNew = (BYTE*)malloc(nNewSize); if (!lpNew) CZipException::Throw(CZipException::memError); m_nBufSize = nNewSize; m_lpBuf = lpNew; } } void CZipMemFile::SetLength(ZIP_FILE_USIZE nNewLen) { if (m_nBufSize < (size_t)nNewLen) Grow((size_t)nNewLen); else m_nPos = (size_t)nNewLen; m_nDataSize = (size_t)nNewLen; } UINT CZipMemFile::Read(void *lpBuf, UINT nCount) { if (m_nPos >= m_nDataSize) return 0; UINT nToRead = (m_nPos + nCount > m_nDataSize) ? (UINT)(m_nDataSize - m_nPos) : nCount; memcpy(lpBuf, m_lpBuf + m_nPos, nToRead); m_nPos += nToRead; return nToRead; } void CZipMemFile::Write(const void *lpBuf, UINT nCount) { if (!nCount) return; if (m_nPos + nCount > m_nBufSize) Grow(m_nPos + nCount); memcpy(m_lpBuf + m_nPos, lpBuf, nCount); m_nPos += nCount; if (m_nPos > m_nDataSize) m_nDataSize = m_nPos; } ZIP_FILE_USIZE CZipMemFile::Seek(ZIP_FILE_SIZE lOff, int nFrom) { ZIP_FILE_USIZE lNew = m_nPos; if (nFrom == CZipAbstractFile::begin) { if (lOff < 0) CZipException::Throw(CZipException::memError); lNew = lOff; } else if (nFrom == CZipAbstractFile::current) { if (lOff < 0 && (ZIP_FILE_USIZE)(-lOff) > lNew) CZipException::Throw(CZipException::memError); lNew += lOff; } else if (nFrom == CZipAbstractFile::end) { if (lOff < 0 && ZIP_FILE_USIZE(-lOff) > m_nDataSize) CZipException::Throw(CZipException::memError); lNew = m_nDataSize + lOff; } else return lNew; // assumption that size_t is always signed if (lNew > (size_t)(-1)) // max of size_t CZipException::Throw(CZipException::memError); if (lNew > m_nDataSize) Grow((size_t)lNew); m_nPos = (size_t)lNew; return lNew; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipArchive.sln0000644000175000017500000001001011300022650021603 0ustar salvisalviMicrosoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZipArchive", "ZipArchive.vcproj", "{A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug DLL|Win32 = Debug DLL|Win32 Debug MFC Static|Win32 = Debug MFC Static|Win32 Debug STL Unicode|Win32 = Debug STL Unicode|Win32 Debug STL|Win32 = Debug STL|Win32 Debug Unicode|Win32 = Debug Unicode|Win32 Debug|Win32 = Debug|Win32 Release DLL|Win32 = Release DLL|Win32 Release MFC Static|Win32 = Release MFC Static|Win32 Release STL Unicode DLL|Win32 = Release STL Unicode DLL|Win32 Release STL Unicode|Win32 = Release STL Unicode|Win32 Release STL|Win32 = Release STL|Win32 Release Unicode DLL|Win32 = Release Unicode DLL|Win32 Release Unicode MFC Static|Win32 = Release Unicode MFC Static|Win32 Release Unicode|Win32 = Release Unicode|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Debug DLL|Win32.Build.0 = Debug DLL|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Debug MFC Static|Win32.ActiveCfg = Debug MFC Static|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Debug MFC Static|Win32.Build.0 = Debug MFC Static|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Debug STL Unicode|Win32.ActiveCfg = Debug STL Unicode|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Debug STL Unicode|Win32.Build.0 = Debug STL Unicode|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Debug STL|Win32.ActiveCfg = Debug STL|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Debug STL|Win32.Build.0 = Debug STL|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Debug Unicode|Win32.ActiveCfg = Debug Unicode|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Debug Unicode|Win32.Build.0 = Debug Unicode|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Debug|Win32.ActiveCfg = Debug|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Debug|Win32.Build.0 = Debug|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release DLL|Win32.ActiveCfg = Release DLL|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release DLL|Win32.Build.0 = Release DLL|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release MFC Static|Win32.ActiveCfg = Release MFC Static|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release MFC Static|Win32.Build.0 = Release MFC Static|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release STL Unicode DLL|Win32.ActiveCfg = Release STL Unicode DLL|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release STL Unicode DLL|Win32.Build.0 = Release STL Unicode DLL|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release STL Unicode|Win32.ActiveCfg = Release STL Unicode|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release STL Unicode|Win32.Build.0 = Release STL Unicode|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release STL|Win32.ActiveCfg = Release STL|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release STL|Win32.Build.0 = Release STL|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release Unicode DLL|Win32.ActiveCfg = Release Unicode DLL|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release Unicode DLL|Win32.Build.0 = Release Unicode DLL|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release Unicode MFC Static|Win32.ActiveCfg = Release Unicode MFC Static|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release Unicode MFC Static|Win32.Build.0 = Release Unicode MFC Static|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release Unicode|Win32.ActiveCfg = Release Unicode|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release Unicode|Win32.Build.0 = Release Unicode|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release|Win32.ActiveCfg = Release|Win32 {A51CF340-B0EA-4C9B-A2FA-4D7487692EF5}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipAesCryptograph.h0000644000175000017500000000125611300022650022624 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipPathComponent_win.cpp0000644000175000017500000000446011300022650023660 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "_platform.h" #ifdef ZIP_ARCHIVE_WIN #include "stdafx.h" #include "ZipPathComponent.h" CZipPathComponent::~CZipPathComponent() { } void CZipPathComponent::SetFullPath(LPCTSTR lpszFullPath) { TCHAR szDrive[_MAX_DRIVE]; #if defined _UNICODE && _MSC_VER >= 1400 TCHAR szDir[32767]; #else TCHAR szDir[_MAX_DIR]; #endif TCHAR szFname[_MAX_FNAME]; TCHAR szExt[_MAX_EXT]; CZipString szTempPath(lpszFullPath); const CZipString szPrefix = _T("\\\\?\\unc\\"); int i = -1, iLen = szPrefix.GetLength(); if (iLen > szTempPath.GetLength()) iLen = szTempPath.GetLength(); CZipString szPossiblePrefix = szTempPath.Left(iLen); szPossiblePrefix.MakeLower(); // must perform case insensitive comparison while (++i < iLen && szPossiblePrefix[i] == szPrefix[i]); if (i == 2 || i == 4 || i == 8) // unc path, unicode path or unc path meeting windows file name conventions { m_szPrefix = szTempPath.Left(i); szTempPath = szTempPath.Mid(i); } else m_szPrefix.Empty(); #if _MSC_VER >= 1400 _tsplitpath_s(szTempPath, szDrive , szDir, szFname, szExt); #else _tsplitpath(szTempPath, szDrive , szDir, szFname, szExt); #endif m_szDrive = szDrive; m_szDirectory = szDir; m_szDirectory.TrimLeft(m_cSeparator); m_szDirectory.TrimRight(m_cSeparator); SetExtension(szExt); m_szFileTitle = szFname; } CZipString CZipPathComponent::GetNoDrive() const { CZipString szPath = m_szDirectory; CZipString szFileName = GetFileName(); if (!szFileName.IsEmpty() && !szPath.IsEmpty()) szPath += m_cSeparator; szPath += szFileName; return szPath; } #endif // ZIP_ARCHIVE_WIN tuxcmd-modules-0.6.70+ds/zip/ZipArchive/DirEnumerator.h0000644000175000017500000001176011300022650021767 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file DirEnumerator.h * Includes the ZipArchiveLib::CDirEnumerator class. * */ #if !defined(ZIPARCHIVE_DIRENUMERATOR_DOT_H) #define ZIPARCHIVE_DIRENUMERATOR_DOT_H #if _MSC_VER > 1000 #pragma once #pragma warning( push ) #pragma warning (disable : 4100) // unreferenced formal parameter #if defined ZIP_HAS_DLL #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class #endif #endif #include "ZipString.h" #include "ZipPathComponent.h" #include "FileFilter.h" /** Includes helper classes. Some of them can be reused in other applications. */ namespace ZipArchiveLib { /** A base class for processing multiple files in a directory. It provides a directory enumeration functionality. */ class ZIP_API CDirEnumerator { LPCTSTR m_lpszDirectory; LPCTSTR m_lpszFileNameMask; bool m_bRecursive; CZipString m_szCurrentDirectory; protected: /** Initializes a new CDirEnumerator object. \param lpszDirectory A directory to process. \param bRecursive The value indicating whether the subfolders of \a lpszDirectory should be processed recursively or not. \see GetDirectory \see IsRecursive */ CDirEnumerator(LPCTSTR lpszDirectory, bool bRecursive = true) { CZipString dir(lpszDirectory); if (dir.IsEmpty()) m_lpszDirectory = _T("."); else m_lpszDirectory = lpszDirectory; m_bRecursive = bRecursive; } /** Override this method to perform file processing while enumerating directories. This method is not called for directories, but for files only. \param lpszPath The full path to the current file. \param info A structure containing an information about the current file. \return Return \c true to continue the enumeration. When you return \c false, the enumeration is aborted. \see CFileFilter::Evaluate */ virtual bool Process(LPCTSTR lpszPath, const CFileInfo& info) = 0; /** This method is called at the beginning of the enumeration process. \see OnEnumerationEnd */ virtual void OnEnumerationBegin(){} /** This method is called at the end of the enumeration process. \param bResult It is set to \c false, if the #Process method returned \c false (the enumeration was aborted). Otherwise, it is set to \c true. \see OnEnumerationBegin */ virtual void OnEnumerationEnd(bool bResult){} /** This method is called when an enumeration process enters a new directory. \see GetCurrentDirectory \see ExitDirectory */ virtual void EnterDirectory(){} /** This method is method called when an enumeration process exits a directory. \see GetCurrentDirectory \see EnterDirectory */ virtual void ExitDirectory(){} public: /** Returns the directory being enumerated. \return The directory being enumerated (root). \see CDirEnumerator::CDirEnumerator */ LPCTSTR GetDirectory() const {return m_lpszDirectory;} /** Returns the value indicating whether the subfolders of the root directory are processed recursively or not. \return \c true, if the enumeration process is recursive; \c false otherwise. \see CDirEnumerator::CDirEnumerator */ bool IsRecursive() const {return m_bRecursive;} /** Returns the directory which the enumeration process is currently processing. \return The directory which the enumeration process is currently processing. */ LPCTSTR GetCurrentDirectory() const {return m_szCurrentDirectory;} /** Starts the enumeration process. Calls CFileFilter::Evaluate method for every file or directory found. If CFileFilter::Evaluate returns \c true, the file is processed by the #Process method. \param filter A filter that decides which directories and/or files should be processed and which should not. \return \c false, if the process was aborted (the #Process method returned \c false); \c true otherwise. \see CFileFilter::Evaluate */ bool Start(CFileFilter& filter); virtual ~CDirEnumerator(){} private: static bool IsDots(LPCTSTR lpszName); }; } #if _MSC_VER > 1000 #pragma warning( pop ) #endif #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCompatibility.cpp0000644000175000017500000001310011300022650023024 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipCompatibility.h" #include "ZipPlatform.h" #include "ZipException.h" #include "ZipAutoBuffer.h" #include "ZipFileHeader.h" enum iInternalAttr { attROnly = 0x01, attHidd = 0x02, attSys = 0x04, attDir = 0x10, attArch = 0x20 }; // *********************** WINDOWS ************************** #ifndef _WIN32 #define FILE_ATTRIBUTE_READONLY 0x00000001 #define FILE_ATTRIBUTE_HIDDEN 0x00000002 #define FILE_ATTRIBUTE_SYSTEM 0x00000004 #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 #define FILE_ATTRIBUTE_ARCHIVE 0x00000020 #endif // *********************** UINX ************************** #define USER_PERMISSIONS_MASK 0x01C0 #define EXTRACT_USER_PERMISSIONS(x) ((x & USER_PERMISSIONS_MASK) >> 6) #define CREATE_USER_PERMISSIONS(x) ((x & 0x0007) << 6) #define GROUP_PERMISSIONS_MASK 0x0038 #define CREATE_GROUP_PERMISSIONS(x) ((x & 0x0007) << 3) #define OTHER_PERMISSIONS_MASK 0x0007 #define CREATE_OTHER_PERMISSIONS(x) (x & 0x0007) #define UNIX_DIRECTORY_ATTRIBUTE 0x4000 #define UNIX_FILE_ATTRIBUTE 0x8000 #define UNIX_EXEC 1 #define UNIX_WRITE 2 #define UNIX_READ 4 using namespace ZipCompatibility; typedef DWORD(*conv_func)(DWORD , bool ); DWORD AttrDos(DWORD , bool ); DWORD AttrUnix(DWORD, bool); DWORD AttrMac(DWORD , bool ); conv_func conv_funcs[11] = {AttrDos, NULL, NULL, AttrUnix, NULL, NULL, AttrDos, AttrMac, NULL, NULL, AttrDos }; DWORD ZipCompatibility::ConvertToSystem(DWORD uAttr, int iFromSystem, int iToSystem) { if (iToSystem != iFromSystem && iFromSystem < 11 && iToSystem < 11) { conv_func p = conv_funcs[iFromSystem], q = conv_funcs[iToSystem]; if (p && q) uAttr = q( p(uAttr, true), false); else CZipException::Throw(CZipException::platfNotSupp); } return uAttr; } DWORD AttrDos(DWORD uAttr, bool ) { return uAttr; } DWORD AttrUnix(DWORD uAttr, bool bFrom) { DWORD uNewAttr = 0; if (bFrom) { bool isDir = (uAttr & UNIX_DIRECTORY_ATTRIBUTE) != 0; if (isDir) uNewAttr = attDir; uAttr = EXTRACT_USER_PERMISSIONS (uAttr); // we may set archive attribute if the file hasn't got the execute permissions // and is not a directory if (!isDir && !(uAttr & UNIX_EXEC)) uNewAttr |= attArch ; if (!(uAttr & UNIX_WRITE)) uNewAttr |= attROnly; if (!(uAttr & UNIX_READ)) uNewAttr |= attHidd; } else { uNewAttr = 0; // we cannot assume that if the file hasn't the archive attribute set // then it is executable and set execute permissions if (!(uAttr & attHidd)) uNewAttr |= (CREATE_OTHER_PERMISSIONS (UNIX_READ) | CREATE_GROUP_PERMISSIONS (UNIX_READ)) | CREATE_USER_PERMISSIONS (UNIX_READ); if (!(uAttr & attROnly)) uNewAttr |= (CREATE_GROUP_PERMISSIONS (UNIX_WRITE) | CREATE_USER_PERMISSIONS (UNIX_WRITE)); if (uAttr & attDir) { uNewAttr |= UNIX_DIRECTORY_ATTRIBUTE; uNewAttr |= (CREATE_OTHER_PERMISSIONS (UNIX_EXEC) | CREATE_GROUP_PERMISSIONS (UNIX_EXEC)) | CREATE_USER_PERMISSIONS (UNIX_EXEC); } else uNewAttr |= UNIX_FILE_ATTRIBUTE; } return uNewAttr; } DWORD AttrMac(DWORD uAttr, bool ) { return uAttr & (attDir | attROnly); } // ************************************************************************ ZIPINLINE bool ZipCompatibility::IsPlatformSupported(int iCode) { return iCode == zcDosFat || iCode == zcUnix || iCode == zcMacintosh || iCode == zcNtfs || iCode == zcOs2Hpfs; } void ZipCompatibility::ConvertBufferToString(CZipString& szString, const CZipAutoBuffer& buffer, UINT uCodePage) { #ifdef _UNICODE ZipPlatform::MultiByteToWide(buffer, szString, uCodePage); #else // iLen does not include the NULL character int iLen; if (uCodePage == CP_OEMCP) { CZipAutoBuffer buf; buf = buffer; ZipPlatform::AnsiOem(buf, false); iLen = buf.GetSize(); memcpy(szString.GetBuffer(iLen), buf.GetBuffer(), iLen); } else { iLen = buffer.GetSize(); memcpy(szString.GetBuffer(iLen), buffer.GetBuffer(), iLen); } szString.ReleaseBuffer(iLen); #endif } void ZipCompatibility::ConvertStringToBuffer(LPCTSTR lpszString, CZipAutoBuffer& buffer, UINT uCodePage) { #ifdef _UNICODE ZipPlatform::WideToMultiByte(lpszString, buffer, uCodePage); #else int iLen = (int)strlen(lpszString); // iLen does not include the NULL character buffer.Allocate(iLen); memcpy(buffer, lpszString, (size_t)iLen); if (uCodePage == CP_OEMCP) ZipPlatform::AnsiOem(buffer, true); #endif } void ZipCompatibility::SlashBackslashChg(CZipString& szFileName, bool bReplaceSlash) { TCHAR t1 = _T('\\') /*backslash*/, t2 = _T('/'), c1, c2; if (bReplaceSlash) { c1 = t1; c2 = t2; } else { c1 = t2; c2 = t1; } szFileName.Replace(c2, c1); } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/FileFilter.h0000644000175000017500000004204311300022650021232 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file FileFilter.h * Includes the ZipArchiveLib::CFileFilter and the derived classes. * */ #if !defined(ZIPARCHIVE_FILEFILTER_DOT_H) #define ZIPARCHIVE_FILEFILTER_DOT_H #if _MSC_VER > 1000 #pragma once #pragma warning( push ) #pragma warning (disable : 4100) // unreferenced formal parameter #endif #include "stdafx.h" #include "ZipExport.h" #include "FileInfo.h" #include "Wildcard.h" #include "ZipPlatform.h" #include "ZipCollections.h" namespace ZipArchiveLib { /** A base class for filters used in the directory enumeration process. \see 0610231446|filters \see CDirEnumerator::Start */ class ZIP_API CFileFilter { public: /** Initializes a new instance of the CFileFilter class. \param bInverted Set to \c true to invert the behavior of the filter or to \c false for the normal behavior. \see SetInverted */ CFileFilter(bool bInverted = false) :m_bInverted(bInverted) { } /** This method is directly called by the CDirEnumerator::Start for each file or directory that was previously accepted with the #HandlesFile method. It internally calls the #Accept method and inverts it's result, if the filter is in the inverted mode and does not handle the inversion internally. - If this method returns \c true for a file, then the file is processed (the CDirEnumerator::Process method is called for the file). Otherwise the file is not processed. - If this method returns \c true for a directory, then the directory can be traversed for files and subfolders (depending on the CDirEnumerator::IsRecursive() method). Otherwise the directory is not traversed. \param lpszParentDir The parent directory containing the file to accept. \param lpszName The name of the file to accept (without a path). \param info A structure containing the information about the current file. \return \c true, if the file is accepted (taking inversion into account); \c false otherwise. \see Accept \see HandlesFile \see HandlesInversion \see SetInverted \see IsInverted \see CDirEnumerator::Start \see CDirEnumerator::Process */ bool Evaluate(LPCTSTR lpszParentDir, LPCTSTR lpszName, const CFileInfo& info) { bool ret = Accept(lpszParentDir, lpszName, info); if (!HandlesInversion()) return m_bInverted ? !ret : ret; return ret; } /** Sets the filter to operate in the inverted or in the normal mode. If the filter operates in an inverted mode, the file that this filer accepts is \b not processed and vice versa. Normal mode means that a file is processed (the CDirEnumerator::Process method is called for that file), if the filter accepts the file. \param bInverted \c true to make the filter operate in an inverted mode or \c false to make the filter operate in a normal mode. \see HandlesInversion \see IsInverted */ void SetInverted(bool bInverted = true) { m_bInverted = bInverted;} /** Returns the value indicating whether the filter operates in an inverted mode or in a normal mode. \return \c true, if the filter operates in an inverted mode; \c false otherwise. \see SetInverted \see HandlesInversion */ bool IsInverted() const {return m_bInverted;} /** Returns the value indicating whether the filter can decide about processing of the \a info file. If it can, then the #Evaluate method will be called for the \a info file. By default this method returns \c true for files and \c false for directories. Override this method to change it's behavior. - If \a info is a file and this method returns \c false, then the file is not processed. - If \a info is a directory and this method returns \c false, then the directory can still be traversed for files and subfolders (depending on the CDirEnumerator::IsRecursive() method). The #Evaluate method is not called in both cases. \param info A structure containing the information about the file. \return \c true, if the \a info file should be evaluated by the #Evaluate method; \c false otherwise. \note This method is particularly useful when the filter operates in the inverted mode (see #SetInverted). For example, if a filter should accept directories in both inverted and non-inverted mode, it would need to particularly handle inversion for directories without this method. With this method it can just not accept directories for evaluation and they still will be traversed. */ virtual bool HandlesFile(const CFileInfo& info) { return !info.IsDirectory(); } virtual ~CFileFilter() { } protected: /** This method is directly called by the #Evaluate method during an enumeration process. If this method returns \c true, the file will later be processed by the CDirEnumerator::Process method. If this method returns \c false for a directory, the directory is not enumerated at all. The meaning of the return value can be reversed by the #SetInverted method. If this filter handles the inversion internally, the return value from this method is not reversed by the #Evaluate method. \param lpszParentDir The parent directory containing the file to accept. \param lpszName The name of the file to accept (without a path). \param info A structure containing the information about the current file. \return \c true, if the file is accepted; \c false otherwise. \see Evaluate \see HandlesInversion \see CDirEnumerator::Start \see CDirEnumerator::Process */ virtual bool Accept(LPCTSTR lpszParentDir, LPCTSTR lpszName, const CFileInfo& info) { return true; } /** Returns the value indicating, whether the current filter handles the inversion mode internally or not. - If the filter is in the inverted mode and it handles the inversion, then the return value \c true from the #Accept method means that the file should be processed. - If the filter is in the inverted mode and it does not handle the inversion, then the return value \c true from the #Accept method means that the file should not be processed. It may be more efficient to handle the inversion internally in some cases. \return \c true, if the filter handles the inversion internally; \c false otherwise. \note This method returns \c false by default. Override this method to change this behavior. \see SetInverted \see IsInverted */ virtual bool HandlesInversion() const { return false; } bool m_bInverted; }; /** A filter that allows filtering files by a filename mask while an enumeration process. \see 0610231446|filters \see 0610242025|wildcards \see CDirEnumerator::Start */ class ZIP_API CNameFileFilter : public CFileFilter { CWildcard m_matcher; int m_iAppliesToTypes; public: /** The file type to which the CNameFileFilter filter can be applied. You can use the logical \c OR to combine them. \see SetAppliesToTypes \see GetAppliesToTypes */ enum AppliesToTypes { toFile = 0x1, ///< Regular files only. toDirectory = 0x2, ///< Directories only. toAll = toFile | toDirectory ///< Both regular files and directories. }; /** Initializes a new instance of the CNameFileFilter class. \param lpszPattern A mask to match against a filename. This filter uses the CWildcard functionality for this purpose. \param iAppliesToTypes The file type to which this filter applies. The file type to which this filter applies. Can be one or more of the #AppliesToTypes values. \param bInverted Set to \c true to invert the behavior of the filter or to \c false for the normal behavior. \param bCaseSensitive \c true, if the matching process is case-sensitive; \c false otherwise. By default, a system case-sensitivity setting is used. \see 0610231446|filters \see 0610242025|wildcards \see SetInverted \see SetAppliesToTypes \see CWildcard \see ZipPlatform::GetSystemCaseSensitivity */ CNameFileFilter(LPCTSTR lpszPattern = _T("*.*"), bool bInverted = false, int iAppliesToTypes = toFile, bool bCaseSensitive = ZipPlatform::GetSystemCaseSensitivity()) :CFileFilter(bInverted), m_matcher(lpszPattern, bCaseSensitive) { m_iAppliesToTypes = iAppliesToTypes; } /** Returns the value indicating whether the filter can be applied to the given \a iType type. \param iType Can be one or more of the #AppliesToTypes values. \return \c true, if the filter can be applied to \a iType type; \c false otherwise. \see SetAppliesToTypes \see GetAppliesToTypes */ bool AppliesToType(int iType) { return (m_iAppliesToTypes & iType) == iType; } /** Set the file type to which this filter applies. \param iType The file type to which this filter applies. Can be one or more of the #AppliesToTypes values. \see GetAppliesToTypes */ void SetAppliesToTypes(int iType) { m_iAppliesToTypes = iType; } /** Return the file type to which this filter applies. \return The file type to which this filter applies. Can be one or more of the #AppliesToTypes values. \see SetAppliesToTypes */ int GetAppliesToTypes() {return m_iAppliesToTypes;} /** Returns the value indicating whether the filter can decide about processing of the \a info file. The CNameFileFilter returns the value depending on the #GetAppliesToTypes value. \param info A structure containing the information about the file. \return \c true, if the \a info file will be evaluated by the #Evaluate method; \c false otherwise. \see GetAppliesToTypes \see SetAppliesToTypes */ bool HandlesFile(const CFileInfo& info) { return info.IsDirectory() ? AppliesToType(toDirectory) : AppliesToType(toFile); } protected: virtual bool Accept(LPCTSTR, LPCTSTR lpszName, const CFileInfo& info) { return m_matcher.IsMatch(lpszName); } }; /** A filter that allows grouping of other filters. \see 0610231446|filters \see CDirEnumerator::Start */ class ZIP_API CGroupFileFilter : public CFileFilter { public: /** The grouping type. */ enum GroupType { And, ///< Logical AND. All the grouped filters must accept a file for the file to be processed. Or ///< Logical OR. At least one of the grouped filters must accept a file for the file to be processed. }; /** Initializes a new instance of the CGroupFileFilter class. \param groupType The grouping type. Should be one of the #GroupType values. \param bAutoDelete \c true, if the grouped filters should be automatically destroyed by this filter; \c false otherwise. \param bInverted Set to \c true to invert the behavior of the filter or to \c false for the normal behavior. This filter handles the inversion mode internally. \see 0610231446|filters \see SetType \see SetAutoDelete \see SetInverted \see HandlesInversion */ CGroupFileFilter(GroupType groupType = CGroupFileFilter::And, bool bAutoDelete = true, bool bInverted = false) :CFileFilter(bInverted), m_iType(groupType), m_bAutoDelete(bAutoDelete) { } /** Add \a pFilter to the filter's group. \param pFilter The filter to add. */ void Add(CFileFilter* pFilter) { m_filters.Add(pFilter); } /** Returns the filter at the given position. \param uIndex The index of the filter to return. */ CFileFilter* GetAt(ZIP_ARRAY_SIZE_TYPE uIndex) { return m_filters[uIndex]; } /** Returns the filter at the given position. \param uIndex The index of the filter to return. */ const CFileFilter* GetAt(ZIP_ARRAY_SIZE_TYPE uIndex) const { return m_filters[uIndex]; } /** Returns the filter at the given position. \param uIndex The index of the filter to return. */ const CFileFilter* operator[] (ZIP_ARRAY_SIZE_TYPE uIndex) const { return GetAt(uIndex); } /** Returns the filter at the given position. \param uIndex The index of the filter to return. */ CFileFilter* operator[] (ZIP_ARRAY_SIZE_TYPE uIndex) { return GetAt(uIndex); } /** Remove the filter at the given position. The removed filter is deleted from memory, if the CGroupFileFilter object is in the auto-delete mode. \param uIndex The index of the filter to remove. \see SetAutoDelete */ void RemoveAt(ZIP_ARRAY_SIZE_TYPE uIndex) { CFileFilter* filter = m_filters[uIndex]; // first remove, then delete m_filters.RemoveAt(uIndex); if (m_bAutoDelete) delete filter; } /** Removes all contained filters from the collection. The removed filters are deleted from memory, if the CGroupFileFilter object is in the auto-delete mode. \see SetAutoDelete */ void Clear() { if (m_filters.GetSize() == 0) return; ZIP_ARRAY_SIZE_TYPE i = m_filters.GetSize() - 1; for (; ;) { RemoveAt(i); if (i == 0) break; i--; } } /** Returns the number of grouped filters. \return The number of grouped filters. */ ZIP_ARRAY_SIZE_TYPE GetSize() { return m_filters.GetSize(); } /** Sets the type of grouping. \param iType The type of grouping. Should be one of the #GroupType values. \see GetType */ void SetType(GroupType iType) {m_iType = iType;} /** Returns the type of grouping. \return The type of groupgroupeding. Can be one of the #GroupType values. \see SetType */ GroupType GetType() const {return m_iType;} /** Enable or disable auto-deletion of grouped filters. If auto-deletion is enabled, the grouped filters are released from memory when they are removed from the group or when the CGroupFileFilter object is destroyed. \param bAutoDelete \c true, to enable auto-deletion; \c false to disable. \see IsAutoDelete */ void SetAutoDelete(bool bAutoDelete) {m_bAutoDelete = bAutoDelete;} /** Return the value indicating whether the auto-deletion is enabled or not. \return \c true, if the auto-deletion is enabled; \c false otherwise. \see SetAutoDelete */ bool IsAutoDelete() const {return m_bAutoDelete;} /** Returns the value indicating whether the filter can decide about processing of the \a info file. The CGroupFileFilter returns the value depending on the value returned by the grouped filters. \param info A structure containing the information about the file. \return \c true, if any of the grouped filters accepts \a info; \c false otherwise. */ bool HandlesFile(const CFileInfo& info) { for (ZIP_ARRAY_SIZE_TYPE i = 0; i < m_filters.GetSize(); i++) // it is enough that one filter handles it if (m_filters[i]->HandlesFile(info)) return true; return false; } ~CGroupFileFilter() { Clear(); } protected: virtual bool Accept(LPCTSTR lpszParentDir, LPCTSTR lpszName, const CFileInfo& info); /** This filter handles inversion internally. \return This method returns \c true for this class. \see CFileFilter::HandlesInversion */ bool HandlesInversion() const { return true; } GroupType m_iType; ///< Set with the #SetType method or in constructor. bool m_bAutoDelete; ///< Set with the #SetAutoDelete or in constructor. private: #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning (push) #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class #endif CZipArray m_filters; #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning( pop) #endif }; } #if _MSC_VER > 1000 #pragma warning( pop ) #endif #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCollections_mfc.h0000644000175000017500000000466211300022650023000 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #ifndef ZIPARCHIVE_ZIPCOLLECTIONS_DOT_H #error Do not include this file directly. Include ZipCollections.h instead #endif #if _MSC_VER > 1000 #pragma warning( push ) #pragma warning (disable:4786) // 'identifier' : identifier was truncated to 'number' characters in the debug information #endif #include #define ZIP_ARRAY_SIZE_TYPE INT_PTR typedef CStringArray CZipStringArray; template class CZipArray : public CArray { public: typedef int (*CompareFunction)(const void* pArg1, const void* pArg2); private: static int CompareAsc(const void *pArg1, const void *pArg2) { TYPE w1 = *(TYPE*)pArg1; TYPE w2 = *(TYPE*)pArg2; return w1 == w2 ? 0 :(w2 > w1 ? - 1 : 1); } static int CompareDesc(const void *pArg1, const void *pArg2) { TYPE w1 = *(TYPE*)pArg1; TYPE w2 = *(TYPE*)pArg2; return w1 == w2 ? 0 :(w1 > w2 ? - 1 : 1); } public: void Sort(bool bAscending) { Sort(bAscending ? CompareAsc : CompareDesc); } void Sort(CompareFunction pFunction) { INT_PTR uSize = GetSize(); if (!uSize) // if ommitted operator [] will fail if empty return; qsort((void*)&((*this)[0]), (size_t)uSize , sizeof(TYPE), pFunction); } }; template class CZipPtrList : public CTypedPtrList { public: typedef POSITION iterator; typedef POSITION const_iterator; bool IteratorValid(const iterator &iter) const { return iter != NULL; } }; template class CZipMap : public CMap { public: typedef POSITION iterator; typedef POSITION const_iterator; bool IteratorValid(const iterator &iter) const { return iter != NULL; } }; #if _MSC_VER > 1000 #pragma warning( pop ) #endiftuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipPlatform_win.cpp0000644000175000017500000002447611300022650022676 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "_platform.h" #ifdef ZIP_ARCHIVE_WIN #define ZIP_USES_SAFE_WINDOWS_API #include "stdafx.h" #include "ZipPlatform.h" #include "ZipFileHeader.h" #include "ZipException.h" #include "ZipAutoBuffer.h" #include #ifndef __BORLANDC__ #include #else #ifndef _UTIMBUF_DEFINED #define _utimbuf utimbuf #define _UTIMBUF_DEFINED #endif #include #endif #ifndef INVALID_FILE_ATTRIBUTES #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif #include #include #include #include "ZipPathComponent.h" #include "ZipCompatibility.h" const TCHAR CZipPathComponent::m_cSeparator = _T('\\'); ULONGLONG ZipPlatform::GetDeviceFreeSpace(LPCTSTR lpszPath) { ULONGLONG uFreeBytesToCaller = 0, uTotalBytes = 0, uFreeBytes = 0; CZipPathComponent zpc (lpszPath); CZipString szDrive = zpc.GetFileDrive(); if (!GetDiskFreeSpaceEx( szDrive, (PULARGE_INTEGER)&uFreeBytesToCaller, (PULARGE_INTEGER)&uTotalBytes, (PULARGE_INTEGER)&uFreeBytes)) { CZipPathComponent::AppendSeparator(szDrive); // in spite of what is written in MSDN it is sometimes needed (on fixed disks) if (!GetDiskFreeSpaceEx( szDrive, (PULARGE_INTEGER)&uFreeBytesToCaller, (PULARGE_INTEGER)&uTotalBytes, (PULARGE_INTEGER)&uFreeBytes)) return 0; } return uFreeBytes; } CZipString ZipPlatform::GetTmpFileName(LPCTSTR lpszPath, ZIP_SIZE_TYPE uSizeNeeded) { TCHAR empty[] = _T(""); CZipString tempPath; bool bCheckTemp = true; if (lpszPath) { tempPath = lpszPath; bCheckTemp = GetDeviceFreeSpace(tempPath) < uSizeNeeded; } if (bCheckTemp) { DWORD size = GetTempPath(0, empty); if (size == 0) return (CZipString)empty; GetTempPath(size, tempPath.GetBuffer(size)); tempPath.ReleaseBuffer(); if (GetDeviceFreeSpace(tempPath) < uSizeNeeded) { if (!GetCurrentDirectory(tempPath) || GetDeviceFreeSpace(tempPath) < uSizeNeeded) return (CZipString)empty; } } CZipString tempName; if (!GetTempFileName(tempPath, _T("ZAR"), 0, tempName.GetBuffer(_MAX_PATH))) return (CZipString)empty; tempName.ReleaseBuffer(); return tempName; } bool ZipPlatform::GetCurrentDirectory(CZipString& sz) { DWORD i = ::GetCurrentDirectory(0, NULL); if (!i) return false; TCHAR* pBuf = new TCHAR[i]; bool b = true; if (!::GetCurrentDirectory(i, pBuf)) b = false; else sz = pBuf; delete[] pBuf; return b; } bool ZipPlatform::SetFileAttr(LPCTSTR lpFileName, DWORD uAttr) { return ::SetFileAttributes(lpFileName, uAttr) != 0; } bool ZipPlatform::GetFileAttr(LPCTSTR lpFileName, DWORD& uAttr) { // not using MFC due to MFC bug (attr is one byte there) DWORD temp = ::GetFileAttributes(lpFileName); if (temp == INVALID_FILE_ATTRIBUTES) return false; uAttr = temp; return true; } bool ZipPlatform::GetFileModTime(LPCTSTR lpFileName, time_t & ttime) { #ifndef __BORLANDC__ struct _stat st; if (_tstat(lpFileName, &st) != 0) #else struct stat st; if (stat(lpFileName, &st) != 0) #endif return false; ttime = st.st_mtime; if (ttime == (time_t)-1) { ttime = time(NULL); return false; } else return true; } bool ZipPlatform::SetFileModTime(LPCTSTR lpFileName, time_t ttime) { struct _utimbuf ub; ub.actime = time(NULL); ub.modtime = ttime == -1 ? time(NULL) : ttime; // if wrong file time, set it to the current return _tutime(lpFileName, &ub) == 0; } bool ZipPlatform::ChangeDirectory(LPCTSTR lpDirectory) { return _tchdir(lpDirectory) == 0; // returns 0 if ok } int ZipPlatform::FileExists(LPCTSTR lpszName) { #ifndef __BORLANDC__ #if _MSC_VER >= 1400 if (_taccess_s(lpszName, 0) == 0) #else if (_taccess(lpszName, 0) == 0) #endif #else #ifdef _UNICODE if (_waccess(lpszName, 0) == 0) #else if (access(lpszName, 0) == 0) #endif #endif { if (DirectoryExists(lpszName)) return -1; return 1; } else return 0; } ZIPINLINE bool ZipPlatform::IsDriveRemovable(LPCTSTR lpszFilePath) { CZipPathComponent zpc(lpszFilePath); return ::GetDriveType(zpc.GetFileDrive()) == DRIVE_REMOVABLE; } ZIPINLINE bool ZipPlatform::SetVolLabel(LPCTSTR lpszPath, LPCTSTR lpszLabel) { CZipPathComponent zpc(lpszPath); CZipString szDrive = zpc.GetFileDrive(); CZipPathComponent::AppendSeparator(szDrive); return ::SetVolumeLabel(szDrive, lpszLabel) != 0; } ZIPINLINE void ZipPlatform::AnsiOem(CZipAutoBuffer& buffer, bool bAnsiToOem) { #ifdef ZIP_USES_SAFE_WINDOWS_API UINT cpIn, cpOut; if (bAnsiToOem) { cpIn = CP_ACP; cpOut = CP_OEMCP; } else { cpIn = CP_OEMCP; cpOut = CP_ACP; } CZipAutoBuffer interBuffer; int size = buffer.GetSize(); // iLen doesn't include terminating character int iLen = MultiByteToWideChar(cpIn, MB_PRECOMPOSED, buffer, size, NULL, 0); if (iLen <= 0) return; interBuffer.Allocate(iLen * sizeof(wchar_t)); LPWSTR lpszWide = (LPWSTR)(char*)interBuffer; iLen = MultiByteToWideChar(cpIn, MB_PRECOMPOSED, buffer, size, lpszWide, iLen); ASSERT(iLen != 0); // iLen does not include terminating character size = WideCharToMultiByte(cpOut, 0, lpszWide, iLen, NULL, 0, NULL, NULL); if (size <= 0) return; buffer.Allocate(size); size = WideCharToMultiByte(cpOut, 0, lpszWide, iLen, buffer, size, NULL, NULL); ASSERT(size != 0); #else if (bAnsiToOem) CharToOemBuffA(buffer, buffer, buffer.GetSize()); else OemToCharBuffA(buffer, buffer, buffer.GetSize()); #endif } ZIPINLINE bool ZipPlatform::RemoveFile(LPCTSTR lpszFileName, bool bThrow) { if (!::DeleteFile((LPTSTR)lpszFileName)) if (bThrow) CZipException::Throw(CZipException::notRemoved, lpszFileName); else return false; return true; } ZIPINLINE bool ZipPlatform::RenameFile( LPCTSTR lpszOldName, LPCTSTR lpszNewName, bool bThrow) { if (!::MoveFile((LPTSTR)lpszOldName, (LPTSTR)lpszNewName)) if (bThrow) CZipException::Throw(CZipException::notRenamed, lpszOldName); else return false; return true; } ZIPINLINE bool ZipPlatform::IsDirectory(DWORD uAttr) { return (uAttr & FILE_ATTRIBUTE_DIRECTORY) != 0; } ZIPINLINE bool ZipPlatform::CreateDirectory(LPCTSTR lpDirectory) { return ::CreateDirectory(lpDirectory, NULL) != 0; } ZIPINLINE DWORD ZipPlatform::GetDefaultAttributes() { return FILE_ATTRIBUTE_ARCHIVE; } ZIPINLINE DWORD ZipPlatform::GetDefaultDirAttributes() { return FILE_ATTRIBUTE_DIRECTORY; } ZIPINLINE int ZipPlatform::GetSystemID() { return ZipCompatibility::zcDosFat; } ZIPINLINE bool ZipPlatform::GetSystemCaseSensitivity() { return false; } #ifdef _UNICODE int ZipPlatform::WideToMultiByte(LPCWSTR lpszIn, CZipAutoBuffer &szOut, UINT uCodePage) { size_t wideLen = wcslen(lpszIn); if (wideLen == 0) { szOut.Release(); return 0; } // iLen does not include terminating character int iLen = WideCharToMultiByte(uCodePage, 0, lpszIn, (int)wideLen, szOut, 0, NULL, NULL); if (iLen > 0) { szOut.Allocate(iLen, true); iLen = WideCharToMultiByte(uCodePage, 0, lpszIn , (int)wideLen, szOut, iLen, NULL, NULL); ASSERT(iLen != 0); } else // here it means error { szOut.Release(); iLen --; } return iLen; } int ZipPlatform::MultiByteToWide(const CZipAutoBuffer &szIn, CZipString& szOut, UINT uCodePage) { int singleLen = szIn.GetSize(); // iLen doesn't include terminating character DWORD dwFlags = uCodePage <= CP_OEMCP ? MB_PRECOMPOSED : 0; int iLen = MultiByteToWideChar(uCodePage, dwFlags, szIn.GetBuffer(), singleLen, NULL, 0); if (iLen > 0) { iLen = MultiByteToWideChar(uCodePage, dwFlags, szIn.GetBuffer(), singleLen, szOut.GetBuffer(iLen) , iLen); szOut.ReleaseBuffer(iLen); ASSERT(iLen != 0); } else { szOut.Empty(); iLen --; // return -1 } return iLen; } #endif #if defined ZIP_ARCHIVE_STL || defined ZIP_FILE_USES_STL #if _MSC_VER > 1000 #pragma warning( push ) #pragma warning (disable : 4702) // unreachable code #endif #include #include bool ZipPlatform::TruncateFile(int iDes, ULONGLONG uSize) { #if (_MSC_VER >= 1400) return _chsize_s(iDes, uSize) == 0; #else if (uSize <= LONG_MAX) return chsize(iDes, (LONG)uSize) == 0; else if (uSize > _I64_MAX) CZipException::Throw(CZipException::tooBigSize); else { HANDLE handle = (HANDLE)GetFileSystemHandle(iDes); ULARGE_INTEGER li; li.QuadPart = uSize; li.LowPart = SetFilePointer(handle, li.LowPart, (LONG*)&li.HighPart, FILE_BEGIN); if (li.LowPart == UINT_MAX && GetLastError() != NO_ERROR) return false; return SetEndOfFile(handle) != 0; } return false; // for the compiler #endif } #if _MSC_VER > 1000 #pragma warning( pop ) #endif int ZipPlatform::OpenFile(LPCTSTR lpszFileName, UINT iMode, int iShareMode) { switch (iShareMode) { case (CZipFile::shareDenyWrite & CZipFile::shareDenyRead): iShareMode = SH_DENYRW; break; case (CZipFile::shareDenyRead): iShareMode = SH_DENYRD; break; case (CZipFile::shareDenyWrite): iShareMode = SH_DENYWR; break; default: iShareMode = SH_DENYNO; } #if _MSC_VER >= 1400 int handle; if (_tsopen_s(&handle, lpszFileName, iMode, iShareMode, S_IREAD | S_IWRITE /*required only when O_CREAT mode*/) != 0) return -1; else return handle; #else return _tsopen(lpszFileName, iMode, iShareMode, S_IREAD | S_IWRITE /*required only when O_CREAT mode*/); #endif } bool ZipPlatform::FlushFile(int iDes) { return _commit(iDes) == 0; } intptr_t ZipPlatform::GetFileSystemHandle(int iDes) { return _get_osfhandle(iDes); } #endif // ZIP_ARCHIVE_STL #endif // ZIP_ARCHIVE_WIN tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCrc32Cryptograph.h0000644000175000017500000000544211300022650022771 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipCrc32Cryptograph.h * Includes the CZipCrc32Cryptograph class. * */ #if !defined(ZIPARCHIVE_ZIPCRC32CRYPTOGRAPH_DOT_H) #define ZIPARCHIVE_ZIPCRC32CRYPTOGRAPH_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "zlib/zlib.h" #include "ZipCryptograph.h" #include "ZipFileHeader.h" #include "ZipStorage.h" #define ZIPARCHIVE_ENCR_HEADER_LEN 12 /** Performs the traditional zip encryption. \see 0610201627|std */ class ZIP_API CZipCrc32Cryptograph : public CZipCryptograph { public: CZipCrc32Cryptograph(){} bool InitDecode(CZipAutoBuffer& password, CZipFileHeader& currentFile, CZipStorage& storage); void InitEncode(CZipAutoBuffer& password, CZipFileHeader& currentFile, CZipStorage& storage); void Decode(char* pBuffer, DWORD uSize) { for (DWORD i = 0; i < uSize; i++) CryptDecode(pBuffer[i]); } void Encode(char* pBuffer, DWORD uSize) { for (DWORD i = 0; i < uSize; i++) CryptEncode(pBuffer[i]); } bool CanHandle(int iEncryptionMethod) { return iEncryptionMethod == CZipCryptograph::encStandard; } /** See CZipCryptograph::GetEncryptedInfoSizeBeforeData */ static DWORD GetEncryptedInfoSizeBeforeData() { return ZIPARCHIVE_ENCR_HEADER_LEN; } /** See CZipCryptograph::GetEncryptedInfoSizeAfterData */ static DWORD GetEncryptedInfoSizeAfterData() { return 0; } /** Returns the CRC table. */ static const DWORD* GetCRCTable() { return zarch_get_crc_table(); } private: void CryptDecode(char &c) { c ^= CryptDecryptByte(); CryptUpdateKeys(c); } char CryptDecryptByte() { int temp = (m_keys[2] & 0xffff) | 2; return (char)(((temp * (temp ^ 1)) >> 8) & 0xff); } void CryptInitKeys(CZipAutoBuffer& password); void CryptUpdateKeys(char c); DWORD CryptCRC32(DWORD l, char c) { const DWORD *CRC_TABLE = zarch_get_crc_table(); return CRC_TABLE[(l ^ c) & 0xff] ^ (l >> 8); } void CryptEncode(char &c) { char t = CryptDecryptByte(); CryptUpdateKeys(c); c ^= t; } DWORD m_keys[3]; public: ~CZipCrc32Cryptograph(){} }; #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipAbstractFile.h0000644000175000017500000000431711300022650022235 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipAbstractFile.h * Includes the CZipAbstractFile class. * */ #if !defined(ZIPARCHIVE_ZIPABSTRACTFILE_DOT_H) #define ZIPARCHIVE_ZIPABSTRACTFILE_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "ZipExport.h" #include "ZipString.h" class ZIP_API CZipAbstractFile { public: enum { begin = SEEK_SET, // 0 current = SEEK_CUR, // 1 end = SEEK_END // 2 }; CZipAbstractFile(){} virtual bool Open(LPCTSTR , UINT , bool ){return false;} virtual void Close() = 0; virtual void Flush() = 0; virtual ZIP_FILE_USIZE GetPosition() const = 0; virtual ZIP_FILE_USIZE Seek(ZIP_FILE_SIZE lOff, int nFrom) = 0; ZIP_FILE_USIZE Seek(ZIP_FILE_USIZE lOff, bool fromBeginning = true) { ZIP_FILE_SIZE offset; if (lOff > ZIP_FILE_SIZEMAX) { offset = GetLength() - lOff; fromBeginning = !fromBeginning; } else offset = (ZIP_FILE_USIZE)lOff; if (fromBeginning) return Seek(offset, CZipAbstractFile::begin); else return Seek(-offset, CZipAbstractFile::end); } virtual ZIP_FILE_USIZE GetLength() const = 0; virtual void SetLength(ZIP_FILE_USIZE nNewLen) = 0; virtual ZIP_FILE_USIZE SeekToBegin(){return Seek(0, begin);} virtual ZIP_FILE_USIZE SeekToEnd(){return Seek(0, end);} virtual CZipString GetFilePath() const = 0; virtual UINT Read(void *lpBuf, UINT nCount) = 0; virtual void Write(const void* lpBuf, UINT nCount) = 0; virtual bool IsClosed() const = 0; virtual ~CZipAbstractFile(){}; }; #endif // !defined(ZIPARCHIVE_ZIPABSTRACTFILE_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCallback.h0000644000175000017500000005503011300022650021364 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipCallback.h * Includes the CZipCallback and the derived classes. * */ #if !defined(ZIPARCHIVE_ZIPCALLBACK_DOT_H) #define ZIPARCHIVE_ZIPCALLBACK_DOT_H #if _MSC_VER > 1000 #pragma once #if defined ZIP_HAS_DLL #pragma warning (push) #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class #endif #endif #include "ZipString.h" #include "ZipExport.h" /* When processing split archives, this value is passes as the argument to the CZipCallback::Callback method to notify that the current volume is the last one. */ #define ZIP_SPLIT_LAST_VOLUME (ZIP_SIZE_TYPE)(-1) /** A base class for callback objects that are notified when various actions take place. You need to derive your own class and overload the #Callback method to use it. Do not derive from CZipCallback directly but derive from: \li CZipSegmCallback, when you create a segmented archive - you will be notified when there the next volume is processed in a segmented archive. \li CZipActionCallback, for other notifications. \see 0610051553|span \see 0610231200 \see CZipSegmCallback \see CZipActionCallback */ struct ZIP_API CZipCallback { /** The method called as a callback. Return \c false from inside the method to abort the current operation. If it is a segmented archive callback object, a CZipException with CZipException::aborted code will be thrown, otherwise the code will be CZipException::abortedAction or CZipException::abortedSafely. The following actions can be safely aborted (without corrupting the archive): - counting bytes before deleting files - testing - saving the central directory in a not segmented archive (saved data is removed in case of break and you can save it again). If the archive is segmented and if saving is aborted, the archive will not be damaged, but saved part of the central directory will be not removed and the new central directory will have to be saved after it. \param uProgress The value depends on the type of the operation. \return \c false to abort the current operation; \c true to continue it. \note Override this method in the derived class. If you define this method inside the class declaration, consider inlining it to make the action progress faster. \see CZipSegmCallback */ virtual bool Callback(ZIP_SIZE_TYPE uProgress) = 0; /** Stored the filename of an external file, if the action (adding, extracting or segmentation) uses such a file. */ CZipString m_szExternalFile; virtual ~CZipCallback(){} }; /** When you derive from CZipSegmCallback, you can use the derived class as a callback object for: - the disk change notification in a spanned archive, - notification about the next part being processed in a split archive. You need to override the CZipActionCallback::Callback method. The value of the \a uProgress parameter in the callback method has the following meaning: - the minimum number of free bytes required on the disk when writing a spanned archive - it is set to \c 0 when reading a spanned archive - when writing or reading a split archive it is set to \c 0 apart for the last volume when it is set to \c ZIP_SPLIT_LAST_VOLUME Return \c false from the callback function to abort the operation: the proper exception will be thrown. \see 0610051553|span \see CZipActionCallback::Callback \see CZipArchive::SetSegmCallback */ struct ZIP_API CZipSegmCallback : public CZipCallback { /** Values indicating the reason for calling the callback. */ enum SegmCodes { scVolumeNeededForRead, ///< The next volume is needed when reading a segmented archive. The number of the volume is stored in #m_uVolumeNeeded. scVolumeNeededForWrite, ///< The next volume is needed when writing a segmented archive. The number of the volume is stored in #m_uVolumeNeeded. scFileNameDuplicated, ///< The file used for writing a new volume already exists. scCannotSetVolLabel, ///< The disk label could not be set. The disk may be write-protected. Called only for spanned archives. scFileCreationFailure, ///< The archive file could not be created. The disk may be write-protected. scFileNotFound, ///< The given volume file was not found when reading a split archive. The number of the volume is stored in #m_uVolumeNeeded. Called only for split archives. }; ZIP_VOLUME_TYPE m_uVolumeNeeded; ///< The number of the volume needed when reading or writing a segmented archive. Volumes are numbered starting from 1. int m_iCode; ///< The reason for calling the callback. Can be one of the #SegmCodes values. }; /** When you derive from CZipActionCallback, you can use the new class as a callback object when adding, extracting, deleting, testing files or saving the central directory. You need to override the CZipActionCallback::Callback method. The value of the \a uProgress parameter in the callback method is the amount of data just processed. \see 0610231200 \see CZipActionCallback::Callback \see CZipArchive::SetCallback */ struct ZIP_API CZipActionCallback : public CZipCallback { friend class CZipArchive; friend class CZipCentralDir; /** Values used for specifying a callback type in the CZipArchive::SetCallback method. You can assign several values to the same callback object (use the logical \c OR). \see 0610231200 \see CZipArchive::SetCallback \see CZipActionCallback */ enum CallbackType { /** Not used. You can use it for your own purposes. */ cbNothing = 0x0000, /** Compressing a file. The callback called when adding a file with one of the CZipArchive::AddNewFile methods. */ cbAdd = 0x0001, /** Moving a file from a temporary archive. The callback called while adding a file (only on a segmented archive) when the smartness level contains CZipArchive::zipsmCheckForEff or CZipArchive::zipsmCheckForEffInMem and if the just compressed file is being moved from a temporary place (file or memory) to the archive. */ cbAddTmp = 0x0002, /** Storing a file. The callback called while adding a file and if its compressing has proven to be inefficient and it is now being stored (instead of compressed) in the archive. The smartness level must contain CZipArchive::zipsmCheckForEff or CZipArchive::zipsmCheckForEffInMem. The archive can be segmented or not. */ cbAddStore = 0x0004, /** Extracting a file. The callback called when extracting a file with one of the CZipArchive::ExtractFile methods. */ cbExtract = 0x0008, /** Counting data to process before deleting. The callback called before the actual deletion takes place and the map of holes and continuous areas is being created. It is safe to abort the operation (by returning \c false from the callback method). */ cbDeleteCnt = 0x0010, /** Deleting files. The callback called when moving data while deleting file(s) with the CZipArchive::RemoveFile method or one of the CZipArchive::RemoveFiles methods. */ cbDelete = 0x0020, /** Testing a file. The callback called when testing a file with the CZipArchive::TestFile method. */ cbTest = 0x0040, /** Saving the central directory. The callback called when saving the central directory with the CZipCentralDir::Write method (usually on close or flush). It is safe to abort the operation on a segmented archive - the saved part of the central directory will be removed from disk. */ cbSave = 0x0080, /** Getting a file from another archive. The callback called when using one of the CZipArchive::GetFromArchive methods. */ cbGet = 0x0100, /** Renaming a file. The callback called when during renaming a file there is a need to make less or more space for the new filename. */ cbRename = 0x0200, /** Moving data. The callback called when moving data inside the archive. It happens while replacing files to make less or more space for the new file or while shifting data with the CZipArchive::ShiftData() method. */ cbMoveData = 0x0400, /** The callback called when counting files and bytes to process when performing multiple actions. When this callback is called, CZipActionCallback::m_uTotalToProcess is not set (because it is not known and that's why the counting is performed), but it allows to abort the counting process. */ cbCalculateForMulti= 0x0800, /** The callback called when adding multiple files with one of the CZipArchive::AddNewFiles methods. This callback also registers for #cbAdd. \see 0610231200|multi */ cbMultiAdd = 0x1000 | cbAdd, /** The callback called when preparing existing files for encryption. \see 0610201627|existing */ cbEncryptPrepare= 0x2000, /** The callback called in order to report the progress of making space inside the archive before the actual encryption takes place. \see 0610201627|existing */ cbEncryptMoveData= 0x4000, /** The callback called for every file being encrypted. \see 0610201627|existing */ cbEncrypt = 0x8000, /** The callback called when encrypting existing files in the archive. This callback also registers for #cbEncryptMoveData and #cbEncrypt. \see 0610201627|existing \see 0610231200|multi */ cbMultiEncrypt = 0x10000 | cbEncryptMoveData | cbEncrypt, /** Reserved. You can declare your own callback types above this value. Do not use the numeric value, but the symbol name - the value may change in the future releases of the library. */ cbNextValue = 0x20000, /** All sub-actions. Represents the sub-actions callbacks - they are called as a part of bigger actions (#cbAddTmp | #cbAddStore | #cbDeleteCnt | #cbMoveData | #cbCalculateForMulti | #cbEncryptPrepare | #cbEncryptMoveData). */ cbSubActions = cbAddTmp | cbAddStore | cbDeleteCnt | cbMoveData | cbCalculateForMulti | cbEncryptPrepare | cbEncryptMoveData, /** Main callbacks. Represents the main action callbacks (#cbAdd | #cbExtract | #cbDelete | #cbTest | #cbSave | #cbGet | #cbRename | #cbEncrypt). */ cbActions = cbAdd | cbExtract | cbDelete | cbTest | cbSave | cbGet | cbRename | cbEncrypt, /** Multiple action callbacks. Represents the multiple action callbacks. */ cbMultiActions = cbMultiAdd | cbMultiEncrypt, /** All values. Use this value to call one callback object for all callback types. */ cbAll = cbActions | cbSubActions | cbMultiActions }; /** A structure that provides global information in case of using multiple actions callbacks. \see 0610231200|multi \see cbMultiActions */ struct ZIP_API CMultiActionsInfo { friend struct CZipActionCallback; ZIP_SIZE_TYPE m_uTotalBytesToProcess; ///< The total number of bytes to process. ZIP_SIZE_TYPE m_uTotalFilesToProcess; ///< The total number of files to process. ZIP_SIZE_TYPE m_uBytesProcessed; ///< The total number of bytes processed so far. ZIP_SIZE_TYPE m_uFilesProcessed; ///< The total number of files processed so far. /** Returns the number of files left to process. \return The number of files left to process. */ ZIP_SIZE_TYPE LeftFilesToProcess() const {return m_uTotalFilesToProcess - m_uFilesProcessed;} /** Returns the number of bytes left to process. \return The number of bytes left to process. */ ZIP_SIZE_TYPE LeftBytesToProcess() const {return m_uTotalBytesToProcess - m_uBytesProcessed;} private: void Init(ZIP_SIZE_TYPE uTotalItemsToProcess, ZIP_SIZE_TYPE uTotalBytesToProcess, int iReactType) { m_uTotalFilesToProcess = uTotalItemsToProcess; m_uTotalBytesToProcess = uTotalBytesToProcess; m_uBytesProcessed = m_uFilesProcessed = 0; m_iReactType = iReactType; m_bActive = false; } void OnCallbackInit(int iType) { // this assumes, that the callback type will stay unchanged // between Init() and CallbackEnd() m_bActive = iType == m_iReactType; } void OnCallCallback(ZIP_SIZE_TYPE uProgress) { if (m_bActive) m_uBytesProcessed += uProgress; } bool OnNextFile() { if (m_bActive) { m_uFilesProcessed++; return true; } else return false; } bool m_bActive; int m_iReactType; }; CZipActionCallback() { m_uTotalToProcess = 0; m_uProcessed = 0; m_pMultiActionsInfo = NULL; } /** Called when the multiple actions operation is about to begin. Initializes CMultiActionsInfo object. \param uTotalFilesToProcess The number of files to process. \param uTotalBytesToProcess The number of bytes to process. \param iReactType The type of the callback that will cause increasing of values in CMultiActionsInfo. Can be one of #CallbackType values. \see 0610231200|multi \see GetMultiActionsInfo \note When overriding this method, call the base method from your code. */ virtual void MultiActionsInit(ZIP_SIZE_TYPE uTotalFilesToProcess, ZIP_SIZE_TYPE uTotalBytesToProcess, int iReactType) { InitMultiActionsInfo(); m_pMultiActionsInfo->Init(uTotalFilesToProcess, uTotalBytesToProcess, iReactType); } /** Called to initialize the callback object. Sets the filenames and resets #m_uTotalToProcess and #m_uProcessed variables to \c 0. #m_iType variable is already set to the proper value. Called at the beginning of the operation. \param lpszFileInZip The file that is being processed in the archive. \param lpszExternalFile The external file being processed. This is set to \c NULL, if the operation takes place in memory. */ virtual void Init(LPCTSTR lpszFileInZip = NULL, LPCTSTR lpszExternalFile = NULL) { m_szFileInZip = lpszFileInZip; m_szExternalFile = lpszExternalFile; m_uTotalToProcess = 0; // not yet known m_uProcessed = 0; // nothing yet done CacheStepSize(); ResetProgressStage(); if (m_pMultiActionsInfo) // the type is known now m_pMultiActionsInfo->OnCallbackInit(m_iType); } /** Called after calculating the total amount of data to process. \param uTotalToDo Total amount of data to process. The method initializes #m_uTotalToProcess with this value. */ virtual void SetTotal(ZIP_SIZE_TYPE uTotalToDo) { m_uTotalToProcess = uTotalToDo; // m_uProcessed = 0; // already done in CZipCallbackProvider::Get } /** Called when a next action begins in multiple actions processing. This method calls #Callback method with \a uProgress parameter set to \c 0. \return The value returned from the #Callback method. \see 0610231200|multi \note When overriding this method, call the base method from your code. */ virtual bool MultiActionsNext() { if (m_pMultiActionsInfo && m_pMultiActionsInfo->OnNextFile()) return Callback(0); else return true; } /** Called after the operation finishes. It is not called in case of an exception, but it is called before throwing CZipException::abortedAction or CZipException::abortedSafely. */ virtual void CallbackEnd() { //ASSERT(m_uProcessed == m_uTotalToProcess); }; /** Called at the end of the multiple actions operation. Releases multiple actions information (CMultiActionsInfo). Override this method, if you want this information to be persisted after operation finishes. In that case, CMultiActionsInfo will be released on destruction. \see 0610231200|multi */ virtual void MultiActionsEnd() { ReleaseMultiActionsInfo(); } /** Gets the amount of data left to process. \return The amount of data left to process. */ ZIP_SIZE_TYPE LeftToProcess() const {return m_uTotalToProcess - m_uProcessed;} /** The total amount of data to process. This value is set when the #SetTotal method is called. Depending on the action it is set then to: - Adding a file : the size the external file being added (or if the type of the callback is CZipActionCallback::cbAddTmp, the size of the compressed data: CZipFileHeader::m_uComprSize). - Extracting a file : the size of the uncompressed data (CZipFileHeader::m_uUncomprSize). - Testing a file : the same as above. - Deleting a file : the number of bytes to move - the size of all files to remain above the first file to delete (calculated from offsets in CZipFileHeader::m_uOffset). - Saving the central directory : the number of files in the archive. */ ZIP_SIZE_TYPE m_uTotalToProcess; ZIP_SIZE_TYPE m_uProcessed; ///< The total amount of data processed so far. CZipString m_szFileInZip; ///< The name of the file that is being processed in the archive. /** The type of the callback. It is set to one of the #CallbackType values when the action begins. It's useful, if you have more than one callback assigned to the same callback object. */ int m_iType; /** Returns the current CMultiActionsInfo object in multiple actions operation or \c NULL, if the current operation is not one of CZipActionCallback::cbMultiActions actions. \return The current CMultiActionsInfo object. \see 0610231200|multi */ CMultiActionsInfo* GetMultiActionsInfo() { return m_pMultiActionsInfo; } /** Sets the type of the callback, that will cause the current CMultiActionsInfo object to update its progress. \param iType The type of the callback. It can be one of the #CallbackType values. */ void SetReactType(int iType) { m_pMultiActionsInfo->m_iReactType = iType; } /** Specifies how often the Callback() method is called. The Callback() method is called every \b n-th callback request, where \b n is the value returned from the GetStepSize() method. Override this method to adjust the frequency of calling the callback. \return The value that determines the frequency of calling the Callback() method. By default, it returns \c 256 for #cbSave, #cbDeleteCnt, #cbCalculateForMulti and #cbEncryptPrepare and \c 1 for other callback types. \note This method is called in the Init() method and the returned value is cached for further processing. This means that when you override this method, even with some time-consuming operations, it will not affect the in-action performance. \note Do not use a too low value, because it may increase significantly the time needed to process a huge number of files. */ virtual int GetStepSize() { return m_iType == cbSave || m_iType == cbDeleteCnt || m_iType == cbCalculateForMulti || m_iType == cbEncryptPrepare ? 256 : 1; } ~CZipActionCallback() { ReleaseMultiActionsInfo(); } /** Called by processing classes when data processing progressed. \param uProgress The amount of data processed. \return The value returned from #Callback, if the method was called; \c true otherwise. */ bool RequestCallback(ZIP_SIZE_TYPE uProgress = 1) { if (!uProgress) return true; if (m_iCachedStepSize == 1) return CallCallback(uProgress); else { m_uAccumulatedProgress += uProgress; if (m_iCurrentStep >= m_iCachedStepSize) { bool ret = CallCallback(m_uAccumulatedProgress); ResetProgressStage(); return ret; } else { m_iCurrentStep++; return true; } } } /** Called by processing classes when data processing has finished to allow calling the Callback() method for the amount of processed data for which the Callback() has not been called. This usually happens, when GetStepSize() does not return 1. \param uProgress The amount of data processed. \return The value returned from the #Callback method, if the method was called; \c true otherwise. */ bool RequestLastCallback(ZIP_SIZE_TYPE uProgress = 0) { bool ret; if (m_uAccumulatedProgress == 0 && uProgress == 0) ret = true; else ret = CallCallback(m_uAccumulatedProgress + uProgress); ResetProgressStage(); return ret; } protected: /** Calls the Callback() method internally, increases CZipActionCallback::m_uProcessed and lets the CZipActionCallback increase its values, if needed. \param uProgress The amount of data processed. \return The return value from the Callback() method. */ virtual bool CallCallback(ZIP_SIZE_TYPE uProgress) { m_uProcessed += uProgress; if (m_pMultiActionsInfo) m_pMultiActionsInfo->OnCallCallback(uProgress); return Callback(uProgress); } /** Caches the value returned from the GetStepSize() method. Called in the Init()method. */ void CacheStepSize() { m_iCachedStepSize = GetStepSize(); if (m_iCachedStepSize == 0) m_iCachedStepSize = 1; } /** Initializes the values that depend on the frequency of calling the Callback() method. Called with every call to the Callback() method. \see GetStepSize */ void ResetProgressStage() { m_iCurrentStep = 1; m_uAccumulatedProgress = 0; } private: CMultiActionsInfo* m_pMultiActionsInfo; void InitMultiActionsInfo() { ReleaseMultiActionsInfo(); m_pMultiActionsInfo = new CMultiActionsInfo(); } void ReleaseMultiActionsInfo() { if (m_pMultiActionsInfo != NULL) { delete m_pMultiActionsInfo; m_pMultiActionsInfo = NULL; } } int m_iCachedStepSize; ///< The cached step value for the time of processing. int m_iCurrentStep; ZIP_SIZE_TYPE m_uAccumulatedProgress; }; #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning (pop) #endif #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipExtraData.cpp0000644000175000017500000000255311300022650022102 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipArchive.h" #include "ZipExtraData.h" #include "BytesWriter.h" using namespace ZipArchiveLib; bool CZipExtraData::Read(char* buffer, WORD uSize) { if (uSize < 4) return false; WORD size; CBytesWriter::ReadBytes(m_uHeaderID, buffer); CBytesWriter::ReadBytes(size, buffer + 2); if (uSize - 4 < size) return false; m_data.Allocate(size); memcpy(m_data, buffer + 4, size); return true; } WORD CZipExtraData::Write(char* buffer)const { CBytesWriter::WriteBytes(buffer, m_uHeaderID); WORD size = (WORD)m_data.GetSize(); CBytesWriter::WriteBytes(buffer + 2, size); memcpy(buffer + 4, m_data, size); return (WORD)(size + 4); } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipBaseException.h0000644000175000017500000000203011300022650022411 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipBaseException.h * Contains a type definition of the base exception class. * */ #ifndef ZIPARCHIVE_ZIPBASEEXCEPTION_DOT_H #define ZIPARCHIVE_ZIPBASEEXCEPTION_DOT_H #ifdef ZIP_ARCHIVE_STL typedef std::exception CZipBaseException; #else typedef CException CZipBaseException; #endif #endif //ZIPARCHIVE_ZIPBASEEXCEPTION_DOT_H tuxcmd-modules-0.6.70+ds/zip/ZipArchive/Wildcard.h0000644000175000017500000001156711300022650020745 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /* This class is based on code by J. Kercheval, created 01/05/1991 and available as a public domain at http://www.snippets.org. */ /** * \file Wildcard.h * Includes the ZipArchiveLib::CWildcard class. * */ #if !defined(ZIPARCHIVE_WILDCARD_DOT_H) #define ZIPARCHIVE_WILDCARD_DOT_H #if _MSC_VER > 1000 #pragma once #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning( push ) #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class #endif #endif #include "ZipString.h" namespace ZipArchiveLib { /** A class used in the wildcard pattern matching. \see 0610242025|wildcards */ class ZIP_API CWildcard { public: enum Match { matchNone, ///< For internal use. matchValid, ///< Valid match. matchEnd, ///< Premature end of the pattern string. matchAbort, ///< Premature end of the text string. matchRange, ///< Match failure on the \c [..] construct. matchLiteral, ///< Match failure on a literal match matchPattern ///< Bad pattern. }; enum Pattern { patternEmpty = -4, ///< The \c [..] construct is empty patternClose, ///< There is no end bracket in the \c [..] construct. patternRange, ///< Malformed range in the \c [..] construct. patternEsc, ///< Literal escape at the end of the pattern. patternValid, ///< Valid pattern. }; /** Matches \a lpszText against the pattern. A match means the entire \a lpszText is used up in matching. Set the pattern with the #SetPattern method or in the constructor. \param lpszText The string to match against the pattern. \param iRetCode If not \c NULL, receives one of #Match values indicating a return code. \return \c true, if \a lpszText matches the pattern. \see SetPattern */ bool IsMatch(LPCTSTR lpszText, int* iRetCode = NULL); /** Gets a value indicating if \a lpszPattern has any special wildcard characters. \param lpszPattern The pattern to test. \return \c true, if the pattern has wildcard characters; \c false otherwise. */ static bool IsPattern(LPCTSTR lpszPattern); /** Tests \a lpszPattern for validity. \param lpszPattern The pattern to test. \param iErrorType If not \c NULL, receives one of the #Pattern values indicating a return code. \return \c true, if \a lpszPattern is a well formed regular expression according to the CWildcard class syntax (see #SetPattern); \c false otherwise. */ static bool IsPatternValid(LPCTSTR lpszPattern, int* iErrorType = NULL); /** Matches \a lpszText against \a lpszPattern. A match means the entire \a lpszText is used in matching. \param lpszPattern The pattern to match. \param lpszText The string to match against the pattern. \return One of #Match values. \see SetPattern */ static int Match(LPCTSTR lpszPattern, LPCTSTR lpszText); /** Initializes a new instance of the CWildcard class. */ CWildcard(){} /** Initializes a new instance of the CWildcard class. \param lpszPattern The pattern to use in matching. \param bCaseSensitive The case-sensitivity of matching. \see 0610242025|wildcards */ CWildcard(LPCTSTR lpszPattern, bool bCaseSensitive) { SetPattern(lpszPattern, bCaseSensitive); } virtual ~CWildcard(){} /** Sets the current pattern \param lpszPattern The pattern used in matching. \param bCaseSensitive The case-sensitivity of matching. \see 0610242025|wildcards */ void SetPattern(LPCTSTR lpszPattern, bool bCaseSensitive) { m_szPattern = lpszPattern; m_bCaseSensitive=bCaseSensitive; if (!bCaseSensitive) m_szPattern.MakeLower(); } operator LPCTSTR() { return (LPCTSTR)m_szPattern; } private: bool m_bCaseSensitive; static int MatchAfterStar(LPCTSTR p , LPCTSTR t); CZipString m_szPattern; }; } #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning (pop) #endif #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipArchive.cpp0000644000175000017500000024501011300022650021603 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipArchive.h" #include "ZipPlatform.h" #include "ZipCompatibility.h" #include "Wildcard.h" #include "BytesWriter.h" #include using namespace ZipArchiveLib; const char CZipArchive::m_gszCopyright[] = {"ZipArchive Library Copyright (C) 2000 - 2007 Artpol Software - Tadeusz Dracz"}; const char CZipArchive::m_gszVersion[] = {"3.2.0"}; void CZipAddNewFileInfo::Defaults() { m_iSmartLevel = CZipArchive::zipsmSafeSmart; m_uReplaceIndex = ZIP_FILE_INDEX_UNSPECIFIED; m_nBufSize = 65536; m_iComprLevel = -1; // default } CZipArchive:: CZipArchive() { Initialize(); } void CZipArchive::Initialize() { m_bRemoveDriveLetter = true; m_bExhaustiveRead = false; m_bAutoFlush = false; m_iFileOpened = nothing; SetCaseSensitivity(ZipPlatform::GetSystemCaseSensitivity()); m_uCompressionMethod = CZipCompressor::methodDeflate; m_iEncryptionMethod = CZipCryptograph::encStandard; m_pCryptograph = NULL; m_pCompressor = NULL; m_iBufferSize = 65536; } CZipArchive::~ CZipArchive() { // Close(); // cannot be here: if an exception is thrown strange things can happen ClearCompressor(); ClearCryptograph(); } bool CZipArchive::Open(LPCTSTR szPathName, int iMode, ZIP_SIZE_TYPE uVolumeSize) { if (!IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive already opened.\n"); return false; } m_storage.Open(szPathName, iMode, uVolumeSize); OpenInternal(iMode); return true; } bool CZipArchive::Open(CZipAbstractFile& af, int iMode) { if (!IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is already opened.\n"); return false; } if (iMode != zipOpen && iMode != zipOpenReadOnly && iMode != zipCreate && iMode != zipCreateAppend) { ZIPTRACE("%s(%i) : Mode is not supported.\n"); return false; } m_storage.Open(af, iMode); OpenInternal(iMode); return true; } bool CZipArchive::OpenFrom( CZipArchive& zip) { if (zip.IsClosed()) { ZIPTRACE("%s(%i) : The source archive must be opened.\n"); return false; } if (!zip.IsReadOnly()) { ZIPTRACE("%s(%i) : The source archive must be opened in the read-only mode.\n"); return false; } if (zip.m_storage.m_bInMemory) { ZIPTRACE("%s(%i) : ZipArchive cannot share an archive in memory.\n"); return false; } m_storage.Open(zip.GetArchivePath(), CZipArchive::zipOpenReadOnly, zip.m_storage.IsSplit() ? 1 : 0); InitOnOpen(zip.GetSystemCompatibility(), &zip.m_centralDir); return true; } void CZipArchive::InitOnOpen(int iArchiveSystCompatib, CZipCentralDir* pSource) { m_pszPassword.Release(); m_iFileOpened = nothing; m_szRootPath.Empty(); m_centralDir.Init(&m_storage, &m_callbacks, &m_stringSettings, pSource); m_iArchiveSystCompatib = iArchiveSystCompatib; } void CZipArchive::OpenInternal(int iMode) { InitOnOpen(ZipPlatform::GetSystemID()); if ((iMode == zipOpen) ||(iMode == zipOpenReadOnly)) { m_centralDir.Read(m_bExhaustiveRead); // if there is at least one file, get system comp. from the first one if (m_centralDir.IsValidIndex(0)) { int iSystemComp = m_centralDir[0]->GetSystemCompatibility(); if (ZipCompatibility::IsPlatformSupported(iSystemComp)) m_iArchiveSystCompatib = iSystemComp; } } } void CZipArchive::ThrowError(int err) { CZipException::Throw(err, IsClosed() ? _T("") : (LPCTSTR)m_storage.m_pFile->GetFilePath()); } bool CZipArchive::GetFileInfo(CZipFileHeader & fhInfo, ZIP_INDEX_TYPE uIndex) const { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return false; } if (!m_centralDir.IsValidIndex(uIndex)) return false; fhInfo = *(m_centralDir[uIndex]); return true; } CZipFileHeader* CZipArchive::GetFileInfo(ZIP_INDEX_TYPE uIndex) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return NULL; } if (!m_centralDir.IsValidIndex(uIndex)) return NULL; return m_centralDir[uIndex]; } const CZipFileHeader* CZipArchive::GetFileInfo(ZIP_INDEX_TYPE uIndex) const { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return NULL; } if (!m_centralDir.IsValidIndex(uIndex)) return NULL; return m_centralDir[uIndex]; } ZIP_INDEX_TYPE CZipArchive::FindFile(LPCTSTR lpszFileName, int iCaseSensitive, bool bFileNameOnly) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return ZIP_FILE_INDEX_NOT_FOUND; } bool bCS; bool bSporadically; switch (iCaseSensitive) { case ffCaseSens: bCS = true; bSporadically = true; break; case ffNoCaseSens: bCS = false; bSporadically = true; break; default: bCS = m_bCaseSensitive; bSporadically = false; } return m_centralDir.FindFile(lpszFileName, bCS, bSporadically, bFileNameOnly); } bool CZipArchive::OpenFile(ZIP_INDEX_TYPE uIndex) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return false; } if (!m_centralDir.IsValidIndex(uIndex)) { ASSERT(FALSE); return false; } if (m_storage.IsSegmented() == 1) { ZIPTRACE("%s(%i) : ZipArchive Library cannot extract from a segmented archive in creation.\n"); return false; } if (m_iFileOpened) { ZIPTRACE("%s(%i) : A file already opened.\n"); return false; } m_centralDir.OpenFile(uIndex); // check it now, not when reading central to allow reading information // but disallow extraction now - unsupported method if (!CZipCompressor::IsCompressionSupported(CurrentFile()->m_uMethod)) { m_centralDir.CloseFile(true); ZIPTRACE("%s(%i) : The compression method is not supported.\n"); return false; } if (CurrentFile()->IsEncrypted()) { if (m_pszPassword.GetSize() == 0) { ZIPTRACE("%s(%i) : Password not set for the encrypted file.\n"); ThrowError(CZipException::badPassword); } CreateCryptograph(CurrentFile()->m_uEncryptionMethod); if (!m_pCryptograph->InitDecode(m_pszPassword, *CurrentFile(), m_storage)) ThrowError(CZipException::badPassword); } else { ClearCryptograph(); if (m_pszPassword.GetSize() != 0) { ZIPTRACE("%s(%i) : Password set for a not encrypted file. Ignoring password.\n"); } } CreateCompressor(CurrentFile()->m_uMethod); m_pCompressor->InitDecompression(CurrentFile(), m_pCryptograph); m_iFileOpened = extract; return true; } CZipFileHeader* CZipArchive::CurrentFile() { ASSERT(m_centralDir.m_pOpenedFile); return m_centralDir.m_pOpenedFile; } DWORD CZipArchive::ReadFile(void *pBuf, DWORD uSize) { if (m_iFileOpened != extract) { ZIPTRACE("%s(%i) : Current file must be opened.\n"); return 0; } if (!pBuf || !uSize) return 0; return m_pCompressor->Decompress(pBuf, uSize); } void CZipArchive::Close(int iAfterException, bool bUpdateTimeStamp) { // if after an exception - the archive may be closed, but the file may be opened if (IsClosed() && (!iAfterException || IsClosed(false))) { ZIPTRACE("%s(%i) : ZipArchive is already closed.\n"); return; } if (m_iFileOpened == extract) CloseFile(NULL, iAfterException != afNoException); if (m_iFileOpened == compress) CloseNewFile(iAfterException != afNoException); bool bWrite = iAfterException != afAfterException && !IsClosed(false);// in segmented archive when user aborts if (bWrite) WriteCentralDirectory(false); // we will flush in CZipStorage::Close time_t tNewestTime = 0; if (bUpdateTimeStamp) { ZIP_INDEX_TYPE iSize = (ZIP_INDEX_TYPE)m_centralDir.GetCount(); for (ZIP_INDEX_TYPE i = 0; i < iSize; i++) { time_t tFileInZipTime = m_centralDir[i]->GetTime(); if (tFileInZipTime > tNewestTime) tNewestTime = tFileInZipTime; } } m_centralDir.Close(); m_stringSettings.Reset(); CZipString szFileName = m_storage.Close(!bWrite); if (bUpdateTimeStamp && !szFileName.IsEmpty()) ZipPlatform::SetFileModTime(szFileName, tNewestTime); } void CZipArchive::WriteCentralDirectory(bool bFlush) { m_centralDir.Write(); if (bFlush) m_storage.Flush(); } void CZipArchive::SetAdvanced(int iWriteBuffer, int iGeneralBuffer, int iSearchBuffer) { if (!IsClosed()) { ZIPTRACE("%s(%i) : Set these options before opening the archive.\n"); return; } m_storage.m_iWriteBufferSize = iWriteBuffer < 1024 ? 1024 : iWriteBuffer; m_iBufferSize = iGeneralBuffer < 1024 ? 1024 : iGeneralBuffer; m_storage.m_iLocateBufferSize = iSearchBuffer < 1024 ? 1024 : iSearchBuffer; } int CZipArchive::CloseFile(CZipFile &file) { CZipString temp = file.GetFilePath(); file.Close(); return CloseFile(temp); } int CZipArchive::CloseFile(LPCTSTR lpszFilePath, bool bAfterException) { if (m_iFileOpened != extract) { ZIPTRACE("%s(%i) : No opened file.\n"); return 0; } int iRet = 1; if (bAfterException) m_pCompressor->FinishDecompression(true); else { if (m_pCompressor->m_uUncomprLeft == 0) { if (m_centralDir.IsConsistencyCheckOn(checkCRC) && !CurrentFile()->m_bIgnoreCrc32 && m_pCompressor->m_uCrc32 != CurrentFile()->m_uCrc32) ThrowError(CZipException::badCrc); } else iRet = -1; m_pCompressor->FinishDecompression(false); if (lpszFilePath) { if (!ZipPlatform::SetFileModTime(lpszFilePath, CurrentFile()->GetTime()) ||!ZipPlatform::SetFileAttr(lpszFilePath, CurrentFile()->GetSystemAttr())) iRet = -2; } if (m_pCryptograph) m_pCryptograph->FinishDecode(*CurrentFile(), m_storage); } m_centralDir.CloseFile(bAfterException); m_iFileOpened = nothing; ClearCryptograph(); return iRet; } bool CZipArchive::OpenNewFile(CZipFileHeader & header, int iLevel, LPCTSTR lpszFilePath, ZIP_INDEX_TYPE uReplaceIndex) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return false; } if (m_iFileOpened) { ZIPTRACE("%s(%i) : A file already opened.\n"); return false; } if (m_storage.IsSegmented() == -1) { ZIPTRACE("%s(%i) : ZipArchive Library cannot add files to an existing segmented archive.\n"); return false; } if (GetCount() ==(WORD)USHRT_MAX) { ZIPTRACE("%s(%i) : Maximum file count inside archive reached.\n"); return false; } DWORD uAttr = 0; time_t ttime; if (lpszFilePath) { if (!ZipPlatform::GetFileAttr(lpszFilePath, uAttr)) // do not continue - if the file was a directory then not recognizing it will cause // serious errors (need uAttr to recognize it) return false; ZipPlatform::GetFileModTime(lpszFilePath, ttime); } if (lpszFilePath) { header.SetTime(ttime); SetFileHeaderAttr(header, uAttr); // set system compatibility as well } else { header.SetSystemCompatibility(m_iArchiveSystCompatib); if (!header.HasTime()) header.SetTime(time(NULL)); } CZipString szFileName = header.GetFileName(); bool bIsDirectory = header.IsDirectory(); if (bIsDirectory) { int iNameLen = szFileName.GetLength(); if (!iNameLen || !CZipPathComponent::IsSeparator(szFileName[iNameLen-1])) { szFileName += CZipPathComponent::m_cSeparator; header.SetFileName(szFileName); } } if (szFileName.IsEmpty()) { szFileName.Format(_T("file%u"), GetCount()); header.SetFileName(szFileName); } bool bEncrypted = WillEncryptNextFile(); #if defined _DEBUG && !defined NOZIPTRACE if (bIsDirectory && bEncrypted) ZIPTRACE("%s(%i) : Encrypting a directory. You may want to consider clearing the password before adding a directory.\n"); #endif bool bReplace = uReplaceIndex != ZIP_FILE_INDEX_UNSPECIFIED; if (iLevel < -1 || iLevel > 9) iLevel = -1; if (bEncrypted) { header.m_uEncryptionMethod = (BYTE)m_iEncryptionMethod; CreateCryptograph(m_iEncryptionMethod); } else { header.m_uEncryptionMethod = CZipCryptograph::encNone; ClearCryptograph(); } if (iLevel == 0 || bIsDirectory) header.m_uMethod = CZipCompressor::methodStore; else header.m_uMethod = m_uCompressionMethod; CreateCompressor(header.m_uMethod); CZipFileHeader* pHeader = m_centralDir.AddNewFile(header, uReplaceIndex, iLevel); // replace can happen only from AddNewFile and the compressed size is already known and set (the file is stored, not compressed) if (bReplace) { // this will be used in GetLocalSize and WriteLocal pHeader->PrepareFileName(); // we use the local size, because the real does not exist yet ZIP_SIZE_TYPE uFileSize = pHeader->GetDataSize(true, false) + pHeader->GetLocalSize(false) + pHeader->GetDataDescriptorSize(&m_storage); InitBuffer(); MakeSpaceForReplace(uReplaceIndex, uFileSize, szFileName); ReleaseBuffer(); } CurrentFile()->WriteLocal(&m_storage); if (m_pCryptograph) m_pCryptograph->InitEncode(m_pszPassword, *pHeader, m_storage); m_pCompressor->InitCompression(iLevel, CurrentFile(), m_pCryptograph); m_iFileOpened = compress; return true; } bool CZipArchive::ExtractFile(ZIP_INDEX_TYPE uIndex, LPCTSTR lpszPath, bool bFullPath, LPCTSTR lpszNewName, DWORD nBufSize) { if (!nBufSize && !lpszPath) return false; CZipFileHeader* pHeader = (*this)[uIndex]; CZipString szFileNameInZip = pHeader->GetFileName(); CZipString szFile = PredictExtractedFileName(szFileNameInZip, lpszPath, bFullPath, lpszNewName); CZipActionCallback* pCallback = GetCallback(CZipActionCallback::cbExtract); if (pCallback) pCallback->Init(szFileNameInZip, szFile); if (pHeader->IsDirectory()) { if (pCallback) pCallback->SetTotal(0); // in case of calling LeftToProcess() afterwards ZipPlatform::ForceDirectory(szFile); ZipPlatform::SetFileAttr(szFile, pHeader->GetSystemAttr()); if (pCallback) pCallback->CallbackEnd(); return true; } else { if (!OpenFile(uIndex)) return false; if (pCallback) pCallback->SetTotal(pHeader->m_uUncomprSize); CZipPathComponent zpc(szFile); ZipPlatform::ForceDirectory(zpc.GetFilePath()); CZipFile f(szFile, CZipFile::modeWrite | CZipFile::modeCreate | CZipFile::shareDenyWrite); DWORD iRead; CZipAutoBuffer buf(nBufSize); int iAborted = 0; for(;;) { iRead = ReadFile(buf, buf.GetSize()); if (!iRead) { if (pCallback && !pCallback->RequestLastCallback()) iAborted = CZipException::abortedSafely; break; } f.Write(buf, iRead); if (pCallback && !pCallback->RequestCallback(iRead)) { if (iRead == buf.GetSize() && ReadFile(buf, 1) != 0) // test one byte if there is something left iAborted = CZipException::abortedAction; else iAborted = CZipException::abortedSafely; break; } } if (pCallback) { if (!iAborted) { bool bRet = CloseFile(f) == 1; pCallback->CallbackEnd(); return bRet; } else { if (iAborted == CZipException::abortedAction) CloseFile(NULL, true); else { bool bRet; try { bRet = CloseFile(f) == 1; } // if any exception was thrown, then we are not successful // catch all exceptions to throw aborted exception only #ifdef ZIP_ARCHIVE_MFC catch(CException* e) { e->Delete(); bRet = false; } #endif catch(...) { bRet = false; } if (!bRet) { CloseFile(NULL, true); iAborted = CZipException::abortedAction; } } pCallback->CallbackEnd(); CZipException::Throw(iAborted, szFile); return false; // for the compiler } } else return CloseFile(f) == 1; } } bool CZipArchive::ExtractFile(ZIP_INDEX_TYPE uIndex, CZipMemFile& mf, bool bRewind, DWORD nBufSize) { if (!nBufSize) return false; CZipFileHeader* pHeader = (*this)[uIndex]; CZipActionCallback* pCallback = GetCallback(CZipActionCallback::cbExtract); if (pCallback) pCallback->Init(pHeader->GetFileName()); if (pHeader->IsDirectory() || !OpenFile(uIndex)) return false; if (pCallback) pCallback->SetTotal(pHeader->m_uUncomprSize); CZipAutoBuffer buf(nBufSize); //mf.SeekToEnd(); ZIP_FILE_USIZE oldPos = 0; if (bRewind) oldPos = mf.GetPosition(); DWORD iRead; int iAborted = 0; for(;;) { iRead = ReadFile(buf, buf.GetSize()); if (!iRead) { if (pCallback && !pCallback->RequestLastCallback()) iAborted = CZipException::abortedSafely; break; } mf.Write(buf, iRead); if (pCallback && !pCallback->RequestCallback(iRead)) { if (iRead == buf.GetSize() && ReadFile(buf, 1) != 0) // test one byte if there is something left iAborted = CZipException::abortedAction; else iAborted = CZipException::abortedSafely; // we did it! break; } } bool bRet; if (pCallback) { if (!iAborted) { bRet = CloseFile() == 1; pCallback->CallbackEnd(); } else { if (iAborted == CZipException::abortedAction) CloseFile(NULL, true); else { bRet = false; try { bRet = CloseFile() == 1; } // if any exception was thrown, then we are not successful // catch all exceptions to thrown aborted exception only #ifdef ZIP_ARCHIVE_MFC catch(CException* e) { e->Delete(); bRet = false; } #endif catch(...) { bRet = false; } if (!bRet) { CloseFile(NULL, true); iAborted = CZipException::abortedAction; } } pCallback->CallbackEnd(); if (bRewind) mf.Seek(oldPos, CZipMemFile::begin); CZipException::Throw(iAborted); return false; // for the compiler } } else bRet = CloseFile() == 1; if (bRewind) mf.Seek(oldPos, CZipMemFile::begin); return bRet; } bool CZipArchive::WriteNewFile(const void *pBuf, DWORD uSize) { if (m_iFileOpened != compress) { ZIPTRACE("%s(%i) : A new file must be opened.\n"); return false; } m_pCompressor->Compress(pBuf, uSize); return true; } bool CZipArchive::CloseNewFile(bool bAfterException) { if (m_iFileOpened != compress) { ZIPTRACE("%s(%i) : A new file must be opened.\n"); return false; } m_pCompressor->FinishCompression(bAfterException); if (bAfterException) m_centralDir.m_pOpenedFile = NULL; else { if (m_pCryptograph) m_pCryptograph->FinishEncode(*CurrentFile(), m_storage); m_centralDir.CloseNewFile(); } m_iFileOpened = nothing; ClearCryptograph(); if (m_bAutoFlush && !bAfterException) Flush(); return true; } bool CZipArchive::RemoveFile(ZIP_INDEX_TYPE uIndex) { CZipIndexesArray indexes; indexes.Add(uIndex); return RemoveFiles(indexes); } void CZipArchive::GetIndexes(const CZipStringArray &aNames, CZipIndexesArray& aIndexes) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return; } ZIP_INDEX_TYPE uSize = (ZIP_INDEX_TYPE)aNames.GetSize(); for (ZIP_INDEX_TYPE i = 0; i < uSize; i++) aIndexes.Add(FindFile(aNames[(ZIP_ARRAY_SIZE_TYPE)i], ffDefault, false)); } bool CZipArchive::RemoveFiles(const CZipStringArray &aNames) { CZipIndexesArray indexes; GetIndexes(aNames, indexes); return RemoveFiles(indexes); } struct CZipDeleteInfo { CZipDeleteInfo(){m_pHeader = NULL; m_bDelete = false;} CZipDeleteInfo(CZipFileHeader* pHeader, bool bDelete) :m_pHeader(pHeader), m_bDelete (bDelete){} CZipFileHeader* m_pHeader; bool m_bDelete; }; bool CZipArchive::RemoveFiles(CZipIndexesArray &aIndexes) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return false; } if (m_storage.IsSegmented()) { ZIPTRACE("%s(%i) : ZipArchive Library cannot delete files from a segmented archive.\n"); return false; } if (m_iFileOpened) { ZIPTRACE("%s(%i) : ZipArchive Library cannot delete files if there is a file opened.\n"); return false; } if (GetCount() == 0) { ZIPTRACE("%s(%i) : There is nothing to delete: the archive is empty.\n"); return false; } ZIP_INDEX_TYPE uSize = (ZIP_INDEX_TYPE)aIndexes.GetSize(); if (!uSize) { ZIPTRACE("%s(%i) : The indexes array is empty.\n"); return true; } aIndexes.Sort(true); // remove all - that's easy so don't waste the time if (uSize == GetCount()) { // check that the indexes are correct bool allIncluded = true; // iterate all indexes, if all are sorted then the condition should always be true for (ZIP_INDEX_TYPE i = 0; i < uSize; i++) if (aIndexes[(ZIP_ARRAY_SIZE_TYPE)i] != i) { allIncluded = false; break; } if (allIncluded) { CZipActionCallback* pCallback = GetCallback(CZipActionCallback::cbDelete); if (pCallback) { // do it right and sent the notification pCallback->Init(); pCallback->SetTotal(uSize); } m_centralDir.RemoveFromDisk(); m_storage.m_pFile->SetLength((ZIP_FILE_USIZE) m_storage.m_uBytesBeforeZip); m_centralDir.RemoveAll(); if (m_bAutoFlush) Flush(); if (pCallback) pCallback->CallbackEnd(); return true; } } else { for (ZIP_INDEX_TYPE i = 0; i < uSize; i++) if (!m_centralDir.IsValidIndex(aIndexes[(ZIP_ARRAY_SIZE_TYPE)i])) return false; } ZIP_INDEX_TYPE i; CZipArray aInfo; CZipActionCallback* pCallback = GetCallback(CZipActionCallback::cbDeleteCnt); if (pCallback) { pCallback->Init(); pCallback->SetTotal(GetCount()); } ZIP_INDEX_TYPE uDelIndex = 0; ZIP_INDEX_TYPE uMaxDelIndex = aIndexes[(ZIP_ARRAY_SIZE_TYPE)(uSize - 1)]; i = aIndexes[0]; // GetCount() is greater than 0 (checked before) and when it is unsigned we do not cause overflow ZIP_INDEX_TYPE uLastPosition = (ZIP_INDEX_TYPE)(GetCount() - 1); bool bAborted = false; if (i <= uLastPosition) for(;;) { CZipFileHeader* pHeader = m_centralDir[i]; bool bDelete; if (i <= uMaxDelIndex && i == aIndexes[(ZIP_ARRAY_SIZE_TYPE)uDelIndex]) { uDelIndex++; bDelete = true; } else bDelete = false; aInfo.Add(CZipDeleteInfo(pHeader, bDelete)); if (i == uLastPosition) { if (pCallback && !pCallback->RequestLastCallback(1)) bAborted = true; break; } else { if (pCallback && !pCallback->RequestCallback()) { bAborted = true; break; } i++; } } ASSERT(uDelIndex == uSize); if (pCallback) { pCallback->CallbackEnd(); if (bAborted) ThrowError(CZipException::abortedSafely); } uSize = (ZIP_INDEX_TYPE)aInfo.GetSize(); if (!uSize) // it is possible return true; // they should already be sorted after reading the in CZipCentralDir::ReadHeaders and when replacing, the index is placed at the same place as the old one //aInfo.Sort(true); // sort by offsets (when operators uncommented in CZipDeleteInfo) // now we start deleting (not safe to break) pCallback = GetCallback(CZipActionCallback::cbDelete); if (pCallback) pCallback->Init(); m_centralDir.RemoveFromDisk(); ZIP_SIZE_TYPE uTotalToMoveBytes = 0, uLastOffset = m_storage.GetLastDataOffset(); // count the number of bytes to move i = uSize; while(i > 0) { i--; // cannot use a decreasing loop because i is unsigned and instead negative at the end of the loop it will be maximum positive const CZipDeleteInfo& di = aInfo[(ZIP_ARRAY_SIZE_TYPE)i]; if (!di.m_bDelete) uTotalToMoveBytes += uLastOffset - di.m_pHeader->m_uOffset; uLastOffset = di.m_pHeader->m_uOffset; } if (pCallback) pCallback->SetTotal(uTotalToMoveBytes); InitBuffer(); ZIP_SIZE_TYPE uMoveBy = 0, uOffsetStart = 0; for (i = 0; i < uSize; i++) { const CZipDeleteInfo& di = aInfo[(ZIP_ARRAY_SIZE_TYPE)i]; if (di.m_bDelete) { // next hole ZIP_SIZE_TYPE uTemp = di.m_pHeader->m_uOffset; m_centralDir.RemoveFile(di.m_pHeader); // first remove if (uOffsetStart) { // copy the files over a previous holes MovePackedFiles(uOffsetStart, uTemp, uMoveBy, pCallback, false, false); uOffsetStart = 0; // never be at the beginning, because the first file is always to be deleted } if (i == uSize - 1) uTemp = (m_storage.GetLastDataOffset()) - uTemp; else uTemp = aInfo[(ZIP_ARRAY_SIZE_TYPE)(i + 1)].m_pHeader->m_uOffset - uTemp; uMoveBy += uTemp; } else { if (uOffsetStart == 0) // find continuous area to move uOffsetStart = di.m_pHeader->m_uOffset; di.m_pHeader->m_uOffset -= uMoveBy; } } if (uOffsetStart) { // will call the last callback, if necessary MovePackedFiles(uOffsetStart, m_storage.GetLastDataOffset(), uMoveBy, pCallback); } else { // call last callback (it was not called in the MovePackedFiles calls in the loop) if (pCallback && !pCallback->RequestLastCallback()) { pCallback->CallbackEnd(); ThrowError(CZipException::abortedAction); } } ReleaseBuffer(); if (uMoveBy) // just in case m_storage.m_pFile->SetLength((ZIP_FILE_USIZE)(m_storage.m_pFile->GetLength() - uMoveBy)); if (pCallback) pCallback->CallbackEnd(); if (m_bAutoFlush) Flush(); return true; } bool CZipArchive::ShiftData(ZIP_SIZE_TYPE uOffset) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive should be opened first.\n"); return false; } if (m_storage.IsSegmented() != 0) { ZIPTRACE("%s(%i) : Cannot shift data for a segmented archive.\n"); return false; } if (m_iFileOpened) { ZIPTRACE("%s(%i) : A file should not be opened.\n"); return false; } if (m_storage.m_uBytesBeforeZip != 0) { ZIPTRACE("%s(%i) : Bytes before zip file must not be present.\n"); return false; } if (uOffset == 0) return true; m_centralDir.RemoveFromDisk(); // does m_storage.Flush(); InitBuffer(); ZIP_SIZE_TYPE uFileLen = (ZIP_SIZE_TYPE)m_storage.m_pFile->GetLength(); CZipActionCallback* pCallback = GetCallback(CZipActionCallback::cbMoveData); if (pCallback) { pCallback->Init(NULL, GetArchivePath()); pCallback->SetTotal(uFileLen); } m_storage.m_pFile->SetLength((ZIP_FILE_USIZE)(uFileLen + uOffset)); // ensure the seek is correct MovePackedFiles(0, uFileLen, uOffset, pCallback, true); ZIP_INDEX_TYPE uSize = GetCount(); for (ZIP_INDEX_TYPE i = 0; i < uSize; i++) m_centralDir[i]->m_uOffset += uOffset; if (pCallback) pCallback->CallbackEnd(); return true; } bool CZipArchive::PrependData(LPCTSTR lpszFilePath, LPCTSTR lpszNewExt) { CZipFile file(lpszFilePath, CZipFile::modeRead | CZipFile::shareDenyNone); return PrependData(file, lpszNewExt); } bool CZipArchive::PrependData(CZipAbstractFile& file, LPCTSTR lpszNewExt) { if (file.IsClosed()) { ZIPTRACE("%s(%i) : File to prepend should be opened.\n"); return false; } ZIP_SIZE_TYPE uOffset = (ZIP_SIZE_TYPE)file.GetLength(); if (uOffset == 0) return true; if (!ShiftData(uOffset)) return false; file.SeekToBegin(); // do not use callback - self-extracting stubs should be small m_storage.Seek(0); char* buf = (char*)m_pBuffer; ZIP_SIZE_TYPE uTotalToMove = uOffset; ZIP_SIZE_TYPE uToRead; UINT uSizeRead; bool bBreak = false; DWORD bufSize = m_pBuffer.GetSize(); do { uToRead = uTotalToMove > bufSize ? bufSize : uTotalToMove; uSizeRead = (UINT)file.Read(buf, (UINT)uToRead); if (!uSizeRead) break; uTotalToMove -= uSizeRead; if (uTotalToMove == 0) bBreak = true; m_storage.m_pFile->Write(buf, uSizeRead); } while (!bBreak); if (m_storage.m_bInMemory || lpszNewExt == NULL) return true; CZipString szInitialPath = m_storage.m_pFile->GetFilePath(); // must close to rename Close(); CZipPathComponent zpc(szInitialPath); zpc.SetExtension(lpszNewExt); CZipString szNewPath = zpc.GetFullPath(); if (!ZipPlatform::RenameFile(szInitialPath, szNewPath, false)) return false; #ifdef ZIP_ARCHIVE_LNX return ZipPlatform::SetExeAttr(szNewPath); #else return true; #endif } bool CZipArchive::AddNewFile(LPCTSTR lpszFilePath, int iComprLevel, bool bFullPath, int iSmartLevel, unsigned long nBufSize) { CZipAddNewFileInfo zanfi (lpszFilePath, bFullPath); zanfi.m_iComprLevel = iComprLevel; zanfi.m_iSmartLevel = iSmartLevel; zanfi.m_nBufSize = nBufSize; return AddNewFile(zanfi); } bool CZipArchive::AddNewFile(LPCTSTR lpszFilePath, LPCTSTR lpszFileNameInZip, int iComprLevel, int iSmartLevel, unsigned long nBufSize) { CZipAddNewFileInfo zanfi(lpszFilePath, lpszFileNameInZip); zanfi.m_iComprLevel = iComprLevel; zanfi.m_iSmartLevel = iSmartLevel; zanfi.m_nBufSize = nBufSize; return AddNewFile(zanfi); } bool CZipArchive::AddNewFile(CZipMemFile& mf, LPCTSTR lpszFileNameInZip, int iComprLevel, int iSmartLevel, unsigned long nBufSize) { CZipAddNewFileInfo zanfi(&mf, lpszFileNameInZip); zanfi.m_iComprLevel = iComprLevel; zanfi.m_iSmartLevel = iSmartLevel; zanfi.m_nBufSize = nBufSize; return AddNewFile(zanfi); } /** A structure for the internal use only. Clears the password if necessary and restores it later (also in case of an exception). */ struct CZipSmClrPass { CZipSmClrPass() { m_pZip = NULL; } void ClearPasswordSmartly( CZipArchive* pZip) { m_pZip = pZip; m_szPass = pZip->GetPassword(); if (!m_szPass.IsEmpty()) pZip->SetPassword(); } ~CZipSmClrPass() { if (!m_szPass.IsEmpty()) m_pZip->SetPassword(m_szPass); } private: CZipString m_szPass; CZipArchive* m_pZip; }; bool CZipArchive::AddNewFile(CZipAddNewFileInfo& info) { // no need for ASSERT and TRACE here - it will be done by OpenNewFile if (!m_iBufferSize) return false; if (info.m_pFile) info.m_szFilePath = info.m_pFile->GetFilePath(); else { CZipPathComponent::RemoveSeparators(info.m_szFilePath); if (info.m_szFilePath.IsEmpty()) return false; } bool bSegm = GetSegmMode() != 0; // checking the replace index if (!UpdateReplaceIndex(info.m_uReplaceIndex)) return false; bool bReplace = info.m_uReplaceIndex != ZIP_FILE_INDEX_UNSPECIFIED; DWORD uAttr; time_t ttime; if (info.m_pFile) { uAttr = ZipPlatform::GetDefaultAttributes(); ttime = time(NULL); } else { if (!ZipPlatform::GetFileAttr(info.m_szFilePath, uAttr)) return false; // we don't know whether it is a file or a directory ZipPlatform::GetFileModTime(info.m_szFilePath, ttime); } CZipFileHeader header; SetFileHeaderAttr(header, uAttr); if (info.m_szFileNameInZip.IsEmpty()) info.m_szFileNameInZip = PredictFileNameInZip(info.m_szFilePath, info.m_bFullPath, header.IsDirectory() ? prDir : prFile); header.SetFileName(info.m_szFileNameInZip); header.SetTime(ttime); bool bInternal = (info.m_iSmartLevel & zipsmInternal01) != 0; if (header.IsDirectory()) // will never be when m_pFile is not NULL, so we don't check it { ASSERT(!info.m_pFile); // should never happened ASSERT(!bInternal); CZipActionCallback* pCallback = GetCallback(CZipActionCallback::cbAdd); if (pCallback) { pCallback->Init(info.m_szFileNameInZip, info.m_szFilePath); pCallback->SetTotal(0); // in case of calling LeftToProcess() afterwards } // clear password for a directory CZipSmClrPass smcp; if (info.m_iSmartLevel & zipsmCPassDir) smcp.ClearPasswordSmartly(this); bool bRet = OpenNewFile(header, CZipCompressor::levelStore, NULL, info.m_uReplaceIndex); CloseNewFile(); if (pCallback) pCallback->CallbackEnd(); return bRet; } CZipSmClrPass smcp; bool bIsCompression = info.m_iComprLevel != 0; bool bEff = (info.m_iSmartLevel & zipsmCheckForEff)&& bIsCompression; bool bCheckForZeroSized = (info.m_iSmartLevel & zipsmCPFile0) && WillEncryptNextFile(); bool bCheckForSmallFiles = (info.m_iSmartLevel & zipsmNotCompSmall) && bIsCompression; ZIP_SIZE_TYPE uFileSize = ZIP_SIZE_TYPE(-1); bool bNeedTempArchive = (bEff && bSegm) || (bReplace && bIsCompression); if (bCheckForSmallFiles || bCheckForZeroSized || bNeedTempArchive) { if (info.m_pFile) uFileSize = (ZIP_SIZE_TYPE)info.m_pFile->GetLength(); else { if (!ZipPlatform::GetFileSize(info.m_szFilePath, uFileSize) && bEff) bEff = false; // the file size is needed only when efficient in a segmented archive } if (uFileSize != ZIP_SIZE_TYPE(-1)) { if (bCheckForZeroSized && uFileSize == 0) smcp.ClearPasswordSmartly(this); if (bCheckForSmallFiles && uFileSize < 5) info.m_iComprLevel = 0; } } bool bEffInMem = bEff && (info.m_iSmartLevel & zipsmMemoryFlag); CZipString szTempFileName; if (bNeedTempArchive && (bEffInMem || !(szTempFileName = ZipPlatform::GetTmpFileName( m_szTempPath.IsEmpty() ? NULL : (LPCTSTR)m_szTempPath, uFileSize) ).IsEmpty())) { CZipMemFile* pmf = NULL; CZipArchive zip; try { // compress first to a temporary file, if ok - copy the data, if not - add storing if (bEffInMem) { pmf = new CZipMemFile; zip.Open(*pmf, zipCreate); } else zip.Open(szTempFileName, zipCreate); zip.SetRootPath(m_szRootPath); zip.SetPassword(GetPassword()); zip.SetEncryptionMethod(m_iEncryptionMethod); zip.SetSystemCompatibility(m_iArchiveSystCompatib); zip.SetCallback(GetCallback(CZipActionCallback::cbAdd), CZipActionCallback::cbAdd); // create a temporary file ZIP_INDEX_TYPE uTempReplaceIndex = info.m_uReplaceIndex; info.m_iSmartLevel = zipsmLazy; info.m_uReplaceIndex = ZIP_FILE_INDEX_UNSPECIFIED; if (!zip.AddNewFile(info)) throw false; info.m_uReplaceIndex = uTempReplaceIndex; // this may also happen when bReplace, but not in a segmented archive if (bEff) { if (!zip[0]->CompressionEfficient()) { info.m_iComprLevel = 0; info.m_iSmartLevel = zipsmInternal01; // compression is not efficient, store instead throw AddNewFile(info); } } zip.m_storage.Flush(); InitBuffer(); throw GetFromArchive(zip, 0, NULL, info.m_uReplaceIndex, true, GetCallback(CZipActionCallback::cbAddTmp)); } catch (bool bRet) { zip.Close(!bRet); // that doesn't really matter how it will be closed if (pmf) delete pmf; if (!bEffInMem) ZipPlatform::RemoveFile(szTempFileName, false); ReleaseBuffer(); return bRet; } catch (...) { zip.Close(true); if (pmf) delete pmf; if (!bEffInMem) ZipPlatform::RemoveFile(szTempFileName, false); ReleaseBuffer(); throw; } } // try to open before adding CZipFile f; CZipAbstractFile *pf; if (info.m_pFile) { pf = info.m_pFile; pf->SeekToBegin(); } else { // cannot be shareDenyWrite // If you specify the GENERIC_READ and GENERIC_WRITE access modes along with the FILE_SHARE_READ and FILE_SHARE_WRITE sharing modes in your first call to CreateFile. If you specify the GENERIC_READ and GENERIC_WRITE access modes and the FILE_SHARE_READ sharing mode only in your second call to CreateFile, the function will fail with a sharing violation because the read-only sharing mode specified in the second call conflicts with the read/write access that has been granted in the first call. // Original information was here (but not any longer): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/creating_and_opening_files.asp if (!f.Open(info.m_szFilePath, CZipFile::modeRead | CZipFile::shareDenyNone, false)) return false; pf = &f; } ASSERT(pf); // call init before opening (in case of exception we have the names) uFileSize = (ZIP_SIZE_TYPE)pf->GetLength(); // predict sizes in local header, so that zip64 can write extra header if needed header.m_uLocalUncomprSize = uFileSize; if (!bIsCompression) header.m_uLocalComprSize = uFileSize; bool bRet; if (bReplace) { ASSERT(!bIsCompression); bRet = OpenNewFile(header, CZipCompressor::levelStore, NULL, info.m_uReplaceIndex); } else bRet = OpenNewFile(header, info.m_iComprLevel); if (!bRet) return false; // we do it here, because if in OpenNewFile is replacing // then we get called cbMoveData callback before and it would // overwrite callback information written in pCallback->Init() CZipActionCallback* pCallback = GetCallback(bInternal ? CZipActionCallback::cbAddStore : CZipActionCallback::cbAdd); if (pCallback) { // Init cbAdd here as well - after smart add - to avoid double initiation when // temporary archive is used - it would init cbAdd again pCallback->Init(info.m_szFileNameInZip, info.m_szFilePath); pCallback->SetTotal(uFileSize); } CZipAutoBuffer buf(info.m_nBufSize); DWORD iRead; int iAborted = 0; do { iRead = pf->Read(buf, info.m_nBufSize); if (iRead) { WriteNewFile(buf, iRead); if (pCallback && !pCallback->RequestCallback(iRead)) { if (iRead == buf.GetSize() && pf->Read(buf, 1) != 0) // test one byte if there is something left { if (!m_storage.IsSegmented() && !bReplace) { RemoveLast(true); iAborted = CZipException::abortedSafely; } else iAborted = CZipException::abortedAction; // close new file with bException set to true, even if abortedSafely, // because in that case we have removed the last file - there is nothing to close CloseNewFile(true); } else // temporary value - possible safe abort iAborted = CZipException::aborted; break; } } } while (iRead == buf.GetSize()); if (pCallback) { if (!iAborted && !pCallback->RequestLastCallback()) // temporaty value - safe abort iAborted = CZipException::aborted; if (!iAborted) { CloseNewFile(); pCallback->CallbackEnd(); } else { // possible safe abort if (iAborted == CZipException::aborted) { bool bRet; try { bRet = CloseNewFile(); } #ifdef ZIP_ARCHIVE_MFC catch(CException* e) { e->Delete(); bRet = false; } #endif catch(...) { bRet = false; } if (bRet) iAborted = CZipException::abortedSafely; else { CloseNewFile(true); iAborted = CZipException::abortedAction; } } pCallback->CallbackEnd(); CZipException::Throw(iAborted); // throw to distinguish from other return codes } } else CloseNewFile(); if (bEff) { // remove the last file and add it without the compression if needed if (!info.m_pFile) f.Close(); buf.Release(); if (RemoveLast()) { info.m_iComprLevel = 0; info.m_iSmartLevel = zipsmInternal01; return AddNewFile(info); } } return true; } bool CZipArchive::RemoveLast(bool bRemoveAnyway) { if (GetCount() == 0) return false; ZIP_INDEX_TYPE uIndex = (ZIP_INDEX_TYPE)(GetCount() - 1); CZipFileHeader* pHeader = m_centralDir[uIndex]; if (!bRemoveAnyway && pHeader->CompressionEfficient()) return false; m_centralDir.RemoveLastFile(pHeader, uIndex); return true; } class CZipRootPathRestorer { CZipString m_szOldRootPath; CZipArchive* m_pZip; public: CZipRootPathRestorer() { m_pZip = NULL; } void SetNewRootPath( CZipArchive* pZip, LPCTSTR lpszNewRoot) { m_pZip = pZip; m_szOldRootPath = m_pZip->GetRootPath(); m_pZip->SetRootPath(lpszNewRoot); } ~CZipRootPathRestorer() { if (m_pZip) m_pZip->SetRootPath(m_szOldRootPath); } }; class CCalculateAddFilesEnumerator : public ZipArchiveLib::CDirEnumerator { CZipActionCallback* m_pCallback; public: ZIP_FILE_USIZE m_uTotalBytes; ZIP_FILE_USIZE m_uTotalFiles; CCalculateAddFilesEnumerator(LPCTSTR lpszDirectory, bool bRecursive, CZipActionCallback* pCallback) :ZipArchiveLib::CDirEnumerator(lpszDirectory, bRecursive) { m_pCallback = pCallback; m_uTotalFiles = m_uTotalBytes = 0; } protected: void OnEnumerationBegin() { if (m_pCallback) m_pCallback->Init(); } bool Process(LPCTSTR, const ZipArchiveLib::CFileInfo& info) { m_uTotalFiles++; m_uTotalBytes += info.m_uSize; if (m_pCallback && !m_pCallback->RequestCallback()) return false; else return true; } void OnEnumerationEnd(bool bResult) { if (m_pCallback) { if (bResult) bResult = m_pCallback->RequestLastCallback(); m_pCallback->CallbackEnd(); // can be false only, if the callback returns false if (!bResult) CZipException::Throw(CZipException::abortedSafely); } } }; class CAddFilesEnumerator : public ZipArchiveLib::CDirEnumerator { CZipArchive* m_pZip; CZipActionCallback* m_pMultiCallback; int m_iComprLevel; int m_iSmartLevel; unsigned long m_nBufSize; public: CAddFilesEnumerator(LPCTSTR lpszDirectory, bool bRecursive, CZipArchive* pZip, int iComprLevel, int iSmartLevel, unsigned long nBufSize, CZipActionCallback* pMultiCallback) :ZipArchiveLib::CDirEnumerator(lpszDirectory, bRecursive), m_pZip(pZip) { m_iComprLevel = iComprLevel; m_nBufSize = nBufSize; m_iSmartLevel = iSmartLevel; m_pMultiCallback = pMultiCallback; } protected: bool Process(LPCTSTR lpszPath, const ZipArchiveLib::CFileInfo&) { bool ret = m_pZip->AddNewFile(lpszPath, m_iComprLevel, m_pZip->GetRootPath().IsEmpty() != 0, m_iSmartLevel, m_nBufSize); if (ret && m_pMultiCallback) if (!m_pMultiCallback->MultiActionsNext()) CZipException::Throw(CZipException::abortedSafely); return ret; } }; bool CZipArchive::AddNewFiles(LPCTSTR lpszPath, CFileFilter& filter, bool bRecursive, int iComprLevel, bool bSkipInitialPath, int iSmartLevel, unsigned long nBufSize) { CZipRootPathRestorer restorer; if (bSkipInitialPath) restorer.SetNewRootPath(this, lpszPath); CZipActionCallback* pMultiCallback = GetCallback(CZipActionCallback::cbMultiAdd); if (pMultiCallback) { // if multi callback is set, calculate total data to process // call cbCalculateForMulti in the meantime CCalculateAddFilesEnumerator calculateEnumerator(lpszPath, bRecursive, GetCallback(CZipActionCallback::cbCalculateForMulti)); if (!calculateEnumerator.Start(filter)) return false; if (pMultiCallback->m_iType != CZipActionCallback::cbMultiAdd) // may happen, if it is the same as calculate pMultiCallback->m_iType = CZipActionCallback::cbMultiAdd; pMultiCallback->MultiActionsInit((ZIP_SIZE_TYPE)calculateEnumerator.m_uTotalFiles, (ZIP_SIZE_TYPE)calculateEnumerator.m_uTotalBytes, CZipActionCallback::cbAdd); } try { CAddFilesEnumerator addFilesEnumerator(lpszPath, bRecursive, this, iComprLevel, iSmartLevel, nBufSize, pMultiCallback); bool ret = addFilesEnumerator.Start(filter); if (pMultiCallback) pMultiCallback->MultiActionsEnd(); return ret; } catch(...) { if (pMultiCallback) pMultiCallback->MultiActionsEnd(); throw; } } CZipString CZipArchive::GetArchivePath() const { if (IsClosed(false)) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return _T(""); } return m_storage.m_pFile->GetFilePath(); } CZipString CZipArchive::GetGlobalComment() const { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return _T(""); } CZipString temp; m_centralDir.GetComment(temp); return temp; } bool CZipArchive::SetGlobalComment(LPCTSTR lpszComment) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return false; } if (m_storage.IsSegmented() == -1) { ZIPTRACE("%s(%i) : ZipArchive Library cannot modify the global comment of an existing segmented archive.\n"); return false; } m_centralDir.SetComment(lpszComment); if (m_bAutoFlush) Flush(); return true; } ZIP_VOLUME_TYPE CZipArchive::GetCurrentVolume() const { return (ZIP_VOLUME_TYPE)(m_storage.GetCurrentVolume() + 1); } bool CZipArchive::SetFileComment(ZIP_INDEX_TYPE uIndex, LPCTSTR lpszComment) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return false; } if (m_storage.IsSegmented() == -1) { ZIPTRACE("%s(%i) : ZipArchive Library cannot modify the file comment in an existing segmented archive.\n"); return false; } m_centralDir.SetFileComment(uIndex, lpszComment); if (m_bAutoFlush) Flush(); return true; } bool CZipArchive::SetPassword(LPCTSTR lpszPassword) { if (m_iFileOpened != nothing) { ZIPTRACE("%s(%i) : ZipArchive Library cannot change the password when a file is opened.\n"); return false; // it's important not to change the password when the file inside archive is opened } if (IsClosed()) { ZIPTRACE("%s(%i) : Setting the password for a closed archive has no effect.\n"); } if (lpszPassword) ZipCompatibility::ConvertStringToBuffer(lpszPassword, m_pszPassword, CP_ACP); else m_pszPassword.Release(); return true; } bool CZipArchive::SetEncryptionMethod(int iEncryptionMethod) { if (m_iFileOpened == compress) { ZIPTRACE("%s(%i) : ZipArchive Library cannot change the encryption method when there is a file opened for compression.\n"); return false; } if (iEncryptionMethod != CZipCryptograph::encNone && !CZipCryptograph::IsEncryptionSupported(iEncryptionMethod)) return false; m_iEncryptionMethod = iEncryptionMethod; return true; } struct CZipEncryptFileInfo { CZipEncryptFileInfo() { m_pHeader = NULL; m_uLocalSizeDiff = 0; m_uDescriptorSizeDiff = 0; m_uIndex = 0; } CZipEncryptFileInfo(CZipFileHeader* pHeader, DWORD uLocalSizeDiff, DWORD uDescriptorSizeDiff, ZIP_INDEX_TYPE uIndex, ZIP_SIZE_TYPE uDataOffset) :m_pHeader(pHeader), m_uLocalSizeDiff(uLocalSizeDiff), m_uDescriptorSizeDiff(uDescriptorSizeDiff), m_uIndex(uIndex), m_uUncompressedOffset(uDataOffset) { } CZipFileHeader* m_pHeader; DWORD m_uLocalSizeDiff; DWORD m_uDescriptorSizeDiff; ZIP_INDEX_TYPE m_uIndex; ZIP_SIZE_TYPE m_uUncompressedOffset; ZIP_SIZE_TYPE GetLastDataOffset() { return m_uUncompressedOffset + m_pHeader->m_uOffset; } }; bool CZipArchive::EncryptFilesInternal(CZipIndexesArray* pIndexes) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return false; } if (m_storage.IsSegmented()) { ZIPTRACE("%s(%i) : ZipArchive Library cannot encrypt existing files in a segmented archive.\n"); return false; } if (m_storage.m_bReadOnly) { ZIPTRACE("%s(%i) : ZipArchive Library cannot encrypt files in a read-only archive.\n"); return false; } if (m_iFileOpened) { ZIPTRACE("%s(%i) : ZipArchive Library cannot encrypt files if there is a file opened.\n"); return false; } if (GetCount() == 0) { ZIPTRACE("%s(%i) : There is nothing to encrypt: the archive is empty.\n"); return false; } if (!WillEncryptNextFile()) { ZIPTRACE("%s(%i) : An encryption method and a password must be set.\n"); return false; } bool bAll; ZIP_ARRAY_SIZE_TYPE i; if (pIndexes == NULL) { bAll = true; i = (ZIP_ARRAY_SIZE_TYPE)GetCount(); } else { bAll = false; pIndexes->Sort(true); i = pIndexes->GetSize(); } CZipActionCallback* pCallback = GetCallback(CZipActionCallback::cbEncryptPrepare); if (pCallback) { pCallback->Init(); pCallback->SetTotal((ZIP_SIZE_TYPE)i); } bool bAborted = false; CZipArray infos; ZIP_SIZE_TYPE uExtraData = 0; while (i > 0) { i--; ZIP_INDEX_TYPE idx; if (bAll) idx = (ZIP_INDEX_TYPE)i; else { idx = pIndexes->GetAt(i); if (!m_centralDir.IsValidIndex(idx)) { if (pCallback && !pCallback->RequestCallback()) { bAborted = true; break; } continue; } } CZipFileHeader* pHeader = GetFileInfo(idx); if (pHeader->IsEncrypted()) { if (pCallback && !pCallback->RequestCallback()) { bAborted = true; break; } continue; } ReadLocalHeaderInternal(idx); DWORD uOrigSize = pHeader->GetLocalSize(true); DWORD uOrigDescriptorSize = pHeader->GetDataDescriptorSize(&m_storage); pHeader->m_uEncryptionMethod = (BYTE)m_iEncryptionMethod; pHeader->UpdateFlag(m_storage.IsSegmented() != 0); // needed for GetLocalSize pHeader->PrepareFileName(); DWORD uLocalDiff = pHeader->GetLocalSize(false) - uOrigSize; DWORD uDescriptorDiff = pHeader->GetDataDescriptorSize(&m_storage) - uOrigDescriptorSize; uExtraData += uLocalDiff + uDescriptorDiff; infos.Add(CZipEncryptFileInfo(pHeader, uLocalDiff, uDescriptorDiff, idx, pHeader->m_uOffset + uOrigSize)); if (pCallback && !pCallback->RequestCallback()) { bAborted = true; break; } } if (pCallback) { if (!bAborted && !pCallback->RequestLastCallback()) bAborted = true; pCallback->CallbackEnd(); if (bAborted) CZipException::Throw(CZipException::abortedAction); } ZIP_ARRAY_SIZE_TYPE uSize = infos.GetSize(); if (!uSize) { ZIPTRACE("%s(%i) : There are no files to encrypt.\n"); return true; } m_centralDir.RemoveFromDisk(); CZipActionCallback* pMultiCallback = GetCallback(CZipActionCallback::cbMultiEncrypt); ZIP_ARRAY_SIZE_TYPE idxIdx; ZIP_INDEX_TYPE idx; if (pMultiCallback) { ZIP_SIZE_TYPE uTotalToMove = 0; ZIP_SIZE_TYPE uTotalToEncrypt = 0; // move files idxIdx = 0; // infos array has data from largest index to the smallest CZipEncryptFileInfo info = infos[0]; idx = GetCount(); ZIP_SIZE_TYPE uLastOffset = m_storage.GetLastDataOffset(); ZIP_INDEX_TYPE lastNormalIdx = ZIP_FILE_INDEX_UNSPECIFIED; while (idx > 0) { idx--; if (idx == info.m_uIndex) { if (lastNormalIdx != ZIP_FILE_INDEX_UNSPECIFIED) { // compensate changed offset uTotalToMove += uLastOffset - GetFileInfo(lastNormalIdx)->m_uOffset; lastNormalIdx = ZIP_FILE_INDEX_UNSPECIFIED; } uTotalToMove += info.m_pHeader->m_uComprSize; uTotalToEncrypt += info.m_pHeader->m_uComprSize; // no more files to encrypt if (++idxIdx == uSize) break; uLastOffset = info.m_pHeader->m_uOffset; info = infos[idxIdx]; } else lastNormalIdx = idx; } pMultiCallback->MultiActionsInit((ZIP_SIZE_TYPE)uSize, uTotalToMove + uTotalToEncrypt, CZipActionCallback::cbEncryptMoveData); } try { // move files idxIdx = 0; // infos array has data from largest index to the smallest CZipEncryptFileInfo info = infos[0]; idx = GetCount(); DWORD uExtraBefore = CZipCryptograph::GetEncryptedInfoSizeBeforeData(m_iEncryptionMethod); DWORD uExtraAfter = CZipCryptograph::GetEncryptedInfoSizeAfterData(m_iEncryptionMethod); // the total amount of extra data uExtraData += ((uExtraBefore + uExtraAfter) * infos.GetSize()); ZIP_SIZE_TYPE uLastOffset = m_storage.GetLastDataOffset(); ZIP_INDEX_TYPE lastNormalIdx = ZIP_FILE_INDEX_UNSPECIFIED; InitBuffer(); pCallback = GetCallback(CZipActionCallback::cbEncryptMoveData); while (idx > 0) { idx--; if (idx == info.m_uIndex) { if (lastNormalIdx != ZIP_FILE_INDEX_UNSPECIFIED) { // compensate changed offset ZIP_SIZE_TYPE uStartOffset = GetFileInfo(lastNormalIdx)->m_uOffset - uExtraData; if (pCallback) { pCallback->Init(); pCallback->SetTotal(uLastOffset - uStartOffset); } MovePackedFiles(uStartOffset, uLastOffset, uExtraData, pCallback, true); if (pCallback) pCallback->CallbackEnd(); lastNormalIdx = ZIP_FILE_INDEX_UNSPECIFIED; } uExtraData -= (uExtraAfter + info.m_uDescriptorSizeDiff); if (pCallback) { pCallback->Init(); pCallback->SetTotal(info.m_pHeader->m_uComprSize); } MovePackedFiles(info.m_uUncompressedOffset, info.m_uUncompressedOffset + info.m_pHeader->m_uComprSize, uExtraData, pCallback, true); if (pCallback) pCallback->CallbackEnd(); // no more files to encrypt if (++idxIdx == uSize) break; uExtraData -= (uExtraBefore + info.m_uLocalSizeDiff); // use original offsett uLastOffset = info.m_pHeader->m_uOffset; // now change the offset (not counting expanded local header - it changed the offset of data, not the offset of local header) info.m_pHeader->m_uOffset += uExtraData; info = infos[idxIdx]; } else { lastNormalIdx = idx; GetFileInfo(idx)->m_uOffset += uExtraData; } } bAborted = false; ZIP_SIZE_TYPE uToEncrypt = 0; i = uSize; // now encrypt the files (starting from the first one in the archive - this way the general direction of data copying is kept CreateCryptograph(m_iEncryptionMethod); if (pMultiCallback) pMultiCallback->SetReactType(CZipActionCallback::cbEncrypt); pCallback = GetCallback(CZipActionCallback::cbEncrypt); while (i > 0) { i--; CZipEncryptFileInfo inf = infos[i]; CZipFileHeader* pHeader = inf.m_pHeader; uToEncrypt = pHeader->m_uComprSize; if (pCallback) { pCallback->Init(pHeader->GetFileName()); pCallback->SetTotal(uToEncrypt); } m_storage.Seek(pHeader->m_uOffset); pHeader->WriteLocal(&m_storage); // take the number of bytes to encode, before m_uComprSize is modified m_pCryptograph->InitEncode(m_pszPassword, *pHeader, m_storage); m_storage.Flush(); if (uToEncrypt) { DWORD bufSize = m_pBuffer.GetSize(); char* buf = (char*)m_pBuffer; ZIP_SIZE_TYPE uToRead; UINT uSizeRead; bool bBreak = false; CZipAbstractFile* pFile = m_storage.m_pFile; ZIP_FILE_USIZE uPosition = pFile->GetPosition(); // the file pointer should be already positioned on the data do { uToRead = uToEncrypt > bufSize ? bufSize : uToEncrypt; uSizeRead = (UINT)pFile->Read(buf, (UINT)uToRead); if (!uSizeRead) break; uToEncrypt -= uSizeRead; if (uToEncrypt == 0) bBreak = true; m_pCryptograph->Encode(buf, uSizeRead); pFile->Seek(uPosition); pFile->Write(buf, uSizeRead); uPosition += uSizeRead; if (pCallback && !pCallback->RequestCallback(uSizeRead)) { bAborted = true; break; } if (pMultiCallback) pMultiCallback->MultiActionsNext(); } while (!bBreak); } // copying from a not segmented to a segmented archive so add the data descriptor // we want write the additional data only if everything is all right, but we don't want to flush the storage before // (and we want to flush the storage before throwing an exception, if something is wrong) if (uToEncrypt == 0) { m_pCryptograph->FinishEncode(*pHeader, m_storage); // it will be written only if needed pHeader->WriteDataDescriptor(&m_storage); m_storage.Flush(); } if (pCallback) { if (!bAborted && !pCallback->RequestLastCallback()) bAborted = true; if (bAborted) { pCallback->CallbackEnd(); CZipException::Throw(CZipException::abortedAction); } } if (uToEncrypt > 0) ThrowError(CZipException::badZipFile); if (pCallback) pCallback->CallbackEnd(); } m_storage.FlushFile(); ClearCryptograph(); } catch(...) { if (pMultiCallback) pMultiCallback->MultiActionsEnd(); throw; } if (pMultiCallback) pMultiCallback->MultiActionsEnd(); return true; } bool CZipArchive::SetCompressionMethod(WORD uCompressionMethod) { if (m_iFileOpened == compress) { ZIPTRACE("%s(%i) : ZipArchive Library cannot change the compression method when there is a file opened for compression.\n"); return false; } if (uCompressionMethod == CZipCompressor::methodStore) { ZIPTRACE("%s(%i) : Use the compression level CZipCompressor::levelStore when compressing files instead.\n"); return false; } if (!CZipCompressor::IsCompressionSupported(uCompressionMethod)) { ZIPTRACE("%s(%i) : The compression method is not supported.\n"); return false; } m_uCompressionMethod = uCompressionMethod; return true; } CZipString CZipArchive::GetPassword()const { CZipString temp; ZipCompatibility::ConvertBufferToString(temp, m_pszPassword, CP_ACP); return temp; } bool CZipArchive::TestFile(ZIP_INDEX_TYPE uIndex, DWORD uBufSize) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return false; } if (m_storage.IsSegmented() == 1) { ZIPTRACE("%s(%i) : ZipArchive Library cannot test a segmented archive in creation.\n"); return false; } if (!uBufSize) return false; CZipFileHeader* pHeader = m_centralDir[uIndex]; CZipActionCallback* pCallback = GetCallback(CZipActionCallback::cbTest); if (pCallback) { pCallback->Init(pHeader->GetFileName()); } if (pHeader->IsDirectory()) { if (pCallback) pCallback->SetTotal(0); // we do not test whether the password for the encrypted directory // is correct, since it seems to be senseless (anyway password // encrypted directories should be avoided - it adds 12 bytes) ZIP_SIZE_TYPE uSize = pHeader->m_uComprSize; if ((uSize != 0 || uSize != pHeader->m_uUncomprSize) // different treating compressed directories && !(pHeader->IsEncrypted() && uSize == 12 && !pHeader->m_uUncomprSize)) CZipException::Throw(CZipException::dirWithSize); if (pCallback) pCallback->CallbackEnd(); return true; } else { try { if (pCallback) pCallback->SetTotal(pHeader->m_uUncomprSize); if (!OpenFile(uIndex)) return false; CZipAutoBuffer buf(uBufSize); DWORD iRead; int iAborted = 0; for(;;) { iRead = ReadFile(buf, buf.GetSize()); if (!iRead) { if (pCallback && !pCallback->RequestLastCallback()) iAborted = CZipException::abortedSafely; break; } if (pCallback && !pCallback->RequestCallback(iRead)) { if (iRead == buf.GetSize() && ReadFile(buf, 1) != 0) // test one byte if there is something left iAborted = CZipException::abortedAction; else iAborted = CZipException::abortedSafely; // we did it! break; } } if (!iAborted) { if (CloseFile() == 1) { if (pCallback) pCallback->CallbackEnd(); return true; } else CZipException::Throw(CZipException::badZipFile); } else { if (iAborted == CZipException::abortedAction) CloseFile(NULL, true); else { bool bRet; try { bRet = CloseFile() == 1; } // if any exception was thrown, then we are not successful // catch all exceptions to thrown aborted exception only #ifdef ZIP_ARCHIVE_MFC catch(CException* e) { e->Delete(); bRet = false; } #endif catch(...) { bRet = false; } if (!bRet) { CloseFile(NULL, true); iAborted = CZipException::abortedAction; } } pCallback->CallbackEnd(); CZipException::Throw(iAborted); } return false; // to satisfy some compilers (some will complain)... } catch(...) { CloseFile(NULL, true); throw; } } } void CZipArchive::SetFileHeaderAttr(CZipFileHeader& header, DWORD uAttr)const { header.SetSystemCompatibility(m_iArchiveSystCompatib); header.SetSystemAttr(uAttr); } void CZipArchive::EnableFindFast(bool bEnable) { if (IsClosed()) { ZIPTRACE("%s(%i) : Set it after opening the archive.\n"); return; } m_centralDir.EnableFindFast(bEnable, m_bCaseSensitive); } bool CZipArchive::SetSystemCompatibility(int iSystemComp) { if (IsClosed()) { ZIPTRACE("%s(%i) : Set it after opening the archive.\n"); return false; } if (m_iFileOpened == compress) { ZIPTRACE("%s(%i) : Set it before opening a file inside archive.\n"); return false; } if (!ZipCompatibility::IsPlatformSupported(iSystemComp)) return false; // change the name coding page, if it was not changed before if (m_stringSettings.IsStandardNameCodePage(m_iArchiveSystCompatib)) m_stringSettings.SetDefaultNameCodePage(iSystemComp); m_iArchiveSystCompatib = iSystemComp; return true; } void CZipArchive::SetRootPath(LPCTSTR szPath) { if (IsClosed()) { ZIPTRACE("%s(%i) : Set it after opening the archive.\n"); return; } if (m_iFileOpened != nothing) { ZIPTRACE("%s(%i) : Set it before opening a file inside archive.\n"); return; } if (szPath) { m_szRootPath = szPath; CZipPathComponent::RemoveSeparators(m_szRootPath); } else m_szRootPath.Empty(); } CZipString CZipArchive::TrimRootPath(CZipPathComponent &zpc)const { if (m_szRootPath.IsEmpty()) return zpc.GetFileName(); CZipString szPath = zpc.GetFullPath(); return RemovePathBeginning(m_szRootPath, szPath, m_pZipCompare) ? szPath : zpc.GetFileName(); } bool CZipArchive::RemovePathBeginning(LPCTSTR lpszBeginning, CZipString& szPath, ZIPSTRINGCOMPARE pCompareFunction) { CZipString szBeginning(lpszBeginning); CZipPathComponent::RemoveSeparators(szBeginning); int iRootPathLength = szBeginning.GetLength(); if (iRootPathLength && szPath.GetLength() >= iRootPathLength && (szPath.Left(iRootPathLength).*pCompareFunction)(szBeginning) == 0) { // the beginning is the same if (szPath.GetLength() == iRootPathLength) { szPath.Empty(); return true; } // is the end of m_szPathRoot only a beginning of a directory name? // check for a separator // we know the length is larger, so we can write: if (CZipPathComponent::IsSeparator(szPath[iRootPathLength])) { szPath = szPath.Mid(iRootPathLength); CZipPathComponent::RemoveSeparatorsLeft(szPath); return true; } } return false; } void CZipArchive::SetTempPath(LPCTSTR lpszPath, bool bForce) { m_szTempPath = lpszPath; if (lpszPath && bForce) ZipPlatform::ForceDirectory(lpszPath); CZipPathComponent::RemoveSeparators(m_szTempPath); } CZipString CZipArchive::PredictFileNameInZip(LPCTSTR lpszFilePath, bool bFullPath, int iWhat)const { CZipString sz = lpszFilePath; if (sz.IsEmpty()) return _T(""); bool bAppend; switch (iWhat) { case prFile: bAppend = false; break; case prDir: bAppend = true; break; default: bAppend = CZipPathComponent::IsSeparator(sz[sz.GetLength() - 1]); } // remove for CZipPathComponent treating last name as a file even if dir CZipPathComponent::RemoveSeparators(sz); // it may be empty after removing separators, e.g.: "/" if (sz.IsEmpty()) return _T(""); CZipPathComponent zpc(sz); if (bFullPath) { if (m_bRemoveDriveLetter) sz = zpc.GetNoDrive(); } else sz = TrimRootPath(zpc); if (bAppend && !sz.IsEmpty()) CZipPathComponent::AppendSeparator(sz); return sz; } CZipString CZipArchive::PredictExtractedFileName(LPCTSTR lpszFileNameInZip, LPCTSTR lpszPath, bool bFullPath, LPCTSTR lpszNewName)const { CZipString szFile = lpszPath; CZipString sz = lpszNewName ? lpszNewName : lpszFileNameInZip; if (sz.IsEmpty()) return szFile; if (!szFile.IsEmpty()) CZipPathComponent::AppendSeparator(szFile); // remove for CZipPathComponent treating last name as a file even if dir CZipPathComponent::RemoveSeparators(sz); CZipPathComponent zpc(sz); szFile += bFullPath ? (m_bRemoveDriveLetter ? zpc.GetNoDrive() : sz) : TrimRootPath(zpc); return szFile; } ZIP_SIZE_TYPE CZipArchive::PredictMaximumFileSizeInArchive(LPCTSTR lpszFilePath, bool bFullPath) const { DWORD attr; if (!ZipPlatform::GetFileAttr(lpszFilePath, attr)) return 0; CZipFileHeader fh; SetFileHeaderAttr(fh, attr); if (!fh.IsDirectory()) if (!ZipPlatform::GetFileSize(lpszFilePath, fh.m_uUncomprSize)) return 0; fh.SetFileName(PredictFileNameInZip(lpszFilePath, bFullPath, fh.IsDirectory() ? prDir : prFile)); return PredictMaximumFileSizeInArchive(fh); } ZIP_SIZE_TYPE CZipArchive::PredictMaximumFileSizeInArchive(CZipFileHeader& fh) const { fh.m_stringSettings = m_stringSettings; fh.m_uEncryptionMethod = WillEncryptNextFile() ? (BYTE)m_iEncryptionMethod : (BYTE)CZipCryptograph::encNone; fh.m_uMethod = CZipCompressor::methodStore; fh.PrepareData(CZipCompressor::levelStore, m_storage.IsSegmented() != 0); DWORD uLocalSize = fh.GetLocalSize(true); return fh.GetSize() + uLocalSize + fh.GetDataSize(true, false) + fh.GetDataDescriptorSize(&m_storage); } void CZipArchive::SetAutoFlush(bool bAutoFlush) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive should be opened first.\n"); return; } if (m_storage.IsSegmented() != 0) { ZIPTRACE("%s(%i) : Cannot set auto-flush for a segmented archive.\n"); return; } m_bAutoFlush = bAutoFlush; } void CZipArchive::Flush() { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive should be opened first.\n"); return; } if (m_storage.IsSegmented() < 0) { ZIPTRACE("%s(%i) : Cannot flush an existing segmented archive.\n"); return; } WriteCentralDirectory(); m_storage.FlushFile(); if (m_storage.IsSegmented() > 0) // try to finalize a segmented archive without closing it m_storage.FinalizeSegm(); } void CZipArchive::GetCentralDirInfo(CZipCentralDir::CInfo& info)const { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive should be opened first.\n"); return; } m_centralDir.GetInfo(info); if (GetSegmMode() > 0) info.m_uLastVolume = m_storage.GetCurrentVolume(); } void CZipArchive::FindMatches(LPCTSTR lpszPattern, CZipIndexesArray &ar, bool bFullPath) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return; } // ar.RemoveAll(); don't do this ZIP_INDEX_TYPE uCount = (ZIP_INDEX_TYPE)GetCount(); CWildcard wc(lpszPattern, m_bCaseSensitive); for (ZIP_INDEX_TYPE i = 0; i < uCount; i++) { CZipString sz = m_centralDir[i]->GetFileName(); if (!bFullPath) { CZipPathComponent::RemoveSeparators(sz); CZipPathComponent zpc(sz); sz = zpc.GetFileName(); } if (wc.IsMatch(sz)) ar.Add(i); } } ZIP_INDEX_TYPE CZipArchive::WillBeDuplicated(LPCTSTR lpszFilePath, bool bFullPath, bool bFileNameOnly , int iWhat) { CZipString szFile; if (bFileNameOnly) { CZipPathComponent zpc(lpszFilePath); szFile = PredictFileNameInZip(zpc.GetFileName(), false, iWhat); } else szFile = PredictFileNameInZip(lpszFilePath, bFullPath, iWhat); return FindFile(szFile, ffDefault, bFileNameOnly); } bool CZipArchive::GetFromArchive( CZipArchive& zip, ZIP_INDEX_TYPE uIndex, LPCTSTR lpszNewFileName, ZIP_INDEX_TYPE uReplaceIndex, bool bKeepSystComp, CZipActionCallback* pCallback) { if (this == &zip) { ZIPTRACE("%s(%i) : ZipArchive Library cannot get files from the same archive.\n"); return false; } if (IsClosed() || zip.IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return false; } if (m_iFileOpened || zip.m_iFileOpened) { ZIPTRACE("%s(%i) : ZipArchive Library cannot get files from another archive if there is a file opened.\n"); return false; } if (m_storage.IsSegmented() == -1) { ZIPTRACE("%s(%i) : ZipArchive Library cannot add files to an existing segmented archive.\n"); return false; } ASSERT(m_pBuffer.GetSize() > 0); bool bSegm = m_storage.IsSegmented() == 1; if (!zip.m_centralDir.IsValidIndex(uIndex)) return false; zip.ReadLocalHeaderInternal(uIndex); CZipFileHeader originalHeader; // we need a copy - we are going to modify this if (!zip.GetFileInfo(originalHeader, uIndex)) return false; if (zip.m_storage.IsSegmented() != 0 && originalHeader.m_uLocalComprSize == 0) // we must compensate for adding the encrypted info size to m_uLocalComprSize at the beginning of CZipFileHeader::WriteLocal() originalHeader.m_uLocalComprSize = originalHeader.m_uComprSize - originalHeader.GetEncryptedInfoSize(); bool bConvertSystem = !bKeepSystComp && originalHeader.GetSystemCompatibility() != m_iArchiveSystCompatib; CZipString szFileName; if (lpszNewFileName != NULL) { szFileName = lpszNewFileName; originalHeader.SetFileName(lpszNewFileName); } else szFileName = originalHeader.GetFileName(); // empty if (bConvertSystem) { DWORD uAttr = originalHeader.GetSystemAttr(); originalHeader.SetSystemCompatibility(m_iArchiveSystCompatib); originalHeader.SetSystemAttr(uAttr); } if (!UpdateReplaceIndex(uReplaceIndex)) return false; bool bReplace = uReplaceIndex != ZIP_FILE_INDEX_UNSPECIFIED; if (bReplace && bSegm) return false; int iCallbackType = 0; if (pCallback) iCallbackType = pCallback->m_iType; if (!originalHeader.IsEncrypted() && WillEncryptNextFile()) { originalHeader.m_uEncryptionMethod = (BYTE)m_iEncryptionMethod; CreateCryptograph(m_iEncryptionMethod); } else ClearCryptograph(); // if the same callback is applied to cbMoveData, then the previous information about the type will be lost // we restore it later CZipFileHeader* pHeader = m_centralDir.AddNewFile(originalHeader, uReplaceIndex, originalHeader.GetCompressionLevel(), true); pHeader->m_stringSettings.m_uCommentCodePage = originalHeader.m_stringSettings.m_uCommentCodePage; // prepare this here: it will be used for GetLocalSize and WriteLocal pHeader->PrepareFileName(); ZIP_SIZE_TYPE uTotalToMove = pHeader->m_uComprSize; if (bReplace) { ZIP_SIZE_TYPE uDataSize; if (m_pCryptograph) // the file will be encrypted and have not yet increased pHeader->m_uComprSize (in m_pCryptograph->InitEncode) uDataSize = pHeader->GetDataSize(false, false); else uDataSize = uTotalToMove; MakeSpaceForReplace(uReplaceIndex, uDataSize + pHeader->GetLocalSize(false) + pHeader->GetDataDescriptorSize(&m_storage), szFileName); } if (pCallback) { // must be set before Init() pCallback->m_iType = iCallbackType; pCallback->Init(szFileName, zip.GetArchivePath()); pCallback->SetTotal(pHeader->m_uComprSize); } // must be written as not converted pHeader->WriteLocal(&m_storage); if (m_pCryptograph) m_pCryptograph->InitEncode(m_pszPassword, *pHeader, m_storage); char* buf = (char*)m_pBuffer; ZIP_SIZE_TYPE uToRead; DWORD uSizeRead; int iAborted = 0; bool bBreak = false; if (uTotalToMove) { DWORD bufSize = m_pBuffer.GetSize(); do { uToRead = uTotalToMove > bufSize ? bufSize : uTotalToMove; uSizeRead = (UINT)zip.m_storage.Read(buf, (UINT)uToRead, false); if (!uSizeRead) break; uTotalToMove -= uSizeRead; if (uTotalToMove == 0) bBreak = true; if (m_pCryptograph) m_pCryptograph->Encode(m_pBuffer, uSizeRead); m_storage.Write(buf, uSizeRead, false); if (pCallback && !pCallback->RequestCallback(uSizeRead)) { if (uTotalToMove != 0) { if (!bSegm && !bReplace) { m_centralDir.RemoveLastFile(); iAborted = CZipException::abortedSafely; } else iAborted = CZipException::abortedAction; } else iAborted = CZipException::abortedSafely; break; } } while (!bBreak); if (pCallback) { if (!iAborted && !pCallback->RequestLastCallback()) iAborted = CZipException::abortedSafely; if (iAborted) { // when no exception, CallbackEnd() called later pCallback->CallbackEnd(); CZipException::Throw(iAborted); // throw to distinguish from other return codes } } } m_centralDir.m_pOpenedFile = NULL; // copying from a not segmented to a segmented archive so add the data descriptor // we want write the additional data only if everything is all right, but we don't want to flush the storage before // (and we want to flush the storage before throwing an exception, if something is wrong) if (uTotalToMove == 0) { if (m_pCryptograph) m_pCryptograph->FinishEncode(*pHeader, m_storage); // it will be written only if needed pHeader->WriteDataDescriptor(&m_storage); } m_storage.Flush(); if (uTotalToMove > 0) ThrowError(CZipException::badZipFile); if (pCallback) pCallback->CallbackEnd(); ClearCryptograph(); return true; } bool CZipArchive::GetFromArchive( CZipArchive& zip, CZipIndexesArray &aIndexes, bool bKeepSystComp) { aIndexes.Sort(true); ZIP_INDEX_TYPE uFiles = (ZIP_INDEX_TYPE)aIndexes.GetSize(); InitBuffer(); try { for (ZIP_INDEX_TYPE i = 0; i < uFiles; i++) { ZIP_INDEX_TYPE uFileIndex = aIndexes[(ZIP_ARRAY_SIZE_TYPE)i]; if (!GetFromArchive(zip, uFileIndex, NULL, ZIP_FILE_INDEX_UNSPECIFIED, bKeepSystComp, GetCallback(CZipActionCallback::cbGet))) { ReleaseBuffer(); return false; } } } catch (...) { ReleaseBuffer(); throw; } ReleaseBuffer(); if (m_bAutoFlush) Flush(); return true; } bool CZipArchive::RenameFile(ZIP_INDEX_TYPE uIndex, LPCTSTR lpszNewName) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return false; } if (m_storage.IsSegmented()) { ZIPTRACE("%s(%i) : ZipArchive Library cannot rename files in a segmented archive.\n"); return false; } if (m_iFileOpened) { ZIPTRACE("%s(%i) : ZipArchive Library cannot rename a file if there is a file opened.\n"); return false; } CZipFileHeader* pHeader = (*this)[uIndex]; if (pHeader == NULL) return false; CZipString szNewName(lpszNewName); if (pHeader->IsDirectory()) CZipPathComponent::AppendSeparator(szNewName); else CZipPathComponent::RemoveSeparators(szNewName); CZipString szPreviousFileName = pHeader->GetFileName(); if (szPreviousFileName.Collate(szNewName) == 0) return true; // don't copy the comment code page, it already could have been set using it's own code page (set CD CP, change comment, change CD CP) pHeader->m_stringSettings.m_bStoreNameInExtraData = m_stringSettings.m_bStoreNameInExtraData; pHeader->m_stringSettings.m_uNameCodePage = m_stringSettings.m_uNameCodePage; pHeader->SetFileName(szNewName); m_centralDir.RemoveFromDisk(); // does m_storage.Flush(); // read local data - it may differ from central data char localInfo[4]; m_storage.Seek(pHeader->m_uOffset + 26); m_storage.m_pFile->Read(localInfo, 4); // read at once WORD uFileNameLen, uExtraFieldSize; CBytesWriter::ReadBytes(uFileNameLen, localInfo); // skip endian issues - the variable will not be used, but written back as it is memcpy(&uExtraFieldSize, localInfo + 2, 2); // filename buffer already cleared (GetFileName), the conversion will take place pHeader->PrepareFileName(); ASSERT(pHeader->m_pszFileNameBuffer.IsAllocated()); WORD uNewFileNameLen = (WORD)pHeader->m_pszFileNameBuffer.GetSize(); int iDelta = uNewFileNameLen - uFileNameLen; int iOffset = 0; CZipAutoBuffer buf, *pBuf; if (iDelta != 0) { // we need to make more or less space InitBuffer(); ZIP_SIZE_TYPE uStartOffset = pHeader->m_uOffset + 30 + uFileNameLen; ZIP_SIZE_TYPE uFileLen = (ZIP_SIZE_TYPE)m_storage.m_pFile->GetLength(); ZIP_SIZE_TYPE uEndOffset = uFileLen - m_storage.m_uBytesBeforeZip; CZipActionCallback* pCallback = GetCallback(CZipActionCallback::cbRename); if (pCallback) { // do it right and sent the notification pCallback->Init(szPreviousFileName, GetArchivePath()); pCallback->SetTotal(uEndOffset - uStartOffset); } bool bForward = iDelta > 0; if (bForward) m_storage.m_pFile->SetLength((ZIP_FILE_USIZE)(uFileLen + iDelta)); // ensure the seek is correct MovePackedFiles(uStartOffset, uEndOffset, abs(iDelta), pCallback, bForward); if (pCallback) pCallback->CallbackEnd(); if (!bForward) m_storage.m_pFile->SetLength((ZIP_FILE_USIZE)(uFileLen + iDelta)); // delta < 0; shrink the file ReleaseBuffer(); ZIP_INDEX_TYPE uSize = (ZIP_INDEX_TYPE)GetCount(); for (ZIP_INDEX_TYPE i = (ZIP_INDEX_TYPE)(uIndex + 1); i < uSize; i++) m_centralDir[i]->m_uOffset += iDelta; buf.Allocate(4 + uNewFileNameLen); CBytesWriter::WriteBytes(buf, uNewFileNameLen); // the variable was not used - we write it back as it was (no endian issues) // to write everything at once memcpy((char*)buf + 2, &uExtraFieldSize, 2); memcpy((char*)buf + 4, pHeader->m_pszFileNameBuffer, uNewFileNameLen); pBuf = &buf; iOffset = -4; } else pBuf = &pHeader->m_pszFileNameBuffer; m_storage.Seek(pHeader->m_uOffset + 30 + iOffset); m_storage.m_pFile->Write(*pBuf, pBuf->GetSize()); m_centralDir.RebuildFindFastArray(); if (m_bAutoFlush) Flush(); return true; } bool CZipArchive::UpdateReplaceIndex(ZIP_INDEX_TYPE& uReplaceIndex) { if (uReplaceIndex == ZIP_FILE_INDEX_UNSPECIFIED) return true; if (GetSegmMode() != 0) { ZIPTRACE("%s(%i) : ZipArchive Library cannot replace files in a segmented archive.\n"); return false; } if (!m_centralDir.IsValidIndex(uReplaceIndex)) { ZIPTRACE("%s(%i) : Not valid replace index.\n"); return false; } if (uReplaceIndex == GetCount() - 1) // replacing last file in the archive { RemoveLast(true); uReplaceIndex = ZIP_FILE_INDEX_UNSPECIFIED; } return true; } void CZipArchive::MakeSpaceForReplace(ZIP_INDEX_TYPE uReplaceIndex, ZIP_SIZE_TYPE uTotal, LPCTSTR lpszFileName) { ASSERT(uReplaceIndex < GetCount() - 1); // we can't use the offset from the central directory here, because the header is already replaced ZIP_SIZE_TYPE uReplaceStart = (ZIP_SIZE_TYPE)m_storage.m_pFile->GetPosition() - m_storage.m_uBytesBeforeZip; // find the next offset (files in the central directory may not necessarily be ordered by offset) ZIP_SIZE_TYPE uReplaceEnd = ZIP_SIZE_TYPE(-1); ZIP_INDEX_TYPE i; for (i = 0; i < (ZIP_INDEX_TYPE)m_centralDir.GetCount(); i++) if (i != uReplaceIndex) { ZIP_SIZE_TYPE uOffset = m_centralDir[i]->m_uOffset; if (uOffset > uReplaceStart && uOffset < uReplaceEnd) uReplaceEnd = uOffset; } ZIP_SIZE_TYPE uReplaceTotal = uReplaceEnd - uReplaceStart; if (uTotal == uReplaceTotal) return; bool bForward = uTotal > uReplaceTotal; ZIP_SIZE_TYPE uDelta; if (bForward) uDelta = uTotal - uReplaceTotal; else uDelta = uReplaceTotal - uTotal; // InitBuffer(); don't - the calling functions will CZipActionCallback* pCallback = GetCallback(CZipActionCallback::cbMoveData); ZIP_SIZE_TYPE uFileLen = (ZIP_SIZE_TYPE)m_storage.m_pFile->GetLength(); ZIP_SIZE_TYPE uUpperLimit = uFileLen - m_storage.m_uBytesBeforeZip; // will be added in m_storage.Seek if (pCallback) { pCallback->Init(lpszFileName, GetArchivePath()); pCallback->SetTotal(uUpperLimit - uReplaceEnd); } if (bForward) m_storage.m_pFile->SetLength((ZIP_FILE_USIZE)(uFileLen + uDelta)); // ensure the seek is correct MovePackedFiles(uReplaceEnd, uUpperLimit, uDelta, pCallback, bForward); if (!bForward) m_storage.m_pFile->SetLength((ZIP_FILE_USIZE)(uFileLen - uDelta)); m_storage.Seek(uReplaceStart); ZIP_INDEX_TYPE uSize = GetCount(); for (i = (ZIP_INDEX_TYPE)(uReplaceIndex + 1); i < uSize; i++) { ZIP_SIZE_TYPE uOffset = m_centralDir[i]->m_uOffset; m_centralDir[i]->m_uOffset = bForward ? uOffset + uDelta : uOffset - uDelta; } if (pCallback) pCallback->CallbackEnd(); } void CZipArchive::MovePackedFiles(ZIP_SIZE_TYPE uStartOffset, ZIP_SIZE_TYPE uEndOffset, ZIP_SIZE_TYPE uMoveBy, CZipActionCallback* pCallback, bool bForward, bool bLastCall) { ASSERT(m_pBuffer.GetSize() > 0); ZIP_SIZE_TYPE uTotalToMove = uEndOffset - uStartOffset; ZIP_SIZE_TYPE uPack = uTotalToMove > m_pBuffer.GetSize() ? m_pBuffer.GetSize() : uTotalToMove; char* buf = (char*)m_pBuffer; UINT uSizeRead; bool bBreak = false; bool bAborted = false; do { if (uEndOffset - uStartOffset < uPack) { uPack = uEndOffset - uStartOffset; if (!uPack) break; bBreak = true; } ZIP_SIZE_TYPE uPosition = bForward ? uEndOffset - uPack : uStartOffset; m_storage.Seek(uPosition); uSizeRead = m_storage.m_pFile->Read(buf, (UINT)uPack); if (!uSizeRead) break; if (bForward) uPosition += uMoveBy; else uPosition -= uMoveBy; m_storage.Seek(uPosition); m_storage.m_pFile->Write(buf, uSizeRead); if (bForward) uEndOffset -= uSizeRead; else uStartOffset += uSizeRead; if (pCallback && !pCallback->RequestCallback(uSizeRead)) { bAborted = true; break; } } while (!bBreak); if (pCallback) { if (!bAborted && bLastCall && !pCallback->RequestLastCallback()) bAborted = true; // do not call here - it will be called in the calling method //pCallback->CallbackEnd(); if (bAborted) { // call here before throwing the the aborted exception pCallback->CallbackEnd(); ThrowError(CZipException::abortedAction); } } if (uEndOffset != uStartOffset) ThrowError(CZipException::internalError); } bool CZipArchive::RemoveCentralDirectoryFromArchive() { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return false; } if (m_storage.IsSegmented()) { ZIPTRACE("%s(%i) : ZipArchive Library cannot remove the central directory from a segmented archive.\n"); return false; } m_centralDir.RemoveFromDisk(); return true; } bool CZipArchive::OverwriteLocalHeader(ZIP_INDEX_TYPE uIndex) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return false; } if (m_storage.IsSegmented()) { ZIPTRACE("%s(%i) : ZipArchive Library cannot overwrite local header in a segmented archive.\n"); return false; } CZipFileHeader* pHeader = GetFileInfo(uIndex); m_storage.Seek(pHeader->m_uOffset); pHeader->WriteLocal(&m_storage); return true; } bool CZipArchive::ReadLocalHeader(ZIP_INDEX_TYPE uIndex) { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return false; } if (m_iFileOpened) { ZIPTRACE("%s(%i) : A file is already opened.\n"); return false; } ReadLocalHeaderInternal(uIndex); return true; } void CZipArchive::SetSegmCallback(CZipSegmCallback* pCallback, int callbackType) { if ((callbackType & scSpan) != 0) m_storage.m_pSpanChangeVolumeFunc = pCallback; if ((callbackType & scSplit) != 0) m_storage.m_pSplitChangeVolumeFunc = pCallback; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/Hmac.cpp0000644000175000017500000000131011300022650020400 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "_features.h" tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCallbackProvider.h0000644000175000017500000000563211300022650023102 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipCallbackProvider.h * Includes the ZipArchiveLib::CZipCallbackProvider class. * */ #if !defined(ZIPARCHIVE_ZIPCALLBACKPROVIDER_DOT_H) #define ZIPARCHIVE_ZIPCALLBACKPROVIDER_DOT_H #if _MSC_VER > 1000 #pragma once #if defined ZIP_HAS_DLL #pragma warning (push) #pragma warning( disable : 4275 ) // non dll-interface used as base for dll-interface class #endif #endif #include "ZipCallback.h" #include "ZipExport.h" #include "ZipCollections.h" namespace ZipArchiveLib { /** The storage for callback objects. A structure for the internal use only. \see CZipArchive::SetCallback CZipArchive::GetCallback */ class ZIP_API CZipCallbackProvider : public CZipMap { public: void Set(CZipActionCallback* pCallback, int iWhich) { CZipActionCallback::CallbackType cbs[] = {CZipActionCallback::cbAdd, CZipActionCallback::cbAddTmp, CZipActionCallback::cbAddStore, CZipActionCallback::cbExtract, CZipActionCallback::cbDeleteCnt, CZipActionCallback::cbDelete, CZipActionCallback::cbTest, CZipActionCallback::cbSave, CZipActionCallback::cbGet, CZipActionCallback::cbRename, CZipActionCallback::cbMoveData, CZipActionCallback::cbCalculateForMulti, CZipActionCallback::cbMultiAdd, CZipActionCallback::cbEncryptPrepare, CZipActionCallback::cbEncryptMoveData, CZipActionCallback::cbEncrypt, CZipActionCallback::cbMultiEncrypt}; int iCount = sizeof(cbs)/sizeof(CZipActionCallback::CallbackType); for (int i = 0; i < iCount; i++) { CZipActionCallback::CallbackType iCallback = cbs[i]; if (iWhich & iCallback) SetInternal(pCallback, iCallback); } } CZipActionCallback* Get(CZipActionCallback::CallbackType iType) { CZipActionCallback* pCallback = NULL; if (Lookup(iType, pCallback)) { pCallback->m_iType = iType; return pCallback; } else return NULL; } protected: void SetInternal(CZipActionCallback* pCallback, CZipActionCallback::CallbackType iType) { if (pCallback) { SetAt(iType, pCallback); } else RemoveKey(iType); } }; } // namespace #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning (pop) #endif #endif // !defined(ZIPARCHIVE_ZIPCALLBACKPROVIDER_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipFile.h0000644000175000017500000000207011300022650020543 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipFile.h * Includes the CZipFile class. * */ #if !defined(ZIPARCHIVE_ZIPFILE_DOT_H) #define ZIPARCHIVE_ZIPFILE_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "_features.h" #if defined ZIP_ARCHIVE_STL || defined ZIP_FILE_USES_STL #include "ZipFile_stl.h" #else #include "ZipFile_mfc.h" #endif #endif // !defined(ZIPARCHIVE_ZIPFILE_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/DeflateCompressor.h0000644000175000017500000000701411300022650022625 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file DeflateCompressor.h * Includes the ZipArchiveLib::CDeflateCompressor class. * */ #if !defined(ZIPARCHIVE_DEFLATECOMPRESSOR_DOT_H) #define ZIPARCHIVE_DEFLATECOMPRESSOR_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "ZipExport.h" #include "BaseLibCompressor.h" #include "ZipException.h" #include "zlib/zlib.h" namespace ZipArchiveLib { /** Compresses and decompresses data using the Zlib library. */ class ZIP_API CDeflateCompressor : public CBaseLibCompressor { public: /** Represents options of the CDeflateCompressor. \see 0610231446|options \see CZipArchive::SetCompressionOptions */ struct ZIP_API COptions : CBaseLibCompressor::COptions { COptions() { m_bCheckLastBlock = true; } int GetType() const { return typeDeflate; } CZipCompressor::COptions* Clone() const { return new COptions(*this); } /** Enables or disables checking, if the compressed data ends with an end-of-stream block. This should be enabled to protect against malformed data. \c true, if the checking of the last block should be enabled; \c false otherwise. */ bool m_bCheckLastBlock; }; /** Initializes a new instance of the CDeflateCompressor class. \param pStorage The current storage object. */ CDeflateCompressor(CZipStorage* pStorage); bool CanProcess(WORD uMethod) {return uMethod == methodStore || uMethod == methodDeflate;} void InitCompression(int iLevel, CZipFileHeader* pFile, CZipCryptograph* pCryptograph); void InitDecompression(CZipFileHeader* pFile, CZipCryptograph* pCryptograph); DWORD Decompress(void *pBuffer, DWORD uSize); void Compress(const void *pBuffer, DWORD uSize); void FinishCompression(bool bAfterException); void FinishDecompression(bool bAfterException); const CZipCompressor::COptions* GetOptions() const { return &m_options; } ~CDeflateCompressor() { } protected: void UpdateOptions(const CZipCompressor::COptions* pOptions) { m_options = *(COptions*)pOptions; } int ConvertInternalError(int iErr) const { switch (iErr) { case Z_NEED_DICT: return CZipException::needDict; case Z_STREAM_END: return CZipException::streamEnd; case Z_ERRNO: return CZipException::errNo; case Z_STREAM_ERROR: return CZipException::streamError; case Z_DATA_ERROR: return CZipException::dataError; case Z_MEM_ERROR: return CZipException::memError; case Z_BUF_ERROR: return CZipException::bufError; case Z_VERSION_ERROR: return CZipException::versionError; default: return CZipException::genericError; } } bool IsCodeErrorOK(int iErr) const { return iErr == Z_OK || iErr == Z_NEED_DICT; } private: COptions m_options; zarch_z_stream m_stream; }; } // namespace #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipAutoBuffer.cpp0000644000175000017500000000403211300022650022261 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipAutoBuffer.h" #include CZipAutoBuffer::CZipAutoBuffer() { m_iSize = 0; m_pBuffer = NULL; } CZipAutoBuffer::CZipAutoBuffer(DWORD iSize, bool bZeroMemory) { m_iSize = 0; m_pBuffer = NULL; Allocate(iSize, bZeroMemory); } CZipAutoBuffer::~CZipAutoBuffer() { Release(); } void CZipAutoBuffer::Release() { if (m_pBuffer) { delete [] m_pBuffer; m_iSize = 0; m_pBuffer = NULL; } } char* CZipAutoBuffer::Allocate(DWORD iSize, bool bZeroMemory) { if (iSize != m_iSize) Release(); else { if (bZeroMemory) memset(m_pBuffer, 0, iSize); // zerowanie bufora return m_pBuffer; } if (iSize > 0) { m_pBuffer = new char [iSize]; if (bZeroMemory) memset(m_pBuffer, 0, iSize); // zerowanie bufora m_iSize = iSize; } else m_pBuffer = NULL; return m_pBuffer; } CZipAutoBuffer::CZipAutoBuffer(const CZipAutoBuffer& buffer) { m_pBuffer = NULL; m_iSize = 0; if (buffer.m_pBuffer) { Allocate(buffer.m_iSize); memcpy(m_pBuffer, buffer.m_pBuffer, buffer.m_iSize); } } CZipAutoBuffer& CZipAutoBuffer::operator=(const CZipAutoBuffer& buffer) { if (this == &buffer) return *this; Release(); if (buffer.m_pBuffer) { Allocate(buffer.m_iSize); memcpy(m_pBuffer, buffer.m_pBuffer, buffer.m_iSize); } return *this; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipPlatform_lnx.cpp0000644000175000017500000001406011300022650022666 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "_platform.h" #ifdef ZIP_ARCHIVE_LNX #if defined __APPLE__ || defined __CYGWIN__ #define FILE_FUNCTIONS_64B_BY_DEFAULT #else #undef FILE_FUNCTIONS_64B_BY_DEFAULT #endif #include "stdafx.h" #include "ZipPlatform.h" #include "ZipFileHeader.h" #include "ZipException.h" #include "ZipAutoBuffer.h" #include #include "ZipPathComponent.h" #include "ZipCompatibility.h" #include #if defined (__FreeBSD__) || defined (__APPLE__) #include #include #else #include #endif #include #include #include #include const TCHAR CZipPathComponent::m_cSeparator = _T('/'); #ifndef _UTIMBUF_DEFINED #define _utimbuf utimbuf #endif #define ZIP_DEFAULT_DIR_ATTRIBUTES (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// ULONGLONG ZipPlatform::GetDeviceFreeSpace(LPCTSTR lpszPath) { struct statfs sStats; #if defined (__SVR4) && defined (__sun) if (statvfs(lpszPath, &sStats) == -1) // Solaris #else if (statfs(lpszPath, &sStats) == -1) #endif return 0; return sStats.f_bsize * sStats.f_bavail; } CZipString ZipPlatform::GetTmpFileName(LPCTSTR lpszPath, ZIP_SIZE_TYPE uSizeNeeded) { TCHAR empty[] = _T(""), prefix [] = _T("zar"); CZipString tempPath = lpszPath; if (tempPath.IsEmpty()) tempPath = "/tmp"; if (ZipPlatform::GetDeviceFreeSpace(tempPath) < uSizeNeeded) return empty; CZipPathComponent::AppendSeparator(tempPath); tempPath += prefix; tempPath += _T("XXXXXX"); int handle = mkstemp(tempPath.GetBuffer(tempPath.GetLength())); tempPath.ReleaseBuffer(); if (handle != -1) { close(handle); // we just create the file and open it later return tempPath; } else return empty; } bool ZipPlatform::GetCurrentDirectory(CZipString& sz) { char* pBuf = getcwd(NULL, 0); if (!pBuf) return false; sz = pBuf; free(pBuf); return true; } bool ZipPlatform::SetFileAttr(LPCTSTR lpFileName, DWORD uAttr) { return chmod(lpFileName, uAttr) == 0; } bool ZipPlatform::GetFileAttr(LPCTSTR lpFileName, DWORD& uAttr) { struct stat sStats; if (stat(lpFileName, &sStats) == -1) return false; uAttr = (sStats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_IFMT)); return true; } bool ZipPlatform::SetExeAttr(LPCTSTR lpFileName) { DWORD uAttr; if (!GetFileAttr(lpFileName, uAttr)) return false; uAttr |= S_IXUSR; return ZipPlatform::SetFileAttr(lpFileName, uAttr); } bool ZipPlatform::GetFileModTime(LPCTSTR lpFileName, time_t & ttime) { struct stat st; if (stat(lpFileName, &st) != 0) return false; ttime = st.st_mtime; if (ttime == (time_t)-1) { ttime = time(NULL); return false; } else return true; } bool ZipPlatform::SetFileModTime(LPCTSTR lpFileName, time_t ttime) { struct utimbuf ub; ub.actime = time(NULL); ub.modtime = ttime == -1 ? time(NULL) : ttime; // if wrong file time, set it to the current return utime(lpFileName, &ub) == 0; } bool ZipPlatform::ChangeDirectory(LPCTSTR lpDirectory) { return chdir(lpDirectory) == 0; } int ZipPlatform::FileExists(LPCTSTR lpszName) { struct stat st; if (stat(lpszName, &st) != 0) return 0; else { if (S_ISDIR(st.st_mode)) return -1; else return 1; } } ZIPINLINE bool ZipPlatform::IsDriveRemovable(LPCTSTR lpszFilePath) { // not implemmented return true; } ZIPINLINE bool ZipPlatform::SetVolLabel(LPCTSTR lpszPath, LPCTSTR lpszLabel) { // not implemmented return true; } ZIPINLINE void ZipPlatform::AnsiOem(CZipAutoBuffer& buffer, bool bAnsiToOem) { // not implemmented } ZIPINLINE bool ZipPlatform::RemoveFile(LPCTSTR lpszFileName, bool bThrow) { if (unlink(lpszFileName) != 0) if (bThrow) CZipException::Throw(CZipException::notRemoved, lpszFileName); else return false; return true; } ZIPINLINE bool ZipPlatform::RenameFile( LPCTSTR lpszOldName, LPCTSTR lpszNewName , bool bThrow) { if (rename(lpszOldName, lpszNewName) != 0) if (bThrow) CZipException::Throw(CZipException::notRenamed, lpszOldName); else return false; return true; } ZIPINLINE bool ZipPlatform::IsDirectory(DWORD uAttr) { return S_ISDIR(uAttr) != 0; } ZIPINLINE bool ZipPlatform::CreateDirectory(LPCTSTR lpDirectory) { return mkdir(lpDirectory, ZIP_DEFAULT_DIR_ATTRIBUTES) == 0; } ZIPINLINE DWORD ZipPlatform::GetDefaultAttributes() { return S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; } ZIPINLINE DWORD ZipPlatform::GetDefaultDirAttributes() { return S_IFDIR | ZIP_DEFAULT_DIR_ATTRIBUTES; } ZIPINLINE int ZipPlatform::GetSystemID() { return ZipCompatibility::zcUnix; } ZIPINLINE bool ZipPlatform::GetSystemCaseSensitivity() { return true; } bool ZipPlatform::TruncateFile(int iDes, ULONGLONG uSize) { return ftruncate(iDes, uSize) == 0; } int ZipPlatform::OpenFile(LPCTSTR lpszFileName, UINT iMode, int iShareMode) { return open(lpszFileName, iMode, S_IRUSR | S_IWUSR | S_IRGRP |S_IROTH ); } bool ZipPlatform::FlushFile(int iDes) { return fsync(iDes) == 0; } intptr_t ZipPlatform::GetFileSystemHandle(int iDes) { return iDes; } #endif // ZIP_ARCHIVE_LNX tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipException.h0000644000175000017500000001574411300022650021636 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipException.h * Includes the CZipException class. * */ #if !defined(ZIPARCHIVE_ZIPEXCEPTION_DOT_H) #define ZIPARCHIVE_ZIPEXCEPTION_DOT_H #if _MSC_VER > 1000 #pragma once #pragma warning( push ) #pragma warning (disable:4702) // disable "Unreachable code" warning in Throw function in the Release mode #if defined ZIP_HAS_DLL #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class #pragma warning( disable : 4275 ) // non dll-interface used as base for dll-interface class #endif #endif #include "ZipString.h" #include "ZipBaseException.h" #include "ZipExport.h" /** Represents exceptions specific to the ZipArchive Library. \see 0610222049 */ class ZIP_API CZipException : public CZipBaseException { public: /** Throws an exception. Whether it throws an object or a pointer to it, depends on the current version (STL or MFC correspondingly). \param iCause The error cause. Takes one of the #ZipErrors values. \param lpszZipName The name of the file where the error occurred (if applicable). May be \c NULL. \see 0610222049 */ static void Throw(int iCause = CZipException::genericError, LPCTSTR lpszZipName = NULL) { #ifdef ZIP_ARCHIVE_MFC throw new CZipException(iCause, lpszZipName); #else CZipException e(iCause, lpszZipName); throw e; #endif } /** Initializes a new instance of the CZipException class. \param iCause The error cause. Takes one of the #ZipErrors values. \param lpszZipName The name of the file where the error occurred (if applicable). May be \c NULL. */ CZipException(int iCause = genericError, LPCTSTR lpszZipName = NULL); CZipException(CZipException& e) { m_szFileName = e.m_szFileName; m_iCause = e.m_iCause; } #ifdef ZIP_ENABLE_ERROR_DESCRIPTION /** Gets the error description. \return The error description. */ CZipString GetErrorDescription(); /** Gets the error description. This method is provided for compatibility with the MFC version (\c CException::GetErrorMessage). \param lpszError The buffer to receive the error message. \param nMaxError The maximum number of characters \a lpszError can hold, including the ending \c NULL character. \return \c TRUE if the error string was successfully copied to \a lpszError; \c FALSE otherwise. \note The method will not copy more than \c nMaxError - 1 characters to the buffer, and it always appends a \c NULL character. If \a lpszError is too small, the error message will be truncated. */ ZBOOL GetErrorMessage(LPTSTR lpszError, UINT nMaxError, UINT* = NULL); #endif //ZIP_ENABLE_ERROR_DESCRIPTION /** The name of the zip file where the error occurred. */ CZipString m_szFileName; /** The codes of errors thrown by the ZipArchive Library. */ enum ZipErrors { noError, ///< No error. // 1 - 42 reserved for errno (from STL) values - used only in non-MFC versions // 43 - 99 reserved genericError = 100, ///< An unknown error. badZipFile, ///< Damaged or not a zip file. badCrc, ///< Crc is mismatched. noCallback, ///< There is no spanned archive callback object set. aborted, ///< The volume change callback in a segmented archive method returned \c false. abortedAction, ///< The action callback method returned \c false. abortedSafely, ///< The action callback method returned \c false, but the data is not corrupted. nonRemovable, ///< The device selected for the spanned archive is not removable. tooManyVolumes, ///< The limit of the maximum volumes reached. tooManyFiles, ///< The limit of the maximum files in an archive reached. tooLongData, ///< The filename, the comment or the local or central extra field of the file added to the archive is too long. tooBigSize, ///< The file size is too large to be supported. badPassword, ///< An incorrect password set for the file being decrypted. dirWithSize, ///< The directory with a non-zero size found while testing. internalError, ///< An internal error. notRemoved, ///< Error while removing a file (under Windows call \c GetLastError() to find out more). notRenamed, ///< Error while renaming a file (under Windows call \c GetLastError() to find out more). platfNotSupp, ///< Cannot create a file for the specified platform. cdirNotFound, ///< The central directory was not found in the archive (or you were trying to open not the last disk of a segmented archive). noZip64, ///< The Zip64 format has not been enabled for the library, but is required to use the archive. noAES, ///< WinZip AES encryption has not been enabled for the library, but is required to decompress the archive. #ifdef ZIP_ARCHIVE_STL outOfBounds, ///< The collection is empty and the bounds do not exist. #endif #ifdef ZIP_ARCHIVE_USE_LOCKING mutexError, ///< Locking or unlocking resources access was unsuccessful. #endif streamEnd = 500, ///< Zlib library error. needDict, ///< Zlib library error. errNo, ///< Zlib library error. streamError, ///< Zlib library error. dataError, ///< Zlib library error. memError, ///< Zlib library or \c CZipMemFile error. bufError, ///< Zlib library error. versionError, ///< Zlib library error. }; /** The error code - takes one of the CZipException::ZipErrors values. */ int m_iCause; virtual ~CZipException() throw(); protected: #ifdef ZIP_ENABLE_ERROR_DESCRIPTION /** Gets the error description. \param iCause The error cause. Takes one of the #ZipErrors values. \param bNoLoop If \c true, does not search for en error description, it the error code is #genericError. \return The error description. */ CZipString GetInternalErrorDescription(int iCause, bool bNoLoop = false); /** Gets the error description based on system variables. \return The error description. */ CZipString GetSystemErrorDescription(); #endif //ZIP_ENABLE_ERROR_DESCRIPTION #if defined _MFC_VER && defined ZIP_ARCHIVE_MFC DECLARE_DYNAMIC(CZipException) #endif }; #if _MSC_VER > 1000 #pragma warning( pop ) #endif #endif // !defined(ZIPARCHIVE_ZIPEXCEPTION_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/Hmac.h0000644000175000017500000000125611300022650020056 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipStorage.cpp0000644000175000017500000004030111300022650021622 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipStorage.h" #include "ZipArchive.h" #include "ZipPlatform.h" char CZipStorage::m_gszExtHeaderSignat[] = {0x50, 0x4b, 0x07, 0x08}; const ZIP_FILE_USIZE CZipStorage::SignatureNotFound = ZIP_FILE_USIZE(-1); CZipStorage::CZipStorage() { Initialize(); } void CZipStorage::Initialize() { m_pSplitChangeVolumeFunc = m_pSpanChangeVolumeFunc = m_pChangeVolumeFunc = NULL; m_iWriteBufferSize = 65536; m_pFile = NULL; m_szSplitExtension = _T("zip"); m_iLocateBufferSize = 32768; m_uBytesBeforeZip = 0; m_uCurrentVolume = ZIP_VOLUME_NUMBER_UNSPECIFIED; m_szArchiveName.Empty(); } CZipStorage::~CZipStorage() { } DWORD CZipStorage::Read(void *pBuf, DWORD iSize, bool bAtOnce) { if (iSize == 0) return 0; DWORD iRead; for(;;) { iRead = m_pFile->Read(pBuf, iSize); if (!iRead) { if (IsSegmented()) ChangeVolume(); else ThrowError(CZipException::badZipFile); } else break; } if (iRead == iSize) return iRead; else if (bAtOnce || !IsSegmented()) ThrowError(CZipException::badZipFile); while (iRead < iSize) { ChangeVolume(); UINT iNewRead = m_pFile->Read((char*)pBuf + iRead, iSize - iRead); if (!iNewRead && iRead < iSize) ThrowError(CZipException::badZipFile); iRead += iNewRead; } return iRead; } void CZipStorage::Open(LPCTSTR lpszPathName, int iMode, ZIP_SIZE_TYPE uVolumeSize) { m_uCurrentVolume = ZIP_VOLUME_NUMBER_UNSPECIFIED; m_pWriteBuffer.Allocate(m_iWriteBufferSize); m_uBytesInWriteBuffer = 0; m_bNewSegm = false; m_pFile = &m_internalfile; m_bInMemory = false; m_szArchiveName = lpszPathName; m_pChangeVolumeFunc = NULL; if (iMode == CZipArchive::zipCreate || iMode == CZipArchive::zipCreateSegm || iMode == CZipArchive::zipCreateAppend) // create new archive { m_bReadOnly = false; m_uCurrentVolume = 0; if (iMode == CZipArchive::zipCreate || iMode == CZipArchive::zipCreateAppend) { m_iSegmMode = noSegments; OpenFile(lpszPathName, (iMode == CZipArchive::zipCreate ? CZipFile::modeCreate : CZipFile::modeNoTruncate) | CZipFile::modeReadWrite); } else // create a segmented archive { m_bNewSegm = true; m_uBytesWritten = 0; if (uVolumeSize == ZIP_AUTODETECT_VOLUME_SIZE) // spanned archive { if (!m_pSpanChangeVolumeFunc) ThrowError(CZipException::noCallback); if (!ZipPlatform::IsDriveRemovable(lpszPathName)) ThrowError(CZipException::nonRemovable); m_iSegmMode = spannedArchive; m_pChangeVolumeFunc = m_pSpanChangeVolumeFunc; } else { m_uSplitData = uVolumeSize; m_iSegmMode = splitArchive; m_pChangeVolumeFunc = m_pSplitChangeVolumeFunc; } NextVolume(4); Write(m_gszExtHeaderSignat, 4, true); } } else // open existing { m_bReadOnly = iMode == CZipArchive::zipOpenReadOnly; OpenFile(lpszPathName, CZipFile::modeNoTruncate | (m_bReadOnly ? CZipFile::modeRead : CZipFile::modeReadWrite)); // m_uData and m_iSegmMode are automatically set during reading the central dir m_iSegmMode = uVolumeSize == 0 ? suggestedAuto : suggestedSplit; } } void CZipStorage::Open(CZipAbstractFile& af, int iMode) { m_pWriteBuffer.Allocate(m_iWriteBufferSize); m_uBytesInWriteBuffer = 0; m_bNewSegm = false; m_pFile = ⁡ m_bInMemory = true; if (iMode == CZipArchive::zipCreate || iMode == CZipArchive::zipCreateAppend) { m_uCurrentVolume = 0; m_iSegmMode = noSegments; if (iMode == CZipArchive::zipCreate) af.SetLength(0); else af.SeekToEnd(); } else // open existing { af.SeekToBegin(); m_iSegmMode = suggestedAuto; } } void CZipStorage::ChangeVolume(ZIP_VOLUME_TYPE uNumber) { if (uNumber == m_uCurrentVolume || m_iSegmMode == noSegments) // the second condition may happen in some bad archives return; m_uCurrentVolume = uNumber; OpenFile(IsSpanned() ? ChangeSpannedRead() : ChangeSplitRead(), CZipFile::modeNoTruncate | CZipFile::modeRead); } void CZipStorage::ThrowError(int err) { CZipException::Throw(err, m_pFile->GetFilePath()); } bool CZipStorage::OpenFile(LPCTSTR lpszName, UINT uFlags, bool bThrow) { return m_pFile->Open(lpszName, uFlags | CZipFile::shareDenyWrite, bThrow); } CZipString CZipStorage::ChangeSpannedRead() { CZipString szTemp = m_pFile->GetFilePath(); m_pFile->Close(); CallCallback(0, CZipSegmCallback::scVolumeNeededForRead, szTemp); return szTemp; } CZipString CZipStorage::ChangeSplitRead() { bool lastPart = (ZIP_SIZE_TYPE)m_uCurrentVolume == m_uSplitData; CZipString szTemp = GetSplitVolumeName(lastPart); if (m_pChangeVolumeFunc) { int iCode = CZipSegmCallback::scVolumeNeededForRead; for(;;) { CallCallback(lastPart ? ZIP_SPLIT_LAST_VOLUME : 0, iCode, szTemp); if (ZipPlatform::FileExists(m_pChangeVolumeFunc->m_szExternalFile)) { szTemp = m_pChangeVolumeFunc->m_szExternalFile; break; } else iCode = CZipSegmCallback::scFileNotFound; } } m_pFile->Close(); return szTemp; } CZipString CZipStorage::RenameLastFileInSplitArchive() { ASSERT(IsSplit()); // give to the last volume the zip extension CZipString szFileName = m_pFile->GetFilePath(); CZipString szNewFileName = GetSplitVolumeName(true); if (m_pChangeVolumeFunc) { int code = CZipSegmCallback::scVolumeNeededForWrite; for(;;) { CallCallback(ZIP_SPLIT_LAST_VOLUME, code, szNewFileName); szNewFileName = m_pChangeVolumeFunc->m_szExternalFile; if (ZipPlatform::FileExists(szNewFileName)) code = CZipSegmCallback::scFileNameDuplicated; else break; } } if (!m_bInMemory) { m_pFile->Flush(); m_pFile->Close(); } if (!m_pChangeVolumeFunc && ZipPlatform::FileExists(szNewFileName)) ZipPlatform::RemoveFile(szNewFileName); ZipPlatform::RenameFile(szFileName, szNewFileName); return szNewFileName; } CZipString CZipStorage::Close(bool bAfterException) { bool bClose = true; CZipString sz; if (!bAfterException) { Flush(); if (IsSplit() && m_bNewSegm) { sz = RenameLastFileInSplitArchive(); bClose = false;// already closed in RenameLastFileInSplitArchive } } if (sz.IsEmpty()) sz = m_pFile->GetFilePath(); if (bClose && !m_bInMemory) { if (!bAfterException) FlushFile(); m_pFile->Close(); } m_pWriteBuffer.Release(); m_uCurrentVolume = ZIP_VOLUME_NUMBER_UNSPECIFIED; m_iSegmMode = noSegments; m_pFile = NULL; m_uBytesBeforeZip = 0; return sz; } CZipString CZipStorage::GetSplitVolumeName(bool bLast) const { CZipString szFilePath = m_szArchiveName; CZipPathComponent zpc(szFilePath); CZipString szExt; if (bLast) szExt = m_szSplitExtension; else { DWORD vol = m_uCurrentVolume + 1; if (vol < 100) szExt.Format(_T("z%.2u"), vol); else szExt.Format(_T("z%u"), vol); } zpc.SetExtension(szExt); return zpc.GetFullPath(); } void CZipStorage::NextVolume(ZIP_SIZE_TYPE uNeeded) { Flush(); ASSERT(m_iSegmMode != noSegments); bool bSpan = IsSpanned(); if (m_uBytesWritten) { m_uBytesWritten = 0; m_uCurrentVolume++; ZIP_VOLUME_TYPE uMaxVolumes = (ZIP_VOLUME_TYPE)(bSpan ? 999 : 0xFFFF); if (m_uCurrentVolume >= uMaxVolumes) // m_uCurrentVolume is a zero-based index ThrowError(CZipException::tooManyVolumes); } CZipString szFileName; if (bSpan) szFileName = m_szArchiveName; else szFileName = GetSplitVolumeName(false); if (!m_pFile->IsClosed()) { m_pFile->Flush(); m_pFile->Close(); } if (m_pChangeVolumeFunc) { int iCode = CZipSegmCallback::scVolumeNeededForWrite; for(;;) { CallCallback(uNeeded, iCode, szFileName); if (!bSpan) // allow the user to change the filename szFileName = m_pChangeVolumeFunc->m_szExternalFile; if (ZipPlatform::FileExists(szFileName)) iCode = CZipSegmCallback::scFileNameDuplicated; else { if (bSpan) { CZipString label; label.Format(_T("pkback# %.3d"), m_uCurrentVolume + 1); if (!ZipPlatform::SetVolLabel(szFileName, label)) { iCode = CZipSegmCallback::scCannotSetVolLabel; continue; } } if (OpenFile(szFileName, CZipFile::modeCreate | CZipFile::modeReadWrite, false)) break; else iCode = CZipSegmCallback::scFileCreationFailure; } } m_uCurrentVolSize = bSpan ? GetFreeVolumeSpace() : m_uSplitData; } else { if (bSpan) ThrowError(CZipException::internalError); m_uCurrentVolSize = m_uSplitData; OpenFile(szFileName, CZipFile::modeCreate | CZipFile::modeReadWrite); } } void CZipStorage::CallCallback(ZIP_SIZE_TYPE uNeeded, int iCode, CZipString szTemp) { if (!m_pChangeVolumeFunc) ThrowError(CZipException::internalError); m_pChangeVolumeFunc->m_szExternalFile = szTemp; m_pChangeVolumeFunc->m_uVolumeNeeded = (ZIP_VOLUME_TYPE)(m_uCurrentVolume + 1); m_pChangeVolumeFunc->m_iCode = iCode; if (!m_pChangeVolumeFunc->Callback(uNeeded)) CZipException::Throw(CZipException::aborted, szTemp); } ZIP_SIZE_TYPE CZipStorage::GetFreeVolumeSpace() const { ASSERT (IsSpanned()); CZipString szTemp = m_pFile->GetFilePath(); if (szTemp.IsEmpty()) // called once when creating a segmented archive return 0; else { CZipPathComponent zpc(szTemp); ULONGLONG ret = ZipPlatform::GetDeviceFreeSpace(zpc.GetFilePath()); if (ret > (ZIP_SIZE_TYPE)(-1)) return (ZIP_SIZE_TYPE)(-1); else return (ZIP_SIZE_TYPE)ret; } } void CZipStorage::UpdateSegmMode(ZIP_VOLUME_TYPE uLastDisk) { m_uCurrentVolume = uLastDisk; if (uLastDisk) { // segmentation detected CZipString szFilePath = m_pFile->GetFilePath(); if (m_iSegmMode == suggestedAuto) m_iSegmMode = ZipPlatform::IsDriveRemovable(szFilePath) ? spannedArchive : splitArchive; else { ASSERT(m_iSegmMode == suggestedSplit); m_iSegmMode = splitArchive; } if (IsSpanned()) { if (!m_pSpanChangeVolumeFunc) ThrowError(CZipException::noCallback); m_pChangeVolumeFunc = m_pSpanChangeVolumeFunc; } else /*if (IsSplit())*/ { m_uSplitData = uLastDisk; // volume with .zip extension ( the last one) m_pChangeVolumeFunc = m_pSplitChangeVolumeFunc; } CZipPathComponent zpc(szFilePath); m_szSplitExtension = zpc.GetFileExt(); m_pWriteBuffer.Release(); // no need for this in this case } else m_iSegmMode = noSegments; } ZIP_SIZE_TYPE CZipStorage::AssureFree(ZIP_SIZE_TYPE uNeeded) { ZIP_SIZE_TYPE uFree; while ((uFree = VolumeLeft()) < uNeeded) { if (IsSplit() && !m_uBytesWritten && !m_uBytesInWriteBuffer) // in the splitArchive mode, if the size of the archive is less // than the size of the packet to be written at once, // increase once the size of the volume m_uCurrentVolSize = uNeeded; else NextVolume(uNeeded); } return uFree; } void CZipStorage::Write(const void *pBuf, DWORD iSize, bool bAtOnce) { if (!IsSegmented()) WriteInternalBuffer((char*)pBuf, iSize); else { // if not at once, one byte is enough free space DWORD iNeeded = bAtOnce ? iSize : 1; DWORD uTotal = 0; while (uTotal < iSize) { ZIP_SIZE_TYPE uFree = AssureFree(iNeeded); DWORD uLeftToWrite = iSize - uTotal; DWORD uToWrite = uFree < uLeftToWrite ? (DWORD)uFree : uLeftToWrite; WriteInternalBuffer((char*)pBuf + uTotal, uToWrite); if (bAtOnce) return; else uTotal += uToWrite; } } } void CZipStorage::WriteInternalBuffer(const char *pBuf, DWORD uSize) { DWORD uWritten = 0; while (uWritten < uSize) { DWORD uFreeInBuffer = GetFreeInBuffer(); if (uFreeInBuffer == 0) { Flush(); uFreeInBuffer = m_pWriteBuffer.GetSize(); } DWORD uLeftToWrite = uSize - uWritten; DWORD uToCopy = uLeftToWrite < uFreeInBuffer ? uLeftToWrite : uFreeInBuffer; memcpy((char*)m_pWriteBuffer + m_uBytesInWriteBuffer, pBuf + uWritten, uToCopy); uWritten += uToCopy; m_uBytesInWriteBuffer += uToCopy; } } ZIP_SIZE_TYPE CZipStorage::VolumeLeft() const { // for spanned archives m_uCurrentVolSize is updated after each flush() ZIP_SIZE_TYPE uBytes = m_uBytesInWriteBuffer + (IsSpanned() ? 0 : m_uBytesWritten); return uBytes > m_uCurrentVolSize ? 0 : m_uCurrentVolSize - uBytes; } void CZipStorage::Flush() { if (m_uBytesInWriteBuffer) { m_pFile->Write(m_pWriteBuffer, m_uBytesInWriteBuffer); if (m_iSegmMode != noSegments) m_uBytesWritten += m_uBytesInWriteBuffer; m_uBytesInWriteBuffer = 0; } if (IsSpanned()) // after writing it is difficult to predict the free space due to // not completly written clusters, write operation may start from a new cluster m_uCurrentVolSize = GetFreeVolumeSpace(); } ZIP_FILE_USIZE CZipStorage::LocateSignature(char* szSignature, ZIP_SIZE_TYPE uMaxDepth) { const int recordSize = 4; CZipAutoBuffer buffer(m_iLocateBufferSize); ZIP_FILE_USIZE uFileLength = m_pFile->GetLength(); ZIP_SIZE_TYPE max = (ZIP_SIZE_TYPE)(uFileLength < uMaxDepth ? uFileLength : uMaxDepth); ZIP_SIZE_TYPE position = (ZIP_SIZE_TYPE)(uFileLength - m_pFile->GetPosition()); int offset = 0; int leftToFind = recordSize - 1; int toRead = m_iLocateBufferSize; bool found = false; // for fast checking if leftToFind needs resetting while ( position < max ) { position += toRead; if ( position > max ) { int diff = (int) ( position - max ); toRead -= diff; offset = diff; position = max; } Seek(position, seekFromEnd); int actuallyRead = m_pFile->Read((char*)buffer + offset, toRead); if (actuallyRead != toRead) ThrowError(CZipException::badZipFile); int pos = m_iLocateBufferSize - 1; while ( pos >= offset ) { if ( buffer[pos] == szSignature[leftToFind] ) { if ( leftToFind == 0 ) return (ZIP_FILE_USIZE)(uFileLength - ( position - ( pos - offset ) )); if ( !found ) found = true; leftToFind--; pos--; } else if ( found ) { leftToFind = recordSize - 1; found = false; // do not decrease position, the current pos may be the first to find } else pos--; } } return SignatureNotFound; } ULONGLONG CZipStorage::Seek(ULONGLONG lOff, SeekType iSeekType) { if (iSeekType == seekCurrent) { ZIP_SIZE_TYPE uPosition = (ZIP_SIZE_TYPE)m_pFile->GetPosition(); if (IsSegmented() == -1) { ZIP_FILE_USIZE uLength = m_pFile->GetLength(); while (uPosition + lOff >= uLength) { ZIP_SIZE_TYPE uCanSeek = (ZIP_SIZE_TYPE)(uLength - uPosition); lOff -= uCanSeek; ChangeVolume(); uPosition = 0; uLength = m_pFile->GetLength(); } return lOff > 0 ? m_pFile->Seek((ZIP_FILE_USIZE)lOff) : 0; } else return m_pFile->Seek((ZIP_FILE_SIZE)lOff, CZipAbstractFile::current); } else { if (m_uCurrentVolume == 0 && m_uBytesBeforeZip > 0) lOff += m_uBytesBeforeZip; return m_pFile->Seek((ZIP_FILE_USIZE)lOff, iSeekType == seekFromBeginning); } } void CZipStorage::FinalizeSegm() { ASSERT(IsSegmented() == 1); // spanned archive in creation ASSERT(!m_bInMemory); CZipString szFileName; if (IsSplit() && m_bNewSegm) szFileName = RenameLastFileInSplitArchive(); else { szFileName = m_pFile->GetFilePath(); // the file is already closed m_pFile->Close(); } m_bNewSegm = false; if (m_uCurrentVolume == 0) // one-volume segmented archive was converted to normal archive m_iSegmMode = noSegments; else m_uSplitData = m_uCurrentVolume; OpenFile(szFileName, CZipFile::modeNoTruncate | (m_iSegmMode == noSegments ? CZipFile::modeReadWrite : CZipFile::modeRead)); } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/BaseLibCompressor.h0000644000175000017500000001121411300022650022557 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file BaseLibCompressor.h * Includes the ZipArchiveLib::CBaseLibCompressor class. * */ #if !defined(ZIPARCHIVE_BASELIBCOMPRESSOR_DOT_H) #define ZIPARCHIVE_BASELIBCOMPRESSOR_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "ZipExport.h" #include "ZipCompressor.h" #include "ZipCollections.h" #include "ZipException.h" namespace ZipArchiveLib { /** A base class for compressors that use external libraries, such as zlib or bzip2. */ class ZIP_API CBaseLibCompressor : public CZipCompressor { public: /** Represents options of compressors that use external libraries. \see 0610231446|options \see CZipArchive::SetCompressionOptions */ struct ZIP_API COptions : CZipCompressor::COptions { COptions() { m_bDetectLibMemoryLeaks = true; } /** \c true, if the ZipArchive Library should detect memory leaks in an external library; \c false otherwise. Recommended to be set to \c true. */ bool m_bDetectLibMemoryLeaks; }; /** Initializes a new instance of the CBaseLibCompressor class. \param pStorage The current storage object. */ CBaseLibCompressor(CZipStorage* pStorage) :CZipCompressor(pStorage) { } void InitDecompression(CZipFileHeader* pFile, CZipCryptograph* pCryptograph) { CZipCompressor::InitDecompression(pFile, pCryptograph); m_bDecompressionDone = false; } ~CBaseLibCompressor() { EmptyPtrList(); } protected: /** A memory allocation method called by an external library. \param opaque Internal data. \param items The number of blocks to allocate. \param size The size of each block to allocate. \return The address of a newly allocated memory. */ static void* _zipalloc(void* opaque, UINT items, UINT size) { void* p = new char[size * items]; if (opaque) { CZipPtrList* list = (CZipPtrList*) opaque; list->AddTail(p); } return p; } /** A memory deallocation method called by an external library. \param opaque Internal data. \param address Memory address to free. */ static void _zipfree(void* opaque, void* address) { if (opaque) { CZipPtrList* list = (CZipPtrList*) opaque; CZipPtrListIter iter = list->Find(address); if (list->IteratorValid(iter)) list->RemoveAt(iter); } delete[] (char*) address; } /** Frees the memory allocated by an external library that hasn't been freed due to an error in the library (usually never happens). */ void EmptyPtrList(); /** Checks, if \a iErr value is an error code. \param iErr The code to check. \return \c true, if \a iErr is an error code; \c false otherwise. */ virtual bool IsCodeErrorOK(int iErr) const = 0; /** Checks, if \a iErr value is an error code and throws an exception, if it is. \param iErr The error code. \note Throws exceptions. */ void CheckForError(int iErr) { if (!IsCodeErrorOK(iErr)) ThrowError(iErr, true); } /** Sets an address of internal data used in ZipArchive Library memory allocation and deallocation methods. \param opaque Receives an address on the internal data. \param pOptions The current decompressor options. */ void SetOpaque(void** opaque, const COptions* pOptions); /** Signalizes, that the decompression process reached the end of the compressed data. It is internally set by derived classes. */ bool m_bDecompressionDone; private: typedef CZipPtrList::iterator CZipPtrListIter; #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning (push) #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class #endif CZipPtrList m_list; ///< A list holding pointers to the memory areas allocated by an external library. #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning( pop) #endif }; } // namespace #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipFileMapping.h0000644000175000017500000000212111300022650022054 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipFileMapping.h * Includes the ZipArchiveLib::CZipFileMapping class. * */ #if !defined(ZIPARCHIVE_ZIPFILEMAPPING_DOT_H) #define ZIPARCHIVE_ZIPFILEMAPPING_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "_platform.h" #ifdef ZIP_ARCHIVE_WIN #include "ZipFileMapping_win.h" #else #include "ZipFileMapping_lnx.h" #endif #endif // !defined(ZIPARCHIVE_ZIPFILEMAPPING_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/BaseLibCompressor.cpp0000644000175000017500000000235511300022650023120 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "BaseLibCompressor.h" namespace ZipArchiveLib { void CBaseLibCompressor::SetOpaque(void** opaque, const COptions* pOptions) { *opaque = pOptions->m_bDetectLibMemoryLeaks ? &m_list : 0; } void CBaseLibCompressor::EmptyPtrList() { if (m_list.GetCount()) { // if some memory hasn't been freed due to an error in zlib, so free it now CZipPtrListIter iter = m_list.GetHeadPosition(); while (m_list.IteratorValid(iter)) delete[] (char*) m_list.GetNext(iter); } m_list.RemoveAll(); } } // namespace tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipFile_stl.h0000644000175000017500000000546211300022650021435 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #ifndef ZIPARCHIVE_ZIPFILE_DOT_H #error Do not include this file directly. Include ZipFile.h instead #endif #include "ZipAbstractFile.h" #include "ZipString.h" #include "ZipExport.h" #ifndef __GNUC__ #include #else #include #include #endif #if !defined (_MSC_VER) || _MSC_VER < 1400 // there seems to be a problem under Windows sometimes when using one of the functions below // without the underscore at the beginning #ifndef _lseek #define _lseek lseek #endif #ifndef _read #define _read read #endif #ifndef _close #define _close close #endif #ifndef _tell #define _tell tell #endif #ifndef _write #define _write write #endif #endif class ZIP_API CZipFile : public CZipAbstractFile { void ThrowError() const; public: int m_hFile; operator HANDLE(); enum OpenModes { modeRead = 0x0001, modeWrite = 0x0002, modeReadWrite = modeRead | modeWrite, shareDenyWrite = 0x0004, shareDenyRead = 0x0008, shareDenyNone = 0x0010, modeCreate = 0x0020, modeNoTruncate = 0x0040, }; CZipFile(LPCTSTR lpszFileName, UINT openFlags) { m_hFile = -1; Open(lpszFileName, openFlags, true); } void Flush(); ZIP_FILE_USIZE GetLength() const; CZipString GetFilePath() const {return m_szFileName;} bool IsClosed()const { return m_hFile == -1;} bool Open(LPCTSTR lpszFileName, UINT openFlags, bool bThrow); void Close() { if (IsClosed()) return; if (_close(m_hFile) != 0) ThrowError(); else { m_szFileName.Empty(); m_hFile = -1; } } void Write(const void* lpBuf, UINT nCount) { if (_write(m_hFile, lpBuf, nCount) != (int) nCount) ThrowError(); } ZIP_FILE_USIZE GetPosition() const; void SetLength(ZIP_FILE_USIZE uNewLen); UINT Read(void *lpBuf, UINT nCount) { errno = 0; int ret = _read(m_hFile, lpBuf, nCount); if (ret < (int) nCount && errno != 0) ThrowError(); return ret; } ZIP_FILE_USIZE Seek(ZIP_FILE_SIZE dOff, int nFrom); CZipFile (); virtual ~CZipFile (){Close();}; protected: CZipString m_szFileName; }; tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCollections.h0000644000175000017500000000224611300022650022147 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipCollections.h * Includes the collections classes used by the ZipArchive Library. * */ #ifndef ZIPARCHIVE_ZIPCOLLECTIONS_DOT_H #define ZIPARCHIVE_ZIPCOLLECTIONS_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "_platform.h" #include "ZipExport.h" #ifdef ZIP_ARCHIVE_STL #include "ZipCollections_stl.h" #else #include "ZipCollections_mfc.h" #endif typedef CZipArray CZipIndexesArray; #endif /* ZIPARCHIVE_ZIPCOLLECTIONS_DOT_H */ tuxcmd-modules-0.6.70+ds/zip/ZipArchive/_platform.h0000644000175000017500000000415111300022650021166 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file _platform.h * Contains definitions that determine the target compilation platform. * */ #if !defined(ZIPARCHIVE_PLATFORM_DOT_H) #define ZIPARCHIVE_PLATFORM_DOT_H #if _MSC_VER > 1000 #pragma once #endif /************ Feel free to adjust the definitions in the following block ************/ /************************************ BLOCK START ***********************************/ //#define ZIP_ARCHIVE_MFC //#define ZIP_ARCHIVE_LNX // simplified endianess detection #ifdef __APPLE__ #ifdef __LITTLE_ENDIAN__ #define ZIP_ARCHIVE_LITTLE_ENDIAN #endif #else #define ZIP_ARCHIVE_LITTLE_ENDIAN #endif /************************************* BLOCK END ***********************************/ /********* The contents below this line are not intended for modification **********/ #ifndef ZIP_ARCHIVE_MFC #define ZIP_ARCHIVE_STL #else #ifdef ZIP_ARCHIVE_STL #undef ZIP_ARCHIVE_STL #endif #endif #ifndef ZIP_ARCHIVE_LNX #define ZIP_ARCHIVE_WIN #else #ifdef ZIP_ARCHIVE_WIN #undef ZIP_ARCHIVE_WIN #endif #endif #ifndef ZIP_ARCHIVE_LITTLE_ENDIAN #define ZIP_ARCHIVE_BIG_ENDIAN #else #ifdef ZIP_ARCHIVE_BIG_ENDIAN #undef ZIP_ARCHIVE_BIG_ENDIAN #endif #endif #if defined (ZIP_ARCHIVE_LNX) && defined (ZIP_ARCHIVE_MFC) #undef ZIP_ARCHIVE_MFC #define ZIP_ARCHIVE_STL #error Using MFC under a non-Windows platform is not supported #endif #endif // !defined(ZIPARCHIVE_PLATFORM_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipFileMapping_win.h0000644000175000017500000000335711300022650022745 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #ifndef ZIPARCHIVE_ZIPFILEMAPPING_DOT_H #error Do not include this file directly. Include ZipFileMapping.h instead #endif #include "ZipFile.h" namespace ZipArchiveLib { struct CZipFileMapping { CZipFileMapping() { m_hFileMap = NULL; m_pFileMap = NULL; } bool CreateMapping(CZipFile* pFile) { if (!pFile) return false; m_hFileMap = CreateFileMapping((*pFile), NULL, PAGE_READWRITE, 0, 0, _T("ZipArchive Mapping File")); if (!m_hFileMap) return false; // Get pointer to memory representing file m_pFileMap = MapViewOfFile(m_hFileMap, FILE_MAP_WRITE, 0, 0, 0); return (m_pFileMap != NULL); } void RemoveMapping() { if (m_pFileMap) { UnmapViewOfFile(m_pFileMap); m_pFileMap = NULL; } if (m_hFileMap) { CloseHandle(m_hFileMap); m_hFileMap = NULL; } } ~CZipFileMapping() { RemoveMapping(); } char* GetMappedMemory() { return reinterpret_cast (m_pFileMap); } protected: HANDLE m_hFileMap; LPVOID m_pFileMap; }; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipFileHeader.h0000644000175000017500000004505611300022650021667 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipFileHeader.h * Includes the CZipFileHeader class. * */ #if !defined(ZIPARCHIVE_ZIPFILEHEADER_DOT_H) #define ZIPARCHIVE_ZIPFILEHEADER_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "ZipExport.h" #include "ZipStorage.h" #include "ZipAutoBuffer.h" #include "sys/types.h" #include "ZipCompatibility.h" #include "ZipCollections.h" #include "ZipExtraField.h" #include "ZipStringStoreSettings.h" #include "ZipCryptograph.h" class CZipCentralDir; /** Represents a single file stored in a zip archive. */ class ZIP_API CZipFileHeader { friend class CZipCentralDir; friend class CZipArchive; public: CZipFileHeader(); CZipFileHeader(const CZipFileHeader& header) { *this = header; } CZipFileHeader& operator=(const CZipFileHeader& header); virtual ~CZipFileHeader(); /** Predicts the filename size after conversion using the current filename code page. \return The number of characters not including a terminating \c NULL character. */ int PredictFileNameSize() const { if (m_pszFileNameBuffer.IsAllocated()) return m_pszFileNameBuffer.GetSize(); CZipAutoBuffer buffer; ConvertFileName(buffer); return buffer.GetSize(); } /** Gets the comment size. \return The number of characters in the comment not including a terminating \c NULL character. */ WORD GetCommentSize() const {return (WORD)m_pszComment.GetSize();} /** Gets the filename. If necessary, performs the conversion using the current filename code page. Caches the result of conversion for faster access the next time. \param bClearBuffer If \c true, releases the internal buffer after performing the filename conversion. If \c false, the internal buffer is not released and both representations of the filename are kept in memory (converted and not converted). This takes more memory, but the conversion does not take place again when the central directory is written back to the archive. \return The converted filename. \see 0610051525 \see GetStringStoreSettings \see CZipStringStoreSettings::m_uNameCodePage */ CZipString& GetFileName(bool bClearBuffer = true); /** Sets the filename. \param lpszFileName The filename to set. */ void SetFileName(LPCTSTR lpszFileName); /** Gets the file comment. \return The file comment. */ CZipString GetComment() const; /** Sets the file comment. \param lpszComment The file comment. */ void SetComment(LPCTSTR lpszComment); /** Gets a value indicating whether the data descriptor is present or not. \return \c true, if the data descriptor is present; \c false otherwise. */ bool IsDataDescriptor()const { return (m_uFlag & (WORD) 8) != 0;} /** Gets the data descriptor size as it is required for the current file. Takes into account various factors, such as the archive segmentation type, encryption and the need for the Zip64 format. \param pStorage The storage to test for segmentation type. \return The required data descriptor size in bytes. */ WORD GetDataDescriptorSize(const CZipStorage* pStorage) const { return GetDataDescriptorSize(NeedsSignatureInDataDescriptor(pStorage)); } /** Gets the data descriptor size as it is required for the current file. Takes into account various factors, such as the need for the data descriptor signature or for the Zip64 format. \param bConsiderSignature \c true, if the data descriptor signature is needed; \c false otherwise. \return The required data descriptor size in bytes. */ WORD GetDataDescriptorSize(bool bConsiderSignature = false) const; /** Gets the size of the compressed data. \param bUseLocal If \c true, uses #m_uLocalComprSize; otherwise uses #m_uComprSize; \param bReal If \c true, the returned value does not include the encrypted information size, only the data size. If \c false, the encrypted information size is added (you should not use this value when the file exists in the archive). \return The compressed data size in bytes. \see GetEncryptedInfoSize */ ZIP_SIZE_TYPE GetDataSize(bool bUseLocal = false, bool bReal = true) const { ZIP_SIZE_TYPE uSize = bUseLocal ? m_uLocalComprSize : m_uComprSize; DWORD uEncrSize = GetEncryptedInfoSize(); return bReal ? (uSize - uEncrSize) : (uSize + uEncrSize); } /** Gets the encrypted information size. The returned value depends on the used encryption method. \return The encrypted information size in bytes. */ DWORD GetEncryptedInfoSize() const { return CZipCryptograph::GetEncryptedInfoSize(m_uEncryptionMethod); } /** Gets the total size of the structure in the central directory. \return The total size in bytes. */ DWORD GetSize()const; /** Gets the local header size. Before calling this method, the local information must be up-to-date (see 0610242128|local for more information). \param bReal If \c true, uses the real local filename size. If \c false, predicts the filename size. \return The local header size in bytes. */ DWORD GetLocalSize(bool bReal) const; /** Gets a value indicating if the compression is efficient. \return \c true if the compression is efficient; \c false if the file should be stored without the compression instead. */ bool CompressionEfficient() { ZIP_SIZE_TYPE uBefore = m_uUncomprSize; // ignore the length of encryption info ZIP_SIZE_TYPE uAfter = GetDataSize(false, true); return uAfter <= uBefore; } /** Gets the compression ratio. \return The compression ratio of the file. */ float GetCompressionRatio() { #if _MSC_VER >= 1300 || !defined(_ZIP64) return m_uUncomprSize ? ((float)m_uComprSize * 100 ) / m_uUncomprSize: 0; #else return m_uUncomprSize ? ((float)(__int64)(m_uComprSize) / (float)(__int64)m_uUncomprSize) * 100: 0; #endif } /** Sets the file modification date. \param ttime The date to set. If this value is incorrect, the date defaults to January 1, 1980. \see GetTime */ void SetTime(const time_t& ttime); /** Gets the file modification time. \return The modification time. \see SetTime */ time_t GetTime()const; /** Gets the file system compatibility. External software can use this information e.g. to determine end-of-line format for text files etc. The ZipArchive Library uses it to perform a proper file attributes conversion. \return The file system compatibility. Can be one of the ZipCompatibility::ZipPlatforms values. \see CZipArchive::GetSystemComatibility \see ZipPlatform::GetSystemID */ int GetSystemCompatibility()const { return (m_uVersionMadeBy & 0xFF00) >> 8; } /** Gets the file attributes. \return The file attributes, converted if necessary to be compatible with the current system. \note Throws an exception, if the archive system or the current system is not supported by the ZipArchive Library. \see GetOriginalAttributes */ DWORD GetSystemAttr(); /** Gets the file attributes exactly as they are stored in the archive. \return The file attributes as they are stored in the archive. No conversion is performed. \note The attributes for Linux are stored shifted left by 16 bits in this field. \see GetSystemAttr */ DWORD GetOriginalAttributes() const {return m_uExternalAttr;} /** Gets a value indicating whether the file represents a directory or not. This method checks the file attributes. If the attributes value is zero, the method checks for the presence of a path separator at the end of the filename. If the path separator is present, the file is assumed to be a directory. \return \c true, if the file represents a directory; \c false otherwise. */ bool IsDirectory(); /** Gets the string store settings for the file. \return The string store settings. \see 0610051525 \see CZipArchive::GetStringStoreSettings */ CZipStringStoreSettings GetStringStoreSettings() { return m_stringSettings; } /** Gets a value indicating if the file is encrypted or not. If the file is encrypted, you need to set the password with the CZipArchive::SetPassword method before decompressing the file. \return \c true if the file is encrypted; \c false otherwise. \see CZipArchive::SetPassword */ bool IsEncrypted()const { return m_uEncryptionMethod != CZipCryptograph::encNone;} /** Gets the encryption method of the file. \return The file encryption method. Can be one of the CZipCryptograph::EncryptionMethod values. */ int GetEncryptionMethod() const {return m_uEncryptionMethod;} /** Gets a value indicating if the file is encrypted using WinZip AES encryption method or not. \return \c true, if the file is encrypted using WinZip AES encryption method; \c false otherwise. */ bool IsWinZipAesEncryption() const { return CZipCryptograph::IsWinZipAesEncryption(m_uEncryptionMethod); } /** Gets an approximate file compression level. \return The compression level. May not be the real value used when compressing the file. */ int GetCompressionLevel() const; /** Returns the value indicating whether the current CZipFileHeader object has the time set or not. \return \c true, if the time is set; \c false otherwise. */ bool HasTime() { return m_uModTime != 0 || m_uModDate != 0; } static char m_gszSignature[]; ///< The central file header signature. static char m_gszLocalSignature[]; ///< The local file header signature. WORD m_uVersionMadeBy; ///< The "made by" version and the system compatibility. WORD m_uVersionNeeded; ///< The version needed to extract the file. WORD m_uFlag; ///< A general purpose bit flag. WORD m_uMethod; ///< The compression method. Can be one of the CZipCompressor::CompressionMethod values. WORD m_uModTime; ///< The file last modification time. WORD m_uModDate; ///< The file last modification date. DWORD m_uCrc32; ///< The crc-32 value. ZIP_SIZE_TYPE m_uComprSize; ///< The compressed size. ZIP_SIZE_TYPE m_uUncomprSize; ///< The uncompressed size. ZIP_VOLUME_TYPE m_uVolumeStart; ///< The volume number at which the compressed file starts. WORD m_uInternalAttr; ///< Internal file attributes. ZIP_SIZE_TYPE m_uLocalComprSize; ///< The compressed size written in the local header. ZIP_SIZE_TYPE m_uLocalUncomprSize; ///< The uncompressed size written in the local header. ZIP_SIZE_TYPE m_uOffset; ///< Relative offset of the local header with respect to CZipFileHeader::m_uVolumeStart. CZipExtraField m_aLocalExtraData; ///< The local extra field. Do not modify after you have started compressing the file. CZipExtraField m_aCentralExtraData; ///< The central extra field. protected: DWORD m_uExternalAttr; ///< External file attributes. WORD m_uLocalFileNameSize; ///< The local filename length. BYTE m_uEncryptionMethod; ///< The file encryption method. Can be one of the CZipCryptograph::EncryptionMethod values. bool m_bIgnoreCrc32; ///< A value indicating whether to ignore Crc32 checking or not. /** Sets the file system compatibility. \param iSystemID The file system compatibility. Can be one of the ZipCompatibility::ZipPlatforms values. \see GetSystemCompatibility */ void SetSystemCompatibility(int iSystemID) { m_uVersionMadeBy &= 0x00FF; m_uVersionMadeBy |= (WORD)(iSystemID << 8); } /** Sets the file attributes. To set the attributes of this structure use the CZipArchive::SetFileHeaderAttr method. \param uAttr The attributes to set. \note Throws exceptions, if the archive system or the current system is not supported by the ZipArchive Library. \see CZipArchive::SetFileHeaderAttr \see GetSystemAttr */ void SetSystemAttr(DWORD uAttr); /** Prepares the filename for writing to the archive. */ void PrepareFileName() { if (m_pszFileNameBuffer.IsAllocated() || m_pszFileName == NULL) return; ConvertFileName(m_pszFileNameBuffer); } /** Validates an existing data descriptor after file decompression. \param pStorage The storage to read the data descriptor from. \return \c true, if the data descriptor is valid; \c false otherwise. */ bool CheckDataDescriptor(CZipStorage* pStorage) const; /** Prepares the data for writing when adding a new file. When Zip64 extensions are required for this file, this method adds Zip64 extra data to #m_aLocalExtraData. \param iLevel The compression level. \param bSegm Set to \c true, if the archive is segmented; \c false otherwise. */ void PrepareData(int iLevel, bool bSegm); /** Writes the local file header to the \a pStorage. The filename and extra field are the same as those that will be stored in the central directory. \param pStorage The storage to write the local file header to. \note Throws exceptions. */ void WriteLocal(CZipStorage *pStorage); /** Reads the local file header from an archive and validates the read data. \param centralDir The current central directory. \return \c true, if read data is consistent; \c false otherwise. \note Throws exceptions. \see CZipArchive::SetIgnoredConsistencyChecks */ bool ReadLocal(CZipCentralDir& centralDir); /** Writes the central file header to \a pStorage. \param pStorage The storage to write the central file header to. \return The size of the file header. \note Throws exceptions. */ DWORD Write(CZipStorage *pStorage); /** Reads the central file header from \a pStorage and validates the read data. \param centralDir The current central directory. \param bReadSignature \c true, if the the central header signature should be read; \c false otherwise. \return \c true, if the read data is consistent; \c false otherwise. \note Throws exceptions. */ bool Read(CZipCentralDir& centralDir, bool bReadSignature); /** Validates the member fields lengths. The tested fields are: filename, extra fields and comment. \return \c false, if any of the lengths exceeds the allowed value. */ bool CheckLengths(bool local) const { if (m_pszComment.GetSize() > USHRT_MAX || m_pszFileNameBuffer.GetSize() > USHRT_MAX) return false; else if (local) return m_aLocalExtraData.Validate(); else return m_aCentralExtraData.Validate(); } /** Writes the Crc32 to \a pBuf. \param pBuf The buffer to write the Crc32 to. Must have be of at least 4 bytes size. */ void WriteCrc32(char* pBuf) const; /** Gets a value indicating whether the file needs the data descriptor. The data descriptor is needed when a file is encrypted or the Zip64 format needs to be used. \return \c true, if the data descriptor is needed; \c false otherwise. */ bool NeedsDataDescriptor() const; /** Writes the data descriptor. \param pDest The buffer to receive the data. \param bLocal Set to \c true, if the local sizes are used; \c false otherwise. */ void WriteSmallDataDescriptor(char* pDest, bool bLocal = true); /** Writes the data descriptor taking into account the Zip64 format. \param pStorage The storage to write the data descriptor to. */ void WriteDataDescriptor(CZipStorage* pStorage); bool NeedsSignatureInDataDescriptor(const CZipStorage* pStorage) const { return pStorage->IsSegmented() != 0 || IsEncrypted(); } /** Updates the local header in the archive after is has already been written. \param pStorage The storage to update the data descriptor in. */ void UpdateLocalHeader(CZipStorage* pStorage); /** Verifies the central header signature. \param buf The buffer that contains the signature to verify. \return \c true, if the signature is valid; \c false otherwise. */ static bool VerifySignature(CZipAutoBuffer& buf) { return memcmp(buf, m_gszSignature, 4) == 0; } /** Updates the general purpose bit flag. \param bSegm \c true, if the current archive is a segmented archive; \c false otherwise. */ void UpdateFlag(bool bSegm) { if (bSegm || m_uEncryptionMethod == CZipCryptograph::encStandard) m_uFlag |= 8; // data descriptor present if (IsEncrypted()) m_uFlag |= 1; // encrypted file } private: /** Sets the "made by" version. \param uVersion The version to set. */ void SetVersion(WORD uVersion) { if ((m_uVersionMadeBy & 0x00FF) != (uVersion & 0x00FF)) { m_uVersionMadeBy &= 0xFF00; m_uVersionMadeBy |= (WORD)(uVersion & 0x00FF); } } void ConvertFileName(CZipAutoBuffer& buffer) const; void ConvertFileName(CZipString& szFileName) const; void ClearFileName() { if (m_stringSettings.m_bStoreNameInExtraData) // we are keeping m_pszFileName, clear the buffer, we need the original, when writing extra header and when accessing the filename m_pszFileNameBuffer.Release(); else if (m_pszFileName != NULL) { delete m_pszFileName; m_pszFileName = NULL; } } void GetCrcAndSizes(char* pBuffer)const; bool NeedsZip64() const { return m_uComprSize >= UINT_MAX || m_uUncomprSize >= UINT_MAX || m_uVolumeStart >= USHRT_MAX || m_uOffset >= UINT_MAX; } void OnNewFileClose(CZipStorage* pStorage) { UpdateLocalHeader(pStorage); WriteDataDescriptor(pStorage); pStorage->Flush(); } CZipAutoBuffer m_pszFileNameBuffer; CZipString* m_pszFileName; CZipStringStoreSettings m_stringSettings; CZipAutoBuffer m_pszComment; }; #endif // !defined(ZIPARCHIVE_ZIPFILEHEADER_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCentralDir.h0000644000175000017500000004640611300022650021726 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipCentralDir.h * Includes the CZipCentralDir class. * */ #if !defined(ZIPARCHIVE_ZIPCENTRALDIR_DOT_H) #define ZIPARCHIVE_ZIPCENTRALDIR_DOT_H #if _MSC_VER > 1000 #pragma once #endif #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning (push) #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class #endif #include "ZipException.h" #include "ZipFileHeader.h" #include "ZipAutoBuffer.h" #include "ZipCollections.h" #include "ZipCompatibility.h" #include "ZipExport.h" #include "ZipCallbackProvider.h" #include "ZipMutex.h" /** Represents the central directory record in the archive. */ class ZIP_API CZipCentralDir { public: /** Used in fast finding files by the filename. A structure for the internal use only. \see CZipCentralDir::m_pFindArray \see CZipArchive::FindFile \see CZipArchive::EnableFindFast */ struct ZIP_API CZipFindFast { CZipFindFast() { m_uIndex = 0; m_pHeader= NULL; } CZipFindFast(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex):m_pHeader(pHeader), m_uIndex(uIndex){} /** A pointer to the structure in CZipCentralDir. We extract a name from it. */ CZipFileHeader* m_pHeader; /** The index in the central directory of the #m_pHeader. */ ZIP_INDEX_TYPE m_uIndex; }; /** Stores general information about the central directory. \see CZipArchive::GetCentralDirInfo */ struct ZIP_API CInfo { /** The position of the End of Central Directory Record. In the Zip64 it points to the Zip64 counterpart. */ ZIP_SIZE_TYPE m_uEndOffset; /** The zero-based number of the volume with the End of Central Directory Record. To determine the total number of segments in an archive, add one to this value. Request this information with CZipArchive::GetCentralDirInfo. */ ZIP_VOLUME_TYPE m_uLastVolume; ZIP_VOLUME_TYPE m_uVolumeWithCD; ///< The number of the volume with the start of the central directory. ZIP_INDEX_TYPE m_uVolumeEntriesNo; ///< The total number of entries in the central directory on the last volume. ZIP_INDEX_TYPE m_uEntriesNumber; ///< The total number of entries in the central directory. /** The size of the central directory. This value is valid only if #m_bInArchive is \c true; in other cases use the #GetSize method instead. */ ZIP_SIZE_TYPE m_uSize; /** The offset of the start of the central directory with respect to the starting volume number. It is the value written in the central directory record. This value is valid only if #m_bInArchive is \c true. */ ZIP_SIZE_TYPE m_uOffset; /** This value is \c true if the central directory is physically present in the archive; \c false otherwise. */ bool m_bInArchive; private: friend class CZipCentralDir; void Init() { m_iReference = 1; #ifdef ZIP_ARCHIVE_USE_LOCKING m_mutex.Open(); #endif m_pCompare = GetCZipStrCompFunc(ZipPlatform::GetSystemCaseSensitivity()); m_bCaseSensitive = false; m_bFindFastEnabled = false; m_pszComment.Release(); // initialize ( necessary when using 64 bits - we are copying only 4 bytes in Read()) m_bInArchive = false; m_uEndOffset = 0; m_uLastVolume = 0; m_uVolumeWithCD = 0; m_uVolumeEntriesNo = 0; m_uEntriesNumber = 0; m_uSize = 0; m_uOffset = 0; } bool CheckIfOK_1() { return (m_uEndOffset >= m_uOffset + m_uSize); } ZIP_SIZE_TYPE CalculateBytesBeforeZip() { return m_uEndOffset - m_uSize - m_uOffset; } bool CheckIfOK_2() { return (m_uSize || !m_uEntriesNumber) && (m_uEntriesNumber || !m_uSize); } void DiskChange(ZIP_VOLUME_TYPE uCurrentVolume) { m_uLastVolume = uCurrentVolume; if (m_uEntriesNumber) { m_uVolumeEntriesNo = 0; } else { m_uVolumeWithCD = m_uLastVolume; m_uOffset = 0; } } /** Gets a value indicating if the current archive properties requires the Zip64 format. \return \c true, if the Zip64 is needed; \c false otherwise. \see 0610051629 */ bool NeedsZip64() const { return m_uLastVolume >= USHRT_MAX || m_uVolumeWithCD >= USHRT_MAX || m_uVolumeEntriesNo >= USHRT_MAX || m_uEntriesNumber >= USHRT_MAX || m_uSize >= UINT_MAX || m_uOffset >= UINT_MAX; } CZipAutoBuffer m_pszComment; ///< The global archive comment. /** The case-sensitivity of CZipCentralDir::m_pFindArray sorting. */ bool m_bCaseSensitive; /** The value set with the CZipCentralDir::EnableFindFast method. */ bool m_bFindFastEnabled; private: /** The method used in string comparisons. It is set depending on the current case-sensitivity. */ ZIPSTRINGCOMPARE m_pCompare; int m_iReference; #ifdef ZIP_ARCHIVE_USE_LOCKING ZipArchiveLib::CZipMutex m_mutex; #endif }; CZipCentralDir(); virtual ~CZipCentralDir(); static char m_gszSignature[]; ///< The End of Central Directory Record signature. static char m_gszSignature64Locator[]; ///< The Zip64 End of Central Directory Locator signature. CZipFileHeader* m_pOpenedFile; ///< It points to the currently opened file or it is \c NULL, if no file is opened. /** Initializes the object. \param pStorage The current storage to use. \param pCallbacks The current callbacks provider. \param pStringSettings The current string settings. \param pSource If not \c NULL, then it specifies the central directory for sharing. \note Throws exceptions. */ void Init(CZipStorage* pStorage, ZipArchiveLib::CZipCallbackProvider* pCallbacks, CZipStringStoreSettings* pStringSettings, CZipCentralDir* pSource = NULL); /** Reads the central directory from the archive. \param bExhaustiveRead \c true, if the exhaustive read should be performed, \c false otherwise. \note Throws exceptions. \see CZipArchive::SetExhaustiveRead */ void Read(bool bExhaustiveRead); /** Opens the file with the given index. \param uIndex A zero-based index of the file to open. \note Throws exceptions. */ void OpenFile(ZIP_INDEX_TYPE uIndex); /** Tests if the given file index is valid. \param uIndex A zero-based index to test. \return \c true, if the file with the given index exists inside the archive; \c false otherwise. */ bool IsValidIndex(ZIP_INDEX_TYPE uIndex)const; /** Removes the file header from the central directory. \param pHeader The header to remove. \param uIndex The index of the header to remove. Use \c ZIP_FILE_INDEX_UNSPECIFIED, if the index is not known. \param bShift If \c true, the data inside the archive is moved over the hole created after removing the file. If \c false, the unused area inside the archive remains. \note Throws exceptions. */ void RemoveFile(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex = ZIP_FILE_INDEX_UNSPECIFIED, bool bShift = true); /** Removes last file from the central directory. \param pHeader The header to remove. \param uIndex The index of the header to remove. Use \c ZIP_FILE_INDEX_UNSPECIFIED, if the index is not known. */ void RemoveLastFile(CZipFileHeader* pHeader = NULL, ZIP_INDEX_TYPE uIndex = ZIP_FILE_INDEX_UNSPECIFIED); /** Removes all files. \note Throws exceptions. */ void RemoveAll(); /** Closes the central directory. */ void Close(); /** Adds a new file to the central directory. \param header Used as a template for the data stored inside the archive. \param uReplaceIndex The index of the file to be replaced. Use \c ZIP_FILE_INDEX_UNSPECIFIED, if the index is not known. \param iLevel The compression level. \param bRichHeaderTemplateCopy \c true, if copy crc and sizes values from \a header; \c false otherwise. \return The new header. \note Throws exceptions. */ CZipFileHeader* AddNewFile(const CZipFileHeader & header, ZIP_INDEX_TYPE uReplaceIndex, int iLevel, bool bRichHeaderTemplateCopy = false); /** Removes physically the central directory from the archive. \note Throws exceptions. */ void RemoveFromDisk(); /** Gets the central directory size. \param bWhole If \c true, include the size of the file headers. If \c false, the size of the file headers is not included. \return The size of the central directory. \see CZipArchive::GetCentralDirSize */ ZIP_SIZE_TYPE GetSize(bool bWhole = false) const; /** Closes a file opened for reading inside the archive. \param skipCheckingDataDescriptor If \c true, the data descriptor that is located after the compressed data in the archive is checked for validity. Set this value to \c false after closing the file after an exception was thrown. \note Throws exceptions. */ void CloseFile(bool skipCheckingDataDescriptor = false); /** Closes a file opened for reading inside the archive. \note Throws exceptions. */ void CloseNewFile(); /** Writes the central directory to the archive. \note Throws exceptions. */ void Write(); /** Enables Find Fast. \see CZipArchive::EnableFindFast */ void EnableFindFast(bool bEnable, bool bCaseSensitive); /** Searches for the file. \see CZipArchive::FindFile */ ZIP_INDEX_TYPE FindFile(LPCTSTR lpszFileName, bool bCaseSensitive, bool bSporadically, bool bFileNameOnly); /** Gets the Find Fast index. \see CZipArchive::GetFindFastIndex */ ZIP_INDEX_TYPE GetFindFastIndex(ZIP_INDEX_TYPE uFindFastIndex)const { if (!IsValidIndex(uFindFastIndex) || !m_pInfo->m_bFindFastEnabled) return ZIP_FILE_INDEX_NOT_FOUND; return (*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)uFindFastIndex]->m_uIndex; } /** Points to CZipArchive::m_storage. */ CZipStorage* m_pStorage; /** Points to the current callback provider. */ ZipArchiveLib::CZipCallbackProvider* m_pCallbacks; /** Gets the information about the file with the given index. \see CZipArchive::operator[](ZIP_INDEX_TYPE) */ CZipFileHeader* operator[](ZIP_INDEX_TYPE uIndex) { return (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)uIndex]; } /** Gets the information about the file with the given index. \see CZipArchive::operator[](ZIP_INDEX_TYPE) const */ const CZipFileHeader* operator[](ZIP_INDEX_TYPE uIndex) const { return (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)uIndex]; } /** Gets the number of files in the archive. \return The number of files in the archive. */ ZIP_ARRAY_SIZE_TYPE GetCount() const { return m_pHeaders == NULL ? 0 : m_pHeaders->GetSize(); } /** Sets the global comment. \see CZipArchive::SetGlobalComment */ void SetComment(LPCTSTR lpszComment); /** Gets the global comment. \see CZipArchive::GetGlobalComment */ void GetComment(CZipString& szComment) const { ZipCompatibility::ConvertBufferToString(szComment, m_pInfo->m_pszComment, m_pStringSettings->m_uCommentCodePage); } /** Sets the file comment. \see CZipArchive::SetFileComment */ bool SetFileComment(ZIP_INDEX_TYPE uIndex, LPCTSTR lpszComment); /** Finds the index of the file with the given name. \param lpszFileName The name of the file to find. \return The index in CZipCentralDir::m_pFindArray with the corresponding CZipFindFast structure or \c ZIP_FILE_INDEX_NOT_FOUND, if there is no such file with the given name. \see CZipArchive::FindFile */ ZIP_INDEX_TYPE FindFileNameIndex(LPCTSTR lpszFileName) const; /** Gets the information about the central directory. \see CZipArchive::GetCentralDirInfo */ void GetInfo(CInfo& info) const {info = *m_pInfo;} /** Gets a value indicating whether the Find Fast feature is enabled or not. \return The value of CInfo::m_bFindFastEnabled. */ bool IsFindFastEnabled(){return m_pInfo->m_bFindFastEnabled;} /** Rebuilds the CZipCentralDir::m_pFindArray array. */ void RebuildFindFastArray() { if (m_pInfo->m_bFindFastEnabled) BuildFindFastArray(m_pInfo->m_bCaseSensitive); } /** The current string store settings. \see SetStringStoreSettings */ CZipStringStoreSettings* m_pStringSettings; /** Consistency checks to ignore. Can be one or more of the CZipArchive::ConsistencyCheck values. \see CZipArchive::SetIgnoredConsistencyChecks */ int m_iIgnoredChecks; /** Checks if the specified consistency check should be performed or not. \param iLevel The level to check. Can be one or more of CZipArchive::ConsistencyCheck values. \return \c true, if the specified check should be performed; \c false otherwise. \see m_iIgnoredChecks */ bool IsConsistencyCheckOn(int iLevel) { // check, if not ignored return (m_iIgnoredChecks & iLevel) == 0; } protected: #if _MSC_VER > 1000 #pragma warning( push ) #pragma warning (disable : 4702) // unreachable code #endif /** The method used in comparison when sorting headers. */ static int CompareHeaders(const void *pArg1, const void *pArg2) { CZipFileHeader* pw1 = *(CZipFileHeader**)pArg1; CZipFileHeader* pw2 = *(CZipFileHeader**)pArg2; if (pw1 == pw2) return 0; if (pw1->m_uVolumeStart == pw2->m_uVolumeStart) { if (pw1->m_uOffset < pw2->m_uOffset) return -1; else if (pw1->m_uOffset > pw2->m_uOffset) return 1; ASSERT(FALSE); // two files with the same offsets in the same volume??? CZipException::Throw(CZipException::badZipFile); return 0; // just for the compiler comfort (and discomfort of another) } else if (pw1->m_uVolumeStart < pw2->m_uVolumeStart) return -1; else // if (pw1->m_uVolumeStart > pw2->m_uVolumeStart) return 1; } #if _MSC_VER > 1000 #pragma warning( pop ) #endif static int CompareFindFastCollate(const void* pArg1, const void* pArg2) { CZipFindFast* pHeader1 = *(CZipFindFast**)pArg1; CZipFindFast* pHeader2 = *(CZipFindFast**)pArg2; return pHeader1->m_pHeader->GetFileName().Collate(pHeader2->m_pHeader->GetFileName()); } static int CompareFindFastCollateNoCase(const void* pArg1, const void* pArg2) { CZipFindFast* pHeader1 = *(CZipFindFast**)pArg1; CZipFindFast* pHeader2 = *(CZipFindFast**)pArg2; return pHeader1->m_pHeader->GetFileName().CollateNoCase(pHeader2->m_pHeader->GetFileName()); } /** Holds the information about all the files inside the archive. \see CZipFileHeader */ CZipArray* m_pHeaders; /** Builds the CZipCentralDir::m_pFindArray array. */ void BuildFindFastArray( bool bCaseSensitive ); void ClearFindFastArray() { ZIP_ARRAY_SIZE_TYPE uCount = m_pFindArray->GetSize(); for (ZIP_ARRAY_SIZE_TYPE i = 0; i < uCount; i++) delete (*m_pFindArray)[i]; m_pFindArray->RemoveAll(); } /** The Find Fast array. \see CZipFindFast \see CInfo::m_bFindFastEnabled \see CZipArchive::FindFile */ CZipArray* m_pFindArray; /** The method used in comparison involving the Find Fast feature. \param lpszFileName The name of the file. \param uIndex The index from the CZipCentralDir::m_pFindArray array. \return The return value has the following meaning: - 0 if the filenames are the same - < 0 if the filename stored in the array is less than \a lpszFileName - > 0 if the filename stored in the array is greater than \a lpszFileName */ int CompareElement(LPCTSTR lpszFileName, ZIP_INDEX_TYPE uIndex) const { return ((*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)uIndex]->m_pHeader->GetFileName().*(m_pInfo->m_pCompare))(lpszFileName); } /** Inserts a new CZipFindFast element to the CZipCentralDir::m_pFindArray array Initializes the CZipFindFast object with \a pHeader and \a uIndex values. \param pHeader The element to insert. \param uIndex The original index of \a pHeader in the central directory. If set to \c ZIP_FILE_INDEX_UNSPECIFIED, it is assumed to be the last element. \return The index in the CZipCentralDir::m_pFindArray array. */ ZIP_INDEX_TYPE InsertFindFastElement(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex); /** The central directory information. \see CInfo */ CInfo* m_pInfo; /** Reads file headers from the archive. \param bExhaustiveRead \c true, if the exhaustive read should be performed, \c false otherwise. \note Throws exceptions. \see CZipArchive::SetExhaustiveRead */ void ReadHeaders(bool bExhaustiveRead); /** Frees the memory allocated for the CZipFileHeader structures. */ void RemoveHeaders(); /** Removes data descriptors from a segmented archive that turned out to be one-segment only. It is not called for encrypted files. \param bFromBuffer If \c true, removes from the write buffer in memory otherwise from the file on the disk. \return \c false, if the file mapping to memory was not successful (can happen only when \a bFromBuffer is \c false); \c true otherwise. \note Throws exceptions. */ bool RemoveDataDescr(bool bFromBuffer); /** Writes the file headers to the archive. \note Throws exceptions. */ void WriteHeaders(bool bOneDisk); /** Writes the End of Central Directory Record. \return The size of the record. \note Throws exceptions. */ void WriteCentralEnd(); /** Throws an exception with the given code. */ void ThrowError(int err) const; /** Creates data that can be shared between different archive objects. \see DestroySharedData */ void CreateSharedData(); /** Destroys data shared between different archive objects, if the usage reference count of the data is zero. \note Throws exceptions. \see CreateSharedData */ void DestroySharedData(); #ifdef ZIP_ARCHIVE_USE_LOCKING /** Locks the access to the shared data. \note Throws exceptions. \see UnlockAccess \see CreateSharedData */ void LockAccess() { ASSERT(m_pInfo); m_pInfo->m_mutex.Lock(); } /** Unlocks the access to the shared data. \note Throws exceptions. \see LockAccess \see CreateSharedData */ void UnlockAccess() { if (m_pInfo) m_pInfo->m_mutex.Unlock(); } #endif }; #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning (pop) #endif #endif // !defined(ZIPARCHIVE_ZIPCENTRALDIR_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/BytesWriter.h0000644000175000017500000001041511300022650021466 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file BytesWriter.h * Includes the ZipArchiveLib::CBytesWriter class. * */ #if !defined(ZIPARCHIVE_BYTESWRITER_DOT_H) #define ZIPARCHIVE_BYTESWRITER_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "ZipCompatibility.h" namespace ZipArchiveLib { /** Provides implementation for various buffer operations depending on the current platform and configuration. */ class ZIP_API CBytesWriter { public: #ifdef ZIP_ARCHIVE_LITTLE_ENDIAN /** Reads \a iCount bytes from \a pSource into \a pDestination. \param[out] pDestination The buffer to retrieve data with byte-ordering depending on the machine. \param[in] pSource The buffer with little-endian ordered data. \param iCount The number of bytes to read. */ static void ReadBytes(WORD& uDestination, const char* pSource, int iCount = 2) { uDestination = 0; memcpy(&uDestination, pSource, iCount); } static void ReadBytes(DWORD& uDestination, const char* pSource, int iCount = 4) { uDestination = 0; memcpy(&uDestination, pSource, iCount); } #ifndef _ZIP_STRICT_U16 static void ReadBytes(int& iDestination, const char* pSource, int iCount) { iDestination = 0; memcpy(&iDestination, pSource, iCount); } #endif /** Writes \a iCount bytes from \a pSource into \a pDestination. \param[out] pDestination The buffer to retrieve little-endian ordered data. \param[in] pSource The buffer with byte-ordering depending on the machine. \param iCount The number of bytes to write. */ static void WriteBytes(char* pDestination, WORD uSource) { memcpy(pDestination, &uSource, 2); } static void WriteBytes(char* pDestination, DWORD uSource, int iCount = 4) { memcpy(pDestination, &uSource, iCount); } #ifndef _ZIP_STRICT_U16 static void WriteBytes(char* pDestination, int uSource, int iCount) { memcpy(pDestination, &uSource, iCount); } #endif #else static void ReadBytes(char* pDestination, const char* pSource, int iDestSize, int iCount) { int i = iCount - iDestSize; while (i < 0) { *pDestination++ = 0; i++; } for (; i < iCount; i++) (pDestination)[i] = pSource[iCount - i - 1]; } static void ReadBytes(WORD& uDestination, const char* pSource, int iCount = 2) { ReadBytes((char*)&uDestination, pSource, 2, iCount); } static void ReadBytes(DWORD& uDestination, const char* pSource, int iCount = 4) { ReadBytes((char*)&uDestination, pSource, 4, iCount); } #ifndef _ZIP_STRICT_U16 static void ReadBytes(int& iDestination, const char* pSource, int iCount) { ReadBytes((char*)&iDestination, pSource, sizeof(int), iCount); } #endif static void WriteBytes(char* pDestination, WORD uSource) { for (int i = 0; i < 2; i++) pDestination[i] = ((char*)&uSource)[2 - i - 1]; } static void WriteBytes(char* pDestination, DWORD uSource, int iCount = 4) { for (int i = 0; i < iCount; i++) pDestination[i] = ((char*)&uSource)[4 - i - 1]; } #ifndef _ZIP_STRICT_U16 static void WriteBytes(char* pDestination, int iSource, int iCount) { for (int i = 0; i < iCount; i++) pDestination[i] = ((char*)&iSource)[sizeof(int) - i - 1]; } #endif #endif static DWORD WriteSafeU32(DWORD uValue) { return uValue; } #ifdef _ZIP_STRICT_U16 static WORD WriteSafeU16(WORD uValue) { return uValue; } #else static WORD WriteSafeU16(int uValue) { return (WORD)uValue; } #endif }; } #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipArchive.h0000644000175000017500000030727111300022650021260 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// // Check the site http://www.artpol-software.com for the updated version of the library. // // The following information files are distributed along with this library: // License.txt - licensing information // Appnote.txt - details on the zip format // ( also available at ftp://ftp.pkware.com/appnote.zip) // /** * \file ZipArchive.h * Includes the CZipArchive class. * */ #if !defined(ZIPARCHIVE_ZIPARCHIVE_DOT_H) #define ZIPARCHIVE_ZIPARCHIVE_DOT_H #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning (push) #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class #pragma warning( disable : 4275 ) // non dll-interface class used as base for dll-interface #endif #include "_features.h" #include "ZipException.h" #include "ZipAutoBuffer.h" #include "ZipCentralDir.h" #include "ZipStorage.h" #include "ZipPathComponent.h" #include "ZipString.h" #include "ZipExport.h" #include "ZipCryptograph.h" #include "FileFilter.h" #include "DirEnumerator.h" #include "ZipCompressor.h" #include "ZipCallbackProvider.h" #define ZIP_AUTODETECT_VOLUME_SIZE ZIP_SIZE_TYPE(-1) /** The structure used as a parameter in CZipArchive::AddNewFile(CZipAddNewFileInfo& ). Use one of the provided constructors and then adjust the member variables as needed. \see 0610231446|simple */ struct ZIP_API CZipAddNewFileInfo { /** Initializes a new instance of the CZipAddNewFileInfo class. \param lpszFilePath Sets #m_szFilePath. \param bFullPath Sets #m_bFullPath. */ CZipAddNewFileInfo(LPCTSTR lpszFilePath, bool bFullPath = true) : m_szFilePath(lpszFilePath),m_bFullPath(bFullPath) { m_pFile = NULL; Defaults(); } /** Initializes a new instance of the CZipAddNewFileInfo class. \param lpszFilePath Sets #m_szFilePath. \param lpszFileNameInZip Sets #m_szFileNameInZip. */ CZipAddNewFileInfo(LPCTSTR lpszFilePath, LPCTSTR lpszFileNameInZip) : m_szFilePath(lpszFilePath), m_szFileNameInZip(lpszFileNameInZip) { m_pFile = NULL; Defaults(); } /** Initializes a new instance of the CZipAddNewFileInfo class. \param pFile Sets #m_pFile. \param lpszFileNameInZip Sets #m_szFileNameInZip. */ CZipAddNewFileInfo(CZipAbstractFile* pFile, LPCTSTR lpszFileNameInZip) : m_pFile(pFile), m_szFileNameInZip(lpszFileNameInZip) { Defaults(); } /** Initialize this field to set the source data for compression to be taken from the \c CZipAbstractFile object (such as \c CZipMemFile) instead of from a physical file. \note - You have to leave #m_szFilePath empty if you set #m_pFile to not \c NULL. - The time of a file in zip will be set to the current time, and the attributes to the default file attributes (depending on the system). - You cannot add directories this way. */ CZipAbstractFile* m_pFile; /** The full path to the file to be added. If it is empty, you need to initialize #m_pFile. If #m_bFullPath is \c true and the path contains a drive letter, the drive letter is removed unless CZipArchive::m_bRemoveDriveLetter is set to \c false. */ CZipString m_szFilePath; /** The file name that will be stored in the archive. If the file is a directory, there will be a path separator automatically appended. The CZipArchive::SetRootPath method has no effect on this parameter. */ CZipString m_szFileNameInZip; /** It has only the meaning when CZipAddNewFileInfo::m_szFileNameInZip is not specified and CZipAddNewFileInfo::m_szFilePath is not empty. - If set to \c true, instructs to store the full path of the file inside the archive, even if CZipArchive::m_szRootPath is set. - If set to \c false only a filename without a path is stored in the archive. In this case, if CZipArchive::m_szRootPath is set previously with CZipArchive::SetRootPath, and if the beginning of #m_szFilePath equals CZipArchive::m_szRootPath, then the filename is set to the not matched part of #m_szFilePath (you could say to #m_szFilePath minus CZipArchive::m_szRootPath). */ bool m_bFullPath; /** The level of compression. You can use values from 0 to 9 and -1 (meaning the default compression) or one of the CZipCompressor::CompressionLevel values. */ int m_iComprLevel; /** The smartness level of the file adding process. Can be one or combined CZipArchive::Smartness values (you can use the logical \c OR). */ int m_iSmartLevel; /** The index of an existing file in the archive to be replaced by the file being added. See 0610231944|replace for more information. The meaning of its values is as follows: - >= 0 : the index of the file to be replaced. - \c ZIP_FILE_INDEX_UNSPECIFIED : do not replace any file and add the new file at the end of the archive (default). Use this value in segmented archives. \note - If you use an invalid index, the action will fail. - If you specify the last file in the archive to be replaced, it'll be removed and the usual action will be taken. \see CZipArchive::SetAdvanced \see CZipArchive::WillBeDuplicated */ ZIP_INDEX_TYPE m_uReplaceIndex; /** The size of the buffer used while file operations. */ unsigned long m_nBufSize; /** Sets default values for #m_iSmartLevel, #m_uReplaceIndex, #m_nBufSize and #m_iComprLevel. Examine the source code for the current values. */ void Defaults(); }; /// /// Represents a zip archive file. /// class ZIP_API CZipArchive { public: static const char m_gszCopyright[]; static const char m_gszVersion[]; CZipArchive(); virtual ~CZipArchive(); /** Sets a password for the file to be opened or created. Use this method before opening or adding a file, but after opening the archive. The password is cleared during opening the archive. For the encryption to work, encryption method must be set to other value than CZipCryptograph::encNone. \param lpszPassword The password. Set it to \c NULL or an empty string to clear the password. \return \c false if the password cannot be changed at this time; \c true otherwise. \see 0610201627 \see SetEncryptionMethod \see WillEncryptNextFile */ bool SetPassword(LPCTSTR lpszPassword = NULL); /** Gets the current archive password or an empty string if there is no password set. \return The current password. \see SetPassword */ CZipString GetPassword()const ; /** Returns the value indicating whether the next file will be encrypted or not. To encrypt a file, a password must be set with the #SetPassword method and an encryption method must be set to a value different from CZipCryptograph::encNone. \return \c true, if the next file added to the archive will be encrypted; \c false otherwise. \see 0610201627 \see SetEncryptionMethod \see GetEncryptionMethod \see SetPassword \see GetPassword */ bool WillEncryptNextFile() const { return m_pszPassword.GetSize() != 0 && m_iEncryptionMethod != CZipCryptograph::encNone; } /** Sets the encryption method when encrypting files. You can encrypt different files using different methods. You need to set the password with the #SetPassword method for the encryption to work. It is important to set the encryption method only when compressing. When decompressing, the encryption method will be detected automatically. \param iEncryptionMethod One of the CZipCryptograph::EncryptionMethod values. \return \c false if selected encryption method is not supported or a file is opened for compression; \c true otherwise. \see 0610201627 \see SetPassword \see CZipCryptograph::EncryptionMethod \see GetEncryptionMethod \see WillEncryptNextFile */ bool SetEncryptionMethod(int iEncryptionMethod = CZipCryptograph::encStandard); /** Gets the current encryption method. \return One of CZipCryptograph::EncryptionMethod values. \see SetEncryptionMethod \see WillEncryptNextFile */ int GetEncryptionMethod() const { return m_iEncryptionMethod; } /** Encrypts an existing file with a given index using the current encryption method. \param uIndex The index of the file to encrypt. \return \c false, if the file could not be encrypted; \c true otherwise. \note - The method will not encrypt a file, if it already is encrypted. - Calls the CZipActionCallback::cbEncryptPrepare, CZipActionCallback::cbMultiEncrypt, CZipActionCallback::cbEncryptMoveData and CZipActionCallback::cbEncrypt callbacks. - Throws exceptions. \see 0610201627|existing \see SetEncryptionMethod \see SetPassword \see WillEncryptNextFile \see EncryptFiles \see EncryptAllFiles */ bool EncryptFile(ZIP_INDEX_TYPE uIndex) { CZipIndexesArray aIndexes; aIndexes.Add(uIndex); return EncryptFilesInternal(&aIndexes); } /** Encrypts existing files with given indexes using the current encryption method. \param aIndexes The indexes of files to encrypt. \return \c false, if the files could not be encrypted; \c true otherwise. \note - The method will not encrypt files that are already encrypted. - Calls the CZipActionCallback::cbEncryptPrepare, CZipActionCallback::cbMultiEncrypt, CZipActionCallback::cbEncryptMoveData and CZipActionCallback::cbEncrypt callbacks. - Throws exceptions. \see 0610201627|existing \see SetEncryptionMethod \see SetPassword \see WillEncryptNextFile \see EncryptFile \see EncryptAllFiles */ bool EncryptFiles(CZipIndexesArray &aIndexes) { return EncryptFilesInternal(&aIndexes); } /** Encrypts all existing files in the archive using the current encryption method. \return \c false, if the files could not be encrypted; \c true otherwise. \note - The method will not encrypt files that are already encrypted. - Calls the CZipActionCallback::cbEncryptPrepare, CZipActionCallback::cbMultiEncrypt, CZipActionCallback::cbEncryptMoveData and CZipActionCallback::cbEncrypt callbacks. - Throws exceptions. \see 0610201627|existing \see SetEncryptionMethod \see SetPassword \see WillEncryptNextFile \see EncryptFile \see EncryptFiles */ bool EncryptAllFiles() { return EncryptFilesInternal(NULL); } /** Sets the compression method used when compressing file. If affects the files that are added to the archive after calling this method. \param uCompressionMethod The compression method to use. Valid values are CZipCompressor::methodDeflate and CZipCompressor::methodBzip2. To store files (without compression), use the CZipCompressor::levelStore compression level when adding files to the archive. \return \c true, if the compression method is supported by the ZipArchive Library and was successfully set; \c false otherwise. \note The compression method used for extraction is automatically determined from the information written in the archive. \see 0610231446|methods \see CZipCompressor::IsCompressionSupported \see GetCompressionMethod \see GetCurrentCompressor */ bool SetCompressionMethod(WORD uCompressionMethod = CZipCompressor::methodDeflate); /** Returns the current compression method used when adding files to the archive. \return The current compression method. Is one of the CZipCompressor::CompressionMethod values. \see SetCompressionMethod */ WORD GetCompressionMethod() const { return m_uCompressionMethod; } /** Sets the compression options for an appropriate compressor. The library automatically detects to which compressor the options apply by examining the return value from the CZipCompressor::COptions::GetType() method. If a file is currently opened for compression or decompression, the options will have no effect on the current file processing. A sample that illustrates setting options can be found at 0610231446|options. \param pOptions The options to set. The \c NULL value has no effect. The object is no longer needed and can be safely released after this method returns. \see 0610231446|options \see GetCurrentCompressor \see CZipCompressor::GetOptions \see SetAdvanced */ void SetCompressionOptions(CZipCompressor::COptions* pOptions) { if (m_iFileOpened) { ZIPTRACE("%s(%i) : The options will have no effect on the current file processing.\n"); } m_compressorsOptions.Set(pOptions); } /** Sets the internal buffer sizes. No buffer size can be set smaller than 1024. Use this method before opening the archive. The optimal size for the write buffer for a segmented archive is the size of the volume. \param iWriteBuffer The write buffer size. See also CZipStorage::m_iWriteBufferSize. \param iGeneralBuffer A helper buffer used in moving data, deleting, getting (#GetFromArchive) files, renaming and replacing. This buffer is not used for compression and decompression. For these purposes, use the CZipCompressor::COptions::m_iBufferSize option. \param iSearchBuffer A buffer used in searching for the central directory. See also CZipStorage::m_iLocateBufferSize. \see GetAdvanced \see SetCompressionOptions */ void SetAdvanced(int iWriteBuffer = 65536, int iGeneralBuffer = 65536, int iSearchBuffer = 32768); /** Retrieves buffer sizes as set with the SetAdvanced() method. \param piWriteBuffer \param piGeneralBuffer \param piSearchBuffer \see SetAdvanced */ void GetAdvanced(int* piWriteBuffer = NULL, int* piGeneralBuffer = NULL, int* piSearchBuffer= NULL) { if (piWriteBuffer) *piWriteBuffer = m_storage.m_iWriteBufferSize; if (piGeneralBuffer) *piGeneralBuffer = m_iBufferSize; if (piSearchBuffer) *piSearchBuffer = m_storage.m_iLocateBufferSize; } /** Registers the callback object to receive specified notifications. \param pCallback The callback object to receive notifications. Set it to \c NULL to stop receiving the selected notifications. \param iWhich The callback type to register for (or unregister from). Can be one or more of the CZipActionCallback::CallbackType values. \see 0610231200 \see CZipActionCallback \see CZipActionCallback::CallbackType \see GetCallback */ void SetCallback(CZipActionCallback* pCallback = NULL, int iWhich = CZipActionCallback::cbAll) { m_callbacks.Set(pCallback, iWhich); } /** Gets the callback object registered for a given notification. \param iWhich The callback type. Can be one or more of CZipActionCallback::CallbackType values. \return The callback object set previously with #SetCallback. \see 0610231200 \see SetCallback \see CZipActionCallback \see CZipActionCallback::CallbackType */ CZipActionCallback* GetCallback(CZipActionCallback::CallbackType iWhich) { return m_callbacks.Get(iWhich); } /** The type of the callback object used during changing volumes in a segmented archive. \see CZipArchive::SetSegmCallback */ enum SegmCallbackType { scSpan = 0x01, ///< The callback object will be set for operations on spanned archives only. scSplit = 0x02, ///< The callback object will be set for operations on split archives only. scAll = scSpan | scSplit ///< The callback object will be set for operations spanned and split archives. }; /** Sets the callback object used during operations on a segmented archive to change volumes in spanned and split archives. Set it before opening the archive. If you open a spanned archive and don't set the callback object, the exception CZipException::noCallback will be thrown. Setting the callback object is not required for a split archive. Callback object's method CZipSegmCallback::Callback is called when the next volume is processed in a segmented archive. Calling CZipArchive methods from inside this method may result in an unexpected behavior. \param pCallback The address of the callback object. Set it to \c NULL to clear the callback. \param callbackType The type of the callback to set. It can be one of the #SegmCallbackType values. \see 0610051553 \see CZipSegmCallback */ void SetSegmCallback(CZipSegmCallback* pCallback = NULL, int callbackType = scSpan); /** Archive open modes used in the CZipArchive::Open(LPCTSTR, int, ZIP_SIZE_TYPE) and CZipArchive::Open(CZipAbstractFile&, int ) methods. */ enum OpenMode { zipOpen, ///< Opens an existing archive. zipOpenReadOnly, ///< Opens an existing archive as a read only file. This mode is intended to use in a self extract code, when opening an archive on a storage without the write access (e.g. CD-ROMS) or when sharing the central directory (see OpenFrom()). If you try to modify the archive in this mode, an exception will be thrown. zipCreate, ///< Creates a new archive. zipCreateSegm, ///< Creates a segmented archive. zipCreateAppend ///< Creates a new archive, but allows appending the archive to an existing file (which can be for example a self-extracting stub). }; /** Opens or creates a zip archive. The archive creation mode depends on the \a iMode and \a uVolumesSize values: - If \a iMode == #zipCreateSegm and \a uVolumeSize is \c ZIP_AUTODETECT_VOLUME_SIZE then a spanned archive is created. - If \a iMode == #zipCreateSegm and \a uVolumeSize > 0 then a split archive is created. - If \a iMode == #zipOpen or \a iMode == #zipOpenReadOnly and the existing archive is a segmented archive then CZipStorage::spannedArchive mode is assumed if the archive is on a removable device or CZipStorage::splitArchive otherwise. If you want to open a split archive on a removable device, set \a uVolumeSize to a value different from 0 (under Linux, the device is always assumed to be removable due to lack of implementation of the ZipPlatform::IsDriveRemovable method). - If \a iMode == #zipCreate or a \a iMode == #zipCreateAppend then \a uVolumeSize doesn't matter. \param szPathName The path to the archive. \param iMode Can be one of the #OpenMode values. \param uVolumeSize The volume size in a split archive. The size of the volume may be from 1 to 4,294,967,295. The bigger this value is - the faster is creation and extraction of segmented archives, because there are no volume changes. \return \c true, if the archive was opened successfully; \c false, if the archive was already opened before. \note Throws exceptions. \see 0610231446 \see 0610241003 \see 0610051553 \see Open(CZipAbstractFile&, int); \see GetSegmMode */ bool Open(LPCTSTR szPathName, int iMode = zipOpen, ZIP_SIZE_TYPE uVolumeSize = 0); /** Opens or creates an archive in memory. The CZipAbstractFile object is not closed after closing the archive, so that it is possible to work with it afterwards. \param af \c CZipAbstractFile object to store the archive data. \param iMode The open mode. The following values are valid: #zipOpen, #zipOpenReadOnly, #zipCreate, #zipCreateAppend. If you use #zipCreate, the contents of the memory file are cleared. Use #zipCreateAppend, if you want to append the archive at the end of the data contained in the memory file. \return \c true, if the archive was opened successfully; \c false, if the archive was already opened before or an invalid open mode was specified. \note Throws exceptions. \see 0610231924 \see Open(LPCTSTR, int, ZIP_SIZE_TYPE); */ bool Open(CZipAbstractFile& af, int iMode = zipOpen); /** Opens the archive from the already opened archive. Both archives will share the same central directory. The \a zip archive must be opened in read-only mode and the newly opened archive will open as read-only as well. \param zip The archive that provides the reference to the central directory. It must be a read-only archive and it cannot be in memory. \return \c true, if the new archive was successfully opened; \c false otherwise. \note If you use this method in a multithreaded environment, make sure that \c ZIP_ARCHIVE_USE_LOCKING is defined in the \e _features.h file. Also make sure, that \a zip stays open until this method returns. \note Throws exceptions. \see 0610241003|thread \see zipOpenReadOnly */ bool OpenFrom(CZipArchive& zip); /** Sets the path fragment to be removed from the beginning of the full path when adding or extracting a file. Use it, if you don't want to use the full path (by setting the \a bFullPath parameter in #AddNewFile or #ExtractFile to \c true) and you don't want to remove the whole path neither (be setting the same parameter to \c false), but you want to remove only a specific beginning. Use it after opening the archive and before calling the #AddNewFile or #ExtractFile methods. \param szPath The string that you want to be removed from the beginning of the path of the file in the archive. Set it to \c NULL stop removing the path beginning. \note Set the case-sensitivity with the #SetCaseSensitivity method. \see AddNewFile \see ExtractFile \see GetRootPath */ void SetRootPath(LPCTSTR szPath = NULL); /** Gets the value set previously with the SetRootPath() method. \return The current value of the #m_szRootPath field. \see SetRootPath */ CZipString GetRootPath()const { return m_szRootPath; } /** The levels of smartness of the adding files action (CZipArchive::AddNewFile). \note If you use #zipsmCheckForEff, you should use #zipsmNotCompSmall as well, because the small file will be surely larger after compression, so that you can add it not compressed straight away. The compression level is always ignored for a directory and set to 0. */ enum Smartness { zipsmLazy = 0x0000, ///< All the smartness options turned off. zipsmCPassDir = 0x0001, ///< Clears the password for directories. zipsmCPFile0 = 0x0002, ///< Clears the password for files of 0 size. /** Does not compress files smaller than 5 bytes - they are always stored larger than uncompressed. */ zipsmNotCompSmall = 0x0004, /** Checks whether the compressed file is larger than uncompressed and if so, remove it and store without the compression. In a segmented archive, a temporary file is used for that: if the file compression is efficient, the data is not compressed again, but moved from the temporary file to the archive. You can use the #SetTempPath method to set the path where the file will be created or you can let the library figure it out (see #SetTempPath). If the the library could not find enough free space for the temporary file, the compression goes the usual way. */ zipsmCheckForEff = 0x0008, /** Combine it with #zipsmCheckForEff or use #zipsmCheckForEffInMem, the temporary file will be created in memory then. This flag is effective also when replacing files (see the note at CZipAddNewFileInfo::m_uReplaceIndex). */ zipsmMemoryFlag = 0x0010, /** The same as #zipsmCheckForEff, but the temporary file is created created in memory instead. It has the meaning only in a segmented archive, not segmented archives don't need a temporary file. */ zipsmCheckForEffInMem = zipsmMemoryFlag | zipsmCheckForEff, zipsmSmartPass = zipsmCPassDir | zipsmCPFile0, ///< The password policy (a combination of #zipsmCPassDir and #zipsmCPFile0). zipsmSmartAdd = zipsmNotCompSmall | zipsmCheckForEff, ///< Smart adding (a combination of #zipsmNotCompSmall and #zipsmCheckForEff). zipsmSafeSmart = zipsmSmartPass | zipsmNotCompSmall, ///< Safe smart (smartest without checking for efficiency). zipsmSmartest = zipsmSmartPass | zipsmSmartAdd, ///< Smartness at its best. zipsmInternal01 = 0xf000 ///< Intended for the internal use only. }; /** Adds a new file to the opened archive. \param info See CZipAddNewFileInfo for more information. \return If \c false then the file was not added (in this case, you can still try to add other files); \c true otherwise. \note - If you abort the operation from a callback object, while adding a file in a not segmented archive, the added data will be removed from the archive. - Throws exceptions. When an exception is thrown, you may need to call #CloseNewFile with \a bAfterException set to \c true, to make the archive reusable. \see 0610231446 \see 0610231200 \see 0610231924 \see AddNewFile(LPCTSTR, LPCTSTR, int, int, unsigned long) \see AddNewFile(LPCTSTR, int, bool, int, unsigned long) \see AddNewFile(CZipMemFile&, LPCTSTR, int, int, unsigned long) \see AddNewFiles(LPCTSTR, ZipArchiveLib::CFileFilter&, bool, int, bool, int, unsigned long) \see AddNewFiles(LPCTSTR, LPCTSTR, bool, int, bool, int, unsigned long) \see SetCallback */ bool AddNewFile(CZipAddNewFileInfo& info); /** Adds a new file to the opened archive. See the #AddNewFile(CZipAddNewFileInfo& ) method. The parameters are equivalent to CZipAddNewFileInfo member variables. */ bool AddNewFile(LPCTSTR lpszFilePath, int iComprLevel = -1, bool bFullPath = true, int iSmartLevel = zipsmSafeSmart, unsigned long nBufSize = 65536); /** Adds a new file to the opened archive. See the #AddNewFile(CZipAddNewFileInfo& ) method. The parameters are equivalent to CZipAddNewFileInfo member variables. */ bool AddNewFile(LPCTSTR lpszFilePath, LPCTSTR lpszFileNameInZip, int iComprLevel = -1, int iSmartLevel = zipsmSafeSmart, unsigned long nBufSize = 65536); /** Adds a new file to the opened archive. See the #AddNewFile(CZipAddNewFileInfo& ) method. The parameters are equivalent to CZipAddNewFileInfo member variables. */ bool AddNewFile(CZipMemFile& mf, LPCTSTR lpszFileNameInZip, int iComprLevel = -1, int iSmartLevel = zipsmSafeSmart, unsigned long nBufSize = 65536); /** Adds new files to the opened archive from the specified directory using a filter. \param lpszPath The root directory containing the files to add. \param filter A filter that determines which files should be added. \param bRecursive \c true, if the files from the subfolders of \a lpszPath should also be added; \c false otherwise. \param iComprLevel The level of compression. You can use values from 0 to 9 and -1 (meaning the default compression) or one of the CZipCompressor::CompressionLevel values. \param bSkipInitialPath \c true, if the \a lpszPath directory should be trimmed out of the paths stored in the archive; \c false otherwise. \param iSmartLevel The smartness level of the file adding process. Can be one or combined #Smartness values (you can use the logical \c OR). \param nBufSize The size of the buffer used while file operations. \return If \c false then some files were probably not added (in this case, you can still try to add other files); \c true otherwise. \note Throws exceptions. \see 0610231446|filters \see ZipArchiveLib::CFileFilter \see ZipArchiveLib::CNameFileFilter \see ZipArchiveLib::CGroupFileFilter \see AddNewFiles(LPCTSTR, LPCTSTR, bool, int, bool, int, unsigned long) \see AddNewFile(CZipAddNewFileInfo&) \see AddNewFile(LPCTSTR, LPCTSTR, int, int, unsigned long) \see AddNewFile(LPCTSTR, int, bool, int, unsigned long) \see AddNewFile(CZipMemFile&, LPCTSTR, int, int, unsigned long) */ bool AddNewFiles(LPCTSTR lpszPath, ZipArchiveLib::CFileFilter& filter, bool bRecursive = true, int iComprLevel = -1, bool bSkipInitialPath = true, int iSmartLevel = zipsmSafeSmart, unsigned long nBufSize = 65536); /** Adds new files to the opened archive from the specified directory using a filename mask. \param lpszPath The root directory containing the files to add. \param lpszFileMask The filename mask to filter the files. Only files that has a filename matching this mask will be added to the archive. This method internally uses ZipArchiveLib::CNameFileFilter. \param bRecursive \c true, if the files from the subfolders of \a lpszPath should also be added; \c false otherwise. \param iComprLevel The level of compression. You can use values from 0 to 9 and -1 (meaning the default compression) or one of the CZipCompressor::CompressionLevel values. \param bSkipInitialPath \c true, if the \a lpszPath directory should be trimmed out of the paths stored in the archive; \c false otherwise. \param iSmartLevel The smartness level of the file adding process. Can be one or combined #Smartness values (you can use the logical \c OR). \param nBufSize The size of the buffer used while file operations. \return If \c false then some files were probably not added (in this case, you can still try to add other files); \c true otherwise. \note Throws exceptions. \see name: 0610242025|wildcards \see AddNewFiles(LPCTSTR, ZipArchiveLib::CFileFilter&, bool, int, bool, int, unsigned long) \see AddNewFile(CZipAddNewFileInfo&) \see AddNewFile(LPCTSTR, LPCTSTR, int, int, unsigned long) \see AddNewFile(LPCTSTR, int, bool, int, unsigned long) \see AddNewFile(CZipMemFile&, LPCTSTR, int, int, unsigned long) */ bool AddNewFiles(LPCTSTR lpszPath, LPCTSTR lpszFileMask = _T("*.*"), bool bRecursive = true, int iComprLevel = -1, bool bSkipInitialPath = true, int iSmartLevel = zipsmSafeSmart, unsigned long nBufSize = 65536) { ZipArchiveLib::CNameFileFilter filter(lpszFileMask); return AddNewFiles(lpszPath, filter, bRecursive, iComprLevel, bSkipInitialPath, iSmartLevel, nBufSize); } /** Adds a new file to the opened archive. The archive cannot be an existing (at the moment of opening the archive) segmented archive, because modifying such an archive is not possible with this version. \param header The structure that provides additional information about the added file and serves as a template for the properties of the new file. The following fields are used: \li CZipFileHeader::m_uModDate and CZipFileHeader::m_uModTime - the modification time. Use CZipFileHeader::SetTime to set them. If \a lpszFilePath is not \c NULL these fields are overwritten and updated automatically. \li CZipFileHeader::m_uExternalAttr - the attributes of the file. Use #SetFileHeaderAttr to set them. If \a lpszFilePath is not \c NULL this field is overwritten and updated automatically. \li \c CZipFileHeader::m_pszFileName - the filename (may be with a path) to be stored inside the archive to represent this file. Use CZipFileHeader::SetFileName to set it. \li CZipFileHeader::m_uLocalComprSize - predicted compressed size. Set it when using the Zip64 functionality and not using encryption or segmentation - you may set it to the size of the file that you want to compress. This is for prediction if the Zip64 extensions are needed, but you should not worry too much about setting this value, The ZipArchive Library will fix the headers if necessary - it just may save some processing. \li \c CZipFileHeader::m_pszComment - the file comment. Use CZipFileHeader::SetComment to set it. \li CZipFileHeader::m_aLocalExtraData - the local extra fields. \li CZipFileHeader::m_aCentralExtraData - the central extra fields. Other fields are ignored - they are updated automatically. If the method returns \c true, \link #SetSystemCompatibility system compatibility \endlink for this object is set to the correct value. Additionally if \a lpszFilePath was not \c NULL, the attributes and the time fields are filled with information retrieved from the file pointed by \a lpszFilePath. \param iLevel The level of compression. You can use values from 0 to 9 and -1 (meaning the default compression) or one of the CZipCompressor::CompressionLevel values. \param lpszFilePath The path to the file to retrieve the date stamp and attributes from. These values are stored inside the archive. \return \c false in the following cases: \li The \a lpszFilePath is not \c NULL and the file attributes and data was not correctly retrieved. \li A file is already opened for extraction or compression. \li The archive is an existing segmented archive. \li The maximum file count inside the archive has already been reached (65,535 for a standard archive and \c 0xFFFFFFFFFFFFFFFF for an archive in the Zip64 format). \c true otherwise. \note Throws exceptions. \see 0610231446|advanced \see 0610242300 \see WriteNewFile \see CloseNewFile */ bool OpenNewFile(CZipFileHeader& header, int iLevel = CZipCompressor::levelDefault, LPCTSTR lpszFilePath = NULL) { return OpenNewFile(header, iLevel, lpszFilePath, ZIP_FILE_INDEX_UNSPECIFIED); } /** Compresses the contents of the buffer and write it to a new file. \param pBuf The buffer containing the data to be compressed and written. \param uSize The number of bytes to be written from \a pBuf. \return \c false, if the new file hasn't been opened yet; \c true otherwise. \note Throws exceptions. \see 0610231446|advanced \see OpenNewFile \see CloseNewFile */ bool WriteNewFile(const void *pBuf, DWORD uSize); /** Closes the new file in the archive. \return \c false, if there is no new file opened; \c true otherwise. \param bAfterException If \c true, the new file will be closed without writing anything. Set it to \c true after an exception was thrown. Use it also this way if an exception other than CZipException::abortedSafely was thrown from one of the #AddNewFile methods. \note Throws exceptions. \see 0610231446|advanced \see OpenNewFile \see WriteNewFile */ bool CloseNewFile(bool bAfterException = false); /** Acquires a file with the given index from another archive. The compressed data of the file from another archive is copied to the current archive without decompression. \param zip The opened archive to get the file from (must not be a segmented archive). \param uIndex A zero-based index of the file to get from the \a zip archive. \param lpszNewFileName The new filename to replace the old one from the \a zip archive. Can be \c NULL to leave the filename the same. \param uReplaceIndex The same as CZipAddNewFileInfo::m_uReplaceIndex. Can be \c ZIP_FILE_INDEX_UNSPECIFIED. \param bKeepSystComp If \c false, then the system compatibility of the file from the \a zip archive is converted to the current archive system compatibility, if they differ. Otherwise the source system compatibility is copied. \return \c false, if the operation could not be performed (either of archives is closed, a file inside either of archives is opened, \a zip archive is segmented or the current archive is an existing segmented archive. \note This method will encrypt data, if an encryption method and a password are set and the file is not already encrypted. \note Throws exceptions. When an exception is thrown, you may need to call #CloseNewFile with \a bAfterException set to \c true, to make the archive reusable. \note It is safe to abort the action (by returning \c false from the CZipActionCallback::Callback) in a not segmented archive and when no replacing is taking place. The file that is not entirely added is removed from the archive then. \see 0610231446|get \see 0610231200 \see GetFromArchive(CZipArchive&, CZipIndexesArray&, bool) \see GetFromArchive(CZipArchive&, CZipStringArray&, bool) \see SetCallback \see SetAdvanced \see SetEncryptionMethod \see SetPassword */ bool GetFromArchive(CZipArchive& zip, ZIP_INDEX_TYPE uIndex, LPCTSTR lpszNewFileName = NULL, ZIP_INDEX_TYPE uReplaceIndex = ZIP_FILE_INDEX_UNSPECIFIED, bool bKeepSystComp = false) { InitBuffer(); bool bRet; try { bRet = GetFromArchive(zip, uIndex, lpszNewFileName, uReplaceIndex, bKeepSystComp, GetCallback(CZipActionCallback::cbGet)); } catch(...) { ReleaseBuffer(); throw; } ReleaseBuffer(); if (bRet && m_bAutoFlush) Flush(); return bRet; } /** Acquires files with the given indexes from another archive. The compressed data of the file from another archive is copied to the current archive without decompression. \param zip The opened archive to get the file from (must not be a segmented archive). \param aIndexes An array of zero-based indexes of the files to acquire from the \a zip archive. \param bKeepSystComp If \c false, then the system compatibility of the file from the \a zip archive is converted to the current archive system compatibility, if they differ. Otherwise the source system compatibility is copied. \return \c false, if the operation could not be performed (either of archives is closed, a file inside either of archives is opened, \a zip archive is segmented or the current archive is an existing segmented archive. \note This method will encrypt data, if an encryption method and a password are set and the file is not already encrypted. \note Throws exceptions. When an exception is thrown, you may need to call #CloseNewFile with \a bAfterException set to \c true, to make the archive reusable. \note It is safe to abort the action (by returning \c false from the CZipActionCallback::Callback) in a not segmented archive and when no replacing is taking place. The file that is not entirely added is removed from the archive then. \see 0610231446|get \see 0610231200 \see GetFromArchive(CZipArchive&, ZIP_INDEX_TYPE, LPCTSTR, ZIP_INDEX_TYPE, bool) \see GetFromArchive(CZipArchive&, CZipStringArray&, bool) \see SetCallback \see SetAdvanced \see SetEncryptionMethod \see SetPassword */ bool GetFromArchive(CZipArchive& zip, CZipIndexesArray &aIndexes, bool bKeepSystComp = false); /** Acquires files with the given names from another archive. The compressed data of the file from another archive is copied to the current archive without decompression. \param zip The opened archive to get the file from (must not be a segmented archive). \param aNames An array of filenames to acquire from the \a zip archive. \param bKeepSystComp If \c false, then the system compatibility of the file from the \a zip archive is converted to the current archive system compatibility, if they differ. Otherwise the source system compatibility is copied. \return \c false, if the operation could not be performed (either of archives is closed, a file inside either of archives is opened, \a zip archive is segmented or the current archive is an existing segmented archive. \note This method will encrypt data, if an encryption method and a password are set and the file is not already encrypted. \note Throws exceptions. When an exception is thrown, you may need to call #CloseNewFile with \a bAfterException set to \c true, to make the archive reusable. \note It is safe to abort the action (by returning \c false from the CZipActionCallback::Callback) in a not segmented archive and when no replacing is taking place. The file that is not entirely added is removed from the archive then. \note This method calls #GetIndexes on the \a zip archive. \see 0610231446|get \see 0610231200 \see GetFromArchive(CZipArchive&, ZIP_INDEX_TYPE, LPCTSTR, ZIP_INDEX_TYPE, bool) \see GetFromArchive(CZipArchive&, CZipIndexesArray&, bool) \see SetCallback \see SetAdvanced \see SetEncryptionMethod \see SetPassword */ bool GetFromArchive(CZipArchive& zip, CZipStringArray &aNames, bool bKeepSystComp = false) { CZipIndexesArray indexes; zip.GetIndexes(aNames, indexes); return GetFromArchive(zip, indexes, bKeepSystComp); } /** Gets indexes of the files with names stored in \a aNames and puts them into \a aIndexes. If a filename was not found, \c ZIP_FILE_INDEX_NOT_FOUND is inserted at the appropriate position in \a aIndexes. \param aNames An array of filenames inside the archive. \param aIndexes An array of indexes to be found. \note Use the #SetCaseSensitivity method to set case-sensitivity. \see 0610242025|findfast \see EnableFindFast */ void GetIndexes(const CZipStringArray &aNames, CZipIndexesArray& aIndexes); /** Extracts a file from the archive. The argument \a lpszNewName may point to a full path and is influenced by \a bFullPath. If \a lpszNewName contains a drive specification then the drive part is removed unless #m_bRemoveDriveLetter is set to \c false. \param uIndex The index of the file to extract. \param lpszPath The directory to extract the file to. May not be \c NULL. \param bFullPath In this paragraph the source path means: \li The full filename stored in the archive, if \a lpszNewName is \c NULL \li \a lpszNewName, if it is not \c NULL The meaning of \a bFullPath is following: \li If it is \c true, then the method extracts using the full source path, even if #m_szRootPath is set. In this case the resulting file path is \a lpszPath plus the source path. \li If it is \c false, then the destination file path is \a lpszPath plus the filename only extracted from the source path. In this case, if #m_szRootPath is set (with #SetRootPath), then before adding the source path to \a lpszPath, from the source path is removed the part that matches #m_szRootPath (matching is performed starting from the beginning of both strings). \param lpszNewName The new name of the file after extraction. If \c NULL, the original filename stored in the archive is used. May include a path information, but if \a bFullPath is \c false, only the filename is extracted from this value. \param pSeekPair If not NULL, the file will be extracted starting from the seek position described by this value. \param nBufSize The size of the buffer used while file operations. \return \c true if successful; \c false otherwise. \note - To extract files which filenames that match a specified pattern, use the #FindMatches method. - Throws exceptions. \see 0610241003 \see 0610231200 \see 0711101739 \see ExtractFile(ZIP_INDEX_TYPE, CZipMemFile&, bool, CZipCompressor::COffsetsPair*, DWORD) \see FindMatches \see SetCallback */ bool ExtractFile(ZIP_INDEX_TYPE uIndex, LPCTSTR lpszPath, bool bFullPath = true, LPCTSTR lpszNewName = NULL, DWORD nBufSize = 65536); /** The same as #ExtractFile(ZIP_INDEX_TYPE, LPCTSTR, bool, LPCTSTR, CZipCompressor::COffsetsPair*, DWORD ) but instead to a physical file, this method extracts data into a \c CZipMemFile object. \param uIndex The index of the file to extract. \param mf The memory file to receive the decompressed data. \param bRewind If \c true, the memory file pointer is positioned at the beginning of the compressed data after compression. The rewind operation is performed even if extraction was aborted, but rewinding will not take place, if other exception than CZipException::abortedAction or CZipException::abortedSafely was thrown in the meantime. \param pSeekPair If not NULL, the file will be extracted starting from the seek position described by this value. \param nBufSize The size of the buffer used while file operations. \note - Writing of the decompressed data starts at the current position of the memory file. Keep this in mind, when you pass a \c CZipMemFile object that already contains data (or has a buffer attached) - its contents may be overwritten. - If you try to extract a directory, the method will return \c false. \see 0610231924 \see 0711101739 \see ExtractFile(ZIP_INDEX_TYPE, LPCTSTR, bool, LPCTSTR, CZipCompressor::COffsetsPair*, DWORD ) */ bool ExtractFile(ZIP_INDEX_TYPE uIndex, CZipMemFile& mf, bool bRewind = true, DWORD nBufSize = 65536); /** Opens the file with the given index in the archive for extracting. Not successful opening of the file doesn't lock the whole archive, so you can try to open another one (after catching an exception, if it was thrown) \param uIndex The index of the file to open. \return \c true, if successful; \c false otherwise. This method will also return \c false, if the compression method of the file is not supported by the ZipArchive Library. \throws CZipException with the CZipException::badPassword code, if the file is encrypted and the password was not set. \see 0610241003|advanced \see ReadFile \see CloseFile */ bool OpenFile(ZIP_INDEX_TYPE uIndex); /** Reads data from the currently opened file and decompresses it to \a pBuf. \param pBuf The buffer to receive the decompressed data. \param uSize The size of \a pBuf. \return The number of bytes read. \see 0610241003|advanced \see OpenFile \see CloseFile \note Throws exceptions. */ DWORD ReadFile(void *pBuf, DWORD uSize); /** Closes the file opened for extraction in the archive and copy its date and attributes to the file pointed by \a lpszFilePath. \param lpszFilePath The path of the file to have the date and attributes information updated. Make sure you have the read access to this file. \param bAfterException Set it to \c true, when you call this method after an exception was thrown, to allow further operations on the archive. \return One of the following values: - \c 1 : The operation was successful. - \c 0 : There is no file opened. - \c -1 : Some bytes were left to uncompress - probably due to a bad password or a corrupted archive. - \c -2 : Setting extracted file date and attributes was not successful. \see 0610241003|advanced \see OpenFile \see ReadFile \see CloseFile(CZipFile&) \note Throws exceptions. */ int CloseFile(LPCTSTR lpszFilePath = NULL, bool bAfterException = false); /** Closes \a file and then calls the CloseFile(LPCTSTR, bool) method using the path of \a file as an argument. Don't call this method, if an exception was thrown before, call the #CloseFile(LPCTSTR, bool) method instead. \param file A \c CZipFile object of the extracted file. It must be opened. \return The same values as the #CloseFile(LPCTSTR, bool) method. \note Throws exceptions. \see 0610241003|advanced \see OpenFile \see ReadFile \see CloseFile(LPCTSTR, bool) */ int CloseFile(CZipFile &file); /** Tests the file with the given index for the integrity. The method throws exceptions but performs all the necessary cleanup before, so that the next file can be tested after catching the exception. \param uIndex The index of the file to test. \param uBufSize The size of the buffer used during extraction. \return \c false, if the incorrect action has been taken (when #OpenFile or #GetFileInfo returned \c false or \a uBufSize is 0); \c true otherwise. If the file didn't passed the test or there was a disk I/O error or the supplied password was incorrect, an exception is thrown. \note Throws exceptions. \see 0610241003 \see SetCallback */ bool TestFile(ZIP_INDEX_TYPE uIndex, DWORD uBufSize = 65536); /** Deletes the file with the given index from the archive. If you plan to delete more than one file, use the #RemoveFiles(CZipIndexesArray&) or #RemoveFiles(const CZipStringArray&) method. These methods are optimized for deleting multiple files. \param uIndex A zero-based index of the file to delete. \return \c false, if the file could not be removed; \c true otherwise. \note Throws exceptions. \see 0610231944|delete \see RemoveFiles(CZipIndexesArray&) \see RemoveFiles(const CZipStringArray&) \see SetCallback \see FindMatches */ bool RemoveFile(ZIP_INDEX_TYPE uIndex); /** Deletes files from the archive. Sorts \a aIndexes in the ascending order. \param aIndexes An array of zero-based indexes of the files to delete. \return \c false, if files could not be removed; \c true otherwise. \note - To remove files which filenames match a specified pattern, use the #FindMatches method before to find the indexes. - Throws exceptions. \see 0610231944|delete \see RemoveFile \see RemoveFiles(const CZipStringArray& ) \see SetCallback \see FindMatches */ bool RemoveFiles(CZipIndexesArray& aIndexes); /** Delete files from the archive. \param aNames An array of filenames to delete; \return \c false, if files could not be removed; \c true otherwise. \note - Use the #SetCaseSensitivity method to set case-sensitivity. - This method uses Find Fast (see 0610242025|findfast for more information). - Throws exceptions. \see 0610231944|delete \see RemoveFile \see RemoveFiles(CZipIndexesArray&) \see SetCallback \see EnableFindFast */ bool RemoveFiles(const CZipStringArray& aNames); /** Shifts data inside the archive to make an empty space at the beginning of the archive. Into this empty space, you can copy for example a self-extracting stub. To perform shifting, the archive must be opened and no file must be opened for compression or extraction. This method will not work with segmented archives or archives, for which #GetBytesBeforeZip method returns value different from \c 0. \param uOffset The number of bytes to shift the archive data by. \return \c true, if data was shifted successfully; \c false otherwise. \note - Calls the CZipActionCallback::cbMoveData callback. - Throws exceptions. \see 0610242241|convert \see PrependData(CZipAbstractFile&, LPCTSTR) \see PrependData(LPCTSTR, LPCTSTR) */ bool ShiftData(ZIP_SIZE_TYPE uOffset); /** Inserts data contained in the file pointed by the \a lpszFilePath path before the archive data. You can use this method for example to convert the archive into a self-extracting archive (store a self-extracting stub inside \a lpszFilePath file). To perform prepending, the archive must be opened and no file must be opened for compression or extraction. This method will not work with segmented archives or archives, for which #GetBytesBeforeZip method returns value different from \c 0. \param lpszFilePath The path of the file to prepend to the archive. \param lpszNewExt If it is not \c NULL, then the extension of the archive is changed to this value after prepending data. Under linux additionally, this method sets executable permission for the owner after prepeding. If renaming is performed, then the archive is closed before it. If this value is \c NULL, the no renaming is performed and the archive stays opened. \return \c true, if data from \a lpszFilePath file was prepended (and optionally renamed) successfully; \c false otherwise. \note - Calls the CZipActionCallback::cbMoveData callback. - Throws exceptions. \see 0610242241|convert \see ShiftData \see PrependData(CZipAbstractFile&, LPCTSTR) */ bool PrependData(LPCTSTR lpszFilePath, LPCTSTR lpszNewExt = #ifdef ZIP_ARCHIVE_WIN _T("exe") #else _T("") #endif ); /** Inserts data contained in the \a file before the archive data. You can use this method for example to convert the archive into a self-extracting archive (store a self-extracting stub inside \a file). To perform prepending, the archive must be opened and no file must be opened for compression or extraction. This method will not work with segmented archives or archives, for which #GetBytesBeforeZip method returns value different from \c 0. \param file The file containing data to insert before the archive data. The file should be opened. \param lpszNewExt If it is not \c NULL, then the extension of the archive is changed to this value after prepending data. Under linux additionally, this method sets executable permission for the owner after prepeding. If renaming is performed, then the archive is closed before it. If this value is \c NULL, the no renaming is performed and the archive stays opened \return \c true, if data from \a file was prepended successfully; \c false otherwise. \note - Calls the CZipActionCallback::cbMoveData callback. - Throws exceptions. \see 0610242241|convert \see ShiftData \see PrependData(LPCTSTR, LPCTSTR) */ bool PrependData(CZipAbstractFile& file, LPCTSTR lpszNewExt = NULL); /** Sets the global comment in the archive. \param lpszComment The comment to set. \return \c false, if the archive is closed or it is an existing segmented archive; \c true otherwise. \note Throws exceptions. \see 0610231944|comment \see GetGlobalComment */ bool SetGlobalComment(LPCTSTR lpszComment); /** Gets the global comment for the archive. \return The global comment or an empty string if the archive is closed. \see 0610231944|comment \see SetGlobalComment */ CZipString GetGlobalComment()const ; /** Sets the comment for the file with the given index. \param uIndex A zero-based index of the file. \param lpszComment The comment to set. \return \c false, if the comment change is impossible; \c true otherwise. \note Throws exceptions. \see 0610231944|comment \see GetFileComment */ bool SetFileComment(ZIP_INDEX_TYPE uIndex, LPCTSTR lpszComment); /** Gets the comment for the file with the given index. \param uIndex A zero-based index of the file. \return The file comment or an empty string, if the archive is closed. \see 0610231944|comment \see SetFileComment */ CZipString GetFileComment(ZIP_INDEX_TYPE uIndex) const { const CZipFileHeader* info = GetFileInfo(uIndex); return info == NULL ? CZipString(_T("")) : info->GetComment(); } /** Gets the path of the currently opened archive segment. \return The current segments' path or an empty string, if the archive is closed. \see 0610051553 */ CZipString GetArchivePath()const; /** Gets the archive volume number currently being processed. The first volume has the number 1. This method is useful while working with a segmented archive in creation to find out how many parts were already created. To find out how many parts are in an existing segmented archive, use the #GetCentralDirInfo method. \return A one-based number of the current volume or 0, if there is no current volume (the archive is closed). \see 0610051553 */ ZIP_VOLUME_TYPE GetCurrentVolume() const ; /** Gets the segmentation mode of the current archive. \return One of the following values: - \c -2 : An existing split archive. - \c -1 : An existing spanned archive. - \c 0 : No archive segmentation or one-volume only. - \c 1 : A spanned archive in creation. - \c 2 : A split archive in creation. \see 0610051553 */ int GetSegmMode()const { return m_storage.m_iSegmMode * m_storage.IsSegmented(); } /** Case-sensitivity values used as the \a iCaseSensitive argument in the FindFile() method. */ enum FFCaseSens { /** Uses the default case-sensitivity as set with the #SetCaseSensitivity method. If the Find Fast array was built before with a different case-sensitivity, it is rebuilt again, if it hasn't been built so far, it is built now with the default case-sensitivity. */ ffDefault, /** Performs a case-sensitive search. If the CZipArchive is non-case-sensitive, a less effective search is performed. It does not rebuild the Find Fast array, but if the array hasn't been built yet, it is built now as \b non-case-sensitive (you can use \c SetCaseSensitivity(true) and then #ffDefault to build it as case-sensitive). */ ffCaseSens, /** Performs a non-case-sensitive search. If the CZipArchive is case-sensitive, a less effective search is performed. It does not rebuild the Find Fast array, but if the array hasn't been built yet, it is build now as \b case-sensitive (you can use \c SetCaseSensitivity(false) and then #ffDefault to build it as non-case-sensitive). */ ffNoCaseSens }; /** Finds a file in the archive. This method enables the Find Fast feature, if it is not enabled already. \param lpszFileName The name of the file to be found in the archive. If the file in the archive is stored with the path information, you must specify it here or set \a bFileNameOnly to \c true. Use the same path separators as they are defined for your system as default (\e "\" for Windows and \e "/" for Unix/Linux). \param iCaseSensitive It can be one of the #FFCaseSens values. \param bFileNameOnly If \c true, the method tries to find a filename without a path (a less effective search is performed). If you wish to find a directory name, do not end it with a path separator. The path separator is required, if you set \a bFileNameOnly to \c false. \note Use the #SetCaseSensitivity method to set the global case-sensitivity. \return The index of the file, if the file was found; \c ZIP_FILE_INDEX_NOT_FOUND if the file was not found. \see 0610242025|findfast \see EnableFindFast */ ZIP_INDEX_TYPE FindFile(LPCTSTR lpszFileName, int iCaseSensitive = ffDefault, bool bFileNameOnly = false); /** Gets the information about the file with the given index. The data is copied to \a fhInfo. This may not be optimal for querying large number of file. To avoid copying data, see the #GetFileInfo(ZIP_INDEX_TYPE) method. \param fhInfo The object to receive data. \param uIndex A zero-based index of the file to get the information about. \return \c true if successful; \c false otherwise. \see 0610242128|file \see GetFileInfo(ZIP_INDEX_TYPE) \see GetFileInfo(ZIP_INDEX_TYPE) const \see operator[](ZIP_INDEX_TYPE) \see operator[](ZIP_INDEX_TYPE) const */ bool GetFileInfo(CZipFileHeader& fhInfo, ZIP_INDEX_TYPE uIndex) const; /** Gets the information about the file with the given index. This method provides a direct access to the file data. You should normally not modify the returned object apart from the reasons given in 0610242128|file. \param uIndex A zero-based index of the file to get the information about. \return A CZipFileHeader object that directly points to a central directory entry in memory; \c NULL if the archive is closed or there is no such index in the archive. \see 0610242128|file \see GetFileInfo(CZipFileHeader&, ZIP_INDEX_TYPE) const \see GetFileInfo(ZIP_INDEX_TYPE) const \see operator[](ZIP_INDEX_TYPE) \see operator[](ZIP_INDEX_TYPE) const */ CZipFileHeader* GetFileInfo(ZIP_INDEX_TYPE uIndex); /** Gets the information about the file with the given index. This method provides a direct access to the file data. This method does not allow modification of the returned object. \param uIndex A zero-based index of the file to get the information about. \return A CZipFileHeader object that directly points to a central directory entry in memory; \c NULL if the archive is closed or there is no such index in the archive. \see 0610242128|file \see GetFileInfo(CZipFileHeader&, ZIP_INDEX_TYPE) const \see GetFileInfo(ZIP_INDEX_TYPE) \see operator[](ZIP_INDEX_TYPE) \see operator[](ZIP_INDEX_TYPE) const */ const CZipFileHeader* GetFileInfo(ZIP_INDEX_TYPE uIndex) const; /** Gets the information about the file with the given index. This method provides a direct access to the file data. You should normally not modify the returned object apart from the reasons given in 0610242128|file. \param uIndex A zero-based index of the file to get the information about. \return A CZipFileHeader object that directly points to a central directory entry in memory; \c NULL if the archive is closed or there is no such index in the archive. \see 0610242128|file \see GetFileInfo(CZipFileHeader&, ZIP_INDEX_TYPE) const \see GetFileInfo(ZIP_INDEX_TYPE) \see GetFileInfo(ZIP_INDEX_TYPE) const \see operator[](ZIP_INDEX_TYPE) const */ CZipFileHeader* operator[](ZIP_INDEX_TYPE uIndex) { return GetFileInfo(uIndex); } /** Gets the information about the file with the given index. This method provides a direct access to the file data. This method does not allow modification of the returned object. \param uIndex A zero-based index of the file to get the information about. \return A CZipFileHeader object that directly points to a central directory entry in memory; \c NULL if the archive is closed or there is no such index in the archive. \see 0610242128|file \see GetFileInfo(CZipFileHeader&, ZIP_INDEX_TYPE) const \see GetFileInfo(ZIP_INDEX_TYPE) \see GetFileInfo(ZIP_INDEX_TYPE) const \see operator[](ZIP_INDEX_TYPE) */ const CZipFileHeader* operator[](ZIP_INDEX_TYPE uIndex) const { return GetFileInfo(uIndex); } /** Gets the number of files in the archive. \param bOnlyFiles If \c true, directories are not included in the total count; otherwise all entries are included. \return The number of files in the archive. \see 0610242128|file */ ZIP_INDEX_TYPE GetCount(bool bOnlyFiles) { if (IsClosed()) return 0; ZIP_INDEX_TYPE iTotalCount = GetCount(); if (bOnlyFiles) { ZIP_INDEX_TYPE iCount = 0; for (ZIP_INDEX_TYPE i = 0; i < iTotalCount; i++) { if (!m_centralDir[i]->IsDirectory()) iCount++; } return iCount; } else return iTotalCount; } /** Gets the number of files in the archive. \return The number of files in the archive. Note that under some compilation configuration this maybe an unsigned value and a signed value under other compilations. */ ZIP_INDEX_TYPE GetCount() const { return (ZIP_INDEX_TYPE) m_centralDir.GetCount(); } /** Calculates the actual size (in bytes) currently occupied by the archive. \return The sum of the sizes: the number of bytes already written to the file, the number of bytes in the write buffer and the whole size of the central directory. If the archive or a volume is closed, the return value is \c 0. \see 0610242128|archive */ ZIP_SIZE_TYPE GetOccupiedSpace() const { if (IsClosed(true) || IsClosed(false)) { ZIPTRACE("%s(%i) : ZipArchive or the current volume file is closed.\n"); return 0; } return m_storage.GetOccupiedSpace() + m_centralDir.GetSize(true); } /** The values used in the CZipArchive::Close() method. */ enum CloseAfterException { /** Normal closing. Use it, when no exception was thrown while processing the archive. */ afNoException, /** Use when an exception was thrown. The #Close method doesn't write any data but performs necessary cleaning to reuse the CZipArchive object for another archive processing. */ afAfterException, /** Use when an exception was thrown. The #Close method writes the central directory structure to the archive, so that the archive should be usable. */ afWriteDir }; /** Closes the archive. \param iAfterException One of the #CloseAfterException values. \param bUpdateTimeStamp If \c true, the method sets the modification date of the zip file to the date of the newest file in the archive. In a segmented archive, only the last segment file will have the time stamp updated. You can use this option even without performing any additional processing on the archive, just open and close the archive. \note Throws exceptions. Does not throw any exceptions, if \a iAfterException is set to the #afAfterException value. \see 0610222049 \see IsClosed */ void Close(int iAfterException = afNoException, bool bUpdateTimeStamp = false); /** Tests if the whole archive or the current volume is closed. \param bArchive
If \c true, test for the whole archive. If \c false, test for the current volume only. \return \c true if a file closed; \c false otherwise. \see Close */ bool IsClosed(bool bArchive = true)const { return m_storage.IsClosed(bArchive); } /** Writes the central directory to the archive and flushes the internal buffers to the disk. After that the archive is finalized on the disk, but you can still modify it, if it is not a segmented archive. \note - This method cannot be used on existing segmented archives - they are not modifiable. - If you have an archive with a huge central directory, it'll influence the performance calling this function without a reason. - Throws exceptions. \see 0610231446|flush \see FlushBuffers \see SetAutoFlush \see GetAutoFlush \see GetSegmMode */ void Flush(); /** Writes internal buffers to the storage file and flushes the file buffers to the disk. \see 0610231446|flush \see Flush */ void FlushBuffers() { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive should be opened first.\n"); return; } m_storage.FlushBuffers(); } /** Sets the CZipArchive object to call the Flush() method after each operation that modifies the archive (apart from changing central extra fields). It is useful when you want to prevent the loss of data in case of the program crash - the zip file will then be finalized on the disk. Use it after opening the archive. \note - You can set auto-flush only for non-segmented archives. - If you have an archive with a huge central directory, enabling auto-flush will influence the performance. \see 0610231446|flush \see Flush \see GetAutoFlush */ void SetAutoFlush(bool bAutoFlush = true); /** Gets the current auto-flush value. \return The current auto-flush value. \see 0610231446|flush \see SetAutoFlush \see Flush */ bool GetAutoFlush()const {return m_bAutoFlush;} /** Sets the system compatibility of the archive. Use it after opening the archive, but before adding a new file or using the #SetFileHeaderAttr method. If the filename code page is standard for the current system compatibility, the ZipArchive Library will change the filename code page to be default for the new system compatibility (see 0610051525 for more information). \param iSystemComp The new system compatibility to use. It can be one of the ZipCompatibility::ZipPlatforms values. \return \c false, if the value \a iSystemComp is not supported or it is not possible to set the value at this moment; \c true otherwise. \see 0610231446|compatibility \see GetSystemCompatibility \see CZipFileHeader::GetSystemCompatibility \see ZipCompatibility::ZipPlatforms \see ZipPlatform::GetSystemID */ bool SetSystemCompatibility(int iSystemComp); /** Gets the system compatibility of the current archive. \return One of the ZipCompatibility::ZipPlatforms values. \see 0610231446|compatibility \see SetSystemCompatibility \see CZipFileHeader::SetSystemCompatibility \see ZipCompatibility::ZipPlatforms \see ZipPlatform::GetSystemID */ int GetSystemCompatibility() const {return m_iArchiveSystCompatib;} /** Sets the attributes for the CZipFileHeader object to be used in the OpenNewFile(CZipFileHeader&, int, LPCTSTR) method. This special procedure is required, because the attributes value depends on the system compatibility of the archive. \param header The object to have the attributes set. \param uAttr The attributes to set. \throws CZipException with the CZipException::platfNotSupp code, if the system compatibility is not supported by the ZipArchive Library. \see 0610231446|advanced \see SetSystemCompatibility */ void SetFileHeaderAttr(CZipFileHeader& header, DWORD uAttr)const; /** Gets the underlying archive storage object. \return The pointer to CZipStorage. \see CZipStorage */ CZipStorage* GetStorage(){return &m_storage;} /** Sets the current settings that control storing of filenames and comments in the archive. \param settings The settings to set. \see 0610051525 \see SetStringStoreSettings(UINT, bool, UINT) \see SetStringStoreSettings(UINT, bool) \see ResetStringStoreSettings \see GetStringStoreSettings */ void SetStringStoreSettings(const CZipStringStoreSettings& settings) { m_stringSettings = settings; } /** Sets the current settings that control storing of filenames and comments in the archive. \param uFileNameCodePage The code page for filenames. \param bStoreNameInExtraData If \c true, the encoded filenames are stored in central extra fields. \param uCommentCodePage The code page for comments. \see 0610051525 \see SetStringStoreSettings(const CZipStringStoreSettings&) \see SetStringStoreSettings(UINT, bool) \see ResetStringStoreSettings \see GetStringStoreSettings */ void SetStringStoreSettings(UINT uFileNameCodePage, bool bStoreNameInExtraData, UINT uCommentCodePage) { m_stringSettings.Set(uFileNameCodePage, bStoreNameInExtraData, uCommentCodePage); } /** Sets the current settings that control storing of filenames and comments in the archive. The code page for comments stays the same when calling this method. \param uFileNameCodePage The code page for filenames. \param bStoreNameInExtraData If \c true, the encoded filenames are stored in central extra fields. \see 0610051525 \see SetStringStoreSettings(const CZipStringStoreSettings&) \see SetStringStoreSettings(UINT, bool, UINT) \see ResetStringStoreSettings \see GetStringStoreSettings */ void SetStringStoreSettings(UINT uFileNameCodePage, bool bStoreNameInExtraData = false) { SetStringStoreSettings(uFileNameCodePage, bStoreNameInExtraData, m_stringSettings.m_uCommentCodePage); } /** Sets the current settings that control storing of filenames and comments in the archive to their default values considering the current system compatibility of the archive (see GetSystemCompatibility()). \see 0610051525 \see SetStringStoreSettings(const CZipStringStoreSettings&) \see SetStringStoreSettings(UINT, bool, UINT) \see SetStringStoreSettings(UINT, bool) \see GetStringStoreSettings */ void ResetStringStoreSettings() { m_stringSettings.Reset(m_iArchiveSystCompatib); } /** Gets the current settings that control storing of filenames and comments in the archive. \return The current string store settings. \see 0610051525 \see SetStringStoreSettings(const CZipStringStoreSettings&) \see SetStringStoreSettings(UINT, bool, UINT) \see SetStringStoreSettings(UINT, bool) \see ResetStringStoreSettings \see CZipFileHeader::GetStringStoreSettings */ CZipStringStoreSettings& GetStringStoreSettings() { return m_stringSettings; } /** Enables or disables fast searching for files inside the archive using filenames. \see 0610242025|findfast \see FindFile \see GetIndexes \see GetFindFastIndex */ void EnableFindFast(bool bEnable = true); /** Allows to retrieve the order of sorted files after you enabled the Find Fast feature with the EnableFindFast() method. \param iFindFastIndex The index of the file in the sorted array. \return The index of the file in the central directory. You can use the return value in other methods that require the file index (such as #GetFileInfo). This method returns \c -1, if you have not called #EnableFindFast before or the archive is closed or the \a iFindFastIndex is out of range. \see 0610242025|findfast \see EnableFindFast */ ZIP_INDEX_TYPE GetFindFastIndex(ZIP_INDEX_TYPE iFindFastIndex) const { if (IsClosed()) { ZIPTRACE("CZipArchive::GetFindFastIndex: ZipArchive should be opened first.\n"); return ZIP_FILE_INDEX_UNSPECIFIED; } return m_centralDir.GetFindFastIndex(iFindFastIndex); } /** Sets the temporary path used when compressing files and there is a need for a temporary archive. Temporary files are used when replacing or when compressing a segmented archive with the #zipsmCheckForEff flag. If the path is not set or it does not exists or there is not enough free space in it, then the ZipArchive Library first tries the the following folders in the given order for sufficient free space: \li system default temporary directory, \li the current directory. If all above fails, no temporary file is created and the compression goes the usual way. \param lpszPath The path used for storing temporary files. Set it to \c NULL, to clear the temporary path and let the ZipArchive Library figure it out (see above). \param bForce If \a lpszPath is not \c NULL and this parameter set to \c true the directory is created, if it doesn't exist. Otherwise the the ZipArchive Library tries to figure out the location for temporary files by itself (see above). \see GetTempPath \see AddNewFile \see Smartness */ void SetTempPath(LPCTSTR lpszPath = NULL, bool bForce = true); /** Gets the current temporary path used when compressing files. \return The current temporary path. \see SetTempPath */ CZipString GetTempPath()const { return m_szTempPath; } /** The values used in the PredictFileNameInZip() method. */ enum Predict { prDir, ///< If \a lpszFilePath is a directory, appends a separator. prFile, ///< Treats \a lpszFilePath as a common file. prAuto ///< Treats \a lpszFilePath as a directory only if it has a path separator appended. }; /** Predicts the filename as it would be stored in the archive, when given parameters would be used with one of the AddNewFile() methods. The method takes into account the root path set with the #SetRootPath method. You can use this method to eliminate duplicates before adding a list of files. \param lpszFilePath The file path, the same as CZipAddNewFileInfo::m_szFilePath. \param bFullPath The same as CZipAddNewFileInfo::m_bFullPath. \param iWhat One of the #Predict values to interpret \a lpszFilePath correctly. \return The filename as it would be stored in the archive. */ CZipString PredictFileNameInZip(LPCTSTR lpszFilePath, bool bFullPath, int iWhat = prAuto)const ; /** Calculates the maximum number of bytes that the file represented by #CZipFileHeader would occupy in the current archive. You need to set the following members in the structure: \li File attributes (use the #SetFileHeaderAttr method). It is for determining whether the file is a directory or not. You can use ZipPlatform::GetFileAttr. \li The filename as it would appear in the archive (use CZipFileHeader::SetFileName). You can use #PredictFileNameInZip. \li The compressed size of the file (use CZipFileHeader::m_uLocalComprSize). You can use an uncompressed file size here for the maximum value estimate. Additionally you may set: - A file comment (use the CZipFileHeader::SetComment method). - Extra fields (use CZipFileHeader::m_aLocalExtraData and CZipFileHeader::m_aCentralExtraData). \param fh A template object pre-filled with data. \return The maximum number of bytes the file would occupy in the archive. \note - The method takes into account if the current archive is a segmented archive. - If the archive has a password set, the method will assume that the file would be stored encrypted in the archive (extra bytes may be added then depending on the encryption method). - The method calls CZipFileHeader::PrepareData - Zip64 only: The method takes into account the current file pointer position in the archive to determine the need for the Zip64 extensions and updates CZipFileHeader::m_uVolumeStart and CZipFileHeader::m_uOffset. - The method does not take into account a situation when a file would be compressed, but mostly stored blocks would be emitted by the Huffman compression engine. In this case extra 5 bytes are added per a single stored block. You should remove the file and store it instead when it happens (see #zipsmCheckForEff). \see PredictMaximumFileSizeInArchive(LPCTSTR, bool) const */ ZIP_SIZE_TYPE PredictMaximumFileSizeInArchive(CZipFileHeader& fh) const; /** Calls the PredictMaximumFileSizeInArchive(CZipFileHeader&) const method. Before calling, fills the #CZipFileHeader structure with the filename as it would appear in the archive and sets the proper file size (unless \a lpszFilePath is a directory). \param lpszFilePath A path to the file for which you want to predict the maximum size it would occupy. \param bFullPath The same as CZipAddNewFileInfo::m_bFullPath. \return The maximum number of bytes the file would occupy in the archive. \see PredictMaximumFileSizeInArchive(CZipFileHeader&) const */ ZIP_SIZE_TYPE PredictMaximumFileSizeInArchive(LPCTSTR lpszFilePath, bool bFullPath) const; /** Checks if the filename of the given file will be duplicated in the archive, if added to the archive with the given parameters. \param lpszFilePath The file path. You normally use it in one of the #AddNewFile methods. \param bFullPath The same as CZipAddNewFileInfo::m_bFullPath. \param bFileNameOnly If \c true, the method assumes that the filename is duplicated if only the name part (no path) is the same (\a bFullPath is ignored), otherwise the whole filename with a path is taken into account. \param iWhat One of the #Predict values to interpret \a lpszFilePath correctly. \return The zero-based index of the file in the archive which filename would be duplicated, or \c ZIP_FILE_INDEX_NOT_FOUND, if the filename would be unique. */ ZIP_INDEX_TYPE WillBeDuplicated(LPCTSTR lpszFilePath, bool bFullPath, bool bFileNameOnly = false, int iWhat = prAuto); /** Predicts the full resulting filename with path after extraction. The parameters (except for the first) are in the form you'd pass to the #ExtractFile(ZIP_INDEX_TYPE , LPCTSTR , bool , LPCTSTR , CZipCompressor::COffsetsPair*, DWORD ) method. The method takes into account the root path set with the #SetRootPath method. \param lpszFileNameInZip The filename of the file inside the archive (may be \c NULL if \a lpszNewName is not \c NULL). \param lpszPath \param bFullPath \param lpszNewName \return The predicted resulting file path. */ CZipString PredictExtractedFileName(LPCTSTR lpszFileNameInZip, LPCTSTR lpszPath, bool bFullPath, LPCTSTR lpszNewName = NULL)const ; /** Removes the root path from \a zpc. \param zpc The path to have the common beginning removed from. \see SetRootPath */ CZipString TrimRootPath(CZipPathComponent& zpc) const ; /** Removes \a lpszBeginning from the beginning of \a szPath. Both argument are considered to be paths - they must match up to the path separator. \param lpszBeginning The beginning to remove. \param szPath The path to have the beginning removed. \param pCompareFunction The compare function used (see #m_pZipCompare). \return \c true, if the path beginning was removed; \c false otherwise. */ static bool RemovePathBeginning(LPCTSTR lpszBeginning, CZipString& szPath, ZIPSTRINGCOMPARE pCompareFunction); /** Sets the default archive case-sensitivity. The default CZipArchive case-sensitivity depends on the system and is set as follows: \li on Windows: \c false \li on Linux: \c true Calling this method affects the following methods: - #FindFile - #GetIndexes - #FindMatches - #EnableFindFast - #TrimRootPath - #RemoveFiles(const CZipStringArray&) \param bCaseSensitive The case-sensitivity to be used. \note Set it before using one of the mentioned methods or leave it as it was set by default. */ void SetCaseSensitivity(bool bCaseSensitive) { m_bCaseSensitive = bCaseSensitive; m_pZipCompare = GetCZipStrCompFunc(bCaseSensitive); } /* Gets the current case sensitivity. \return \c true, if the archive is case-sensitive; \c false otherwise. \see SetCaseSensitivity */ bool GetCaseSensitivity() const { return m_bCaseSensitive; } /** Gets the central directory information. \param info The object to retrieve information data. \see GetCentralDirSize */ void GetCentralDirInfo(CZipCentralDir::CInfo& info)const; /** Gets the central directory size. \param bWhole If \c true, the return value includes the size of file headers. \return The size of the central directory. \see GetCentralDirInfo */ ZIP_SIZE_TYPE GetCentralDirSize(bool bWhole = true) const { if (IsClosed()) { ZIPTRACE("%s(%i) : ZipArchive is closed.\n"); return 0; } return m_centralDir.GetSize(bWhole); } /** Gets a value indicating whether the archive can be modified or not. An archive can be read-only when it is an existing segmented archive or it was opened with the #zipOpenReadOnly flag. \return \c true if the archive is read-only; \c false otherwise. */ bool IsReadOnly(){return m_storage.IsReadOnly();} const /** Sets the number of non-archive bytes that are present before the actual archive in the archive file. The library usually tries to automatically calculate this value, but this may not be possible under some conditions. \param uCount The number of bytes before the actual archive. \see GetBytesBeforeZip */ void SetBytesBeforeZip(ZIP_SIZE_TYPE uCount = 0) { if (!IsClosed()) { ZIPTRACE("%s(%i) : Set it before opening the archive.\n"); return; } m_storage.m_uBytesBeforeZip = uCount; } /** Gets the number of non-archive bytes that are present before the actual archive in the archive file. \return The number of bytes before the actual archive. \see SetBytesBeforeZip */ ZIP_SIZE_TYPE GetBytesBeforeZip() const { return m_storage.m_uBytesBeforeZip; } /** Values describing various archive consistency checks that the library performs. Instruct the library to skip selected checks using the #SetIgnoredConsistencyChecks method. */ enum ConsistencyCheck { checkNone, ///< If used in the the #SetIgnoredConsistencyChecks method, checks for all inconsistencies in an archive. checkCRC = 0x0001, ///< Check CRC after decompression. Use it when working with Java TM Archives (jar). The CRC check is performed using CRC written in a central header when closing a file after extraction. checkLocalMethod = 0x0002, ///< Check if the compression method written in a local header matches the compression method written in a central header. checkLocalSizes = 0x0004, ///< Check if sizes of compressed and uncompressed data written in a local header match their counterparts in a central header. The compressed size in the local header is always ignored, if it is 0. checkLocalCRC = 0x0008, ///< Check if the CRC written in a local header matches the CRC written in a central header. checkLocalFlag = 0x0010, ///< Check if the general purpose flag value written in a local header matches its counterpart written in a central header. checkLocalAll = checkLocalMethod | checkLocalSizes | checkLocalCRC | checkLocalFlag, ///< Check for inconsistencies between central and local headers at all. These checks are performed when opening a file for extraction. checkDataDescriptor = 0x0100, ///< Check if values written in extra data descriptor match values written in central header. This check is performed when closing a file after extraction, only if a file has a data descriptor (see CZipFileHeader::IsDataDescriptor()). Ignored by default (it is consistent with behavior of popular archivers). checkAll = checkCRC | checkLocalAll | checkDataDescriptor, ///< Logical sum of all possible checks. checkIgnoredByDefault = checkDataDescriptor, ///< Checks that are ignored by default by the ZipArchive Library }; /** Set the consistency checks to ignore while processing an archive. Allows opening archives which are not entirely consistent, but nevertheless the compressed data is correct. The level is reset to #checkIgnoredByDefault when opening or creating an archive. \param iLevel The consistency check. Can be one or more (OR-ed together) of #ConsistencyCheck values. \see ConsistencyCheck \see GetIgnoredConsistencyChecks */ void SetIgnoredConsistencyChecks(int iLevel = checkIgnoredByDefault) { if (IsClosed()) { ZIPTRACE("%s(%i) : Set it after opening the archive.\n"); return; } m_centralDir.m_iIgnoredChecks = iLevel; } /** Return the currently ignored consitency checks. Can be one or more of #ConsistencyCheck values. \see SetIgnoredConsistencyChecks */ int GetIgnoredConsistencyChecks() const { return m_centralDir.m_iIgnoredChecks; } /** Forces reading all headers from the central directory, even if the number of files reported by the archive is different. By default, the ZipArchive Library reads only the number of headers declared by the archive. Call this method before opening an archive. \note This method is useful when dealing with archives created with external software that put more files inside an archive that it is permitted by the zip format. Such a situation can take place with archives created with e.g. BOMArchiveHelper (Mac OS X utility), when the number of files exceeds 65,535. \see GetExhaustiveRead */ void SetExhaustiveRead(bool bExhaustiveRead) { if (!IsClosed()) { ZIPTRACE("%s(%i) : Set it before opening the archive.\n"); return; } m_bExhaustiveRead = bExhaustiveRead; } /** Returns the value indicating whether the exhaustive read function is active or not. \return \c true, if the exhaustive read function is active; \c false otherwise. \see SetExhaustiveRead */ bool GetExhaustiveRead() const { return m_bExhaustiveRead; } /** Finds indexes of the files, which filenames match the specified pattern. The indexes are stored in the \a ar array. The indexes can be used then e.g. in deleting or extracting files. \param lpszPattern The pattern to match. The case-sensitivity of the pattern is set to the global archive case-sensitivity (set with the #SetCaseSensitivity method). \param ar The array which will contain the resulting indexes. The contents of \a ar are not cleared, but the indexes are appended to it. \param bFullPath \li If \c true, the method matches the filename with path (if present) of the file. If the file is a directory, end it with a path separator or use a pattern that will recognize it. \li If \c false, the method matches only the name of the file. If the file is a directory, do not end it with a path separator. \see 0610242025|match \see SetCaseSensitivity \see ZipArchiveLib::CWildcard */ void FindMatches(LPCTSTR lpszPattern, CZipIndexesArray& ar, bool bFullPath = true); /** Renames the file with the given index in the archive. \param uIndex A zero-based index of the file to rename. \param lpszNewName The new name for the file. \return \c true, if the file was renamed; \c false otherwise. \note Throws exceptions. \see 0610231944|rename */ bool RenameFile(ZIP_INDEX_TYPE uIndex, LPCTSTR lpszNewName); /** Removes the central directory from the archive. You may then modify central extra fields and write the central directory back to the archive afterwards (use the #Close method). \return \c true, if the central directory was successfully removed; \c false otherwise. \see 0610242300|central */ bool RemoveCentralDirectoryFromArchive(); /** Reads the local header information of the file with the given index. \param uIndex The index of the file for which to update the local information. \return \c true, if the information was successfully updated; \c false otherwise. \note Throws exceptions. \see 0610231944|time \see OverwriteLocalHeader */ bool ReadLocalHeader(ZIP_INDEX_TYPE uIndex); /** Writes the local header information of the file with the given index back to the archive. \param uIndex The index of the file for which to write the local information. \return \c true, if the information was successfully written; \c false otherwise. \note Throws exceptions. \see 0610231944|time \see ReadLocalHeader */ bool OverwriteLocalHeader(ZIP_INDEX_TYPE uIndex); /** Retrieves the current compressor. The type of the compressor depends on the compression method used for compressing or decompressing data. \see SetCompressionMethod */ const CZipCompressor* GetCurrentCompressor() const { return m_pCompressor; } /** If \c true, the drive letter is removed from the filename stored inside the archive when adding a new file to the archive or extracting an existing one. It affects #AddNewFile, #ExtractFile, #PredictFileNameInZip, #PredictExtractedFileName, #WillBeDuplicated methods. The default value is \c true. */ bool m_bRemoveDriveLetter; protected: /** Reads the local header information of the file with the given index. \param uIndex The index of the file for which to update the local information. \note Throws exceptions. */ void ReadLocalHeaderInternal(ZIP_INDEX_TYPE uIndex) { // update sizes of local filename and extra field - they may differ from the ones in the central directory m_centralDir.OpenFile(uIndex); // skip checking the data descriptor, we are not there yet m_centralDir.CloseFile(true); } /** See the description of #EncryptFiles. \param pIndexes \return \c false, if the files could not be encrypted; \c true otherwise. \note Throws exceptions. \see EncryptFiles */ bool EncryptFilesInternal(CZipIndexesArray* pIndexes); /** The value set with #SetExhaustiveRead. */ bool m_bExhaustiveRead; /** See the description of #OpenNewFile(CZipFileHeader&, int, LPCTSTR) \param header \param iLevel \param lpszFilePath \param uReplaceIndex For internal use only. \see OpenNewFile(CZipFileHeader&, int, LPCTSTR) */ bool OpenNewFile(CZipFileHeader & header, int iLevel, LPCTSTR lpszFilePath, ZIP_INDEX_TYPE uReplaceIndex); /** See CZipCallbackProvider. */ ZipArchiveLib::CZipCallbackProvider m_callbacks; /** Writes the central directory notifying a callback object if available. */ void WriteCentralDirectory(bool bFlush = true); /** The value set with #SetCaseSensitivity. */ bool m_bCaseSensitive; /** A pointer to a method used to compare strings. Can point to \c Compare, \c CompareNoCase, \c Collate or \c CollateNoCase method. */ ZIPSTRINGCOMPARE m_pZipCompare; /** Physical layer of the archive. \see CZipStorage */ CZipStorage m_storage; /** A central directory object. \see CZipCentralDir */ CZipCentralDir m_centralDir; /** The open mode of the current file inside archive. */ enum OpenFileType { extract = -1, ///< A file is opened for extraction. nothing, ///< There is no file inside the archive opened. compress ///< A new file is opened for compression. }; /** Takes one of the CZipArchive::OpenFileType enum values. */ int m_iFileOpened; /** The value set with SetAutoFlush(). */ bool m_bAutoFlush; /** The value set with SetRootPath(). */ CZipString m_szRootPath; /** The value set with SetTempPath(). */ CZipString m_szTempPath; /** Opens the archive in the given mode. Called by #Open(LPCTSTR, int, ZIP_SIZE_TYPE) and #Open(CZipAbstractFile&, int). \param iMode The mode. \note Throws exceptions. */ void OpenInternal(int iMode); /** Initializes the archive during opening. \param iArchiveSystCompatib The system's compatibility of the archive. \param pSource If not \c NULL, then it specifies the central directory for sharing. \note Throws exceptions. */ void InitOnOpen(int iArchiveSystCompatib, CZipCentralDir* pSource = NULL); /** The value set with #SetSystemCompatibility. */ int m_iArchiveSystCompatib; /** The value set with #SetPassword. */ CZipAutoBuffer m_pszPassword; /** Gets the file currently opened for compression or decompression. \return The currently opened file or \c NULL, if there is no file opened. */ CZipFileHeader* CurrentFile(); /** Releases the current cryptograph. */ void ClearCryptograph() { if (m_pCryptograph) { delete m_pCryptograph; m_pCryptograph = NULL; } } /** Creates a new cryptograph. You can override this method and implement your own cryptograph. \param iEncryptionMethod The requested encryption method. \see CZipCryptograph::EncryptionMethod */ virtual void CreateCryptograph(int iEncryptionMethod) { if (m_pCryptograph != NULL) if (m_pCryptograph->CanHandle(iEncryptionMethod)) return; ClearCryptograph(); m_pCryptograph = CZipCryptograph::CreateCryptograph(iEncryptionMethod); } /** The current cryptograph. */ CZipCryptograph* m_pCryptograph; /** Releases the current compressor. */ void ClearCompressor() { if (m_pCompressor) { delete m_pCompressor; m_pCompressor = NULL; } } /** Creates a new compressor. You can override this method and implement your own compressor. \param uMethod The requested data compression method. \see CZipCompressor::CompressionMethod */ virtual void CreateCompressor(WORD uMethod) { if (m_pCompressor == NULL || !m_pCompressor->CanProcess(uMethod)) { ClearCompressor(); m_pCompressor = CZipCompressor::CreateCompressor(uMethod, &m_storage); } m_pCompressor->UpdateOptions(m_compressorsOptions); } /** The current compressor. */ CZipCompressor* m_pCompressor; /** The value set with #SetEncryptionMethod. */ int m_iEncryptionMethod; /** The value set with #SetCompressionMethod. */ WORD m_uCompressionMethod; /** A helper buffer used during various IO operations. \see m_iBufferSize \see SetAdvanced */ CZipAutoBuffer m_pBuffer; /** The size of the #m_pBuffer buffer. Set it before opening the archive. It is usually set with the #SetAdvanced method (specify this value as the second argument). \see SetAdvanced */ DWORD m_iBufferSize; /** The value set with the SetStringStoreSettings() method. */ CZipStringStoreSettings m_stringSettings; private: CZipCompressor::COptionsMap m_compressorsOptions; void Initialize(); void MakeSpaceForReplace(ZIP_INDEX_TYPE iReplaceIndex, ZIP_SIZE_TYPE uTotal, LPCTSTR lpszFileName); void MovePackedFiles(ZIP_SIZE_TYPE uStartOffset, ZIP_SIZE_TYPE uEndOffset, ZIP_SIZE_TYPE uMoveBy, CZipActionCallback* pCallback, bool bForward = false, bool bLastCall = true); bool RemoveLast(bool bRemoveAnyway = false); bool GetFromArchive(CZipArchive& zip, ZIP_INDEX_TYPE uIndex, LPCTSTR lpszNewFileName, ZIP_INDEX_TYPE iReplaceIndex, bool bKeepSystComp, CZipActionCallback* pCallback); bool UpdateReplaceIndex(ZIP_INDEX_TYPE& iReplaceIndex); void ThrowError(int err); void InitBuffer() { m_pBuffer.Allocate(m_iBufferSize); } void ReleaseBuffer() { m_pBuffer.Release(); } }; #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning (pop) #endif #endif // !defined(ZIPARCHIVE_ZIPARCHIVE_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/Aes.h0000644000175000017500000000125611300022650017716 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// tuxcmd-modules-0.6.70+ds/zip/ZipArchive/RandomPool.h0000644000175000017500000000125611300022650021260 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// tuxcmd-modules-0.6.70+ds/zip/ZipArchive/FileFilter.cpp0000644000175000017500000000315211300022650021563 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #if defined _MSC_VER && _MSC_VER < 1300 // STL warnings #include "stdafx.h" #pragma warning (push, 3) #endif #include "FileFilter.h" namespace ZipArchiveLib { bool CGroupFileFilter::Accept(LPCTSTR lpszParentDir, LPCTSTR lpszName, const CFileInfo& info) { bool conditionToBreak; bool valueToReturn; // handle the evaluation as quickly as possible if (m_iType == CGroupFileFilter::And) { conditionToBreak = false; valueToReturn = m_bInverted; } else { conditionToBreak = true; valueToReturn = !m_bInverted; } for (ZIP_ARRAY_SIZE_TYPE i = 0; i < m_filters.GetSize(); i++) { CFileFilter* pFilter = m_filters[i]; if (pFilter->HandlesFile(info) && pFilter->Evaluate(lpszParentDir, lpszName, info) == conditionToBreak) return valueToReturn; } return !valueToReturn; } } // namespace #if defined _MSC_VER && _MSC_VER < 1300 // STL warnings #pragma warning (pop) #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/DirEnumerator.cpp0000644000175000017500000001060011300022650022312 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #if defined _MSC_VER && _MSC_VER < 1300 // STL warnings #pragma warning (push, 3) #endif #include "DirEnumerator.h" #include "FileFilter.h" #include #if defined __GNUC__ && !defined __MINGW32__ #include #include #else #include #ifdef __BORLANDC__ #ifndef _tfindfirsti64 #define _tfindfirsti64 __tfindfirsti64 #endif #ifndef _tfindnexti64 #define _tfindnexti64 __tfindnexti64 #endif #ifndef _tfinddatai64_t #define _tfinddatai64_t __tfinddatai64_t #endif #endif #endif namespace ZipArchiveLib { #if defined __GNUC__ && !defined __MINGW32__ #define ZIP_ENUMERATOR_FOR_GNUC #endif bool CDirEnumerator::Start(CFileFilter& filter) { OnEnumerationBegin(); std::queue dirs; dirs.push(CZipString(m_lpszDirectory)); bool ret = true; do { m_szCurrentDirectory = dirs.front(); dirs.pop(); CZipPathComponent::AppendSeparator(m_szCurrentDirectory); EnterDirectory(); #ifdef ZIP_ENUMERATOR_FOR_GNUC DIR* dp = opendir(m_szCurrentDirectory); if (dp) { while (true) { struct dirent* entry = readdir(dp); if (!entry) break; CZipString path(m_szCurrentDirectory + entry->d_name); #if !defined __APPLE__ && !defined __CYGWIN__ struct stat64 sStats; if (stat64(path, &sStats) == -1) #else struct stat sStats; if (stat(path, &sStats) == -1) #endif continue; LPCTSTR name = entry->d_name; CFileInfo info; info.m_uAttributes = sStats.st_mode; #else CZipString szFullFileName = m_szCurrentDirectory + _T("*"); _tfinddatai64_t ffInfo; #if _MSC_VER > 1200 intptr_t hFile; #else long hFile; #endif if( (hFile = _tfindfirsti64( (LPTSTR)(LPCTSTR)szFullFileName, &ffInfo )) != -1L ) { do { LPCTSTR name = ffInfo.name; CFileInfo info; info.m_uAttributes = ffInfo.attrib; #endif bool isDir; if (ZipPlatform::IsDirectory(info.m_uAttributes)) { if (!m_bRecursive || IsDots(name)) continue; isDir = true; } else isDir = false; #ifdef ZIP_ENUMERATOR_FOR_GNUC info.m_uSize = (ZIP_FILE_USIZE)sStats.st_size; info.m_uCreateTime = sStats.st_ctime; info.m_uModTime = sStats.st_mtime; info.m_uAccessTime = sStats.st_atime; #else info.m_uSize = (ZIP_FILE_USIZE)ffInfo.size; info.m_uCreateTime = ffInfo.time_create; info.m_uModTime = ffInfo.time_write; info.m_uAccessTime = ffInfo.time_access; CZipString path(m_szCurrentDirectory + ffInfo.name); #endif if (isDir) { bool bAllow; if (filter.HandlesFile(info)) bAllow = filter.Evaluate(path, name, info); else // examine directory, if the filter cannot decide bAllow = true; if (bAllow) dirs.push(path); } else { bool bAllow; if (filter.HandlesFile(info)) bAllow = filter.Evaluate(path, name, info); else // skip file, if the filter cannot decide bAllow = false; if (bAllow && !Process(path, info)) { ret = false; break; } } #ifdef ZIP_ENUMERATOR_FOR_GNUC } closedir(dp); } #else } while (_tfindnexti64(hFile, &ffInfo) == 0L); _findclose(hFile); } #endif ExitDirectory(); } while(!dirs.empty() && ret); OnEnumerationEnd(ret); return ret; } bool CDirEnumerator::IsDots(LPCTSTR lpszName) { CZipString name(lpszName); return name.Compare(_T(".")) == 0 || name.Compare(_T("..")) == 0; } } // namespace #if defined _MSC_VER && _MSC_VER < 1300 // STL warnings #pragma warning (pop) #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/Wildcard.cpp0000644000175000017500000002306711300022650021276 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Wildcard.h" namespace ZipArchiveLib { bool CWildcard::IsPatternValid(LPCTSTR lpszPattern, int* iErrorType) { try { /* loop through pattern to EOS */ while (*lpszPattern) { /* determine pattern type */ switch (*lpszPattern) { /* check literal escape, it cannot be at end of pattern */ case _T('\\'): if (!*++lpszPattern) throw patternEsc; lpszPattern++; break; /* the [..] construct must be well formed */ case _T('['): lpszPattern++; /* if the next character is ']' then bad pattern */ if (*lpszPattern == _T(']')) throw patternEmpty; /* if end of pattern here then bad pattern */ if (!*lpszPattern) throw patternClose; /* loop to end of [..] construct */ while (*lpszPattern != _T(']')) { /* check for literal escape */ if (*lpszPattern == _T('\\')) { lpszPattern++; /* if end of pattern here then bad pattern */ if (!*lpszPattern++) throw patternEsc; } else lpszPattern++; /* if end of pattern here then bad pattern */ if (!*lpszPattern) throw patternClose; /* if this a range */ if (*lpszPattern == _T('-')) { /* we must have an end of range */ if (!*++lpszPattern || *lpszPattern == ']') throw patternRange; else { /* check for literal escape */ if (*lpszPattern == _T('\\')) lpszPattern++; /* if end of pattern here then bad pattern */ if (!*lpszPattern++) throw patternEsc; } } } break; /* all other characters are valid pattern elements */ case '*': case '?': default: lpszPattern++; /* "normal" character */ break; } } throw patternValid; } catch (int i) { if (iErrorType) *iErrorType = i; return i == patternValid; } } bool CWildcard::IsPattern(LPCTSTR lpszPattern) { while (*lpszPattern) { switch (*lpszPattern++) { case _T('?'): case _T('*'): case _T('['): case _T('\\'): return true; } } return false; } bool CWildcard::IsMatch(LPCTSTR lpszText, int *iRetCode) { CZipString sz; if (!m_bCaseSensitive) { sz = lpszText; sz.MakeLower(); lpszText = (LPCTSTR)sz; } int i = Match((LPCTSTR)m_szPattern, lpszText); if (iRetCode) *iRetCode = i; return i == matchValid; } int CWildcard::MatchAfterStar(LPCTSTR p, LPCTSTR t) { int iMatch = matchNone; TCHAR nextp; /* pass over existing ? and * in pattern */ while ( *p == _T('?') || *p == _T('*') ) { /* take one char for each ? and + */ if (*p == _T('?')) { /* if end of text then no match */ if (!*t++) return matchAbort; } /* move to next char in pattern */ p++; } /* if end of pattern we have matched regardless of text left */ if (!*p) return matchValid; /* get the next character to match which must be a literal or '[' */ nextp = *p; if (nextp == _T('\\')) { nextp = p[1]; /* if end of text then we have a bad pattern */ if (!nextp) return matchPattern; } /* Continue until we run out of text or definite result seen */ do { /* a precondition for matching is that the next character in the pattern match the next character in the text or that the next pattern char is the beginning of a range. Increment text pointer as we go here */ if (nextp == *t || nextp == _T('[')) iMatch = Match(p, t); /* try finding another precondition */ if (iMatch == matchPattern) iMatch = matchNone; /* if the end of text is reached then no iMatch */ if (!*t++) iMatch = matchAbort; } while ( iMatch != matchValid && iMatch != matchAbort); /* return result */ return iMatch; } int CWildcard::Match(LPCTSTR lpszPattern, LPCTSTR lpszText) { TCHAR range_start, range_end; /* start and end in range */ bool bInvert; /* is this [..] or [!..] */ bool bMemberMatch; /* have I matched the [..] construct? */ bool bLoop; /* should I terminate? */ for ( ; *lpszPattern; lpszPattern++, lpszText++) { /* if this is the end of the text then this is the end of the match */ if (!*lpszText) { if ( *lpszPattern == _T('*') && *++lpszPattern == _T('\0') ) return matchValid; else return matchAbort; } /* determine and react to pattern type */ switch (*lpszPattern) { case _T('?'): /* single any character match */ break; case _T('*'): /* multiple any character match */ return MatchAfterStar (lpszPattern, lpszText); /* [..] construct, single member/exclusion character match */ case _T('['): { /* move to beginning of range */ lpszPattern++; /* check if this is a member match or exclusion match */ bInvert = false; if (*lpszPattern == _T('!') || *lpszPattern == _T('^')) { bInvert = true; lpszPattern++; } /* if closing bracket here or at range start then we have a malformed pattern */ if (*lpszPattern == _T(']')) return matchPattern; bMemberMatch = false; bLoop = true; while (bLoop) { /* if end of construct then bLoop is done */ if (*lpszPattern == _T(']')) { bLoop = false; continue; } /* matching a '!', '^', '-', '\' or a ']' */ if (*lpszPattern == _T('\\')) range_start = range_end = *++lpszPattern; else range_start = range_end = *lpszPattern; /* if end of pattern then bad pattern (Missing ']') */ if (!*lpszPattern) return matchPattern; /* check for range bar */ if (*++lpszPattern == _T('-')) { /* get the range end */ range_end = *++lpszPattern; /* if end of pattern or construct then bad pattern */ if (range_end == _T('\0') || range_end == _T(']')) return matchPattern; /* special character range end */ if (range_end == _T('\\')) { range_end = *++lpszPattern; /* if end of text then we have a bad pattern */ if (!range_end) return matchPattern; } /* move just beyond this range */ lpszPattern++; } /* if the text character is in range then match found. make sure the range letters have the proper relationship to one another before comparison */ if (range_start < range_end) { if (*lpszText >= range_start && *lpszText <= range_end) { bMemberMatch = true; bLoop = false; } } else { if (*lpszText >= range_end && *lpszText <= range_start) { bMemberMatch = true; bLoop = false; } } } /* if there was a match in an exclusion set then no match */ /* if there was no match in a member set then no match */ if ((bInvert && bMemberMatch) || !(bInvert || bMemberMatch)) return matchRange; /* if this is not an exclusion then skip the rest of the [...] construct that already matched. */ if (bMemberMatch) { while (*lpszPattern != _T(']')) { /* bad pattern (Missing ']') */ if (!*lpszPattern) return matchPattern; /* skip exact match */ if (*lpszPattern == _T('\\')) { lpszPattern++; /* if end of text then we have a bad pattern */ if (!*lpszPattern) return matchPattern; } /* move to next pattern char */ lpszPattern++; } } break; } case _T('\\'): /* next character is quoted and must match exactly */ /* move pattern pointer to quoted char and fall through */ lpszPattern++; /* if end of text then we have a bad pattern */ if (!*lpszPattern) return matchPattern; /* must match this character exactly */ default: if (*lpszPattern != *lpszText) return matchPattern; } } /* if end of text not reached then the pattern fails */ if (*lpszText) return matchEnd; else return matchValid; } } // namespace tuxcmd-modules-0.6.70+ds/zip/ZipArchive/std_mfc.h0000644000175000017500000000273311300022650020626 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #ifndef ZIPARCHIVE_STDAFX_DOT_H #error Do not include this file directly. Include stdafx.h instead #endif #if _MSC_VER > 1000 #ifndef WINVER #define WINVER 0x0400 #endif #pragma once #endif #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit #ifndef VC_EXTRALEAN #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #endif #include #include typedef BOOL ZBOOL; #if _MSC_VER >= 1300 || defined ZIP_FILE_USES_STL #define ZIP_FILE_USIZE ULONGLONG #define ZIP_FILE_SIZE LONGLONG #define ZIP_FILE_SIZEMAX _I64_MAX #else #define ZIP_FILE_USIZE DWORD #define ZIP_FILE_SIZE LONG #define ZIP_FILE_SIZEMAX MAXLONG #endiftuxcmd-modules-0.6.70+ds/zip/ZipArchive/resource.h0000644000175000017500000000063611300022650021036 0ustar salvisalvi//{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by ZipArchive.rc // // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCompressor.cpp0000644000175000017500000000560711300022650022364 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipCompressor.h" #include "BytesWriter.h" #include "DeflateCompressor.h" using namespace ZipArchiveLib; CZipCompressor* CZipCompressor::CreateCompressor(WORD uMethod, CZipStorage* pStorage) { if (uMethod == methodStore || uMethod == methodDeflate) return new CDeflateCompressor(pStorage); return NULL; } void CZipCompressor::UpdateFileCrc(const void *pBuffer, DWORD uSize) { m_pFile->m_uCrc32 = zarch_crc32(m_pFile->m_uCrc32, (zarch_Bytef*)pBuffer, uSize); } void CZipCompressor::UpdateCrc(const void *pBuffer, DWORD uSize) { m_uCrc32 = zarch_crc32(m_uCrc32, (zarch_Bytef*)pBuffer, uSize); } void CZipCompressor::UpdateOptions(const COptionsMap& optionsMap) { const COptions* pOptions = GetOptions(); if (pOptions == NULL) return; const COptions* pNewOptions = optionsMap.Get(pOptions->GetType()); if (pNewOptions != NULL) UpdateOptions(pNewOptions); } void CZipCompressor::InitBuffer() { // This should be greated that 64k for deflate when creating offsets pairs is enabled // otherwise deflate will not be able to write one block in one go and will never report // a flushed block for low-compressable data const COptions* pOptions = GetOptions(); DWORD bufferSize = 0; if (pOptions != NULL) bufferSize = pOptions->m_iBufferSize; if (bufferSize == 0) bufferSize = COptions::cDefaultBufferSize; m_pBuffer.Allocate(bufferSize); } void CZipCompressor::COptionsMap::Set(const CZipCompressor::COptions* pOptions) { if (pOptions == NULL) return; int iType = pOptions->GetType(); Remove(iType); SetAt(iType, pOptions->Clone()); } CZipCompressor::COptions* CZipCompressor::COptionsMap::Get(int iType) const { COptions* pTemp = NULL; if (Lookup(iType, pTemp)) return pTemp; else return NULL; } void CZipCompressor::COptionsMap::Remove(int iType) { COptions* pTemp = Get(iType); if (pTemp != NULL) { delete pTemp; RemoveKey(iType); } } CZipCompressor::COptionsMap::~COptionsMap() { COptionsMap::iterator iter = GetStartPosition(); while (IteratorValid(iter)) { COptions* pOptions = NULL; int iType = 0; GetNextAssoc(iter, iType, pOptions); delete pOptions; } RemoveAll(); } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipMutex_win.h0000644000175000017500000000335211300022650021647 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #ifndef ZIPARCHIVE_ZIPMUTEX_DOT_H #error Do not include this file directly. Include ZipMutex.h instead #endif #ifdef ZIP_ARCHIVE_USE_LOCKING #include "ZipException.h" namespace ZipArchiveLib { class ZIP_API CZipMutex { HANDLE m_handle; public: CZipMutex(bool bOpen = false) { if (bOpen) Open(); else m_handle = NULL; } void Open() { Close(); m_handle = ::CreateMutex(NULL, FALSE, NULL); if (m_handle == NULL) CZipException::Throw(CZipException::mutexError); } void Lock() { DWORD dwRet = ::WaitForSingleObject(m_handle, INFINITE); if (dwRet != WAIT_OBJECT_0 && dwRet != WAIT_ABANDONED) CZipException::Throw(CZipException::mutexError); } void Unlock() { if (!::ReleaseMutex(m_handle)) CZipException::Throw(CZipException::mutexError); } void Close() { if (m_handle != NULL) { ::CloseHandle(m_handle); m_handle = NULL; } } CZipMutex& operator=(const CZipMutex&) { m_handle = NULL; return *this; } ~CZipMutex() { Close(); } }; } #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipAutoBuffer.h0000644000175000017500000000341311300022650021730 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipAutoBuffer.h * Includes the CZipAutoBuffer class. * */ #if !defined(ZIPARCHIVE_ZIPAUTOBUFFER_DOT_H) #define ZIPARCHIVE_ZIPAUTOBUFFER_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "ZipExport.h" /** A smart buffer freeing its contents on destruction. */ class ZIP_API CZipAutoBuffer { public: operator char*() { return m_pBuffer; } #if !defined (__BORLANDC__) || (__BORLANDC__ > 0x560) // The actual version may be different. operator const char*() const { return m_pBuffer; } #endif const char* GetBuffer() const {return m_pBuffer;} char* Allocate(DWORD iSize, bool bZeroMemory = false); void Release(); DWORD GetSize() const { return m_iSize; } bool IsAllocated() const { return (m_pBuffer != NULL); } CZipAutoBuffer(DWORD iSize, bool bZeroMemory = false); CZipAutoBuffer(); CZipAutoBuffer(const CZipAutoBuffer& buffer); virtual ~CZipAutoBuffer(); CZipAutoBuffer& operator=(const CZipAutoBuffer& buffer); protected: char* m_pBuffer; DWORD m_iSize; }; #endif // !defined(ZIPARCHIVE_ZIPAUTOBUFFER_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipArchive.vcproj0000644000175000017500000010052611300022650022326 0ustar salvisalvi tuxcmd-modules-0.6.70+ds/zip/ZipArchive/Bzip2Compressor.cpp0000644000175000017500000000131011300022650022573 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "_features.h" tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipPlatformComm.cpp0000644000175000017500000000427511300022650022630 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipFile.h" #include "ZipPlatform.h" #include "ZipException.h" using namespace ZipPlatform; bool ZipPlatform::DirectoryExists(LPCTSTR lpszDir) { CZipString sz; if (!GetCurrentDirectory(sz)) return false; if (!ChangeDirectory(lpszDir)) return false; ChangeDirectory(sz); return true; } bool ZipPlatform::ForceDirectory(LPCTSTR lpDirectory) { ASSERT(lpDirectory); CZipString szDirectory = lpDirectory; szDirectory.TrimRight(CZipPathComponent::m_cSeparator); CZipPathComponent zpc(szDirectory); if ((zpc.GetFilePath().Compare((LPCTSTR)szDirectory)) == 0 || (FileExists(szDirectory) == -1)) return true; if (!ForceDirectory(zpc.GetFilePath())) return false; if (!CreateDirectory(szDirectory)) return false; return true; } bool ZipPlatform::GetFileSize(LPCTSTR lpszFileName, ZIP_SIZE_TYPE& dSize) { CZipFile f; if (!f.Open(lpszFileName, CZipFile::modeRead | CZipFile::shareDenyWrite, false)) return false; bool ret; try { ZIP_FILE_USIZE size = f.GetLength(); // the file may be too large if zip64 is not enabled ret = size <= ZIP_SIZE_TYPE(-1); if (ret) dSize = (ZIP_SIZE_TYPE)size; } #ifdef ZIP_ARCHIVE_MFC catch(CZipBaseException* e) { e->Delete(); ret = false; } #else catch(CZipBaseException e) { ret = false; } #endif try { f.Close(); } #ifdef ZIP_ARCHIVE_MFC catch(CZipBaseException* e) { e->Delete(); } #else catch(CZipBaseException e) { } #endif return ret; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/_readme.txt0000644000175000017500000000032611300022650021167 0ustar salvisalviThe complete functionality of the ZipArchive Library (with Zip64, AES and BZIP2) is available in the commercial version. To evaluate the full version, please visit http://www.artpol-software.com/DownloadTrial.aspxtuxcmd-modules-0.6.70+ds/zip/ZipArchive/stdafx.h0000644000175000017500000000410111300022650020467 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file stdafx.h * Contains global definitions. * */ #if !defined(ZIPARCHIVE_STDAFX_DOT_H) #define ZIPARCHIVE_STDAFX_DOT_H #include "_features.h" #include "_platform.h" #if _MSC_VER > 1000 #pragma once #endif // uncomment to disable compiling standard error messages into the library #define ZIP_ENABLE_ERROR_DESCRIPTION #if _MSC_VER < 1300 && !defined __BORLANDC__ && !defined (__GNUC__) #define ZIPINLINE inline #else #define ZIPINLINE #endif #ifdef ZIP_ARCHIVE_STL #include "std_stl.h" #else #include "std_mfc.h" #endif #ifdef TRACE #if _MSC_VER >= 1300 #define ZIPTRACE(f) TRACE(f,__FILE__,__LINE__) #else #define ZIPTRACE(f) TRACE(_T(f)) #endif #else #define ZIPTRACE(f) #define NOZIPTRACE #endif #ifdef _ZIP_STRICT_U16 #define ZIP_INDEX_TYPE WORD #define ZIP_VOLUME_TYPE WORD #else #define ZIP_INDEX_TYPE int #define ZIP_VOLUME_TYPE int #endif #define ZIP_SIZE_TYPE DWORD #define ZIP_ZLIB_TYPE int #if !defined(_INTPTR_T_DEFINED) && !defined(__GNUC__) #if defined (__BORLANDC__) #include #elif _MSC_VER <= 1200 || !defined _MSC_VER typedef long intptr_t; #endif #endif #define ZIP_FILE_INDEX_NOT_FOUND ZIP_INDEX_TYPE(-1) #define ZIP_FILE_INDEX_UNSPECIFIED ZIP_FILE_INDEX_NOT_FOUND #define ZIP_VOLUME_NUMBER_UNSPECIFIED ZIP_VOLUME_TYPE(-1) #endif // !defined(ZIPARCHIVE_STDAFX_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipFileMapping_lnx.h0000644000175000017500000000302211300022650022736 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #ifndef ZIPARCHIVE_ZIPFILEMAPPING_DOT_H #error Do not include this file directly. Include ZipFileMapping.h instead #endif #include namespace ZipArchiveLib { struct CZipFileMapping { CZipFileMapping() { m_iSize = 0; m_pFileMap = NULL; } bool CreateMapping(CZipFile* pFile) { if (!pFile) return false; m_iSize = pFile->GetLength(); m_pFileMap = mmap(0, m_iSize, PROT_READ|PROT_WRITE, MAP_SHARED, pFile->m_hFile, 0); return (m_pFileMap != NULL); } void RemoveMapping() { if (m_pFileMap) { munmap(m_pFileMap, m_iSize); m_pFileMap = NULL; } } ~CZipFileMapping() { RemoveMapping(); } char* GetMappedMemory() { return reinterpret_cast (m_pFileMap); } protected: void* m_pFileMap; size_t m_iSize; }; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/License.txt0000644000175000017500000003617111300022650021164 0ustar salvisalviThe ZipArchive Library is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz For the licensing details, please visit: http://www.artpol-software.com/ZipArchive/KB/license.aspx ------------------------------------------------------------------ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipArchive.rc0000644000175000017500000000464111300022650021430 0ustar salvisalvi// Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO FILEVERSION 3,2,0,0 PRODUCTVERSION 3,2,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x40004L FILETYPE 0x2L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "http://www.artpol-software.com" VALUE "CompanyName", "Artpol Software" VALUE "FileDescription", "ZipArchive Library - zip compression library" VALUE "FileVersion", "3.2.0" VALUE "InternalName", "ZipArchive" VALUE "LegalCopyright", "Copyright (c) 2000 - 2007 Artpol Software - Tadeusz Dracz" VALUE "OriginalFilename", "ZipArchive.dll" VALUE "ProductName", "ZipArchive Library" VALUE "ProductVersion", "3.2.0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipPathComponent_lnx.cpp0000644000175000017500000000470511300022650023666 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "_platform.h" #ifdef ZIP_ARCHIVE_LNX #include "stdafx.h" #include "ZipPathComponent.h" CZipPathComponent::~CZipPathComponent() { } void CZipPathComponent::SetFullPath(LPCTSTR lpszFullPath) { CZipString szTempPath(lpszFullPath); const CZipString szPrefix = _T("\\\\?\\unc\\"); int i = -1, iLen = szPrefix.GetLength(); if (iLen > szTempPath.GetLength()) iLen = szTempPath.GetLength(); CZipString szPossiblePrefix = szTempPath.Left(iLen); szPossiblePrefix.MakeLower(); // must perform case insensitive comparison while (++i < iLen && szPossiblePrefix[i] == szPrefix[i]); if (i == 2 || i == 4 || i == 8) // unc path, unicode path or unc path meeting windows file name conventions { m_szPrefix = szTempPath.Left(i); szTempPath = szTempPath.Mid(i); } else m_szPrefix.Empty(); m_szDrive.Empty(); m_szFileTitle.Empty(); m_szDirectory.Empty(); m_szFileExt.Empty(); int p; for (p = szTempPath.GetLength() - 1; p >= 0; p--) if (szTempPath[p] == m_cSeparator) break; if (p != -1) { m_szDirectory = szTempPath.Left(p); if (p == szTempPath.GetLength() - 1 ) return; // no filename present else p++; } else p = 0; // p points at the beginning of the filename m_szFileTitle = szTempPath.Mid(p); for (p = m_szFileTitle.GetLength() - 1; p >= 0; p--) if (m_szFileTitle[p] == _T('.')) break; if (p != -1) { m_szFileExt = m_szFileTitle.Mid(p+1); m_szFileTitle = m_szFileTitle.Left(p); } } CZipString CZipPathComponent::GetNoDrive() const { CZipString szPath = m_szDirectory; CZipString szFileName = GetFileName(); if (!szFileName.IsEmpty() && !szPath.IsEmpty()) szPath += m_cSeparator; szPath += szFileName; return szPath; } #endif // ZIP_ARCHIVE_LNX tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipFile_mfc.cpp0000644000175000017500000000202611300022650021724 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "_features.h" #if defined ZIP_ARCHIVE_MFC && !defined ZIP_FILE_USES_STL #include "stdafx.h" #include "ZipFile.h" // IMPLEMENT_DYNAMIC(CZipAbstractFile, CFile) IMPLEMENT_DYNAMIC(CZipFile, CFile) CZipFile::CZipFile() { } CZipFile::~CZipFile() { Close(); } CZipFile::operator HANDLE() { return (HANDLE)m_hFile; } #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipExtraData.h0000644000175000017500000000656511300022650021556 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipExtraData.h * Includes the CZipExtraData class. * */ #if !defined(ZIPARCHIVE_ZIPEXTRADATA_DOT_H) #define ZIPARCHIVE_ZIPEXTRADATA_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "ZipExport.h" #include "ZipAutoBuffer.h" #include "ZipExtraField.h" #include "memory.h" /** Represents a single data record in an extra field. \see 0610242300 */ class ZIP_API CZipExtraData { friend class CZipExtraField; public: /** The custom data contained by this record. */ CZipAutoBuffer m_data; CZipExtraData() { m_uHeaderID = 0; } CZipExtraData(const CZipExtraData& extra) { *this = extra; } /** Initializes a new instance of the CZipExtraData class. \param uHeaderID The unique ID of the data. */ CZipExtraData(WORD uHeaderID) { m_uHeaderID = uHeaderID; } CZipExtraData& operator=(const CZipExtraData& extra) { m_uHeaderID = extra.m_uHeaderID; DWORD uSize = extra.m_data.GetSize(); m_data.Allocate(uSize); if (uSize > 0) memcpy(m_data, extra.m_data, uSize); return *this; } bool operator==(const CZipExtraData& extra) { return m_uHeaderID == extra.m_uHeaderID && m_data.GetSize() == extra.m_data.GetSize() && memcmp(m_data, extra.m_data, m_data.GetSize()) == 0; } bool operator != (const CZipExtraData& extra) { return !(*this == extra); } bool operator > (const CZipExtraData& extra) { return m_uHeaderID > extra.m_uHeaderID; } bool operator < (const CZipExtraData& extra) { return m_uHeaderID < extra.m_uHeaderID; } bool operator >= (const CZipExtraData& extra) { return m_uHeaderID > extra.m_uHeaderID || *this == extra; } bool operator <= (const CZipExtraData& extra) { return m_uHeaderID < extra.m_uHeaderID || *this == extra; } /** Gets the total size, the extra data will occupy in the archive. \return The size in bytes. */ int GetTotalSize() const { return 4 + m_data.GetSize(); } /** Gets the data ID. \return The data ID. */ WORD GetHeaderID() const { return m_uHeaderID; } protected: /** Reads the extra data record from \a buffer. \param buffer The buffer to read the data from. \param uSize The size of the data to read. \return \c false, if \a uSize was smaller than the declared extra data size; \c true otherwise. */ bool Read(char* buffer, WORD uSize); /** Writes the extra data record to \a buffer. \param buffer The buffer to write to. \return The total size of extra data in bytes. */ WORD Write(char* buffer)const; private: WORD m_uHeaderID; }; #endif // !defined(ZIPARCHIVE_ZIPEXTRADATA_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipFile_mfc.h0000644000175000017500000000467411300022650021404 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #ifndef ZIPARCHIVE_ZIPFILE_DOT_H #error Do not include this file directly. Include ZipFile.h instead #endif #if _MSC_VER > 1000 && defined ZIP_HAS_DLL #pragma warning (push) #pragma warning( disable : 4275 ) // non dll-interface used as base for dll-interface class #endif #include "ZipAbstractFile.h" #include "ZipExport.h" class ZIP_API CZipFile : public CZipAbstractFile, public CFile { public: DECLARE_DYNAMIC(CZipFile) void Flush(){CFile::Flush();} CZipString GetFilePath() const { try { // it throws an exception when working on an offline file return CFile::GetFilePath(); } catch (CException* e) { e->Delete(); return this->m_strFileName; } } ZIP_FILE_USIZE GetPosition() const {return CFile::GetPosition() ;} void SetLength(ZIP_FILE_USIZE nNewLen) {CFile::SetLength(nNewLen);} ZIP_FILE_USIZE Seek(ZIP_FILE_SIZE lOff , int nFrom){return CFile::Seek(lOff, nFrom);} ZIP_FILE_USIZE GetLength() const {return CFile::GetLength();} UINT Read(void *lpBuf, UINT nCount){return CFile::Read(lpBuf, nCount);} void Write(const void* lpBuf, UINT nCount){CFile::Write(lpBuf, nCount);} bool Open( LPCTSTR lpszFileName, UINT nOpenFlags, bool bThrowExc) { CFileException* e = new CFileException; bool bRet = CFile::Open(lpszFileName, nOpenFlags, e) != 0; if (!bRet && bThrowExc) throw e; e->Delete(); return bRet; } CZipFile(); bool IsClosed() const { return m_hFile == CFile::hFileNull; } CZipFile( LPCTSTR lpszFileName, UINT nOpenFlags ):CFile(lpszFileName, nOpenFlags) { } void Close( ) { if (!IsClosed()) CFile::Close(); } operator HANDLE(); virtual ~CZipFile(); }; #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning (pop) #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipFile_stl.cpp0000644000175000017500000000644311300022650021770 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "_features.h" #if defined ZIP_ARCHIVE_STL || defined ZIP_FILE_USES_STL #if defined __APPLE__ || defined __CYGWIN__ #define FILE_FUNCTIONS_64B_BY_DEFAULT #else #undef FILE_FUNCTIONS_64B_BY_DEFAULT #endif #include "stdafx.h" #include "ZipFile.h" #include "ZipException.h" #include "ZipPlatform.h" #include CZipFile::CZipFile() { m_hFile = -1; } void CZipFile::ThrowError() const { CZipException::Throw(errno, m_szFileName); } ZIP_FILE_USIZE CZipFile::GetLength() const { // cannot use Seek here, Seek is not const ZIP_SIZE_TYPE lLen, lCur; lCur = _lseek(m_hFile, 0, current); if (lCur == (ZIP_SIZE_TYPE)-1) ThrowError(); lLen = _lseek(m_hFile, 0, end); // first go back bool err = _lseek(m_hFile, lCur, begin) == -1; if (err || lLen == (ZIP_SIZE_TYPE)-1) ThrowError(); return lLen; } bool CZipFile::Open(LPCTSTR lpszFileName, UINT openFlags, bool bThrow) { if (!IsClosed()) Close(); #ifdef O_BINARY UINT iNewFlags = O_BINARY; #else UINT iNewFlags = 0; #endif bool bReadOnly = false; if (openFlags & CZipFile::modeCreate) iNewFlags |= O_CREAT; if ((openFlags & CZipFile::modeReadWrite) == CZipFile::modeReadWrite) iNewFlags |= O_RDWR; else if (openFlags & CZipFile::modeRead) { // O_RDONLY is defined as 0 bReadOnly = true; iNewFlags |= O_RDONLY; } else if (openFlags & CZipFile::modeWrite) iNewFlags |= O_WRONLY; if (!(openFlags & CZipFile::modeNoTruncate) && !bReadOnly) iNewFlags |= O_TRUNC; m_hFile = ZipPlatform::OpenFile(lpszFileName, iNewFlags, openFlags & 0x1C); if (m_hFile == -1) if (bThrow) CZipException::Throw(errno, lpszFileName); else return false; m_szFileName = lpszFileName; return true; } void CZipFile::SetLength(ULONGLONG uNewLen) { ZipPlatform::TruncateFile(m_hFile, uNewLen); } ZIP_FILE_USIZE CZipFile::GetPosition() const { #ifndef __GNUC__ ZIP_FILE_USIZE ret = _tell(m_hFile); #else ZIP_FILE_USIZE ret = lseek(m_hFile, 0, SEEK_CUR); #endif if (ret == (ZIP_FILE_USIZE)-1) ThrowError(); return ret; } ZIP_FILE_USIZE CZipFile::Seek(ZIP_FILE_SIZE dOff, int nFrom) { // restricted to signed ZIP_FILE_SIZE ret = (ZIP_FILE_SIZE)_lseek(m_hFile, (long)dOff, nFrom); if (ret == -1) ThrowError(); return (ZIP_FILE_USIZE)ret; } void CZipFile::Flush() { if (!ZipPlatform::FlushFile(m_hFile)) ThrowError(); } CZipFile::operator HANDLE() { intptr_t fh = ZipPlatform::GetFileSystemHandle(m_hFile); if (fh == -1) ThrowError(); #if _MSC_VER >= 1300 return (HANDLE)fh; #else return (HANDLE)fh; #endif } #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/Sha1.h0000644000175000017500000000125611300022650020002 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// tuxcmd-modules-0.6.70+ds/zip/ZipArchive/Makefile0000644000175000017500000001231611300022650020474 0ustar salvisalvi# Makefile for ZipArchive library # Copyright (C) 2000 - 2007 Artpol Software - Tadeusz Dracz # For conditions of distribution and use, see copyright notice in License.txt # To install to /usr/lib and /usr/include, type: # make install # to install to a different directory change prefix #Define this variable to use the bzip2 library provided with the ZipArchive Library #otherwise, the system's bzip2 library will be used #INTERNAL_BZIP2 = 1 CC=g++ CCC=cc #CCC=gcc CFLAGS = -D ZIP_ARCHIVE_LNX #CFLAGS = ifdef INTERNAL_BZIP2 CFLAGS += -D ZIP_ARCHIVE_BZIP2_INTERNAL endif ZIPARCHLIB = libziparch.a ZIPPIELOCATION = ../Zippie/ ZLIBLOCATION = zlib/ ifdef INTERNAL_BZIP2 BZIP2LOCATION = bzip2/ endif INCLUDES = -I. -Izlib ifdef INTERNAL_BZIP2 INCLUDES += -Ibzip2 endif prefix = /usr #prefix = libdir = ${prefix}/lib includedir = ${prefix}/include zipardir = $(includedir)/ziparchive zlibdir = $(zipardir)/zlib ifdef INTERNAL_BZIP2 bzip2dir = $(zipardir)/bzip2 endif AR=ar rc RANLIB=ranlib .SUFFIXES: .c .cpp .c.o: $(CCC) $(CFLAGS) $(INCLUDES) -c -o $*.o $< .cpp.o: $(CC) $(CFLAGS) $(INCLUDES) -c $< OBJS = $(ZLIBLOCATION)adler32.o $(ZLIBLOCATION)compress.o $(ZLIBLOCATION)crc32.o $(ZLIBLOCATION)uncompr.o $(ZLIBLOCATION)deflate.o $(ZLIBLOCATION)trees.o \ $(ZLIBLOCATION)zutil.o $(ZLIBLOCATION)inflate.o $(ZLIBLOCATION)infback.o $(ZLIBLOCATION)inftrees.o $(ZLIBLOCATION)inffast.o\ ZipArchive.o ZipAutoBuffer.o ZipCentralDir.o \ ZipCompressor.o BaseLibCompressor.o Bzip2Compressor.o DeflateCompressor.o ZipCompatibility.o ZipException.o ZipFile_stl.o ZipFileHeader.o \ ZipMemFile.o ZipPlatformComm.o \ ZipStorage.o ZipString.o ZipExtraData.o ZipExtraField.o \ DirEnumerator.o FileFilter.o Wildcard.o \ ZipCryptograph.o ZipCrc32Cryptograph.o \ Aes.o Hmac.o RandomPool.o ZipAesCryptograph.o Sha1.o ifdef INTERNAL_BZIP2 OBJS += $(BZIP2LOCATION)bzlib.o $(BZIP2LOCATION)blocksort.o $(BZIP2LOCATION)bzcompress.o $(BZIP2LOCATION)crctable.o\ $(BZIP2LOCATION)decompress.o $(BZIP2LOCATION)huffman.o $(BZIP2LOCATION)randtable.o endif OBJP = ZipPathComponent_lnx.o ZipPlatform_lnx.o #OBJP = ZipPathComponent_win.o ZipPlatform_win.o $(ZIPARCHLIB): $(OBJS) $(OBJP) $(AR) $@ $(OBJS) $(OBJP) -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 adler32.o: zlib.h zconf.h compress.o: zlib.h zconf.h crc32.o: crc32.h zlib.h zconf.h deflate.o: deflate.h zutil.h zlib.h zconf.h inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inftrees.o: zutil.h zlib.h zconf.h inftrees.h trees.o: deflate.h zutil.h zlib.h zconf.h trees.h uncompr.o: zlib.h zconf.h zutil.o: zutil.h zlib.h zconf.h ifdef INTERNAL_BZIP2 bzlib.o: bzlib.h bzlib_private.h blocksort.o: bzlib_private.h bzcompress.o: bzlib_private.h crctable.o: bzlib_private.h decompress.o: bzlib_private.h huffman.o: bzlib_private.h randtable.o: bzlib_private.h endif ZipArchive.o: ZipArchive.h ZipAutoBuffer.o: ZipAutoBuffer.h ZipCentralDir.o: ZipCentralDir.h ZipCompressor.o: ZipCompressor.h BaseLibCompressor.o: BaseLibCompressor.h Bzip2Compressor.o: Bzip2Compressor.h DeflateCompressor.o: DeflateCompressor.h ZipCompatibility.o: ZipCompatibility.h ZipException.o: ZipException.h ZipFile_stl.o: ZipFile.h ZipFileHeader.o: ZipFileHeader.h ZipMemFile.o: ZipMemFile.h ZipStorage.o: ZipStorage.h ZipString.o: ZipString.h ZipExtraData.o: ZipExtraData.h ZipExtraField.o: ZipExtraField.h DirEnumerator.o: DirEnumerator.cpp FileFilter.o: FileFilter.cpp Wildcard.o: Wildcard.cpp ZipCryptograph.o: ZipCryptograph.h ZipCrc32Cryptograph.o: ZipCrc32Cryptograph.h Aes.o: Aes.h Hmac.o: Hmac.h RandomPool.o: RandomPool.h ZipAesCryptograph.o: ZipAesCryptograph.h Sha1.o: Sha1.h ZipPathComponent_lnx.o: ZipPathComponent.h #ZipPathComponent_win.o: ZipPathComponent.h ZipPlatform_lnx.o: ZipPlatform.h #ZipPlatform_win.o: ZipPlatform.h LIBS = -lstdc++ -lziparch ifndef INTERNAL_BZIP2 LIBS += -lbz2 endif clean: -rm -f *.o *~ $(ZIPARCHLIB) $(ZLIBLOCATION)*.o $(ZLIBLOCATION)*~ $(BZIP2LOCATION)*.o $(BZIP2LOCATION)*~ zippie: $(CC) -I$(zipardir) $(CFLAGS) -o zippie $(ZIPPIELOCATION)zippie.cpp $(ZIPPIELOCATION)CmdLine.cpp $(LIBS) #$(CC) -I$(zipardir) -L$(libdir) $(CFLAGS) -o zippie $(ZIPPIELOCATION)zippie.cpp $(ZIPPIELOCATION)CmdLine.cpp $(LIBS) cleanzippie: -rm -f zippie #-rm -f zippie.exe install: -@if [ ! -d $(includedir) ]; then mkdir $(includedir); fi -@if [ ! -d $(libdir) ]; then mkdir $(libdir); fi -@if [ ! -d $(zipardir) ]; then mkdir $(zipardir); fi -@if [ ! -d $(zlibdir) ]; then mkdir $(zlibdir); fi cp libziparch.a $(libdir) chmod 755 $(libdir)/$(ZIPARCHLIB) cp *.h $(zipardir) chmod 644 $(zipardir)/*h cp $(ZLIBLOCATION)*.h $(zlibdir) chmod 644 $(zlibdir)/*h ifdef INTERNAL_BZIP2 -@if [ ! -d $(bzip2dir) ]; then mkdir $(bzip2dir); fi cp $(BZIP2LOCATION)*.h $(bzip2dir) chmod 644 $(bzip2dir)/*h endif uninstall: rm -f $(zlibdir)/*h rm -f $(zipardir)/*h rm -f $(libdir)/$(ZIPARCHLIB) rmdir $(zlibdir) ifdef INTERNAL_BZIP2 rm -f $(bzip2dir)/*h rmdir $(bzip2dir) endif rmdir $(zipardir) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipException.cpp0000644000175000017500000001650111300022650022161 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipException.h" #include "zlib/zlib.h" #include ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// #if defined _MFC_VER && defined ZIP_ARCHIVE_MFC IMPLEMENT_DYNAMIC( CZipException, CException) #endif CZipException::CZipException(int iCause, LPCTSTR lpszZipName) #ifdef _MFC_VER :CException(TRUE) #endif { m_iCause = iCause; if (lpszZipName) m_szFileName = lpszZipName; } CZipException::~CZipException() throw() { } // inline void CZipException::Throw(int iZipError, LPCTSTR lpszZipName) // { // #ifdef _MFC_VER // throw new CZipException(iZipError, lpszZipName); // #else // CZipException e(iZipError, lpszZipName); // throw e; // #endif // MSVC++: ignore "Unreachable code" warning here, it's due to // optimizations // } #ifdef ZIP_ENABLE_ERROR_DESCRIPTION ZBOOL CZipException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError, UINT* ) { if (!lpszError || !nMaxError) return FALSE; CZipString sz = GetErrorDescription(); if (sz.IsEmpty()) return FALSE; UINT iLen = sz.GetLength(); if (nMaxError - 1 < iLen) iLen = nMaxError - 1; LPTSTR lpsz = sz.GetBuffer(iLen); #if _MSC_VER >= 1400 #ifdef _UNICODE wcsncpy_s(lpszError, nMaxError, lpsz, iLen); #else strncpy_s(lpszError, nMaxError, lpsz, iLen); #endif #else #ifdef _UNICODE wcsncpy(lpszError, lpsz, iLen); #else strncpy(lpszError, lpsz, iLen); #endif #endif lpszError[iLen] = _T('\0'); return TRUE; } CZipString CZipException::GetErrorDescription() { return GetInternalErrorDescription(m_iCause); } CZipString CZipException::GetSystemErrorDescription() { #ifdef WIN32 DWORD x = GetLastError(); if (x) { LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS, NULL, x, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); CZipString sz = (LPCTSTR)lpMsgBuf; LocalFree(lpMsgBuf); return sz; } #endif return GetInternalErrorDescription(errno == 0 ? genericError : errno, true); } CZipString CZipException::GetInternalErrorDescription(int iCause, bool bNoLoop) { CZipString sz; switch (iCause) { case EROFS: sz = _T("Read-only file system."); break; case ESPIPE: sz = _T("Illegal seek."); break; case ENOSPC: sz = _T("No space left on device."); break; case EFBIG: sz = _T("File too large."); break; case EMFILE: sz = _T("Too many open files."); break; case ENFILE: sz = _T("File table overflow."); break; case EINVAL: sz = _T("Invalid argument."); break; case EISDIR: sz = _T("Is a directory."); break; case ENOTDIR: sz = _T("Not a directory."); break; case ENODEV: sz = _T("No such device."); break; case EXDEV: sz = _T("Cross-device link."); break; case EEXIST: sz = _T("File exists."); break; case EFAULT: sz = _T("Bad address."); break; case EACCES: sz = _T("Permission denied."); break; case ENOMEM: sz = _T("Not enough space."); break; case EBADF: sz = _T("Bad file number."); break; case ENXIO: sz = _T("No such device or address."); break; case EIO: sz = _T("I/O error."); break; case EINTR: sz = _T("Interrupted system call."); break; case ENOENT: sz = _T("No such file or directory."); break; case EPERM: sz = _T("Not super-user."); break; case badZipFile: sz = _T("Damaged or not a zip file."); break; case badCrc: sz = _T("Crc is mismatched."); break; case noCallback: sz = _T("There is no spanned archive callback object set."); break; case aborted: sz = _T("Volume change aborted in a segmented archive."); break; case abortedAction: sz = _T("Action aborted."); break; case abortedSafely: sz = _T("Action aborted safely."); break; case nonRemovable: sz = _T("The device selected for the spanned archive is not removable."); break; case tooManyVolumes: sz = _T("The limit of the maximum volumes reached."); break; case tooManyFiles: sz = _T("The limit of the maximum files in an archive reached."); break; case tooLongData: sz = _T("The filename, the comment or the local or central extra field of the file added to the archive is too long."); break; case tooBigSize: sz = _T("The file size is too large to be supported."); break; case badPassword: sz = _T("An incorrect password set for the file being decrypted."); break; case dirWithSize: sz = _T("The directory with a non-zero size found while testing."); break; case internalError: sz = _T("An internal error."); break; case notRemoved: sz.Format(_T("%s (%s)."), _T("Error while removing a file"), (LPCTSTR)GetSystemErrorDescription()); break; case notRenamed: sz.Format(_T("%s (%s)."), _T("Error while renaming a file"), (LPCTSTR)GetSystemErrorDescription()); break; case platfNotSupp: sz = _T("Cannot create a file for the specified platform."); break; case cdirNotFound: sz = _T("The central directory was not found in the archive (or you were trying to open not the last volume of a segmented archive)."); break; case noZip64: sz = _T("The Zip64 format has not been enabled for the library, but is required to use the archive."); break; case noAES: sz = _T("WinZip AES encryption has not been enabled for the library, but is required to decompress the archive."); break; #ifdef ZIP_ARCHIVE_STL case outOfBounds: sz = _T("The collection is empty and the bounds do not exist."); break; #endif #ifdef ZIP_ARCHIVE_USE_LOCKING case mutexError: sz = _T("Locking or unlocking resources access was unsuccessful."); break; #endif case streamEnd: sz = _T("Zlib library error (end of stream)."); break; case errNo: sz = GetInternalErrorDescription(errno != errNo ? errno : genericError); break; case streamError: sz = _T("Zlib library error (stream error)."); break; case dataError: sz = _T("Zlib library error (data error)."); break; case memError: sz = _T("Not enough memory."); break; case bufError: sz = _T("Zlib library error (buffer error)."); break; case versionError: sz = _T("Zlib library error (version error)."); break; default: sz = bNoLoop ? _T("Unknown error") :(LPCTSTR) GetSystemErrorDescription(); } return sz; } #endif //ZIP_ENABLE_ERROR_DESCRIPTION tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipMutex_lnx.h0000644000175000017500000000341511300022650021653 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #ifndef ZIPARCHIVE_ZIPMUTEX_DOT_H #error Do not include this file directly. Include ZipMutex.h instead #endif #ifdef ZIP_ARCHIVE_USE_LOCKING #include namespace ZipArchiveLib { class ZIP_API CZipMutex { pthread_mutex_t m_mutex; bool m_bOpened; public: CZipMutex(bool bOpen = false) { if (bOpen) Open(); else m_bOpened = false; } void Open() { Close(); if (pthread_mutex_init(&m_mutex, NULL) == 0) m_bOpened = true; else CZipException::Throw(CZipException::mutexError); } void Lock() { if (pthread_mutex_lock(&m_mutex) != 0) CZipException::Throw(CZipException::mutexError); } void Unlock() { if (pthread_mutex_unlock(&m_mutex) != 0) CZipException::Throw(CZipException::mutexError); } CZipMutex& operator=(const CZipMutex&) { m_bOpened = false; return *this; } void Close() { if (m_bOpened) if (pthread_mutex_destroy(&m_mutex) == 0) m_bOpened = false; else CZipException::Throw(CZipException::mutexError); } ~CZipMutex() { Close(); } }; } #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipAesCryptograph.cpp0000644000175000017500000000131011300022650023146 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "_features.h" tuxcmd-modules-0.6.70+ds/zip/ZipArchive/std_stl.h0000644000175000017500000000642011300022650020660 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #ifndef ZIPARCHIVE_STDAFX_DOT_H #error Do not include this file directly. Include stdafx.h instead #endif #include "_features.h" #include #if _MSC_VER > 1000 // STL warnings #pragma warning (disable : 4710) // 'function' : function not inlined #pragma warning (disable : 4514) // unreferenced inline/local function has been removed #pragma warning (disable : 4786) // 'identifier' : identifier was truncated to 'number' characters in the debug information #pragma warning (disable : 4702) // unreachable code #endif #if defined (_UNICODE) && !defined (UNICODE) #define UNICODE #endif #if defined (UNICODE) && !defined (_UNICODE) #define _UNICODE #endif #ifndef _WIN32 #ifndef NULL #define NULL 0 #endif #include typedef int HFILE; typedef void* HANDLE; typedef unsigned long DWORD; typedef long LONG; typedef int ZBOOL; /* to avoid conflicts when using Objective-C under Mac */ typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned int UINT; #ifndef FALSE #define FALSE (int)0 #endif #ifndef TRUE #define TRUE (int)1 #endif typedef unsigned short WCHAR; // wc, 16-bit UNICODE character typedef const WCHAR *LPCWSTR; typedef const char *LPCSTR; typedef WCHAR *LPWSTR; typedef char *LPSTR; #ifdef _UNICODE typedef wchar_t TCHAR; typedef LPCWSTR LPCTSTR; typedef LPWSTR LPTSTR; #define _T(x) L ## x #else /* _UNICODE */ // r_winnt typedef char TCHAR; typedef LPCSTR LPCTSTR; typedef LPSTR LPTSTR; #ifdef _T #undef _T #endif #define _T(x) x #endif /* _UNICODE */ // r_winnt typedef unsigned long long ULONGLONG; typedef long long LONGLONG; #define CP_ACP 0 #define CP_OEMCP 1 #ifndef _I64_MAX #ifdef LLONG_MAX #define _I64_MAX LLONG_MAX #else #define _I64_MAX LONG_LONG_MAX #endif #endif #ifndef _UI64_MAX #ifdef ULLONG_MAX #define _UI64_MAX ULLONG_MAX #else #define _UI64_MAX ULONG_LONG_MAX #endif #endif #define _lseeki64 lseek64 #else #include #include #include #ifndef STRICT #define STRICT #endif typedef BOOL ZBOOL; #endif // #ifndef _WIN32 #ifndef ASSERT #include #define ASSERT(f) assert((f)) #endif #ifndef VERIFY #ifdef _DEBUG #define VERIFY(x) ASSERT((x)) #else #define VERIFY(x) x #endif #endif #define ZIP_FILE_USIZE ULONGLONG #define ZIP_FILE_SIZE LONGLONG #define ZIP_FILE_SIZEMAX _I64_MAX tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCryptograph.cpp0000644000175000017500000000335611300022650022531 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipCryptograph.h" #include "ZipAesCryptograph.h" #include "ZipCrc32Cryptograph.h" CZipCryptograph* CZipCryptograph::CreateCryptograph(int iEncryptionMethod) { if (iEncryptionMethod == encNone) return NULL; return new CZipCrc32Cryptograph(); } DWORD CZipCryptograph::GetEncryptedInfoSize(int iEncryptionMethod) { if (iEncryptionMethod != encNone) { if (iEncryptionMethod == encStandard) return CZipCrc32Cryptograph::GetEncryptedInfoSizeBeforeData() + CZipCrc32Cryptograph::GetEncryptedInfoSizeAfterData(); } return 0; } DWORD CZipCryptograph::GetEncryptedInfoSizeBeforeData(int iEncryptionMethod) { if (iEncryptionMethod != encNone) { if (iEncryptionMethod == encStandard) return CZipCrc32Cryptograph::GetEncryptedInfoSizeBeforeData(); } return 0; } DWORD CZipCryptograph::GetEncryptedInfoSizeAfterData(int iEncryptionMethod) { if (iEncryptionMethod != encNone) { if (iEncryptionMethod == encStandard) return CZipCrc32Cryptograph::GetEncryptedInfoSizeAfterData(); } return 0; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCollections_stl.h0000644000175000017500000001457411300022650023040 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #ifndef ZIPARCHIVE_ZIPCOLLECTIONS_DOT_H #error Do not include this file directly. Include ZipCollections.h instead #endif #if _MSC_VER > 1000 #pragma warning( push, 3 ) // STL #pragma warning (disable : 4284) //return type for 'identifier::operator >' is not a UDT or reference to a UDT. Will produce errors if applied using infix notation #pragma warning (disable : 4018) //'expression' : signed/unsigned mismatch #endif #include #include #include #include #include #include "ZipString.h" #include "ZipException.h" #define ZIP_ARRAY_SIZE_TYPE size_t template class CZipArray : private std::vector { public: typedef int (*CompareFunction)(const void* pArg1, const void* pArg2); private: struct Sorter { CompareFunction m_pFunction; Sorter(CompareFunction pFunction) { m_pFunction = pFunction; } bool operator ()(TYPE const& t1, TYPE const& t2) { return (*m_pFunction)(&t1, &t2) < 0; } }; public: typedef typename std::vector::iterator iterator; typedef typename std::vector inherited; protected: iterator GetIterFromIndex(size_t uIndex) { iterator iter = this->begin(); iter += uIndex; // int t = 0; while (t != uIndex) {iter++;t++;} return iter; } public: void Sort(bool bAscending) { if (bAscending) std::sort (this->begin(), this->end(), std::less()); else std::sort (this->begin(), this->end(), std::greater()); } void Sort(CompareFunction pFunction) { std::sort(this->begin(), this->end(), Sorter(pFunction)); } size_t GetSize() const{return this->size(); } size_t GetCount() const{return this->size(); } size_t GetUpperBound() const { size_t ret = this->size(); if (ret == 0) CZipException::Throw(CZipException::outOfBounds); return ret - 1; } TYPE& GetAt(size_t uIndex) {return this->at(uIndex);} const TYPE& GetAt(size_t uIndex) const {return this->at(uIndex);} size_t Add(const TYPE& x) {push_back(x);return GetUpperBound();} void RemoveAll() {this->clear();} void RemoveAt(size_t uIndex) { erase(GetIterFromIndex(uIndex));} void InsertAt(size_t uIndex, const TYPE& x){insert(GetIterFromIndex(uIndex), x);} TYPE& operator[](size_t uIndex) { return inherited::operator[](uIndex); } TYPE operator[](size_t uIndex) const { return inherited::operator[](uIndex); } }; typedef CZipArray CZipStringArray; typedef CZipArray CZipWordArray; template class CZipPtrList : private std::list { public: typedef typename std::list::iterator iterator; typedef typename std::list::const_iterator const_iterator; size_t GetCount() const {return this->size();} void AddTail(const TYPE& x){push_back(x);} void AddHead(const TYPE& x){push_front(x);} void RemoveHead() {this->pop_front();} void RemoveTail() {this->pop_back();} void RemoveAll() {this->clear();} TYPE& GetHead() {return this->front();} TYPE GetHead() const {return this->front();} TYPE& GetTail() {return this->back();} TYPE GetTail() const {return this->back();} iterator GetHeadPosition() { return this->begin();} const_iterator GetHeadPosition() const { return this->begin();} iterator GetTailPosition() { return this->back();} TYPE& GetNext(iterator& pos) { return *pos++;} const TYPE GetNext(const_iterator& pos) const{ return *pos++;} TYPE& GetPrev(iterator& pos) { return *pos--;} TYPE GetPrev(iterator& pos) const{ return *pos--;} iterator Find(TYPE& x) { return std::find(this->begin(), this->end(), x);} void RemoveAt(iterator& pos) { erase(pos);} bool IteratorValid(const_iterator &iter) const { return iter != this->end(); } bool IteratorValid(iterator &iter) { return iter != this->end(); } iterator FindIndex(size_t uIndex) { iterator iter = this->begin(); size_t t = 0; while (t != uIndex) {iter++;t++;} return iter; } const_iterator FindIndex(size_t uIndex) const { const_iterator iter = this->begin(); size_t t = 0; while (t != uIndex) {iter++;t++;} return iter; } TYPE& GetAt(const iterator& pos) { return *pos;} TYPE GetAt(const_iterator& pos) const{ return *pos;} }; // simplified and partial only template class CZipMap : private std::map { public: typedef typename std::map::iterator iterator; typedef typename std::map::const_iterator const_iterator; typedef typename std::map, std::allocator > >::value_type v_type; void SetAt( KEY key, VALUE newValue) { insert(v_type(key, newValue)); } ZBOOL RemoveKey( KEY key ) { return erase(key) != 0; } ZBOOL Lookup( KEY key, VALUE& rValue ) const { #if (__GNUC__ >= 3) // The actual version number may be different. const_iterator iter = std::map::find(key); if (iter == std::map::end()) #else const_iterator iter = find(key); if (iter == end()) #endif return FALSE; else { rValue = iter->second; return TRUE; } } iterator GetStartPosition() { return this->begin();} const_iterator GetStartPosition() const { return this->begin();} bool IteratorValid(const_iterator &iter) const { return iter != this->end(); } bool IteratorValid(iterator &iter) { return iter != this->end(); } void GetNextAssoc(iterator &iter, KEY& key, VALUE& value) { key = iter->first; value = iter->second; iter++; } void GetNextAssoc(const_iterator &iter, KEY& key, VALUE& value) { key = iter->first; value = iter->second; iter++; } void RemoveAll() {this->clear();} }; #if _MSC_VER > 1000 #pragma warning( pop) #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/Bzip2Compressor.h0000644000175000017500000000125611300022650022251 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// tuxcmd-modules-0.6.70+ds/zip/ZipArchive/Aes.cpp0000644000175000017500000000131011300022650020240 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "_features.h" tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipStorage.h0000644000175000017500000003340311300022650021274 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipStorage.h * Includes the CZipStorage class. * */ #if !defined(ZIPARCHIVE_ZIPSTORAGE_DOT_H) #define ZIPARCHIVE_ZIPSTORAGE_DOT_H #if _MSC_VER > 1000 #pragma once #if defined ZIP_HAS_DLL #pragma warning (push) #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class #endif #endif #include "ZipFile.h" #include "ZipAutoBuffer.h" #include "ZipString.h" #include "ZipMemFile.h" #include "ZipExport.h" #include "ZipCallback.h" /** Represents the storage layer for an archive. */ class ZIP_API CZipStorage { friend class CZipArchive; friend class CZipCentralDir; public: /** The type of the segmentation of the archive. \see 0610051553 \see CZipArchive::GetSegmMode */ enum ZipSegmentationMode { noSegments, ///< No archive segmentation. spannedArchive, ///< A spanned archive. splitArchive, ///< A split archive. /** The archive segmentation type will be auto-detected. If the archive is on the removable device, assume a spanned archive, otherwise assume a split archive. */ suggestedAuto, /** If a segmented archive is on a removable device, assume a split archive. Normally you create spanned archives on removable devices. */ suggestedSplit }; /** The direction of seeking operation. \see CZipStorage::Seek */ enum SeekType { seekFromBeginning, ///< Start seeking from the beginning of a file. seekFromEnd, ///< Start seeking from the end of a file. /** Start seeking from the current position in an archive. This value can cause a volume change when a segmented archive is opened for reading. */ seekCurrent }; CZipStorage(); virtual ~CZipStorage(); void Initialize(); /** Opens a new or existing archive in memory. The meaning for the parameters is the same as in the CZipArchive::Open(CZipAbstractFile& , int) method. */ void Open(CZipAbstractFile& af, int iMode); /** Opens or creates an archive. The meaning for the parameters is the same as in the CZipArchive::Open(LPCTSTR, int, ZIP_SIZE_TYPE) method. */ void Open(LPCTSTR lpszPathName, int iMode, ZIP_SIZE_TYPE uVolumeSize); /** Closes a segmented archive in creation and reopens it as an existing segmented archive (no modifications allowed). The archive may also turn out to be a not segmented archive. */ void FinalizeSegm(); /** Called only by CZipCentralDir::Read when opening an existing archive. \param uLastVolume The number of the volme the central directory is on. \note Throws exceptions. */ void UpdateSegmMode(ZIP_VOLUME_TYPE uLastVolume); /** Ensures than in a segmented archive, there is enough free space on the current volume. \param uNeeded The size of the required free space in bytes. \return The number of free bytes on the current volume. \note Throws exceptions. */ ZIP_SIZE_TYPE AssureFree(ZIP_SIZE_TYPE uNeeded); /** Writes a chunk of data to the archive. \param pBuf The buffer with data. \param iSize The number of bytes to write. \param bAtOnce If \c true, the whole chunk must fit in the current volume. If there is not enough free space, a volume change is performed. \note Throws exceptions. */ void Write(const void *pBuf, DWORD iSize, bool bAtOnce); /** Gets the total size currently occupied by the archive. \return The length of the current archive file increased by the number of bytes in the write buffer. */ ZIP_SIZE_TYPE GetOccupiedSpace() const { return ZIP_SIZE_TYPE(m_pFile->GetLength() + m_uBytesInWriteBuffer); } /** The same as the CZipArchive::IsClosed method. */ bool IsClosed(bool bArchive) const { if (bArchive) return GetCurrentVolume() == ZIP_VOLUME_NUMBER_UNSPECIFIED; else return !m_pFile || !m_bInMemory && m_pFile->IsClosed(); } /** Reads a chunk of data from the archive. \param pBuf The buffer to receive the data. \param iSize The number of bytes to read. \param bAtOnce If \c true, the specified number of bytes must be read from the same volume (no volume change is allowed). \note Throws exceptions. */ DWORD Read(void* pBuf, DWORD iSize, bool bAtOnce); /** Gets the position in the file, taking into account the number of bytes in the write buffer and the number of bytes before the archive. \return The position in the file. \note Throws exceptions. */ ZIP_SIZE_TYPE GetPosition() const { ZIP_SIZE_TYPE uPos = (ZIP_SIZE_TYPE)(m_pFile->GetPosition()) + m_uBytesInWriteBuffer; if (m_uCurrentVolume == 0) uPos -= m_uBytesBeforeZip; return uPos; } /** Flushes the data from the read buffer to the disk. \note Throws exceptions. */ void Flush(); /** Forces any data remaining in the file buffer to be written to the disk. */ void FlushFile() { if (!m_bInMemory && !IsReadOnly()) m_pFile->Flush(); } void FlushBuffers() { Flush(); FlushFile(); } /** Changes volumes during writing to a segmented archive. \param uNeeded The number of bytes needed in the volume. \note Throws exceptions. */ void NextVolume(ZIP_SIZE_TYPE uNeeded); /** Gets a zero-based number of the current volume. */ ZIP_VOLUME_TYPE GetCurrentVolume() const {return m_uCurrentVolume;} /** Changes the volume during extract operations. \param uNumber A zero-based number of the requested volume. */ void ChangeVolume(ZIP_VOLUME_TYPE uNumber); /** Changes the current volume to the next volume during extract operations. */ void ChangeVolume() { ChangeVolume((ZIP_VOLUME_TYPE)(m_uCurrentVolume + 1)); } /** Detects the segmentation mode. \return - \c -1 : An existing segmented archive is opened. - \c 0 : The archive is not segmented. - \c 1 : A segmented archive in creation. */ int IsSegmented() const { return m_iSegmMode == noSegments ? 0 : (m_bNewSegm ? 1 : -1); } /** Checks, if the archive is a split archive. \return \c true, if the archive is a split archive; \c false otherwise. */ bool IsSplit() const { return m_iSegmMode == splitArchive; } /** Checks, if the archive is a spanned archive. \return \c true, if the archive is a spanned archive; \c false otherwise. */ bool IsSpanned() const { return m_iSegmMode == spannedArchive; } /** The same as the CZipArchive::IsReadOnly method. */ bool IsReadOnly() { return m_bReadOnly || IsSegmented() < 0; } /** Performs the seeking operation on the #m_pFile. \param lOff The new position in the file. \param iSeekType The direction of the seek operation. It can be one of the #SeekType values. */ ULONGLONG Seek(ULONGLONG lOff, SeekType iSeekType = seekFromBeginning); /** Gets the number of free bytes on the current volume. \return The number of free bytes on the current volume. */ ZIP_SIZE_TYPE VolumeLeft() const; /** Closes the storage. \param bAfterException Set to \c true, if an exception was thrown before. \return The file path of the archive. \note Throws exceptions. */ CZipString Close(bool bAfterException); /** Represents the physical storage of the current archive segment. */ CZipAbstractFile* m_pFile; /** The signature of the extended header. */ static char m_gszExtHeaderSignat[]; protected: /** Returns the file offset after the last data byte in the archive. \return The file offset after the last data byte in the archive. */ ZIP_SIZE_TYPE GetLastDataOffset() { return (ZIP_SIZE_TYPE)m_pFile->GetLength() - m_uBytesBeforeZip; } /** Reverse-finds the location of the given signature starting from the current position in file. \param szSignature The signature to locate. \param uMaxDepth The maximum number of bytes to search for \a szSignature. \return The location of the signature. \note Throws exceptions. */ ZIP_FILE_USIZE LocateSignature(char* szSignature, ZIP_SIZE_TYPE uMaxDepth); /** Flushes without writing. Can be used only on not segmented archives. */ void EmptyWriteBuffer() { m_uBytesInWriteBuffer = 0; } /** Opens a physical file. \param lpszName The name of the file to open. \param uFlags The file open flags. \param bThrow If \c true, throw an exception in case of failure. \return \c true if successful; \c false otherwise. */ bool OpenFile(LPCTSTR lpszName, UINT uFlags, bool bThrow = true); /** Renames the last segment file in a split archive when finalizing the whole archive. \return The name of the last segment. */ CZipString RenameLastFileInSplitArchive(); /** Writes data to the internal buffer. \param *pBuf The buffer to copy the data from. \param uSize The number of bytes to write. \note Throws exceptions. */ void WriteInternalBuffer(const char *pBuf, DWORD uSize); /** Gets the free space size on the current removable disk. \return The free space in bytes. */ ZIP_SIZE_TYPE GetFreeVolumeSpace() const; /** Notifies the callback object. Throws an exception if the callback method returns \c false. \param uNeeded The minimum number of free bytes required on the disk. \param iCode The code to be passed to the callback method. \param szTemp The string to be used as a filename (as an argument in the CZipException::Throw method) when an exception must be thrown. \note Throws exceptions. \see CZipArchive::SetSegmCallback */ void CallCallback(ZIP_SIZE_TYPE uNeeded, int iCode, CZipString szTemp); /** Constructs the name of a segment in a split archive. \param bLast Set it to \c true, if constructing the last volume name. \return The segment name. */ CZipString GetSplitVolumeName(bool bLast) const; /** Changes a file when processing a split archive. */ CZipString ChangeSplitRead(); /** Changes a disk when processing a spanned archive. */ CZipString ChangeSpannedRead(); /** Gets the free space left in the write buffer. \return The free space left in the write buffer in bytes. */ DWORD GetFreeInBuffer() const {return m_pWriteBuffer.GetSize() - m_uBytesInWriteBuffer;} /** The value it holds, depends on the current mode: - An opened existing split archive - stores the number of the last volume ( the one with "zip" extension). - A split archive in creation - the size of the volume. This method is used only when processing split archives. */ ZIP_SIZE_TYPE m_uSplitData; /** The extension of the last segment. */ CZipString m_szSplitExtension; /** The number of bytes available in the write buffer. */ DWORD m_uBytesInWriteBuffer; /** The value it holds depends on the segmentation mode: - A split archive : the total size of the current volume. - A spanned archive: the free space on the current volume. */ ZIP_SIZE_TYPE m_uCurrentVolSize; /** The write buffer caching data. */ CZipAutoBuffer m_pWriteBuffer; /** Stores the number of bytes that have been written physically to the current segment. Used only when processing a segmented archive in creation. */ ZIP_SIZE_TYPE m_uBytesWritten; /** \c true, if the current archive is a new segmented archive; \c false otherwise. */ bool m_bNewSegm; /** The current volume number in a segmented archive. The value is zero-based. */ ZIP_VOLUME_TYPE m_uCurrentVolume; /** \c true when the archive is created in memory; \c false otherwise. */ bool m_bInMemory; /** \c true if OpenMode::zipOpenReadOnly was specified when opening the archive. */ bool m_bReadOnly; /** The number of bytes before the actual zip archive in a file. \see CZipArchive::GetBytesBeforeZip */ ZIP_SIZE_TYPE m_uBytesBeforeZip; /** The size of the write buffer. \see CZipArchive::SetAdvanced */ int m_iWriteBufferSize; /** The size of the buffer used in searching for the central directory. \see CZipArchive::SetAdvanced */ int m_iLocateBufferSize; /** Takes one of the #ZipSegmentationMode values. */ int m_iSegmMode; /** A callback object called when there is a need for a volume change in a spanned archive. \see CZipArchive::SetSegmCallback */ CZipSegmCallback* m_pSpanChangeVolumeFunc; /** A callback object called when there is a need for a volume change in a split archive. \see CZipArchive::SetSegmCallback */ CZipSegmCallback* m_pSplitChangeVolumeFunc; private: CZipSegmCallback* m_pChangeVolumeFunc; CZipString m_szArchiveName; CZipFile m_internalfile; static const ZIP_FILE_USIZE SignatureNotFound; void ThrowError(int err); }; #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning (pop) #endif #endif // !defined(ZIPARCHIVE_ZIPSTORAGE_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCompatibility.h0000644000175000017500000000734211300022650022504 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipCompatibility.h * ZipCompatibility namespace declaration. * */ #if !defined(ZIPARCHIVE_ZIPCOMPATIBILITY_DOT_H) #define ZIPARCHIVE_ZIPCOMPATIBILITY_DOT_H #if _MSC_VER > 1000 #pragma once #endif class CZipAutoBuffer; class CZipFileHeader; #include "ZipString.h" /** Includes functions that provide support for the proper conversion of attributes and filenames between different system platforms. */ namespace ZipCompatibility { /** The codes of the compatibility of the file attribute information. \see CZipArchive::GetSystemCompatibility \see CZipFileHeader::GetSystemCompatibility \see ZipPlatform::GetSystemID */ enum ZipPlatforms { zcDosFat, ///< MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems) zcAmiga, ///< Amiga zcVaxVms, ///< VAX/VMS zcUnix, ///< Unix / Linux zcVmCms, ///< VM/CMS zcAtari, ///< Atari ST zcOs2Hpfs, ///< OS/2 H.P.F.S. zcMacintosh, ///< Macintosh zcZsystem, ///< Z-System zcCpm, ///< CP/M zcNtfs ///< Windows NTFS }; /** Checks whether the system with the given code is supported by the ZipArchive Library. \param iCode One of the #ZipPlatforms values to check. \return \c true, if supported; \c false otherwise. */ bool IsPlatformSupported(int iCode); /** Converts the system attributes between different system platforms. \param uAttr The attributes to convert. \param iFromSystem The system code to convert \a uAttr from. \param iToSystem The system code to convert \a uAttr to. \return The converted attributes. \note Throws exceptions. \see ZipPlatforms */ DWORD ConvertToSystem(DWORD uAttr, int iFromSystem, int iToSystem); /** Converts the string stored in \a buffer using the given code page. \param buffer The buffer to convert the string from. \param szString The string to receive the result. \param uCodePage The code page used in conversion. \see 0610051525 */ void ConvertBufferToString(CZipString& szString, const CZipAutoBuffer& buffer, UINT uCodePage); /** Converts the \a lpszString using the given code page. \param lpszString The string to convert from. \param buffer The buffer to receive the result. \param uCodePage The code page used in conversion. \see 0610051525 */ void ConvertStringToBuffer(LPCTSTR lpszString, CZipAutoBuffer& buffer, UINT uCodePage); /** Changes the path separators from slash to backslash or vice-versa in \a szFileName. \param szFileName The filename to have the path separators changed. \param bReplaceSlash If \c true, changes slash to backslash. If \c false, changes backslash to slash. */ void SlashBackslashChg(CZipString& szFileName, bool bReplaceSlash); }; #endif // !defined(ZIPARCHIVE_ZIPCOMPATIBILITY_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipMemFile.h0000644000175000017500000000541611300022650021211 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipMemFile.h * Includes the CZipMemFile class. * */ #if !defined(ZIPARCHIVE_ZIPMEMFILE_DOT_H) #define ZIPARCHIVE_ZIPMEMFILE_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "ZipAbstractFile.h" #include "ZipString.h" #include "ZipExport.h" /** Represents a file in memory. Automatically grows when necessary. */ class ZIP_API CZipMemFile : public CZipAbstractFile { protected: size_t m_nGrowBy, m_nPos; size_t m_nBufSize, m_nDataSize; BYTE* m_lpBuf; bool m_bAutoDelete; void Free() { if (m_lpBuf) { free(m_lpBuf); m_lpBuf = NULL; } } void Init() { m_nGrowBy = m_nPos = 0; m_nBufSize = m_nDataSize = 0; m_lpBuf = NULL; } void Grow(size_t nBytes); public: bool IsClosed() const { return m_lpBuf == NULL;} void Flush(){} ZIP_FILE_USIZE Seek(ZIP_FILE_SIZE lOff, int nFrom); ZIP_FILE_USIZE GetLength() const {return m_nDataSize;} void Write(const void* lpBuf, UINT nCount); UINT Read(void* lpBuf, UINT nCount); void SetLength(ZIP_FILE_USIZE nNewLen); CZipString GetFilePath() const {return _T("");} CZipMemFile(long nGrowBy = 1024) { Init(); m_nGrowBy = nGrowBy; m_bAutoDelete = true; } CZipMemFile(BYTE* lpBuf, UINT nBufSize, long nGrowBy = 0) { Init(); Attach(lpBuf, nBufSize, nGrowBy); } CZipMemFile(CZipMemFile& from) { Copy(from); } void Copy(CZipMemFile& from) { SetLength(from.m_nDataSize); from.Read(m_lpBuf, (UINT)from.m_nDataSize); } ZIP_FILE_USIZE GetPosition() const { return m_nPos;} void Attach(BYTE* lpBuf, UINT nBufSize, long nGrowBy = 0) { Close(); m_lpBuf = lpBuf; m_nGrowBy = nGrowBy; m_nBufSize = nBufSize; m_nDataSize = nGrowBy == 0 ? nBufSize : 0; m_bAutoDelete = false; } void ReInit(long nGrowBy = 1024) { Close(); Init(); m_nGrowBy = nGrowBy; m_bAutoDelete = true; } BYTE* Detach() { BYTE* b = m_lpBuf; Init(); return b; } void Close() { if (m_bAutoDelete) Free(); Init(); } virtual ~CZipMemFile(){Close();} }; #endif // !defined(ZIPARCHIVE_ZIPMEMFILE_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCentralDir.cpp0000644000175000017500000006717211300022650022264 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" //#include #include "ZipCentralDir.h" #include "ZipArchive.h" #include "ZipFileMapping.h" #include "ZipPlatform.h" #include "BytesWriter.h" #define CENTRAL_DIR_END_SIZE 22 using namespace ZipArchiveLib; char CZipCentralDir::m_gszSignature[] = {0x50, 0x4b, 0x05, 0x06}; char CZipCentralDir::m_gszSignature64Locator[] = {0x50, 0x4b, 0x06, 0x07}; CZipCentralDir::CZipCentralDir() { m_pInfo = NULL; m_pHeaders = NULL; m_pFindArray = NULL; m_pStorage = NULL; m_pOpenedFile = NULL; m_iIgnoredChecks = 0; m_pCallbacks = NULL; } void CZipCentralDir::Init(CZipStorage* pStorage, ZipArchiveLib::CZipCallbackProvider* pCallbacks, CZipStringStoreSettings* pStringSettings, CZipCentralDir* pSource) { m_pStorage = pStorage; m_pCallbacks = pCallbacks; m_pStringSettings = pStringSettings; m_pOpenedFile = NULL; m_iIgnoredChecks = CZipArchive::checkIgnoredByDefault; // just in case DestroySharedData(); if (pSource != NULL) { #ifdef ZIP_ARCHIVE_USE_LOCKING pSource->LockAccess(); #endif m_pInfo = pSource->m_pInfo; m_pInfo->m_iReference++; m_pHeaders = pSource->m_pHeaders; m_pFindArray = pSource->m_pFindArray; #ifdef ZIP_ARCHIVE_USE_LOCKING // points to the same object now UnlockAccess(); #endif m_pStorage->UpdateSegmMode(m_pInfo->m_uLastVolume); m_pStorage->m_uBytesBeforeZip = pSource->m_pStorage->m_uBytesBeforeZip; } else CreateSharedData(); } CZipCentralDir::~CZipCentralDir() { DestroySharedData(); } void CZipCentralDir::Read(bool bExhaustiveRead) { if (!m_pStorage) { ASSERT(FALSE); return; } m_pStorage->m_pFile->SeekToEnd(); // maximum size of end of central dir record m_pInfo->m_uEndOffset = (ZIP_SIZE_TYPE)m_pStorage->LocateSignature(m_gszSignature, 0xFFFF + CENTRAL_DIR_END_SIZE); if (m_pInfo->m_uEndOffset == CZipStorage::SignatureNotFound) ThrowError(CZipException::cdirNotFound); m_pStorage->m_pFile->Seek((ZIP_FILE_USIZE)(m_pInfo->m_uEndOffset + 4)); CZipAutoBuffer buf(CENTRAL_DIR_END_SIZE); // we can skip the signature, we already know it is good - it was found int uRead = m_pStorage->m_pFile->Read(buf, CENTRAL_DIR_END_SIZE - 4); if (uRead != CENTRAL_DIR_END_SIZE - 4) ThrowError(CZipException::badZipFile); WORD uCommentSize; CBytesWriter::ReadBytes(m_pInfo->m_uLastVolume, buf, 2); CBytesWriter::ReadBytes(m_pInfo->m_uVolumeWithCD, buf + 2, 2); CBytesWriter::ReadBytes(m_pInfo->m_uVolumeEntriesNo,buf + 4, 2); CBytesWriter::ReadBytes(m_pInfo->m_uEntriesNumber,buf + 6, 2); CBytesWriter::ReadBytes(m_pInfo->m_uSize, buf + 8, 4); CBytesWriter::ReadBytes(m_pInfo->m_uOffset, buf + 12, 4); CBytesWriter::ReadBytes(uCommentSize, buf + 16); buf.Release(); if (uCommentSize) { m_pInfo->m_pszComment.Allocate(uCommentSize); uRead = m_pStorage->m_pFile->Read(m_pInfo->m_pszComment, uCommentSize); if (uRead != uCommentSize) ThrowError(CZipException::badZipFile); } if ( m_pInfo->NeedsZip64() ) { m_pStorage->m_pFile->Seek((ZIP_FILE_USIZE)(m_pInfo->m_uEndOffset)); ULONGLONG uPosition = m_pStorage->LocateSignature(m_gszSignature64Locator, ZIP_SIZE_TYPE(-1)); if (uPosition != CZipStorage::SignatureNotFound) ThrowError(CZipException::noZip64); // when the zip64 locator is not found, try to treat this archive as normal } // if m_uLastVolume is not zero, it is enough to say that it is a multi-volume archive ASSERT((!m_pInfo->m_uLastVolume && (m_pInfo->m_uEntriesNumber == m_pInfo->m_uVolumeEntriesNo) && !m_pInfo->m_uVolumeWithCD) || m_pInfo->m_uLastVolume); m_pStorage->UpdateSegmMode(m_pInfo->m_uLastVolume); if (!m_pStorage->IsSegmented() && !m_pInfo->CheckIfOK_1()) ThrowError(CZipException::badZipFile); if (m_pStorage->m_uBytesBeforeZip == 0 && m_pInfo->m_uLastVolume == 0) m_pStorage->m_uBytesBeforeZip = m_pInfo->CalculateBytesBeforeZip(); if (!m_pInfo->CheckIfOK_2()) ThrowError(CZipException::badZipFile); m_pInfo->m_bInArchive = true; m_pStorage->ChangeVolume(m_pInfo->m_uVolumeWithCD); if (!m_pInfo->m_uSize) return; ReadHeaders(bExhaustiveRead); } void CZipCentralDir::ThrowError(int err) const { CZipException::Throw(err, m_pStorage->m_pFile->GetFilePath()); } void CZipCentralDir::ReadHeaders(bool bExhaustiveRead) { m_pStorage->Seek(m_pInfo->m_uOffset); RemoveHeaders(); //just in case for (ZIP_INDEX_TYPE i = 0; i < m_pInfo->m_uEntriesNumber; i++) { CZipFileHeader* pHeader = new CZipFileHeader; m_pHeaders->Add(pHeader); if (!pHeader->Read(*this, true)) ThrowError(CZipException::badZipFile); } if (bExhaustiveRead) { ZIP_FILE_USIZE uPosition = m_pStorage->m_pFile->GetPosition(); // different offset, or different parts if (uPosition != m_pInfo->m_uEndOffset || m_pStorage->IsSegmented() && m_pStorage->GetCurrentVolume() != m_pInfo->m_uLastVolume) for(;;) { CZipAutoBuffer buf(4); m_pStorage->Read(buf, 4, true); if (!CZipFileHeader::VerifySignature(buf)) break; CZipFileHeader* pHeader = new CZipFileHeader; m_pHeaders->Add(pHeader); if (!pHeader->Read(*this, false)) ThrowError(CZipException::badZipFile); } } // this is necessary when removing data descriptors, CZipArchive::MakeSpaceForReplace, deleting, replacing or encrypting files // sort always, to yield the same results in requesting files by index regardless of the reason for opening m_pHeaders->Sort(CompareHeaders); RebuildFindFastArray(); } void CZipCentralDir::Close() { m_pOpenedFile = NULL; DestroySharedData(); // do not reference it anymore m_pInfo = NULL; m_pHeaders = NULL; m_pFindArray = NULL; } bool CZipCentralDir::IsValidIndex(ZIP_INDEX_TYPE uIndex)const { return uIndex < (ZIP_INDEX_TYPE)m_pHeaders->GetSize() && uIndex != ZIP_FILE_INDEX_UNSPECIFIED; } void CZipCentralDir::OpenFile(ZIP_INDEX_TYPE uIndex) { CZipFileHeader* pOpenedFile = (*this)[uIndex]; m_pStorage->ChangeVolume(pOpenedFile->m_uVolumeStart); m_pStorage->Seek(pOpenedFile->m_uOffset); if (!pOpenedFile->ReadLocal(*this)) ThrowError(CZipException::badZipFile); m_pOpenedFile = pOpenedFile; } void CZipCentralDir::CloseFile(bool skipCheckingDataDescriptor) { if (!m_pOpenedFile) return; if (!skipCheckingDataDescriptor && IsConsistencyCheckOn(CZipArchive::checkDataDescriptor) && !m_pOpenedFile->CheckDataDescriptor(m_pStorage)) ThrowError(CZipException::badZipFile); m_pOpenedFile = NULL; } // add new header using the argument as a template CZipFileHeader* CZipCentralDir::AddNewFile(const CZipFileHeader & header, ZIP_INDEX_TYPE uReplaceIndex, int iLevel, bool bRichHeaderTemplateCopy) { // copy some of the template data m_pOpenedFile = NULL; ZIP_INDEX_TYPE uIndex; CZipFileHeader* pHeader = new CZipFileHeader(); try { pHeader->m_uMethod = header.m_uMethod; pHeader->m_uModDate = header.m_uModDate; pHeader->m_uModTime = header.m_uModTime; pHeader->m_uExternalAttr = header.m_uExternalAttr; pHeader->m_uLocalComprSize = header.m_uLocalComprSize; pHeader->m_uLocalUncomprSize = header.m_uLocalUncomprSize; if (header.m_pszFileName != NULL) pHeader->m_pszFileName = new CZipString(*header.m_pszFileName); pHeader->m_pszFileNameBuffer = header.m_pszFileNameBuffer; pHeader->m_pszComment = header.m_pszComment; pHeader->m_aLocalExtraData = header.m_aLocalExtraData; // local will be removed in a moment in PrepareData pHeader->m_aCentralExtraData = header.m_aCentralExtraData; pHeader->m_aCentralExtraData.RemoveInternalHeaders(); pHeader->SetSystemCompatibility(header.GetSystemCompatibility()); pHeader->m_uEncryptionMethod = header.m_uEncryptionMethod; // current settings pHeader->m_stringSettings = *m_pStringSettings; // set only when adding a new file, not in PrepareData (which may be called under different circumstances) // we need the proper encryption method to be set already RemoveFromDisk(); bool bReplace = IsValidIndex(uReplaceIndex); pHeader->PrepareData(iLevel, m_pStorage->IsSegmented() != 0); if (bRichHeaderTemplateCopy) { // call here, because PrepareData will zero them pHeader->m_uCrc32 = header.m_uCrc32; pHeader->m_uComprSize = header.m_uComprSize; pHeader->m_uUncomprSize = header.m_uUncomprSize; } // local extra field is updated if needed, so we can check the lengths if (!pHeader->CheckLengths(true)) ThrowError(CZipException::tooLongData); // now that everything is all right, we can add the new file if (bReplace) { CZipFileHeader* pfh = (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)uReplaceIndex]; m_pStorage->Seek(pfh->m_uOffset); RemoveFile(pfh, uReplaceIndex, false); m_pHeaders->InsertAt((ZIP_ARRAY_SIZE_TYPE)uReplaceIndex, pHeader); m_pOpenedFile = pHeader; uIndex = uReplaceIndex; } else { uIndex = (ZIP_INDEX_TYPE)m_pHeaders->Add(pHeader); m_pOpenedFile = pHeader; m_pStorage->m_pFile->SeekToEnd(); } } catch(...) { // otherwise it is added to the collection and will be auto-deleted if (pHeader != NULL && m_pOpenedFile == NULL) delete pHeader; throw; } if (m_pInfo->m_bFindFastEnabled) InsertFindFastElement(pHeader, uIndex); // GetCount > 0, because we have just added a header return pHeader; } void CZipCentralDir::SetComment(LPCTSTR lpszComment) { ZipCompatibility::ConvertStringToBuffer(lpszComment, m_pInfo->m_pszComment, m_pStringSettings->m_uCommentCodePage); RemoveFromDisk(); } bool CZipCentralDir::SetFileComment(ZIP_INDEX_TYPE uIndex, LPCTSTR lpszComment) { if (!IsValidIndex(uIndex)) { ASSERT(FALSE); return false; } CZipFileHeader* pHeader = (*this)[uIndex]; pHeader->m_stringSettings.m_uCommentCodePage = m_pStringSettings->m_uCommentCodePage; pHeader->SetComment(lpszComment); RemoveFromDisk(); return true; } void CZipCentralDir::RemoveFromDisk() { if (m_pInfo->m_bInArchive) { ASSERT(!m_pStorage->IsSegmented()); // you can't add files to an existing segmented archive or to delete them from it m_pStorage->m_pFile->SetLength((ZIP_FILE_USIZE)(m_pStorage->m_uBytesBeforeZip + m_pInfo->m_uOffset)); m_pInfo->m_bInArchive = false; } else m_pStorage->Flush(); // if remove from disk is requested, then the archive modification will follow, so flush the buffers } void CZipCentralDir::CloseNewFile() { m_pOpenedFile->OnNewFileClose(m_pStorage); m_pOpenedFile = NULL; } void CZipCentralDir::Write() { if (m_pInfo->m_bInArchive) return; m_pInfo->m_uEntriesNumber = (ZIP_INDEX_TYPE)m_pHeaders->GetSize(); if (!m_pStorage->IsSegmented()) { m_pStorage->Flush(); m_pStorage->m_pFile->SeekToEnd(); } // else // we are at the end already m_pInfo->m_uSize = 0; bool bDontAllowVolumeChange = false; if (m_pStorage->IsSegmented()) { // segmentation signature at the beginning (4 bytes) + the size of the data descr. for each file ZIP_SIZE_TYPE uSize = GetSize(true); // if there is a segmented archive in creation and it is only one-volume, // (current volume number is 0 so far, no bytes has been written so we know they are // all in the buffer) make sure that it will be after writing central dir // and make it a not segmented archive if (m_pStorage->GetCurrentVolume() == 0) { // calculate the size of data descriptors already in the buffer or on the disk // (they will be removed in the not segmented archive). ZIP_SIZE_TYPE uToGrow = uSize - 4; for (ZIP_INDEX_TYPE i = 0; i < m_pInfo->m_uEntriesNumber; i++) { CZipFileHeader* pHeader = (*this)[i]; if (pHeader->NeedsDataDescriptor()) { if (!pHeader->IsEncrypted()) uToGrow -= 4; // remove the signature only } else uToGrow -= pHeader->GetDataDescriptorSize(true); } ZIP_SIZE_TYPE uVolumeFree = m_pStorage->VolumeLeft(); if (uVolumeFree >= uToGrow) // lets make sure it will be one-volume archive { // can the operation be done only in the buffer? if (!m_pStorage->m_uBytesWritten && // no bytes on the disk yet (m_pStorage->GetFreeInBuffer() >= uToGrow)) // is the buffer big enough? { RemoveDataDescr(true); bDontAllowVolumeChange = true; // if a volume change occurs somehow, we'll throw an error later } else { m_pStorage->Flush(); if (RemoveDataDescr(false)) bDontAllowVolumeChange = true; // if a volume change occurs somehow, we'll throw an error later } } } // make sure that in a segmented archive, the whole central directory will fit on the single volume if (!bDontAllowVolumeChange) m_pStorage->AssureFree(uSize); } try { WriteHeaders(bDontAllowVolumeChange || !m_pStorage->IsSegmented()); WriteCentralEnd(); if (bDontAllowVolumeChange) { if (m_pStorage->GetCurrentVolume() != 0) ThrowError(CZipException::badZipFile); } } catch (...) { if (bDontAllowVolumeChange) { m_pStorage->FinalizeSegm(); m_pInfo->m_uLastVolume = 0; } throw; } m_pInfo->m_bInArchive = true; } void CZipCentralDir::WriteHeaders(bool bOneDisk) { CZipActionCallback* pCallback = m_pCallbacks->Get(CZipActionCallback::cbSave); m_pInfo->m_uVolumeEntriesNo = 0; m_pInfo->m_uVolumeWithCD = m_pStorage->GetCurrentVolume(); m_pInfo->m_uOffset = m_pStorage->GetPosition(); if (!m_pInfo->m_uEntriesNumber) return; ZIP_VOLUME_TYPE uDisk = m_pInfo->m_uVolumeWithCD; if (pCallback) { pCallback->Init(); pCallback->SetTotal(m_pInfo->m_uEntriesNumber); } int iAborted = 0; if (m_pInfo->m_uEntriesNumber > 0) { ZIP_INDEX_TYPE uLast = (ZIP_INDEX_TYPE)(m_pInfo->m_uEntriesNumber - 1); ZIP_INDEX_TYPE i = 0; for (;;) { CZipFileHeader* pHeader = (*this)[i]; m_pInfo->m_uSize += pHeader->Write(m_pStorage); if (m_pStorage->GetCurrentVolume() != uDisk) { m_pInfo->m_uVolumeEntriesNo = 1; uDisk = m_pStorage->GetCurrentVolume(); // update the information about the offset and starting volume if the // first header was written in the new volume if (i == 0) { m_pInfo->m_uOffset = 0; m_pInfo->m_uVolumeWithCD = uDisk; } } else m_pInfo->m_uVolumeEntriesNo++; if (pCallback) { bool ret, last; if (i == uLast) { ret = pCallback->RequestLastCallback(1); last = true; } else { ret = pCallback->RequestCallback(); last = false; } if (ret) { if (last) break; } else { if (bOneDisk) { ASSERT(!m_pStorage->IsSegmented()); // if segmented, would need to m_pStorage->Flush(), but the headers can span multiple volumes m_pStorage->EmptyWriteBuffer(); // remove saved part from the volume m_pStorage->m_pFile->SetLength((ZIP_FILE_USIZE)(m_pStorage->m_uBytesBeforeZip + m_pInfo->m_uOffset)); // We can now abort safely iAborted = CZipException::abortedSafely; } else iAborted = CZipException::abortedAction; break; } } else if (i == uLast) break; i++; } } if (pCallback) { pCallback->CallbackEnd(); if (iAborted) ThrowError(iAborted); } } void CZipCentralDir::WriteCentralEnd() { ZIP_SIZE_TYPE uSize = CENTRAL_DIR_END_SIZE + m_pInfo->m_pszComment.GetSize(); CZipAutoBuffer buf((DWORD)uSize); char* pBuf = buf; ZIP_VOLUME_TYPE uDisk = m_pStorage->GetCurrentVolume(); if (m_pStorage->IsSegmented() != 0) { // update the volume number m_pStorage->AssureFree(uSize); m_pInfo->m_uLastVolume = m_pStorage->GetCurrentVolume(); } if (m_pInfo->m_uLastVolume != uDisk) m_pInfo->m_uVolumeEntriesNo = 0; WORD uCommentSize = (WORD)m_pInfo->m_pszComment.GetSize(); memcpy(pBuf, m_gszSignature, 4); CBytesWriter::WriteBytes(pBuf + 4, CBytesWriter::WriteSafeU16(m_pInfo->m_uLastVolume)); CBytesWriter::WriteBytes(pBuf + 6, CBytesWriter::WriteSafeU16(m_pInfo->m_uVolumeWithCD)); CBytesWriter::WriteBytes(pBuf + 8, CBytesWriter::WriteSafeU16(m_pInfo->m_uVolumeEntriesNo)); CBytesWriter::WriteBytes(pBuf + 10, CBytesWriter::WriteSafeU16(m_pInfo->m_uEntriesNumber)); CBytesWriter::WriteBytes(pBuf + 12, CBytesWriter::WriteSafeU32(m_pInfo->m_uSize)); CBytesWriter::WriteBytes(pBuf + 16, CBytesWriter::WriteSafeU32(m_pInfo->m_uOffset)); CBytesWriter::WriteBytes(pBuf + 20, uCommentSize); memcpy(pBuf + 22, m_pInfo->m_pszComment, uCommentSize); if (uSize > (DWORD)(-1)) CZipException::Throw(CZipException::internalError); m_pStorage->Write(buf, (DWORD)uSize, true); } void CZipCentralDir::RemoveAll() { ClearFindFastArray(); RemoveHeaders(); } void CZipCentralDir::RemoveFile(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex, bool bShift) { if (uIndex == ZIP_FILE_INDEX_UNSPECIFIED) { // we need to know the index to remove ZIP_INDEX_TYPE uCount = (ZIP_INDEX_TYPE)m_pHeaders->GetSize(); for (ZIP_INDEX_TYPE i = 0; i < uCount; i++) if (pHeader == (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)i]) { uIndex = i; break; } } ASSERT(uIndex != ZIP_FILE_INDEX_UNSPECIFIED || pHeader); if (!pHeader) pHeader = (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)uIndex]; if (m_pInfo->m_bFindFastEnabled) { ZIP_INDEX_TYPE i = FindFileNameIndex(pHeader->GetFileName()); ASSERT(i != ZIP_FILE_INDEX_NOT_FOUND); CZipFindFast* pFindFast = (*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)i]; ZIP_INDEX_TYPE uBorderIndex = pFindFast->m_uIndex; delete pFindFast; pFindFast = NULL; m_pFindArray->RemoveAt((ZIP_ARRAY_SIZE_TYPE)i); // shift down the indexes if (bShift) { ZIP_INDEX_TYPE uSize = (ZIP_INDEX_TYPE)m_pFindArray->GetSize(); for (ZIP_INDEX_TYPE j = 0; j < uSize; j++) { if ((*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)j]->m_uIndex > uBorderIndex) (*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)j]->m_uIndex--; } } } if (uIndex != ZIP_FILE_INDEX_UNSPECIFIED) { delete pHeader; m_pHeaders->RemoveAt((ZIP_ARRAY_SIZE_TYPE)uIndex); } } void CZipCentralDir::RemoveLastFile(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex) { if (uIndex == ZIP_FILE_INDEX_UNSPECIFIED) { if (m_pHeaders->GetSize() == 0) return; uIndex = (ZIP_VOLUME_TYPE)(m_pHeaders->GetSize() - 1); } if (!pHeader) pHeader = (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)uIndex]; ZIP_SIZE_TYPE uNewSize = pHeader->m_uOffset + m_pStorage->m_uBytesBeforeZip; // then remove RemoveFile(pHeader, uIndex); m_pStorage->Flush(); m_pStorage->m_pFile->SetLength((ZIP_FILE_USIZE)uNewSize); m_pInfo->m_bInArchive = false; // it is true when AutoFlush is set to true } ZIP_SIZE_TYPE CZipCentralDir::GetSize(bool bWhole) const { ZIP_SIZE_TYPE uTotal = CENTRAL_DIR_END_SIZE + m_pInfo->m_pszComment.GetSize(); ZIP_INDEX_TYPE uCount = (ZIP_INDEX_TYPE)m_pHeaders->GetSize(); if (bWhole) { for (ZIP_INDEX_TYPE i = 0; i < uCount; i++) { const CZipFileHeader* pHeader = (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)i]; uTotal += pHeader->GetSize(); } } return uTotal; } bool CZipCentralDir::RemoveDataDescr(bool bFromBuffer) { // this will not work if there are bytes before zip CZipFileMapping fm; char* pFile; ZIP_SIZE_TYPE uSize; if (bFromBuffer) { uSize = m_pStorage->m_uBytesInWriteBuffer; pFile = m_pStorage->m_pWriteBuffer; } else { uSize = (ZIP_SIZE_TYPE)m_pStorage->m_pFile->GetLength(); // we cannot use CZipMemFile in multi-volume archive // so it must be CZipFile if (!fm.CreateMapping(static_cast(m_pStorage->m_pFile))) return false; pFile = fm.GetMappedMemory(); } ZIP_SIZE_TYPE uOffsetToChange = 4; ZIP_SIZE_TYPE uPosInBuffer = 0; WORD uExtraHeaderLen; ZIP_INDEX_TYPE uCount = (ZIP_INDEX_TYPE)m_pHeaders->GetSize(); for (ZIP_INDEX_TYPE i = 0; i < uCount; i++) { CZipFileHeader* pHeader = (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)i]; char* pSour = pFile + pHeader->m_uOffset; if (pHeader->NeedsDataDescriptor()) uExtraHeaderLen = (WORD)(pHeader->IsEncrypted() ? 0 : 4); else { uExtraHeaderLen = pHeader->GetDataDescriptorSize(true); // removing data descriptor pHeader->m_uFlag &= ~8; // update local header: // write modified flag in the local header CBytesWriter::WriteBytes(pSour + 6, pHeader->m_uFlag); pHeader->WriteSmallDataDescriptor(pSour + 14, false); } ZIP_SIZE_TYPE uToCopy = (i == (uCount - 1) ? uSize : (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)(i + 1)]->m_uOffset) - pHeader->m_uOffset - uExtraHeaderLen; if (uToCopy > 0) // TODO: [postponed] the size_t limit on uToCopy, but creating such a big segment is unlikely (at least at the moment of writing) memmove(pFile + uPosInBuffer, pSour, (size_t)uToCopy); uPosInBuffer += uToCopy; pHeader->m_uOffset -= uOffsetToChange; uOffsetToChange += uExtraHeaderLen; } if (bFromBuffer) m_pStorage->m_uBytesInWriteBuffer = (DWORD)uPosInBuffer; else { m_pStorage->m_uBytesWritten = uPosInBuffer; fm.RemoveMapping(); m_pStorage->m_pFile->SetLength((ZIP_FILE_USIZE)uPosInBuffer); } return true; } void CZipCentralDir::RemoveHeaders() { ZIP_INDEX_TYPE uCount = (ZIP_INDEX_TYPE)m_pHeaders->GetSize(); for (ZIP_INDEX_TYPE i = 0; i < uCount; i++) delete (*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)i]; m_pHeaders->RemoveAll(); } void CZipCentralDir::BuildFindFastArray( bool bCaseSensitive ) { ClearFindFastArray(); m_pInfo->m_bCaseSensitive = bCaseSensitive; // for later m_pInfo->m_pCompare = GetCZipStrCompFunc(bCaseSensitive); ZIP_INDEX_TYPE uCount = (ZIP_INDEX_TYPE)m_pHeaders->GetSize(); for (ZIP_INDEX_TYPE i = 0; i < uCount; i++) m_pFindArray->Add(new CZipFindFast((*m_pHeaders)[(ZIP_ARRAY_SIZE_TYPE)i], i)); m_pFindArray->Sort(bCaseSensitive ? CompareFindFastCollate : CompareFindFastCollateNoCase); } void CZipCentralDir::EnableFindFast(bool bEnable, bool bCaseSensitive) { if (m_pInfo->m_bFindFastEnabled == bEnable) return; m_pInfo->m_bFindFastEnabled = bEnable; if (bEnable) BuildFindFastArray(bCaseSensitive); else m_pFindArray->RemoveAll(); } ZIP_INDEX_TYPE CZipCentralDir::FindFile(LPCTSTR lpszFileName, bool bCaseSensitive, bool bSporadically, bool bFileNameOnly) { if (!m_pInfo->m_bFindFastEnabled) EnableFindFast(true, bSporadically ? !bCaseSensitive : bCaseSensitive); ZIP_INDEX_TYPE uResult = ZIP_FILE_INDEX_NOT_FOUND; if (bFileNameOnly) { // a non-effective search (treat an array as unsorted) // set the proper compare function ZIPSTRINGCOMPARE pCompare = bCaseSensitive == m_pInfo->m_bCaseSensitive ? m_pInfo->m_pCompare : GetCZipStrCompFunc(bCaseSensitive); ZIP_INDEX_TYPE uSize = (ZIP_INDEX_TYPE)m_pFindArray->GetSize(); for (ZIP_INDEX_TYPE i = 0; i < uSize; i++) { CZipString sz = (*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)i]->m_pHeader->GetFileName(); CZipPathComponent::RemoveSeparators(sz); // to find a dir CZipPathComponent zpc(sz); sz = zpc.GetFileName(); if ((sz.*pCompare)(lpszFileName) == 0) { uResult = i; break; } } } else if (bCaseSensitive == m_pInfo->m_bCaseSensitive) uResult = FindFileNameIndex(lpszFileName); else { if (bSporadically) { // a non-effective search (treat an array as unsorted) // do not use m_pInfo->m_pCompare, as it may be shared ZIPSTRINGCOMPARE pCompare = GetCZipStrCompFunc(bCaseSensitive); ZIP_INDEX_TYPE uSize = (ZIP_INDEX_TYPE)m_pFindArray->GetSize(); for (ZIP_INDEX_TYPE i = 0; i < uSize; i++) if (((*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)i]->m_pHeader->GetFileName().*pCompare)(lpszFileName) == 0) { uResult = i; break; } } else { BuildFindFastArray(bCaseSensitive); uResult = FindFileNameIndex(lpszFileName); } } return uResult == ZIP_FILE_INDEX_NOT_FOUND ? ZIP_FILE_INDEX_NOT_FOUND : (*m_pFindArray)[(ZIP_ARRAY_SIZE_TYPE)uResult]->m_uIndex; } ZIP_INDEX_TYPE CZipCentralDir::InsertFindFastElement(CZipFileHeader* pHeader, ZIP_INDEX_TYPE uIndex) { CZipString fileName = pHeader->GetFileName(); ZIP_ARRAY_SIZE_TYPE uSize = m_pFindArray->GetSize(); // Our initial binary search range encompasses the entire array of filenames: ZIP_ARRAY_SIZE_TYPE start = 0; ZIP_ARRAY_SIZE_TYPE end = uSize; // Keep halving our search range until we find the right place // to insert the new element: while ( start < end ) { // Find the midpoint of the search range: ZIP_ARRAY_SIZE_TYPE midpoint = ( start + end ) / 2; // Compare the filename with the filename at the midpoint of the current search range: int result = CompareElement(fileName, (ZIP_INDEX_TYPE)midpoint); // If our filename is larger, it must fall in the first half of the search range: if ( result > 0 ) { end = midpoint; } // If it's smaller, it must fall in the last half: else if ( result < 0 ) { start = midpoint + 1; } // If they're equal, we can go ahead and insert here: else { start = midpoint; break; } } m_pFindArray->InsertAt(start, new CZipFindFast(pHeader, uIndex == ZIP_FILE_INDEX_UNSPECIFIED ? (ZIP_INDEX_TYPE)uSize : uIndex /* just in case */)); return (ZIP_INDEX_TYPE)start; } ZIP_INDEX_TYPE CZipCentralDir::FindFileNameIndex(LPCTSTR lpszFileName) const { ZIP_ARRAY_SIZE_TYPE start = 0; ZIP_ARRAY_SIZE_TYPE end = m_pFindArray->GetSize(); if (end == 0) return ZIP_FILE_INDEX_NOT_FOUND; else end--; // Keep halving our search range until we find the given element: while ( start <= end ) { // Find the midpoint of the search range: ZIP_ARRAY_SIZE_TYPE midpoint = ( start + end ) / 2; // Compare the given filename with the filename at the midpoint of the search range: int result = CompareElement(lpszFileName, (ZIP_INDEX_TYPE)midpoint); // If our filename is smaller, it must fall in the first half of the search range: if ( result > 0 ) { if (midpoint == 0) return ZIP_FILE_INDEX_NOT_FOUND; end = midpoint - 1; } // If it's larger, it must fall in the last half: else if ( result < 0 ) { start = midpoint + 1; } // If they're equal, return the result: else { return (ZIP_INDEX_TYPE)midpoint; } } // Signal failure: return ZIP_FILE_INDEX_NOT_FOUND; } void CZipCentralDir::CreateSharedData() { m_pInfo = new CInfo(); m_pInfo->Init(); m_pHeaders = new CZipArray(); m_pFindArray = new CZipArray(); } void CZipCentralDir::DestroySharedData() { if (!m_pInfo) return; #ifdef ZIP_ARCHIVE_USE_LOCKING LockAccess(); try { #endif m_pInfo->m_iReference--; if (m_pInfo->m_iReference <= 0) // <= is just in case instead of == { if (m_pHeaders != NULL) { RemoveHeaders(); delete m_pHeaders; m_pHeaders = NULL; } if (m_pFindArray != NULL) { ClearFindFastArray(); delete m_pFindArray; m_pFindArray = NULL; } #ifdef ZIP_ARCHIVE_USE_LOCKING UnlockAccess(); #endif delete m_pInfo; m_pInfo = NULL; } #ifdef ZIP_ARCHIVE_USE_LOCKING } catch(...) { UnlockAccess(); throw; } UnlockAccess(); #endif } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipPathComponent.h0000644000175000017500000001454411300022650022454 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipPathComponent.h * Includes the CZipPathComponent class. * */ #if !defined(ZIPARCHIVE_ZIPPATHCOMPONENT_DOT_H) #define ZIPARCHIVE_ZIPPATHCOMPONENT_DOT_H #if _MSC_VER > 1000 #pragma once #if defined ZIP_HAS_DLL #pragma warning (push) #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class #endif #endif #include "ZipString.h" #include "ZipExport.h" /** Splits a file path into components. */ class ZIP_API CZipPathComponent { public: CZipPathComponent(){} virtual ~CZipPathComponent(); static const TCHAR m_cSeparator; ///< A system - specific default path separator. /** Appends a path separator to \a szPath, if it is not already appended. \param szPath The path to have a separator appended. */ static void AppendSeparator(CZipString& szPath) { RemoveSeparators(szPath); szPath += m_cSeparator; } /** Combines a path information with a file name information. \param szPath Provides the path information and retrieves the result. \param lpszName The filename to be appended to the path. */ static void Combine(CZipString& szPath, LPCTSTR lpszName) { AppendSeparator(szPath); if (lpszName != NULL) szPath += lpszName; } /** Removes path separators from the end of \a szPath \param szPath The path to have path separators removed. */ static void RemoveSeparators(CZipString& szPath) { // szPath.TrimRight(m_cSeparator); szPath.TrimRight(_T("\\/")); } /** Removes path separators from the beginning of \a szPath. \param szPath The path to have path separators removed. */ static void RemoveSeparatorsLeft(CZipString& szPath) { szPath.TrimLeft(_T("\\/")); } /** Tests the character, if it is a separator or not. \param c The character to test. \return \c true, if \a c is a path separator; \c false otherwise. */ static bool IsSeparator(TCHAR c) { return c == _T('\\') || c == _T('/'); } /** Checks if \a szPath has a path separator appended. \param szPath The path to be tested. \return \c true, if \a szPath has a path separator at the end; \c false otherwise. */ static bool HasEndingSeparator(const CZipString& szPath) { int iLen = szPath.GetLength(); if (iLen) return IsSeparator(szPath[iLen - 1]); else return false; } /** Initializes a new instance of the CZipPathComponent class. \param lpszFullPath The full path to the file. \see SetFullPath */ CZipPathComponent(LPCTSTR lpszFullPath) { SetFullPath(lpszFullPath); } /** Sets the full path to the file. \param lpszFullPath The full path to the file including a filename. The last element in the path is assumed to be a filename. */ void SetFullPath(LPCTSTR lpszFullPath); /** Gets the name of the file without an extension (and without a path). \return The title of the file. */ CZipString GetFileTitle() const { return m_szFileTitle;} /** Sets the file title (the name without an extension and without a path). \param lpszFileTitle The title to set. */ void SetFileTitle(LPCTSTR lpszFileTitle) { m_szFileTitle = lpszFileTitle;} /** Sets the extension alone. \param lpszExt The extension to set. May contain a dot at the beginning, but doesn't have to. */ void SetExtension(LPCTSTR lpszExt) { m_szFileExt = lpszExt; m_szFileExt.TrimLeft(_T('.')); } /** Gets the extension of the file. \return The extension without a dot. */ CZipString GetFileExt() const { return m_szFileExt;} /** Gets the drive of the file. \return The drive without a path separator at the end. */ CZipString GetFileDrive() const { return m_szDrive;} /** Gets the full path to the file without the drive. \return The path without the drive and without a path separator at the beginning. */ CZipString GetNoDrive() const ; /** Get the filename. \return The filename including an extension and without a path. */ CZipString GetFileName() const { CZipString szFullFileName = m_szFileTitle; if (!m_szFileExt.IsEmpty()) { szFullFileName += _T("."); szFullFileName += m_szFileExt; } return szFullFileName; } /** Gets the full path to the file. \return The full path information including the filename. */ CZipString GetFullPath() const { CZipString szFullPath = GetFilePath(); CZipString szFileName = GetFileName(); if (!szFileName.IsEmpty()) { if (szFullPath.IsEmpty()) szFullPath += _T('.'); szFullPath += m_cSeparator; szFullPath += szFileName; } return szFullPath; } /** Gets the path part only. \return The path to the file without a filename and without a path separator at the end. */ CZipString GetFilePath() const { CZipString szDrive = m_szDrive; CZipString szDir = m_szDirectory; if (!szDrive.IsEmpty() && !szDir.IsEmpty()) szDrive += m_cSeparator; return m_szPrefix + szDrive + szDir; } protected: /** \name Path parts. */ //@{ CZipString m_szDirectory, ///< A directory(ies) only without path separators at the end and the beginning. m_szFileTitle, ///< A filename without an extension. m_szFileExt, ///< A file extension without a dot. m_szDrive, ///< A drive (if the system path standard uses it) without a path separator at the end. m_szPrefix; ///< A prefix (e.g. for the UNC path or Unicode path under Windows). //@} }; #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning (pop) #endif #endif // !defined(ZIPARCHIVE_ZIPPATHCOMPONENT_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipFileHeader.cpp0000644000175000017500000006205111300022650022214 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipFileHeader.h" #include "ZipAutoBuffer.h" #include "ZipArchive.h" #include "ZipPlatform.h" #include "ZipCompatibility.h" #include #include "ZipCrc32Cryptograph.h" #include "BytesWriter.h" #define FILEHEADERSIZE 46 #define LOCALFILEHEADERSIZE 30 #define ZIP_EXTRA_ZARCH_NAME_VER 1 using namespace ZipArchiveLib; char CZipFileHeader::m_gszSignature[] = {0x50, 0x4b, 0x01, 0x02}; char CZipFileHeader::m_gszLocalSignature[] = {0x50, 0x4b, 0x03, 0x04}; CZipFileHeader::CZipFileHeader() { m_uExternalAttr = 0;//ZipPlatform::GetDefaultAttributes(); m_uModDate = m_uModTime = 0; m_uMethod = CZipCompressor::methodDeflate; m_uVersionMadeBy = 0; m_uCrc32 = 0; // initialize to 0, because on 64 bit platform unsigned long is 8 byte and we are copying only 4 bytes in Read() m_uComprSize = m_uUncomprSize = m_uOffset = 0; m_uLocalFileNameSize = 0; m_uLocalComprSize = m_uLocalUncomprSize = 0; m_uVolumeStart = 0; m_pszFileName = NULL; m_uEncryptionMethod = CZipCryptograph::encNone; m_bIgnoreCrc32 = false; m_uFlag = 0; } CZipFileHeader::~CZipFileHeader() { if (m_pszFileName != NULL) delete m_pszFileName; } bool CZipFileHeader::Read(CZipCentralDir& centralDir, bool bReadSignature) { CZipStorage *pStorage = centralDir.m_pStorage; WORD uFileNameSize, uCommentSize, uExtraFieldSize; CZipAutoBuffer buf(FILEHEADERSIZE); if (bReadSignature) { pStorage->Read(buf, FILEHEADERSIZE, true); if (!VerifySignature(buf)) return false; } else pStorage->Read((char*)buf + 4, FILEHEADERSIZE - 4, true); CBytesWriter::ReadBytes(m_uVersionMadeBy, buf + 4); CBytesWriter::ReadBytes(m_uVersionNeeded, buf + 6); CBytesWriter::ReadBytes(m_uFlag, buf + 8); CBytesWriter::ReadBytes(m_uMethod, buf + 10); CBytesWriter::ReadBytes(m_uModTime, buf + 12); CBytesWriter::ReadBytes(m_uModDate, buf + 14); CBytesWriter::ReadBytes(m_uCrc32, buf + 16); CBytesWriter::ReadBytes(m_uComprSize, buf + 20, 4); CBytesWriter::ReadBytes(m_uUncomprSize, buf + 24, 4); CBytesWriter::ReadBytes(uFileNameSize, buf + 28); CBytesWriter::ReadBytes(uExtraFieldSize, buf + 30); CBytesWriter::ReadBytes(uCommentSize, buf + 32); CBytesWriter::ReadBytes(m_uVolumeStart, buf + 34, 2); CBytesWriter::ReadBytes(m_uInternalAttr, buf + 36); CBytesWriter::ReadBytes(m_uExternalAttr, buf + 38); CBytesWriter::ReadBytes(m_uOffset, buf + 42, 4); buf.Release(); // we may need to modify this later m_uEncryptionMethod = (BYTE)((m_uFlag & (WORD) 1) != 0 ? CZipCryptograph::encStandard : CZipCryptograph::encNone); ZIP_VOLUME_TYPE uCurDsk = pStorage->GetCurrentVolume(); m_pszFileNameBuffer.Allocate(uFileNameSize); // don't add NULL at the end pStorage->Read(m_pszFileNameBuffer, uFileNameSize, true); if (centralDir.m_pStringSettings->IsStandardNameCodePage()) m_stringSettings.SetDefaultNameCodePage(GetSystemCompatibility()); else m_stringSettings.m_uNameCodePage = centralDir.m_pStringSettings->m_uNameCodePage; if (!centralDir.m_pStringSettings->IsStandardCommentCodePage()) m_stringSettings.m_uCommentCodePage = centralDir.m_pStringSettings->m_uCommentCodePage; if (!m_aCentralExtraData.Read(pStorage, uExtraFieldSize)) return false; CZipExtraData* pExtra = m_aCentralExtraData.Lookup(ZIP_EXTRA_ZARCH_NAME); if (pExtra != NULL) { WORD uExtraDataSize = (WORD)pExtra->m_data.GetSize(); int offset = 1; if (offset > uExtraDataSize) return false; if (pExtra->m_data[0] <= ZIP_EXTRA_ZARCH_NAME_VER) // else don't parse it { offset++; if (offset > uExtraDataSize) return false; BYTE flag = pExtra->m_data[1]; bool bReadCommentCp = (flag & 4) != 0; if ((flag & 1) != 0) { // code page present if (offset + 4 > uExtraDataSize) return false; // avoid warnings DWORD temp; CBytesWriter::ReadBytes(temp, pExtra->m_data + offset); m_stringSettings.m_uNameCodePage = temp; offset += 4; } if ((flag & 3) == 3) { m_stringSettings.m_bStoreNameInExtraData = true; int iFileNameSize = pExtra->m_data.GetSize() - 2 - 4; if (bReadCommentCp) iFileNameSize -= 4; // code page present if (offset + iFileNameSize > uExtraDataSize || iFileNameSize <= 0) return false; CZipAutoBuffer buffer; buffer.Allocate(iFileNameSize); memcpy(buffer, pExtra->m_data + offset, iFileNameSize); m_pszFileName = new CZipString(_T("")); ZipCompatibility::ConvertBufferToString(*m_pszFileName, buffer, m_stringSettings.m_uNameCodePage); offset += iFileNameSize; m_pszFileNameBuffer.Release(); } else m_stringSettings.m_bStoreNameInExtraData = false; if (bReadCommentCp) { // code page present if (offset + 4 > uExtraDataSize) return false; DWORD temp; CBytesWriter::ReadBytes(temp, pExtra->m_data + offset); m_stringSettings.m_uCommentCodePage = temp; // offset += 4; } } } if (uCommentSize) { m_pszComment.Allocate(uCommentSize); pStorage->Read(m_pszComment, uCommentSize, true); } return pStorage->GetCurrentVolume() == uCurDsk; // check that the whole header is in one volume } time_t CZipFileHeader::GetTime()const { struct tm atm; atm.tm_sec = (m_uModTime & ~0xFFE0) << 1; atm.tm_min = (m_uModTime & ~0xF800) >> 5; atm.tm_hour = m_uModTime >> 11; atm.tm_mday = m_uModDate & ~0xFFE0; atm.tm_mon = ((m_uModDate & ~0xFE00) >> 5) - 1; atm.tm_year = (m_uModDate >> 9) + 80; atm.tm_isdst = -1; return mktime(&atm); } // write the header to the central dir DWORD CZipFileHeader::Write(CZipStorage *pStorage) { m_aCentralExtraData.RemoveInternalHeaders(); WORD uMethod = m_uMethod; if (!CheckLengths(false)) CZipException::Throw(CZipException::tooLongData); PrepareFileName(); if (m_stringSettings.m_bStoreNameInExtraData) { if (m_pszFileName == NULL && m_pszFileNameBuffer.IsAllocated()) GetFileName(false); // don't clear the buffer, it will be needed in a moment ASSERT(m_pszFileName != NULL); if (m_pszFileName->GetLength() == 0) m_stringSettings.m_bStoreNameInExtraData = false; } int iSystemCompatibility = GetSystemCompatibility(); if (!m_stringSettings.IsStandard(iSystemCompatibility)) { CZipExtraData* pExtra = m_aCentralExtraData.CreateNew(ZIP_EXTRA_ZARCH_NAME); bool bWriteCommentCp = !m_stringSettings.IsStandardCommentCodePage(); BYTE flag = 0; int offset = 2; char* data = NULL; if (m_stringSettings.m_bStoreNameInExtraData) { CZipAutoBuffer buffer; // m_pszFileNameBuffer contains CP_ACP page, we don't check if the current page is CP_ACP - too large dependency on PrepareFileName ZipCompatibility::ConvertStringToBuffer(*m_pszFileName, buffer, m_stringSettings.m_uNameCodePage); int size = 2 + 4 + buffer.GetSize(); if (bWriteCommentCp) size += 4; pExtra->m_data.Allocate(size); data = (char*)pExtra->m_data; CBytesWriter::WriteBytes(data + offset, (DWORD)m_stringSettings.m_uNameCodePage); offset += 4; memcpy(data + offset, buffer, buffer.GetSize()); offset += buffer.GetSize(); flag = 3; } else if (!m_stringSettings.IsStandardNameCodePage(iSystemCompatibility)) { int size = 2 + 4; if (bWriteCommentCp) size += 4; pExtra->m_data.Allocate(size); data = (char*)pExtra->m_data; CBytesWriter::WriteBytes(data + offset, (DWORD)m_stringSettings.m_uNameCodePage); offset += 4; flag = 1; } if (bWriteCommentCp) { if (!pExtra->m_data.IsAllocated()) { pExtra->m_data.Allocate(2 + 4); data = (char*)pExtra->m_data; } ASSERT(data); CBytesWriter::WriteBytes(data + offset, (DWORD)m_stringSettings.m_uCommentCodePage); flag |= 4; } data[0] = ZIP_EXTRA_ZARCH_NAME_VER; data[1] = flag; } WORD uFileNameSize = (WORD)m_pszFileNameBuffer.GetSize(), uCommentSize = (WORD)GetCommentSize(), uExtraFieldSize = (WORD)m_aCentralExtraData.GetTotalSize(); DWORD uSize = FILEHEADERSIZE + uFileNameSize + uCommentSize + uExtraFieldSize; CZipAutoBuffer buf(uSize); char* dest = (char*)buf; memcpy(dest, m_gszSignature, 4); CBytesWriter::WriteBytes(dest + 4, m_uVersionMadeBy); CBytesWriter::WriteBytes(dest + 6, m_uVersionNeeded); CBytesWriter::WriteBytes(dest + 8, m_uFlag); CBytesWriter::WriteBytes(dest + 10, uMethod); CBytesWriter::WriteBytes(dest + 12, m_uModTime); CBytesWriter::WriteBytes(dest + 14, m_uModDate); WriteCrc32(dest + 16); CBytesWriter::WriteBytes(dest + 20, CBytesWriter::WriteSafeU32(m_uComprSize)); CBytesWriter::WriteBytes(dest + 24, CBytesWriter::WriteSafeU32(m_uUncomprSize)); CBytesWriter::WriteBytes(dest + 28, uFileNameSize); CBytesWriter::WriteBytes(dest + 30, uExtraFieldSize); CBytesWriter::WriteBytes(dest + 32, uCommentSize); CBytesWriter::WriteBytes(dest + 34, CBytesWriter::WriteSafeU16(m_uVolumeStart)); CBytesWriter::WriteBytes(dest + 36, m_uInternalAttr); CBytesWriter::WriteBytes(dest + 38, m_uExternalAttr); CBytesWriter::WriteBytes(dest + 42, CBytesWriter::WriteSafeU32(m_uOffset)); memcpy(dest + 46, m_pszFileNameBuffer, uFileNameSize); if (uExtraFieldSize) m_aCentralExtraData.Write(dest + 46 + uFileNameSize); if (uCommentSize) memcpy(dest + 46 + uFileNameSize + uExtraFieldSize, m_pszComment, uCommentSize); pStorage->Write(dest, uSize, true); // remove to avoid miscalculations in GetSize() m_aCentralExtraData.RemoveInternalHeaders(); ClearFileName(); return uSize; } bool CZipFileHeader::ReadLocal(CZipCentralDir& centralDir) { char buf[LOCALFILEHEADERSIZE]; CZipStorage* pStorage = centralDir.m_pStorage; pStorage->Read(buf, LOCALFILEHEADERSIZE, true); if (memcmp(buf, m_gszLocalSignature, 4) != 0) return false; bool bIsDataDescr = (((WORD)*(buf + 6)) & 8) != 0; WORD uTemp; CBytesWriter::ReadBytes(uTemp, buf + 6); // do not compare the whole flag - the bits reserved by PKWARE may differ // in local and central headers if (centralDir.IsConsistencyCheckOn( CZipArchive::checkLocalFlag) && (uTemp & 0xf) != (m_uFlag & 0xf)) return false; // method WORD uMethod; CBytesWriter::ReadBytes(uMethod, buf + 8); // this may be different in the local header (it may contain disk name for example) CBytesWriter::ReadBytes(m_uLocalFileNameSize, buf + 26); WORD uExtraFieldSize; CBytesWriter::ReadBytes(uExtraFieldSize, buf + 28); ZIP_VOLUME_TYPE uCurDsk = pStorage->GetCurrentVolume(); // skip reading the local file name pStorage->m_pFile->Seek(m_uLocalFileNameSize, CZipAbstractFile::current); if (!m_aLocalExtraData.Read(pStorage, uExtraFieldSize)) return false; CBytesWriter::ReadBytes(m_uLocalComprSize, buf + 18, 4); CBytesWriter::ReadBytes(m_uLocalUncomprSize, buf + 22, 4); if (uMethod == CZipCompressor::methodWinZipAes && IsEncrypted()) CZipException::Throw(CZipException::noAES); if (centralDir.IsConsistencyCheckOn( CZipArchive::checkLocalMethod) && uMethod != m_uMethod ) return false; if (!bIsDataDescr && centralDir.IsConsistencyCheckOn( CZipArchive::checkLocalCRC | CZipArchive::checkLocalSizes)) { // read all at once - probably overally faster than checking and reading separately DWORD uCrc32; CBytesWriter::ReadBytes(uCrc32, buf + 14); if (centralDir.IsConsistencyCheckOn( CZipArchive::checkLocalCRC) && uCrc32 != m_uCrc32) return false; if (centralDir.IsConsistencyCheckOn( CZipArchive::checkLocalSizes) // do not check, if local compressed size is 0 - this usually means, that some archiver // could not update the compressed size after compression && ( m_uLocalComprSize != 0 && m_uLocalComprSize != m_uComprSize || m_uLocalUncomprSize != m_uUncomprSize)) return false; } return pStorage->GetCurrentVolume() == uCurDsk; // check that the whole header is in one volume } void CZipFileHeader::SetTime(const time_t & ttime) { #if _MSC_VER >= 1400 tm gts; tm* gt = >s; localtime_s(gt, &ttime); #else tm* gt = localtime(&ttime); #endif WORD year, month, day, hour, min, sec; if (gt == NULL) { year = 0; month = day = 1; hour = min = sec = 0; } else { year = (WORD)(gt->tm_year + 1900); if (year <= 1980) year = 0; else year -= 1980; month = (WORD)gt->tm_mon + 1; day = (WORD)gt->tm_mday; hour = (WORD)gt->tm_hour; min = (WORD)gt->tm_min; sec = (WORD)gt->tm_sec; } m_uModDate = (WORD) (day + ( month << 5) + (year << 9)); m_uModTime = (WORD) ((sec >> 1) + (min << 5) + (hour << 11)); } void CZipFileHeader::ConvertFileName(CZipAutoBuffer& buffer) const { if (m_pszFileName == NULL) return; CZipString temp = *m_pszFileName; ZipCompatibility::SlashBackslashChg(temp, false); if (m_stringSettings.m_bStoreNameInExtraData) ZipCompatibility::ConvertStringToBuffer(temp, buffer, m_stringSettings.GetDefaultNameCodePage(GetSystemCompatibility())); else ZipCompatibility::ConvertStringToBuffer(temp, buffer, m_stringSettings.m_uNameCodePage); } void CZipFileHeader::ConvertFileName(CZipString& szFileName) const { if (!m_pszFileNameBuffer.IsAllocated() || m_pszFileNameBuffer.GetSize() == 0) return; ZipCompatibility::ConvertBufferToString(szFileName, m_pszFileNameBuffer, m_stringSettings.m_uNameCodePage); int sc = ZipPlatform::GetSystemID(); if (sc == ZipCompatibility::zcDosFat || sc == ZipCompatibility::zcNtfs) ZipCompatibility::SlashBackslashChg(szFileName, true); else // some archives may have an invalid path separator stored ZipCompatibility::SlashBackslashChg(szFileName, false); } // write the local header void CZipFileHeader::WriteLocal(CZipStorage *pStorage) { if (IsDataDescriptor()) { m_uLocalComprSize = 0; // write, if we know it - WinZip 9.0 in segmented mode with AES encryption will // complain otherwise (this seems like a bug, because the data descriptor is present and // local descriptor should be discarded) if (!IsWinZipAesEncryption()) m_uLocalUncomprSize = 0; } else { m_uLocalComprSize = GetDataSize(true, false); } WORD uMethod = m_uMethod; PrepareFileName(); m_uLocalFileNameSize = (WORD)m_pszFileNameBuffer.GetSize(); DWORD uExtraFieldSize = m_aLocalExtraData.GetTotalSize(); DWORD iLocalSize = LOCALFILEHEADERSIZE + uExtraFieldSize + m_uLocalFileNameSize; CZipAutoBuffer buf(iLocalSize); char* dest = (char*) buf; memcpy(dest, m_gszLocalSignature, 4); CBytesWriter::WriteBytes(dest + 4, m_uVersionNeeded); CBytesWriter::WriteBytes(dest + 6, m_uFlag); CBytesWriter::WriteBytes(dest + 8, uMethod); CBytesWriter::WriteBytes(dest + 10, m_uModTime); CBytesWriter::WriteBytes(dest + 12, m_uModDate); WriteSmallDataDescriptor(dest + 14); CBytesWriter::WriteBytes(dest + 26, m_uLocalFileNameSize); CBytesWriter::WriteBytes(dest + 28, (WORD)uExtraFieldSize); memcpy(dest + 30, m_pszFileNameBuffer, m_uLocalFileNameSize); if (uExtraFieldSize) m_aLocalExtraData.Write(dest + 30 + m_uLocalFileNameSize); // possible volume change before writing to the file in the segmented archive // so write the local header first pStorage->Write(dest, iLocalSize, true); m_uVolumeStart = pStorage->GetCurrentVolume(); m_uOffset = pStorage->GetPosition() - iLocalSize; ClearFileName(); } WORD CZipFileHeader::GetDataDescriptorSize(bool bConsiderSignature) const { if (IsDataDescriptor()) { WORD size = 12; return (WORD)(bConsiderSignature ? size + 4 : size); } else return 0; } bool CZipFileHeader::NeedsDataDescriptor() const { return m_uEncryptionMethod == CZipCryptograph::encStandard; } void CZipFileHeader::PrepareData(int iLevel, bool bSegm) { // could be == 1, but the way below it works for PredictMaximumFileSizeInArchive when used on an existing segmented archive - for whatever reason m_uInternalAttr = 0; // version made by SetVersion((WORD)(0x14)); m_uCrc32 = 0; m_uComprSize = 0; m_uUncomprSize = 0; ASSERT(CZipCompressor::IsCompressionSupported(m_uMethod) && ((iLevel == 0) == (m_uMethod == CZipCompressor::methodStore))); m_uFlag = 0; if (m_uMethod == CZipCompressor::methodDeflate) switch (iLevel) { case 1: m_uFlag |= 6; break; case 2: m_uFlag |= 4; break; case 8: case 9: m_uFlag |= 2; break; } UpdateFlag(bSegm); m_uVersionNeeded = 0; if (m_uVersionNeeded == 0) m_uVersionNeeded = IsDirectory() ? 0xa : 0x14; // 1.0 or 2.0 } void CZipFileHeader::GetCrcAndSizes(char * pBuffer)const { WriteCrc32(pBuffer); CBytesWriter::WriteBytes(pBuffer + 4, m_uComprSize, 4); CBytesWriter::WriteBytes(pBuffer + 8, m_uUncomprSize, 4); } bool CZipFileHeader::CheckDataDescriptor(CZipStorage* pStorage) const { if (!IsDataDescriptor()) return true; const int sizeOfSize = 4; const int size = 4 + 2 * sizeOfSize; // crc and two sizes CZipAutoBuffer buf(size + 4); pStorage->Read(buf, size, false); char* pBuf; // when an archive is segmented, files that are divided between volume have bit 3 of flag set // which tell about the presence of the data descriptor after the compressed data // This signature may be in a segmented archive that is one volume only // (it is detected as a not segmented archive) if (memcmp(buf, CZipStorage::m_gszExtHeaderSignat, 4) == 0) // there is a signature { pStorage->Read((char*)buf + size, 4, false); pBuf = (char*)buf + 4; } else pBuf = buf; DWORD uCrc32 = 0; ZIP_SIZE_TYPE uCompressed = 0, uUncompressed = 0; CBytesWriter::ReadBytes(uCrc32, pBuf); CBytesWriter::ReadBytes(uCompressed, pBuf + 4, sizeOfSize); CBytesWriter::ReadBytes(uUncompressed, pBuf + 4 + sizeOfSize, sizeOfSize); return uCrc32 == m_uCrc32 && uCompressed == m_uComprSize && uUncompressed == m_uUncomprSize; } DWORD CZipFileHeader::GetSize()const { DWORD uSize = FILEHEADERSIZE + PredictFileNameSize() + GetCommentSize(); uSize += m_aCentralExtraData.GetTotalSize(); if (m_stringSettings.m_bStoreNameInExtraData) { CZipString temp; if (m_pszFileName != NULL) temp = *m_pszFileName; else ConvertFileName(temp); if (temp.GetLength() > 0) { uSize += 4 + 2 + 4; // headerID, size + version, flag + filename code page CZipAutoBuffer buffer; ZipCompatibility::ConvertStringToBuffer(temp, buffer, m_stringSettings.m_uNameCodePage); uSize += buffer.GetSize(); if (!m_stringSettings.IsStandardCommentCodePage()) uSize += 4; } } return uSize; } DWORD CZipFileHeader::GetLocalSize(bool bReal)const { DWORD uSize = LOCALFILEHEADERSIZE + m_aLocalExtraData.GetTotalSize(); if (bReal) uSize += m_uLocalFileNameSize; else uSize += PredictFileNameSize(); return uSize; } void CZipFileHeader::SetComment(LPCTSTR lpszComment) { ZipCompatibility::ConvertStringToBuffer(lpszComment, m_pszComment, m_stringSettings.m_uCommentCodePage); } CZipString CZipFileHeader::GetComment() const { CZipString temp; ZipCompatibility::ConvertBufferToString(temp, m_pszComment, m_stringSettings.m_uCommentCodePage); return temp; } int CZipFileHeader::GetCompressionLevel() const { if (m_uMethod == CZipCompressor::methodStore) return CZipCompressor::levelStore; else if ((m_uFlag & (WORD) 6) != 0) return 1; else if ((m_uFlag & (WORD) 4) != 0) return 2; else if ((m_uFlag & (WORD) 2) != 0) return CZipCompressor::levelBest; else return CZipCompressor::levelDefault; } void CZipFileHeader::SetFileName(LPCTSTR lpszFileName) { if (m_pszFileName == NULL) m_pszFileName = new CZipString(lpszFileName); else *m_pszFileName = lpszFileName; m_pszFileNameBuffer.Release(); } CZipString& CZipFileHeader::GetFileName(bool bClearBuffer) { if (m_pszFileName != NULL) return *m_pszFileName; m_pszFileName = new CZipString(_T("")); ConvertFileName(*m_pszFileName); // don't keep it in memory if (bClearBuffer) m_pszFileNameBuffer.Release(); return *m_pszFileName; } bool CZipFileHeader::IsDirectory() { return ZipPlatform::IsDirectory(GetSystemAttr()); } DWORD CZipFileHeader::GetSystemAttr() { int iSystemComp = GetSystemCompatibility(); if (ZipCompatibility::IsPlatformSupported(iSystemComp)) { DWORD uAttr = iSystemComp == ZipCompatibility::zcUnix ? (m_uExternalAttr >> 16) : (m_uExternalAttr & 0xFFFF); if (!uAttr && CZipPathComponent::HasEndingSeparator(GetFileName())) return ZipPlatform::GetDefaultDirAttributes(); // can happen else { uAttr = ZipCompatibility::ConvertToSystem(uAttr, iSystemComp, ZipPlatform::GetSystemID()); #ifdef ZIP_ARCHIVE_LNX // converting from Windows attributes may create a not readable linux directory if (iSystemComp != ZipCompatibility::zcUnix && ZipPlatform::IsDirectory(uAttr)) return ZipPlatform::GetDefaultDirAttributes(); #endif return uAttr; } } else return CZipPathComponent::HasEndingSeparator(GetFileName()) ? ZipPlatform::GetDefaultDirAttributes() : ZipPlatform::GetDefaultAttributes(); } void CZipFileHeader::SetSystemAttr(DWORD uAttr) { // make it readable under Unix as well, since it stores its attributes in HIWORD(uAttr) int iSystemComp = GetSystemCompatibility(); m_uExternalAttr = ZipCompatibility::ConvertToSystem(uAttr, ZipPlatform::GetSystemID(), iSystemComp); if (iSystemComp == ZipCompatibility::zcUnix) { m_uExternalAttr <<= 16; if (ZipPlatform::IsDirectory(uAttr)) m_uExternalAttr |= 0x10; // make it recognizable under other systems (all use 0x10 for directory) } else // make it readable under linux m_uExternalAttr |= (ZipCompatibility::ConvertToSystem(uAttr, ZipPlatform::GetSystemID(), ZipCompatibility::zcUnix) << 16); } CZipFileHeader& CZipFileHeader::operator=(const CZipFileHeader& header) { m_uVersionMadeBy = header.m_uVersionMadeBy; m_uVersionNeeded = header.m_uVersionNeeded; m_uFlag = header.m_uFlag; m_uMethod = header.m_uMethod; m_uModTime = header.m_uModTime; m_uModDate = header.m_uModDate; m_uCrc32 = header.m_uCrc32; m_uComprSize = header.m_uComprSize; m_uUncomprSize = header.m_uUncomprSize; m_uVolumeStart = header.m_uVolumeStart; m_uInternalAttr = header.m_uInternalAttr; m_uLocalComprSize = header.m_uLocalComprSize; m_uLocalUncomprSize = header.m_uUncomprSize; m_uExternalAttr = header.m_uExternalAttr; m_uLocalFileNameSize = header.m_uLocalFileNameSize;; m_uOffset = header.m_uOffset; m_aLocalExtraData = header.m_aLocalExtraData; m_aCentralExtraData = header.m_aCentralExtraData; m_uEncryptionMethod = header.m_uEncryptionMethod; if (m_pszFileName) delete m_pszFileName; if (header.m_pszFileName) m_pszFileName = new CZipString(*header.m_pszFileName); else m_pszFileName = NULL; m_pszFileNameBuffer = header.m_pszFileNameBuffer; m_pszComment = header.m_pszComment; m_stringSettings = header.m_stringSettings; return *this; } void CZipFileHeader::WriteSmallDataDescriptor(char* pDest, bool bLocal) { WriteCrc32(pDest); if (bLocal) { CBytesWriter::WriteBytes(pDest + 4, m_uLocalComprSize, 4); CBytesWriter::WriteBytes(pDest + 8, m_uLocalUncomprSize, 4); } else { CBytesWriter::WriteBytes(pDest + 4, m_uComprSize, 4); CBytesWriter::WriteBytes(pDest + 8, m_uUncomprSize, 4); } } void CZipFileHeader::WriteDataDescriptor(CZipStorage* pStorage) { if (!IsDataDescriptor()) return; bool signature = NeedsSignatureInDataDescriptor(pStorage); CZipAutoBuffer buf; buf.Allocate(GetDataDescriptorSize(signature)); char* pBuf; if (signature) { memcpy(buf, CZipStorage::m_gszExtHeaderSignat, 4); pBuf = (char*)buf + 4; } else pBuf = buf; WriteCrc32(pBuf); CBytesWriter::WriteBytes(pBuf + 4, m_uComprSize, 4); CBytesWriter::WriteBytes(pBuf + 8, m_uUncomprSize, 4); pStorage->Write(buf, buf.GetSize(), true); } void CZipFileHeader::UpdateLocalHeader(CZipStorage* pStorage) { if (pStorage->IsSegmented() != 0 || IsDataDescriptor()) // there is nothing to fix return; pStorage->Flush(); ZIP_FILE_USIZE uPos = pStorage->m_pFile->GetPosition(); // update crc and sizes, the sizes may already be all right, // but 8 more bytes won't make a difference, we need to update crc32 anyway CZipAutoBuffer buf(12); m_uLocalComprSize = CBytesWriter::WriteSafeU32(m_uComprSize); m_uLocalUncomprSize = CBytesWriter::WriteSafeU32(m_uUncomprSize); WriteSmallDataDescriptor(buf); pStorage->Seek(m_uOffset + 14); pStorage->m_pFile->Write(buf, 12); pStorage->m_pFile->Seek(uPos); } void CZipFileHeader::WriteCrc32(char* pBuf) const { DWORD uCrc = m_bIgnoreCrc32 ? 0 : m_uCrc32; CBytesWriter::WriteBytes(pBuf, uCrc); } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/_features.h0000644000175000017500000000476311300022650021171 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file _features.h * Contains definitions that enable or disable certain features in the ZipArchive Library. * */ #if !defined(ZIPARCHIVE_FEATURES_DOT_H) /// @cond #define ZIPARCHIVE_FEATURES_DOT_H /// @endcond #if _MSC_VER > 1000 #pragma once #endif #include "_platform.h" #ifdef __GNUC__ #ifndef __int64 #define __int64 long long #endif #endif /************ Feel free to adjust the definitions in the following block ************/ /************************************ BLOCK START ***********************************/ /** Make sure it is defined, if you use ZIP64. Comment this out otherwise. \see 0610051629 */ // #define _ZIP64 /** Make sure it is defined, if you use AES. Comment this out otherwise. \see 0610201627|aes */ // #define _ZIP_AES /** Make sure it is defined, if you use the BZIP2 algorithm for compression. Comment this out otherwise. \see 0610231446|bzip2 */ // #define _BZIP2 /** Make sure it is defined, if you want to create seekable data. \see 0711101739 */ // #define _ZIP_SEEK /** Make sure it is defined, if you use the AES encryption in a multithreaded environment or archive sharing (CZipArchive::OpenFrom). Comment this out otherwise. \see 0610201627|aes \see 0610241003|thread */ // #define ZIP_ARCHIVE_USE_LOCKING #ifndef _ZIP64 // Uncomment this to have the index and volume numbers types defined as WORD. Otherwise they are defined as int. #define _ZIP_STRICT_U16 #endif /************************************* BLOCK END ***********************************/ /***** The contents below this line are usually not intended for modification ******/ #endif // !defined(ZIPARCHIVE_FEATURES_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/Appnote.txt0000644000175000017500000040537011300022650021211 0ustar salvisalviFile: APPNOTE.TXT - .ZIP File Format Specification Version: 6.3.1 Revised: April 11, 2007 Copyright (c) 1989 - 2007 PKWARE Inc., All Rights Reserved. The use of certain technological aspects disclosed in the current APPNOTE is available pursuant to the below section entitled "Incorporating PKWARE Proprietary Technology into Your Product". I. Purpose ---------- This specification is intended to define a cross-platform, interoperable file storage and transfer format. Since its first publication in 1989, PKWARE has remained committed to ensuring the interoperability of the .ZIP file format through publication and maintenance of this specification. We trust that all .ZIP compatible vendors and application developers that have adopted and benefited from this format will share and support this commitment to interoperability. II. Contacting PKWARE --------------------- PKWARE, Inc. 648 N. Plankinton Avenue, Suite 220 Milwaukee, WI 53203 +1-414-289-9788 +1-414-289-9789 FAX zipformat@pkware.com III. Disclaimer --------------- Although PKWARE will attempt to supply current and accurate information relating to its file formats, algorithms, and the subject programs, the possibility of error or omission cannot be eliminated. PKWARE therefore expressly disclaims any warranty that the information contained in the associated materials relating to the subject programs and/or the format of the files created or accessed by the subject programs and/or the algorithms used by the subject programs, or any other matter, is current, correct or accurate as delivered. Any risk of damage due to any possible inaccurate information is assumed by the user of the information. Furthermore, the information relating to the subject programs and/or the file formats created or accessed by the subject programs and/or the algorithms used by the subject programs is subject to change without notice. If the version of this file is marked as a NOTIFICATION OF CHANGE, the content defines an Early Feature Specification (EFS) change to the .ZIP file format that may be subject to modification prior to publication of the Final Feature Specification (FFS). This document may also contain information on Planned Feature Specifications (PFS) defining recognized future extensions. IV. Change Log -------------- Version Change Description Date ------- ------------------ ---------- 5.2 -Single Password Symmetric Encryption 06/02/2003 storage 6.1.0 -Smartcard compatibility 01/20/2004 -Documentation on certificate storage 6.2.0 -Introduction of Central Directory 04/26/2004 Encryption for encrypting metadata -Added OS/X to Version Made By values 6.2.1 -Added Extra Field placeholder for 04/01/2005 POSZIP using ID 0x4690 -Clarified size field on "zip64 end of central directory record" 6.2.2 -Documented Final Feature Specification 01/06/2006 for Strong Encryption -Clarifications and typographical corrections 6.3.0 -Added tape positioning storage 09/29/2006 parameters -Expanded list of supported hash algorithms -Expanded list of supported compression algorithms -Expanded list of supported encryption algorithms -Added option for Unicode filename storage -Clarifications for consistent use of Data Descriptor records -Added additional "Extra Field" definitions 6.3.1 -Corrected standard hash values for 04/11/2007 SHA-256/384/512 V. General Format of a .ZIP file -------------------------------- Files stored in arbitrary order. Large .ZIP files can span multiple volumes or be split into user-defined segment sizes. All values are stored in little-endian byte order unless otherwise specified. Overall .ZIP file format: [local file header 1] [file data 1] [data descriptor 1] . . . [local file header n] [file data n] [data descriptor n] [archive decryption header] [archive extra data record] [central directory] [zip64 end of central directory record] [zip64 end of central directory locator] [end of central directory record] A. Local file header: local file header signature 4 bytes (0x04034b50) version needed to extract 2 bytes general purpose bit flag 2 bytes compression method 2 bytes last mod file time 2 bytes last mod file date 2 bytes crc-32 4 bytes compressed size 4 bytes uncompressed size 4 bytes file name length 2 bytes extra field length 2 bytes file name (variable size) extra field (variable size) B. File data Immediately following the local header for a file is the compressed or stored data for the file. The series of [local file header][file data][data descriptor] repeats for each file in the .ZIP archive. C. Data descriptor: crc-32 4 bytes compressed size 4 bytes uncompressed size 4 bytes This descriptor exists only if bit 3 of the general purpose bit flag is set (see below). It is byte aligned and immediately follows the last byte of compressed data. This descriptor is used only when it was not possible to seek in the output .ZIP file, e.g., when the output .ZIP file was standard output or a non-seekable device. For ZIP64(tm) format archives, the compressed and uncompressed sizes are 8 bytes each. When compressing files, compressed and uncompressed sizes should be stored in ZIP64 format (as 8 byte values) when a files size exceeds 0xFFFFFFFF. However ZIP64 format may be used regardless of the size of a file. When extracting, if the zip64 extended information extra field is present for the file the compressed and uncompressed sizes will be 8 byte values. Although not originally assigned a signature, the value 0x08074b50 has commonly been adopted as a signature value for the data descriptor record. Implementers should be aware that ZIP files may be encountered with or without this signature marking data descriptors and should account for either case when reading ZIP files to ensure compatibility. When writing ZIP files, it is recommended to include the signature value marking the data descriptor record. When the signature is used, the fields currently defined for the data descriptor record will immediately follow the signature. An extensible data descriptor will be released in a future version of this APPNOTE. This new record is intended to resolve conflicts with the use of this record going forward, and to provide better support for streamed file processing. When the Central Directory Encryption method is used, the data descriptor record is not required, but may be used. If present, and bit 3 of the general purpose bit field is set to indicate its presence, the values in fields of the data descriptor record should be set to binary zeros. D. Archive decryption header: The Archive Decryption Header is introduced in version 6.2 of the ZIP format specification. This record exists in support of the Central Directory Encryption Feature implemented as part of the Strong Encryption Specification as described in this document. When the Central Directory Structure is encrypted, this decryption header will precede the encrypted data segment. The encrypted data segment will consist of the Archive extra data record (if present) and the encrypted Central Directory Structure data. The format of this data record is identical to the Decryption header record preceding compressed file data. If the central directory structure is encrypted, the location of the start of this data record is determined using the Start of Central Directory field in the Zip64 End of Central Directory record. Refer to the section on the Strong Encryption Specification for information on the fields used in the Archive Decryption Header record. E. Archive extra data record: archive extra data signature 4 bytes (0x08064b50) extra field length 4 bytes extra field data (variable size) The Archive Extra Data Record is introduced in version 6.2 of the ZIP format specification. This record exists in support of the Central Directory Encryption Feature implemented as part of the Strong Encryption Specification as described in this document. When present, this record immediately precedes the central directory data structure. The size of this data record will be included in the Size of the Central Directory field in the End of Central Directory record. If the central directory structure is compressed, but not encrypted, the location of the start of this data record is determined using the Start of Central Directory field in the Zip64 End of Central Directory record. F. Central directory structure: [file header 1] . . . [file header n] [digital signature] File header: central file header signature 4 bytes (0x02014b50) version made by 2 bytes version needed to extract 2 bytes general purpose bit flag 2 bytes compression method 2 bytes last mod file time 2 bytes last mod file date 2 bytes crc-32 4 bytes compressed size 4 bytes uncompressed size 4 bytes file name length 2 bytes extra field length 2 bytes file comment length 2 bytes disk number start 2 bytes internal file attributes 2 bytes external file attributes 4 bytes relative offset of local header 4 bytes file name (variable size) extra field (variable size) file comment (variable size) Digital signature: header signature 4 bytes (0x05054b50) size of data 2 bytes signature data (variable size) With the introduction of the Central Directory Encryption feature in version 6.2 of this specification, the Central Directory Structure may be stored both compressed and encrypted. Although not required, it is assumed when encrypting the Central Directory Structure, that it will be compressed for greater storage efficiency. Information on the Central Directory Encryption feature can be found in the section describing the Strong Encryption Specification. The Digital Signature record will be neither compressed nor encrypted. G. Zip64 end of central directory record zip64 end of central dir signature 4 bytes (0x06064b50) size of zip64 end of central directory record 8 bytes version made by 2 bytes version needed to extract 2 bytes number of this disk 4 bytes number of the disk with the start of the central directory 4 bytes total number of entries in the central directory on this disk 8 bytes total number of entries in the central directory 8 bytes size of the central directory 8 bytes offset of start of central directory with respect to the starting disk number 8 bytes zip64 extensible data sector (variable size) The value stored into the "size of zip64 end of central directory record" should be the size of the remaining record and should not include the leading 12 bytes. Size = SizeOfFixedFields + SizeOfVariableData - 12. The above record structure defines Version 1 of the zip64 end of central directory record. Version 1 was implemented in versions of this specification preceding 6.2 in support of the ZIP64 large file feature. The introduction of the Central Directory Encryption feature implemented in version 6.2 as part of the Strong Encryption Specification defines Version 2 of this record structure. Refer to the section describing the Strong Encryption Specification for details on the version 2 format for this record. Special purpose data may reside in the zip64 extensible data sector field following either a V1 or V2 version of this record. To ensure identification of this special purpose data it must include an identifying header block consisting of the following: Header ID - 2 bytes Data Size - 4 bytes The Header ID field indicates the type of data that is in the data block that follows. Data Size identifies the number of bytes that follow for this data block type. Multiple special purpose data blocks may be present, but each must be preceded by a Header ID and Data Size field. Current mappings of Header ID values supported in this field are as defined in APPENDIX C. H. Zip64 end of central directory locator zip64 end of central dir locator signature 4 bytes (0x07064b50) number of the disk with the start of the zip64 end of central directory 4 bytes relative offset of the zip64 end of central directory record 8 bytes total number of disks 4 bytes I. End of central directory record: end of central dir signature 4 bytes (0x06054b50) number of this disk 2 bytes number of the disk with the start of the central directory 2 bytes total number of entries in the central directory on this disk 2 bytes total number of entries in the central directory 2 bytes size of the central directory 4 bytes offset of start of central directory with respect to the starting disk number 4 bytes .ZIP file comment length 2 bytes .ZIP file comment (variable size) J. Explanation of fields: version made by (2 bytes) The upper byte indicates the compatibility of the file attribute information. If the external file attributes are compatible with MS-DOS and can be read by PKZIP for DOS version 2.04g then this value will be zero. If these attributes are not compatible, then this value will identify the host system on which the attributes are compatible. Software can use this information to determine the line record format for text files etc. The current mappings are: 0 - MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems) 1 - Amiga 2 - OpenVMS 3 - UNIX 4 - VM/CMS 5 - Atari ST 6 - OS/2 H.P.F.S. 7 - Macintosh 8 - Z-System 9 - CP/M 10 - Windows NTFS 11 - MVS (OS/390 - Z/OS) 12 - VSE 13 - Acorn Risc 14 - VFAT 15 - alternate MVS 16 - BeOS 17 - Tandem 18 - OS/400 19 - OS/X (Darwin) 20 thru 255 - unused The lower byte indicates the ZIP specification version (the version of this document) supported by the software used to encode the file. The value/10 indicates the major version number, and the value mod 10 is the minor version number. version needed to extract (2 bytes) The minimum supported ZIP specification version needed to extract the file, mapped as above. This value is based on the specific format features a ZIP program must support to be able to extract the file. If multiple features are applied to a file, the minimum version should be set to the feature having the highest value. New features or feature changes affecting the published format specification will be implemented using higher version numbers than the last published value to avoid conflict. Current minimum feature versions are as defined below: 1.0 - Default value 1.1 - File is a volume label 2.0 - File is a folder (directory) 2.0 - File is compressed using Deflate compression 2.0 - File is encrypted using traditional PKWARE encryption 2.1 - File is compressed using Deflate64(tm) 2.5 - File is compressed using PKWARE DCL Implode 2.7 - File is a patch data set 4.5 - File uses ZIP64 format extensions 4.6 - File is compressed using BZIP2 compression* 5.0 - File is encrypted using DES 5.0 - File is encrypted using 3DES 5.0 - File is encrypted using original RC2 encryption 5.0 - File is encrypted using RC4 encryption 5.1 - File is encrypted using AES encryption 5.1 - File is encrypted using corrected RC2 encryption** 5.2 - File is encrypted using corrected RC2-64 encryption** 6.1 - File is encrypted using non-OAEP key wrapping*** 6.2 - Central directory encryption 6.3 - File is compressed using LZMA 6.3 - File is compressed using PPMd+ 6.3 - File is encrypted using Blowfish 6.3 - File is encrypted using Twofish * Early 7.x (pre-7.2) versions of PKZIP incorrectly set the version needed to extract for BZIP2 compression to be 50 when it should have been 46. ** Refer to the section on Strong Encryption Specification for additional information regarding RC2 corrections. *** Certificate encryption using non-OAEP key wrapping is the intended mode of operation for all versions beginning with 6.1. Support for OAEP key wrapping should only be used for backward compatibility when sending ZIP files to be opened by versions of PKZIP older than 6.1 (5.0 or 6.0). + Files compressed using PPMd should set the version needed to extract field to 6.3, however, not all ZIP programs enforce this and may be unable to decompress data files compressed using PPMd if this value is set. When using ZIP64 extensions, the corresponding value in the zip64 end of central directory record should also be set. This field should be set appropriately to indicate whether Version 1 or Version 2 format is in use. general purpose bit flag: (2 bytes) Bit 0: If set, indicates that the file is encrypted. (For Method 6 - Imploding) Bit 1: If the compression method used was type 6, Imploding, then this bit, if set, indicates an 8K sliding dictionary was used. If clear, then a 4K sliding dictionary was used. Bit 2: If the compression method used was type 6, Imploding, then this bit, if set, indicates 3 Shannon-Fano trees were used to encode the sliding dictionary output. If clear, then 2 Shannon-Fano trees were used. (For Methods 8 and 9 - Deflating) Bit 2 Bit 1 0 0 Normal (-en) compression option was used. 0 1 Maximum (-exx/-ex) compression option was used. 1 0 Fast (-ef) compression option was used. 1 1 Super Fast (-es) compression option was used. (For Method 14 - LZMA) Bit 1: If the compression method used was type 14, LZMA, then this bit, if set, indicates an end-of-stream (EOS) marker is used to mark the end of the compressed data stream. If clear, then an EOS marker is not present and the compressed data size must be known to extract. Note: Bits 1 and 2 are undefined if the compression method is any other. Bit 3: If this bit is set, the fields crc-32, compressed size and uncompressed size are set to zero in the local header. The correct values are put in the data descriptor immediately following the compressed data. (Note: PKZIP version 2.04g for DOS only recognizes this bit for method 8 compression, newer versions of PKZIP recognize this bit for any compression method.) Bit 4: Reserved for use with method 8, for enhanced deflating. Bit 5: If this bit is set, this indicates that the file is compressed patched data. (Note: Requires PKZIP version 2.70 or greater) Bit 6: Strong encryption. If this bit is set, you should set the version needed to extract value to at least 50 and you must also set bit 0. If AES encryption is used, the version needed to extract value must be at least 51. Bit 7: Currently unused. Bit 8: Currently unused. Bit 9: Currently unused. Bit 10: Currently unused. Bit 11: Language encoding flag (EFS). If this bit is set, the filename and comment fields for this file must be encoded using UTF-8. (see APPENDIX D) Bit 12: Reserved by PKWARE for enhanced compression. Bit 13: Used when encrypting the Central Directory to indicate selected data values in the Local Header are masked to hide their actual values. See the section describing the Strong Encryption Specification for details. Bit 14: Reserved by PKWARE. Bit 15: Reserved by PKWARE. compression method: (2 bytes) (see accompanying documentation for algorithm descriptions) 0 - The file is stored (no compression) 1 - The file is Shrunk 2 - The file is Reduced with compression factor 1 3 - The file is Reduced with compression factor 2 4 - The file is Reduced with compression factor 3 5 - The file is Reduced with compression factor 4 6 - The file is Imploded 7 - Reserved for Tokenizing compression algorithm 8 - The file is Deflated 9 - Enhanced Deflating using Deflate64(tm) 10 - PKWARE Data Compression Library Imploding (old IBM TERSE) 11 - Reserved by PKWARE 12 - File is compressed using BZIP2 algorithm 13 - Reserved by PKWARE 14 - LZMA (EFS) 15 - Reserved by PKWARE 16 - Reserved by PKWARE 17 - Reserved by PKWARE 18 - File is compressed using IBM TERSE (new) 19 - IBM LZ77 z Architecture (PFS) 98 - PPMd version I, Rev 1 date and time fields: (2 bytes each) The date and time are encoded in standard MS-DOS format. If input came from standard input, the date and time are those at which compression was started for this data. If encrypting the central directory and general purpose bit flag 13 is set indicating masking, the value stored in the Local Header will be zero. CRC-32: (4 bytes) The CRC-32 algorithm was generously contributed by David Schwaderer and can be found in his excellent book "C Programmers Guide to NetBIOS" published by Howard W. Sams & Co. Inc. The 'magic number' for the CRC is 0xdebb20e3. The proper CRC pre and post conditioning is used, meaning that the CRC register is pre-conditioned with all ones (a starting value of 0xffffffff) and the value is post-conditioned by taking the one's complement of the CRC residual. If bit 3 of the general purpose flag is set, this field is set to zero in the local header and the correct value is put in the data descriptor and in the central directory. When encrypting the central directory, if the local header is not in ZIP64 format and general purpose bit flag 13 is set indicating masking, the value stored in the Local Header will be zero. compressed size: (4 bytes) uncompressed size: (4 bytes) The size of the file compressed and uncompressed, respectively. When a decryption header is present it will be placed in front of the file data and the value of the compressed file size will include the bytes of the decryption header. If bit 3 of the general purpose bit flag is set, these fields are set to zero in the local header and the correct values are put in the data descriptor and in the central directory. If an archive is in ZIP64 format and the value in this field is 0xFFFFFFFF, the size will be in the corresponding 8 byte ZIP64 extended information extra field. When encrypting the central directory, if the local header is not in ZIP64 format and general purpose bit flag 13 is set indicating masking, the value stored for the uncompressed size in the Local Header will be zero. file name length: (2 bytes) extra field length: (2 bytes) file comment length: (2 bytes) The length of the file name, extra field, and comment fields respectively. The combined length of any directory record and these three fields should not generally exceed 65,535 bytes. If input came from standard input, the file name length is set to zero. disk number start: (2 bytes) The number of the disk on which this file begins. If an archive is in ZIP64 format and the value in this field is 0xFFFF, the size will be in the corresponding 4 byte zip64 extended information extra field. internal file attributes: (2 bytes) Bits 1 and 2 are reserved for use by PKWARE. The lowest bit of this field indicates, if set, that the file is apparently an ASCII or text file. If not set, that the file apparently contains binary data. The remaining bits are unused in version 1.0. The 0x0002 bit of this field indicates, if set, that a 4 byte variable record length control field precedes each logical record indicating the length of the record. The record length control field is stored in little-endian byte order. This flag is independent of text control characters, and if used in conjunction with text data, includes any control characters in the total length of the record. This value is provided for mainframe data transfer support. external file attributes: (4 bytes) The mapping of the external attributes is host-system dependent (see 'version made by'). For MS-DOS, the low order byte is the MS-DOS directory attribute byte. If input came from standard input, this field is set to zero. relative offset of local header: (4 bytes) This is the offset from the start of the first disk on which this file appears, to where the local header should be found. If an archive is in ZIP64 format and the value in this field is 0xFFFFFFFF, the size will be in the corresponding 8 byte zip64 extended information extra field. file name: (Variable) The name of the file, with optional relative path. The path stored should not contain a drive or device letter, or a leading slash. All slashes should be forward slashes '/' as opposed to backwards slashes '\' for compatibility with Amiga and UNIX file systems etc. If input came from standard input, there is no file name field. If encrypting the central directory and general purpose bit flag 13 is set indicating masking, the file name stored in the Local Header will not be the actual file name. A masking value consisting of a unique hexadecimal value will be stored. This value will be sequentially incremented for each file in the archive. See the section on the Strong Encryption Specification for details on retrieving the encrypted file name. extra field: (Variable) This is for expansion. If additional information needs to be stored for special needs or for specific platforms, it should be stored here. Earlier versions of the software can then safely skip this file, and find the next file or header. This field will be 0 length in version 1.0. In order to allow different programs and different types of information to be stored in the 'extra' field in .ZIP files, the following structure should be used for all programs storing data in this field: header1+data1 + header2+data2 . . . Each header should consist of: Header ID - 2 bytes Data Size - 2 bytes Note: all fields stored in Intel low-byte/high-byte order. The Header ID field indicates the type of data that is in the following data block. Header ID's of 0 thru 31 are reserved for use by PKWARE. The remaining ID's can be used by third party vendors for proprietary usage. The current Header ID mappings defined by PKWARE are: 0x0001 Zip64 extended information extra field 0x0007 AV Info 0x0008 Reserved for extended language encoding data (PFS) (see APPENDIX D) 0x0009 OS/2 0x000a NTFS 0x000c OpenVMS 0x000d UNIX 0x000e Reserved for file stream and fork descriptors 0x000f Patch Descriptor 0x0014 PKCS#7 Store for X.509 Certificates 0x0015 X.509 Certificate ID and Signature for individual file 0x0016 X.509 Certificate ID for Central Directory 0x0017 Strong Encryption Header 0x0018 Record Management Controls 0x0019 PKCS#7 Encryption Recipient Certificate List 0x0065 IBM S/390 (Z390), AS/400 (I400) attributes - uncompressed 0x0066 Reserved for IBM S/390 (Z390), AS/400 (I400) attributes - compressed 0x4690 POSZIP 4690 (reserved) Third party mappings commonly used are: 0x07c8 Macintosh 0x2605 ZipIt Macintosh 0x2705 ZipIt Macintosh 1.3.5+ 0x2805 ZipIt Macintosh 1.3.5+ 0x334d Info-ZIP Macintosh 0x4341 Acorn/SparkFS 0x4453 Windows NT security descriptor (binary ACL) 0x4704 VM/CMS 0x470f MVS 0x4b46 FWKCS MD5 (see below) 0x4c41 OS/2 access control list (text ACL) 0x4d49 Info-ZIP OpenVMS 0x4f4c Xceed original location extra field 0x5356 AOS/VS (ACL) 0x5455 extended timestamp 0x554e Xceed unicode extra field 0x5855 Info-ZIP UNIX (original, also OS/2, NT, etc) 0x6542 BeOS/BeBox 0x756e ASi UNIX 0x7855 Info-ZIP UNIX (new) 0xa220 Microsoft Open Packaging Growth Hint 0xfd4a SMS/QDOS Detailed descriptions of Extra Fields defined by third party mappings will be documented as information on these data structures is made available to PKWARE. PKWARE does not guarantee the accuracy of any published third party data. The Data Size field indicates the size of the following data block. Programs can use this value to skip to the next header block, passing over any data blocks that are not of interest. Note: As stated above, the size of the entire .ZIP file header, including the file name, comment, and extra field should not exceed 64K in size. In case two different programs should appropriate the same Header ID value, it is strongly recommended that each program place a unique signature of at least two bytes in size (and preferably 4 bytes or bigger) at the start of each data area. Every program should verify that its unique signature is present, in addition to the Header ID value being correct, before assuming that it is a block of known type. -Zip64 Extended Information Extra Field (0x0001): The following is the layout of the zip64 extended information "extra" block. If one of the size or offset fields in the Local or Central directory record is too small to hold the required data, a Zip64 extended information record is created. The order of the fields in the zip64 extended information record is fixed, but the fields will only appear if the corresponding Local or Central directory record field is set to 0xFFFF or 0xFFFFFFFF. Note: all fields stored in Intel low-byte/high-byte order. Value Size Description ----- ---- ----------- (ZIP64) 0x0001 2 bytes Tag for this "extra" block type Size 2 bytes Size of this "extra" block Original Size 8 bytes Original uncompressed file size Compressed Size 8 bytes Size of compressed data Relative Header Offset 8 bytes Offset of local header record Disk Start Number 4 bytes Number of the disk on which this file starts This entry in the Local header must include BOTH original and compressed file size fields. If encrypting the central directory and bit 13 of the general purpose bit flag is set indicating masking, the value stored in the Local Header for the original file size will be zero. -OS/2 Extra Field (0x0009): The following is the layout of the OS/2 attributes "extra" block. (Last Revision 09/05/95) Note: all fields stored in Intel low-byte/high-byte order. Value Size Description ----- ---- ----------- (OS/2) 0x0009 2 bytes Tag for this "extra" block type TSize 2 bytes Size for the following data block BSize 4 bytes Uncompressed Block Size CType 2 bytes Compression type EACRC 4 bytes CRC value for uncompress block (var) variable Compressed block The OS/2 extended attribute structure (FEA2LIST) is compressed and then stored in it's entirety within this structure. There will only ever be one "block" of data in VarFields[]. -NTFS Extra Field (0x000a): The following is the layout of the NTFS attributes "extra" block. (Note: At this time the Mtime, Atime and Ctime values may be used on any WIN32 system.) Note: all fields stored in Intel low-byte/high-byte order. Value Size Description ----- ---- ----------- (NTFS) 0x000a 2 bytes Tag for this "extra" block type TSize 2 bytes Size of the total "extra" block Reserved 4 bytes Reserved for future use Tag1 2 bytes NTFS attribute tag value #1 Size1 2 bytes Size of attribute #1, in bytes (var.) Size1 Attribute #1 data . . . TagN 2 bytes NTFS attribute tag value #N SizeN 2 bytes Size of attribute #N, in bytes (var.) SizeN Attribute #N data For NTFS, values for Tag1 through TagN are as follows: (currently only one set of attributes is defined for NTFS) Tag Size Description ----- ---- ----------- 0x0001 2 bytes Tag for attribute #1 Size1 2 bytes Size of attribute #1, in bytes Mtime 8 bytes File last modification time Atime 8 bytes File last access time Ctime 8 bytes File creation time -OpenVMS Extra Field (0x000c): The following is the layout of the OpenVMS attributes "extra" block. Note: all fields stored in Intel low-byte/high-byte order. Value Size Description ----- ---- ----------- (VMS) 0x000c 2 bytes Tag for this "extra" block type TSize 2 bytes Size of the total "extra" block CRC 4 bytes 32-bit CRC for remainder of the block Tag1 2 bytes OpenVMS attribute tag value #1 Size1 2 bytes Size of attribute #1, in bytes (var.) Size1 Attribute #1 data . . . TagN 2 bytes OpenVMS attribute tag value #N SizeN 2 bytes Size of attribute #N, in bytes (var.) SizeN Attribute #N data Rules: 1. There will be one or more of attributes present, which will each be preceded by the above TagX & SizeX values. These values are identical to the ATR$C_XXXX and ATR$S_XXXX constants which are defined in ATR.H under OpenVMS C. Neither of these values will ever be zero. 2. No word alignment or padding is performed. 3. A well-behaved PKZIP/OpenVMS program should never produce more than one sub-block with the same TagX value. Also, there will never be more than one "extra" block of type 0x000c in a particular directory record. -UNIX Extra Field (0x000d): The following is the layout of the UNIX "extra" block. Note: all fields are stored in Intel low-byte/high-byte order. Value Size Description ----- ---- ----------- (UNIX) 0x000d 2 bytes Tag for this "extra" block type TSize 2 bytes Size for the following data block Atime 4 bytes File last access time Mtime 4 bytes File last modification time Uid 2 bytes File user ID Gid 2 bytes File group ID (var) variable Variable length data field The variable length data field will contain file type specific data. Currently the only values allowed are the original "linked to" file names for hard or symbolic links, and the major and minor device node numbers for character and block device nodes. Since device nodes cannot be either symbolic or hard links, only one set of variable length data is stored. Link files will have the name of the original file stored. This name is NOT NULL terminated. Its size can be determined by checking TSize - 12. Device entries will have eight bytes stored as two 4 byte entries (in little endian format). The first entry will be the major device number, and the second the minor device number. -PATCH Descriptor Extra Field (0x000f): The following is the layout of the Patch Descriptor "extra" block. Note: all fields stored in Intel low-byte/high-byte order. Value Size Description ----- ---- ----------- (Patch) 0x000f 2 bytes Tag for this "extra" block type TSize 2 bytes Size of the total "extra" block Version 2 bytes Version of the descriptor Flags 4 bytes Actions and reactions (see below) OldSize 4 bytes Size of the file about to be patched OldCRC 4 bytes 32-bit CRC of the file to be patched NewSize 4 bytes Size of the resulting file NewCRC 4 bytes 32-bit CRC of the resulting file Actions and reactions Bits Description ---- ---------------- 0 Use for auto detection 1 Treat as a self-patch 2-3 RESERVED 4-5 Action (see below) 6-7 RESERVED 8-9 Reaction (see below) to absent file 10-11 Reaction (see below) to newer file 12-13 Reaction (see below) to unknown file 14-15 RESERVED 16-31 RESERVED Actions Action Value ------ ----- none 0 add 1 delete 2 patch 3 Reactions Reaction Value -------- ----- ask 0 skip 1 ignore 2 fail 3 Patch support is provided by PKPatchMaker(tm) technology and is covered under U.S. Patents and Patents Pending. The use or implementation in a product of certain technological aspects set forth in the current APPNOTE, including those with regard to strong encryption, patching, or extended tape operations requires a license from PKWARE. Please contact PKWARE with regard to acquiring a license. -PKCS#7 Store for X.509 Certificates (0x0014): This field contains information about each of the certificates files may be signed with. When the Central Directory Encryption feature is enabled for a ZIP file, this record will appear in the Archive Extra Data Record, otherwise it will appear in the first central directory record and will be ignored in any other record. Note: all fields stored in Intel low-byte/high-byte order. Value Size Description ----- ---- ----------- (Store) 0x0014 2 bytes Tag for this "extra" block type TSize 2 bytes Size of the store data TData TSize Data about the store -X.509 Certificate ID and Signature for individual file (0x0015): This field contains the information about which certificate in the PKCS#7 store was used to sign a particular file. It also contains the signature data. This field can appear multiple times, but can only appear once per certificate. Note: all fields stored in Intel low-byte/high-byte order. Value Size Description ----- ---- ----------- (CID) 0x0015 2 bytes Tag for this "extra" block type TSize 2 bytes Size of data that follows TData TSize Signature Data -X.509 Certificate ID and Signature for central directory (0x0016): This field contains the information about which certificate in the PKCS#7 store was used to sign the central directory structure. When the Central Directory Encryption feature is enabled for a ZIP file, this record will appear in the Archive Extra Data Record, otherwise it will appear in the first central directory record. Note: all fields stored in Intel low-byte/high-byte order. Value Size Description ----- ---- ----------- (CDID) 0x0016 2 bytes Tag for this "extra" block type TSize 2 bytes Size of data that follows TData TSize Data -Strong Encryption Header (0x0017): Value Size Description ----- ---- ----------- 0x0017 2 bytes Tag for this "extra" block type TSize 2 bytes Size of data that follows Format 2 bytes Format definition for this record AlgID 2 bytes Encryption algorithm identifier Bitlen 2 bytes Bit length of encryption key Flags 2 bytes Processing flags CertData TSize-8 Certificate decryption extra field data (refer to the explanation for CertData in the section describing the Certificate Processing Method under the Strong Encryption Specification) -Record Management Controls (0x0018): Value Size Description ----- ---- ----------- (Rec-CTL) 0x0018 2 bytes Tag for this "extra" block type CSize 2 bytes Size of total extra block data Tag1 2 bytes Record control attribute 1 Size1 2 bytes Size of attribute 1, in bytes Data1 Size1 Attribute 1 data . . . TagN 2 bytes Record control attribute N SizeN 2 bytes Size of attribute N, in bytes DataN SizeN Attribute N data -PKCS#7 Encryption Recipient Certificate List (0x0019): This field contains information about each of the certificates used in encryption processing and it can be used to identify who is allowed to decrypt encrypted files. This field should only appear in the archive extra data record. This field is not required and serves only to aide archive modifications by preserving public encryption key data. Individual security requirements may dictate that this data be omitted to deter information exposure. Note: all fields stored in Intel low-byte/high-byte order. Value Size Description ----- ---- ----------- (CStore) 0x0019 2 bytes Tag for this "extra" block type TSize 2 bytes Size of the store data TData TSize Data about the store TData: Value Size Description ----- ---- ----------- Version 2 bytes Format version number - must 0x0001 at this time CStore (var) PKCS#7 data blob -MVS Extra Field (0x0065): The following is the layout of the MVS "extra" block. Note: Some fields are stored in Big Endian format. All text is in EBCDIC format unless otherwise specified. Value Size Description ----- ---- ----------- (MVS) 0x0065 2 bytes Tag for this "extra" block type TSize 2 bytes Size for the following data block ID 4 bytes EBCDIC "Z390" 0xE9F3F9F0 or "T4MV" for TargetFour (var) TSize-4 Attribute data (see APPENDIX B) -OS/400 Extra Field (0x0065): The following is the layout of the OS/400 "extra" block. Note: Some fields are stored in Big Endian format. All text is in EBCDIC format unless otherwise specified. Value Size Description ----- ---- ----------- (OS400) 0x0065 2 bytes Tag for this "extra" block type TSize 2 bytes Size for the following data block ID 4 bytes EBCDIC "I400" 0xC9F4F0F0 or "T4MV" for TargetFour (var) TSize-4 Attribute data (see APPENDIX A) Third-party Mappings: -ZipIt Macintosh Extra Field (long) (0x2605): The following is the layout of the ZipIt extra block for Macintosh. The local-header and central-header versions are identical. This block must be present if the file is stored MacBinary-encoded and it should not be used if the file is not stored MacBinary-encoded. Value Size Description ----- ---- ----------- (Mac2) 0x2605 Short tag for this extra block type TSize Short total data size for this block "ZPIT" beLong extra-field signature FnLen Byte length of FileName FileName variable full Macintosh filename FileType Byte[4] four-byte Mac file type string Creator Byte[4] four-byte Mac creator string -ZipIt Macintosh Extra Field (short, for files) (0x2705): The following is the layout of a shortened variant of the ZipIt extra block for Macintosh (without "full name" entry). This variant is used by ZipIt 1.3.5 and newer for entries of files (not directories) that do not have a MacBinary encoded file. The local-header and central-header versions are identical. Value Size Description ----- ---- ----------- (Mac2b) 0x2705 Short tag for this extra block type TSize Short total data size for this block (12) "ZPIT" beLong extra-field signature FileType Byte[4] four-byte Mac file type string Creator Byte[4] four-byte Mac creator string fdFlags beShort attributes from FInfo.frFlags, may be omitted 0x0000 beShort reserved, may be omitted -ZipIt Macintosh Extra Field (short, for directories) (0x2805): The following is the layout of a shortened variant of the ZipIt extra block for Macintosh used only for directory entries. This variant is used by ZipIt 1.3.5 and newer to save some optional Mac-specific information about directories. The local-header and central-header versions are identical. Value Size Description ----- ---- ----------- (Mac2c) 0x2805 Short tag for this extra block type TSize Short total data size for this block (12) "ZPIT" beLong extra-field signature frFlags beShort attributes from DInfo.frFlags, may be omitted View beShort ZipIt view flag, may be omitted The View field specifies ZipIt-internal settings as follows: Bits of the Flags: bit 0 if set, the folder is shown expanded (open) when the archive contents are viewed in ZipIt. bits 1-15 reserved, zero; -FWKCS MD5 Extra Field (0x4b46): The FWKCS Contents_Signature System, used in automatically identifying files independent of file name, optionally adds and uses an extra field to support the rapid creation of an enhanced contents_signature: Header ID = 0x4b46 Data Size = 0x0013 Preface = 'M','D','5' followed by 16 bytes containing the uncompressed file's 128_bit MD5 hash(1), low byte first. When FWKCS revises a .ZIP file central directory to add this extra field for a file, it also replaces the central directory entry for that file's uncompressed file length with a measured value. FWKCS provides an option to strip this extra field, if present, from a .ZIP file central directory. In adding this extra field, FWKCS preserves .ZIP file Authenticity Verification; if stripping this extra field, FWKCS preserves all versions of AV through PKZIP version 2.04g. FWKCS, and FWKCS Contents_Signature System, are trademarks of Frederick W. Kantor. (1) R. Rivest, RFC1321.TXT, MIT Laboratory for Computer Science and RSA Data Security, Inc., April 1992. ll.76-77: "The MD5 algorithm is being placed in the public domain for review and possible adoption as a standard." -Microsoft Open Packaging Growth Hint (0xa220): Value Size Description ----- ---- ----------- 0xa220 Short tag for this extra block type TSize Short size of Sig + PadVal + Padding Sig Short verification signature (A028) PadVal Short Initial padding value Padding variable filled with NULL characters file comment: (Variable) The comment for this file. number of this disk: (2 bytes) The number of this disk, which contains central directory end record. If an archive is in ZIP64 format and the value in this field is 0xFFFF, the size will be in the corresponding 4 byte zip64 end of central directory field. number of the disk with the start of the central directory: (2 bytes) The number of the disk on which the central directory starts. If an archive is in ZIP64 format and the value in this field is 0xFFFF, the size will be in the corresponding 4 byte zip64 end of central directory field. total number of entries in the central dir on this disk: (2 bytes) The number of central directory entries on this disk. If an archive is in ZIP64 format and the value in this field is 0xFFFF, the size will be in the corresponding 8 byte zip64 end of central directory field. total number of entries in the central dir: (2 bytes) The total number of files in the .ZIP file. If an archive is in ZIP64 format and the value in this field is 0xFFFF, the size will be in the corresponding 8 byte zip64 end of central directory field. size of the central directory: (4 bytes) The size (in bytes) of the entire central directory. If an archive is in ZIP64 format and the value in this field is 0xFFFFFFFF, the size will be in the corresponding 8 byte zip64 end of central directory field. offset of start of central directory with respect to the starting disk number: (4 bytes) Offset of the start of the central directory on the disk on which the central directory starts. If an archive is in ZIP64 format and the value in this field is 0xFFFFFFFF, the size will be in the corresponding 8 byte zip64 end of central directory field. .ZIP file comment length: (2 bytes) The length of the comment for this .ZIP file. .ZIP file comment: (Variable) The comment for this .ZIP file. ZIP file comment data is stored unsecured. No encryption or data authentication is applied to this area at this time. Confidential information should not be stored in this section. zip64 extensible data sector (variable size) (currently reserved for use by PKWARE) K. Splitting and Spanning ZIP files Spanning is the process of segmenting a ZIP file across multiple removable media. This support has typically only been provided for DOS formatted floppy diskettes. File splitting is a newer derivative of spanning. Splitting follows the same segmentation process as spanning, however, it does not require writing each segment to a unique removable medium and instead supports placing all pieces onto local or non-removable locations such as file systems, local drives, folders, etc... A key difference between spanned and split ZIP files is that all pieces of a spanned ZIP file have the same name. Since each piece is written to a separate volume, no name collisions occur and each segment can reuse the original .ZIP file name given to the archive. Sequence ordering for DOS spanned archives uses the DOS volume label to determine segment numbers. Volume labels for each segment are written using the form PKBACK#xxx, where xxx is the segment number written as a decimal value from 001 - nnn. Split ZIP files are typically written to the same location and are subject to name collisions if the spanned name format is used since each segment will reside on the same drive. To avoid name collisions, split archives are named as follows. Segment 1 = filename.z01 Segment n-1 = filename.z(n-1) Segment n = filename.zip The .ZIP extension is used on the last segment to support quickly reading the central directory. The segment number n should be a decimal value. Spanned ZIP files may be PKSFX Self-extracting ZIP files. PKSFX files may also be split, however, in this case the first segment must be named filename.exe. The first segment of a split PKSFX archive must be large enough to include the entire executable program. Capacities for split archives are as follows. Maximum number of segments = 4,294,967,295 - 1 Maximum .ZIP segment size = 4,294,967,295 bytes Minimum segment size = 64K Maximum PKSFX segment size = 2,147,483,647 bytes Segment sizes may be different however by convention, all segment sizes should be the same with the exception of the last, which may be smaller. Local and central directory header records must never be split across a segment boundary. When writing a header record, if the number of bytes remaining within a segment is less than the size of the header record, end the current segment and write the header at the start of the next segment. The central directory may span segment boundaries, but no single record in the central directory should be split across segments. Spanned/Split archives created using PKZIP for Windows (V2.50 or greater), PKZIP Command Line (V2.50 or greater), or PKZIP Explorer will include a special spanning signature as the first 4 bytes of the first segment of the archive. This signature (0x08074b50) will be followed immediately by the local header signature for the first file in the archive. A special spanning marker may also appear in spanned/split archives if the spanning or splitting process starts but only requires one segment. In this case the 0x08074b50 signature will be replaced with the temporary spanning marker signature of 0x30304b50. Split archives can only be uncompressed by other versions of PKZIP that know how to create a split archive. The signature value 0x08074b50 is also used by some ZIP implementations as a marker for the Data Descriptor record. Conflict in this alternate assignment can be avoided by ensuring the position of the signature within the ZIP file to determine the use for which it is intended. L. General notes: 1) All fields unless otherwise noted are unsigned and stored in Intel low-byte:high-byte, low-word:high-word order. 2) String fields are not null terminated, since the length is given explicitly. 3) The entries in the central directory may not necessarily be in the same order that files appear in the .ZIP file. 4) If one of the fields in the end of central directory record is too small to hold required data, the field should be set to -1 (0xFFFF or 0xFFFFFFFF) and the ZIP64 format record should be created. 5) The end of central directory record and the Zip64 end of central directory locator record must reside on the same disk when splitting or spanning an archive. VI. UnShrinking - Method 1 -------------------------- Shrinking is a Dynamic Ziv-Lempel-Welch compression algorithm with partial clearing. The initial code size is 9 bits, and the maximum code size is 13 bits. Shrinking differs from conventional Dynamic Ziv-Lempel-Welch implementations in several respects: 1) The code size is controlled by the compressor, and is not automatically increased when codes larger than the current code size are created (but not necessarily used). When the decompressor encounters the code sequence 256 (decimal) followed by 1, it should increase the code size read from the input stream to the next bit size. No blocking of the codes is performed, so the next code at the increased size should be read from the input stream immediately after where the previous code at the smaller bit size was read. Again, the decompressor should not increase the code size used until the sequence 256,1 is encountered. 2) When the table becomes full, total clearing is not performed. Rather, when the compressor emits the code sequence 256,2 (decimal), the decompressor should clear all leaf nodes from the Ziv-Lempel tree, and continue to use the current code size. The nodes that are cleared from the Ziv-Lempel tree are then re-used, with the lowest code value re-used first, and the highest code value re-used last. The compressor can emit the sequence 256,2 at any time. VII. Expanding - Methods 2-5 ---------------------------- The Reducing algorithm is actually a combination of two distinct algorithms. The first algorithm compresses repeated byte sequences, and the second algorithm takes the compressed stream from the first algorithm and applies a probabilistic compression method. The probabilistic compression stores an array of 'follower sets' S(j), for j=0 to 255, corresponding to each possible ASCII character. Each set contains between 0 and 32 characters, to be denoted as S(j)[0],...,S(j)[m], where m<32. The sets are stored at the beginning of the data area for a Reduced file, in reverse order, with S(255) first, and S(0) last. The sets are encoded as { N(j), S(j)[0],...,S(j)[N(j)-1] }, where N(j) is the size of set S(j). N(j) can be 0, in which case the follower set for S(j) is empty. Each N(j) value is encoded in 6 bits, followed by N(j) eight bit character values corresponding to S(j)[0] to S(j)[N(j)-1] respectively. If N(j) is 0, then no values for S(j) are stored, and the value for N(j-1) immediately follows. Immediately after the follower sets, is the compressed data stream. The compressed data stream can be interpreted for the probabilistic decompression as follows: let Last-Character <- 0. loop until done if the follower set S(Last-Character) is empty then read 8 bits from the input stream, and copy this value to the output stream. otherwise if the follower set S(Last-Character) is non-empty then read 1 bit from the input stream. if this bit is not zero then read 8 bits from the input stream, and copy this value to the output stream. otherwise if this bit is zero then read B(N(Last-Character)) bits from the input stream, and assign this value to I. Copy the value of S(Last-Character)[I] to the output stream. assign the last value placed on the output stream to Last-Character. end loop B(N(j)) is defined as the minimal number of bits required to encode the value N(j)-1. The decompressed stream from above can then be expanded to re-create the original file as follows: let State <- 0. loop until done read 8 bits from the input stream into C. case State of 0: if C is not equal to DLE (144 decimal) then copy C to the output stream. otherwise if C is equal to DLE then let State <- 1. 1: if C is non-zero then let V <- C. let Len <- L(V) let State <- F(Len). otherwise if C is zero then copy the value 144 (decimal) to the output stream. let State <- 0 2: let Len <- Len + C let State <- 3. 3: move backwards D(V,C) bytes in the output stream (if this position is before the start of the output stream, then assume that all the data before the start of the output stream is filled with zeros). copy Len+3 bytes from this position to the output stream. let State <- 0. end case end loop The functions F,L, and D are dependent on the 'compression factor', 1 through 4, and are defined as follows: For compression factor 1: L(X) equals the lower 7 bits of X. F(X) equals 2 if X equals 127 otherwise F(X) equals 3. D(X,Y) equals the (upper 1 bit of X) * 256 + Y + 1. For compression factor 2: L(X) equals the lower 6 bits of X. F(X) equals 2 if X equals 63 otherwise F(X) equals 3. D(X,Y) equals the (upper 2 bits of X) * 256 + Y + 1. For compression factor 3: L(X) equals the lower 5 bits of X. F(X) equals 2 if X equals 31 otherwise F(X) equals 3. D(X,Y) equals the (upper 3 bits of X) * 256 + Y + 1. For compression factor 4: L(X) equals the lower 4 bits of X. F(X) equals 2 if X equals 15 otherwise F(X) equals 3. D(X,Y) equals the (upper 4 bits of X) * 256 + Y + 1. VIII. Imploding - Method 6 -------------------------- The Imploding algorithm is actually a combination of two distinct algorithms. The first algorithm compresses repeated byte sequences using a sliding dictionary. The second algorithm is used to compress the encoding of the sliding dictionary output, using multiple Shannon-Fano trees. The Imploding algorithm can use a 4K or 8K sliding dictionary size. The dictionary size used can be determined by bit 1 in the general purpose flag word; a 0 bit indicates a 4K dictionary while a 1 bit indicates an 8K dictionary. The Shannon-Fano trees are stored at the start of the compressed file. The number of trees stored is defined by bit 2 in the general purpose flag word; a 0 bit indicates two trees stored, a 1 bit indicates three trees are stored. If 3 trees are stored, the first Shannon-Fano tree represents the encoding of the Literal characters, the second tree represents the encoding of the Length information, the third represents the encoding of the Distance information. When 2 Shannon-Fano trees are stored, the Length tree is stored first, followed by the Distance tree. The Literal Shannon-Fano tree, if present is used to represent the entire ASCII character set, and contains 256 values. This tree is used to compress any data not compressed by the sliding dictionary algorithm. When this tree is present, the Minimum Match Length for the sliding dictionary is 3. If this tree is not present, the Minimum Match Length is 2. The Length Shannon-Fano tree is used to compress the Length part of the (length,distance) pairs from the sliding dictionary output. The Length tree contains 64 values, ranging from the Minimum Match Length, to 63 plus the Minimum Match Length. The Distance Shannon-Fano tree is used to compress the Distance part of the (length,distance) pairs from the sliding dictionary output. The Distance tree contains 64 values, ranging from 0 to 63, representing the upper 6 bits of the distance value. The distance values themselves will be between 0 and the sliding dictionary size, either 4K or 8K. The Shannon-Fano trees themselves are stored in a compressed format. The first byte of the tree data represents the number of bytes of data representing the (compressed) Shannon-Fano tree minus 1. The remaining bytes represent the Shannon-Fano tree data encoded as: High 4 bits: Number of values at this bit length + 1. (1 - 16) Low 4 bits: Bit Length needed to represent value + 1. (1 - 16) The Shannon-Fano codes can be constructed from the bit lengths using the following algorithm: 1) Sort the Bit Lengths in ascending order, while retaining the order of the original lengths stored in the file. 2) Generate the Shannon-Fano trees: Code <- 0 CodeIncrement <- 0 LastBitLength <- 0 i <- number of Shannon-Fano codes - 1 (either 255 or 63) loop while i >= 0 Code = Code + CodeIncrement if BitLength(i) <> LastBitLength then LastBitLength=BitLength(i) CodeIncrement = 1 shifted left (16 - LastBitLength) ShannonCode(i) = Code i <- i - 1 end loop 3) Reverse the order of all the bits in the above ShannonCode() vector, so that the most significant bit becomes the least significant bit. For example, the value 0x1234 (hex) would become 0x2C48 (hex). 4) Restore the order of Shannon-Fano codes as originally stored within the file. Example: This example will show the encoding of a Shannon-Fano tree of size 8. Notice that the actual Shannon-Fano trees used for Imploding are either 64 or 256 entries in size. Example: 0x02, 0x42, 0x01, 0x13 The first byte indicates 3 values in this table. Decoding the bytes: 0x42 = 5 codes of 3 bits long 0x01 = 1 code of 2 bits long 0x13 = 2 codes of 4 bits long This would generate the original bit length array of: (3, 3, 3, 3, 3, 2, 4, 4) There are 8 codes in this table for the values 0 thru 7. Using the algorithm to obtain the Shannon-Fano codes produces: Reversed Order Original Val Sorted Constructed Code Value Restored Length --- ------ ----------------- -------- -------- ------ 0: 2 1100000000000000 11 101 3 1: 3 1010000000000000 101 001 3 2: 3 1000000000000000 001 110 3 3: 3 0110000000000000 110 010 3 4: 3 0100000000000000 010 100 3 5: 3 0010000000000000 100 11 2 6: 4 0001000000000000 1000 1000 4 7: 4 0000000000000000 0000 0000 4 The values in the Val, Order Restored and Original Length columns now represent the Shannon-Fano encoding tree that can be used for decoding the Shannon-Fano encoded data. How to parse the variable length Shannon-Fano values from the data stream is beyond the scope of this document. (See the references listed at the end of this document for more information.) However, traditional decoding schemes used for Huffman variable length decoding, such as the Greenlaw algorithm, can be successfully applied. The compressed data stream begins immediately after the compressed Shannon-Fano data. The compressed data stream can be interpreted as follows: loop until done read 1 bit from input stream. if this bit is non-zero then (encoded data is literal data) if Literal Shannon-Fano tree is present read and decode character using Literal Shannon-Fano tree. otherwise read 8 bits from input stream. copy character to the output stream. otherwise (encoded data is sliding dictionary match) if 8K dictionary size read 7 bits for offset Distance (lower 7 bits of offset). otherwise read 6 bits for offset Distance (lower 6 bits of offset). using the Distance Shannon-Fano tree, read and decode the upper 6 bits of the Distance value. using the Length Shannon-Fano tree, read and decode the Length value. Length <- Length + Minimum Match Length if Length = 63 + Minimum Match Length read 8 bits from the input stream, add this value to Length. move backwards Distance+1 bytes in the output stream, and copy Length characters from this position to the output stream. (if this position is before the start of the output stream, then assume that all the data before the start of the output stream is filled with zeros). end loop IX. Tokenizing - Method 7 ------------------------- This method is not used by PKZIP. X. Deflating - Method 8 ----------------------- The Deflate algorithm is similar to the Implode algorithm using a sliding dictionary of up to 32K with secondary compression from Huffman/Shannon-Fano codes. The compressed data is stored in blocks with a header describing the block and the Huffman codes used in the data block. The header format is as follows: Bit 0: Last Block bit This bit is set to 1 if this is the last compressed block in the data. Bits 1-2: Block type 00 (0) - Block is stored - All stored data is byte aligned. Skip bits until next byte, then next word = block length, followed by the ones compliment of the block length word. Remaining data in block is the stored data. 01 (1) - Use fixed Huffman codes for literal and distance codes. Lit Code Bits Dist Code Bits --------- ---- --------- ---- 0 - 143 8 0 - 31 5 144 - 255 9 256 - 279 7 280 - 287 8 Literal codes 286-287 and distance codes 30-31 are never used but participate in the huffman construction. 10 (2) - Dynamic Huffman codes. (See expanding Huffman codes) 11 (3) - Reserved - Flag a "Error in compressed data" if seen. Expanding Huffman Codes ----------------------- If the data block is stored with dynamic Huffman codes, the Huffman codes are sent in the following compressed format: 5 Bits: # of Literal codes sent - 256 (256 - 286) All other codes are never sent. 5 Bits: # of Dist codes - 1 (1 - 32) 4 Bits: # of Bit Length codes - 3 (3 - 19) The Huffman codes are sent as bit lengths and the codes are built as described in the implode algorithm. The bit lengths themselves are compressed with Huffman codes. There are 19 bit length codes: 0 - 15: Represent bit lengths of 0 - 15 16: Copy the previous bit length 3 - 6 times. The next 2 bits indicate repeat length (0 = 3, ... ,3 = 6) Example: Codes 8, 16 (+2 bits 11), 16 (+2 bits 10) will expand to 12 bit lengths of 8 (1 + 6 + 5) 17: Repeat a bit length of 0 for 3 - 10 times. (3 bits of length) 18: Repeat a bit length of 0 for 11 - 138 times (7 bits of length) The lengths of the bit length codes are sent packed 3 bits per value (0 - 7) in the following order: 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 The Huffman codes should be built as described in the Implode algorithm except codes are assigned starting at the shortest bit length, i.e. the shortest code should be all 0's rather than all 1's. Also, codes with a bit length of zero do not participate in the tree construction. The codes are then used to decode the bit lengths for the literal and distance tables. The bit lengths for the literal tables are sent first with the number of entries sent described by the 5 bits sent earlier. There are up to 286 literal characters; the first 256 represent the respective 8 bit character, code 256 represents the End-Of-Block code, the remaining 29 codes represent copy lengths of 3 thru 258. There are up to 30 distance codes representing distances from 1 thru 32k as described below. Length Codes ------------ Extra Extra Extra Extra Code Bits Length Code Bits Lengths Code Bits Lengths Code Bits Length(s) ---- ---- ------ ---- ---- ------- ---- ---- ------- ---- ---- --------- 257 0 3 265 1 11,12 273 3 35-42 281 5 131-162 258 0 4 266 1 13,14 274 3 43-50 282 5 163-194 259 0 5 267 1 15,16 275 3 51-58 283 5 195-226 260 0 6 268 1 17,18 276 3 59-66 284 5 227-257 261 0 7 269 2 19-22 277 4 67-82 285 0 258 262 0 8 270 2 23-26 278 4 83-98 263 0 9 271 2 27-30 279 4 99-114 264 0 10 272 2 31-34 280 4 115-130 Distance Codes -------------- Extra Extra Extra Extra Code Bits Dist Code Bits Dist Code Bits Distance Code Bits Distance ---- ---- ---- ---- ---- ------ ---- ---- -------- ---- ---- -------- 0 0 1 8 3 17-24 16 7 257-384 24 11 4097-6144 1 0 2 9 3 25-32 17 7 385-512 25 11 6145-8192 2 0 3 10 4 33-48 18 8 513-768 26 12 8193-12288 3 0 4 11 4 49-64 19 8 769-1024 27 12 12289-16384 4 1 5,6 12 5 65-96 20 9 1025-1536 28 13 16385-24576 5 1 7,8 13 5 97-128 21 9 1537-2048 29 13 24577-32768 6 2 9-12 14 6 129-192 22 10 2049-3072 7 2 13-16 15 6 193-256 23 10 3073-4096 The compressed data stream begins immediately after the compressed header data. The compressed data stream can be interpreted as follows: do read header from input stream. if stored block skip bits until byte aligned read count and 1's compliment of count copy count bytes data block otherwise loop until end of block code sent decode literal character from input stream if literal < 256 copy character to the output stream otherwise if literal = end of block break from loop otherwise decode distance from input stream move backwards distance bytes in the output stream, and copy length characters from this position to the output stream. end loop while not last block if data descriptor exists skip bits until byte aligned read crc and sizes endif XI. Enhanced Deflating - Method 9 --------------------------------- The Enhanced Deflating algorithm is similar to Deflate but uses a sliding dictionary of up to 64K. Deflate64(tm) is supported by the Deflate extractor. XII. BZIP2 - Method 12 ---------------------- BZIP2 is an open-source data compression algorithm developed by Julian Seward. Information and source code for this algorithm can be found on the internet. XIII. LZMA - Method 14 (EFS) ---------------------------- LZMA is a block-oriented, general purpose data compression algorithm developed and maintained by Igor Pavlov. It is a derivative of LZ77 that utilizes Markov chains and a range coder. Information and source code for this algorithm can be found on the internet. Consult with the author of this algorithm for information on terms or restrictions on use. Support for LZMA within the ZIP format is defined as follows: The Compression method field within the ZIP Local and Central Header records will be set to the value 14 to indicate data was compressed using LZMA. The Version needed to extract field within the ZIP Local and Central Header records will be set to 6.3 to indicate the minimum ZIP format version supporting this feature. File data compressed using the LZMA algorithm must be placed immediately following the Local Header for the file. If a standard ZIP encryption header is required, it will follow the Local Header and will precede the LZMA compressed file data segment. The location of LZMA compressed data segment within the ZIP format will be as shown: [local header file 1] [encryption header file 1] [LZMA compressed data segment for file 1] [data descriptor 1] [local header file 2] The encryption header and data descriptor records may be conditionally present. The LZMA Compressed Data Segment will consist of an LZMA Properties Header followed by the LZMA Compressed Data as shown: [LZMA properties header for file 1] [LZMA compressed data for file 1] The LZMA Compressed Data will be stored as provided by the LZMA compression library. Compressed size, uncompressed size and other file characteristics about the file being compressed must be stored in standard ZIP storage format. The LZMA Properties Header will store specific data required to decompress the LZMA compressed Data. This data is set by the LZMA compression engine using the function WriteCoderProperties() as documented within the LZMA SDK. Storage fields for the property information within the LZMA Properties Header are as follows: LZMA Version Information 2 bytes LZMA Properties Size 2 bytes LZMA Properties Data variable, defined by "LZMA Properties Size" LZMA Version Information - this field identifies which version of the LZMA SDK was used to compress a file. The first byte will store the major version number of the LZMA SDK and the second byte will store the minor number. LZMA Properties Size - this field defines the size of the remaining property data. Typically this size should be determined by the version of the SDK. This size field is included as a convenience and to help avoid any ambiguity should it arise in the future due to changes in this compression algorithm. LZMA Property Data - this variable sized field records the required values for the decompressor as defined by the LZMA SDK. The data stored in this field should be obtained using the WriteCoderProperties() in the version of the SDK defined by the "LZMA Version Information" field. The layout of the "LZMA Properties Data" field is a function of the LZMA compression algorithm. It is possible that this layout may be changed by the author over time. The data layout in version 4.32 of the LZMA SDK defines a 5 byte array that uses 4 bytes to store the dictionary size in little-endian order. This is preceded by a single packed byte as the first element of the array that contains the following fields: PosStateBits LiteralPosStateBits LiteralContextBits Refer to the LZMA documentation for a more detailed explanation of these fields. Data compressed with method 14, LZMA, may include an end-of-stream (EOS) marker ending the compressed data stream. This marker is not required, but its use is highly recommended to facilitate processing and implementers should include the EOS marker whenever possible. When the EOS marker is used, general purpose bit 1 must be set. If general purpose bit 1 is not set, the EOS marker is not present. XIV. PPMd - Method 98 --------------------- PPMd is a data compression algorithm developed by Dmitry Shkarin which includes a carryless rangecoder developed by Dmitry Subbotin. This algorithm is based on predictive phrase matching on multiple order contexts. Information and source code for this algorithm can be found on the internet. Consult with the author of this algorithm for information on terms or restrictions on use. Support for PPMd within the ZIP format currently is provided only for version I, revision 1 of the algorithm. Storage requirements for using this algorithm are as follows: Parameters needed to control the algorithm are stored in the two bytes immediately preceding the compressed data. These bytes are used to store the following fields: Model order - sets the maximum model order, default is 8, possible values are from 2 to 16 inclusive Sub-allocator size - sets the size of sub-allocator in MB, default is 50, possible values are from 1MB to 256MB inclusive Model restoration method - sets the method used to restart context model at memory insufficiency, values are: 0 - restarts model from scratch - default 1 - cut off model - decreases performance by as much as 2x 2 - freeze context tree - not recommended An example for packing these fields into the 2 byte storage field is illustrated below. These values are stored in Intel low-byte/high-byte order. wPPMd = (Model order - 1) + ((Sub-allocator size - 1) << 4) + (Model restoration method << 12) XV. Traditional PKWARE Encryption --------------------------------- The following information discusses the decryption steps required to support traditional PKWARE encryption. This form of encryption is considered weak by today's standards and its use is recommended only for situations with low security needs or for compatibility with older .ZIP applications. Decryption ---------- PKWARE is grateful to Mr. Roger Schlafly for his expert contribution towards the development of PKWARE's traditional encryption. PKZIP encrypts the compressed data stream. Encrypted files must be decrypted before they can be extracted. Each encrypted file has an extra 12 bytes stored at the start of the data area defining the encryption header for that file. The encryption header is originally set to random values, and then itself encrypted, using three, 32-bit keys. The key values are initialized using the supplied encryption password. After each byte is encrypted, the keys are then updated using pseudo-random number generation techniques in combination with the same CRC-32 algorithm used in PKZIP and described elsewhere in this document. The following is the basic steps required to decrypt a file: 1) Initialize the three 32-bit keys with the password. 2) Read and decrypt the 12-byte encryption header, further initializing the encryption keys. 3) Read and decrypt the compressed data stream using the encryption keys. Step 1 - Initializing the encryption keys ----------------------------------------- Key(0) <- 305419896 Key(1) <- 591751049 Key(2) <- 878082192 loop for i <- 0 to length(password)-1 update_keys(password(i)) end loop Where update_keys() is defined as: update_keys(char): Key(0) <- crc32(key(0),char) Key(1) <- Key(1) + (Key(0) & 000000ffH) Key(1) <- Key(1) * 134775813 + 1 Key(2) <- crc32(key(2),key(1) >> 24) end update_keys Where crc32(old_crc,char) is a routine that given a CRC value and a character, returns an updated CRC value after applying the CRC-32 algorithm described elsewhere in this document. Step 2 - Decrypting the encryption header ----------------------------------------- The purpose of this step is to further initialize the encryption keys, based on random data, to render a plaintext attack on the data ineffective. Read the 12-byte encryption header into Buffer, in locations Buffer(0) thru Buffer(11). loop for i <- 0 to 11 C <- buffer(i) ^ decrypt_byte() update_keys(C) buffer(i) <- C end loop Where decrypt_byte() is defined as: unsigned char decrypt_byte() local unsigned short temp temp <- Key(2) | 2 decrypt_byte <- (temp * (temp ^ 1)) >> 8 end decrypt_byte After the header is decrypted, the last 1 or 2 bytes in Buffer should be the high-order word/byte of the CRC for the file being decrypted, stored in Intel low-byte/high-byte order. Versions of PKZIP prior to 2.0 used a 2 byte CRC check; a 1 byte CRC check is used on versions after 2.0. This can be used to test if the password supplied is correct or not. Step 3 - Decrypting the compressed data stream ---------------------------------------------- The compressed data stream can be decrypted as follows: loop until done read a character into C Temp <- C ^ decrypt_byte() update_keys(temp) output Temp end loop XVI. Strong Encryption Specification ------------------------------------ The Strong Encryption technology defined in this specification is covered under a pending patent application. The use or implementation in a product of certain technological aspects set forth in the current APPNOTE, including those with regard to strong encryption, patching, or extended tape operations requires a license from PKWARE. Portions of this Strong Encryption technology are available for use at no charge. Contact PKWARE for licensing terms and conditions. Refer to section II of this APPNOTE (Contacting PKWARE) for information on how to contact PKWARE. Version 5.x of this specification introduced support for strong encryption algorithms. These algorithms can be used with either a password or an X.509v3 digital certificate to encrypt each file. This format specification supports either password or certificate based encryption to meet the security needs of today, to enable interoperability between users within both PKI and non-PKI environments, and to ensure interoperability between different computing platforms that are running a ZIP program. Password based encryption is the most common form of encryption people are familiar with. However, inherent weaknesses with passwords (e.g. susceptibility to dictionary/brute force attack) as well as password management and support issues make certificate based encryption a more secure and scalable option. Industry efforts and support are defining and moving towards more advanced security solutions built around X.509v3 digital certificates and Public Key Infrastructures(PKI) because of the greater scalability, administrative options, and more robust security over traditional password based encryption. Most standard encryption algorithms are supported with this specification. Reference implementations for many of these algorithms are available from either commercial or open source distributors. Readily available cryptographic toolkits make implementation of the encryption features straight-forward. This document is not intended to provide a treatise on data encryption principles or theory. Its purpose is to document the data structures required for implementing interoperable data encryption within the .ZIP format. It is strongly recommended that you have a good understanding of data encryption before reading further. The algorithms introduced in Version 5.0 of this specification include: RC2 40 bit, 64 bit, and 128 bit RC4 40 bit, 64 bit, and 128 bit DES 3DES 112 bit and 168 bit Version 5.1 adds support for the following: AES 128 bit, 192 bit, and 256 bit Version 6.1 introduces encryption data changes to support interoperability with Smartcard and USB Token certificate storage methods which do not support the OAEP strengthening standard. Version 6.2 introduces support for encrypting metadata by compressing and encrypting the central directory data structure to reduce information leakage. Information leakage can occur in legacy ZIP applications through exposure of information about a file even though that file is stored encrypted. The information exposed consists of file characteristics stored within the records and fields defined by this specification. This includes data such as a files name, its original size, timestamp and CRC32 value. Version 6.3 introduces support for encrypting data using the Blowfish and Twofish algorithms. These are symmetric block ciphers developed by Bruce Schneier. Blowfish supports using a variable length key from 32 to 448 bits. Block size is 64 bits. Implementations should use 16 rounds and the only mode supported within ZIP files is CBC. Twofish supports key sizes 128, 192 and 256 bits. Block size is 128 bits. Implementations should use 16 rounds and the only mode supported within ZIP files is CBC. Information and source code for both Blowfish and Twofish algorithms can be found on the internet. Consult with the author of these algorithms for information on terms or restrictions on use. Central Directory Encryption provides greater protection against information leakage by encrypting the Central Directory structure and by masking key values that are replicated in the unencrypted Local Header. ZIP compatible programs that cannot interpret an encrypted Central Directory structure cannot rely on the data in the corresponding Local Header for decompression information. Extra Field records that may contain information about a file that should not be exposed should not be stored in the Local Header and should only be written to the Central Directory where they can be encrypted. This design currently does not support streaming. Information in the End of Central Directory record, the Zip64 End of Central Directory Locator, and the Zip64 End of Central Directory records are not encrypted. Access to view data on files within a ZIP file with an encrypted Central Directory requires the appropriate password or private key for decryption prior to viewing any files, or any information about the files, in the archive. Older ZIP compatible programs not familiar with the Central Directory Encryption feature will no longer be able to recognize the Central Directory and may assume the ZIP file is corrupt. Programs that attempt streaming access using Local Headers will see invalid information for each file. Central Directory Encryption need not be used for every ZIP file. Its use is recommended for greater security. ZIP files not using Central Directory Encryption should operate as in the past. This strong encryption feature specification is intended to provide for scalable, cross-platform encryption needs ranging from simple password encryption to authenticated public/private key encryption. Encryption provides data confidentiality and privacy. It is recommended that you combine X.509 digital signing with encryption to add authentication and non-repudiation. Single Password Symmetric Encryption Method: ------------------------------------------- The Single Password Symmetric Encryption Method using strong encryption algorithms operates similarly to the traditional PKWARE encryption defined in this format. Additional data structures are added to support the processing needs of the strong algorithms. The Strong Encryption data structures are: 1. General Purpose Bits - Bits 0 and 6 of the General Purpose bit flag in both local and central header records. Both bits set indicates strong encryption. Bit 13, when set indicates the Central Directory is encrypted and that selected fields in the Local Header are masked to hide their actual value. 2. Extra Field 0x0017 in central header only. Fields to consider in this record are: Format - the data format identifier for this record. The only value allowed at this time is the integer value 2. AlgId - integer identifier of the encryption algorithm from the following range 0x6601 - DES 0x6602 - RC2 (version needed to extract < 5.2) 0x6603 - 3DES 168 0x6609 - 3DES 112 0x660E - AES 128 0x660F - AES 192 0x6610 - AES 256 0x6702 - RC2 (version needed to extract >= 5.2) 0x6720 - Blowfish 0x6721 - Twofish 0x6801 - RC4 0xFFFF - Unknown algorithm Bitlen - Explicit bit length of key 32 - 448 bits Flags - Processing flags needed for decryption 0x0001 - Password is required to decrypt 0x0002 - Certificates only 0x0003 - Password or certificate required to decrypt Values > 0x0003 reserved for certificate processing 3. Decryption header record preceding compressed file data. -Decryption Header: Value Size Description ----- ---- ----------- IVSize 2 bytes Size of initialization vector (IV) IVData IVSize Initialization vector for this file Size 4 bytes Size of remaining decryption header data Format 2 bytes Format definition for this record AlgID 2 bytes Encryption algorithm identifier Bitlen 2 bytes Bit length of encryption key Flags 2 bytes Processing flags ErdSize 2 bytes Size of Encrypted Random Data ErdData ErdSize Encrypted Random Data Reserved1 4 bytes Reserved certificate processing data Reserved2 (var) Reserved for certificate processing data VSize 2 bytes Size of password validation data VData VSize-4 Password validation data VCRC32 4 bytes Standard ZIP CRC32 of password validation data IVData - The size of the IV should match the algorithm block size. The IVData can be completely random data. If the size of the randomly generated data does not match the block size it should be complemented with zero's or truncated as necessary. If IVSize is 0,then IV = CRC32 + Uncompressed File Size (as a 64 bit little-endian, unsigned integer value). Format - the data format identifier for this record. The only value allowed at this time is the integer value 3. AlgId - integer identifier of the encryption algorithm from the following range 0x6601 - DES 0x6602 - RC2 (version needed to extract < 5.2) 0x6603 - 3DES 168 0x6609 - 3DES 112 0x660E - AES 128 0x660F - AES 192 0x6610 - AES 256 0x6702 - RC2 (version needed to extract >= 5.2) 0x6720 - Blowfish 0x6721 - Twofish 0x6801 - RC4 0xFFFF - Unknown algorithm Bitlen - Explicit bit length of key 32 - 448 bits Flags - Processing flags needed for decryption 0x0001 - Password is required to decrypt 0x0002 - Certificates only 0x0003 - Password or certificate required to decrypt Values > 0x0003 reserved for certificate processing ErdData - Encrypted random data is used to store random data that is used to generate a file session key for encrypting each file. SHA1 is used to calculate hash data used to derive keys. File session keys are derived from a master session key generated from the user-supplied password. If the Flags field in the decryption header contains the value 0x4000, then the ErdData field must be decrypted using 3DES. If the value 0x4000 is not set, then the ErdData field must be decrypted using AlgId. Reserved1 - Reserved for certificate processing, if value is zero, then Reserved2 data is absent. See the explanation under the Certificate Processing Method for details on this data structure. Reserved2 - If present, the size of the Reserved2 data structure is located by skipping the first 4 bytes of this field and using the next 2 bytes as the remaining size. See the explanation under the Certificate Processing Method for details on this data structure. VSize - This size value will always include the 4 bytes of the VCRC32 data and will be greater than 4 bytes. VData - Random data for password validation. This data is VSize in length and VSize must be a multiple of the encryption block size. VCRC32 is a checksum value of VData. VData and VCRC32 are stored encrypted and start the stream of encrypted data for a file. 4. Useful Tips Strong Encryption is always applied to a file after compression. The block oriented algorithms all operate in Cypher Block Chaining (CBC) mode. The block size used for AES encryption is 16. All other block algorithms use a block size of 8. Two ID's are defined for RC2 to account for a discrepancy found in the implementation of the RC2 algorithm in the cryptographic library on Windows XP SP1 and all earlier versions of Windows. It is recommended that zero length files not be encrypted, however programs should be prepared to extract them if they are found within a ZIP file. A pseudo-code representation of the encryption process is as follows: Password = GetUserPassword() MasterSessionKey = DeriveKey(SHA1(Password)) RD = CryptographicStrengthRandomData() For Each File IV = CryptographicStrengthRandomData() VData = CryptographicStrengthRandomData() VCRC32 = CRC32(VData) FileSessionKey = DeriveKey(SHA1(IV + RD) ErdData = Encrypt(RD,MasterSessionKey,IV) Encrypt(VData + VCRC32 + FileData, FileSessionKey,IV) Done The function names and parameter requirements will depend on the choice of the cryptographic toolkit selected. Almost any toolkit supporting the reference implementations for each algorithm can be used. The RSA BSAFE(r), OpenSSL, and Microsoft CryptoAPI libraries are all known to work well. Single Password - Central Directory Encryption: ----------------------------------------------- Central Directory Encryption is achieved within the .ZIP format by encrypting the Central Directory structure. This encapsulates the metadata most often used for processing .ZIP files. Additional metadata is stored for redundancy in the Local Header for each file. The process of concealing metadata by encrypting the Central Directory does not protect the data within the Local Header. To avoid information leakage from the exposed metadata in the Local Header, the fields containing information about a file are masked. Local Header: Masking replaces the true content of the fields for a file in the Local Header with false information. When masked, the Local Header is not suitable for streaming access and the options for data recovery of damaged archives is reduced. Extra Data fields that may contain confidential data should not be stored within the Local Header. The value set into the Version needed to extract field should be the correct value needed to extract the file without regard to Central Directory Encryption. The fields within the Local Header targeted for masking when the Central Directory is encrypted are: Field Name Mask Value ------------------ --------------------------- compression method 0 last mod file time 0 last mod file date 0 crc-32 0 compressed size 0 uncompressed size 0 file name (variable size) Base 16 value from the range 1 - 0xFFFFFFFFFFFFFFFF represented as a string whose size will be set into the file name length field The Base 16 value assigned as a masked file name is simply a sequentially incremented value for each file starting with 1 for the first file. Modifications to a ZIP file may cause different values to be stored for each file. For compatibility, the file name field in the Local Header should never be left blank. As of Version 6.2 of this specification, the Compression Method and Compressed Size fields are not yet masked. Fields having a value of 0xFFFF or 0xFFFFFFFF for the ZIP64 format should not be masked. Encrypting the Central Directory: Encryption of the Central Directory does not include encryption of the Central Directory Signature data, the Zip64 End of Central Directory record, the Zip64 End of Central Directory Locator, or the End of Central Directory record. The ZIP file comment data is never encrypted. Before encrypting the Central Directory, it may optionally be compressed. Compression is not required, but for storage efficiency it is assumed this structure will be compressed before encrypting. Similarly, this specification supports compressing the Central Directory without requiring that it also be encrypted. Early implementations of this feature will assume the encryption method applied to files matches the encryption applied to the Central Directory. Encryption of the Central Directory is done in a manner similar to that of file encryption. The encrypted data is preceded by a decryption header. The decryption header is known as the Archive Decryption Header. The fields of this record are identical to the decryption header preceding each encrypted file. The location of the Archive Decryption Header is determined by the value in the Start of the Central Directory field in the Zip64 End of Central Directory record. When the Central Directory is encrypted, the Zip64 End of Central Directory record will always be present. The layout of the Zip64 End of Central Directory record for all versions starting with 6.2 of this specification will follow the Version 2 format. The Version 2 format is as follows: The leading fixed size fields within the Version 1 format for this record remain unchanged. The record signature for both Version 1 and Version 2 will be 0x06064b50. Immediately following the last byte of the field known as the Offset of Start of Central Directory With Respect to the Starting Disk Number will begin the new fields defining Version 2 of this record. New fields for Version 2: Note: all fields stored in Intel low-byte/high-byte order. Value Size Description ----- ---- ----------- Compression Method 2 bytes Method used to compress the Central Directory Compressed Size 8 bytes Size of the compressed data Original Size 8 bytes Original uncompressed size AlgId 2 bytes Encryption algorithm ID BitLen 2 bytes Encryption key length Flags 2 bytes Encryption flags HashID 2 bytes Hash algorithm identifier Hash Length 2 bytes Length of hash data Hash Data (variable) Hash data The Compression Method accepts the same range of values as the corresponding field in the Central Header. The Compressed Size and Original Size values will not include the data of the Central Directory Signature which is compressed or encrypted. The AlgId, BitLen, and Flags fields accept the same range of values the corresponding fields within the 0x0017 record. Hash ID identifies the algorithm used to hash the Central Directory data. This data does not have to be hashed, in which case the values for both the HashID and Hash Length will be 0. Possible values for HashID are: Value Algorithm ------ --------- 0x0000 none 0x0001 CRC32 0x8003 MD5 0x8004 SHA1 0x8007 RIPEMD160 0x800C SHA256 0x800D SHA384 0x800E SHA512 When the Central Directory data is signed, the same hash algorithm used to hash the Central Directory for signing should be used. This is recommended for processing efficiency, however, it is permissible for any of the above algorithms to be used independent of the signing process. The Hash Data will contain the hash data for the Central Directory. The length of this data will vary depending on the algorithm used. The Version Needed to Extract should be set to 62. The value for the Total Number of Entries on the Current Disk will be 0. These records will no longer support random access when encrypting the Central Directory. When the Central Directory is compressed and/or encrypted, the End of Central Directory record will store the value 0xFFFFFFFF as the value for the Total Number of Entries in the Central Directory. The value stored in the Total Number of Entries in the Central Directory on this Disk field will be 0. The actual values will be stored in the equivalent fields of the Zip64 End of Central Directory record. Decrypting and decompressing the Central Directory is accomplished in the same manner as decrypting and decompressing a file. Certificate Processing Method: ----------------------------- The Certificate Processing Method of for ZIP file encryption defines the following additional data fields: 1. Certificate Flag Values Additional processing flags that can be present in the Flags field of both the 0x0017 field of the central directory Extra Field and the Decryption header record preceding compressed file data are: 0x0007 - reserved for future use 0x000F - reserved for future use 0x0100 - Indicates non-OAEP key wrapping was used. If this this field is set, the version needed to extract must be at least 61. This means OAEP key wrapping is not used when generating a Master Session Key using ErdData. 0x4000 - ErdData must be decrypted using 3DES-168, otherwise use the same algorithm used for encrypting the file contents. 0x8000 - reserved for future use 2. CertData - Extra Field 0x0017 record certificate data structure The data structure used to store certificate data within the section of the Extra Field defined by the CertData field of the 0x0017 record are as shown: Value Size Description ----- ---- ----------- RCount 4 bytes Number of recipients. HashAlg 2 bytes Hash algorithm identifier HSize 2 bytes Hash size SRList (var) Simple list of recipients hashed public keys RCount This defines the number intended recipients whose public keys were used for encryption. This identifies the number of elements in the SRList. HashAlg This defines the hash algorithm used to calculate the public key hash of each public key used for encryption. This field currently supports only the following value for SHA-1 0x8004 - SHA1 HSize This defines the size of a hashed public key. SRList This is a variable length list of the hashed public keys for each intended recipient. Each element in this list is HSize. The total size of SRList is determined using RCount * HSize. 3. Reserved1 - Certificate Decryption Header Reserved1 Data: Value Size Description ----- ---- ----------- RCount 4 bytes Number of recipients. RCount This defines the number intended recipients whose public keys were used for encryption. This defines the number of elements in the REList field defined below. 4. Reserved2 - Certificate Decryption Header Reserved2 Data Structures: Value Size Description ----- ---- ----------- HashAlg 2 bytes Hash algorithm identifier HSize 2 bytes Hash size REList (var) List of recipient data elements HashAlg This defines the hash algorithm used to calculate the public key hash of each public key used for encryption. This field currently supports only the following value for SHA-1 0x8004 - SHA1 HSize This defines the size of a hashed public key defined in REHData. REList This is a variable length of list of recipient data. Each element in this list consists of a Recipient Element data structure as follows: Recipient Element (REList) Data Structure: Value Size Description ----- ---- ----------- RESize 2 bytes Size of REHData + REKData REHData HSize Hash of recipients public key REKData (var) Simple key blob RESize This defines the size of an individual REList element. This value is the combined size of the REHData field + REKData field. REHData is defined by HSize. REKData is variable and can be calculated for each REList element using RESize and HSize. REHData Hashed public key for this recipient. REKData Simple Key Blob. The format of this data structure is identical to that defined in the Microsoft CryptoAPI and generated using the CryptExportKey() function. The version of the Simple Key Blob supported at this time is 0x02 as defined by Microsoft. Certificate Processing - Central Directory Encryption: ------------------------------------------------------ Central Directory Encryption using Digital Certificates will operate in a manner similar to that of Single Password Central Directory Encryption. This record will only be present when there is data to place into it. Currently, data is placed into this record when digital certificates are used for either encrypting or signing the files within a ZIP file. When only password encryption is used with no certificate encryption or digital signing, this record is not currently needed. When present, this record will appear before the start of the actual Central Directory data structure and will be located immediately after the Archive Decryption Header if the Central Directory is encrypted. The Archive Extra Data record will be used to store the following information. Additional data may be added in future versions. Extra Data Fields: 0x0014 - PKCS#7 Store for X.509 Certificates 0x0016 - X.509 Certificate ID and Signature for central directory 0x0019 - PKCS#7 Encryption Recipient Certificate List The 0x0014 and 0x0016 Extra Data records that otherwise would be located in the first record of the Central Directory for digital certificate processing. When encrypting or compressing the Central Directory, the 0x0014 and 0x0016 records must be located in the Archive Extra Data record and they should not remain in the first Central Directory record. The Archive Extra Data record will also be used to store the 0x0019 data. When present, the size of the Archive Extra Data record will be included in the size of the Central Directory. The data of the Archive Extra Data record will also be compressed and encrypted along with the Central Directory data structure. Certificate Processing Differences: The Certificate Processing Method of encryption differs from the Single Password Symmetric Encryption Method as follows. Instead of using a user-defined password to generate a master session key, cryptographically random data is used. The key material is then wrapped using standard key-wrapping techniques. This key material is wrapped using the public key of each recipient that will need to decrypt the file using their corresponding private key. This specification currently assumes digital certificates will follow the X.509 V3 format for 1024 bit and higher RSA format digital certificates. Implementation of this Certificate Processing Method requires supporting logic for key access and management. This logic is outside the scope of this specification. OAEP Processing with Certificate-based Encryption: OAEP stands for Optimal Asymmetric Encryption Padding. It is a strengthening technique used for small encoded items such as decryption keys. This is commonly applied in cryptographic key-wrapping techniques and is supported by PKCS #1. Versions 5.0 and 6.0 of this specification were designed to support OAEP key-wrapping for certificate-based decryption keys for additional security. Support for private keys stored on Smartcards or Tokens introduced a conflict with this OAEP logic. Most card and token products do not support the additional strengthening applied to OAEP key-wrapped data. In order to resolve this conflict, versions 6.1 and above of this specification will no longer support OAEP when encrypting using digital certificates. Versions of PKZIP available during initial development of the certificate processing method set a value of 61 into the version needed to extract field for a file. This indicates that non-OAEP key wrapping is used. This affects certificate encryption only, and password encryption functions should not be affected by this value. This means values of 61 may be found on files encrypted with certificates only, or on files encrypted with both password encryption and certificate encryption. Files encrypted with both methods can safely be decrypted using the password methods documented. XVII. Change Process -------------------- In order for the .ZIP file format to remain a viable definition, this specification should be considered as open for periodic review and revision. Although this format was originally designed with a certain level of extensibility, not all changes in technology (present or future) were or will be necessarily considered in its design. If your application requires new definitions to the extensible sections in this format, or if you would like to submit new data structures, please forward your request to zipformat@pkware.com. All submissions will be reviewed by the ZIP File Specification Committee for possible inclusion into future versions of this specification. Periodic revisions to this specification will be published to ensure interoperability. We encourage comments and feedback that may help improve clarity or content. XVIII. Incorporating PKWARE Proprietary Technology into Your Product -------------------------------------------------------------------- PKWARE is committed to the interoperability and advancement of the .ZIP format. PKWARE offers a free license for certain technological aspects described above under certain restrictions and conditions. However, the use or implementation in a product of certain technological aspects set forth in the current APPNOTE, including those with regard to strong encryption, patching, or extended tape operations requires a license from PKWARE. Please contact PKWARE with regard to acquiring a license. XIX. Acknowledgements ---------------------- In addition to the above mentioned contributors to PKZIP and PKUNZIP, I would like to extend special thanks to Robert Mahoney for suggesting the extension .ZIP for this software. XX. References -------------- Fiala, Edward R., and Greene, Daniel H., "Data compression with finite windows", Communications of the ACM, Volume 32, Number 4, April 1989, pages 490-505. Held, Gilbert, "Data Compression, Techniques and Applications, Hardware and Software Considerations", John Wiley & Sons, 1987. Huffman, D.A., "A method for the construction of minimum-redundancy codes", Proceedings of the IRE, Volume 40, Number 9, September 1952, pages 1098-1101. Nelson, Mark, "LZW Data Compression", Dr. Dobbs Journal, Volume 14, Number 10, October 1989, pages 29-37. Nelson, Mark, "The Data Compression Book", M&T Books, 1991. Storer, James A., "Data Compression, Methods and Theory", Computer Science Press, 1988 Welch, Terry, "A Technique for High-Performance Data Compression", IEEE Computer, Volume 17, Number 6, June 1984, pages 8-19. Ziv, J. and Lempel, A., "A universal algorithm for sequential data compression", Communications of the ACM, Volume 30, Number 6, June 1987, pages 520-540. Ziv, J. and Lempel, A., "Compression of individual sequences via variable-rate coding", IEEE Transactions on Information Theory, Volume 24, Number 5, September 1978, pages 530-536. APPENDIX A - AS/400 Extra Field (0x0065) Attribute Definitions -------------------------------------------------------------- Field Definition Structure: a. field length including length 2 bytes b. field code 2 bytes c. data x bytes Field Code Description 4001 Source type i.e. CLP etc 4002 The text description of the library 4003 The text description of the file 4004 The text description of the member 4005 x'F0' or 0 is PF-DTA, x'F1' or 1 is PF_SRC 4007 Database Type Code 1 byte 4008 Database file and fields definition 4009 GZIP file type 2 bytes 400B IFS code page 2 bytes 400C IFS Creation Time 4 bytes 400D IFS Access Time 4 bytes 400E IFS Modification time 4 bytes 005C Length of the records in the file 2 bytes 0068 GZIP two words 8 bytes APPENDIX B - z/OS Extra Field (0x0065) Attribute Definitions ------------------------------------------------------------ Field Definition Structure: a. field length including length 2 bytes b. field code 2 bytes c. data x bytes Field Code Description 0001 File Type 2 bytes 0002 NonVSAM Record Format 1 byte 0003 Reserved 0004 NonVSAM Block Size 2 bytes Big Endian 0005 Primary Space Allocation 3 bytes Big Endian 0006 Secondary Space Allocation 3 bytes Big Endian 0007 Space Allocation Type1 byte flag 0008 Modification Date Retired with PKZIP 5.0 + 0009 Expiration Date Retired with PKZIP 5.0 + 000A PDS Directory Block Allocation 3 bytes Big Endian binary value 000B NonVSAM Volume List variable 000C UNIT Reference Retired with PKZIP 5.0 + 000D DF/SMS Management Class 8 bytes EBCDIC Text Value 000E DF/SMS Storage Class 8 bytes EBCDIC Text Value 000F DF/SMS Data Class 8 bytes EBCDIC Text Value 0010 PDS/PDSE Member Info. 30 bytes 0011 VSAM sub-filetype 2 bytes 0012 VSAM LRECL 13 bytes EBCDIC "(num_avg num_max)" 0013 VSAM Cluster Name Retired with PKZIP 5.0 + 0014 VSAM KSDS Key Information 13 bytes EBCDIC "(num_length num_position)" 0015 VSAM Average LRECL 5 bytes EBCDIC num_value padded with blanks 0016 VSAM Maximum LRECL 5 bytes EBCDIC num_value padded with blanks 0017 VSAM KSDS Key Length 5 bytes EBCDIC num_value padded with blanks 0018 VSAM KSDS Key Position 5 bytes EBCDIC num_value padded with blanks 0019 VSAM Data Name 1-44 bytes EBCDIC text string 001A VSAM KSDS Index Name 1-44 bytes EBCDIC text string 001B VSAM Catalog Name 1-44 bytes EBCDIC text string 001C VSAM Data Space Type 9 bytes EBCDIC text string 001D VSAM Data Space Primary 9 bytes EBCDIC num_value left-justified 001E VSAM Data Space Secondary 9 bytes EBCDIC num_value left-justified 001F VSAM Data Volume List variable EBCDIC text list of 6-character Volume IDs 0020 VSAM Data Buffer Space 8 bytes EBCDIC num_value left-justified 0021 VSAM Data CISIZE 5 bytes EBCDIC num_value left-justified 0022 VSAM Erase Flag 1 byte flag 0023 VSAM Free CI % 3 bytes EBCDIC num_value left-justified 0024 VSAM Free CA % 3 bytes EBCDIC num_value left-justified 0025 VSAM Index Volume List variable EBCDIC text list of 6-character Volume IDs 0026 VSAM Ordered Flag 1 byte flag 0027 VSAM REUSE Flag 1 byte flag 0028 VSAM SPANNED Flag 1 byte flag 0029 VSAM Recovery Flag 1 byte flag 002A VSAM WRITECHK Flag 1 byte flag 002B VSAM Cluster/Data SHROPTS 3 bytes EBCDIC "n,y" 002C VSAM Index SHROPTS 3 bytes EBCDIC "n,y" 002D VSAM Index Space Type 9 bytes EBCDIC text string 002E VSAM Index Space Primary 9 bytes EBCDIC num_value left-justified 002F VSAM Index Space Secondary 9 bytes EBCDIC num_value left-justified 0030 VSAM Index CISIZE 5 bytes EBCDIC num_value left-justified 0031 VSAM Index IMBED 1 byte flag 0032 VSAM Index Ordered Flag 1 byte flag 0033 VSAM REPLICATE Flag 1 byte flag 0034 VSAM Index REUSE Flag 1 byte flag 0035 VSAM Index WRITECHK Flag 1 byte flag Retired with PKZIP 5.0 + 0036 VSAM Owner 8 bytes EBCDIC text string 0037 VSAM Index Owner 8 bytes EBCDIC text string 0038 Reserved 0039 Reserved 003A Reserved 003B Reserved 003C Reserved 003D Reserved 003E Reserved 003F Reserved 0040 Reserved 0041 Reserved 0042 Reserved 0043 Reserved 0044 Reserved 0045 Reserved 0046 Reserved 0047 Reserved 0048 Reserved 0049 Reserved 004A Reserved 004B Reserved 004C Reserved 004D Reserved 004E Reserved 004F Reserved 0050 Reserved 0051 Reserved 0052 Reserved 0053 Reserved 0054 Reserved 0055 Reserved 0056 Reserved 0057 Reserved 0058 PDS/PDSE Member TTR Info. 6 bytes Big Endian 0059 PDS 1st LMOD Text TTR 3 bytes Big Endian 005A PDS LMOD EP Rec # 4 bytes Big Endian 005B Reserved 005C Max Length of records 2 bytes Big Endian 005D PDSE Flag 1 byte flag 005E Reserved 005F Reserved 0060 Reserved 0061 Reserved 0062 Reserved 0063 Reserved 0064 Reserved 0065 Last Date Referenced 4 bytes Packed Hex "yyyymmdd" 0066 Date Created 4 bytes Packed Hex "yyyymmdd" 0068 GZIP two words 8 bytes 0071 Extended NOTE Location 12 bytes Big Endian 0072 Archive device UNIT 6 bytes EBCDIC 0073 Archive 1st Volume 6 bytes EBCDIC 0074 Archive 1st VOL File Seq# 2 bytes Binary APPENDIX C - Zip64 Extensible Data Sector Mappings (EFS) -------------------------------------------------------- -Z390 Extra Field: The following is the general layout of the attributes for the ZIP 64 "extra" block for extended tape operations. Portions of this extended tape processing technology is covered under a pending patent application. The use or implementation in a product of certain technological aspects set forth in the current APPNOTE, including those with regard to strong encryption, patching or extended tape operations, requires a license from PKWARE. Please contact PKWARE with regard to acquiring a license. Note: some fields stored in Big Endian format. All text is in EBCDIC format unless otherwise specified. Value Size Description ----- ---- ----------- (Z390) 0x0065 2 bytes Tag for this "extra" block type Size 4 bytes Size for the following data block Tag 4 bytes EBCDIC "Z390" Length71 2 bytes Big Endian Subcode71 2 bytes Enote type code FMEPos 1 byte Length72 2 bytes Big Endian Subcode72 2 bytes Unit type code Unit 1 byte Unit Length73 2 bytes Big Endian Subcode73 2 bytes Volume1 type code FirstVol 1 byte Volume Length74 2 bytes Big Endian Subcode74 2 bytes FirstVol file sequence FileSeq 2 bytes Sequence APPENDIX D - Language Encoding (EFS) ------------------------------------ The ZIP format has historically supported only the original IBM PC character encoding set, commonly referred to as IBM Code Page 437. This limits storing file name characters to only those within the original MS-DOS range of values and does not properly support file names in other character encodings, or languages. To address this limitation, this specification will support the following change. If general purpose bit 11 is unset, the file name and comment should conform to the original ZIP character encoding. If general purpose bit 11 is set, the filename and comment must support The Unicode Standard, Version 4.1.0 or greater using the character encoding form defined by the UTF-8 storage specification. The Unicode Standard is published by the The Unicode Consortium (www.unicode.org). UTF-8 encoded data stored within ZIP files is expected to not include a byte order mark (BOM). Applications may choose to supplement this file name storage through the use of the 0x0008 Extra Field. Storage for this optional field is currently undefined, however it will be used to allow storing extended information on source or target encoding that may further assist applications with file name, or file content encoding tasks. Please contact PKWARE with any requirements on how this field should be used. The 0x0008 Extra Field storage may be used with either setting for general purpose bit 11. Examples of the intended usage for this field is to store whether "modified-UTF-8" (JAVA) is used, or UTF-8-MAC. Similarly, other commonly used character encoding (code page) designations can be indicated through this field. Formalized values for use of the 0x0008 record remain undefined at this time. The definition for the layout of the 0x0008 field will be published when available. Use of the 0x0008 Extra Field provides for storing data within a ZIP file in an encoding other than IBM Code Page 437 or UTF-8. General purpose bit 11 will not imply any encoding of file content or password. Values defining character encoding for file content or password must be stored within the 0x0008 Extended Language Encoding Extra Field. tuxcmd-modules-0.6.70+ds/zip/ZipArchive/RandomPool.cpp0000644000175000017500000000131011300022650021602 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "_features.h" tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipPlatform.h0000644000175000017500000001647011300022650021461 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipPlatform.h * ZipPlatform namespace declaration. * */ #if !defined(ZIPARCHIVE_ZIPPLATFORM_DOT_H) #define ZIPARCHIVE_ZIPPLATFORM_DOT_H #if _MSC_VER > 1000 #pragma once #endif class CZipFileHeader; class CZipAutoBuffer; #include "ZipString.h" #include "ZipPathComponent.h" #include #include "ZipExport.h" /** Includes functions that require system-specific implementation. */ namespace ZipPlatform { /** Gets the default case-sensitivity for the current file system. \return \c true, if the system is case-sensitive; \c false otherwise. */ ZIP_API bool GetSystemCaseSensitivity(); /** Gets the current system identifier. \return One of the ZipCompatibility::ZipPlatforms values. \see CZipArchive::SetSystemCompatibility */ ZIP_API int GetSystemID(); /** Gets the default file attributes for the current system. \return The default file attributes. */ ZIP_API DWORD GetDefaultAttributes(); /** Gets the default directory attributes for the current system. \return The default directory attributes. */ ZIP_API DWORD GetDefaultDirAttributes(); /** Gets the free space on the given device. \param lpszPath Points to the device to test. \return The free space in bytes. */ ZIP_API ULONGLONG GetDeviceFreeSpace(LPCTSTR lpszPath); /** Gets the name of a temporary file ensuring there is enough free space in the destination directory. \param lpszPath The path to the directory to initially create the file in. \param uSizeNeeded The requested free space size in bytes. If set to ZIP_SIZE_TYPE(-1), the space availability is not checked. */ ZIP_API CZipString GetTmpFileName(LPCTSTR lpszPath = NULL, ZIP_SIZE_TYPE uSizeNeeded = ZIP_SIZE_TYPE(-1)); /** \name Various operations on files and directories. If the functions returns a \c bool value, then \c true indicates that the operation was successful. */ //@{ ZIP_API bool GetCurrentDirectory(CZipString& sz); ///< Gets the current directory and stores it in \a sz. ZIP_API bool ChangeDirectory(LPCTSTR lpDirectory); ///< Changes the current directory. ZIP_API bool SetFileAttr(LPCTSTR lpFileName, DWORD uAttr); ///< Sets the file attributes. ZIP_API bool GetFileAttr(LPCTSTR lpFileName, DWORD& uAttr); ///< Gets the file attributes. ZIP_API bool GetFileModTime(LPCTSTR lpFileName, time_t & ttime); ///< Gets the file modification time. ZIP_API bool SetFileModTime(LPCTSTR lpFileName, time_t ttime); ///< Set the file modification time. ZIP_API bool GetFileSize(LPCTSTR lpszFileName, ZIP_SIZE_TYPE& dSize); ///< Gets the file size. ZIP_API bool CreateDirectory(LPCTSTR lpDirectory); ///< Creates a new directory. ZIP_API bool SetVolLabel(LPCTSTR lpszPath, LPCTSTR lpszLabel); ///< Sets a label on a removable device. \c lpszPath may point to a file on the device. ZIP_API bool ForceDirectory(LPCTSTR lpDirectory); ///< Creates nested directories at once. ZIP_API bool RemoveFile(LPCTSTR lpszFileName, bool bThrow = true); ///< Removes a file. ZIP_API bool RenameFile( LPCTSTR lpszOldName, LPCTSTR lpszNewName, bool bThrow = true); ///< Renames a file. #ifdef ZIP_ARCHIVE_LNX ZIP_API bool SetExeAttr( LPCTSTR lpFileName ); ///< Sets executable permissions for a file. #endif #if defined ZIP_ARCHIVE_STL || defined ZIP_FILE_USES_STL /** Truncates the file. \note Defined only in the STL version. */ ZIP_API bool TruncateFile(int iDes, ULONGLONG uSize); /** Opens the file. \note Defined only in the STL version. */ ZIP_API int OpenFile(LPCTSTR lpszFileName, UINT iMode, int iShareMode); /** Flushes the file to the disk. \note Defined only in the STL version. */ ZIP_API bool FlushFile(int iDes); /** Gets the underlying system handle. \note Defined only in the STL version. */ ZIP_API intptr_t GetFileSystemHandle(int iDes); #endif //@} /** Checks if the given directory exists. \param lpszDir The directory to test. \return \c true, if \a lpszDir exists; \c false otherwise. */ ZIP_API bool DirectoryExists(LPCTSTR lpszDir); /** Checks if the given drive is removable. \param lpszFilePath The path to the drive. May point to a file path or a directory on the drive. \return \c true. if the drive is removable; \c false otherwise. \note Implemented only on Windows system, on all others always returns \c true. */ ZIP_API bool IsDriveRemovable(LPCTSTR lpszFilePath); /** Checks if the given attributes represent a directory. \param uAttr The attributes to test. \return \c true if the attributes represent a directory; \c false otherwise. */ ZIP_API bool IsDirectory(DWORD uAttr); /** Performs the translation between ANSI and OEM character sets. \param buffer The buffer containing characters to be translated. \param bAnsiToOem If \c true, convert ANSI to OEM; if \c false, OEM to ANSI. */ ZIP_API void AnsiOem(CZipAutoBuffer& buffer, bool bAnsiToOem); /** Checks if the given file or directory exists. \param lpszName The path to the file or directory to test. \return One of the following values: - \c -1 : the given file exists and is a directory - \c 1 : the given file exists and is a regular file - \c 0 : there is no such a file */ ZIP_API int FileExists(LPCTSTR lpszName); #ifdef _UNICODE /** Converts a wide character string to a multi-byte character string. \param lpszIn The wide character string to convert. \param szOut The buffer to receive the converted string. Does not contain the terminating \c NULL character. \param uCodePage The code page used in conversion. \return The \a szOut buffer length, or \c -1 when not succeeded. \note Defined only in the UNICODE version. */ ZIP_API int WideToMultiByte(LPCWSTR lpszIn, CZipAutoBuffer &szOut, UINT uCodePage); /** Converts a multi-byte character string to a wide character string. \param szIn The multi-byte character string to convert. Should not contain the terminating \c NULL character. \param szOut Receives the converted string. \param uCodePage The code page used in conversion. \return The length of the string after the conversion (without the terminating \c NULL character) or \c -1 when the function did not succeed. \note Defined only in the UNICODE version. */ ZIP_API int MultiByteToWide(const CZipAutoBuffer &szIn, CZipString& szOut, UINT uCodePage); #endif }; #endif // !defined(ZIPARCHIVE_ZIPPLATFORM_DOT_H) tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCompressor.h0000644000175000017500000002610011300022650022020 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipCompressor.h * Includes the CZipCompressor class. * */ #if !defined(ZIPARCHIVE_ZIPCOMPRESSOR_DOT_H) #define ZIPARCHIVE_ZIPCOMPRESSOR_DOT_H #if _MSC_VER > 1000 #pragma once #pragma warning( push ) #pragma warning (disable : 4100) // unreferenced formal parameter #endif #include "ZipExport.h" #include "ZipAutoBuffer.h" #include "ZipFileHeader.h" #include "ZipStorage.h" #include "ZipCryptograph.h" #include "ZipException.h" /** A base class for compressors used in compression and decompression of data. */ class ZIP_API CZipCompressor { protected: CZipStorage* m_pStorage; ///< The current storage object. CZipAutoBuffer m_pBuffer; ///< A buffer that receives compressed data or provides data for decompression. CZipCryptograph* m_pCryptograph; ///< Current cryptograph. CZipFileHeader* m_pFile; ///< The file header being compressed or decompressed. /** Initializes a new instance of the CZipCompressor class. \param pStorage The current storage object. */ CZipCompressor(CZipStorage* pStorage) :m_pStorage(pStorage) { m_pCryptograph = NULL; m_uUncomprLeft = 0; m_uComprLeft = 0; m_uCrc32 = 0; } public: /** The type of a compressor. */ enum CompressorType { typeDeflate = 1, ///< Deflate compression (default in zip archives). typeBzip2 ///< Bzip2 compression. }; /** The compression level. */ enum CompressionLevel { levelDefault = -1, ///< The default compression level (equals 6 for deflate). levelStore = 0, ///< No compression used. Data is stored. levelFastest = 1, ///< The fastest compression. The compression ratio is the lowest (apart from #levelStore). levelBest = 9 ///< The highest compression ratio. It's usually the slowest. }; /** The compression method. */ enum CompressionMethod { methodStore = 0, ///< A file is stored, not compressed. methodDeflate = 8, ///< The deflate compression method. /** A file is compressed using the bzip2 algorithm. \see 0610231446|bzip2 */ methodBzip2 = 12, /** This value means that WinZip AES encryption is used. The original compression method is stored in a WinZip extra field. It is only an informational value - you cannot set it as a compression method. The ZipArchive Library handles this value internally. \see 0610201627|aes */ methodWinZipAes = 99 }; /** The base class for compressors options. \see 0610231446|options \see CZipArchive::SetCompressionOptions */ struct ZIP_API COptions { /** Helper constants. */ enum Constants { /** The default size of the buffer used in compression and decompression operations. */ cDefaultBufferSize = 2 * 65536 }; COptions() { m_iBufferSize = cDefaultBufferSize; } /** Gets the type of the compressor to which the current options apply. \return The type of the compressor. It can be one of the #CompressorType values. */ virtual int GetType() const = 0; /** Clones the current options object. \return The cloned object of the same type as the current object. */ virtual COptions* Clone() const = 0; /** The size of the buffer used in compression and decompression operations. By default it is set to to #cDefaultBufferSize. For the optimal performance of the deflate algorithm it should be set at least to 128kB. \see CZipArchive::SetAdvanced */ int m_iBufferSize; virtual ~COptions() { } }; /** A dictionary used for keeping options for different types of compressors. \see CZipArchive::SetCompressionOptions */ class ZIP_API COptionsMap : public CZipMap { public: void Set(const COptions* pOptions); void Remove(int iType); COptions* Get(int iType) const; ~COptionsMap(); }; /** Returns the value indicating whether the given compression method is supported by the ZipArchive Library. \param uCompressionMethod The compression method. Can be one of the #CompressionMethod values. \return \c true, if the compression method is supported, \c false otherwise. */ static bool IsCompressionSupported(WORD uCompressionMethod) { return uCompressionMethod == methodStore || uCompressionMethod == methodDeflate ; } ZIP_SIZE_TYPE m_uUncomprLeft; ///< The number of bytes left to decompress. ZIP_SIZE_TYPE m_uComprLeft; ///< The number of bytes left to compress. DWORD m_uCrc32; ///< The CRC32 file checksum. /** Returns the value indicating, if the current #CZipCompressor object supports the given compression method. \param uMethod The compression method. Can be one of the #CompressionMethod values. \return \c true, if the compression method is supported; \c false otherwise. */ virtual bool CanProcess(WORD uMethod) = 0; /** The method called when a new file is opened for compression. \param iLevel The compression level. \param pFile The file being compressed. \param pCryptograph The current CZipCryptograph. Can be \c NULL, if no encryption is used. \see Compress \see FinishCompression */ virtual void InitCompression(int iLevel, CZipFileHeader* pFile, CZipCryptograph* pCryptograph) { InitBuffer(); m_uComprLeft = 0; m_pFile = pFile; m_pCryptograph = pCryptograph; } /** The method called when a new file is opened for extraction. \param pFile The file being extracted. \param pCryptograph The current CZipCryptograph. Can be \c NULL, if no decryption is used. \see Decompress \see FinishDecompression */ virtual void InitDecompression(CZipFileHeader* pFile, CZipCryptograph* pCryptograph) { InitBuffer(); m_pFile = pFile; m_pCryptograph = pCryptograph; m_uComprLeft = m_pFile->GetDataSize(false, true); m_uUncomprLeft = m_pFile->m_uUncomprSize; m_uCrc32 = 0; } /** Compresses the given data. \param pBuffer The buffer that holds the data to compress. \param uSize The size of \a pBuffer. \see InitCompression \see FinishCompression */ virtual void Compress(const void *pBuffer, DWORD uSize) = 0; /** Decompresses the given data. \param pBuffer The buffer that receives the decompressed data. \param uSize The size of \a pBuffer. \return The number of bytes decompressed and written to \a pBuffer. \note This method should be called repeatedly until it returns 0. \see InitDecompression \see FinishDecompression */ virtual DWORD Decompress(void *pBuffer, DWORD uSize) = 0; /** The method called at the end of the compression process. \param bAfterException Set to \c true, if an exception occurred before or to \c false otherwise. \see InitCompression \see Compress */ virtual void FinishCompression(bool bAfterException){} /** The method called at the end of the decompression process. \param bAfterException Set to \c true, if an exception occurred before or to \c false otherwise. \see InitDecompression \see Decompress */ virtual void FinishDecompression(bool bAfterException){} /** Returns the current options of the compressor. \return The current options for the compressor. \see 0610231446|options \see CZipArchive::SetCompressionOptions \see UpdateOptions */ virtual const COptions* GetOptions() const { return NULL; } /** Updates the current options with the options stored in \a optionsMap, if the appropriate options are present in the map. \param optionsMap The map to get the new options from. \see 0610231446|options \see GetOptions */ void UpdateOptions(const COptionsMap& optionsMap); virtual ~CZipCompressor() { } /** A factory method that creates an appropriate compressor for the given compression method. \param uMethod The compression method to create a compressor for. Can be one of #CompressionMethod values. \param pStorage The current storage object. */ static CZipCompressor* CreateCompressor(WORD uMethod, CZipStorage* pStorage); protected: /** Updates the current options with the new options. \param pOptions The new options to apply. */ virtual void UpdateOptions(const COptions* pOptions) { } /** Updates CRC value while compression. \param pBuffer A buffer with data for which the CRC value should be updated. \param uSize The size of the buffer. */ void UpdateFileCrc(const void *pBuffer, DWORD uSize); /** Updates CRC value while decompression. \param pBuffer A buffer with data for which the CRC value should be updated. \param uSize The size of the buffer. */ void UpdateCrc(const void *pBuffer, DWORD uSize); /** Flushes data in the buffer into the storage, encrypting the data if needed. \note Throws exceptions. */ void FlushWriteBuffer() { if (m_pCryptograph) m_pCryptograph->Encode(m_pBuffer, (DWORD)m_uComprLeft); m_pStorage->Write(m_pBuffer, (DWORD)m_uComprLeft, false); m_uComprLeft = 0; } /** Initializes the internal buffer. \see ReleaseBuffer */ void InitBuffer(); /** Releases the internal buffer. \see InitBuffer */ void ReleaseBuffer() { m_pBuffer.Release(); } /** Converts internal error code of the compressor to the ZipArchive Library error code. \param iErr An internal error code. \return A ZipArchive Library error code. */ virtual int ConvertInternalError(int iErr) const { return iErr; } /** Throws an exception with a given error code. \param iErr An error code. \param bInternal \c true, if \a iErr is an internal error code and needs a conversion to the ZipArchive Library error code; \c false otherwise. \note Throws exceptions. \see ConvertInternalError */ void ThrowError(int iErr, bool bInternal = false) { if (bInternal) iErr = ConvertInternalError(iErr); CZipException::Throw(iErr, m_pStorage->IsClosed(true) ? _T("") : (LPCTSTR)m_pStorage->m_pFile->GetFilePath()); } }; #if _MSC_VER > 1000 #pragma warning( pop ) #endif #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipCryptograph.h0000644000175000017500000001500711300022650022172 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipCryptograph.h * Includes the CZipCryptograph class. * */ #if !defined(ZIPARCHIVE_ZIPCRYPTOGRAPH_DOT_H) #define ZIPARCHIVE_ZIPCRYPTOGRAPH_DOT_H #if _MSC_VER > 1000 #pragma once #pragma warning( push ) #pragma warning (disable : 4100) // unreferenced formal parameter #endif // _MSC_VER > 1000 #include "ZipAutoBuffer.h" #include "ZipStorage.h" class CZipFileHeader; /** The base class for cryptographs used in encryption and decryption of file data. \see 0610201627 */ class ZIP_API CZipCryptograph { public: /** The encryption method. \see 0610201627 */ enum EncryptionMethod { encStandard, ///< The traditional zip encryption. encWinZipAes128, ///< WinZip AES 128-bit encryption. encWinZipAes192, ///< WinZip AES 192-bit encryption. encWinZipAes256, ///< WinZip AES 256-bit encryption. encNone = 0xFF ///< Indicates no encryption. }; /** A factory method that creates an appropriate cryptograph for the given method. \param iEncryptionMethod The encryption method to create a cryptograph for. Can be one of #EncryptionMethod values. \return The new cryptograph. The caller is responsible for destroying the object. If the method is not supported, creates CZipCrc32Cryptograph. */ static CZipCryptograph* CreateCryptograph(int iEncryptionMethod); /** Determines if the given method is one of the WinZip AES encryption method. \param iEncryptionMethod The encryption method to test. Can be one of #EncryptionMethod values. \return \c true, if the method is one the WinZip AES encryption methods; \c false otherwise. */ static bool IsWinZipAesEncryption(int iEncryptionMethod) { return iEncryptionMethod == encWinZipAes128 || iEncryptionMethod == encWinZipAes192 || iEncryptionMethod == encWinZipAes256; } /** Returns the total size of the extra data that is added to the compression stream during encryption with the given method. \param iEncryptionMethod The encryption method. Can be one of #EncryptionMethod values. \return The total size of extra data for the given encryption method. */ static DWORD GetEncryptedInfoSize(int iEncryptionMethod); /** Returns the size of the extra data that is added before the compression stream during encryption with the given method. \param iEncryptionMethod The encryption method. Can be one of #EncryptionMethod values. \return The size of extra data at the beginning of the compression stream for the given encryption method. */ static DWORD GetEncryptedInfoSizeBeforeData(int iEncryptionMethod); /** Returns the size of the extra data that is added after the compression stream during encryption with the given method. \param iEncryptionMethod The encryption method. Can be one of #EncryptionMethod values. \return The size of extra data at the end of the compression stream for the given encryption method. */ static DWORD GetEncryptedInfoSizeAfterData(int iEncryptionMethod); /** Determines if the given encryption method is supported by the current compilation of the ZipArchive Library. \param iEncryptionMethod The encryption method to test. Can be one of #EncryptionMethod values. \return \c true, if the method is supported; \c false otherwise. */ static bool IsEncryptionSupported(int iEncryptionMethod) { return iEncryptionMethod == encStandard; } /** The method called when an existing file is opened for extraction. \param password The supplied password with the CZipArchive::SetPassword method. \param currentFile The file being decoded and extracted. \param storage The current CZipStorage. \return \c true, if the password is initially considered correct; \c false otherwise. */ virtual bool InitDecode(CZipAutoBuffer& password, CZipFileHeader& currentFile, CZipStorage& storage) = 0; /** The method called when a new file is opened for compression. \param password The supplied password with the CZipArchive::SetPassword method. \param currentFile The file being compressed and encoded. \param storage The current CZipStorage. */ virtual void InitEncode(CZipAutoBuffer& password, CZipFileHeader& currentFile, CZipStorage& storage) = 0; /** Decodes the given data. \param pBuffer The buffer that holds the data to decode and that receives the results. \param uSize The size of \a pBuffer. */ virtual void Decode(char* pBuffer, DWORD uSize) = 0; /** Encodes the given data. \param pBuffer The buffer that holds the data to encode and that receives the results. \param uSize The size of \a pBuffer. */ virtual void Encode(char* pBuffer, DWORD uSize) = 0; /** The method called at the end of the decoding process. \param currentFile The file being decoded and extracted. \param storage The current CZipStorage. */ virtual void FinishDecode(CZipFileHeader& currentFile, CZipStorage& storage){}; /** The method called at the end of the decoding process. \param currentFile The file being compressed and encoded. \param storage The current CZipStorage. */ virtual void FinishEncode(CZipFileHeader& currentFile, CZipStorage& storage){}; /** Returns the value indicating whether the current compressor can handle the given encryption method. \param iEncryptionMethod The encryption method to test. Can be one of #EncryptionMethod values. \return \c true, if the current compressor can handle the given encryption method; \c false otherwise. */ virtual bool CanHandle(int iEncryptionMethod) { return false; } virtual ~CZipCryptograph(){} }; #if _MSC_VER > 1000 #pragma warning( pop ) #endif // _MSC_VER > 1000 #endif tuxcmd-modules-0.6.70+ds/zip/ZipArchive/Sha1.cpp0000644000175000017500000000131011300022650020324 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "_features.h" tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipString.cpp0000644000175000017500000000174411300022650021474 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipString.h" ZIPSTRINGCOMPARE GetCZipStrCompFunc(bool bCaseSensitive, bool bCollate) { if (bCollate) return bCaseSensitive ? & CZipString::Collate : & CZipString::CollateNoCase; else return bCaseSensitive ? & CZipString::Compare : & CZipString::CompareNoCase; } tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipString.h0000644000175000017500000000202411300022650021131 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipString.h * Includes the CZipString class. * */ #ifndef ZIPARCHIVE_ZIPSTRING_DOT_H #define ZIPARCHIVE_ZIPSTRING_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "_platform.h" #ifdef ZIP_ARCHIVE_STL #include "ZipString_stl.h" #else #include "ZipString_mfc.h" #endif #endif /* ZIPARCHIVE_ZIPSTRING_DOT_H */ tuxcmd-modules-0.6.70+ds/zip/ZipArchive/ZipExtraField.h0000644000175000017500000001362711300022650021725 0ustar salvisalvi//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2007 by Artpol Software - Tadeusz Dracz // // This program 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 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// /** * \file ZipExtraField.h * Includes the CZipExtraField class. * */ #if !defined(ZIPARCHIVE_ZIPEXTRAFIELD_DOT_H) #define ZIPARCHIVE_ZIPEXTRAFIELD_DOT_H #if _MSC_VER > 1000 #pragma once #endif #include "ZipExport.h" #include "ZipExtraData.h" #include "ZipCollections.h" #include "ZipStorage.h" #define ZIP_EXTRA_ZARCH_NAME 0x5A4C // ZL - ZipArchive Library #define ZIP_EXTRA_ZARCH_SEEK 0x5A4D #if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL) #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class #endif /** Represents a local or central extra field in a zip archive. This is a collection of extra data records (CZipExtraData). \see 0610242300 \see CZipExtraData */ class ZIP_API CZipExtraField { friend class CZipFileHeader; public: CZipExtraField(){} CZipExtraField(const CZipExtraField& arr) { *this = arr; } CZipExtraField& operator=(const CZipExtraField& field) { Clear(); for (int i = 0; i < field.GetCount(); i++) Add(new CZipExtraData(*field.GetAt(i))); return *this; } /** Gets the total size, the extra data will occupy in the archive. \return The size in bytes. */ int GetTotalSize() const; /** Validates the current size of the extra field. \return \c false, if the size is larger than allowed; \c false otherwise. */ bool Validate() const { return GetTotalSize() <= USHRT_MAX; } /** Gets the number of extra data records included in the extra field. \return The number of extra fields included. */ int GetCount() const { return (int)m_aData.GetSize(); } /** Gets the extra data record at the given index. \param index The index of extra data record to retrieve. \return The extra data record. */ CZipExtraData* GetAt(int index) const { return m_aData.GetAt(index); } /** Removes the extra data record at the given index. \param index The index of the extra data record to remove. */ void RemoveAt(int index) { delete (GetAt(index)); m_aData.RemoveAt(index); } /** Adds a new extra data record to the extra field. \param pExtra The extra data record to add. \return The index of \a pExtra in the internal collection. */ int Add(CZipExtraData* pExtra) { return (int)m_aData.Add(pExtra); } /** Creates a new extra data record with the given ID and adds it to the extra field. \param headerID The extra data ID. \return The created extra data record. \see CZipExtraData::GetHeaderID */ CZipExtraData* CreateNew(WORD headerID) { int temp; return CreateNew(headerID, temp); } /** Creates a new extra data record with the given ID and adds it to the extra field. \param headerID The extra data ID. \param idx Receives the value of the index of the new extra data in the internal collection. \return The created extra data record. \see CZipExtraData::GetHeaderID */ CZipExtraData* CreateNew(WORD headerID, int& idx) { CZipExtraData* pData = new CZipExtraData(headerID); idx = (int)m_aData.Add(pData); return pData; } /** Removes all extra data records from the extra field, that are internally used by the ZipArchive Library. */ void RemoveInternalHeaders(); /** Lookups the extra field for the extra data record with the given ID. \param headerID The ID of the extra data to lookup. \return The found extra data record or \c NULL, if the extra data could not be found. */ CZipExtraData* Lookup(WORD headerID) const { int temp; return Lookup(headerID, temp); } /** Returns the value indicating whether the extra data record with the given ID is present in the extra field. \param headerID The ID of the extra data to check. \return \c true, if the extra data record with the given ID is present in the extra field; \c false otherwise. */ bool HasHeader(WORD headerID) { return Lookup(headerID) != NULL; } /** Lookups the extra field for the extra data record with the given ID. \param headerID The ID of the extra data to lookup. \param index Receives the value of the index of the found extra data in the internal collection. \return The found extra data record or \c NULL, if the extra data could not be found. */ CZipExtraData* Lookup(WORD headerID, int& index) const; ~CZipExtraField() { Clear(); } protected: /** Removes all extra data records from the extra field. */ void Clear() { for (int i = 0; i < GetCount(); i++) delete (GetAt(i)); m_aData.RemoveAll(); } /** Reads the extra field from \a buffer. \param pStorage The storage to read the data from. \param uSize The size of the data to read. \return \c false, if \a uSize was smaller than the declared extra field size; \c true otherwise. */ bool Read(CZipStorage* pStorage, WORD uSize); /** Writes the extra field to \a buffer. \param buffer The buffer to write to. */ void Write(char* buffer) const; private: CZipArray m_aData; }; #endif // !defined(ZIPARCHIVE_ZIPEXTRAFIELD_DOT_H) tuxcmd-modules-0.6.70+ds/zip/treepath_vfs.h0000777000175000017500000000000011300603570024201 2../common/treepath_vfs.hustar salvisalvituxcmd-modules-0.6.70+ds/zip/COPYING0000644000175000017500000004310311300022650016021 0ustar salvisalvi GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. tuxcmd-modules-0.6.70+ds/zip/vfsutils.h0000777000175000017500000000000011300603570022553 2../common/vfsutils.hustar salvisalvituxcmd-modules-0.6.70+ds/zip/treepathutils.c0000777000175000017500000000000011300603570024575 2../common/treepathutils.custar salvisalvituxcmd-modules-0.6.70+ds/zip/strutils.c0000777000175000017500000000000011300603570022565 2../common/strutils.custar salvisalvituxcmd-modules-0.6.70+ds/zip/Makefile0000644000175000017500000000254711300613427016445 0ustar salvisalvi# path definitions DESTDIR = /usr INSTALL=install -c INSTALL_DATA = ${INSTALL} -m 644 DIR_ZIPARCHIVE = ./ZipArchive/ # compiler options CC = gcc CPP = g++ CFLAGS =-I. -I$(DIR_ZIPARCHIVE) -I/usr/include \ -Wall -fPIC -O2 -g \ -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \ -D__VERBOSE_DEBUGx LIB_SUFFIX=`if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi` VFS_COMMON_OBJECTS=strutils.o treepathutils.o treepath_vfs.o vfsutils.o VFS_C_OBJECTS= VFS_CPP_OBJECTS=zip.o .SUFFIXES: .c .cpp .c.o: $(CPP) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $< .cpp.o: $(CPP) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $< all shared static: libzip_plugin.so libzip_plugin.so: ziparchive $(VFS_COMMON_OBJECTS) $(VFS_CPP_OBJECTS) $(VFS_C_OBJECTS) $(CPP) -shared -o libzip_plugin.so zip.o $(VFS_COMMON_OBJECTS) $(DIR_ZIPARCHIVE)libziparch.a -lz -lm $(CFLAGS) `pkg-config glib-2.0 --libs` ziparchive: ( cd $(DIR_ZIPARCHIVE) && make -f ../Makefile.ziparch ) || exit 1 strutils.o: strutils.c strutils.h treepathutils.o: treepathutils.c treepathutils.h vfsutils.o: vfsutils.c vfsutils.h treepath_vfs.o: treepath_vfs.c treepath_vfs.h install:: $(INSTALL) ./libzip_plugin.so $(DESTDIR)/lib$(LIB_SUFFIX)/tuxcmd/ clean: ( cd $(DIR_ZIPARCHIVE) && make -f ../Makefile.ziparch clean ) || exit 1 rm -f *.o *.d *.gch libzip_plugin.so tuxcmd-modules-0.6.70+ds/zip/treepath_vfs.c0000777000175000017500000000000011300603570024167 2../common/treepath_vfs.custar salvisalvituxcmd-modules-0.6.70+ds/zip/vfsutils.c0000777000175000017500000000000011300603570022541 2../common/vfsutils.custar salvisalvituxcmd-modules-0.6.70+ds/zip/zip.cpp0000644000175000017500000011505511300022650016302 0ustar salvisalvi/* ZIP plugin for Tux Commander * version 0.5.6, designed for ZipArchive v3.2.0 * Copyright (C) 2008 Tomas Bzatek * Check for updates on tuxcmd.sourceforge.net * * Uses ZipArchive library * Copyright (C) 2000 - 2007 Artpol Software - Tadeusz Dracz * http://www.artpol-software.com/ZipArchive/ * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include "vfs_types.h" #include "strutils.h" #include "vfsutils.h" #include "treepathutils.h" #include "treepath_vfs.h" #include "ZipArchive.h" #include "ZipPlatform.h" #include "ZipCallback.h" #define VERSION "0.5.6" #define BUILD_DATE "2009-10-25" #define DEFAULT_BLOCK_SIZE 65536 using namespace std; extern "C" { /******************************************************************************************************/ /** Utilities */ /************** ****************/ TVFSResult get_vfs_errorcode(int m_iCause) { switch (m_iCause) { case 13: return cVFS_WriteErr; // Permission denied case CZipException::noError: return cVFS_WriteErr; // No error. case CZipException::genericError: return cVFS_WriteErr; // An unknown error. case CZipException::badZipFile: return cVFS_ReadErr; // Damaged or not a zip file. case CZipException::badCrc: return cVFS_ReadErr; // Crc is mismatched. case CZipException::noCallback: return cVFS_Failed; // There is no spanned archive callback object set. case CZipException::aborted: return cVFS_Failed; // The disk change callback method returned false. case CZipException::abortedAction: return cVFS_Failed; // The action callback method returned false. case CZipException::abortedSafely: return cVFS_Failed; // The action callback method returned false, but the data is not corrupted. case CZipException::nonRemovable: return cVFS_WriteErr; // The device selected for the spanned archive is not removable. case CZipException::tooManyVolumes: return cVFS_WriteErr; // The limit of the maximum volumes reached. case CZipException::tooManyFiles: return cVFS_ReadErr; // The limit of the maximum files in an archive reached. case CZipException::tooLongData: return cVFS_ReadErr; // The filename, the comment or the local or central extra field of the file added to the archive is too long. case CZipException::tooBigSize: return cVFS_ReadErr; // The file size is too large to be supported. case CZipException::badPassword: return cVFS_ReadErr; // An incorrect password set for the file being decrypted. case CZipException::dirWithSize: return cVFS_ReadErr; // The directory with a non-zero size found while testing. case CZipException::internalError: return cVFS_WriteErr; // An internal error. case CZipException::notRemoved: return cVFS_WriteErr; // Error while removing a file case CZipException::notRenamed: return cVFS_WriteErr; // Error while renaming a file (under Windows call GetLastError() to find out more). case CZipException::platfNotSupp: return cVFS_WriteErr; // Cannot create a file for the specified platform. case CZipException::cdirNotFound: return cVFS_ReadErr; // The central directory was not found in the archive (or you were trying to open not the last disk of a segmented archive). // case CZipException::cdir64NotFound: return cVFS_ReadErr; // The Zip64 central directory signature was not found in the archive where expected. // case CZipException::noBBZInZip64: return cVFS_ReadErr; // The number of bytes before a zip archive must be zero in the Zip64 format. // case CZipException::badAesAuthCode: return cVFS_ReadErr; // Mismatched authentication code in WinZip AEC decrypted data. case CZipException::noZip64: return cVFS_ReadErr; // The Zip64 format has not been enabled for the library, but is required to open the archive. case CZipException::noAES: return cVFS_ReadErr; // WinZip AES encryption has not been enabled for the library, but is required to decompress the archive. case CZipException::outOfBounds: return cVFS_ReadErr; // The collection is empty and the bounds do not exist. // case CZipException::mutexError: return cVFS_ReadErr; // Locking or unlocking resources access was unsuccessful. case CZipException::streamEnd: return cVFS_ReadErr; // Zlib library error. case CZipException::needDict: return cVFS_ReadErr; // Zlib library error. case CZipException::errNo: return cVFS_ReadErr; // Zlib library error. case CZipException::streamError: return cVFS_ReadErr; // Zlib library error. case CZipException::dataError: return cVFS_ReadErr; // Zlib library error. case CZipException::memError: return cVFS_ReadErr; // Zlib library or CZipMemFile error. case CZipException::bufError: return cVFS_ReadErr; // Zlib library error. case CZipException::versionError: return cVFS_ReadErr; // Zlib library error. // case CZipException::bzSequenceError: return cVFS_ReadErr; // Bzlib library error. // case CZipException::bzParamError: return cVFS_ReadErr; // Bzlib library error. // case CZipException::bzMemError: return cVFS_ReadErr; // Bzlib library error. // case CZipException::bzDataError: return cVFS_ReadErr; // Bzlib library error. // case CZipException::bzDataErrorMagic: return cVFS_ReadErr; // Bzlib library error. // case CZipException::bzIoError: return cVFS_ReadErr; // Bzlib library error. // case CZipException::bzUnexpectedEof: return cVFS_ReadErr; // Bzlib library error. // case CZipException::bzOutbuffFull: return cVFS_ReadErr; // Bzlib library error. // case CZipException::bzConfigError: return cVFS_ReadErr; // Bzlib library error. // case CZipException::bzInternalError: return cVFS_ReadErr; // Internal Bzlib library error. default: return cVFS_WriteErr; } return cVFS_Failed; // Default error } /******************************************************************************************************/ /** Auxiliary classes */ /************** ****************/ struct ZIP_API CVFSZipActionCallback; struct TVFSGlobs { TVFSLogFunc log_func; char *curr_dir; char *archive_path; gboolean need_password; CZipArchive *zip; CVFSZipActionCallback *extract_callback; bool archive_opened; unsigned long block_size; bool archive_modified; struct PathTree *files; struct VfsFilelistData *vfs_filelist; TVFSAskQuestionCallback callback_ask_question; TVFSAskPasswordCallback callback_ask_password; TVFSProgressCallback callback_progress; void *callback_data; }; // Define the progress class and the class methods struct ZIP_API CVFSZipActionCallback : public CZipActionCallback { CVFSZipActionCallback() { m_uTotalToProcess = 0; m_uProcessed = 0; globs = NULL; } struct TVFSGlobs *globs; virtual bool Callback(ZIP_SIZE_TYPE uProgress) { fprintf(stderr, "(II) Callback called, position = %lu; m_uTotalToProcess = %lu; m_uProcessed = %lu\n", uProgress, m_uTotalToProcess, m_uProcessed); bool ret = true; try { if (globs && globs->callback_progress) ret = globs->callback_progress (m_uProcessed, m_uTotalToProcess, globs->callback_data); } catch (...) { fprintf(stderr, "(EE) extract_callback: Fatal error occured when calling pCallBackProgress\n"); } return ret; } }; /*********************************************************************************************************************** * Internal tree functions ********/ void build_global_filelist(struct TVFSGlobs *globs) { int iCount = globs->zip->GetCount(); // Ensure the filelist is freed if (globs->files) filelist_tree_free(globs->files); globs->files = filelist_tree_new(); vfs_filelist_set_files(globs->vfs_filelist, globs->files); // list files in archive for (int i = 0; i < iCount; i++) { CZipFileHeader *fh = globs->zip->GetFileInfo(i); if (fh != NULL) printf(" No: %i, '%s', IsDir: %i, Size: %lu, SystemAttr = 0x%lX, OriginalAttr = 0x%lX, encrypted = %d\n", i, (LPCTSTR)fh->GetFileName(), fh->IsDirectory(), fh->m_uUncomprSize, fh->GetSystemAttr(), fh->GetOriginalAttributes(), fh->IsEncrypted()); } printf("\n\n"); for (int i = 0; i < iCount; i++) { CZipFileHeader *fh = globs->zip->GetFileInfo(i); if (fh != NULL) { // Create a TVFSItem entry and fill all info struct TVFSItem *item = (struct TVFSItem*)malloc(sizeof(struct TVFSItem)); memset(item, 0, sizeof(struct TVFSItem)); item->iSize = (int64_t)fh->m_uUncomprSize; item->iPackedSize = (int64_t)fh->m_uComprSize; if (fh->IsDirectory()) item->ItemType = vDirectory; else item->ItemType = vRegular; item->iMode = fh->GetSystemAttr(); item->iUID = geteuid(); item->iGID = getegid(); item->m_time = (__time_t)fh->GetTime(); item->c_time = item->m_time; item->a_time = item->m_time; if (fh->IsEncrypted()) globs->need_password = TRUE; char *s; s = g_filename_display_name ((LPCTSTR)fh->GetFileName()); // Add item to the global list and continue with next file filelist_tree_add_item(globs->files, s, s, item, i + 1); g_free (s); printf("\n"); } } if (globs->need_password) printf("Password present.\n"); printf("\n\n\n\nPrinting the contents of the global filelist:\n\n"); filelist_tree_print(globs->files); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Basic initialization functions struct TVFSGlobs * VFSNew (TVFSLogFunc log_func) { struct TVFSGlobs * globs; globs = (struct TVFSGlobs *) malloc (sizeof (struct TVFSGlobs)); memset (globs, 0, sizeof (struct TVFSGlobs)); globs->archive_opened = false; globs->block_size = DEFAULT_BLOCK_SIZE; globs->archive_modified = false; globs->need_password = FALSE; globs->callback_data = NULL; globs->callback_ask_question = NULL; globs->callback_ask_password = NULL; globs->callback_progress = NULL; globs->log_func = log_func; if (globs->log_func != NULL) globs->log_func("zip plugin: VFSInit"); return globs; } void VFSSetCallbacks (struct TVFSGlobs *globs, TVFSAskQuestionCallback ask_question_callback, TVFSAskPasswordCallback ask_password_callback, TVFSProgressCallback progress_func, void *data) { globs->callback_ask_question = ask_question_callback; globs->callback_ask_password = ask_password_callback; globs->callback_progress = progress_func; globs->callback_data = data; } void VFSFree (struct TVFSGlobs *globs) { if (globs->log_func != NULL) globs->log_func("zip plugin: VFSDestroy"); free (globs); } int VFSVersion() { return cVFSVersion; } struct TVFSInfo * VFSGetInfo() { struct TVFSInfo *module_info = (TVFSInfo*) g_malloc0 (sizeof (struct TVFSInfo)); module_info->ID = g_strdup ("zip_plugin"); module_info->Name = g_strdup ("ZIP plugin"); module_info->About = g_strdup_printf ("version %s, build date: %s\nusing ZipArchive library v%s\n", VERSION, BUILD_DATE, CZipArchive::m_gszVersion); module_info->Copyright = g_strdup_printf ("Plugin Copyright (C) 2004-2009 Tomáš Bžatek\n%s", CZipArchive::m_gszCopyright); return module_info; } char * VFSGetArchiveExts() { return g_strdup ("zip"); } /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ TVFSResult VFSOpenArchive(struct TVFSGlobs *globs, char *sName) { // Initialize the objects globs->files = NULL; globs->vfs_filelist = vfs_filelist_new(NULL); globs->curr_dir = NULL; globs->zip = new CZipArchive; try { fprintf(stderr, "(--) VFSOpenArchive: trying to open the file...\n"); try { if (! globs->zip->Open(sName, CZipArchive::zipOpen, 0)) { printf("(EE) VFSOpenArchive: error opening zip archive\n"); return cVFS_Failed; } } catch (...) { printf("(!!) VFSOpenArchive: error opening readwrite zip, trying readonly...\n"); try { // try to open in read only mode (required if there's no write access on the media) if (! globs->zip->Open(sName, CZipArchive::zipOpenReadOnly, 0)) { printf("(EE) VFSOpenArchive: error opening readonly zip archive\n"); return cVFS_Failed; } } catch (...) { printf("(EE) VFSOpenArchive: error opening readonly zip\n"); return cVFS_Failed; } } int iCount = globs->zip->GetCount(false); printf("(II) VFSOpenArchive: %i records found, %i files.\n", iCount, globs->zip->GetCount(true)); if (iCount < 1) return cVFS_Failed; // Build the global file list build_global_filelist(globs); // Set the progress callback globs->extract_callback = new CVFSZipActionCallback; globs->extract_callback->globs = globs; globs->zip->SetCallback(globs->extract_callback, CZipActionCallback::cbExtract); globs->zip->SetCallback(globs->extract_callback, CZipActionCallback::cbAdd); // Set automatic flushing of changes to disk globs->zip->SetAutoFlush(true); } catch (CZipException e) { printf ("(EE) VFSOpenArchive: Error while processing archive %s\n%s\n", (LPCTSTR) sName, (LPCTSTR)e.GetErrorDescription()); if (e.m_szFileName.IsEmpty()) printf("\n"); else printf("(EE) VFSOpenArchive: Filename in error object: %s\n\n", (LPCTSTR)e.m_szFileName); globs->zip->Close(true); return cVFS_Failed; } catch (...) { printf ("(EE) VFSOpenArchive: Unknown error while processing archive %s\n\n", (LPCTSTR) sName); globs->zip->Close(true); return cVFS_Failed; } globs->archive_path = strdup(sName); globs->archive_modified = false; return cVFS_OK; } TVFSResult VFSClose(struct TVFSGlobs *globs) { if (globs) { // Closing the archive... fprintf(stderr, "(II) VFSClose: Closing the archive...\n"); try { if (globs->archive_modified) globs->zip->Flush(); globs->zip->Close(CZipArchive::afNoException, false); //*** In case of inconsistency, try using afWriteDir value // (Use when an exception was thrown. The Close method writes the // central directory structure to the archive, so that the archive should be usable.) } catch (CZipException e) { fprintf(stderr, "(EE) VFSClose: Error while closing archive: %s\n", (LPCTSTR)e.GetErrorDescription()); return cVFS_Failed; } // Freeing the ZIP objects... fprintf(stderr, "(II) VFSClose: Freeing ZipArchive objects...\n"); try { delete globs->extract_callback; delete globs->zip; } catch (...) { fprintf(stderr, "(EE) VFSClose: Error freeing ZipArchive objects\n"); return cVFS_Failed; } // Freeing the filelist fprintf(stderr, "(II) VFSClose: Freeing filelist...\n"); if (globs->vfs_filelist) vfs_filelist_free(globs->vfs_filelist); if (globs->files) filelist_tree_free(globs->files); // Free the rest... free(globs->archive_path); } return cVFS_OK; } char * VFSGetPath (struct TVFSGlobs *globs) { return g_strdup (globs->curr_dir); } u_int64_t VFSGetFileSystemFree(struct TVFSGlobs *globs, char *APath) { return 0; } u_int64_t VFSGetFileSystemSize(struct TVFSGlobs *globs, char *APath) { return globs->zip->GetOccupiedSpace(); } /******************************************************************************************************/ TVFSResult VFSChangeDir(struct TVFSGlobs *globs, char *NewPath) { if (NewPath == NULL) { printf("(EE) VFSChangeDir: NewPath is NULL!\n"); return cVFS_Failed; } globs->curr_dir = vfs_filelist_change_dir(globs->vfs_filelist, NewPath); if (globs->curr_dir) return cVFS_OK; else return cVFS_Failed; } /* int VFSSetPassword(struct TVFSGlobs *globs, char *pass) { printf ("(II) VFSSetPassword: Going to set the password...\n"); try { globs->zip->SetPassword(pass); } catch (...) { printf ("(EE) VFSSetPassword: Changing password failed. Maybe closed archive ?\n"); return cVFS_Failed; } return cVFS_OK; } */ int VFSGetPasswordRequired(struct TVFSGlobs *globs) { if (globs) return globs->need_password; return FALSE; } void VFSResetPassword(struct TVFSGlobs *globs) { if (globs) globs->zip->SetPassword(NULL); } /******************************************************************************************************/ TVFSResult VFSListFirst(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) { if (sDir == NULL) { printf("(EE) VFSListFirst: sDir is NULL!\n"); return cVFS_Failed; } printf ("(--) VFSListFirst: Going to list all items in '%s'\n", sDir); return vfs_filelist_list_first(globs->vfs_filelist, sDir, Item); } TVFSResult VFSListNext(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) { return vfs_filelist_list_next(globs->vfs_filelist, sDir, Item); } TVFSResult VFSListClose(struct TVFSGlobs *globs) { return vfs_filelist_list_close(globs->vfs_filelist); } /******************************************************************************************************/ long VFSFileExists(struct TVFSGlobs *globs, const char *FileName, const long Use_lstat) { if (! globs) return FALSE; return vfs_filelist_file_exists(globs->vfs_filelist, FileName, Use_lstat); } TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item) { printf("(--) VFSFileInfo: requested info for object '%s'\n", AFileName); if (!globs) return cVFS_Failed; return vfs_filelist_file_info(globs->vfs_filelist, AFileName, Item); } /******************************************************************************************************/ /** Recursive tree size counting */ /************** ****************/ u_int64_t VFSGetDirSize(struct TVFSGlobs *globs, char *APath) { if (! globs) return 0; return vfs_filelist_get_dir_size(globs->vfs_filelist, APath); } void VFSBreakGetDirSize(struct TVFSGlobs *globs) { printf("(WW) VFSBreakGetDirSize: calling break\n"); if (globs) vfs_filelist_get_dir_size_break(globs->vfs_filelist); } /******************************************************************************************************/ /** Methods modifying the archive */ /************** ****************/ TVFSResult VFSMkDir(struct TVFSGlobs *globs, const char *sDirName) { if ((sDirName == NULL) || (strlen(sDirName) < 1)) { printf("(EE) VFSMkDir: The value of 'sDirName' is NULL or empty\n"); return cVFS_Failed; } if ((strlen(sDirName) < 1) || (strcmp(sDirName, "/") == 0)) { printf("(EE) VFSMkDir: Invalid value '%s' (duplicate root entry?)\n", sDirName); return cVFS_Failed; } printf ("(II) VFSMkDir: Going to create new directory '%s'...\n", sDirName); try { try { CZipFileHeader header; // globs->zip->SetFileHeaderAttr(header, 0x41ED0010); // alternatively use ZipPlatform::GetDefaultAttributes(); globs->zip->SetFileHeaderAttr(header, 0x41ED); // alternatively use ZipPlatform::GetDefaultAttributes(); char *s = exclude_leading_path_sep(sDirName); header.SetFileName(s); free(s); header.SetTime(time(NULL)); bool bRet = globs->zip->OpenNewFile(header, 0, NULL); globs->zip->CloseNewFile(); if (! bRet) { printf("(EE) VFSMkDir: Error creating new directory '%s'\n", sDirName); return cVFS_Failed; } globs->archive_modified = true; build_global_filelist(globs); return cVFS_OK; } catch (CZipException e) { globs->zip->CloseNewFile(true); fprintf(stderr, "(EE) VFSMkDir: Error creating new directory '%s': [%d] %s, archive closed = %d.\n", sDirName, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); return get_vfs_errorcode(e.m_iCause); } } catch (...) { printf("(EE) VFSMkDir: Error creating new directory '%s'\n", sDirName); return cVFS_Failed; } } TVFSResult VFSRemove(struct TVFSGlobs *globs, const char *APath) { printf("(II) VFSRemove: Going to remove the file '%s'...\n", APath); char *AFile = exclude_trailing_path_sep(APath); unsigned long int file_no = filelist_find_index_by_path(globs->files, AFile) - 1; free(AFile); if (file_no < 0) { printf("(EE) VFSRemove: can't find the file specified: '%s'\n", APath); return cVFS_Failed; } try { try { if (! globs->zip->RemoveFile(file_no)) { printf("(EE) VFSRemove: Delete file '%s' failed.\n", APath); return cVFS_Failed; } build_global_filelist(globs); globs->archive_modified = true; printf("(II) VFSRemove OK.\n"); // Test for the sparse ZIP central directory char *AFile1 = exclude_trailing_path_sep(APath); char *AFile2 = g_path_get_dirname(AFile1); char *AFile3 = exclude_trailing_path_sep(AFile2); if ((strlen(AFile3) > 0) && (strcmp(AFile3, "/") != 0)) { printf("(II) VFSRemove: AFile1: '%s', AFile2: '%s', AFile3: '%s'\n", AFile1, AFile2, AFile3); file_no = filelist_find_index_by_path(globs->files, AFile2) - 1; printf("(II) VFSRemove: deleted: '%s', parent: '%s', file_no = %ld\n", APath, AFile3, file_no); if (file_no < 0) { printf("(WW) VFSRemove: sparse ZIP archive detected, adding empty directory: '%s'\n", AFile3); VFSMkDir(globs, AFile3); } } free(AFile1); free(AFile2); free(AFile3); return cVFS_OK; } catch (CZipException e) { fprintf(stderr, "(EE) VFSRemove: Delete file '%s' failed: [%d] %s, archive closed = %d.\n", APath, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); return get_vfs_errorcode(e.m_iCause); } } catch (...) { printf("(EE) VFSRemove: Delete file '%s' failed.\n", APath); return cVFS_Failed; } } TVFSResult VFSRename(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName) { printf ("(II) VFSRename: Going to rename/move the file '%s' to '%s'...\n", sSrcName, sDstName); char *AFile = exclude_trailing_path_sep(sSrcName); char *ADestFile = exclude_trailing_path_sep(sDstName); unsigned long int file_no = filelist_find_index_by_path(globs->files, AFile) - 1; free(AFile); if (file_no < 0) { printf("(EE) VFSRename: can't find the file specified: '%s'\n", sSrcName); return cVFS_Failed; } try { try { if (! globs->zip->RenameFile(file_no, ADestFile)) { printf ("(EE) VFSRename: Rename/move file '%s' failed.\n", sSrcName); return cVFS_Failed; } free(ADestFile); build_global_filelist(globs); globs->archive_modified = true; return cVFS_OK; } catch (CZipException e) { fprintf(stderr, "(EE) VFSRename: Rename/move file '%s' failed: [%d] %s, archive closed = %d.\n", sSrcName, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); return get_vfs_errorcode(e.m_iCause); } } catch (...) { printf ("(EE) VFSRename: Rename/move file failed.\n"); return cVFS_Failed; } } TVFSResult VFSMakeSymLink(struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo) { fprintf(stderr, "(EE) VFSMakeSymLink: Symbolic links not supported in ZIP archives.\n"); return cVFS_Not_Supported; } TVFSResult VFSChmod(struct TVFSGlobs *globs, const char *FileName, const uint Mode) { printf("(II) VFSChmod: Going to change permissions of the file '%s'...\n", FileName); char *AFile = exclude_trailing_path_sep(FileName); unsigned long int file_no = filelist_find_index_by_path(globs->files, AFile) - 1; free(AFile); if (file_no < 0) { printf("(EE) VFSChmod: can't find the file specified: '%s'\n", FileName); return cVFS_Failed; } try { try { // Set system compatibility first if (! globs->zip->SetSystemCompatibility(ZipCompatibility::zcUnix)) { printf("(EE) VFSChmod: Unable to set system compatibility\n"); } // Change the header data globs->zip->ReadLocalHeader(file_no); CZipFileHeader *header = globs->zip->GetFileInfo(file_no); if (! header) { printf("(EE) VFSChmod: Permissions modification of the file '%s' failed: NULL returned by GetFileInfo()\n", FileName); return cVFS_Failed; } // We need to change only 0xF000FFFF mask // The 0xF_______ bits represents file/directory type, the 0x____FFFF represents ZIP attributes and 0x_FFF____ represents unix permissions // printf("(II) VFSChmod: Current permissions: %lX, stripped: %lX, setting to: %X, modified: %lX\n", // header->GetSystemAttr(), header->GetSystemAttr() & 0xF000FFFF, Mode & 0xFFF, (header->GetSystemAttr() & 0xF000FFFF) + ((Mode & 0xFFF) << 16)); // globs->zip->SetFileHeaderAttr(*header, (header->GetSystemAttr() & 0xF000FFFF) + ((Mode & 0xFFF) << 16)); printf("(II) VFSChmod: Current permissions: 0x%lX, stripped: 0x%lX, setting to: 0x%X, modified: 0x%lX\n", header->GetSystemAttr(), header->GetSystemAttr() & 0xFFFFF000, Mode & 0xFFF, (header->GetSystemAttr() & 0xFFFFF000) + (Mode & 0xFFF)); globs->zip->SetFileHeaderAttr(*header, (header->GetSystemAttr() & 0xFFFFF000) + (Mode & 0xFFF)); // write the local header information globs->zip->OverwriteLocalHeader(file_no); /* // Re-encrypt the file if (header->IsEncrypted()) { printf("(II) VFSChmod: Re-encrypting the file...\n"); if (! globs->zip->EncryptFile(file_no)) printf("(EE) VFSChmod: Unable to encrypt the file\n"); } */ globs->zip->RemoveCentralDirectoryFromArchive(); globs->zip->Flush(); printf("(II) VFSChmod OK.\n"); build_global_filelist(globs); globs->archive_modified = true; return cVFS_OK; } catch (CZipException e) { globs->zip->CloseNewFile(true); fprintf(stderr, "(EE) VFSChmod: permissions modification of the file '%s' failed: [%d] %s, archive closed = %d.\n", FileName, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); return get_vfs_errorcode(e.m_iCause); } } catch (...) { printf("(EE) VFSChmod: permissions modification of the file '%s' failed.\n", FileName); return cVFS_Failed; } } TVFSResult VFSChown(struct TVFSGlobs *globs, const char *FileName, const uint UID, const uint GID) { fprintf(stderr, "(EE) VFSChown: Owner changing is not supported in ZIP archives.\n"); return cVFS_Not_Supported; } TVFSResult VFSChangeTimes(struct TVFSGlobs *globs, char *APath, long mtime, long atime) { printf ("(II) VFSChangeTimes: Going to change date/times of the file '%s'...\n", APath); char *AFile = exclude_trailing_path_sep(APath); unsigned long int file_no = filelist_find_index_by_path(globs->files, AFile) - 1; free(AFile); if (file_no < 0) { printf("(EE) VFSChangeTimes: can't find the file specified: '%s'\n", APath); return cVFS_Failed; } try { try { // read the local header information globs->zip->ReadLocalHeader(file_no); CZipFileHeader *header = globs->zip->GetFileInfo(file_no); if (! header) { printf("(EE) VFSChangeTimes: DateTime modification of the file '%s' failed: NULL returned by GetFileInfo()\n", APath); return cVFS_Failed; } // Change the header data header->SetTime(mtime); /* // Re-encrypt the file if (header->IsEncrypted()) { printf("(II) VFSChangeTimes: Re-encrypting the file...\n"); if (! globs->zip->EncryptFile(file_no)) printf("(EE) VFSChangeTimes: Unable to encrypt the file\n"); } */ // write the local header information globs->zip->OverwriteLocalHeader(file_no); globs->zip->RemoveCentralDirectoryFromArchive(); printf("(II) VFSChangeTimes OK.\n"); build_global_filelist(globs); globs->archive_modified = true; return cVFS_OK; } catch (CZipException e) { globs->zip->CloseNewFile(true); fprintf(stderr, "(EE) VFSChangeTimes: DateTime modification of the file '%s' failed: [%d] %s, archive closed = %d.\n", APath, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); return get_vfs_errorcode(e.m_iCause); } } catch (...) { printf("(EE) VFSChangeTimes: DateTime modification of the file '%s' failed.\n", APath); return cVFS_Failed; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////// TVFSFileDes VFSOpenFile(struct TVFSGlobs *globs, const char *APath, int Mode, int *Error) { *Error = cVFS_Not_Supported; return (TVFSFileDes)0; } TVFSResult VFSCloseFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor) { return cVFS_Not_Supported; } u_int64_t VFSFileSeek(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, u_int64_t AbsoluteOffset, int *Error) { *Error = cVFS_Not_Supported; return 0; } int VFSReadFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buffer, int ABlockSize, int *Error) { *Error = cVFS_Not_Supported; return 0; } int VFSWriteFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buffer, int BytesCount, int *Error) { *Error = cVFS_Not_Supported; return 0; } void VFSSetBlockSize(struct TVFSGlobs *globs, int Value) { globs->block_size = Value; } int VFSIsOnSameFS(struct TVFSGlobs *globs, const char *Path1, const char *Path2) { printf("(II) VFSIsOnSameFS: Not supported in ZIP archives.\n"); return true; } int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path2) { printf("(II) VFSTwoSameFiles: Not supported in ZIP archives, comparing by paths.\n"); return compare_two_same_files(Path1, Path2); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////// // Known issues: - crashes when no space left on NFS mounts, probably unhandled exception in further ZipArchive code (repro: Gentoo, Ubuntu) TVFSResult VFSCopyToLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append) { gboolean try_again; if ((sSrcName == NULL) || (sDstName == NULL) || (strlen(sSrcName) < 1) || (strlen(sDstName) < 1)) { printf("(EE) VFSCopyToLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty\n"); return cVFS_Failed; } printf("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName); unsigned long int file_no = filelist_find_index_by_path(globs->files, sSrcName) - 1; if (file_no < 0) { printf("(EE) VFSCopyToLocal: can't find source file '%s'\n", sSrcName); return cVFS_ReadErr; } char *s = exclude_trailing_path_sep(sDstName); char *dest_path = extract_file_path(s); char *dest_filename = extract_file_name(s); free(s); // Perform extract try { do { try { try_again = FALSE; if (! globs->zip->ExtractFile(file_no, dest_path, false, dest_filename, globs->block_size)) { globs->zip->CloseFile(NULL, true); fprintf(stderr, "(EE) VFSCopyToLocal: Error while copying out, archive closed = %d.\n", globs->zip->IsClosed()); return cVFS_WriteErr; } fprintf(stderr, "(II) VFSCopyToLocal: copy OK, archive closed = %d.\n", globs->zip->IsClosed()); } catch (CZipException e) { globs->zip->CloseFile(NULL, true); fprintf(stderr, "(EE) VFSCopyToLocal: Error while copying out: [%d] %s, archive closed = %d.\n", e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); switch (e.m_iCause) { case CZipException::badPassword: if (globs->callback_ask_password) { char *passwd = NULL; int res = globs->callback_ask_password ("The archive is encrypted and requires password", NULL, NULL, NULL, (TVFSAskPasswordFlags)(VFS_ASK_PASSWORD_NEED_PASSWORD | VFS_ASK_PASSWORD_ARCHIVE_MODE), NULL, &passwd, NULL, NULL, NULL, globs->callback_data); if (res && passwd) { fprintf(stderr, " (II) VFSCopyToLocal: setting password to '%s'\n", passwd); globs->zip->SetPassword(passwd); try_again = TRUE; break; } else return cVFS_Cancelled; } default: return get_vfs_errorcode(e.m_iCause); } } } while (try_again); } catch (...) { fprintf(stderr, "(EE) VFSCopyToLocal: Fatal error while copying out..., archive closed = %d.\n", globs->zip->IsClosed()); return cVFS_WriteErr; } free(dest_path); free(dest_filename); return cVFS_OK; } // Known issues: - archive corruption when no space left on device // - encrypted files are unreadable after copy in TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append) { gboolean try_again; if ((sSrcName == NULL) || (sDstName == NULL) || (strlen(sSrcName) < 1) || (strlen(sDstName) < 1)) { printf("(EE) VFSCopyFromLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty\n"); return cVFS_Failed; } printf("(II) VFSCopyFromLocal: copying file '%s' in to '%s'\n", sSrcName, sDstName); try { do { try { try_again = FALSE; char *s = exclude_leading_path_sep(sDstName); if (! globs->zip->AddNewFile(sSrcName, s, -1, CZipArchive::zipsmSafeSmart, globs->block_size)) { globs->zip->CloseNewFile(true); globs->zip->CloseFile(NULL, true); build_global_filelist(globs); fprintf(stderr, "(EE) VFSCopyFromLocal: Error while copying in, archive closed = %d.\n", globs->zip->IsClosed()); return cVFS_WriteErr; } globs->zip->Flush(); printf("(II) VFSCopyFromLocal: copy OK, archive closed = %d.\n", globs->zip->IsClosed()); build_global_filelist(globs); globs->archive_modified = true; /* // Encrypt the file if archive contains any encrypted files if (globs->need_password) { unsigned long int file_no = filelist_find_index_by_path(globs->files, s) - 1; if (file_no < 0) { printf("(EE) VFSCopyFromLocal: unable to find index for newly written file '%s'\n", sSrcName); return cVFS_WriteErr; } printf("(II) VFSCopyFromLocal: Encrypting the newly written file...\n"); if (! globs->zip->EncryptFile(file_no)) printf("(EE) VFSCopyFromLocal: Unable to encrypt the newly written file\n"); } */ free(s); } catch (CZipException e) { globs->zip->CloseNewFile(true); globs->zip->CloseFile(NULL, true); build_global_filelist(globs); fprintf(stderr, "(EE) VFSCopyFromLocal: Error while copying in: [%d] %s, archive closed = %d.\n", e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); switch (e.m_iCause) { case CZipException::badPassword: if (globs->callback_ask_password) { char *passwd = NULL; int res = globs->callback_ask_password ("The archive is encrypted and requires password", NULL, NULL, NULL, (TVFSAskPasswordFlags)(VFS_ASK_PASSWORD_NEED_PASSWORD | VFS_ASK_PASSWORD_ARCHIVE_MODE), NULL, &passwd, NULL, NULL, NULL, globs->callback_data); if (res && passwd) { fprintf(stderr, " (II) VFSCopyFromLocal: setting password to '%s'\n", passwd); globs->zip->SetPassword(passwd); try_again = TRUE; break; } else return cVFS_Cancelled; } default: return get_vfs_errorcode(e.m_iCause); } } } while (try_again); } catch (...) { fprintf(stderr, "(EE) VFSCopyFromLocal: Fatal error while copying in..., archive closed = %d.\n", globs->zip->IsClosed()); return cVFS_WriteErr; } return cVFS_OK; } /////////////////////////////// // end of extern "C" } /*** * Todo: * * - UTF-8, FName/FDisplayName and absolute/relative paths revision needed! * (check http://www.artpol-software.com/ZipArchive/KB/0610051525.aspx ) * - implement an "opened" flag - is it really needed? + add tests to all functions * - readonly checking IsReadOnly() + add tests to all functions modifying the archive * - after VFS API update implement archive testing, compression level setting, retrieving compression info for each file and archive, readonly flags, begin-action, end-action (no refresh, faster operations) ... * - moving files from one directory to another within the archive * */ tuxcmd-modules-0.6.70+ds/zip/README0000644000175000017500000000302511300022650015645 0ustar salvisalviZIP plugin for Tux Commander Version: 0.5.6 Release date: 2009-Oct-25 Copyright (C) 2004-2009 Tomas Bzatek http://tuxcmd.sourceforge.net This plugin uses ZipArchive library v3.2.0 Copyright (C) 2000 - 2007 Artpol Software - Tadeusz Dracz http://www.artpol-software.com/ZipArchive/ See ZipArchive/License.txt for licensing conditions This is the ZIP archiving VFS (Virtual File System) plugin for Tux Commander file manager. It uses external ZipArchive library, which is statically linked thus no additional system libraries are required. Both plugin and the library are pretty stable for normal use at their current versions. Feature highlights: * full read/write support for ZIP archives * full support for Unix file and directory permissions * password protection support (read/write) To be implemented: * archive consistency testing (needs new VFS API) * creating archives from scratch (needs new VFS API) * compression level setting (needs new VFS API) * multidisk archives The current VFS implementation in Tux Commander lacks some extended features for both archiving and remote filesystems. This is one of the main goals for the 0.6.x series. Known issues: - Modifying password protected archive might lead to data corruption For successful compilation you will need working gcc compiler and glib2 library installed with development files. The ZipArchive library sources are included, no external files are required. Compilation has been tested with gcc compiler v4.4.2 tuxcmd-modules-0.6.70+ds/libarchive/0000755000175000017500000000000011300613427016303 5ustar salvisalvituxcmd-modules-0.6.70+ds/libarchive/libarchive.c0000644000175000017500000004744111300022650020561 0ustar salvisalvi/* libarchive plugin for Tux Commander * version 0.1.5, designed for libarchive 2.5.5 * Copyright (C) 2008 Tomas Bzatek * Check for updates on tuxcmd.sourceforge.net * * Uses libarchive library * Copyright (c) 2003-2007 Tim Kientzle * * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include "vfs_types.h" #include "vfsutils.h" #include "strutils.h" #include "treepathutils.h" #include "treepath_vfs.h" #include #include #define VERSION "0.1.5" #define BUILD_DATE "2009-10-25" #define DEFAULT_BLOCK_SIZE 65536 /******************************************************************************************************/ /** Auxiliary classes */ /************** ****************/ // Declaration of the global plugin object struct TVFSGlobs { TVFSLogFunc log_func; char *curr_dir; char *archive_path; unsigned long block_size; struct PathTree *files; struct VfsFilelistData *vfs_filelist; u_int64_t total_size; TVFSAskQuestionCallback callback_ask_question; TVFSAskPasswordCallback callback_ask_password; TVFSProgressCallback callback_progress; void *callback_data; }; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////// // Basic initialization functions struct TVFSGlobs * VFSNew (TVFSLogFunc log_func) { struct TVFSGlobs * globs; globs = (struct TVFSGlobs *) malloc (sizeof (struct TVFSGlobs)); memset (globs, 0, sizeof (struct TVFSGlobs)); globs->block_size = DEFAULT_BLOCK_SIZE; globs->callback_data = NULL; globs->callback_ask_question = NULL; globs->callback_ask_password = NULL; globs->callback_progress = NULL; globs->log_func = log_func; if (globs->log_func != NULL) globs->log_func("libarchive plugin: VFSInit"); return globs; } void VFSSetCallbacks (struct TVFSGlobs *globs, TVFSAskQuestionCallback ask_question_callback, TVFSAskPasswordCallback ask_password_callback, TVFSProgressCallback progress_func, void *data) { globs->callback_ask_question = ask_question_callback; globs->callback_ask_password = ask_password_callback; globs->callback_progress = progress_func; globs->callback_data = data; } void VFSFree (struct TVFSGlobs *globs) { if (globs->log_func != NULL) globs->log_func("libarchive plugin: VFSDestroy"); free (globs); } int VFSVersion() { return cVFSVersion; } struct TVFSInfo * VFSGetInfo() { struct TVFSInfo *module_info = g_malloc0 (sizeof (struct TVFSInfo)); module_info->ID = g_strdup ("libarchive_plugin"); module_info->Name = g_strdup ("libarchive plugin"); module_info->About = g_strdup_printf ("version %s, build date: %s\nusing %s\n", VERSION, BUILD_DATE, ARCHIVE_LIBRARY_VERSION); module_info->Copyright = g_strdup ("Plugin Copyright (C) 2008-2009 Tomáš Bžatek\nlibarchive sources Copyright (c) 2003-2007 Tim Kientzle"); return module_info; } char * VFSGetArchiveExts () { return g_strdup ("tar;tar.gz;tar.bz2;tgz;tbz2;cpio;iso;a;deb"); } /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ static TVFSResult libarchive_open(struct archive **a, const char *filename, size_t block_size) { int r; *a = archive_read_new(); // Register supported formats archive_read_support_compression_all(*a); archive_read_support_format_all(*a); /* archive_read_support_compression_bzip2(*a); archive_read_support_compression_gzip(*a); archive_read_support_compression_compress(*a); archive_read_support_compression_none(*a); archive_read_support_format_tar(*a); archive_read_support_format_cpio(*a); archive_read_support_format_ar(*a); archive_read_support_format_empty(*a); archive_read_support_format_gnutar(*a); archive_read_support_format_iso9660(*a); archive_read_support_format_cpio(*a); */ r = archive_read_open_file(*a, filename, block_size); if (r) { fprintf(stderr, "(EE) libarchive_open: error occured when opening archive: %s\n", archive_error_string(*a)); return cVFS_Failed; } return cVFS_OK; } TVFSResult VFSOpenArchive(struct TVFSGlobs *globs, char *sName) { globs->files = filelist_tree_new(); globs->vfs_filelist = vfs_filelist_new(globs->files); globs->curr_dir = NULL; globs->archive_path = strdup(sName); globs->total_size = 0; fprintf(stderr, "(--) VFSOpenArchive: trying to open archive '%s'...\n", globs->archive_path); TVFSResult Result; struct archive *a; struct archive_entry *entry; int r; Result = libarchive_open(&a, globs->archive_path, globs->block_size); if (Result == cVFS_OK) { for (;;) { entry = NULL; r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) { break; } else if (r == ARCHIVE_WARN) { log("(WW) VFSOpenArchive: file '%s' - libarchive warning: '%s'\n", archive_entry_pathname(entry), archive_error_string(a)); } else if (r != ARCHIVE_OK) { fprintf(stderr, "(EE) VFSOpenArchive: error occured while reading archive: '%s'\n", archive_error_string(a)); Result = cVFS_Failed; break; } log("found file: %s, mode = %x\n", archive_entry_pathname(entry), archive_entry_mode(entry)); // Create a TVFSItem entry and fill all info struct TVFSItem *item = (struct TVFSItem*)malloc(sizeof(struct TVFSItem)); memset(item, 0, sizeof(struct TVFSItem)); item->iSize = (int64_t)archive_entry_size(entry); item->iPackedSize = -1; /* no support */ globs->total_size += item->iSize; mode_t mode = archive_entry_mode(entry); item->iMode = archive_entry_mode(entry); if (S_ISREG(mode)) item->ItemType = vRegular; else if (S_ISDIR(mode)) item->ItemType = vDirectory; else if (S_ISCHR(mode)) item->ItemType = vChardev; else if (S_ISBLK(mode)) item->ItemType = vBlockdev; else if (S_ISFIFO(mode)) item->ItemType = vFifo; else if (S_ISLNK(mode)) item->ItemType = vSymlink; else if (S_ISSOCK(mode)) item->ItemType = vSock; if (item->ItemType == vSymlink) item->sLinkTo = strdup(archive_entry_symlink(entry)); item->iUID = geteuid(); item->iGID = getegid(); item->m_time = archive_entry_mtime(entry); item->c_time = archive_entry_ctime(entry); item->a_time = archive_entry_atime(entry); char *s; if (g_utf8_validate (archive_entry_pathname(entry), -1, NULL)) s = g_strdup (archive_entry_pathname(entry)); else { if (archive_entry_pathname_w(entry)) s = wide_to_utf8 (archive_entry_pathname_w(entry)); else s = g_filename_display_name (archive_entry_pathname(entry)); } // g_print("file = '%s', wide = '%ls'\n", archive_entry_pathname(entry), archive_entry_pathname_w(entry)); // Add item to the global list and continue with next file filelist_tree_add_item(globs->files, s, archive_entry_pathname(entry), item, 0); g_free (s); } archive_read_close(a); } archive_read_finish(a); fprintf(stderr, "(II) VFSOpenArchive: done. \n"); /* FIXME: temporarily disabled */ // filelist_tree_resolve_symlinks(globs->files); printf("\n\nList of items:\n"); filelist_tree_print(globs->files); return Result; } TVFSResult VFSClose(struct TVFSGlobs *globs) { if (globs) { fprintf(stderr, "(II) VFSClose: Freeing objects...\n"); if (globs->vfs_filelist) vfs_filelist_free(globs->vfs_filelist); if (globs->files) filelist_tree_free(globs->files); if (globs->archive_path) free(globs->archive_path); if (globs->curr_dir) free(globs->curr_dir); } return cVFS_OK; } char * VFSGetPath (struct TVFSGlobs *globs) { return include_trailing_path_sep (globs->curr_dir); } u_int64_t VFSGetFileSystemFree(struct TVFSGlobs *globs, char *APath) { return 0; } u_int64_t VFSGetFileSystemSize(struct TVFSGlobs *globs, char *APath) { return globs->total_size; } /******************************************************************************************************/ TVFSResult VFSChangeDir(struct TVFSGlobs *globs, char *NewPath) { if (NewPath == NULL) { printf("(EE) VFSChangeDir: NewPath is NULL!\n"); return cVFS_Failed; } globs->curr_dir = vfs_filelist_change_dir(globs->vfs_filelist, NewPath); if (globs->curr_dir) return cVFS_OK; else return cVFS_Failed; } int VFSGetPasswordRequired(struct TVFSGlobs *globs) { return FALSE; } /******************************************************************************************************/ TVFSResult VFSListFirst(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) { if (sDir == NULL) { printf("(EE) VFSListFirst: sDir is NULL!\n"); return cVFS_Failed; } printf ("(--) VFSListFirst: Going to list all items in '%s'\n", sDir); return vfs_filelist_list_first(globs->vfs_filelist, sDir, Item); } TVFSResult VFSListNext(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) { return vfs_filelist_list_next(globs->vfs_filelist, sDir, Item); } TVFSResult VFSListClose(struct TVFSGlobs *globs) { return vfs_filelist_list_close(globs->vfs_filelist); } /******************************************************************************************************/ long VFSFileExists(struct TVFSGlobs *globs, const char *FileName, const long Use_lstat) { if (! globs) return FALSE; return vfs_filelist_file_exists(globs->vfs_filelist, FileName, Use_lstat); } TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item) { printf("(--) VFSFileInfo: requested info for object '%s'\n", AFileName); if (!globs) return cVFS_Failed; return vfs_filelist_file_info(globs->vfs_filelist, AFileName, Item); } /******************************************************************************************************/ /** Recursive tree size counting */ /************** ****************/ u_int64_t VFSGetDirSize(struct TVFSGlobs *globs, char *APath) { if (! globs) return 0; return vfs_filelist_get_dir_size(globs->vfs_filelist, APath); } void VFSBreakGetDirSize(struct TVFSGlobs *globs) { printf("(WW) VFSBreakGetDirSize: calling break\n"); if (globs) vfs_filelist_get_dir_size_break(globs->vfs_filelist); } /******************************************************************************************************/ /** Methods modifying the archive */ /************** ****************/ TVFSResult VFSMkDir(struct TVFSGlobs *globs, const char *sDirName) { printf("(WW) VFSMkDir: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } TVFSResult VFSRemove(struct TVFSGlobs *globs, const char *APath) { printf("(WW) VFSRemove: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } TVFSResult VFSRename(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName) { printf("(WW) VFSRename: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } TVFSResult VFSMakeSymLink(struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo) { printf("(WW) VFSMakeSymLink: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } TVFSResult VFSChmod(struct TVFSGlobs *globs, const char *FileName, const uint Mode) { printf("(WW) VFSChmod: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } TVFSResult VFSChown(struct TVFSGlobs *globs, const char *FileName, const uint UID, const uint GID) { printf("(WW) VFSChown: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } TVFSResult VFSChangeTimes(struct TVFSGlobs *globs, char *APath, long mtime, long atime) { printf("(WW) VFSChangeTimes: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////// TVFSFileDes VFSOpenFile(struct TVFSGlobs *globs, const char *APath, int Mode, int *Error) { *Error = cVFS_Not_Supported; return (TVFSFileDes)0; } TVFSResult VFSCloseFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor) { return cVFS_Not_Supported; } u_int64_t VFSFileSeek(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, u_int64_t AbsoluteOffset, int *Error) { *Error = cVFS_Not_Supported; return 0; } int VFSReadFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buffer, int ABlockSize, int *Error) { *Error = cVFS_Not_Supported; return 0; } int VFSWriteFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buffer, int BytesCount, int *Error) { *Error = cVFS_Not_Supported; return 0; } void VFSSetBlockSize(struct TVFSGlobs *globs, int Value) { globs->block_size = Value; } int VFSIsOnSameFS(struct TVFSGlobs *globs, const char *Path1, const char *Path2) { printf("(WW) VFSIsOnSameFS: Not supported in libarchive plugin.\n"); return TRUE; } int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path2) { printf("(WW) VFSTwoSameFiles: Not supported in libarchive, comparing by paths.\n"); return compare_two_same_files(Path1, Path2); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////// /** * The following code has been stolen from archive_read_data_into_fd.c (libarchive sources) and modified to allow progress callbacks * Quote: "This implementation minimizes copying of data and is sparse-file aware." **/ static TVFSResult my_archive_read_data_into_fd(struct TVFSGlobs *globs, struct archive *a, struct archive_entry *entry, const char *sDstName, size_t max_block, int Append) { int r; int fd; const void *buff; size_t size, bytes_to_write; ssize_t bytes_written, total_written; off_t offset; off_t output_offset; u_int64_t file_size; gboolean cancel = FALSE; printf("(II) my_archive_read_data_into_fd: extracting to '%s', Append = %d\n", sDstName, Append); if (Append) fd = open(sDstName, O_APPEND | O_WRONLY); else fd = open(sDstName, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) { fprintf(stderr, "(EE) my_archive_read_data_into_fd: error occured while extracting data: %s\n", strerror(errno)); return cVFS_Failed; } total_written = 0; output_offset = 0; file_size = (u_int64_t)archive_entry_size(entry); while ((r = archive_read_data_block(a, &buff, &size, &offset)) == ARCHIVE_OK) { const char *p = buff; if (offset > output_offset) { lseek(fd, offset - output_offset, SEEK_CUR); output_offset = offset; } while (size > 0) { if (cancel) break; bytes_to_write = size; if (bytes_to_write > max_block) bytes_to_write = max_block; bytes_written = write(fd, p, bytes_to_write); if (bytes_written < 0) { fprintf(stderr, "(EE) my_archive_read_data_into_fd: error occured while extracting data: %s\n", strerror(errno)); return cVFS_Failed; } output_offset += bytes_written; total_written += bytes_written; p += bytes_written; size -= bytes_written; log(" (II) my_archive_read_data_into_fd: bytes_written = %zd, total_written = %zd\n", bytes_written, total_written); if (globs->callback_progress) { if (! globs->callback_progress(total_written, file_size, globs->callback_data)) { cancel = TRUE; break; } // usleep(100000); } } } if ((close(fd)) || ((r != ARCHIVE_OK) && (r != ARCHIVE_EOF))) { fprintf(stderr, "(EE) my_archive_read_data_into_fd: error closing extracted file: %s\n", strerror(errno)); return cVFS_WriteErr; } if (cancel) { if (unlink(sDstName)) fprintf(stderr, "(EE) my_archive_read_data_into_fd: error unlinking cancelled extraction: %s\n", strerror(errno)); return cVFS_Cancelled; } printf("(II) my_archive_read_data_into_fd: done.\n"); return cVFS_OK; } TVFSResult VFSCopyToLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append) { if ((sSrcName == NULL) || (sDstName == NULL) || (strlen(sSrcName) < 1) || (strlen(sDstName) < 1)) { printf("(EE) VFSCopyToLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty\n"); return cVFS_Failed; } printf("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName); struct PathTree *node = filelist_tree_find_node_by_path(globs->files, sSrcName); if (! node) { fprintf(stderr, "(EE) VFSCopyToLocal: cannot find file '%s'\n", sSrcName); return cVFS_ReadErr; } const char *src = node->original_pathstr; if (! src) { fprintf(stderr, "(WW) VFSCopyToLocal: cannot determine original filename\n"); src = sSrcName; } printf("(II) VFSCopyToLocal: new src path: '%s'\n", src); TVFSResult Result; struct archive *a; struct archive_entry *entry; int r; gboolean found = FALSE; Result = libarchive_open(&a, globs->archive_path, globs->block_size); if (Result == cVFS_OK) { for (;;) { entry = NULL; r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) { break; } else if (r == ARCHIVE_WARN) { log("(WW) VFSOpen: file '%s' - libarchive warning: '%s'\n", archive_entry_pathname(entry), archive_error_string(a)); } else if (r != ARCHIVE_OK) { fprintf(stderr, "(EE) VFSCopyToLocal: error occured while reading archive: '%s'\n", archive_error_string(a)); Result = cVFS_Failed; break; } // printf ("found file: %s, mode = %x\n", archive_entry_pathname(entry), archive_entry_mode(entry)); const char *ssrc = src; const char *asrc = archive_entry_pathname(entry); if (IS_DIR_SEP(*ssrc)) ssrc++; if (IS_DIR_SEP(*asrc)) asrc++; // printf ("strcmp: '%s' vs. '%s'\n", ssrc, asrc); if (strcmp(ssrc, asrc) == 0) { // printf("--> found file, extracting\n"); fprintf(stderr, "(II) VFSCopyToLocal: extract_file_path(sDstName) = '%s', extract_file_name(sDstName) = '%s' \n", extract_file_path(sDstName), extract_file_name(sDstName)); found = TRUE; Result = my_archive_read_data_into_fd(globs, a, entry, sDstName, globs->block_size, Append); break; } } archive_read_close(a); } archive_read_finish(a); if ((! found) && Result == cVFS_OK) { fprintf(stderr, "(EE) VFSCopyToLocal: file not found in archive.\n"); Result = cVFS_ReadErr; } fprintf(stderr, "(II) VFSCopyToLocal: finished. \n"); return Result; } TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append) { printf("(WW) VFSCopyFromLocal: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } /********** * TODO: * * - UTF-8, FName/FDisplayName and absolute/relative paths revision needed! * - archive testing (needs new VFS API) * - write support * - support creating new archives (needs new VFS API) * ***/ tuxcmd-modules-0.6.70+ds/libarchive/vfs_types.h0000777000175000017500000000000011300603570024367 2../common/vfs_types.hustar salvisalvituxcmd-modules-0.6.70+ds/libarchive/strutils.h0000777000175000017500000000000011300603570024105 2../common/strutils.hustar salvisalvituxcmd-modules-0.6.70+ds/libarchive/treepathutils.h0000777000175000017500000000000011300603570026115 2../common/treepathutils.hustar salvisalvituxcmd-modules-0.6.70+ds/libarchive/treepath_vfs.h0000777000175000017500000000000011300603570025507 2../common/treepath_vfs.hustar salvisalvituxcmd-modules-0.6.70+ds/libarchive/COPYING0000644000175000017500000004310311300022650017327 0ustar salvisalvi GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. tuxcmd-modules-0.6.70+ds/libarchive/vfsutils.h0000777000175000017500000000000011300603570024061 2../common/vfsutils.hustar salvisalvituxcmd-modules-0.6.70+ds/libarchive/treepathutils.c0000777000175000017500000000000011300603570026103 2../common/treepathutils.custar salvisalvituxcmd-modules-0.6.70+ds/libarchive/strutils.c0000777000175000017500000000000011300603570024073 2../common/strutils.custar salvisalvituxcmd-modules-0.6.70+ds/libarchive/Makefile0000644000175000017500000000362111300613427017745 0ustar salvisalvi# path definitions DESTDIR = /usr INSTALL=install -c INSTALL_DATA = ${INSTALL} -m 644 DIR_COMMON=../common/ DIR_LIBARCHIVE=./libarchive-2.5.5 # compiler options CC = gcc CPP = g++ CFLAGS =-I. -I/usr/include -I$(DIR_COMMON) \ -Wall -fPIC -O2 -g \ -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \ -D__VERBOSE_DEBUGx LIB_SUFFIX=`if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi` VFS_COMMON_OBJECTS=strutils.o treepathutils.o treepath_vfs.o vfsutils.o VFS_OBJECTS=libarchive.o .SUFFIXES: .c .cpp .c.o: $(CC) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $< .cpp.o: $(CPP) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $< all: static shared: $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS) $(CC) -shared -o libarchive_plugin.so $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS) $(CFLAGS) `pkg-config glib-2.0 --libs` -larchive -lz -lbz2 static: CFLAGS += -I$(DIR_LIBARCHIVE)/libarchive static: lib_libarchive_compile $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS) $(CC) -shared -o libarchive_plugin.so $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS) $(DIR_LIBARCHIVE)/.libs/libarchive.a $(CFLAGS) `pkg-config glib-2.0 --libs` -lz -lbz2 lib_libarchive_compile: @which uudecode > /dev/null || exit 1; @if test ! -f "$(DIR_LIBARCHIVE)/.libs/libarchive.a"; then \ echo "Building libarchive..."; echo; \ (cd "$(DIR_LIBARCHIVE)" && ./configure --enable-static --disable-shared --disable-bsdtar --disable-bsdcpio --with-pic && $(MAKE)) || exit 1; \ echo; echo "Libarchive build successful"; echo; \ fi; strutils.o: strutils.c strutils.h treepathutils.o: treepathutils.c treepathutils.h vfsutils.o: vfsutils.c vfsutils.h treepath_vfs.o: treepath_vfs.c treepath_vfs.h install:: $(INSTALL) ./libarchive_plugin.so $(DESTDIR)/lib$(LIB_SUFFIX)/tuxcmd/ clean: rm -f *.o *.d *.gch libarchive_plugin.so @if test -e $(DIR_LIBARCHIVE)/Makefile; then \ (cd "$(DIR_LIBARCHIVE)" && $(MAKE) clean) \ fi; tuxcmd-modules-0.6.70+ds/libarchive/treepath_vfs.c0000777000175000017500000000000011300603570025475 2../common/treepath_vfs.custar salvisalvituxcmd-modules-0.6.70+ds/libarchive/vfsutils.c0000777000175000017500000000000011300603570024047 2../common/vfsutils.custar salvisalvituxcmd-modules-0.6.70+ds/libarchive/README0000644000175000017500000000307511300022650017160 0ustar salvisalvilibarchive plugin for Tux Commander Version: 0.1.5 Release date: 2009-Oct-25 Copyright (C) 2008-2009 Tomas Bzatek http://tuxcmd.sourceforge.net This plugin uses libarchive library v2.5.5 Copyright (c) 2003-2007 Tim Kientzle http://people.freebsd.org/~kientzle/libarchive/ See libarchive-2.5.5/COPYING for licensing conditions This is the libarchive archiving VFS (Virtual File System) plugin for Tux Commander file manager. Uses libarchive library, providing access and routines for manipulation with the archives. By default, Tux Commander binary package comes with statically linked libarchive plugin, not requiring any libraries other than zlib and bzip2, which are pretty standard in modern linux distributions. Feature highlights: * read-only support for TAR, TAR.GZ, TAR.BZ2, ISO9660, CPIO, A (ar), DEB archives * full support for Unix file and directory permissions * large files (> 4GB) support * correctly handles sparse files To be implemented: * archive consistency testing (needs new VFS API) * write support (probably creating new archives only) Requirements: - system zlib and bzip2 libraries Static compilation (default): - requires uudecode utility (sharutils package) - "make static" - libz and libbz2 are still linked dynamically - libarchive sources are included in plugin source tree, no need for any external files Shared library compilation: - requires libarchive library installed on your system - "make shared" Compilation has been tested with gcc compiler version 4.4.2 tuxcmd-modules-0.6.70+ds/common/0000755000175000017500000000000011300022650015453 5ustar salvisalvituxcmd-modules-0.6.70+ds/common/vfs_types.h0000644000175000017500000001120311300022650017643 0ustar salvisalvi/* Tux Commander VFS: Virtual File System types and definitions * - prototypes functions and types * draft version 3 * * Copyright (C) 2003 Radek Cervinka * Copyright (C) 2008 Tomas Bzatek * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __VFS_TYPES_H__ #define __VFS_TYPES_H__ #include #include #include typedef int TVFSResult; /* Compatible with gio/GAskPasswordFlags */ typedef enum { VFS_ASK_PASSWORD_NEED_PASSWORD = 1<<0, VFS_ASK_PASSWORD_NEED_USERNAME = 1<<1, VFS_ASK_PASSWORD_NEED_DOMAIN = 1<<2, VFS_ASK_PASSWORD_SAVING_SUPPORTED = 1<<3, VFS_ASK_PASSWORD_ANONYMOUS_SUPPORTED = 1<<4, VFS_ASK_PASSWORD_SAVE_INTERNAL = 1<<14, VFS_ASK_PASSWORD_ARCHIVE_MODE = 1<<15 } TVFSAskPasswordFlags; /* Compatible with gio/GPasswordSave */ typedef enum { VFS_PASSWORD_SAVE_NEVER, VFS_PASSWORD_SAVE_FOR_SESSION, VFS_PASSWORD_SAVE_PERMANENTLY } TVFSPasswordSave; typedef void (* TVFSLogFunc)(const char *s); typedef void *TVFSFileDes; /* Return FALSE to break the operation */ typedef int (* TVFSProgressCallback) (u_int64_t position, u_int64_t max, void *user_data); /* Return index of the choice selected or negative number when dialog has been cancelled */ typedef void (* TVFSAskQuestionCallback) (const char *message, const char **choices, int *choice, int cancel_choice, void *user_data); typedef int (* TVFSAskPasswordCallback) (const char *message, const char *default_user, const char *default_domain, const char *default_password, TVFSAskPasswordFlags flags, char **username, char **password, int *anonymous, char **domain, TVFSPasswordSave *password_save, void *user_data); static const int cVFSVersion = 5; // current version of the VFS API // Capabilities static const int capVFS_nil = 0; static const int capVFS_List = 1 << 0; static const int capVFS_CopyOut = 1 << 1; static const int capVFS_CopyIn = 1 << 2; static const int capVFS_MkDir = 1 << 3; static const int capVFS_RmDir = 1 << 4; static const int capVFS_Multiple = 1 << 5; // support multiple files = background copy & thread safe static const int capVFS_Delete = 1 << 6; static const int capVFS_Rename = 1 << 7; static const int capVFS_Execute = 1 << 8; static const int capVFS_Append = 1 << 9; // Error codes (TVFSResult) enum { cVFS_OK = 0, cVFS_Failed = 1, // also No such file cVFS_Cancelled = 2, cVFS_Not_Supported = 3, cVFS_No_More_Files = 4, cVFS_ReadErr = 5, cVFS_WriteErr = 6, // also Readonly FileSystem cVFS_LoginFailed = 7, cVFS_PermissionDenied = 8, cVFS_NoSpaceLeft = 9, cVFS_mallocFailed = 10, cVFS_BadPassword = 11, cVFS_MissingVolume = 12, cVFS_CorruptedArchive = 13 }; // Open modes enum { cVFS_OpenRead, cVFS_OpenWrite, cVFS_OpenAppend }; // Item Type enum enum TVFSItemType { vRegular = 0, vSymlink = 1, vChardev = 2, vBlockdev = 3, vDirectory = 4, vFifo = 5, vSock = 6, vOther = 7 }; struct TVFSItem { char *FName; char *FDisplayName; // valid UTF-8 string int64_t iSize; int64_t iPackedSize; // set to -1 if plugin doesn't support this feature __time_t m_time; // numbers should be located before the other variables (bug?) __time_t a_time; __time_t c_time; __mode_t iMode; char *sLinkTo; __uid_t iUID; __gid_t iGID; enum TVFSItemType ItemType; }; struct TVFSInfo { char *ID; // unique identifier, not shown in GUI char *Name; // plugin name, GUI string (UTF-8) char *About; // GUI string (UTF-8) char *Copyright; // GUI string (UTF-8) }; #endif /* __VFS_TYPES_H__ */ tuxcmd-modules-0.6.70+ds/common/strutils.h0000644000175000017500000000323311300022650017516 0ustar salvisalvi/* Tux Commander VFS: String utilities * Copyright (C) 2007 Tomas Bzatek * Check for updates on tuxcmd.sourceforge.net * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __STRUTILS_H__ #define __STRUTILS_H__ #include #include #ifdef __VERBOSE_DEBUG #define log(msg...) printf(msg) #else #define log(msg...) { } #endif #define IS_DIR_SEP(ch) ((ch) == '/') // path manipulating functions, all return newly allocated string, you can then free them as you want char* include_trailing_path_sep(const char *APath); char* exclude_trailing_path_sep(const char *APath); char* include_leading_path_sep(const char *APath); char* exclude_leading_path_sep(const char *APath); char* extract_file_name(const char *APath); char* extract_file_path(const char *APath); char* resolve_relative(const char *source, const char *point_to); char* canonicalize_filename(const char *filename); char* wide_to_utf8(const wchar_t *src); #endif /* __STRUTILS_H__ */ tuxcmd-modules-0.6.70+ds/common/treepathutils.h0000644000175000017500000000366111300022650020527 0ustar salvisalvi/* Tux Commander VFS: String utilities * Copyright (C) 2007-2008 Tomas Bzatek * Check for updates on tuxcmd.sourceforge.net * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __TREEPATHUTILS_H__ #define __TREEPATHUTILS_H__ #include #include #include #include "vfs_types.h" struct PathTree { GPtrArray* items; struct TVFSItem *data; unsigned long index; char *node; char *original_pathstr; }; struct PathTree* filelist_tree_new(); void filelist_tree_free(struct PathTree *tree); void filelist_tree_print(struct PathTree *tree); /* Symlink resolving: strongly discouraged to use at the present state of art. * We would have to implement full symlink system, do loop checking etc. */ void filelist_tree_resolve_symlinks(struct PathTree *tree); gboolean filelist_tree_add_item(struct PathTree *tree, const char *path, const char *original_pathstr, struct TVFSItem *item, unsigned long index); struct PathTree* filelist_tree_find_node_by_path(struct PathTree *tree, const char *path); unsigned long int filelist_find_index_by_path(struct PathTree *tree, const char *path); struct PathTree* filelist_tree_get_item_by_index(struct PathTree *tree, unsigned long index); #endif /* __TREEPATHUTILS_H__ */ tuxcmd-modules-0.6.70+ds/common/treepath_vfs.h0000644000175000017500000000414411300022650020321 0ustar salvisalvi/* Tux Commander VFS: basic tree_path routines * Copyright (C) 2007 Tomas Bzatek * Check for updates on tuxcmd.sourceforge.net * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __TREEPATH_VFS_H__ #define __TREEPATH_VFS_H__ #include #include #include #include "vfs_types.h" #include "treepathutils.h" struct VfsFilelistData { struct PathTree *files; unsigned int list_dir_index; struct PathTree *list_dir_node; gboolean break_get_dir_size; }; struct VfsFilelistData* vfs_filelist_new(struct PathTree *files); void vfs_filelist_free(struct VfsFilelistData *data); void vfs_filelist_set_files(struct VfsFilelistData *data, struct PathTree *files); u_int64_t vfs_filelist_get_dir_size(struct VfsFilelistData *data, char *APath); void vfs_filelist_get_dir_size_break(struct VfsFilelistData *data); long vfs_filelist_file_exists(struct VfsFilelistData *data, const char *FileName, const long Use_lstat); TVFSResult vfs_filelist_file_info(struct VfsFilelistData *data, char *AFileName, struct TVFSItem *Item); TVFSResult vfs_filelist_list_first(struct VfsFilelistData *data, char *sDir, struct TVFSItem *Item); TVFSResult vfs_filelist_list_next(struct VfsFilelistData *data, char *sDir, struct TVFSItem *Item); TVFSResult vfs_filelist_list_close(struct VfsFilelistData *data); char* vfs_filelist_change_dir(struct VfsFilelistData *data, char *NewPath); #endif /* __TREEPATH_VFS_H__ */ tuxcmd-modules-0.6.70+ds/common/vfsutils.h0000644000175000017500000000227711300022650017513 0ustar salvisalvi/* Tux Commander VFS: String utilities * Copyright (C) 2007 Tomas Bzatek * Check for updates on tuxcmd.sourceforge.net * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __VFSUTILS_H__ #define __VFSUTILS_H__ #include #include #include #include "vfs_types.h" void copy_vfs_item(struct TVFSItem *src, struct TVFSItem *dst); void free_vfs_item(struct TVFSItem *item); int compare_two_same_files(const char *Path1, const char *Path2); #endif /* __VFSUTILS_H__ */ tuxcmd-modules-0.6.70+ds/common/treepathutils.c0000644000175000017500000003010411300022650020512 0ustar salvisalvi/* Tux Commander VFS: String utilities * Copyright (C) 2007-2008 Tomas Bzatek * Check for updates on tuxcmd.sourceforge.net * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include "treepathutils.h" #include "strutils.h" #include "vfsutils.h" struct PathTree* filelist_tree_new() { struct PathTree *tree = (struct PathTree*)malloc(sizeof(struct PathTree)); memset(tree, 0, sizeof(struct PathTree)); log("filelist_tree_new()\n"); tree->items = g_ptr_array_new(); tree->data = NULL; tree->index = 0; tree->node = strdup("/"); tree->original_pathstr = NULL; // create placeholder data tree->data = (struct TVFSItem*)malloc(sizeof(struct TVFSItem)); memset(tree->data, 0, sizeof(struct TVFSItem)); tree->data->FName = strdup(tree->node); tree->data->FDisplayName = strdup(tree->node); tree->data->ItemType = vDirectory; tree->data->iMode = S_IRWXO + S_IRWXG + S_IRWXU; tree->data->iUID = geteuid(); tree->data->iGID = getegid(); tree->data->m_time = time(NULL); tree->data->c_time = tree->data->m_time; tree->data->a_time = tree->data->m_time; return tree; } void filelist_tree_free(struct PathTree *tree) { if (! tree) { fprintf(stderr, "filelist_tree_free: tree == NULL !\n"); return; } if (tree) { if ((tree->items) && (tree->items->len > 0)) { unsigned int i; for (i = 0; i < tree->items->len; i++) filelist_tree_free((struct PathTree*)g_ptr_array_index(tree->items, i)); } if (tree->items) g_ptr_array_free(tree->items, TRUE); if (tree->data) { if (tree->data->FName) free(tree->data->FName); if (tree->data->FDisplayName) free(tree->data->FDisplayName); if (tree->data->sLinkTo) free(tree->data->sLinkTo); free(tree->data); } if (tree->node) free(tree->node); if (tree->original_pathstr) free(tree->original_pathstr); free(tree); } } void filelist_tree_print_recurr(struct PathTree *tree, int level) { if (tree) { char *fill = g_strnfill(level * 2, 32); printf(" %s#%lu. \"%s\"\n", fill, tree->index, tree->node); if ((tree->items) && (tree->items->len > 0)) { unsigned int i; for (i = 0; i < tree->items->len; i++) { struct PathTree* t = (struct PathTree*)g_ptr_array_index(tree->items, i); filelist_tree_print_recurr(t, level + 1); } } g_free(fill); } } void filelist_tree_print(struct PathTree *tree) { filelist_tree_print_recurr(tree, 0); } struct PathTree* filelist_tree_find_node_by_path(struct PathTree *tree, const char *path) { // remove leading './' if (strstr(path, "./") == path) path += 2; // remove leading and trailing '/' if present char *p; if (IS_DIR_SEP(*path)) p = exclude_trailing_path_sep(path + 1); else p = exclude_trailing_path_sep(path); log(" filelist_tree_find_node_by_path: path = '%s', p = '%s'\n", path, p); // log("xx: '%s', '%s'\n", tree->node, path); struct PathTree* node = NULL; if ((tree) && (tree->node) && (strcmp(tree->node, "/") == 0) && (strcmp(path, "/") == 0)) { log(" filelist_tree_find_node_by_path: matched root '/' element, returning.\n"); node = tree; } else if ((tree) && (tree->items) && (tree->items->len > 0)) { // split path char *pos = strstr(p, "/"); char *first_part; char *last_part; if (pos) { first_part = strndup(p, pos - p); if (strlen(pos + 1) > 0) last_part = strdup(pos + 1); else last_part = NULL; } else { first_part = strdup(p); last_part = NULL; } log(" filelist_tree_find_node_by_path: pos = '%s'\n", pos); log(" filelist_tree_find_node_by_path: first_part = '%s'\n", first_part); log(" filelist_tree_find_node_by_path: last_part = '%s'\n", last_part); // find existing node unsigned int i; for (i = 0; i < tree->items->len; i++) { struct PathTree* t = (struct PathTree*)g_ptr_array_index(tree->items, i); if (strcmp(t->node, first_part) == 0) { // this is the final station if (! last_part) { node = t; log(" filelist_tree_find_node_by_path: found final node '%s', returning.\n", t->node); } else // recurse to child items if ((t->items) && (last_part)) { log(" filelist_tree_find_node_by_path: found node '%s', recursing in deep.\n", t->node); node = filelist_tree_find_node_by_path(t, last_part); } else { // item found but no subitems log(" filelist_tree_find_node_by_path: found node '%s', but no subitems found.\n", t->node); } break; } } free(first_part); free(last_part); } free(p); return node; } unsigned long int filelist_find_index_by_path(struct PathTree *tree, const char *path) { struct PathTree* node = filelist_tree_find_node_by_path(tree, path); if (node) return node->index; else return 0; } void filelist_tree_add_item_recurr(struct PathTree *tree, const char *path, const char *original_pathstr, struct TVFSItem *item, unsigned long index) { const char *pos = strstr(path, "/"); char *first_part; char *last_part; if (pos) { first_part = strndup(path, pos - path); if (strlen(pos + 1) > 0) last_part = strdup(pos + 1); else last_part = NULL; } else { first_part = strdup(path); last_part = NULL; } log(" filelist_tree_add_item_recur: pos = '%s'\n", pos); log(" filelist_tree_add_item_recur: first_part = '%s'\n", first_part); log(" filelist_tree_add_item_recur: last_part = '%s'\n", last_part); if (! last_part) { // final destination, create new item here log(" filelist_tree_add_item_recur: creating new item here.\n"); struct PathTree *t = (struct PathTree*)malloc(sizeof(struct PathTree)); memset(t, 0, sizeof(struct PathTree)); t->items = NULL; t->data = item; t->index = index; t->node = strdup(path); if (original_pathstr) t->original_pathstr = strdup(original_pathstr); if (t->data) t->data->FName = strdup(path); if (t->data) t->data->FDisplayName = strdup(path); // create new list of subitems and add new item if (! tree->items) tree->items = g_ptr_array_new(); g_ptr_array_add(tree->items, t); } else { // find parent node or create new one if doesn't exist log(" filelist_tree_add_item_recur: node '%s', path '%s'\n", tree->node, path); if (! tree->items) tree->items = g_ptr_array_new(); struct PathTree *node = NULL; if (tree->items->len > 0) { unsigned int i; for (i = 0; i < tree->items->len; i++) { struct PathTree* t = (struct PathTree*)g_ptr_array_index(tree->items, i); if (strcmp(t->node, first_part) == 0) { log(" filelist_tree_add_item_recur: found node '%s'\n", t->node); node = t; break; } } } // create new path holder node if (! node) { log(" filelist_tree_add_item_recur: parent node not found, creating new path holder\n"); node = (struct PathTree*)malloc(sizeof(struct PathTree)); memset(node, 0, sizeof(struct PathTree)); node->items = g_ptr_array_new(); node->index = 0; node->node = strdup(first_part); node->original_pathstr = NULL; // create placeholder data node->data = (struct TVFSItem*)malloc(sizeof(struct TVFSItem)); memset(node->data, 0, sizeof(struct TVFSItem)); node->data->FName = strdup(node->node); node->data->FDisplayName = strdup(node->node); node->data->ItemType = vDirectory; node->data->iMode = S_IRWXO + S_IRWXG + S_IRWXU; node->data->iUID = geteuid(); node->data->iGID = getegid(); node->data->m_time = time(NULL); node->data->c_time = node->data->m_time; node->data->a_time = node->data->m_time; g_ptr_array_add(tree->items, node); } // and recurse one level deeper filelist_tree_add_item_recurr(node, last_part, original_pathstr, item, index); } free(first_part); free(last_part); } gboolean filelist_tree_add_item(struct PathTree *tree, const char *path, const char *original_pathstr, struct TVFSItem *item, unsigned long index) { if (! tree) { fprintf(stderr, "filelist_tree_add_item: tree == NULL !\n"); return FALSE; } if (! path) { fprintf(stderr, "filelist_tree_add_item: path == NULL !\n"); return FALSE; } if ((strcmp(path, "/") == 0) || (strcmp(path, ".") == 0) || (strcmp(path, "..") == 0) || (strcmp(path, "./") == 0)) { fprintf(stderr, "filelist_tree_add_item: path '%s' is not a valid path\n", path); return FALSE; } // remove leading './' if (strstr(path, "./") == path) path += 2; // remove leading and trailing '/' if present char *p; if (IS_DIR_SEP(*path)) p = exclude_trailing_path_sep(path + 1); else p = exclude_trailing_path_sep(path); log(" filelist_tree_add_item: p = '%s'\n", p); char *pp; pp = canonicalize_filename (p); if (! pp) pp = strdup (p); struct PathTree* found = filelist_tree_find_node_by_path(tree, pp); if (found) { // replace old data with current ones (record might have been created automatically during path building) log(" filelist_tree_add_item: found old item, replacing data\n"); found->index = index; // free old data if (found->data) free_vfs_item(found->data); found->data = item; if (found->data) found->data->FName = strdup(found->node); if (found->data) found->data->FDisplayName = strdup(found->node); } else // create new item recursively filelist_tree_add_item_recurr(tree, pp, original_pathstr, item, index); free(p); free(pp); return TRUE; } struct PathTree* filelist_tree_get_item_by_index(struct PathTree *tree, unsigned long index) { struct PathTree* t = NULL; if ((tree) && (tree->items) && (tree->items->len > index)) { t = (struct PathTree*)g_ptr_array_index(tree->items, index); } return t; } void filelist_tree_resolve_symlinks_recurr(struct PathTree *tree, struct PathTree *root_tree, const char *path) { if (tree) { if ((tree->items) && (tree->items->len > 0)) { unsigned int i; for (i = 0; i < tree->items->len; i++) { struct PathTree* t = (struct PathTree*)g_ptr_array_index(tree->items, i); gchar *new_path; if ((t) && (t->data) && (t->data->ItemType == vSymlink) && (t->data->sLinkTo)) { log("filelist_tree_resolve_symlinks: found '%s/%s' --> '%s'\n", path, t->node, t->data->sLinkTo); gchar *rel = resolve_relative(path, t->data->sLinkTo); log(" filelist_tree_resolve_symlinks: relative = '%s'\n", rel); if (rel) { struct PathTree* link_t = filelist_tree_find_node_by_path(root_tree, rel); if ((link_t) && (link_t->data)) { /* WARNING: this is dangerous since we're destroying the symlink type */ // t->data->ItemType = link_t->data->ItemType; t->data->a_time = link_t->data->a_time; t->data->c_time = link_t->data->c_time; t->data->m_time = link_t->data->m_time; t->data->iGID = link_t->data->iGID; t->data->iUID = link_t->data->iUID; t->data->iMode = link_t->data->iMode; t->data->iSize = link_t->data->iSize; } g_free(rel); } } if ((strlen(path) == 1) && (IS_DIR_SEP(*path))) new_path = g_strconcat("/", t->node, NULL); else new_path = g_strconcat(path, "/", t->node, NULL); filelist_tree_resolve_symlinks_recurr(t, root_tree, new_path); g_free(new_path); } } } } void filelist_tree_resolve_symlinks(struct PathTree *tree) { log("filelist_tree_resolve_symlinks: begin\n"); filelist_tree_resolve_symlinks_recurr(tree, tree, "/"); log("filelist_tree_resolve_symlinks: end\n"); } tuxcmd-modules-0.6.70+ds/common/strutils.c0000644000175000017500000001531211300022650017512 0ustar salvisalvi/* Tux Commandern VFS: String utilities * Copyright (C) 2007 Tomas Bzatek * Check for updates on tuxcmd.sourceforge.net * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "strutils.h" char* include_trailing_path_sep(const char *APath) { if (APath == NULL) return NULL; char *ANewPath; // log("xxx = %s\n", (APath + strlen(APath) - 1)); if (strcmp(APath + strlen(APath) - 1, "/") != 0) { ANewPath = (char*)malloc(strlen(APath) + 2); snprintf(ANewPath, strlen(APath) + 2, "%s/", APath); } else ANewPath = strdup(APath); return ANewPath; } char* exclude_trailing_path_sep(const char *APath) { if (APath == NULL) return NULL; char *ANewPath; // log("orig = %s, len = %d, xxx = %s\n", APath, (int)strlen(APath), (APath + strlen(APath) - 1)); if ((strcmp(APath + strlen(APath) - 1, "/") == 0) && (strlen(APath) > 1)) { ANewPath = (char*)malloc(strlen(APath)); snprintf(ANewPath, strlen(APath), "%s", APath); // The number of bytes copied includes the trailing \0 } else ANewPath = strdup(APath); return ANewPath; } char* include_leading_path_sep(const char *APath) { if (APath == NULL) return NULL; char *ANewPath; // log("xxx = %s, %lu, strlen(APath) = %d, index() = %ld\n", APath, (unsigned long int)APath, (int)strlen(APath), (unsigned long int)index(APath, 0x2f)); if (index(APath, 0x2f) != APath) { ANewPath = (char*)malloc(strlen(APath) + 2); snprintf(ANewPath, strlen(APath) + 2, "/%s", APath); // The number of bytes copied includes the trailing \0 } else ANewPath = strdup(APath); return ANewPath; } char* exclude_leading_path_sep(const char* APath) { if (APath == NULL) return NULL; char *s = strdup(APath); char *ss; if (IS_DIR_SEP(*s)) ss = strdup(s + 1); else ss = strdup(s); free(s); return ss; } char* extract_file_name(const char *APath) { if (APath == NULL) return NULL; // log("xxx = %s\n", (APath + strlen(APath) - 1)); const char *file_part = rindex(APath, 0x2f); // returns NULL if not found or if the file is in the root ( / ) if (file_part == NULL) return NULL; return strdup(file_part + 1); } // Extracts file path starting with "/" and ending with "/" char* extract_file_path(const char *APath) { if (APath == NULL) return NULL; // log("xxx = %s\n", (APath + strlen(APath) - 1)); const char *file_part = rindex(APath, 0x2f); // returns NULL if not found or if the file is in the root ( / ) if (file_part == NULL) return NULL; char *ANewPath = (char*)malloc(file_part - APath + 2); snprintf(ANewPath, file_part - APath + 2, "%s", APath); return ANewPath; } // canonicalize_filename() is stolen from glib-2.16 // Copyright (C) 2006-2007 Alexander Larsson char * canonicalize_filename (const char *filename) { char *canon, *start, *p, *q; int i; canon = g_strdup (filename); start = (char *)g_path_skip_root (canon); if (start == NULL) start = canon; /* POSIX allows double slashes at the start to * mean something special (as does windows too). * So, "//" != "/", but more than two slashes * is treated as "/". */ i = 0; for (p = start - 1; (p >= canon) && G_IS_DIR_SEPARATOR (*p); p--) i++; if (i > 2) { i -= 1; start -= i; memmove (start, start+i, strlen (start+i)+1); } p = start; while (*p != 0) { if (p[0] == '.' && (p[1] == 0 || G_IS_DIR_SEPARATOR (p[1]))) { memmove (p, p+1, strlen (p+1)+1); } else if (p[0] == '.' && p[1] == '.' && (p[2] == 0 || G_IS_DIR_SEPARATOR (p[2]))) { q = p + 2; /* Skip previous separator */ p = p - 2; if (p < start) p = start; while (p > start && !G_IS_DIR_SEPARATOR (*p)) p--; if (G_IS_DIR_SEPARATOR (*p)) *p++ = G_DIR_SEPARATOR; memmove (p, q, strlen (q)+1); } else { /* Skip until next separator */ while (*p != 0 && !G_IS_DIR_SEPARATOR (*p)) p++; if (*p != 0) { /* Canonicalize one separator */ *p++ = G_DIR_SEPARATOR; } } /* Remove additional separators */ q = p; while (*q && G_IS_DIR_SEPARATOR (*q)) q++; if (p != q) memmove (p, q, strlen (q)+1); } /* Remove trailing slashes */ if (p > start && G_IS_DIR_SEPARATOR (*(p-1))) *(p-1) = 0; return canon; } char* resolve_relative(const char *source, const char *point_to) { if (source == NULL) return NULL; if (point_to == NULL) return strdup(source); if (g_path_is_absolute(point_to)) return strdup(point_to); char *rel = g_build_filename(source, point_to, NULL); log("resolve_relative: rel = '%s'\n", rel); char *canon = canonicalize_filename(rel); log("resolve_relative: canon = '%s'\n", canon); free(rel); return canon; } // Originally stolen from wine-0.9.19, utf8.c // Copyright 2000 Alexandre Julliard char* wide_to_utf8 (const wchar_t *src) { #define CONV_BUFF_MAX 32768 int len; char *buf, *dst, *ret; buf = (char *) malloc (CONV_BUFF_MAX); memset (&buf[0], 0, CONV_BUFF_MAX); dst = buf; if (src) for (len = CONV_BUFF_MAX; *src; src++) { wchar_t ch = *src; if (ch < 0x80) /* 0x00-0x7f: 1 byte */ { if (!len--) { log ("wide_to_utf8: error converting input string, overflow.\n"); break; /* overflow */ } *dst++ = ch; continue; } if (ch < 0x800) /* 0x80-0x7ff: 2 bytes */ { if ((len -= 2) < 0) { log ("wide_to_utf8: error converting input string, overflow.\n"); break; /* overflow */ } dst[1] = 0x80 | (ch & 0x3f); ch >>= 6; dst[0] = 0xc0 | ch; dst += 2; continue; } /* 0x800-0xffff: 3 bytes */ if ((len -= 3) < 0) { log ("wide_to_utf8: error converting input string, overflow.\n"); break; /* overflow */ } dst[2] = 0x80 | (ch & 0x3f); ch >>= 6; dst[1] = 0x80 | (ch & 0x3f); ch >>= 6; dst[0] = 0xe0 | ch; dst += 3; } ret = g_strdup (buf); free (buf); return ret; } tuxcmd-modules-0.6.70+ds/common/treepath_vfs.c0000644000175000017500000001410111300022650020306 0ustar salvisalvi/* Tux Commander VFS: basic tree_path routines * Copyright (C) 2007 Tomas Bzatek * Check for updates on tuxcmd.sourceforge.net * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "vfs_types.h" #include "strutils.h" #include "vfsutils.h" #include "treepathutils.h" #include "treepath_vfs.h" struct VfsFilelistData* vfs_filelist_new(struct PathTree *files) { struct VfsFilelistData *data= (struct VfsFilelistData*)malloc(sizeof(struct VfsFilelistData)); memset(data, 0, sizeof(struct VfsFilelistData)); log("vfs_filelist_new()\n"); data->files = files; return data; } void vfs_filelist_free(struct VfsFilelistData *data) { if (! data) { fprintf(stderr, "vfs_filelist_free: data == NULL !\n"); return; } if (data) { free(data); } } void vfs_filelist_set_files(struct VfsFilelistData *data, struct PathTree *files) { if (data) data->files = files; } u_int64_t internal_get_dir_size(struct VfsFilelistData *data, struct PathTree *tree) { if (data->break_get_dir_size) return 0; u_int64_t Size = 0; if (tree) { struct PathTree *n = NULL; unsigned long idx = 0; while ((n = filelist_tree_get_item_by_index(tree, idx))) { if (data->break_get_dir_size) break; if (n->data) { log("internal_get_dir_size: found item '%s', size = %zd \n", n->node, n->data->iSize); Size += (n->data->ItemType == vDirectory) ? internal_get_dir_size(data, n) : n->data->iSize; } idx++; } } return Size; } u_int64_t vfs_filelist_get_dir_size(struct VfsFilelistData *data, char *APath) { if (! data) return 0; data->break_get_dir_size = FALSE; struct PathTree* node = filelist_tree_find_node_by_path(data->files, APath); if (node) { return internal_get_dir_size(data, node); } else { printf("(EE) VFSGetDirSize: path '%s' not found\n", APath); return 0; } } void vfs_filelist_get_dir_size_break(struct VfsFilelistData *data) { if (data) data->break_get_dir_size = TRUE; } long vfs_filelist_file_exists(struct VfsFilelistData *data, const char *FileName, const long Use_lstat) { if ((data) && (data->files)) { struct PathTree* node = filelist_tree_find_node_by_path(data->files, FileName); return node != NULL; } else { printf ("(EE) VFSFileExists: Invalid pointers to data objects.\n"); return FALSE; } } TVFSResult vfs_filelist_file_info(struct VfsFilelistData *data, char *AFileName, struct TVFSItem *Item) { if ((data) && (data->files)) { struct PathTree* node = filelist_tree_find_node_by_path(data->files, AFileName); if (node) { if (node->data) { copy_vfs_item(node->data, Item); Item->FName = strdup(AFileName); Item->FDisplayName = strdup(AFileName); printf("(II) VFSFileInfo: found file: '%s'\n", Item->FName); return cVFS_OK; } else { printf("(EE) VFSFileInfo: node->data == NULL! \n"); return cVFS_Failed; } } else { printf("(EE) VFSFileInfo: file specified not found\n"); return cVFS_No_More_Files; } } else { printf ("(EE) VFSFileInfo: Invalid pointers to data objects.\n"); return cVFS_Failed; } } TVFSResult vfs_filelist_list_first(struct VfsFilelistData *data, char *sDir, struct TVFSItem *Item) { data->list_dir_index = -1; data->list_dir_node = NULL; if (sDir == NULL) { printf("(EE) VFSListFirst: sDir is NULL!\n"); return cVFS_Failed; } data->list_dir_index = 0; data->list_dir_node = filelist_tree_find_node_by_path(data->files, sDir); // Find the directory in the filelist if (data->list_dir_node) { struct PathTree* node = filelist_tree_get_item_by_index(data->list_dir_node, data->list_dir_index); if (node) { copy_vfs_item(node->data, Item); printf("(II) VFSListFirst: found file: %s\n", Item->FName); return cVFS_OK; } else { printf("(II) VFSListFirst: no more files\n"); return cVFS_No_More_Files; } } else { printf ("(EE) VFSListFirst: Directory '%s' not found.\n", sDir); return cVFS_Failed; } } TVFSResult vfs_filelist_list_next(struct VfsFilelistData *data, char *sDir, struct TVFSItem *Item) { if (! data->list_dir_node) { printf("(EE) VFSListNext: data->list_dir_node is NULL!\n"); return cVFS_Failed; } data->list_dir_index++; struct PathTree* node = filelist_tree_get_item_by_index(data->list_dir_node, data->list_dir_index); if (node) { copy_vfs_item(node->data, Item); printf("(II) VFSListNext: found file: %s\n", Item->FName); return cVFS_OK; } else { printf("(II) VFSListNext: no more files\n"); return cVFS_No_More_Files; } } TVFSResult vfs_filelist_list_close(struct VfsFilelistData *data) { data->list_dir_index = -1; data->list_dir_node = NULL; return cVFS_OK; } char* vfs_filelist_change_dir(struct VfsFilelistData *data, char *NewPath) { if (NewPath == NULL) { printf("(EE) VFSChangeDir: NewPath is NULL!\n"); return NULL; } // Make up the target path printf ("(--) VFSChangeDir: Going to change dir from '%s'\n", NewPath); char *ANewPath = exclude_trailing_path_sep(NewPath); if (strlen(ANewPath) <= 0) ANewPath = strdup("/"); printf ("(--) VFSChangeDir: Going to change dir to '%s'\n", ANewPath); // Find the directory in the filelist if (filelist_tree_find_node_by_path(data->files, ANewPath)) { return ANewPath; } else { printf ("(EE) VFSChangeDir: Directory '%s' not found.\n", ANewPath); free(ANewPath); return NULL; } } tuxcmd-modules-0.6.70+ds/common/vfsutils.c0000644000175000017500000000360111300022650017476 0ustar salvisalvi/* Tux Commander VFS: String utilities * Copyright (C) 2007 Tomas Bzatek * Check for updates on tuxcmd.sourceforge.net * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "strutils.h" #include "vfs_types.h" void copy_vfs_item(struct TVFSItem *src, struct TVFSItem *dst) { dst->FName = g_strdup (src->FName); dst->FDisplayName = g_strdup (src->FDisplayName); dst->iSize = src->iSize; dst->iPackedSize = src->iPackedSize; dst->m_time = src->m_time; dst->a_time = src->a_time; dst->c_time = src->c_time; dst->iMode = src->iMode; dst->sLinkTo = g_strdup (src->sLinkTo); dst->iUID = src->iUID; dst->iGID = src->iGID; dst->ItemType = src->ItemType; } void free_vfs_item(struct TVFSItem *item) { if (item) { if (item->FName) free(item->FName); if (item->FDisplayName) free(item->FDisplayName); if (item->sLinkTo) free(item->sLinkTo); free(item); } } int compare_two_same_files(const char *Path1, const char *Path2) { char *f1 = exclude_trailing_path_sep(Path1); char *f2 = exclude_trailing_path_sep(Path2); gboolean b = strcmp(f1, f2) == 0; free(f1); free(f2); return b; } tuxcmd-modules-0.6.70+ds/Makefile0000644000175000017500000000041411300023025015617 0ustar salvisalviSUBDIRS = zip libarchive gvfs all install clean shared static:: target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ (cd $$subdir && $(MAKE) $$target) || exit 1; \ done; \ modules: all tuxcmd-modules-0.6.70+ds/.pc/0000755000175000017500000000000011300613427014653 5ustar salvisalvituxcmd-modules-0.6.70+ds/.pc/.version0000644000175000017500000000000211300610465016330 0ustar salvisalvi2