diff options
Diffstat (limited to 'libarchive/libarchive.c')
| -rw-r--r-- | libarchive/libarchive.c | 200 |
1 files changed, 109 insertions, 91 deletions
diff --git a/libarchive/libarchive.c b/libarchive/libarchive.c index 6c6c59c..cadd6a0 100644 --- a/libarchive/libarchive.c +++ b/libarchive/libarchive.c @@ -1,5 +1,5 @@ /* libarchive plugin for Tux Commander - * version 0.2.1, designed for libarchive v2.5.5 - v2.7.1 (recommended) + * version 0.2.2, 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 * @@ -30,6 +30,7 @@ #include <errno.h> #include <fcntl.h> #include <glib.h> +#include <gio/gio.h> #include "tuxcmd-vfs.h" #include "vfsutils.h" @@ -52,8 +53,8 @@ #endif -#define MODULE_VERSION "0.2.1" -#define MODULE_BUILD_DATE "2009-11-29" +#define MODULE_VERSION "0.2.2" +#define MODULE_BUILD_DATE "2009-12-12" #define DEFAULT_BLOCK_SIZE 65536 @@ -257,8 +258,8 @@ char *formats; /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ -static TVFSResult -libarchive_open (struct archive **a, const char *filename, guint32 block_size) +static gboolean +libarchive_open (struct archive **a, const char *filename, guint32 block_size, GError **error) { int r; @@ -268,24 +269,25 @@ libarchive_open (struct archive **a, const char *filename, guint32 block_size) archive_read_support_compression_all (*a); archive_read_support_format_all (*a); - r = archive_read_open_file (*a, filename, block_size); + r = archive_read_open_filename (*a, filename, block_size); if (r) { fprintf (stderr, "(EE) libarchive_open: error occured when opening archive: %s\n", archive_error_string (*a)); - return cVFS_Failed; + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (archive_errno (*a)), archive_error_string (*a)); + return FALSE; } - return cVFS_OK; + return TRUE; } -TVFSResult -VFSOpenArchive (struct TVFSGlobs *globs, const char *sName) +gboolean +VFSOpenArchive (struct TVFSGlobs *globs, const char *sName, GError **error) { - TVFSResult Result; struct archive *a; struct archive_entry *entry; struct TVFSItem *item; int r; char *s; guint64 inode_no; + gboolean res; globs->files = filelist_tree_new (); globs->vfs_filelist = vfs_filelist_new (globs->files); @@ -294,8 +296,8 @@ VFSOpenArchive (struct TVFSGlobs *globs, const char *sName) globs->total_size = 0; fprintf (stderr, "(--) VFSOpenArchive: trying to open archive '%s'...\n", globs->archive_path); - Result = libarchive_open (&a, globs->archive_path, globs->block_size); - if (Result == cVFS_OK) { + res = libarchive_open (&a, globs->archive_path, globs->block_size, error); + if (res) { inode_no = 0; for (;;) { entry = NULL; @@ -308,7 +310,8 @@ VFSOpenArchive (struct TVFSGlobs *globs, const char *sName) } else if (r != ARCHIVE_OK) { fprintf (stderr, "(EE) VFSOpenArchive: error occured while reading archive: '%s'\n", archive_error_string (a)); - Result = cVFS_Failed; + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (archive_errno (a)), archive_error_string (a)); + res = FALSE; break; } @@ -393,12 +396,12 @@ VFSOpenArchive (struct TVFSGlobs *globs, const char *sName) printf ("\n\nList of items:\n"); filelist_tree_print (globs->files); - return Result; + return res; } -TVFSResult -VFSClose (struct TVFSGlobs *globs) +gboolean +VFSClose (struct TVFSGlobs *globs, GError **error) { if (globs) { fprintf (stderr, "(II) VFSClose: Freeing objects...\n"); @@ -409,7 +412,7 @@ VFSClose (struct TVFSGlobs *globs) g_free (globs->archive_path); g_free (globs->curr_dir); } - return cVFS_OK; + return TRUE; } @@ -420,7 +423,7 @@ VFSGetPath (struct TVFSGlobs *globs) } -TVFSResult +void VFSGetFileSystemInfo (struct TVFSGlobs *globs, const char *APath, gint64 *FSSize, gint64 *FSFree, char **FSLabel) { if (FSSize) @@ -429,24 +432,21 @@ 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; - else - return cVFS_Failed; + s = vfs_filelist_change_dir (globs->vfs_filelist, NewPath, error); + if (s) { + globs->curr_dir = s; + return TRUE; + } else + return FALSE; } @@ -460,41 +460,35 @@ VFSGetPasswordRequired (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); } @@ -525,6 +519,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 libarchive plugin.\n"); @@ -566,12 +561,13 @@ TVFSResult VFSChangeTimes (struct TVFSGlobs *globs, char *APath, guint32 mtime, printf ("(WW) VFSChangeTimes: Not supported in libarchive 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; @@ -600,6 +596,7 @@ int VFSWriteFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buff *Error = cVFS_Not_Supported; return 0; } +#endif void VFSSetBlockSize (struct TVFSGlobs *globs, guint32 Value) @@ -632,8 +629,8 @@ VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2, * The following code has been stolen from archive_read_data_into_fd.c (libarchive sources) and modified to allow progress callbacks * Quote: "This implementation minimizes copying of data and is sparse-file aware." **/ -static TVFSResult -my_archive_read_data_into_fd (struct TVFSGlobs *globs, struct archive *a, struct archive_entry *entry, const char *sDstName, size_t max_block, gboolean Append) +static gboolean +my_archive_read_data_into_fd (struct TVFSGlobs *globs, struct archive *a, struct archive_entry *entry, const char *sDstName, size_t max_block, gboolean Append, GError **error) { int r; int fd; @@ -644,6 +641,7 @@ my_archive_read_data_into_fd (struct TVFSGlobs *globs, struct archive *a, struct off_t output_offset; guint64 file_size; gboolean cancel = FALSE; + int saved_errno; printf ("(II) my_archive_read_data_into_fd: extracting to '%s', Append = %d\n", sDstName, Append); @@ -654,8 +652,10 @@ my_archive_read_data_into_fd (struct TVFSGlobs *globs, struct archive *a, struct 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; + saved_errno = errno; + fprintf (stderr, "(EE) my_archive_read_data_into_fd: error occured while extracting data: %s\n", strerror (saved_errno)); + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (saved_errno), "Error extracting data: %s", g_strerror (saved_errno)); + return FALSE; } total_written = 0; @@ -676,8 +676,11 @@ my_archive_read_data_into_fd (struct TVFSGlobs *globs, struct archive *a, struct bytes_to_write = max_block; bytes_written = write (fd, p, bytes_to_write); if (bytes_written < 0) { - fprintf (stderr, "(EE) my_archive_read_data_into_fd: error occured while extracting data: %s\n", strerror (errno)); - return cVFS_Failed; + saved_errno = errno; + fprintf (stderr, "(EE) my_archive_read_data_into_fd: error occured while extracting data: %s\n", strerror (saved_errno)); + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (saved_errno), "Error writing data: %s", g_strerror (saved_errno)); + close (fd); + return FALSE; } output_offset += bytes_written; total_written += bytes_written; @@ -686,48 +689,57 @@ my_archive_read_data_into_fd (struct TVFSGlobs *globs, struct archive *a, struct log (" (II) my_archive_read_data_into_fd: bytes_written = %zd, total_written = %zd\n", bytes_written, total_written); if (globs->callback_progress) - if (! globs->callback_progress (total_written, file_size, globs->callback_data)) { + if (! globs->callback_progress (total_written, NULL, globs->callback_data)) { cancel = TRUE; break; } } } - if (close (fd) || (r != ARCHIVE_OK && r != ARCHIVE_EOF)) { + if (r != ARCHIVE_OK && r != ARCHIVE_EOF) { fprintf (stderr, "(EE) my_archive_read_data_into_fd: error closing extracted file: %s\n", strerror (errno)); - return cVFS_WriteErr; + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (archive_errno (a)), archive_error_string (a)); + close (fd); + return FALSE; + } + if (close (fd)) { + saved_errno = errno; + fprintf (stderr, "(EE) my_archive_read_data_into_fd: error closing extracted file: %s\n", strerror (errno)); + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (saved_errno), "Error closing extracted file: %s", g_strerror (saved_errno)); + return FALSE; } if (cancel) { if (unlink (sDstName)) fprintf (stderr, "(EE) my_archive_read_data_into_fd: error unlinking cancelled extraction: %s\n", strerror (errno)); - return cVFS_Cancelled; + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Operation has been cancelled."); + return FALSE; } printf ("(II) my_archive_read_data_into_fd: done.\n"); - return cVFS_OK; + return TRUE; } -TVFSResult -VFSStartCopyOperation (struct TVFSGlobs *globs) +gboolean +VFSStartCopyOperation (struct TVFSGlobs *globs, GError **error) { - TVFSResult Result; - - g_return_val_if_fail (globs != NULL, cVFS_Failed); - g_return_val_if_fail (globs->op_archive == NULL, cVFS_Failed); + if (globs->op_archive != NULL) { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED, "globs->op_archive != NULL"); + return FALSE; + } printf ("(II) VFSStartCopyOperation: opening archive '%s'\n", globs->archive_path); - Result = libarchive_open (&globs->op_archive, globs->archive_path, globs->block_size); - - return Result; + return libarchive_open (&globs->op_archive, globs->archive_path, globs->block_size, error); } -TVFSResult -VFSStopCopyOperation (struct TVFSGlobs *globs) +gboolean +VFSStopCopyOperation (struct TVFSGlobs *globs, GError **error) { - g_return_val_if_fail (globs != NULL, cVFS_Failed); - g_return_val_if_fail (globs->op_archive != NULL, cVFS_Failed); + if (globs->op_archive == NULL) { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED, "globs->op_archive == NULL"); + return FALSE; + } printf ("(II) VFSStopCopyOperation: closing archive.\n"); @@ -735,26 +747,29 @@ VFSStopCopyOperation (struct TVFSGlobs *globs) archive_read_finish (globs->op_archive); globs->op_archive = NULL; - return cVFS_OK; + return TRUE; } -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; const char *src; - TVFSResult Result; struct archive_entry *entry; int r; gboolean found; + gboolean res; - g_return_val_if_fail (globs->op_archive != NULL, cVFS_ReadErr); - + if (globs->op_archive == NULL) { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "globs->op_archive == 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); @@ -762,7 +777,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; @@ -774,7 +790,7 @@ VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstN found = FALSE; - Result = cVFS_ReadErr; + res = TRUE; for (;;) { entry = NULL; @@ -787,32 +803,34 @@ VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstN } 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; + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (archive_errno (globs->op_archive)), archive_error_string (globs->op_archive)); 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); + res = my_archive_read_data_into_fd (globs, globs->op_archive, entry, sDstName, globs->block_size, Append, error); break; } } - if (! found && Result == cVFS_OK) { + if (! found && res) { 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."); + res = FALSE; } fprintf (stderr, "(II) VFSCopyToLocal: finished. \n"); - return Result; + return res; } -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 libarchive plugin.\n"); - return cVFS_Not_Supported; + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Not supported in libarchive plugin."); + return FALSE; } |
