summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2009-11-29 16:35:02 +0100
committerTomas Bzatek <tbzatek@users.sourceforge.net>2009-11-29 16:35:02 +0100
commit01072f4baa7ae333e796800d8a17aa157fe08a4e (patch)
tree3c18844c391e2d7838e23de22f06bbef7db5e637
parent736d90da1b6cee6333889912513c634d55004d90 (diff)
downloadtuxcmd-modules-01072f4baa7ae333e796800d8a17aa157fe08a4e.tar.xz
Introduce copy operation start/stop callsv0.6.73
-rw-r--r--libarchive/libarchive.c94
-rw-r--r--unrar/unrar.c255
-rw-r--r--zip/zip.cpp45
3 files changed, 251 insertions, 143 deletions
diff --git a/libarchive/libarchive.c b/libarchive/libarchive.c
index 535d565..4337bb1 100644
--- a/libarchive/libarchive.c
+++ b/libarchive/libarchive.c
@@ -1,5 +1,5 @@
/* libarchive plugin for Tux Commander
- * version 0.2.0, designed for libarchive v2.5.5 - v2.7.1 (recommended)
+ * version 0.2.1, designed for libarchive v2.5.5 - v2.7.1 (recommended)
* Copyright (C) 2008-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
@@ -52,8 +52,8 @@
#endif
-#define MODULE_VERSION "0.2.0"
-#define MODULE_BUILD_DATE "2009-11-26"
+#define MODULE_VERSION "0.2.1"
+#define MODULE_BUILD_DATE "2009-11-29"
#define DEFAULT_BLOCK_SIZE 65536
@@ -81,6 +81,9 @@ struct TVFSGlobs {
TVFSAskPasswordCallback callback_ask_password;
TVFSProgressCallback callback_progress;
void *callback_data;
+
+ /* copy operation private */
+ struct archive *op_archive;
};
@@ -104,6 +107,8 @@ VFSNew (TVFSLogFunc log_func)
globs->callback_ask_password = NULL;
globs->callback_progress = NULL;
+ globs->op_archive = NULL;
+
globs->log_func = log_func;
if (globs->log_func != NULL)
globs->log_func ("libarchive plugin: VFSInit");
@@ -639,8 +644,8 @@ my_archive_read_data_into_fd (struct TVFSGlobs *globs, struct archive *a, struct
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);
+ 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;
@@ -696,16 +701,50 @@ my_archive_read_data_into_fd (struct TVFSGlobs *globs, struct archive *a, struct
TVFSResult
+VFSStartCopyOperation (struct TVFSGlobs *globs)
+{
+ TVFSResult Result;
+
+ g_return_val_if_fail (globs != NULL, cVFS_Failed);
+ g_return_val_if_fail (globs->op_archive == NULL, cVFS_Failed);
+
+ printf ("(II) VFSStartCopyOperation: opening archive '%s'\n", globs->archive_path);
+
+ Result = libarchive_open (&globs->op_archive, globs->archive_path, globs->block_size);
+
+ return Result;
+}
+
+
+TVFSResult
+VFSStopCopyOperation (struct TVFSGlobs *globs)
+{
+ g_return_val_if_fail (globs != NULL, cVFS_Failed);
+ g_return_val_if_fail (globs->op_archive != NULL, cVFS_Failed);
+
+ printf ("(II) VFSStopCopyOperation: closing archive.\n");
+
+ archive_read_close (globs->op_archive);
+ archive_read_finish (globs->op_archive);
+ globs->op_archive = NULL;
+
+ return cVFS_OK;
+}
+
+
+TVFSResult
VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append)
{
struct PathTree *node;
const char *src;
TVFSResult Result;
- struct archive *a;
struct archive_entry *entry;
int r;
gboolean found;
+
+ g_return_val_if_fail (globs->op_archive != NULL, cVFS_ReadErr);
+
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;
@@ -728,32 +767,29 @@ VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstN
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;
- }
+ Result = cVFS_ReadErr;
+
+ for (;;) {
+ entry = NULL;
+ r = archive_read_next_header (globs->op_archive, &entry);
+ if (r == ARCHIVE_EOF) {
+ break;
+ } else
+ if (r == ARCHIVE_WARN) {
+ log ("(WW) VFSCopyToLocal: file '%s' - libarchive warning: '%s'\n", archive_entry_pathname (entry), archive_error_string (globs->op_archive));
+ } else
+ if (r != ARCHIVE_OK) {
+ fprintf (stderr, "(EE) VFSCopyToLocal: error occured while reading archive: '%s'\n", archive_error_string (globs->op_archive));
+ Result = cVFS_Failed;
+ break;
+ }
- if (g_strcmp0 (src, archive_entry_pathname (entry)) == 0) {
- found = TRUE;
- Result = my_archive_read_data_into_fd (globs, a, entry, sDstName, globs->block_size, Append);
- break;
- }
+ if (g_strcmp0 (src, archive_entry_pathname (entry)) == 0) {
+ found = TRUE;
+ Result = my_archive_read_data_into_fd (globs, globs->op_archive, 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");
diff --git a/unrar/unrar.c b/unrar/unrar.c
index f804ff2..ad02765 100644
--- a/unrar/unrar.c
+++ b/unrar/unrar.c
@@ -1,5 +1,5 @@
/* UNRAR plugin for Tux Commander
- * version 0.4.0, designed for unrar v3.8.2
+ * version 0.4.1, designed for unrar v3.8.2
* Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
@@ -56,8 +56,8 @@ enum HOST_SYSTEM {
};
-#define VERSION "0.4.0"
-#define BUILD_DATE "2009-11-26"
+#define VERSION "0.4.1"
+#define BUILD_DATE "2009-11-29"
#define DEFAULT_BLOCK_SIZE 65536
@@ -91,6 +91,9 @@ struct TVFSGlobs {
TVFSAskPasswordCallback callback_ask_password;
TVFSProgressCallback callback_progress;
void *callback_data;
+
+ /* copy operation private */
+ HANDLE PASCAL op_handle;
};
@@ -114,6 +117,7 @@ VFSNew (TVFSLogFunc log_func)
globs->failed_passwd_callback = FALSE;
globs->volume_missing_abort = FALSE;
globs->password = NULL;
+ globs->op_handle = NULL;
globs->callback_data = NULL;
globs->callback_ask_question = NULL;
@@ -695,6 +699,79 @@ VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2,
TVFSResult
+VFSStartCopyOperation (struct TVFSGlobs *globs)
+{
+ TVFSResult Result;
+ struct RAROpenArchiveDataEx *archive_data;
+ HANDLE PASCAL handle;
+
+ g_return_val_if_fail (globs != NULL, cVFS_Failed);
+ g_return_val_if_fail (globs->op_handle == NULL, cVFS_Failed);
+
+ printf ("(II) VFSStartCopyOperation: opening archive '%s'\n", globs->archive_path);
+
+ Result = cVFS_Failed;
+
+ /* WARNING: do not use g_malloc0() here, leads to memory corruption */
+ archive_data = malloc (sizeof (struct RAROpenArchiveDataEx));
+ memset (archive_data, 0, sizeof (struct RAROpenArchiveDataEx));
+ archive_data->ArcName = globs->archive_path;
+ archive_data->OpenMode = RAR_OM_EXTRACT;
+
+ handle = RAROpenArchiveEx (archive_data);
+// printf(" handle = %lu \n", (unsigned long int)handle);
+// printf(" archive_data->OpenResult = %d \n", archive_data->OpenResult);
+// printf(" archive_data->CmtState = %d \n", archive_data->CmtState);
+// printf(" archive_data->CmtSize = %d \n", archive_data->CmtSize);
+
+ if (handle && ! archive_data->OpenResult) {
+ /* set callbacks */
+// printf(" setting callback: globs = 0x%lX, (unsigned long int)globs = 0x%lX, (LONG)globs = 0x%lX\n", globs, (unsigned long int)globs, (LONG)globs);
+ RARSetCallback (handle, unrar_callback, (LONG) globs);
+// RARSetChangeVolProc(handle, unrar_changevol_proc);
+// RARSetProcessDataProc(handle, unrar_process_data_proc);
+
+ /* set password */
+ if (globs->password) {
+ printf ("(II) VFSStartCopyOperation: Setting password... \n");
+ RARSetPassword (handle, globs->password);
+ }
+
+ globs->op_handle = handle;
+ Result = cVFS_OK;
+ } else {
+ fprintf (stderr, "(EE) VFSStartCopyOperation: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult);
+ Result = cVFS_ReadErr;
+ }
+ free (archive_data);
+
+ return Result;
+}
+
+
+TVFSResult
+VFSStopCopyOperation (struct TVFSGlobs *globs)
+{
+ TVFSResult Result;
+ int res;
+ g_return_val_if_fail (globs != NULL, cVFS_Failed);
+ g_return_val_if_fail (globs->op_handle != NULL, cVFS_Failed);
+
+ printf ("(II) VFSStopCopyOperation: closing archive.\n");
+
+ Result = cVFS_OK;
+ res = RARCloseArchive (globs->op_handle);
+ if (res) {
+ fprintf (stderr, "(EE) VFSCopyToLocal: RARCloseArchive result = %d\n", res);
+ Result = cVFS_ReadErr;
+ }
+ globs->op_handle = NULL;
+
+ return Result;
+}
+
+
+TVFSResult
VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append)
{
struct PathTree *node;
@@ -702,6 +779,8 @@ VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstN
gboolean found;
char *src;
+ g_return_val_if_fail (globs->op_handle != NULL, cVFS_ReadErr);
+
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;
@@ -715,131 +794,90 @@ VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstN
return cVFS_ReadErr;
}
- Result = cVFS_OK;
- found = FALSE;
-
src = node->original_pathstr;
if (! src) {
fprintf (stderr, "(WW) VFSCopyToLocal: cannot determine original filename\n");
src = (char *) sSrcName;
}
-
printf ("(II) VFSCopyToLocal: new src path: '%s'\n", src);
- HANDLE PASCAL handle;
- struct RAROpenArchiveDataEx *archive_data;
-
+ struct RARHeaderDataEx *header;
/* WARNING: do not use g_malloc0() here, leads to memory corruption */
- archive_data = malloc (sizeof (struct RAROpenArchiveDataEx));
- memset (archive_data, 0, sizeof (struct RAROpenArchiveDataEx));
- archive_data->ArcName = globs->archive_path;
- archive_data->OpenMode = RAR_OM_EXTRACT;
-
- handle = RAROpenArchiveEx (archive_data);
-// printf(" handle = %lu \n", (unsigned long int)handle);
-// printf(" archive_data->OpenResult = %d \n", archive_data->OpenResult);
-// printf(" archive_data->CmtState = %d \n", archive_data->CmtState);
-// printf(" archive_data->CmtSize = %d \n", archive_data->CmtSize);
-// printf("sizeof(TVFSResult) = %ld \n", sizeof(TVFSResult));
-
- if (handle && ! archive_data->OpenResult)
- {
- // Set callbacks
-// printf(" setting callback: globs = 0x%lX, (unsigned long int)globs = 0x%lX, (LONG)globs = 0x%lX\n", globs, (unsigned long int)globs, (LONG)globs);
- RARSetCallback (handle, unrar_callback, (LONG)globs);
-// RARSetChangeVolProc(handle, unrar_changevol_proc);
-// RARSetProcessDataProc(handle, unrar_process_data_proc);
+ header = malloc (sizeof (struct RARHeaderDataEx));
+ memset (header, 0, sizeof (struct RARHeaderDataEx));
- if (globs->password) {
- printf ("(II) VFSCopyToLocal: Setting password... \n");
- RARSetPassword (handle, globs->password);
- }
-
- struct RARHeaderDataEx *header;
- /* WARNING: do not use g_malloc0() here, leads to memory corruption */
- header = malloc (sizeof (struct RARHeaderDataEx));
- memset (header, 0, sizeof (struct RARHeaderDataEx));
+ int res = 0;
+ found = FALSE;
+ Result = cVFS_OK;
- int res = 0;
- while ((res = RARReadHeaderEx(handle, header)) == 0) {
- if (g_strcmp0 (src, header->FileName) == 0) {
+ while ((res = RARReadHeaderEx(globs->op_handle, header)) == 0) {
+ g_print ("VFSCopyToLocal: found '%s'\n", header->FileName);
+ if (g_strcmp0 (src, header->FileName) == 0) {
// fprintf(stderr, "(II) VFSCopyToLocal: extract_file_path(sDstName) = '%s', extract_file_name(sDstName) = '%s' \n", extract_file_path(sDstName), extract_file_name(sDstName));
- globs->extract_done = 0;
- globs->extract_file_size = (guint64)((guint64)(header->UnpSizeHigh * 0x100000000) + (guint64)header->UnpSize);
- globs->extract_cancelled = FALSE;
- found = TRUE;
-
- int res2 = RARProcessFile (handle, RAR_EXTRACT, NULL, (char *)sDstName);
-
- if (globs->extract_cancelled) {
- fprintf (stderr, "(WW) VFSCopyToLocal: cancelled !\n");
- Result = cVFS_Cancelled;
- }
- else
- if (res2) {
- fprintf (stderr, "(EE) VFSCopyToLocal: RARProcessFile result = %d\n", res2);
- Result = cVFS_ReadErr;
- }
- break;
- } else {
- int res2 = RARProcessFile (handle, RAR_SKIP, NULL, NULL);
- if (res2) {
- fprintf (stderr, "(EE) VFSCopyToLocal: RARProcessFile result = %d\n", res2);
- Result = cVFS_ReadErr;
- }
- }
- }
+ globs->extract_done = 0;
+ globs->extract_file_size = (guint64)((guint64)(header->UnpSizeHigh * 0x100000000) + (guint64)header->UnpSize);
+ globs->extract_cancelled = FALSE;
+ found = TRUE;
+
+ int res2 = RARProcessFile (globs->op_handle, RAR_EXTRACT, NULL, (char *)sDstName);
- if (res != ERAR_END_ARCHIVE && res) {
if (globs->extract_cancelled) {
fprintf (stderr, "(WW) VFSCopyToLocal: cancelled !\n");
Result = cVFS_Cancelled;
}
- else {
- fprintf (stderr, "(EE) VFSCopyToLocal: 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;
- g_free (globs->password);
- globs->password = NULL;
- break;
- case ERAR_UNKNOWN:
- default:
- Result = cVFS_WriteErr;
- break;
- }
+ else
+ if (res2) {
+ fprintf (stderr, "(EE) VFSCopyToLocal: RARProcessFile result = %d\n", res2);
+ Result = cVFS_ReadErr;
+ }
+ break;
+ } else {
+ int res2 = RARProcessFile (globs->op_handle, RAR_SKIP, NULL, NULL);
+ if (res2) {
+ fprintf (stderr, "(EE) VFSCopyToLocal: RARProcessFile result = %d\n", res2);
+ Result = cVFS_ReadErr;
}
}
+ }
- free (header);
-
- res = RARCloseArchive (handle);
- if (res) {
- fprintf (stderr, "(EE) VFSCopyToLocal: RARCloseArchive result = %d\n", res);
- Result = cVFS_ReadErr;
+ /* TODO: reopen archive on 'Unexpected end of archive' */
+ if (res != ERAR_END_ARCHIVE && res) {
+ if (globs->extract_cancelled) {
+ fprintf (stderr, "(WW) VFSCopyToLocal: cancelled !\n");
+ Result = cVFS_Cancelled;
+ }
+ else {
+ fprintf (stderr, "(EE) VFSCopyToLocal: 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;
+ g_free (globs->password);
+ globs->password = NULL;
+ break;
+ case ERAR_UNKNOWN:
+ default:
+ Result = cVFS_WriteErr;
+ break;
+ }
}
- } else {
- fprintf (stderr, "(EE) VFSCopyToLocal: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult);
- Result = cVFS_ReadErr;
}
-
- free (archive_data);
+ free (header);
if (! found && Result == cVFS_OK) {
fprintf (stderr, "(EE) VFSCopyToLocal: file not found in archive.\n");
@@ -867,5 +905,8 @@ VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDs
* - find a reliable way to catch bad password errors and free the cached invalid password
* - no error reporting when archive is corrupted -- hopefully fixed by ask_question callback
* - archive testing (needs new VFS API)
+ * - when bad password was entered during archive open, loop until succeeded or cancelled
+ * - when copy failed due to wrong password, reset it and do the callback (though we can't do that in loop)
+ * - reopen archive on 'Unexpected end of archive'
*
***/
diff --git a/zip/zip.cpp b/zip/zip.cpp
index 4a07b01..035b4b2 100644
--- a/zip/zip.cpp
+++ b/zip/zip.cpp
@@ -1,5 +1,5 @@
/* ZIP plugin for Tux Commander
- * version 0.6.0, designed for ZipArchive v3.2.0
+ * version 0.6.1, designed for ZipArchive v3.2.0
* Copyright (C) 2004-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
@@ -47,8 +47,8 @@
-#define VERSION "0.6.0"
-#define BUILD_DATE "2009-11-28"
+#define VERSION "0.6.1"
+#define BUILD_DATE "2009-11-29"
#define DEFAULT_BLOCK_SIZE 65536
@@ -927,6 +927,40 @@ VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2,
////////////////////////
+TVFSResult
+VFSStartCopyOperation (struct TVFSGlobs *globs)
+{
+ TVFSResult Result;
+
+ g_return_val_if_fail (globs != NULL, cVFS_Failed);
+
+ printf ("(II) VFSStartCopyOperation: doing nothing for the moment.\n");
+ Result = cVFS_OK;
+
+ return Result;
+}
+
+
+TVFSResult
+VFSStopCopyOperation (struct TVFSGlobs *globs)
+{
+ TVFSResult Result;
+
+ g_return_val_if_fail (globs != NULL, cVFS_Failed);
+
+ if (globs->archive_modified) {
+ printf ("(II) VFSStopCopyOperation: rebuilding tree.\n");
+ globs->zip->Flush ();
+ build_global_filelist (globs);
+ } else {
+ printf ("(II) VFSStartCopyOperation: doing nothing for the moment.\n");
+ }
+ Result = cVFS_OK;
+
+ return Result;
+}
+
+
/* Known issues:
* - crashes when no space left on NFS mounts, probably unhandled exception in further ZipArchive code (repro: Gentoo, Ubuntu)
*
@@ -1039,14 +1073,11 @@ VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDs
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;
/*
@@ -1068,7 +1099,6 @@ VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDs
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) {
@@ -1118,6 +1148,7 @@ VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDs
* - 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
+* - do something like start/stop operation for write, so that chmod/chown/utime calls can find newly packed file.
*
*/