summaryrefslogtreecommitdiff
path: root/unrar
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2008-10-28 17:10:07 +0100
committerTomas Bzatek <tbzatek@users.sourceforge.net>2008-10-28 17:10:07 +0100
commitda1cdfc3ada7109330a92955239bdc7981e95430 (patch)
treea816308895fd45de50a0dc06cada0c1b50b4ccfe /unrar
parentc4db474055a604156e1acf162991e625fd340fa5 (diff)
downloadtuxcmd-modules-0.6.54.tar.xz
Password callback support from all VFS modulesv0.6.54
Diffstat (limited to 'unrar')
-rw-r--r--unrar/unrar.c199
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)
*