summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore12
-rw-r--r--common/vfs_types.h12
-rw-r--r--gvfs/gvfs.c80
-rw-r--r--libarchive/libarchive.c54
-rw-r--r--unrar/unrar.c199
-rw-r--r--zip/zip.cpp238
6 files changed, 360 insertions, 235 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d3dcca6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+*.o
+*.lo
+*.a
+*.*~
+*.so
+*.ppu
+*.dcu
+.project
+.cproject
+
+UVFSCore.pas
+uVFSprototypes.pas
diff --git a/common/vfs_types.h b/common/vfs_types.h
index 99334f9..aced4d3 100644
--- a/common/vfs_types.h
+++ b/common/vfs_types.h
@@ -37,7 +37,8 @@ typedef enum {
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<<15
+ VFS_ASK_PASSWORD_SAVE_INTERNAL = 1<<14,
+ VFS_ASK_PASSWORD_ARCHIVE_MODE = 1<<15
} TVFSAskPasswordFlags;
/* Compatible with gio/GPasswordSave */
@@ -49,9 +50,15 @@ typedef enum {
typedef void (* TVFSLogFunc)(char *s);
-typedef int (* TVFSCopyCallBackFunc)(u_int64_t iPos, u_int64_t iMax, void *data);
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,
@@ -64,6 +71,7 @@ typedef int (* TVFSAskPasswordCallback)
(const char *message,
const char *default_user,
const char *default_domain,
+ const char *default_password,
TVFSAskPasswordFlags flags,
char **username,
char **password,
diff --git a/gvfs/gvfs.c b/gvfs/gvfs.c
index 557f08c..a5734cf 100644
--- a/gvfs/gvfs.c
+++ b/gvfs/gvfs.c
@@ -31,8 +31,8 @@
-#define VERSION "0.1.3"
-#define BUILD_DATE "2008-10-12"
+#define VERSION "0.1.4"
+#define BUILD_DATE "2008-10-28"
#define DEFAULT_BLOCK_SIZE 0x10000 /* 64kB */
#define CONST_DEFAULT_QUERY_INFO_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_NAME "," \
@@ -46,6 +46,7 @@ struct TVFSGlobs {
TVFSLogFunc log_func;
GFile *file;
GFileEnumerator *enumerator;
+ GCancellable *cancellable;
GMainLoop *mount_main_loop;
TVFSResult mount_result;
@@ -57,7 +58,8 @@ struct TVFSGlobs {
TVFSAskQuestionCallback callback_ask_question;
TVFSAskPasswordCallback callback_ask_password;
- void *callbacks_data;
+ TVFSProgressCallback callback_progress;
+ void *callback_data;
};
@@ -167,9 +169,9 @@ ask_password_cb (GMountOperation *op,
if (globs->callback_ask_password) {
fprintf (stderr, " (II) Spawning callback_ask_password (0x%.16llX)...\n", (unsigned long long) globs->callback_ask_password);
- result = globs->callback_ask_password (message, default_user, default_domain, flags,
+ result = globs->callback_ask_password (message, default_user, default_domain, NULL, flags,
&username, &password, &anonymous, &domain, &password_save,
- globs->callbacks_data);
+ globs->callback_data);
fprintf (stderr, " (II) Received result = %d\n", result);
if (result) {
if (flags & G_ASK_PASSWORD_NEED_USERNAME)
@@ -217,7 +219,7 @@ ask_question_cb (GMountOperation *op,
if (globs->callback_ask_question) {
fprintf (stderr, " (II) Spawning callback_ask_question (0x%.16llX)...\n", (unsigned long long) 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->callbacks_data);
+ globs->callback_ask_question (message, choices, &choice, 1, globs->callback_data);
fprintf (stderr, " (II) Received choice = %d\n", choice);
if (choice >= 0) {
@@ -298,13 +300,15 @@ VFSNew (TVFSLogFunc log_func)
globs->file = NULL;
globs->enumerator = NULL;
+ globs->cancellable = NULL;
globs->break_get_dir_size = FALSE;
globs->block_size = DEFAULT_BLOCK_SIZE;
- globs->callbacks_data = NULL;
+ globs->callback_data = NULL;
globs->callback_ask_question = NULL;
globs->callback_ask_password = NULL;
+ globs->callback_progress = NULL;
return globs;
}
@@ -313,11 +317,13 @@ 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->callbacks_data = data;
+ globs->callback_progress = progress_func;
+ globs->callback_data = data;
}
void
@@ -599,17 +605,6 @@ VFSChangeDir (struct TVFSGlobs *globs, char *NewPath)
return res;
}
-int
-VFSLogin (struct TVFSGlobs *globs, char *user, char *pass)
-{
- g_print ("(II) VFSLogin: logging in with '%s'/'%s'\n", user, pass);
-
- /* FIXME: add auth code */
-
- return cVFS_Not_Supported;
-}
-
-
/**************************************************************************************************************************************/
/**************************************************************************************************************************************/
@@ -1275,41 +1270,31 @@ VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2)
/**************************************************************************************************************************************/
/**************************************************************************************************************************************/
-
-struct CopyJobRef {
- struct TVFSGlobs *globs;
- TVFSCopyCallBackFunc callback_func;
- void *callback_data;
-
- GCancellable *cancellable;
-};
-
static void
vfs_copy_progress_callback (goffset current_num_bytes,
goffset total_num_bytes,
gpointer user_data)
{
- struct CopyJobRef *ref;
+ 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;
- ref = (struct CopyJobRef*) user_data;
+ globs = (struct TVFSGlobs *)user_data;
- if (ref->callback_func) {
- if (! ref->callback_func (current_num_bytes, total_num_bytes, ref->callback_data))
- g_cancellable_cancel (ref->cancellable);
+ if (globs->callback_progress) {
+ if (! globs->callback_progress (current_num_bytes, total_num_bytes, globs->callback_data))
+ g_cancellable_cancel (globs->cancellable);
}
}
TVFSResult
-VFSCopyOut (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, TVFSCopyCallBackFunc pCallBackProgress, void *data, gboolean Append)
+VFSCopyOut (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append)
{
GFile *src, *dst;
GError *error;
- struct CopyJobRef *ref;
TVFSResult res;
@@ -1331,15 +1316,11 @@ VFSCopyOut (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName,
return cVFS_Failed;
}
- ref = g_slice_new0 (struct CopyJobRef);
- ref->globs = globs;
- ref->callback_func = pCallBackProgress;
- ref->callback_data = data;
- ref->cancellable = g_cancellable_new ();
+ globs->cancellable = g_cancellable_new ();
res = cVFS_OK;
error = NULL;
- g_file_copy (src, dst, G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS, ref->cancellable, vfs_copy_progress_callback, ref, &error);
+ g_file_copy (src, dst, G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS, globs->cancellable, vfs_copy_progress_callback, globs, &error);
if (error) {
g_print ("(EE) VFSCopyOut: g_file_copy() error: %s\n", error->message);
// res = g_error_to_TVFSResult (error);
@@ -1349,19 +1330,17 @@ VFSCopyOut (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName,
g_error_free (error);
}
- g_object_unref (ref->cancellable);
- g_slice_free (struct CopyJobRef, ref);
+ g_object_unref (globs->cancellable);
g_object_unref (src);
g_object_unref (dst);
return res;
}
TVFSResult
-VFSCopyIn (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, TVFSCopyCallBackFunc pCallBackProgress, void *data, gboolean Append)
+VFSCopyIn (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append)
{
GFile *src, *dst;
GError *error;
- struct CopyJobRef *ref;
TVFSResult res;
@@ -1383,16 +1362,12 @@ VFSCopyIn (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName,
return cVFS_Failed;
}
- ref = g_slice_new0 (struct CopyJobRef);
- ref->globs = globs;
- ref->callback_func = pCallBackProgress;
- ref->callback_data = data;
- ref->cancellable = g_cancellable_new ();
+ globs->cancellable = g_cancellable_new ();
res = cVFS_OK;
error = NULL;
/* FIXME: Appending not supported */
- g_file_copy (src, dst, G_FILE_COPY_NOFOLLOW_SYMLINKS, ref->cancellable, vfs_copy_progress_callback, ref, &error);
+ g_file_copy (src, dst, G_FILE_COPY_NOFOLLOW_SYMLINKS, globs->cancellable, vfs_copy_progress_callback, globs, &error);
if (error) {
g_print ("(EE) VFSCopyIn: g_file_copy() error: %s\n", error->message);
// res = g_error_to_TVFSResult (error);
@@ -1402,8 +1377,7 @@ VFSCopyIn (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName,
g_error_free (error);
}
- g_object_unref (ref->cancellable);
- g_slice_free (struct CopyJobRef, ref);
+ g_object_unref (globs->cancellable);
g_object_unref (src);
g_object_unref (dst);
return res;
diff --git a/libarchive/libarchive.c b/libarchive/libarchive.c
index 4a360bd..be6326b 100644
--- a/libarchive/libarchive.c
+++ b/libarchive/libarchive.c
@@ -1,5 +1,5 @@
/* libarchive plugin for Tux Commander
- * version 0.1.0, designed for libarchive 2.5.5
+ * version 0.1.1, designed for libarchive 2.5.5
* Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
@@ -47,8 +47,8 @@
-#define VERSION "0.1.0"
-#define BUILD_DATE "2008-10-05"
+#define VERSION "0.1.1"
+#define BUILD_DATE "2008-10-28"
#define DEFAULT_BLOCK_SIZE 65536
@@ -73,6 +73,11 @@ struct TVFSGlobs {
struct VfsFilelistData *vfs_filelist;
u_int64_t total_size;
+
+ TVFSAskQuestionCallback callback_ask_question;
+ TVFSAskPasswordCallback callback_ask_password;
+ TVFSProgressCallback callback_progress;
+ void *callback_data;
};
@@ -92,6 +97,12 @@ VFSNew (TVFSLogFunc log_func)
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((char*)"libarchive plugin: VFSInit");
@@ -99,6 +110,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*)"libarchive plugin: VFSDestroy");
@@ -297,18 +321,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("(WW) VFSSetPassword: Not supported in libarchive plugin.\n");
- return cVFS_Not_Supported;
-}
-
int VFSGetPasswordRequired(struct TVFSGlobs *globs)
{
return FALSE;
@@ -480,7 +492,7 @@ int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path
* Quote: "This implementation minimizes copying of data and is sparse-file aware."
**/
static TVFSResult
-my_archive_read_data_into_fd(struct archive *a, struct archive_entry *entry, const char *sDstName, size_t max_block, TVFSCopyCallBackFunc pCallBackProgress, void *data, int Append)
+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;
@@ -529,8 +541,8 @@ my_archive_read_data_into_fd(struct archive *a, struct archive_entry *entry, con
size -= bytes_written;
log(" (II) my_archive_read_data_into_fd: bytes_written = %u, total_written = %u\n", bytes_written, total_written);
- if (pCallBackProgress) {
- if (! pCallBackProgress(total_written, file_size, data)) {
+ if (globs->callback_progress) {
+ if (! globs->callback_progress(total_written, file_size, globs->callback_data)) {
cancel = TRUE;
break;
}
@@ -553,7 +565,7 @@ my_archive_read_data_into_fd(struct archive *a, struct archive_entry *entry, con
}
-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");
@@ -602,7 +614,7 @@ TVFSResult VFSCopyOut(struct TVFSGlobs *globs, const char *sSrcName, const char
// printf("--> found file, extracting\n");
fprintf(stderr, "(II) VFSCopyOut: extract_file_path(sDstName) = '%s', extract_file_name(sDstName) = '%s' \n", extract_file_path(sDstName), extract_file_name(sDstName));
- Result = my_archive_read_data_into_fd(a, entry, sDstName, globs->block_size, pCallBackProgress, data, Append);
+ Result = my_archive_read_data_into_fd(globs, a, entry, sDstName, globs->block_size, Append);
break;
}
}
@@ -615,7 +627,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 libarchive plugin.\n");
return cVFS_Not_Supported;
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)
*
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 <tbzatek@users.sourceforge.net>
* 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,6 +247,11 @@ 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");
@@ -248,6 +259,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*)"zip plugin: VFSDestroy");
@@ -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 (...)
{