summaryrefslogtreecommitdiff
path: root/libarchive/libarchive.c
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@redhat.com>2024-10-25 12:15:08 +0200
committerTomas Bzatek <tbzatek@redhat.com>2024-10-25 12:15:08 +0200
commit5060e318edf3bec2bdb1b353b911203db923ff5f (patch)
tree04fc60b9f5a79bd562cc7b0c1666750694633808 /libarchive/libarchive.c
parent921396db23f8281bec8372c680b89089de42703c (diff)
downloadtuxcmd-modules-5060e318edf3bec2bdb1b353b911203db923ff5f.tar.xz
libarchive: Implement manual file open-read-closev0.6.83
No write support.
Diffstat (limited to 'libarchive/libarchive.c')
-rw-r--r--libarchive/libarchive.c200
1 files changed, 124 insertions, 76 deletions
diff --git a/libarchive/libarchive.c b/libarchive/libarchive.c
index 13789e1..e7647a4 100644
--- a/libarchive/libarchive.c
+++ b/libarchive/libarchive.c
@@ -1,5 +1,5 @@
/* libarchive plugin for Tux Commander
- * version 0.3.1, designed for libarchive v3.6.1
+ * version 0.4, designed for libarchive v3.6.1
* Copyright (C) 2008-2024 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
@@ -48,8 +48,8 @@
#endif
-#define MODULE_VERSION "0.3.2"
-#define MODULE_BUILD_DATE "2024-10-23"
+#define MODULE_VERSION "0.4"
+#define MODULE_BUILD_DATE "2024-10-25"
#define DEFAULT_BLOCK_SIZE 65536
@@ -607,37 +607,6 @@ TVFSResult VFSChangeTimes (struct TVFSGlobs *globs, char *APath, guint32 mtime,
/******************************************************************************************************/
/************** **/
-#if 0
-TVFSFileDes VFSOpenFile(struct TVFSGlobs *globs, const char *APath, int Mode, int *Error)
-{
- *Error = cVFS_Not_Supported;
- return (TVFSFileDes)0;
-}
-
-TVFSResult VFSCloseFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor)
-{
- return cVFS_Not_Supported;
-}
-
-u_int64_t VFSFileSeek(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, u_int64_t AbsoluteOffset, int *Error)
-{
- *Error = cVFS_Not_Supported;
- return 0;
-}
-
-int VFSReadFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buffer, int ABlockSize, int *Error)
-{
- *Error = cVFS_Not_Supported;
- return 0;
-}
-
-int VFSWriteFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buffer, int BytesCount, int *Error)
-{
- *Error = cVFS_Not_Supported;
- return 0;
-}
-#endif
-
void
VFSSetBlockSize (struct TVFSGlobs *globs, guint32 Value)
{
@@ -790,76 +759,74 @@ VFSStopCopyOperation (struct TVFSGlobs *globs, GError **error)
return TRUE;
}
-
-gboolean
-VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append, GError **error)
+static struct archive_entry *
+seek_to_archive_record (struct TVFSGlobs *globs, const char *sSrcName, const char *log_prefix, GError **error)
{
struct PathTree *node;
const char *src;
- struct archive_entry *entry;
int r;
- gboolean found;
- gboolean res;
-
-
- if (globs->op_archive == NULL) {
- g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_EXCEPTION, "globs->op_archive == NULL");
- return FALSE;
- }
- if (sSrcName == NULL || sDstName == NULL || strlen (sSrcName) < 1 || strlen (sDstName) < 1) {
- log_error ("VFSCopyToLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty");
- g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_EXCEPTION, "The value of 'sSrcName' or 'sDstName' is NULL or empty.");
- return FALSE;
- }
-
- log_notice ("VFSCopyToLocal: copying file '%s' out to '%s'", sSrcName, sDstName);
node = filelist_tree_find_node_by_path (globs->files, sSrcName);
if (! node) {
- log_error ("VFSCopyToLocal: cannot find file '%s'", sSrcName);
- g_set_error (error, TUXCMD_ERROR, TUXCMD_ERROR_SOURCE_OPEN, "Cannot find file '%s'", sSrcName);
- return FALSE;
+ log_error ("%s: cannot find file '%s'", log_prefix, sSrcName);
+ g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_SOURCE_OPEN, "File not found in the archive.");
+ return NULL;
}
src = node->original_pathstr;
if (! src) {
- log_warn ("VFSCopyToLocal: cannot determine original filename");
+ log_warn ("%s: cannot determine original filename", log_prefix);
src = sSrcName;
}
- log_debug ("VFSCopyToLocal: new src path: '%s'", src);
-
-
- found = FALSE;
- res = TRUE;
+ log_debug ("%s: new src path: '%s'", log_prefix, src);
for (;;) {
- entry = NULL;
+ struct archive_entry *entry = NULL;
+
r = archive_read_next_header (globs->op_archive, &entry);
if (r == ARCHIVE_EOF) {
break;
} else
if (r == ARCHIVE_WARN) {
- log_warn ("VFSCopyToLocal: file '%s' - libarchive warning: '%s'", archive_entry_pathname (entry), archive_error_string (globs->op_archive));
+ log_warn ("%s: file '%s' - libarchive warning: '%s'", log_prefix, archive_entry_pathname (entry), archive_error_string (globs->op_archive));
} else
if (r != ARCHIVE_OK) {
- log_error ("VFSCopyToLocal: error occured while reading archive: '%s'", archive_error_string (globs->op_archive));
+ log_error ("%s: error occured while reading archive: '%s'", log_prefix, archive_error_string (globs->op_archive));
g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_SOURCE_READ, archive_error_string (globs->op_archive));
- break;
+ return NULL;
}
- if (g_strcmp0 (src, archive_entry_pathname (entry)) == 0) {
- found = TRUE;
- res = my_archive_read_data_into_fd (globs, globs->op_archive, entry, sDstName, globs->block_size, Append, error);
- break;
- }
+ if (g_strcmp0 (src, archive_entry_pathname (entry)) == 0)
+ return entry;
}
- if (! found && res) {
- log_error ("VFSCopyToLocal: file not found in the archive.");
- if (error && *error == NULL)
- g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_SOURCE_OPEN, "File not found in the archive.");
- res = FALSE;
+ log_error ("%s: file not found in the archive.", log_prefix);
+ g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_SOURCE_OPEN, "File not found in the archive.");
+ return NULL;
+}
+
+gboolean
+VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append, GError **error)
+{
+ struct archive_entry *entry;
+ gboolean res;
+
+ if (globs->op_archive == NULL) {
+ g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_EXCEPTION, "globs->op_archive == NULL");
+ return FALSE;
}
+ if (sSrcName == NULL || sDstName == NULL || strlen (sSrcName) < 1 || strlen (sDstName) < 1) {
+ log_error ("VFSCopyToLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty");
+ g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_EXCEPTION, "The value of 'sSrcName' or 'sDstName' is NULL or empty.");
+ return FALSE;
+ }
+
+ log_notice ("VFSCopyToLocal: copying file '%s' out to '%s'", sSrcName, sDstName);
+ entry = seek_to_archive_record (globs, sSrcName, "VFSCopyToLocal", error);
+ if (!entry)
+ return FALSE;
+
+ res = my_archive_read_data_into_fd (globs, globs->op_archive, entry, sDstName, globs->block_size, Append, error);
log_debug ("VFSCopyToLocal: finished.");
return res;
@@ -875,6 +842,87 @@ VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDs
}
+/******************************************************************************************************/
+/************** **/
+
+TVFSFileDes
+VFSOpenFile (struct TVFSGlobs *globs, const char *APath, int Mode, GError **error)
+{
+ struct archive_entry *entry;
+ GError *local_error = NULL;
+
+ switch (Mode) {
+ case cVFS_OpenRead:
+ /* OK, break */
+ break;
+ case cVFS_OpenWrite:
+ case cVFS_OpenAppend:
+ g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_OPEN_FILE, "Writing files in the archive is not supported");
+ return NULL;
+ default:
+ g_set_error (error, TUXCMD_ERROR, TUXCMD_ERROR_OPEN_FILE, "Invalid file open mode %d", Mode);
+ return NULL;
+ }
+
+ /* FIXME: fix the use outside of running copy operation (archive might not have been opened) */
+ if (globs->op_archive == NULL) {
+ g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_EXCEPTION, "globs->op_archive == NULL");
+ return FALSE;
+ }
+
+ entry = seek_to_archive_record (globs, APath, "VFSCopyToLocal", &local_error);
+ if (!entry) {
+ g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_OPEN_FILE, local_error->message);
+ g_error_free (local_error);
+ return NULL;
+ }
+
+ return globs->op_archive; /* FIXME: what to use as a filedescriptor? */
+}
+
+gboolean
+VFSCloseFile (struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, GError **error)
+{
+ /* nothing special to do here */
+ return TRUE;
+}
+
+gint64
+VFSReadFile (struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, gpointer Buffer, guint64 ABlockSize, GError **error)
+{
+ la_ssize_t r;
+
+ r = archive_read_data (FileDescriptor, Buffer, ABlockSize);
+ /* On error, a value of ARCHIVE_FATAL = -30, ARCHIVE_WARN = -20, or ARCHIVE_RETRY = -10 is returned. */
+ if (r < 0) {
+ log_error ("VFSReadFile: error reading data from the archive: %s", archive_error_string (FileDescriptor));
+ g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_READ_FILE, archive_error_string (FileDescriptor));
+ return -1;
+ }
+ return r;
+}
+
+gint64
+VFSWriteFile (struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, gpointer Buffer, guint64 BytesCount, GError **error)
+{
+ g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_WRITE_FILE, "Writing files in the archive is not supported");
+ return -1;
+}
+
+guint64
+VFSFileSeek (struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, guint64 AbsoluteOffset, GError **error)
+{
+ la_int64_t r;
+
+ r = archive_seek_data (FileDescriptor, AbsoluteOffset, SEEK_SET);
+ if (r < 0) {
+ log_error ("VFSFileSeek: error seeking in the archive: %s", archive_error_string (FileDescriptor));
+ g_set_error_literal (error, TUXCMD_ERROR, TUXCMD_ERROR_SEEK, archive_error_string (FileDescriptor));
+ return 0;
+ }
+ return r;
+}
+
/**********