diff options
| author | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2008-10-28 17:10:07 +0100 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2008-10-28 17:10:07 +0100 |
| commit | da1cdfc3ada7109330a92955239bdc7981e95430 (patch) | |
| tree | a816308895fd45de50a0dc06cada0c1b50b4ccfe /unrar | |
| parent | c4db474055a604156e1acf162991e625fd340fa5 (diff) | |
| download | tuxcmd-modules-0.6.54.tar.xz | |
Password callback support from all VFS modulesv0.6.54
Diffstat (limited to 'unrar')
| -rw-r--r-- | unrar/unrar.c | 199 |
1 files changed, 129 insertions, 70 deletions
diff --git a/unrar/unrar.c b/unrar/unrar.c index 8793dc4..22d5497 100644 --- a/unrar/unrar.c +++ b/unrar/unrar.c @@ -1,5 +1,5 @@ /* UNRAR plugin for Tux Commander - * version 0.3.0, designed for unrar v3.8.2 + * version 0.3.2, designed for unrar v3.8.2 * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net> * Check for updates on tuxcmd.sourceforge.net * @@ -55,19 +55,14 @@ enum HOST_SYSTEM { }; -#define VERSION "0.3.0" -#define BUILD_DATE "2008-10-05" +#define VERSION "0.3.2" +#define BUILD_DATE "2008-10-28" #define DEFAULT_BLOCK_SIZE 65536 -/******************************************************************************************************/ -/** Auxiliary classes */ -/************** ****************/ - - // Declaration of the global plugin object struct TVFSGlobs { @@ -86,11 +81,14 @@ struct TVFSGlobs { u_int64_t total_size; - void *extract_callback_data; - TVFSCopyCallBackFunc extract_callback_func; u_int64_t extract_file_size; u_int64_t extract_done; gboolean extract_cancelled; + + TVFSAskQuestionCallback callback_ask_question; + TVFSAskPasswordCallback callback_ask_password; + TVFSProgressCallback callback_progress; + void *callback_data; }; @@ -110,10 +108,14 @@ VFSNew (TVFSLogFunc log_func) memset (globs, 0, sizeof (struct TVFSGlobs)); globs->block_size = DEFAULT_BLOCK_SIZE; - globs->extract_callback_data = NULL; - globs->extract_callback_func = NULL; globs->need_password = FALSE; globs->passwd_callback = FALSE; + globs->password = NULL; + + 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*)"unrar plugin: VFSInit"); @@ -122,6 +124,19 @@ VFSNew (TVFSLogFunc log_func) } 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((char*)"unrar plugin: VFSDestroy"); @@ -167,6 +182,11 @@ char *VFSGetExts() int unrar_callback(UINT msg, LONG UserData, LONG P1, LONG P2) { // fprintf(stderr, "(II) unrar_callback called: msg = %d, UserData = %lx, sizeof(UserData) = %ld, P1 = %ld, P2 = %ld\n", msg, UserData, sizeof(UserData), P1, P2); + if (! UserData) { + fprintf(stderr, "(WW) unrar_callback: UserData == NULL, exiting!\n"); + return 0; + } + struct TVFSGlobs *globs = (struct TVFSGlobs *)UserData; // >= 0 => Weiter, -1 => Stop switch(msg) @@ -174,11 +194,35 @@ int unrar_callback(UINT msg, LONG UserData, LONG P1, LONG P2) case UCM_CHANGEVOLUME: { if (P2 == RAR_VOL_ASK) { fprintf(stderr, " (II) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_ASK, P1 = %ld, (char*)P1 = '%s' \n", P1, (char*)P1); - if (P1) + if (P1) { + if (globs->callback_ask_question) { + static const char *choices[] = { + "Cancel", + "Continue", + NULL + }; + char *message; + int choice = 2; + + message = g_strdup_printf ("volume missing: %s", (char *)P1); + globs->callback_ask_question (message, choices, &choice, 0, + globs->callback_data); + g_free (message); + switch (choice) { + case 0: /* Cancel */ + return -1; + case 1: /* Continue */ + return 0; + /* Any other options? */ + } + } +/* if (access((char*)P1, R_OK) != 0) { fprintf(stderr, "(EE) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_ASK: access test failed - missing part? Error = %s \n", strerror(errno)); return -1; } +*/ + } } else if (P2 == RAR_VOL_NOTIFY) { fprintf(stderr, " (II) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_NOTIFY, P1 = %ld, (char*)P1 = '%s' \n", P1, (char*)P1); @@ -188,20 +232,19 @@ int unrar_callback(UINT msg, LONG UserData, LONG P1, LONG P2) case UCM_PROCESSDATA: { fprintf(stderr, " (II) unrar_callback: UCM_PROCESSDATA message, P1 = %ld, P2 = %ld \n", P1, P2); - struct TVFSGlobs *globs = (struct TVFSGlobs *)UserData; // printf(" (II) unrar_callback: globs = 0x%lX, UserData = 0x%lX \n", (unsigned long int)globs, UserData); - if ((globs) && (globs->extract_callback_func != NULL)) { + if ((globs) && (globs->callback_progress)) { // printf(" (II) unrar_callback: globs->extract_callback_func = 0x%lX, globs->extract_callback_data = 0x%lX \n", (unsigned long int)globs->extract_callback_func, (unsigned long int)globs->extract_callback_data); // long int res = globs->extract_callback_func((u_int64_t)P1, (u_int64_t)((u_int64_t)P1 + (u_int64_t)P2), globs->extract_callback_data); globs->extract_done += P2; - int res = globs->extract_callback_func(globs->extract_done, globs->extract_file_size, globs->extract_callback_data); + int res = globs->callback_progress(globs->extract_done, globs->extract_file_size, globs->callback_data); // fprintf(stderr, " (II) unrar_callback: res = %d \n", res); if (! res ) { - globs->extract_cancelled = TRUE; - fprintf(stderr, "(WW) unrar_callback: received cancellation result\n"); - return -1; // Cancel operation + globs->extract_cancelled = TRUE; + fprintf(stderr, "(WW) unrar_callback: received cancellation result\n"); + return -1; // Cancel operation } } break; @@ -209,9 +252,32 @@ int unrar_callback(UINT msg, LONG UserData, LONG P1, LONG P2) case UCM_NEEDPASSWORD: { fprintf(stderr, " (II) unrar_callback: UCM_NEEDPASSWORD message, P1 = %ld, P2 = %ld, (char*)P1 = '%s', maxlen = %ld \n", P1, P2, (char*)P1, P2); - struct TVFSGlobs *globs = (struct TVFSGlobs *)UserData; - if (globs) globs->passwd_callback = TRUE; - break; + + char *passwd = NULL; + int res = FALSE; + + globs->passwd_callback = TRUE; + if (globs->callback_ask_password) { + res = globs->callback_ask_password ("The archive is encrypted and requires password", + NULL, NULL, NULL, VFS_ASK_PASSWORD_NEED_PASSWORD | VFS_ASK_PASSWORD_ARCHIVE_MODE, + NULL, &passwd, NULL, NULL, NULL, + globs->callback_data); + if (res && passwd) { + fprintf(stderr, " (II) unrar_callback: setting password to '%s'\n", passwd); + if (strlen (passwd) > 0) { + strncpy((char *)P1, passwd, P2); + if (globs->password) g_free (globs->password); + globs->password = g_strdup (passwd); + } + g_free (passwd); + } + } + if (res) + return 0; + else { + globs->extract_cancelled = TRUE; + return -1; + } } } @@ -407,20 +473,6 @@ 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"); - if (globs->password) free(globs->password); - globs->password = strdup(pass); - return cVFS_OK; -} - int VFSGetPasswordRequired(struct TVFSGlobs *globs) { if (globs) return globs->need_password; @@ -577,7 +629,7 @@ int VFSIsOnSameFS(struct TVFSGlobs *globs, const char *Path1, const char *Path2) int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path2) { - printf("(WW) VFSTwoSameFiles: Not supported in ZIP archives, comparing by paths.\n"); + printf("(WW) VFSTwoSameFiles: Not supported in RAR archives, comparing by paths.\n"); return compare_two_same_files(Path1, Path2); } @@ -586,7 +638,7 @@ int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path //////////////////////// -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) { 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"); @@ -603,10 +655,6 @@ TVFSResult VFSCopyOut(struct TVFSGlobs *globs, const char *sSrcName, const char printf("(II) VFSCopyOut: new src path: '%s'\n", src); -// printf("(II) VFSCopyOut: pCallBackProgress = 0x%lX, data = 0x%lX\n", (unsigned long int)pCallBackProgress, (unsigned long int)data); - globs->extract_callback_data = data; - globs->extract_callback_func = pCallBackProgress; - HANDLE PASCAL handle; struct RAROpenArchiveDataEx *archive_data; @@ -658,7 +706,10 @@ TVFSResult VFSCopyOut(struct TVFSGlobs *globs, const char *sSrcName, const char int res2 = RARProcessFile(handle, RAR_EXTRACT, NULL, (char *)sDstName); - if (globs->extract_cancelled) Result = cVFS_Cancelled; + if (globs->extract_cancelled) { + fprintf(stderr, "(WW) VFSCopyOut: cancelled !\n"); + Result = cVFS_Cancelled; + } else if (res2) { fprintf(stderr, "(EE) VFSCopyOut: RARProcessFile result = %d\n", res2); @@ -675,32 +726,39 @@ TVFSResult VFSCopyOut(struct TVFSGlobs *globs, const char *sSrcName, const char } if ((res != ERAR_END_ARCHIVE) && (res)) { - fprintf(stderr, "(EE) VFSCopyOut: RARReadHeader result = %d\n", res); - switch (res) { - case ERAR_NO_MEMORY: - case ERAR_SMALL_BUF: - Result = cVFS_mallocFailed; - break; - case ERAR_BAD_DATA: - case ERAR_BAD_ARCHIVE: - case ERAR_UNKNOWN_FORMAT: - case ERAR_EOPEN: - case ERAR_ECLOSE: - case ERAR_EREAD: - Result = cVFS_ReadErr; - break; - case ERAR_ECREATE: - case ERAR_EWRITE: - Result = cVFS_WriteErr; - break; - case ERAR_MISSING_PASSWORD: - Result = cVFS_BadPassword; - break; - case ERAR_UNKNOWN: - default: - Result = cVFS_WriteErr; - break; - } + if (globs->extract_cancelled) { + fprintf(stderr, "(WW) VFSCopyOut: cancelled !\n"); + Result = cVFS_Cancelled; + } + else { + fprintf(stderr, "(EE) VFSCopyOut: RARReadHeader result = %d\n", res); + switch (res) { + case ERAR_NO_MEMORY: + case ERAR_SMALL_BUF: + Result = cVFS_mallocFailed; + break; + case ERAR_BAD_DATA: + case ERAR_BAD_ARCHIVE: + case ERAR_UNKNOWN_FORMAT: + case ERAR_EOPEN: + case ERAR_ECLOSE: + case ERAR_EREAD: + Result = cVFS_ReadErr; + break; + case ERAR_ECREATE: + case ERAR_EWRITE: + Result = cVFS_WriteErr; + break; + case ERAR_MISSING_PASSWORD: + Result = cVFS_BadPassword; + if (globs->password) g_free (globs->password); + break; + case ERAR_UNKNOWN: + default: + Result = cVFS_WriteErr; + break; + } + } } free(header); @@ -722,7 +780,7 @@ TVFSResult VFSCopyOut(struct TVFSGlobs *globs, const char *sSrcName, const char return Result; } -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) { printf("(WW) VFSCopyIn: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; @@ -735,6 +793,7 @@ TVFSResult VFSCopyIn(struct TVFSGlobs *globs, const char *sSrcName, const char * * TODO: * * - UTF-8, FName/FDisplayName and absolute/relative paths revision needed! + * - find a reliable way to catch bad password errors and free the cached invalid password * - no error reporting when archive is corrupted * - archive testing (needs new VFS API) * |
