From da1cdfc3ada7109330a92955239bdc7981e95430 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Tue, 28 Oct 2008 17:10:07 +0100 Subject: Password callback support from all VFS modules --- zip/zip.cpp | 238 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 149 insertions(+), 89 deletions(-) (limited to 'zip/zip.cpp') diff --git a/zip/zip.cpp b/zip/zip.cpp index 8b61068..2f87778 100644 --- a/zip/zip.cpp +++ b/zip/zip.cpp @@ -1,5 +1,5 @@ /* ZIP plugin for Tux Commander - * version 0.5.0, designed for ZipArchive v3.2.0 + * version 0.5.1, designed for ZipArchive v3.2.0 * Copyright (C) 2008 Tomas Bzatek * Check for updates on tuxcmd.sourceforge.net * @@ -47,8 +47,8 @@ -#define VERSION "0.5.0" -#define BUILD_DATE "2008-10-05" +#define VERSION "0.5.1" +#define BUILD_DATE "2008-10-28" #define DEFAULT_BLOCK_SIZE 65536 @@ -120,6 +120,31 @@ TVFSResult get_vfs_errorcode(int m_iCause) /** 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 { @@ -127,12 +152,10 @@ struct ZIP_API CVFSZipActionCallback : public CZipActionCallback { m_uTotalToProcess = 0; m_uProcessed = 0; - pCallBackProgress = NULL; - data = NULL; + globs = NULL; } - TVFSCopyCallBackFunc pCallBackProgress; - void *data; + struct TVFSGlobs *globs; virtual bool Callback(ZIP_SIZE_TYPE uProgress) { @@ -140,7 +163,8 @@ struct ZIP_API CVFSZipActionCallback : public CZipActionCallback uProgress, m_uTotalToProcess, m_uProcessed); bool ret = true; try { - if (pCallBackProgress != NULL) ret = pCallBackProgress(m_uProcessed, m_uTotalToProcess, data); + 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"); @@ -150,24 +174,6 @@ struct ZIP_API CVFSZipActionCallback : public CZipActionCallback }; -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; -}; - /*********************************************************************************************************************** @@ -241,12 +247,30 @@ VFSNew (TVFSLogFunc log_func) 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((char*)"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) { @@ -331,6 +355,7 @@ TVFSResult VFSOpen(struct TVFSGlobs *globs, char *sName) // 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); @@ -428,11 +453,7 @@ TVFSResult VFSChangeDir(struct TVFSGlobs *globs, char *NewPath) else return cVFS_Failed; } -int VFSLogin(struct TVFSGlobs *globs, char *user, char *pass) -{ - return cVFS_Not_Supported; -} - +/* int VFSSetPassword(struct TVFSGlobs *globs, char *pass) { printf ("(II) VFSSetPassword: Going to set the password...\n"); @@ -446,6 +467,7 @@ int VFSSetPassword(struct TVFSGlobs *globs, char *pass) } return cVFS_OK; } +*/ int VFSGetPasswordRequired(struct TVFSGlobs *globs) { @@ -846,8 +868,10 @@ int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path // Known issues: - crashes when no space left on NFS mounts, probably unhandled exception in further ZipArchive code (repro: Gentoo, Ubuntu) -TVFSResult VFSCopyOut(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, TVFSCopyCallBackFunc pCallBackProgress, void *data, int Append) +TVFSResult VFSCopyOut(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) VFSCopyOut: The value of 'sSrcName' or 'sDstName' is NULL or empty\n"); return cVFS_Failed; @@ -866,26 +890,43 @@ TVFSResult VFSCopyOut(struct TVFSGlobs *globs, const char *sSrcName, const char char *dest_filename = extract_file_name(s); free(s); - // Set callback data - globs->extract_callback->data = data; - globs->extract_callback->pCallBackProgress = pCallBackProgress; - // Perform extract try { - try { - if (! globs->zip->ExtractFile(file_no, dest_path, false, dest_filename, globs->block_size)) { + 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) VFSCopyOut: Error while copying out, archive closed = %d.\n", globs->zip->IsClosed()); + return cVFS_WriteErr; + } + fprintf(stderr, "(II) VFSCopyOut: copy OK, archive closed = %d.\n", globs->zip->IsClosed()); + } + catch (CZipException e) { globs->zip->CloseFile(NULL, true); - fprintf(stderr, "(EE) VFSCopyOut: Error while copying out, archive closed = %d.\n", globs->zip->IsClosed()); - return cVFS_WriteErr; - } - fprintf(stderr, "(II) VFSCopyOut: copy OK, archive closed = %d.\n", globs->zip->IsClosed()); - } - catch (CZipException e) { - globs->zip->CloseFile(NULL, true); - fprintf(stderr, "(EE) VFSCopyOut: Error while copying out: [%d] %s, archive closed = %d.\n", - e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); - return get_vfs_errorcode(e.m_iCause); - } + fprintf(stderr, "(EE) VFSCopyOut: 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) VFSCopyOut: 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 (...) { @@ -900,8 +941,10 @@ TVFSResult VFSCopyOut(struct TVFSGlobs *globs, const char *sSrcName, const char // Known issues: - archive corruption when no space left on device // - encrypted files are unreadable after copy in -TVFSResult VFSCopyIn(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, TVFSCopyCallBackFunc pCallBackProgress, void *data, int Append) +TVFSResult VFSCopyIn(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) VFSCopyIn: The value of 'sSrcName' or 'sDstName' is NULL or empty\n"); return cVFS_Failed; @@ -909,50 +952,67 @@ TVFSResult VFSCopyIn(struct TVFSGlobs *globs, const char *sSrcName, const char * printf("(II) VFSCopyIn: copying file '%s' in to '%s'\n", sSrcName, sDstName); - // Set callback data - globs->extract_callback->data = data; - globs->extract_callback->pCallBackProgress = pCallBackProgress; - try { - try { - char *s = exclude_leading_path_sep(sDstName); - if (! globs->zip->AddNewFile(sSrcName, s, -1, CZipArchive::zipsmSafeSmart, globs->block_size)) { + 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) VFSCopyIn: Error while copying in, archive closed = %d.\n", globs->zip->IsClosed()); + return cVFS_WriteErr; + } + + globs->zip->Flush(); + printf("(II) VFSCopyIn: 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) VFSCopyIn: unable to find index for newly written file '%s'\n", sSrcName); + return cVFS_WriteErr; + } + printf("(II) VFSCopyIn: Encrypting the newly written file...\n"); + if (! globs->zip->EncryptFile(file_no)) + printf("(EE) VFSCopyIn: 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) VFSCopyIn: Error while copying in, archive closed = %d.\n", globs->zip->IsClosed()); - return cVFS_WriteErr; + fprintf(stderr, "(EE) VFSCopyIn: 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) VFSCopyIn: 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); + } } - - globs->zip->Flush(); - printf("(II) VFSCopyIn: 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) VFSCopyIn: unable to find index for newly written file '%s'\n", sSrcName); - return cVFS_WriteErr; - } - printf("(II) VFSCopyIn: Encrypting the newly written file...\n"); - if (! globs->zip->EncryptFile(file_no)) - printf("(EE) VFSCopyIn: 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) VFSCopyIn: Error while copying in: [%d] %s, archive closed = %d.\n", - e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); - return get_vfs_errorcode(e.m_iCause); - } + } while (try_again); } catch (...) { -- cgit v1.2.3