From e42a4ff3031aa1c1aaf27aa34d9395fec185924b Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Sun, 13 Dec 2009 14:36:33 +0100 Subject: Error system transformation to GError --- unrar/Makefile | 6 +- unrar/unrar.c | 254 +++++++++++++++++++++++++++++++++------------------------ 2 files changed, 150 insertions(+), 110 deletions(-) (limited to 'unrar') diff --git a/unrar/Makefile b/unrar/Makefile index 4e930da..e822800 100644 --- a/unrar/Makefile +++ b/unrar/Makefile @@ -39,15 +39,15 @@ VFS_OBJECTS = unrar.o rarlog.o .SUFFIXES: .c .cpp .c.o: - $(CC) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $< + $(CC) $(CFLAGS) `pkg-config glib-2.0 gio-2.0 --cflags` -c $< .cpp.o: - $(CPP) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $< + $(CPP) $(CFLAGS) `pkg-config glib-2.0 gio-2.0 --cflags` -c $< all shared static: libunrar_plugin.so libunrar_plugin.so: libunrar $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS) - $(CPP) -shared -o libunrar_plugin.so $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS) $(UNRAR_OBJECTS) $(UNRAR_LIB_OBJ) $(CFLAGS) `pkg-config glib-2.0 --libs` + $(CPP) -shared -o libunrar_plugin.so $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS) $(UNRAR_OBJECTS) $(UNRAR_LIB_OBJ) $(CFLAGS) `pkg-config glib-2.0 gio-2.0 --libs` libunrar: ( cd $(DIR_UNRAR) && make -f ../Makefile.unrar ) || exit 1 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 * Check for updates on tuxcmd.sourceforge.net * @@ -31,6 +31,7 @@ #include #include #include +#include #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; } -- cgit v1.2.3