summaryrefslogtreecommitdiff
path: root/libarchive/libarchive.c
diff options
context:
space:
mode:
Diffstat (limited to 'libarchive/libarchive.c')
-rw-r--r--libarchive/libarchive.c200
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;
}