diff options
| author | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2009-11-29 16:35:02 +0100 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2009-11-29 16:35:02 +0100 |
| commit | 01072f4baa7ae333e796800d8a17aa157fe08a4e (patch) | |
| tree | 3c18844c391e2d7838e23de22f06bbef7db5e637 | |
| parent | 736d90da1b6cee6333889912513c634d55004d90 (diff) | |
| download | tuxcmd-modules-0.6.73.tar.xz | |
Introduce copy operation start/stop callsv0.6.73
| -rw-r--r-- | libarchive/libarchive.c | 94 | ||||
| -rw-r--r-- | unrar/unrar.c | 255 | ||||
| -rw-r--r-- | zip/zip.cpp | 45 |
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. * */ |
