summaryrefslogtreecommitdiff
path: root/unrar/unrar.c
diff options
context:
space:
mode:
Diffstat (limited to 'unrar/unrar.c')
-rw-r--r--unrar/unrar.c254
1 files changed, 147 insertions, 107 deletions
diff --git a/unrar/unrar.c b/unrar/unrar.c
index 1d5a595..a022775 100644
--- a/unrar/unrar.c
+++ b/unrar/unrar.c
@@ -1,5 +1,5 @@
/* UNRAR plugin for Tux Commander
- * version 0.4.1, designed for unrar v3.8.2
+ * version 0.4.2, designed for unrar v3.8.2
* Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
@@ -31,6 +31,7 @@
#include <errno.h>
#include <unistd.h>
#include <glib.h>
+#include <gio/gio.h>
#include "tuxcmd-vfs.h"
#include "vfsutils.h"
@@ -56,8 +57,8 @@ enum HOST_SYSTEM {
};
-#define VERSION "0.4.1"
-#define BUILD_DATE "2009-11-29"
+#define VERSION "0.4.2"
+#define BUILD_DATE "2009-12-12"
#define DEFAULT_BLOCK_SIZE 65536
@@ -83,7 +84,6 @@ struct TVFSGlobs {
guint64 total_size;
- guint64 extract_file_size;
guint64 extract_done;
gboolean extract_cancelled;
@@ -255,7 +255,7 @@ unrar_callback (UINT msg, LONG UserData, LONG P1, LONG P2)
// 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;
- gboolean res = globs->callback_progress(globs->extract_done, globs->extract_file_size, globs->callback_data);
+ gboolean res = globs->callback_progress(globs->extract_done, NULL, globs->callback_data);
// fprintf(stderr, " (II) unrar_callback: res = %d \n", res);
if (! res ) {
@@ -317,6 +317,7 @@ unrar_process_data_proc (unsigned char *Addr, int Size)
return 0;
}
+/* ----------------------------------------------------------------------------------------------------------- */
static time_t
rar_time_to_unix (unsigned int FileTime)
@@ -334,17 +335,68 @@ rar_time_to_unix (unsigned int FileTime)
}
+/* TODO: find proper verbose explanation for each error. */
+static void
+rar_error_to_gerror (int code, GError **error)
+{
+ switch (code) {
+ case ERAR_END_ARCHIVE:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, "Unexpected end of archive.");
+ break;
+ case ERAR_NO_MEMORY:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Memory allocation failed.");
+ break;
+ case ERAR_BAD_DATA:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Bad data.");
+ break;
+ case ERAR_BAD_ARCHIVE:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Bad archive.");
+ break;
+ case ERAR_UNKNOWN_FORMAT:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Unknown format.");
+ break;
+ case ERAR_EOPEN:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Open error.");
+ break;
+ case ERAR_ECREATE:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, "Create error.");
+ break;
+ case ERAR_ECLOSE:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, "Close error.");
+ break;
+ case ERAR_EREAD:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Read error.");
+ break;
+ case ERAR_EWRITE:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Write error.");
+ break;
+ case ERAR_SMALL_BUF:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Small buffer error.");
+ break;
+ case ERAR_UNKNOWN:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_UNKNOWN, "Unknown error.");
+ break;
+ case ERAR_MISSING_PASSWORD:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, "Missing password.");
+ break;
+ default:
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Operation failed.");
+ break;
+ }
+}
+
+
/* ----------------------------------------------------------------------------------------------------------- */
-TVFSResult
-VFSOpenArchive (struct TVFSGlobs *globs, const char *sName)
+gboolean
+VFSOpenArchive (struct TVFSGlobs *globs, const char *sName, GError **error)
{
- TVFSResult Result;
HANDLE PASCAL handle;
struct RAROpenArchiveDataEx *archive_data;
guint64 inode_no;
+ gboolean Result;
- Result = cVFS_OK;
+ Result = TRUE;
globs->files = filelist_tree_new ();
globs->vfs_filelist = vfs_filelist_new (globs->files);
@@ -447,9 +499,12 @@ VFSOpenArchive (struct TVFSGlobs *globs, const char *sName)
// 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;
+ rar_error_to_gerror (res, error);
+ Result = FALSE;
+/* TODO:
if (res == ERAR_MISSING_PASSWORD || (res == ERAR_BAD_DATA && globs->failed_passwd_callback))
Result = cVFS_BadPassword;
+*/
}
free (header);
@@ -458,7 +513,8 @@ VFSOpenArchive (struct TVFSGlobs *globs, const char *sName)
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;
+ rar_error_to_gerror (archive_data->OpenResult, error);
+ Result = FALSE;
}
free (archive_data);
@@ -472,8 +528,8 @@ VFSOpenArchive (struct TVFSGlobs *globs, const char *sName)
}
-TVFSResult
-VFSClose (struct TVFSGlobs *globs)
+gboolean
+VFSClose (struct TVFSGlobs *globs, GError **error)
{
if (globs) {
fprintf (stderr, "(II) VFSClose: Freeing objects...\n");
@@ -485,7 +541,7 @@ VFSClose (struct TVFSGlobs *globs)
g_free (globs->curr_dir);
g_free (globs->password);
}
- return cVFS_OK;
+ return TRUE;
}
char *
@@ -494,7 +550,7 @@ VFSGetPath (struct TVFSGlobs *globs)
return include_trailing_path_sep (globs->curr_dir);
}
-TVFSResult
+void
VFSGetFileSystemInfo (struct TVFSGlobs *globs, const char *APath, gint64 *FSSize, gint64 *FSFree, char **FSLabel)
{
if (FSSize)
@@ -503,25 +559,23 @@ VFSGetFileSystemInfo (struct TVFSGlobs *globs, const char *APath, gint64 *FSSize
*FSFree = 0;
if (FSLabel)
*FSLabel = NULL;
- return cVFS_OK;
}
/******************************************************************************************************/
-TVFSResult
-VFSChangeDir (struct TVFSGlobs *globs, const char *NewPath)
+gboolean
+VFSChangeDir (struct TVFSGlobs *globs, const char *NewPath, GError **error)
{
- if (NewPath == NULL) {
- printf ("(EE) VFSChangeDir: NewPath is NULL!\n");
- return cVFS_Failed;
- }
+ char *s;
- globs->curr_dir = vfs_filelist_change_dir (globs->vfs_filelist, NewPath);
- if (globs->curr_dir)
- return cVFS_OK;
+ s = vfs_filelist_change_dir (globs->vfs_filelist, NewPath, error);
+ if (s) {
+ globs->curr_dir = s;
+ return TRUE;
+ }
else
- return cVFS_Failed;
+ return FALSE;
}
gboolean
@@ -544,41 +598,35 @@ VFSResetPassword (struct TVFSGlobs *globs)
/******************************************************************************************************/
-TVFSResult
-VFSListFirst (struct TVFSGlobs *globs, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath)
+struct TVFSItem *
+VFSListFirst (struct TVFSGlobs *globs, const char *sDir, gboolean FollowSymlinks, gboolean AddFullPath, GError **error)
{
- if (sDir == NULL) {
- 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, FollowSymlinks, AddFullPath);
+ return vfs_filelist_list_first (globs->vfs_filelist, sDir, FollowSymlinks, AddFullPath, error);
}
-TVFSResult
-VFSListNext (struct TVFSGlobs *globs, struct TVFSItem *Item)
+struct TVFSItem *
+VFSListNext (struct TVFSGlobs *globs, GError **error)
{
- return vfs_filelist_list_next (globs->vfs_filelist, Item);
+ return vfs_filelist_list_next (globs->vfs_filelist, error);
}
-TVFSResult
-VFSListClose (struct TVFSGlobs *globs)
+gboolean
+VFSListClose (struct TVFSGlobs *globs, GError **error)
{
- return vfs_filelist_list_close (globs->vfs_filelist);
+ return vfs_filelist_list_close (globs->vfs_filelist, error);
}
/******************************************************************************************************/
-TVFSResult
-VFSFileInfo (struct TVFSGlobs *globs, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath)
+struct TVFSItem *
+VFSFileInfo (struct TVFSGlobs *globs, const char *AFileName, gboolean FollowSymlinks, gboolean AddFullPath, GError **error)
{
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);
+ return vfs_filelist_file_info (globs->vfs_filelist, AFileName, FollowSymlinks, AddFullPath, error);
}
@@ -608,6 +656,7 @@ VFSBreakGetDirSize (struct TVFSGlobs *globs)
/** Methods modifying the archive */
/************** ****************/
+#if 0
TVFSResult VFSMkDir (struct TVFSGlobs *globs, const char *sDirName)
{
printf ("(WW) VFSMkDir: Not supported in UNRAR plugin.\n");
@@ -649,12 +698,13 @@ TVFSResult VFSChangeTimes (struct TVFSGlobs *globs, const char *APath, guint32 m
printf ("(WW) VFSChangeTimes: Not supported in UNRAR plugin.\n");
return cVFS_Not_Supported;
}
-
+#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////
+#if 0
TVFSFileDes VFSOpenFile(struct TVFSGlobs *globs, const char *APath, int Mode, int *Error)
{
*Error = cVFS_Not_Supported;
@@ -683,6 +733,7 @@ int VFSWriteFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buff
*Error = cVFS_Not_Supported;
return 0;
}
+#endif
void
VFSSetBlockSize (struct TVFSGlobs *globs, guint32 Value)
@@ -710,19 +761,20 @@ VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2,
////////////////////////
-TVFSResult
-VFSStartCopyOperation (struct TVFSGlobs *globs)
+gboolean
+VFSStartCopyOperation (struct TVFSGlobs *globs, GError **error)
{
- TVFSResult Result;
struct RAROpenArchiveDataEx *archive_data;
HANDLE PASCAL handle;
+ gboolean Result;
- g_return_val_if_fail (globs != NULL, cVFS_Failed);
- g_return_val_if_fail (globs->op_handle == NULL, cVFS_Failed);
-
+ if (globs->op_handle != NULL) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED, "globs->op_handle != NULL");
+ return FALSE;
+ }
printf ("(II) VFSStartCopyOperation: opening archive '%s'\n", globs->archive_path);
- Result = cVFS_Failed;
+ Result = FALSE;
/* WARNING: do not use g_malloc0() here, leads to memory corruption */
archive_data = malloc (sizeof (struct RAROpenArchiveDataEx));
@@ -750,10 +802,11 @@ VFSStartCopyOperation (struct TVFSGlobs *globs)
}
globs->op_handle = handle;
- Result = cVFS_OK;
+ Result = TRUE;
} else {
fprintf (stderr, "(EE) VFSStartCopyOperation: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult);
- Result = cVFS_ReadErr;
+ rar_error_to_gerror (archive_data->OpenResult, error);
+ Result = FALSE;
}
free (archive_data);
@@ -761,21 +814,25 @@ VFSStartCopyOperation (struct TVFSGlobs *globs)
}
-TVFSResult
-VFSStopCopyOperation (struct TVFSGlobs *globs)
+gboolean
+VFSStopCopyOperation (struct TVFSGlobs *globs, GError **error)
{
- TVFSResult Result;
int res;
- g_return_val_if_fail (globs != NULL, cVFS_Failed);
- g_return_val_if_fail (globs->op_handle != NULL, cVFS_Failed);
+ gboolean Result;
+
+ if (globs->op_handle == NULL) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED, "globs->op_handle == NULL");
+ return FALSE;
+ }
printf ("(II) VFSStopCopyOperation: closing archive.\n");
- Result = cVFS_OK;
+ Result = TRUE;
res = RARCloseArchive (globs->op_handle);
if (res) {
fprintf (stderr, "(EE) VFSCopyToLocal: RARCloseArchive result = %d\n", res);
- Result = cVFS_ReadErr;
+ rar_error_to_gerror (res, error);
+ Result = FALSE;
}
globs->op_handle = NULL;
@@ -783,19 +840,22 @@ VFSStopCopyOperation (struct TVFSGlobs *globs)
}
-TVFSResult
-VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append)
+gboolean
+VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append, GError **error)
{
struct PathTree *node;
- TVFSResult Result;
gboolean found;
+ gboolean Result;
char *src;
- g_return_val_if_fail (globs->op_handle != NULL, cVFS_ReadErr);
-
- if (sSrcName == NULL || sDstName == NULL || strlen (sSrcName) < 1 || strlen (sDstName) < 1) {
+ if (globs->op_handle == NULL) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "globs->op_handle == NULL");
+ return FALSE;
+ }
+ 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;
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "The value of 'sSrcName' or 'sDstName' is NULL or empty.");
+ return FALSE;
}
printf ("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName);
@@ -803,7 +863,8 @@ VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstN
node = filelist_tree_find_node_by_path (globs->files, sSrcName);
if (! node) {
fprintf (stderr, "(EE) VFSCopyToLocal: cannot find file '%s'\n", sSrcName);
- return cVFS_ReadErr;
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "cannot find file '%s'", sSrcName);
+ return FALSE;
}
src = node->original_pathstr;
@@ -820,14 +881,13 @@ VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstN
int res = 0;
found = FALSE;
- Result = cVFS_OK;
+ Result = TRUE;
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;
@@ -835,19 +895,22 @@ VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstN
if (globs->extract_cancelled) {
fprintf (stderr, "(WW) VFSCopyToLocal: cancelled !\n");
- Result = cVFS_Cancelled;
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Operation has been cancelled.");
+ Result = FALSE;
}
else
if (res2) {
fprintf (stderr, "(EE) VFSCopyToLocal: RARProcessFile result = %d\n", res2);
- Result = cVFS_ReadErr;
+ rar_error_to_gerror (res2, error);
+ Result = FALSE;
}
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;
+ rar_error_to_gerror (res2, error);
+ Result = FALSE;
}
}
}
@@ -856,55 +919,32 @@ VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstN
if (res != ERAR_END_ARCHIVE && res) {
if (globs->extract_cancelled) {
fprintf (stderr, "(WW) VFSCopyToLocal: cancelled !\n");
- Result = cVFS_Cancelled;
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Operation has been cancelled.");
+ Result = FALSE;
}
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;
- }
+ rar_error_to_gerror (res, error);
}
}
free (header);
- if (! found && Result == cVFS_OK) {
+ if (! found && Result) {
fprintf (stderr, "(EE) VFSCopyToLocal: file not found in archive.\n");
- Result = cVFS_ReadErr;
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "File not found in archive.");
+ Result = FALSE;
}
fprintf (stderr, "(II) VFSCopyToLocal: finished. \n");
return Result;
}
-TVFSResult
-VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append)
+gboolean
+VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append, GError **error)
{
printf ("(WW) VFSCopyFromLocal: Not supported in UNRAR plugin.\n");
- return cVFS_Not_Supported;
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Not supported in UNRAR plugin.");
+ return FALSE;
}