diff options
| author | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2009-11-28 13:11:51 +0100 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2009-11-28 13:11:51 +0100 |
| commit | 9382f127ccebdd59917c97c61d008ed0e127cd75 (patch) | |
| tree | 0a48c8296199b343c76ef532eef014f908bc2e4d /unrar/unrar.c | |
| parent | 70eeaa4ec712895539ca6ecd60a42b93ec9b0904 (diff) | |
| download | tuxcmd-modules-0.6.72.tar.xz | |
Engine and VFS API cleanupv0.6.72
Also enable symlink resolving by default.
Diffstat (limited to 'unrar/unrar.c')
| -rw-r--r-- | unrar/unrar.c | 794 |
1 files changed, 414 insertions, 380 deletions
diff --git a/unrar/unrar.c b/unrar/unrar.c index 0db1493..61ce4c4 100644 --- a/unrar/unrar.c +++ b/unrar/unrar.c @@ -1,6 +1,6 @@ /* UNRAR plugin for Tux Commander - * version 0.3.7, designed for unrar v3.8.2 - * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net> + * version 0.4.0, designed for unrar v3.8.2 + * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net> * Check for updates on tuxcmd.sourceforge.net * * Uses UNRAR sources @@ -26,21 +26,17 @@ */ #include <string.h> +#include <stdio.h> #include <stdlib.h> -#include <stdint.h> -#include <sys/stat.h> -#include <sys/types.h> #include <errno.h> -#include <dirent.h> -#include <fnmatch.h> #include <unistd.h> #include <glib.h> -#include "vfs_types.h" +#include "tuxcmd-vfs.h" #include "vfsutils.h" #include "strutils.h" -#include "treepathutils.h" -#include "treepath_vfs.h" +#include "filelist.h" +#include "filelist-vfs-intf.h" #define _UNIX @@ -48,15 +44,20 @@ #include "unrar/dll.hpp" -// Compatibility types from headers.hpp +/* Compatibility types from headers.hpp */ enum HOST_SYSTEM { - HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4, - HOST_BEOS=5,HOST_MAX + HOST_MSDOS = 0, + HOST_OS2 = 1, + HOST_WIN32 = 2, + HOST_UNIX = 3, + HOST_MACOS = 4, + HOST_BEOS = 5, + HOST_MAX }; -#define VERSION "0.3.7" -#define BUILD_DATE "2009-10-25" +#define VERSION "0.4.0" +#define BUILD_DATE "2009-11-26" #define DEFAULT_BLOCK_SIZE 65536 @@ -64,7 +65,7 @@ enum HOST_SYSTEM { -// Declaration of the global plugin object +/* Declaration of the global plugin object */ struct TVFSGlobs { TVFSLogFunc log_func; char *curr_dir; @@ -75,15 +76,15 @@ struct TVFSGlobs { gboolean volume_missing_abort; char *password; - unsigned long block_size; + guint32 block_size; struct PathTree *files; struct VfsFilelistData *vfs_filelist; - int64_t total_size; + guint64 total_size; - int64_t extract_file_size; - int64_t extract_done; + guint64 extract_file_size; + guint64 extract_done; gboolean extract_cancelled; TVFSAskQuestionCallback callback_ask_question; @@ -100,13 +101,13 @@ struct TVFSGlobs { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////// // Basic initialization functions + struct TVFSGlobs * VFSNew (TVFSLogFunc log_func) { struct TVFSGlobs * globs; - globs = (struct TVFSGlobs *) malloc (sizeof (struct TVFSGlobs)); - memset (globs, 0, sizeof (struct TVFSGlobs)); + globs = g_malloc0 (sizeof (struct TVFSGlobs)); globs->block_size = DEFAULT_BLOCK_SIZE; globs->need_password = FALSE; @@ -120,7 +121,8 @@ VFSNew (TVFSLogFunc log_func) globs->callback_progress = NULL; globs->log_func = log_func; - if (globs->log_func != NULL) globs->log_func("unrar plugin: VFSInit"); + if (globs->log_func) + globs->log_func("unrar plugin: VFSInit"); return globs; } @@ -141,19 +143,23 @@ VFSSetCallbacks (struct TVFSGlobs *globs, void VFSFree (struct TVFSGlobs *globs) { - if (globs->log_func != NULL) globs->log_func("unrar plugin: VFSDestroy"); - free (globs); + if (globs->log_func) + globs->log_func("unrar plugin: VFSDestroy"); + g_free (globs); } -int VFSVersion() +int +VFSVersion () { return cVFSVersion; } struct TVFSInfo * -VFSGetInfo() +VFSGetInfo () { - struct TVFSInfo *module_info = g_malloc0 (sizeof (struct TVFSInfo)); + struct TVFSInfo *module_info; + + module_info = g_malloc0 (sizeof (struct TVFSInfo)); module_info->ID = g_strdup ("unrar_plugin"); module_info->Name = g_strdup ("UNRAR plugin"); @@ -174,77 +180,79 @@ VFSGetArchiveExts () /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ -int unrar_callback(UINT msg, LONG UserData, LONG P1, LONG P2) +static int +unrar_callback (UINT msg, LONG UserData, LONG P1, LONG P2) { + struct TVFSGlobs *globs; + // 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"); + fprintf (stderr, "(WW) unrar_callback: UserData == NULL, exiting!\n"); return 0; } - struct TVFSGlobs *globs = (struct TVFSGlobs *)UserData; + globs = (struct TVFSGlobs *) UserData; // >= 0 => Weiter, -1 => Stop - switch(msg) - { + switch (msg) { 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 (globs->callback_ask_question) { - static const char *choices[] = { - "Abort", /* response = 0 */ - "Ignore", /* response = 1 */ - NULL - }; - char *message, *s; - int choice = -1; - - s = g_filename_to_utf8 ((char *)P1, -1, NULL, NULL, NULL); - message = g_strdup_printf ("Archive is incomplete, volume missing: \n\n%s", s ? s : (char *)P1); - globs->callback_ask_question (message, &choices[0], &choice, 0, - globs->callback_data); - g_free (message); - if (s) g_free (s); - - if (choice != 1) - globs->volume_missing_abort = TRUE; - return -1; - } else { - 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; - } - } - } + fprintf (stderr, " (II) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_ASK, P1 = %ld, (char*)P1 = '%s' \n", P1, (char*)P1); + if (P1) { + if (globs->callback_ask_question) { + static const char *choices[] = { + "Abort", /* response = 0 */ + "Ignore", /* response = 1 */ + NULL + }; + char *message, *s; + int choice = -1; + + s = g_filename_display_name((char *)P1); + message = g_strdup_printf ("Archive is incomplete, volume missing: \n\n%s", s ? s : (char *)P1); + globs->callback_ask_question (message, &choices[0], &choice, 0, + globs->callback_data); + g_free (message); + g_free (s); + + if (choice != 1) + globs->volume_missing_abort = TRUE; + return -1; + } else { + 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); + fprintf (stderr, " (II) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_NOTIFY, P1 = %ld, (char*)P1 = '%s' \n", P1, (char*)P1); } break; } case UCM_PROCESSDATA: { - fprintf(stderr, " (II) unrar_callback: UCM_PROCESSDATA message, P1 = %ld, P2 = %ld \n", P1, P2); + fprintf (stderr, " (II) unrar_callback: UCM_PROCESSDATA message, P1 = %ld, P2 = %ld \n", P1, P2); // printf(" (II) unrar_callback: globs = 0x%lX, UserData = 0x%lX \n", (unsigned long int)globs, UserData); - 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->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 - } + 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->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 + } } break; } 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); + fprintf (stderr, " (II) unrar_callback: UCM_NEEDPASSWORD message, P1 = %ld, P2 = %ld, (char*)P1 = '%s', maxlen = %ld \n", P1, P2, (char*)P1, P2); char *passwd = NULL; int res = FALSE; @@ -258,8 +266,8 @@ int unrar_callback(UINT msg, LONG UserData, LONG P1, LONG P2) 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); + strncpy ((char *)P1, passwd, P2); + g_free (globs->password); globs->password = g_strdup (passwd); } g_free (passwd); @@ -277,22 +285,25 @@ int unrar_callback(UINT msg, LONG UserData, LONG P1, LONG P2) return 0; } -int PASCAL unrar_changevol_proc(char *ArcName, int Mode) +static int PASCAL +unrar_changevol_proc (char *ArcName, int Mode) { - fprintf(stderr, "(II) unrar_changevol_proc called: ArcName = '%s', Mode = %d\n", ArcName, Mode); + fprintf (stderr, "(II) unrar_changevol_proc called: ArcName = '%s', Mode = %d\n", ArcName, Mode); return 0; } -int PASCAL unrar_process_data_proc(unsigned char *Addr, int Size) +static int PASCAL +unrar_process_data_proc (unsigned char *Addr, int Size) { - fprintf(stderr, "(II) unrar_process_data_proc called: Addr = '%s', Size = %d\n", Addr, Size); + fprintf (stderr, "(II) unrar_process_data_proc called: Addr = '%s', Size = %d\n", Addr, Size); return 0; } -time_t rar_time_to_unix(unsigned int FileTime) +static time_t +rar_time_to_unix (unsigned int FileTime) { struct tm t; t.tm_sec = (FileTime & 0x1f) * 2; @@ -303,146 +314,155 @@ time_t rar_time_to_unix(unsigned int FileTime) t.tm_year = (FileTime >> 25) + 80; t.tm_isdst = -1; // printf("date: %d-%.2d-%.2d %d:%.2d:%.2d \n", t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); - return(mktime(&t)); + return (mktime(&t)); } -TVFSResult VFSOpenArchive(struct TVFSGlobs *globs, char *sName) +/* ----------------------------------------------------------------------------------------------------------- */ + +TVFSResult +VFSOpenArchive (struct TVFSGlobs *globs, const char *sName) { - TVFSResult Result = cVFS_OK; + TVFSResult Result; + HANDLE PASCAL handle; + struct RAROpenArchiveDataEx *archive_data; - globs->files = filelist_tree_new(); - globs->vfs_filelist = vfs_filelist_new(globs->files); + Result = cVFS_OK; + + globs->files = filelist_tree_new (); + globs->vfs_filelist = vfs_filelist_new (globs->files); globs->curr_dir = NULL; - globs->archive_path = strdup(sName); + globs->archive_path = g_strdup (sName); globs->total_size = 0; globs->failed_passwd_callback = FALSE; globs->volume_missing_abort = FALSE; - fprintf(stderr, "(--) VFSOpenArchive: trying to open archive '%s'...\n", globs->archive_path); - - HANDLE PASCAL handle; - struct RAROpenArchiveDataEx *archive_data; + fprintf (stderr, "(--) VFSOpenArchive: trying to open archive '%s'...\n", globs->archive_path); - archive_data = (struct RAROpenArchiveDataEx*) malloc(sizeof(struct RAROpenArchiveDataEx)); - memset(archive_data, 0, sizeof(struct RAROpenArchiveDataEx)); + /* 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->CmtBuf = NULL; archive_data->CmtBufSize = 0; archive_data->OpenMode = RAR_OM_LIST; - handle = RAROpenArchiveEx(archive_data); + 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 - RARSetCallback(handle, unrar_callback, (LONG)globs); -// RARSetChangeVolProc(handle, unrar_changevol_proc); -// RARSetProcessDataProc(handle, unrar_process_data_proc); - - if (globs->password) { - fprintf(stderr, "(II) VFSOpenArchive: Setting password... \n"); - RARSetPassword(handle, globs->password); - } - - struct RARHeaderDataEx *header; - header = (struct RARHeaderDataEx*) malloc(sizeof(struct RARHeaderDataEx)); - memset(header, 0, sizeof(struct RARHeaderDataEx)); - header->CmtBuf = NULL; - header->CmtBufSize = 0; - - int PASCAL res = 0; - while ((res = RARReadHeaderEx(handle, header)) == 0) - { -// printf(" header->FileName = '%s', Flags = 0x%x\n", header->FileName, header->Flags); - - // Create a TVFSItem entry and fill all info - struct TVFSItem *item = (struct TVFSItem*)malloc(sizeof(struct TVFSItem)); - memset(item, 0, sizeof(struct TVFSItem)); - - item->iSize = (int64_t)((int64_t)(header->UnpSizeHigh * 0x100000000) + (int64_t)header->UnpSize); - item->iPackedSize = (int64_t)((int64_t)(header->PackSizeHigh * 0x100000000) + (int64_t)header->PackSize); - globs->total_size += item->iSize; - if ((header->Flags & 0x00e0 /* LHD_WINDOWMASK */ ) == 0x00e0 /* LHD_DIRECTORY */) - item->ItemType = vDirectory; - else item->ItemType = vRegular; - if ((header->Flags & 0x0004) == 0x0004) globs->need_password = TRUE; - - switch (header->HostOS) - { - case HOST_MSDOS: - case HOST_OS2: - case HOST_WIN32: - if (header->FileAttr & 0x10) header->FileAttr = 0x41ff | header->FileAttr; - else - if (header->FileAttr & 1) header->FileAttr = 0x8124 | header->FileAttr; - else header->FileAttr = 0x81b6 | header->FileAttr; - break; - } - - item->iMode = header->FileAttr; - item->iUID = geteuid(); - item->iGID = getegid(); - item->m_time = rar_time_to_unix(header->FileTime); - item->c_time = item->m_time; - item->a_time = item->m_time; - -// g_print (" valid = %d\n", g_utf8_validate (header->FileName, -1, NULL)); - - char *s; - if (g_utf8_validate (header->FileName, -1, NULL)) - s = g_strdup (header->FileName); - else - s = wide_to_utf8 (header->FileNameW); -// g_print (" ansi = '%s'\n wide = '%ls'\n utf8 = '%s'\n", header->FileName, header->FileNameW, s); - - // Add item to the global list and continue with next file - filelist_tree_add_item(globs->files, s, header->FileName, item, 0); - g_free (s); - - int PASCAL res2 = RARProcessFile(handle, RAR_SKIP, NULL, NULL); - if (res2) printf("RARProcessFile result = %d\n", res2); - } -// printf("\nRARReadHeader result = %d\n", res); - if (res != ERAR_END_ARCHIVE || globs->volume_missing_abort) { - fprintf(stderr, "(EE) VFSOpenArchive: RARReadHeader result = %d\n", res); - Result = cVFS_Failed; - if ((res == ERAR_MISSING_PASSWORD) || ((res == ERAR_BAD_DATA) && (globs->failed_passwd_callback))) - Result = cVFS_BadPassword; - } - free(header); - - res = RARCloseArchive(handle); - if (res) { - fprintf(stderr, "(EE) VFSOpenArchive: RARCloseArchive result = %d\n", res); - } + if (handle && ! archive_data->OpenResult) { + // Set callbacks + RARSetCallback (handle, unrar_callback, (LONG)globs); +// RARSetChangeVolProc(handle, unrar_changevol_proc); +// RARSetProcessDataProc(handle, unrar_process_data_proc); + + if (globs->password) { + fprintf (stderr, "(II) VFSOpenArchive: 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 PASCAL res = 0; + while ((res = RARReadHeaderEx(handle, header)) == 0) { +// printf(" header->FileName = '%s', Flags = 0x%x\n", header->FileName, header->Flags); + + /* Create a TVFSItem entry and fill all info */ + struct TVFSItem *item = g_malloc0 (sizeof (struct TVFSItem)); + + item->iSize = (guint64)((guint64)(header->UnpSizeHigh * 0x100000000) + (guint64)header->UnpSize); + item->iPackedSize = (guint64)((guint64)(header->PackSizeHigh * 0x100000000) + (guint64)header->PackSize); + globs->total_size += item->iSize; + if ((header->Flags & 0x00e0 /* LHD_WINDOWMASK */ ) == 0x00e0 /* LHD_DIRECTORY */) + item->ItemType = vDirectory; + else + item->ItemType = vRegular; + if ((header->Flags & 0x0004) == 0x0004) + globs->need_password = TRUE; + + switch (header->HostOS) { + case HOST_MSDOS: + case HOST_OS2: + case HOST_WIN32: + if (header->FileAttr & 0x10) + header->FileAttr = 0x41ff | header->FileAttr; + else + if (header->FileAttr & 1) + header->FileAttr = 0x8124 | header->FileAttr; + else + header->FileAttr = 0x81b6 | header->FileAttr; + break; + } + + item->iMode = header->FileAttr; + item->iUID = geteuid (); + item->iGID = getegid (); + item->m_time = rar_time_to_unix (header->FileTime); + item->c_time = item->m_time; + item->a_time = item->m_time; + +// g_print (" valid = %d\n", g_utf8_validate (header->FileName, -1, NULL)); + + char *s; + if (g_utf8_validate (header->FileName, -1, NULL)) + s = g_strdup (header->FileName); + else + s = wide_to_utf8 (header->FileNameW); +// g_print (" ansi = '%s'\n wide = '%ls'\n utf8 = '%s'\n", header->FileName, header->FileNameW, s); + + // Add item to the global list and continue with next file + filelist_tree_add_item (globs->files, s, item, header->FileName, 0); + g_free (s); + + int PASCAL res2 = RARProcessFile (handle, RAR_SKIP, NULL, NULL); + if (res2) + printf ("RARProcessFile result = %d\n", res2); + } +// printf("\nRARReadHeader result = %d\n", res); + if (res != ERAR_END_ARCHIVE || globs->volume_missing_abort) { + fprintf (stderr, "(EE) VFSOpenArchive: RARReadHeader result = %d\n", res); + Result = cVFS_Failed; + if (res == ERAR_MISSING_PASSWORD || (res == ERAR_BAD_DATA && globs->failed_passwd_callback)) + Result = cVFS_BadPassword; + } + free (header); + + res = RARCloseArchive(handle); + if (res) + fprintf (stderr, "(EE) VFSOpenArchive: RARCloseArchive result = %d\n", res); } else { - fprintf(stderr, "(EE) VFSOpenArchive: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult); - Result = cVFS_Failed; + fprintf (stderr, "(EE) VFSOpenArchive: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult); + Result = cVFS_Failed; } - free(archive_data); - fprintf(stderr, "(II) VFSOpenArchive: done. \n"); - if (globs->need_password) printf("Password present.\n"); - printf("\n\nList of items:\n"); - filelist_tree_print(globs->files); + free (archive_data); + fprintf (stderr, "(II) VFSOpenArchive: done. \n"); + if (globs->need_password) + printf ("Password present.\n"); + printf ("\n\nList of items:\n"); + filelist_tree_print (globs->files); return Result; } -TVFSResult VFSClose(struct TVFSGlobs *globs) +TVFSResult +VFSClose (struct TVFSGlobs *globs) { if (globs) { - fprintf(stderr, "(II) VFSClose: Freeing objects...\n"); - if (globs->vfs_filelist) vfs_filelist_free(globs->vfs_filelist); - if (globs->files) filelist_tree_free(globs->files); - if (globs->archive_path) free(globs->archive_path); - if (globs->curr_dir) free(globs->curr_dir); - if (globs->password) free(globs->password); + fprintf (stderr, "(II) VFSClose: Freeing objects...\n"); + if (globs->vfs_filelist) + vfs_filelist_free(globs->vfs_filelist); + if (globs->files) + filelist_tree_free(globs->files); + g_free (globs->archive_path); + g_free (globs->curr_dir); + g_free (globs->password); } return cVFS_OK; } @@ -453,42 +473,48 @@ VFSGetPath (struct TVFSGlobs *globs) return include_trailing_path_sep (globs->curr_dir); } -u_int64_t VFSGetFileSystemFree(struct TVFSGlobs *globs, char *APath) +TVFSResult +VFSGetFileSystemInfo (struct TVFSGlobs *globs, const char *APath, gint64 *FSSize, gint64 *FSFree, char **FSLabel) { - return 0; -} - -u_int64_t VFSGetFileSystemSize(struct TVFSGlobs *globs, char *APath) -{ - return globs->total_size; + if (FSSize) + *FSSize = globs->total_size; + if (FSFree) + *FSFree = 0; + if (FSLabel) + *FSLabel = NULL; + return cVFS_OK; } - - /******************************************************************************************************/ -TVFSResult VFSChangeDir(struct TVFSGlobs *globs, char *NewPath) +TVFSResult +VFSChangeDir (struct TVFSGlobs *globs, const char *NewPath) { if (NewPath == NULL) { - printf("(EE) VFSChangeDir: NewPath is NULL!\n"); + printf ("(EE) VFSChangeDir: NewPath is NULL!\n"); return cVFS_Failed; } - globs->curr_dir = vfs_filelist_change_dir(globs->vfs_filelist, NewPath); - if (globs->curr_dir) return cVFS_OK; - else return cVFS_Failed; + globs->curr_dir = vfs_filelist_change_dir (globs->vfs_filelist, NewPath); + if (globs->curr_dir) + return cVFS_OK; + else + return cVFS_Failed; } -int VFSGetPasswordRequired(struct TVFSGlobs *globs) +gboolean +VFSGetPasswordRequired (struct TVFSGlobs *globs) { - if (globs) return globs->need_password; + if (globs) + return globs->need_password; return FALSE; } -void VFSResetPassword(struct TVFSGlobs *globs) +void +VFSResetPassword (struct TVFSGlobs *globs) { - if (globs && globs->password) { + if (globs) { g_free (globs->password); globs->password = NULL; } @@ -497,40 +523,41 @@ void VFSResetPassword(struct TVFSGlobs *globs) /******************************************************************************************************/ -TVFSResult VFSListFirst(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) +TVFSResult +VFSListFirst (struct TVFSGlobs *globs, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath) { if (sDir == NULL) { - printf("(EE) VFSListFirst: sDir is NULL!\n"); + printf ("(EE) VFSListFirst: sDir is NULL!\n"); return cVFS_Failed; } printf ("(--) VFSListFirst: Going to list all items in '%s'\n", sDir); - return vfs_filelist_list_first(globs->vfs_filelist, sDir, Item); + return vfs_filelist_list_first (globs->vfs_filelist, sDir, Item, FollowSymlinks, AddFullPath); } -TVFSResult VFSListNext(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) +TVFSResult +VFSListNext (struct TVFSGlobs *globs, struct TVFSItem *Item) { - return vfs_filelist_list_next(globs->vfs_filelist, sDir, Item); + return vfs_filelist_list_next (globs->vfs_filelist, Item); } -TVFSResult VFSListClose(struct TVFSGlobs *globs) +TVFSResult +VFSListClose (struct TVFSGlobs *globs) { - return vfs_filelist_list_close(globs->vfs_filelist); + return vfs_filelist_list_close (globs->vfs_filelist); } /******************************************************************************************************/ -long VFSFileExists(struct TVFSGlobs *globs, const char *FileName, const long Use_lstat) -{ - if (! globs) return FALSE; - return vfs_filelist_file_exists(globs->vfs_filelist, FileName, Use_lstat); -} -TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item) +TVFSResult +VFSFileInfo (struct TVFSGlobs *globs, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath) { - printf("(--) VFSFileInfo: requested info for object '%s'\n", AFileName); - if (!globs) return cVFS_Failed; - return vfs_filelist_file_info(globs->vfs_filelist, AFileName, Item); + printf ("(--) VFSFileInfo: requested info for object '%s'\n", AFileName); + if (! globs) + return cVFS_Failed; + + return vfs_filelist_file_info (globs->vfs_filelist, AFileName, Item, FollowSymlinks, AddFullPath); } @@ -538,16 +565,21 @@ TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem /** Recursive tree size counting */ /************** ****************/ -u_int64_t VFSGetDirSize(struct TVFSGlobs *globs, char *APath) +guint64 +VFSGetDirSize (struct TVFSGlobs *globs, const char *APath) { - if (! globs) return 0; - return vfs_filelist_get_dir_size(globs->vfs_filelist, APath); + if (! globs) + return 0; + + return vfs_filelist_get_dir_size (globs->vfs_filelist, APath); } -void VFSBreakGetDirSize(struct TVFSGlobs *globs) +void +VFSBreakGetDirSize (struct TVFSGlobs *globs) { - printf("(WW) VFSBreakGetDirSize: calling break\n"); - if (globs) vfs_filelist_get_dir_size_break(globs->vfs_filelist); + printf ("(WW) VFSBreakGetDirSize: calling break\n"); + if (globs) + vfs_filelist_get_dir_size_break (globs->vfs_filelist); } @@ -555,45 +587,45 @@ void VFSBreakGetDirSize(struct TVFSGlobs *globs) /** Methods modifying the archive */ /************** ****************/ -TVFSResult VFSMkDir(struct TVFSGlobs *globs, const char *sDirName) +TVFSResult VFSMkDir (struct TVFSGlobs *globs, const char *sDirName) { - printf("(WW) VFSMkDir: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSMkDir: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSRemove(struct TVFSGlobs *globs, const char *APath) +TVFSResult VFSRemove (struct TVFSGlobs *globs, const char *APath) { - printf("(WW) VFSRemove: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSRemove: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSRename(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName) +TVFSResult VFSRename (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName) { - printf("(WW) VFSRename: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSRename: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSMakeSymLink(struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo) +TVFSResult VFSMakeSymLink (struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo) { - printf("(WW) VFSMakeSymLink: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSMakeSymLink: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSChmod(struct TVFSGlobs *globs, const char *FileName, const uint Mode) +TVFSResult VFSChmod (struct TVFSGlobs *globs, const char *FileName, guint32 Mode) { - printf("(WW) VFSChmod: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSChmod: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSChown(struct TVFSGlobs *globs, const char *FileName, const uint UID, const uint GID) +TVFSResult VFSChown (struct TVFSGlobs *globs, const char *FileName, guint32 UID, guint32 GID) { - printf("(WW) VFSChown: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSChown: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSChangeTimes(struct TVFSGlobs *globs, char *APath, long mtime, long atime) +TVFSResult VFSChangeTimes (struct TVFSGlobs *globs, const char *APath, guint32 mtime, guint32 atime) { - printf("(WW) VFSChangeTimes: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSChangeTimes: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } @@ -631,21 +663,25 @@ int VFSWriteFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buff return 0; } -void VFSSetBlockSize(struct TVFSGlobs *globs, int Value) +void +VFSSetBlockSize (struct TVFSGlobs *globs, guint32 Value) { - globs->block_size = Value; + if (globs) + globs->block_size = Value; } -int VFSIsOnSameFS(struct TVFSGlobs *globs, const char *Path1, const char *Path2) +gboolean +VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks) { - printf("(WW) VFSIsOnSameFS: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSIsOnSameFS: Not supported in UNRAR plugin.\n"); return TRUE; } -int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path2) +gboolean +VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks) { - printf("(WW) VFSTwoSameFiles: Not supported in RAR archives, comparing by paths.\n"); - return compare_two_same_files(Path1, Path2); + printf ("(WW) VFSTwoSameFiles: Not supported in RAR archives, comparing by paths.\n"); + return compare_two_same_files (Path1, Path2); } @@ -653,168 +689,166 @@ int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path //////////////////////// -TVFSResult VFSCopyToLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append) +TVFSResult +VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append) { - 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"); + struct PathTree *node; + TVFSResult Result; + gboolean found; + char *src; + + 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; } - printf("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName); + printf ("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName); - struct PathTree *node = filelist_tree_find_node_by_path(globs->files, sSrcName); + node = filelist_tree_find_node_by_path (globs->files, sSrcName); if (! node) { - fprintf(stderr, "(EE) VFSCopyToLocal: cannot find file '%s'\n", sSrcName); + fprintf (stderr, "(EE) VFSCopyToLocal: cannot find file '%s'\n", sSrcName); return cVFS_ReadErr; } - TVFSResult Result = cVFS_OK; - gboolean found = FALSE; + Result = cVFS_OK; + found = FALSE; - char *src = node->original_pathstr; + src = node->original_pathstr; if (! src) { - fprintf(stderr, "(WW) VFSCopyToLocal: cannot determine original filename\n"); - src = (char *)sSrcName; + fprintf (stderr, "(WW) VFSCopyToLocal: cannot determine original filename\n"); + src = (char *) sSrcName; } - printf("(II) VFSCopyToLocal: new src path: '%s'\n", src); + printf ("(II) VFSCopyToLocal: new src path: '%s'\n", src); HANDLE PASCAL handle; struct RAROpenArchiveDataEx *archive_data; - archive_data = (struct RAROpenArchiveDataEx*) malloc(sizeof(struct RAROpenArchiveDataEx)); - memset(archive_data, 0, sizeof(struct RAROpenArchiveDataEx)); + /* 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->CmtBuf = NULL; - archive_data->CmtBufSize = 0; archive_data->OpenMode = RAR_OM_EXTRACT; - handle = RAROpenArchiveEx(archive_data); + 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)) + 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); - - if (globs->password) { - printf("(II) VFSCopyToLocal: Setting password... \n"); - RARSetPassword(handle, globs->password); - } - - struct RARHeaderDataEx *header; - header = (struct RARHeaderDataEx*) malloc(sizeof(struct RARHeaderDataEx)); - memset(header, 0, sizeof(struct RARHeaderDataEx)); - header->CmtBuf = NULL; - header->CmtBufSize = 0; - - int res = 0; - while ((res = RARReadHeaderEx(handle, header)) == 0) - { - char *ssrc = src; - char *asrc = header->FileName; - if (IS_DIR_SEP(*ssrc)) ssrc++; - if (IS_DIR_SEP(*asrc)) asrc++; - if (strcmp(ssrc, asrc) == 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 = (int64_t)((int64_t)(header->UnpSizeHigh * 0x100000000) + (int64_t)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; - } - } - } - - 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; - if (globs->password) { - g_free (globs->password); - globs->password = NULL; - } - break; - case ERAR_UNKNOWN: - default: - Result = cVFS_WriteErr; - break; - } - } - } - - free(header); - - res = RARCloseArchive(handle); - if (res) { - fprintf(stderr, "(EE) VFSCopyToLocal: RARCloseArchive result = %d\n", res); - Result = cVFS_ReadErr; - } + // 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); + + 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; + while ((res = RARReadHeaderEx(handle, header)) == 0) { + 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; + } + } + } + + 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; + } + } + } + + free (header); + + res = RARCloseArchive (handle); + if (res) { + fprintf (stderr, "(EE) VFSCopyToLocal: RARCloseArchive result = %d\n", res); + Result = cVFS_ReadErr; + } } else { - fprintf(stderr, "(EE) VFSCopyToLocal: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult); - Result = cVFS_ReadErr; + fprintf (stderr, "(EE) VFSCopyToLocal: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult); + Result = cVFS_ReadErr; } - free(archive_data); + free (archive_data); - if ((! found) && Result == cVFS_OK) { - fprintf(stderr, "(EE) VFSCopyToLocal: file not found in archive.\n"); + if (! found && Result == cVFS_OK) { + fprintf (stderr, "(EE) VFSCopyToLocal: file not found in archive.\n"); Result = cVFS_ReadErr; } - fprintf(stderr, "(II) VFSCopyToLocal: finished. \n"); + fprintf (stderr, "(II) VFSCopyToLocal: finished. \n"); return Result; } -TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append) +TVFSResult +VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append) { - printf("(WW) VFSCopyFromLocal: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSCopyFromLocal: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } @@ -824,7 +858,7 @@ TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const /********** * TODO: * - * - UTF-8, FName/FDisplayName and absolute/relative paths revision needed! + * DONE - 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 -- hopefully fixed by ask_question callback * - archive testing (needs new VFS API) |
