diff options
| author | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2009-11-28 13:11:51 +0100 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2009-11-28 13:11:51 +0100 |
| commit | 9382f127ccebdd59917c97c61d008ed0e127cd75 (patch) | |
| tree | 0a48c8296199b343c76ef532eef014f908bc2e4d | |
| parent | 70eeaa4ec712895539ca6ecd60a42b93ec9b0904 (diff) | |
| download | tuxcmd-modules-0.6.72.tar.xz | |
Engine and VFS API cleanupv0.6.72
Also enable symlink resolving by default.
53 files changed, 2506 insertions, 2241 deletions
diff --git a/common/filelist-vfs-intf.c b/common/filelist-vfs-intf.c new file mode 100644 index 0000000..e806334 --- /dev/null +++ b/common/filelist-vfs-intf.c @@ -0,0 +1,263 @@ +/* Tux Commander VFS: convenient interface for VFS modules to a filelist tree + * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net> + * Check for updates on tuxcmd.sourceforge.net + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdio.h> +#include <string.h> +#include <glib.h> + +#include "tuxcmd-vfs.h" +#include "strutils.h" +#include "vfsutils.h" +#include "filelist.h" +#include "filelist-vfs-intf.h" + + + + + + +struct VfsFilelistData * +vfs_filelist_new (struct PathTree *files) +{ + struct VfsFilelistData * data; + + data = g_malloc0 (sizeof (struct VfsFilelistData)); + + log ("vfs_filelist_new()\n"); + data->files = files; + + return data; +} + +void +vfs_filelist_free (struct VfsFilelistData *data) +{ + if (! data) { + fprintf (stderr, "vfs_filelist_free: data == NULL !\n"); + return; + } + g_free (data->list_dir_path); + g_free (data); +} + + +/* -------------------------------------------------------------------------------------- */ + +guint64 +internal_get_dir_size (struct VfsFilelistData *data, struct PathTree *tree) +{ + guint64 Size; + struct PathTree *n; + unsigned long idx; + + Size = 0; + if (! data->break_get_dir_size && tree) { + n = NULL; + idx = 0; + while ((n = filelist_tree_get_item_by_index (tree, idx))) { + if (data->break_get_dir_size) + break; + if (n->data) { + log ("internal_get_dir_size: found item '%s', size = %zd \n", n->node, n->data->iSize); + Size += (n->data->ItemType == vDirectory) ? internal_get_dir_size (data, n) : n->data->iSize; + } + idx++; + } + } + return Size; +} + +guint64 +vfs_filelist_get_dir_size (struct VfsFilelistData *data, const char *APath) +{ + struct PathTree *node; + + if (! data) + return 0; + data->break_get_dir_size = FALSE; + + node = filelist_tree_find_node_by_path (data->files, APath); + if (node) { + return internal_get_dir_size (data, node); + } else { + printf ("(EE) VFSGetDirSize: path '%s' not found\n", APath); + return 0; + } +} + +void +vfs_filelist_get_dir_size_break (struct VfsFilelistData *data) +{ + if (data) + data->break_get_dir_size = TRUE; +} + + +/* -------------------------------------------------------------------------------------- */ + +static void +assign_file_info (struct PathTree* node, struct TVFSItem *Item, const char *reference_full_path, gboolean follow_symlinks, gboolean add_full_path) +{ + copy_vfs_item (node->data, Item); + if (add_full_path && reference_full_path) { + g_free (Item->FName); + g_free (Item->FDisplayName); + Item->FName = g_strdup (reference_full_path); + Item->FDisplayName = g_filename_display_name (reference_full_path); + } + if (follow_symlinks && node->symlink_target_data) { + Item->iSize = node->symlink_target_data->iSize; + Item->iPackedSize = node->symlink_target_data->iPackedSize; + Item->ItemType = node->symlink_target_data->ItemType; + } +} + +TVFSResult +vfs_filelist_file_info (struct VfsFilelistData *data, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath) +{ + struct PathTree *node; + + if (data && data->files) { + node = filelist_tree_find_node_by_path (data->files, AFileName); + if (node) { + if (node->data) { + assign_file_info (node, Item, AFileName, FollowSymlinks, AddFullPath); + printf ("(II) VFSFileInfo: found file: '%s'\n", Item->FName); + return cVFS_OK; + } else { + printf ("(EE) VFSFileInfo: node->data == NULL! \n"); + return cVFS_Failed; + } + } else { + printf ("(EE) VFSFileInfo: file specified not found\n"); + return cVFS_No_More_Files; + } + } else { + printf ("(EE) VFSFileInfo: Invalid pointers to data objects.\n"); + return cVFS_Failed; + } +} + +TVFSResult +vfs_filelist_list_first (struct VfsFilelistData *data, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath) +{ + struct PathTree *node; + char *full_path; + + data->list_dir_index = -1; + data->list_dir_node = NULL; + + if (sDir == NULL) { + printf ("(EE) VFSListFirst: sDir is NULL!\n"); + return cVFS_Failed; + } + + data->list_dir_index = 0; + data->list_dir_node = filelist_tree_find_node_by_path (data->files, sDir); + data->follow_symlinks = FollowSymlinks; + data->add_full_path = AddFullPath; + data->list_dir_path = include_trailing_path_sep (sDir); + + /* Find the directory in the filelist */ + if (data->list_dir_node) { + node = filelist_tree_get_item_by_index (data->list_dir_node, data->list_dir_index); + if (node) { + full_path = NULL; + if (AddFullPath) + full_path = g_build_filename (sDir, node->data->FName, NULL); + assign_file_info (node, Item, full_path, FollowSymlinks, AddFullPath); + g_free (full_path); + printf ("(II) VFSListFirst: found file: %s\n", Item->FName); + return cVFS_OK; + } else { + printf ("(II) VFSListFirst: no more files\n"); + return cVFS_No_More_Files; + } + } else { + printf ("(EE) VFSListFirst: Directory '%s' not found.\n", sDir); + return cVFS_Failed; + } +} + +TVFSResult +vfs_filelist_list_next (struct VfsFilelistData *data, struct TVFSItem *Item) +{ + struct PathTree *node; + char *full_path; + + full_path = NULL; + if (! data->list_dir_node) { + printf ("(EE) VFSListNext: data->list_dir_node is NULL!\n"); + return cVFS_Failed; + } + data->list_dir_index++; + + node = filelist_tree_get_item_by_index (data->list_dir_node, data->list_dir_index); + if (node) { + if (data->add_full_path) + full_path = g_build_filename (data->list_dir_path, node->data->FName, NULL); + assign_file_info (node, Item, full_path, data->follow_symlinks, data->add_full_path); + g_free (full_path); + printf ("(II) VFSListNext: found file: %s\n", Item->FName); + return cVFS_OK; + } else { + printf ("(II) VFSListNext: no more files\n"); + return cVFS_No_More_Files; + } +} + +TVFSResult +vfs_filelist_list_close (struct VfsFilelistData *data) +{ + data->list_dir_index = -1; + data->list_dir_node = NULL; + g_free (data->list_dir_path); + data->list_dir_path = NULL; + return cVFS_OK; +} + + +/* -------------------------------------------------------------------------------------- */ + +char * +vfs_filelist_change_dir (struct VfsFilelistData *data, const char *NewPath) +{ + char *ANewPath; + + if (NewPath == NULL) { + printf("(EE) VFSChangeDir: NewPath is NULL!\n"); + return NULL; + } + + /* make up the target path */ + printf ("(--) VFSChangeDir: Going to change dir from '%s'\n", NewPath); + ANewPath = exclude_trailing_path_sep (NewPath); + if (! ANewPath || strlen (ANewPath) <= 0) + ANewPath = g_strdup ("/"); + printf ("(--) VFSChangeDir: Going to change dir to '%s'\n", ANewPath); + + /* find the directory in the filelist */ + if (filelist_tree_find_node_by_path (data->files, ANewPath)) { + return ANewPath; + } else { + printf ("(EE) VFSChangeDir: Directory '%s' not found.\n", ANewPath); + g_free (ANewPath); + return NULL; + } +} diff --git a/common/filelist-vfs-intf.h b/common/filelist-vfs-intf.h new file mode 100644 index 0000000..ce93e1e --- /dev/null +++ b/common/filelist-vfs-intf.h @@ -0,0 +1,68 @@ +/* Tux Commander VFS: convenient interface for VFS modules to a filelist tree + * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net> + * Check for updates on tuxcmd.sourceforge.net + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __TREEPATH_VFS_H__ +#define __TREEPATH_VFS_H__ + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <glib.h> + +#include "tuxcmd-vfs.h" +#include "filelist.h" + + +struct VfsFilelistData { + struct PathTree *files; + + unsigned int list_dir_index; + struct PathTree *list_dir_node; + char * list_dir_path; + + gboolean follow_symlinks; + gboolean add_full_path; + + gboolean break_get_dir_size; +}; + + +struct VfsFilelistData * vfs_filelist_new (struct PathTree *files); +void vfs_filelist_free (struct VfsFilelistData *data); + +guint64 vfs_filelist_get_dir_size (struct VfsFilelistData *data, const char *APath); +void vfs_filelist_get_dir_size_break (struct VfsFilelistData *data); + +gboolean vfs_filelist_file_exists (struct VfsFilelistData *data, const char *FileName, const long Use_lstat); +TVFSResult vfs_filelist_file_info (struct VfsFilelistData *data, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath); + +TVFSResult vfs_filelist_list_first (struct VfsFilelistData *data, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath); +TVFSResult vfs_filelist_list_next (struct VfsFilelistData *data, struct TVFSItem *Item); +TVFSResult vfs_filelist_list_close (struct VfsFilelistData *data); + +char * vfs_filelist_change_dir (struct VfsFilelistData *data, const char *NewPath); + + + +#ifdef __cplusplus + } +#endif +#endif /* __TREEPATH_VFS_H__ */ diff --git a/common/filelist.c b/common/filelist.c new file mode 100644 index 0000000..cae250e --- /dev/null +++ b/common/filelist.c @@ -0,0 +1,382 @@ +/* Tux Commander VFS: Filelist tree storage + * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net> + * Check for updates on tuxcmd.sourceforge.net + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdio.h> +#include <string.h> +#include <glib.h> + +#include "filelist.h" +#include "strutils.h" +#include "vfsutils.h" + + + +struct PathTree * +filelist_tree_new () +{ + struct PathTree *tree; + + tree = g_malloc0 (sizeof (struct PathTree)); + log ("filelist_tree_new()\n"); + tree->items = g_ptr_array_new (); + tree->data = NULL; + tree->original_index = 0; + tree->node = g_strdup ("/"); + tree->original_pathstr = NULL; + + /* create placeholder data */ + tree->data = create_placeholder_item (tree->node, vDirectory); + + return tree; +} + +void +filelist_tree_free (struct PathTree *tree) +{ + int i; + + if (! tree) { + fprintf (stderr, "filelist_tree_free: tree == NULL !\n"); + return; + } + + if (tree->items && tree->items->len > 0) { + for (i = 0; i < tree->items->len; i++) + filelist_tree_free (g_ptr_array_index (tree->items, i)); + } + if (tree->items) + g_ptr_array_free (tree->items, TRUE); + free_vfs_item (tree->data); + g_free (tree->node); + g_free (tree->original_pathstr); + g_free (tree); +} + + +/* -------------------------------------------------------------------------------------- */ + +static void +filelist_tree_print_recurr (struct PathTree *tree, int level) +{ + char *fill; + int i; + struct PathTree* t; + + if (tree) { + fill = g_strnfill (level * 2, 32); + g_print (" %s#%lu. \"%s\"\n", fill, tree->original_index, tree->node); + + if (tree->items && tree->items->len > 0) + for (i = 0; i < tree->items->len; i++) { + t = g_ptr_array_index (tree->items, i); + filelist_tree_print_recurr (t, level + 1); + } + g_free (fill); + } +} + +void +filelist_tree_print (struct PathTree *tree) +{ + filelist_tree_print_recurr (tree, 0); +} + + +/* -------------------------------------------------------------------------------------- */ + +struct PathTree * +filelist_tree_find_node_by_path (struct PathTree *tree, const char *path) +{ + char *p; + char *first_part; + char *last_part; + struct PathTree *node; + struct PathTree *t; + unsigned int i; + + /* remove leading './' */ + if (strstr (path, "./") == path) + path += 2; + /* remove leading and trailing '/' if present */ + p = exclude_trailing_path_sep (path + G_IS_DIR_SEPARATOR (*path)); + log (" filelist_tree_find_node_by_path: path = '%s', p = '%s'\n", path, p); + + node = NULL; + if (tree && tree->node && g_strcmp0 (tree->node, "/") == 0 && g_strcmp0 (path, "/") == 0) { + log (" filelist_tree_find_node_by_path: matched root '/' element, returning.\n"); + node = tree; + } else + if (tree && tree->items && tree->items->len > 0) { + split_path (p, &first_part, &last_part); + log (" filelist_tree_find_node_by_path: pos = '%s'\n", pos); + log (" filelist_tree_find_node_by_path: first_part = '%s'\n", first_part); + log (" filelist_tree_find_node_by_path: last_part = '%s'\n", last_part); + + /* find existing node */ + for (i = 0; i < tree->items->len; i++) { + t = g_ptr_array_index (tree->items, i); + if (g_strcmp0 (t->node, first_part) == 0) { + /* this is the final station */ + if (! last_part) { + node = t; + log (" filelist_tree_find_node_by_path: found final node '%s', returning.\n", t->node); + } else + + /* recurse to child items */ + if (t->items && last_part) { + log (" filelist_tree_find_node_by_path: found node '%s', recursing in deep.\n", t->node); + node = filelist_tree_find_node_by_path (t, last_part); + } else { + /* item found but no subitems */ + log (" filelist_tree_find_node_by_path: found node '%s', but no subitems found.\n", t->node); + } + + break; + } + } + g_free (first_part); + g_free (last_part); + } + g_free (p); + return node; +} + +unsigned long int +filelist_find_original_index_by_path (struct PathTree *tree, const char *path) +{ + struct PathTree *node; + + node = filelist_tree_find_node_by_path (tree, path); + return node ? node->original_index : 0; +} + + +/* -------------------------------------------------------------------------------------- */ + +static void +filelist_tree_add_item_recurr (struct PathTree *tree, const char *path, struct TVFSItem *item, const char *original_pathstr, unsigned long int original_index) +{ + char *first_part; + char *last_part; + struct PathTree *t; + struct PathTree *node; + unsigned int i; + + split_path (path, &first_part, &last_part); + log (" filelist_tree_add_item_recur: pos = '%s'\n", pos); + log (" filelist_tree_add_item_recur: first_part = '%s'\n", first_part); + log (" filelist_tree_add_item_recur: last_part = '%s'\n", last_part); + + if (last_part == NULL) { + /* final destination, create new item here */ + log (" filelist_tree_add_item_recur: creating new item here.\n"); + t = g_malloc0 (sizeof (struct PathTree)); + t->items = NULL; + t->data = item; + t->node = g_strdup (first_part); + t->original_index = original_index; + t->original_pathstr = g_strdup (original_pathstr); + if (t->data) { + g_free (t->data->FName); + g_free (t->data->FDisplayName); + t->data->FName = g_strdup (path); + t->data->FDisplayName = g_filename_display_name (path); + } + /* create new list of subitems and add new item */ + if (! tree->items) + tree->items = g_ptr_array_new (); + g_ptr_array_add (tree->items, t); + } else { + /* not a final place, find parent node or create new one if doesn't exist */ + log (" filelist_tree_add_item_recur: node '%s', path '%s'\n", tree->node, path); + if (! tree->items) + tree->items = g_ptr_array_new (); + + node = NULL; + if (tree->items->len > 0) + for (i = 0; i < tree->items->len; i++) { + t = g_ptr_array_index (tree->items, i); + if (g_strcmp0 (t->node, first_part) == 0) { + log (" filelist_tree_add_item_recur: found node '%s'\n", t->node); + node = t; + break; + } + } + + if (node == NULL) { + /* create new path holder node */ + log (" filelist_tree_add_item_recur: parent node not found, creating new path holder\n"); + node = g_malloc0 (sizeof (struct PathTree)); + node->items = g_ptr_array_new (); + node->node = g_strdup (first_part); + node->original_index = 0; + node->original_pathstr = NULL; + + /* create placeholder data */ + node->data = create_placeholder_item (node->node, vDirectory); + g_ptr_array_add (tree->items, node); + } + + /* and recurse one level deeper */ + filelist_tree_add_item_recurr (node, last_part, item, original_pathstr, original_index); + } + g_free (first_part); + g_free (last_part); +} + + +gboolean +filelist_tree_add_item (struct PathTree *tree, const char *path, struct TVFSItem *item, const char *original_pathstr, unsigned long int original_index) +{ + char *p; + char *pp; + struct PathTree *found; + + if (! tree) { + fprintf (stderr, "filelist_tree_add_item: tree == NULL !\n"); + return FALSE; + } + if (! path) { + fprintf (stderr, "filelist_tree_add_item: path == NULL !\n"); + return FALSE; + } + + if (g_strcmp0 (path, "/") == 0 || g_strcmp0 (path, ".") == 0 || g_strcmp0 (path, "..") == 0 || g_strcmp0 (path, "./") == 0) { + fprintf (stderr, "filelist_tree_add_item: path '%s' is not a valid path\n", path); + return FALSE; + } + + /* remove leading './' */ + if (g_strstr_len (path, -1, "./") == path) + path += 2; + + /* remove leading and trailing '/' if present */ + p = exclude_trailing_path_sep (path + G_IS_DIR_SEPARATOR (*path)); + log (" filelist_tree_add_item: p = '%s'\n", p); + + pp = canonicalize_filename (p); + if (! pp) + pp = g_strdup (p); + + found = filelist_tree_find_node_by_path (tree, pp); + if (found) { + /* replace old data with current ones (record might have been created automatically during path building) */ + log (" filelist_tree_add_item: found old item, replacing data\n"); + found->original_index = original_index; + /* free old data */ + free_vfs_item (found->data); + found->data = item; + if (found->data) { + g_free (found->data->FName); + g_free (found->data->FDisplayName); + found->data->FName = g_strdup (found->node); + found->data->FDisplayName = g_filename_display_name (found->node); + } + } else { + /* create new item recursively */ + filelist_tree_add_item_recurr (tree, pp, item, original_pathstr, original_index); + } + + g_free (p); + g_free (pp); + return TRUE; +} + + +/* -------------------------------------------------------------------------------------- */ + +struct PathTree * +filelist_tree_get_item_by_index (struct PathTree *tree, unsigned long int index) +{ + struct PathTree *t = NULL; + + if (tree && tree->items && tree->items->len > index) + t = g_ptr_array_index (tree->items, index); + return t; +} + + +/* -------------------------------------------------------------------------------------- */ + +static void +resolve_symlink_recurr (struct PathTree *node, struct PathTree *root_tree, const char *path, const char *link_dest, int level) +{ + char *rel; + char *new_path; + struct PathTree *link_t; + + rel = resolve_relative (path, link_dest); + g_print (" resolve_symlink_recurr: relative = '%s'\n", rel); + if (rel) { + link_t = filelist_tree_find_node_by_path (root_tree, rel); + if (link_t && link_t->data) { + if (link_t->data->IsLink) { + /* another symlink, recurse into deep */ + new_path = g_path_get_dirname (rel); + if (level > FILELIST_MAX_SYMLINK_DEPTH || ! new_path) { + node->symlink_target_data = link_t->data; + g_print (" resolve_symlink_recurr: max depth reached, link is broken. new_path = '%s'\n", new_path); + } else { + g_print (" resolve_symlink_recurr: going deep, rel = '%s', new_path = '%s'\n", rel, new_path); + resolve_symlink_recurr (node, root_tree, new_path, link_t->data->sLinkTo, level + 1); + } + g_free (new_path); + } else { + /* final destination */ + node->symlink_target_data = link_t->data; + g_print (" resolve_symlink_recurr: reached target '%s'\n", rel); + } + } else { + /* target not found, link is broken */ + node->symlink_target_data = NULL; + g_print (" resolve_symlink_recurr: target '%s' not found, link is broken\n", rel); + } + } + g_free (rel); +} + +static void +filelist_tree_resolve_symlinks_recurr (struct PathTree *tree, struct PathTree *root_tree, const char *path) +{ + struct PathTree *t; + char *new_path; + unsigned int i; + + if (tree && tree->items && tree->items->len > 0) { + for (i = 0; i < tree->items->len; i++) { + t = g_ptr_array_index (tree->items, i); + + if (t && t->data && t->data->IsLink && t->data->sLinkTo) { + g_print ("filelist_tree_resolve_symlinks: found '%s/%s' --> '%s', resolving...\n", path, t->node, t->data->sLinkTo); + resolve_symlink_recurr (t, root_tree, path, t->data->sLinkTo, 1); + } + new_path = g_build_filename (path, t->node, NULL); + filelist_tree_resolve_symlinks_recurr (t, root_tree, new_path); + g_free (new_path); + } + } +} + +void +filelist_tree_resolve_symlinks (struct PathTree *tree) +{ + log ("filelist_tree_resolve_symlinks: begin\n"); + filelist_tree_resolve_symlinks_recurr (tree, tree, "/"); + log ("filelist_tree_resolve_symlinks: end\n"); +} diff --git a/common/filelist.h b/common/filelist.h new file mode 100644 index 0000000..e28699e --- /dev/null +++ b/common/filelist.h @@ -0,0 +1,99 @@ +/* Tux Commander VFS: Filelist tree storage + * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net> + * Check for updates on tuxcmd.sourceforge.net + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __TREEPATHUTILS_H__ +#define __TREEPATHUTILS_H__ + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <glib.h> +#include "tuxcmd-vfs.h" + + +/**** + * USAGE / RULES: + * + * 1. create new tree, add items one by one with filelist_tree_add_item(), found during first archive listing + * 2. optionally call filelist_tree_resolve_symlinks() + * 3. when mapping a file back, use filelist_find_original_index_by_path() or filelist_tree_find_node_by_path() + * and take the particular attribute (original_XXX) as a reference to match the archive records against. + * + * + * - don't set the FName and FDisplayName values, filelist functions set these dynamically + * when traversing tree during adding. + * + * - due to the previous fact, the FDisplayName string is taken from original path, making + * sure it's valid UTF-8. No way to have different display name than the file name. + * + * - it's important to set either 'original_index' or 'original_pathstr' value, to match + * exact file back in the archive during VFSCopyToLocal operation. These attributes are + * left untouched by filelist functions. + * + * - all returned values are constants, do not modify anything (except of the item data itself). + * + * - the 'symlink_target_data' member is just a pointer to an existing data, don't free it. + * + * - the single 'node' and 'tree' objects are virtually equal, linked together. It may lead + * to a slight confusion. + * + */ + + +#define FILELIST_MAX_SYMLINK_DEPTH 20 /* do not go deeper than 20 levels */ + + +struct PathTree { + GPtrArray * items; + struct TVFSItem * data; + struct TVFSItem * symlink_target_data; + unsigned long int original_index; /* original index as stored in the archive, for matching back */ + char * node; + char * original_pathstr; /* original path as stored in the archive, for matching back */ +}; + + +struct PathTree * filelist_tree_new (); +void filelist_tree_free (struct PathTree *tree); + +/* Convenient function to print whole tree, for debugging purposes. */ +void filelist_tree_print (struct PathTree *tree); + +/* Add item into the particular structure under the 'path' node. This function tries to find the right node + * and creates placeholder nodes in between, when a part of the directory structure is missing. + */ +gboolean filelist_tree_add_item (struct PathTree *tree, const char *path, struct TVFSItem *item, const char *original_pathstr, unsigned long int original_index); + +struct PathTree * filelist_tree_find_node_by_path (struct PathTree *tree, const char *path); +unsigned long int filelist_find_original_index_by_path (struct PathTree *tree, const char *path); + +void filelist_tree_resolve_symlinks (struct PathTree *tree); + +/* Find the n-th item inside one node, the 'index' argument is absolute position in the list. + * Don't confuse with 'original_index' member. Used in vfs_filelist_list_next(). + */ +struct PathTree * filelist_tree_get_item_by_index (struct PathTree *tree, unsigned long int index); + + +#ifdef __cplusplus + } +#endif +#endif /* __TREEPATHUTILS_H__ */ diff --git a/common/strutils.c b/common/strutils.c index 5383b8a..3b0a1db 100644 --- a/common/strutils.c +++ b/common/strutils.c @@ -1,4 +1,4 @@ -/* Tux Commandern VFS: String utilities +/* Tux Commander VFS: String utilities * Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net> * Check for updates on tuxcmd.sourceforge.net * @@ -17,89 +17,102 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <stdio.h> #include <string.h> #include <glib.h> + #include "strutils.h" -char* include_trailing_path_sep(const char *APath) + +char * +include_trailing_path_sep (const char *APath) { - if (APath == NULL) return NULL; - char *ANewPath; -// log("xxx = %s\n", (APath + strlen(APath) - 1)); - if (strcmp(APath + strlen(APath) - 1, "/") != 0) { - ANewPath = (char*)malloc(strlen(APath) + 2); - snprintf(ANewPath, strlen(APath) + 2, "%s/", APath); - } else ANewPath = strdup(APath); - return ANewPath; + if (APath == NULL) + return NULL; + if (g_strcmp0 (APath + strlen (APath) - 1, "/") != 0) + return g_strdup_printf ("%s/", APath); + else + return g_strdup (APath); } -char* exclude_trailing_path_sep(const char *APath) +char * +exclude_trailing_path_sep (const char *APath) { - if (APath == NULL) return NULL; - char *ANewPath; -// log("orig = %s, len = %d, xxx = %s\n", APath, (int)strlen(APath), (APath + strlen(APath) - 1)); - if ((strcmp(APath + strlen(APath) - 1, "/") == 0) && (strlen(APath) > 1)) { - ANewPath = (char*)malloc(strlen(APath)); - snprintf(ANewPath, strlen(APath), "%s", APath); // The number of bytes copied includes the trailing \0 - } else ANewPath = strdup(APath); - return ANewPath; + if (APath == NULL) + return NULL; + if (strlen (APath) > 1 && g_strcmp0 (APath + strlen (APath) - 1, "/") == 0) + return g_strndup (APath, strlen (APath) - 1); + else + return g_strdup(APath); } -char* include_leading_path_sep(const char *APath) +char * +include_leading_path_sep (const char *APath) { - if (APath == NULL) return NULL; - char *ANewPath; -// log("xxx = %s, %lu, strlen(APath) = %d, index() = %ld\n", APath, (unsigned long int)APath, (int)strlen(APath), (unsigned long int)index(APath, 0x2f)); - if (index(APath, 0x2f) != APath) { - ANewPath = (char*)malloc(strlen(APath) + 2); - snprintf(ANewPath, strlen(APath) + 2, "/%s", APath); // The number of bytes copied includes the trailing \0 - } else ANewPath = strdup(APath); - return ANewPath; + if (APath == NULL) + return NULL; + if (! g_path_is_absolute (APath)) + return g_strdup_printf ("/%s", APath); + else + return g_strdup (APath); } -char* exclude_leading_path_sep(const char* APath) +char * +exclude_leading_path_sep (const char *APath) { - if (APath == NULL) return NULL; - char *s = strdup(APath); - char *ss; - if (IS_DIR_SEP(*s)) ss = strdup(s + 1); else ss = strdup(s); - free(s); - return ss; + if (APath == NULL) + return NULL; + if (g_path_is_absolute (APath)) + return g_strdup (APath + 1); + else + return g_strdup (APath); } -char* extract_file_name(const char *APath) +/* -------------------------------------------------------------------------------------- */ + +char * +resolve_relative (const char *source, const char *point_to) { - if (APath == NULL) return NULL; -// log("xxx = %s\n", (APath + strlen(APath) - 1)); - const char *file_part = rindex(APath, 0x2f); // returns NULL if not found or if the file is in the root ( / ) - if (file_part == NULL) return NULL; - return strdup(file_part + 1); + char *rel; + char *canon; + + if (source == NULL) + return NULL; + if (point_to == NULL) + return g_strdup (source); + if (g_path_is_absolute (point_to)) + return g_strdup (point_to); + + rel = g_build_filename (source, point_to, NULL); + log ("resolve_relative: rel = '%s'\n", rel); + canon = canonicalize_filename (rel); + log ("resolve_relative: canon = '%s'\n", canon); + g_free (rel); + + return canon; } -// Extracts file path starting with "/" and ending with "/" -char* extract_file_path(const char *APath) +void +split_path (const char *path, char **first_part, char **last_part) { - if (APath == NULL) return NULL; -// log("xxx = %s\n", (APath + strlen(APath) - 1)); - const char *file_part = rindex(APath, 0x2f); // returns NULL if not found or if the file is in the root ( / ) - if (file_part == NULL) return NULL; - char *ANewPath = (char*)malloc(file_part - APath + 2); - snprintf(ANewPath, file_part - APath + 2, "%s", APath); - return ANewPath; + const char *pos; + + pos = strstr (path, "/"); + if (pos) { + *first_part = g_strndup (path, pos - path); + *last_part = g_strdup (pos + 1); + } else { + *first_part = g_strdup (path); + *last_part = NULL; + } } +/* -------------------------------------------------------------------------------------- */ - - - - - -// canonicalize_filename() is stolen from glib-2.16 -// Copyright (C) 2006-2007 Alexander Larsson <alexl@redhat.com> +/* canonicalize_filename() has been stolen from glib-2.16 */ +/* Copyright (C) 2006-2007 Alexander Larsson <alexl@redhat.com> */ char * canonicalize_filename (const char *filename) { @@ -179,34 +192,18 @@ canonicalize_filename (const char *filename) } -char* resolve_relative(const char *source, const char *point_to) -{ - if (source == NULL) return NULL; - if (point_to == NULL) return strdup(source); - if (g_path_is_absolute(point_to)) return strdup(point_to); - - char *rel = g_build_filename(source, point_to, NULL); - log("resolve_relative: rel = '%s'\n", rel); - char *canon = canonicalize_filename(rel); - log("resolve_relative: canon = '%s'\n", canon); - free(rel); - - return canon; -} - - +/* -------------------------------------------------------------------------------------- */ -// Originally stolen from wine-0.9.19, utf8.c -// Copyright 2000 Alexandre Julliard -char* +/* stolen from wine-0.9.19, utf8.c */ +/* Copyright 2000 Alexandre Julliard */ +char * wide_to_utf8 (const wchar_t *src) { #define CONV_BUFF_MAX 32768 int len; char *buf, *dst, *ret; - buf = (char *) malloc (CONV_BUFF_MAX); - memset (&buf[0], 0, CONV_BUFF_MAX); + buf = (char *) g_malloc0 (CONV_BUFF_MAX); dst = buf; if (src) @@ -251,6 +248,6 @@ wide_to_utf8 (const wchar_t *src) } ret = g_strdup (buf); - free (buf); + g_free (buf); return ret; } diff --git a/common/strutils.h b/common/strutils.h index 84f6013..7fed4c5 100644 --- a/common/strutils.h +++ b/common/strutils.h @@ -20,32 +20,36 @@ #ifndef __STRUTILS_H__ #define __STRUTILS_H__ - - -#include <string.h> -#include <stdlib.h> +#ifdef __cplusplus + extern "C" { +#endif #ifdef __VERBOSE_DEBUG - #define log(msg...) printf(msg) + #define log(msg...) g_print(msg) #else #define log(msg...) { } #endif -#define IS_DIR_SEP(ch) ((ch) == '/') +/* path manipulating functions, all return newly allocated string */ +char * include_trailing_path_sep (const char *APath); +char * exclude_trailing_path_sep (const char *APath); +char * include_leading_path_sep (const char *APath); +char * exclude_leading_path_sep (const char *APath); + +char * resolve_relative (const char *source, const char *point_to); -// path manipulating functions, all return newly allocated string, you can then free them as you want -char* include_trailing_path_sep(const char *APath); -char* exclude_trailing_path_sep(const char *APath); -char* include_leading_path_sep(const char *APath); -char* exclude_leading_path_sep(const char *APath); -char* extract_file_name(const char *APath); -char* extract_file_path(const char *APath); -char* resolve_relative(const char *source, const char *point_to); -char* canonicalize_filename(const char *filename); +/* split the first path element (single level) and copy the rest (multiple levels) */ +void split_path (const char *path, char **first_part, char **last_part); -char* wide_to_utf8(const wchar_t *src); +char * canonicalize_filename (const char *filename); +char * wide_to_utf8 (const wchar_t *src); + + +#ifdef __cplusplus + } +#endif #endif /* __STRUTILS_H__ */ diff --git a/common/treepath_vfs.c b/common/treepath_vfs.c deleted file mode 100644 index 34a779a..0000000 --- a/common/treepath_vfs.c +++ /dev/null @@ -1,231 +0,0 @@ -/* Tux Commander VFS: basic tree_path routines - * Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net> - * Check for updates on tuxcmd.sourceforge.net - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <stdio.h> -#include <string.h> -#include <glib.h> - -#include "vfs_types.h" -#include "strutils.h" -#include "vfsutils.h" -#include "treepathutils.h" -#include "treepath_vfs.h" - - - - - - -struct VfsFilelistData* vfs_filelist_new(struct PathTree *files) -{ - struct VfsFilelistData *data= (struct VfsFilelistData*)malloc(sizeof(struct VfsFilelistData)); - memset(data, 0, sizeof(struct VfsFilelistData)); - - log("vfs_filelist_new()\n"); - data->files = files; - - return data; -} - - -void vfs_filelist_free(struct VfsFilelistData *data) -{ - if (! data) { - fprintf(stderr, "vfs_filelist_free: data == NULL !\n"); - return; - } - if (data) - { - free(data); - } -} - -void vfs_filelist_set_files(struct VfsFilelistData *data, struct PathTree *files) -{ - if (data) data->files = files; -} - - - - - -u_int64_t internal_get_dir_size(struct VfsFilelistData *data, struct PathTree *tree) -{ - if (data->break_get_dir_size) return 0; - u_int64_t Size = 0; - if (tree) { - struct PathTree *n = NULL; - unsigned long idx = 0; - while ((n = filelist_tree_get_item_by_index(tree, idx))) { - if (data->break_get_dir_size) break; - if (n->data) { - log("internal_get_dir_size: found item '%s', size = %zd \n", n->node, n->data->iSize); - Size += (n->data->ItemType == vDirectory) ? internal_get_dir_size(data, n) : n->data->iSize; - } - idx++; - } - } - return Size; -} - -u_int64_t vfs_filelist_get_dir_size(struct VfsFilelistData *data, char *APath) -{ - if (! data) return 0; - data->break_get_dir_size = FALSE; - - struct PathTree* node = filelist_tree_find_node_by_path(data->files, APath); - if (node) { - return internal_get_dir_size(data, node); - } else { - printf("(EE) VFSGetDirSize: path '%s' not found\n", APath); - return 0; - } -} - -void vfs_filelist_get_dir_size_break(struct VfsFilelistData *data) -{ - if (data) data->break_get_dir_size = TRUE; -} - - - - - - -long vfs_filelist_file_exists(struct VfsFilelistData *data, const char *FileName, const long Use_lstat) -{ - if ((data) && (data->files)) { - struct PathTree* node = filelist_tree_find_node_by_path(data->files, FileName); - return node != NULL; - } else { - printf ("(EE) VFSFileExists: Invalid pointers to data objects.\n"); - return FALSE; - } -} - - -TVFSResult vfs_filelist_file_info(struct VfsFilelistData *data, char *AFileName, struct TVFSItem *Item) -{ - if ((data) && (data->files)) { - struct PathTree* node = filelist_tree_find_node_by_path(data->files, AFileName); - if (node) { - if (node->data) { - copy_vfs_item(node->data, Item); - Item->FName = strdup(AFileName); - Item->FDisplayName = strdup(AFileName); - printf("(II) VFSFileInfo: found file: '%s'\n", Item->FName); - return cVFS_OK; - } else { - printf("(EE) VFSFileInfo: node->data == NULL! \n"); - return cVFS_Failed; - } - } else { - printf("(EE) VFSFileInfo: file specified not found\n"); - return cVFS_No_More_Files; - } - } else { - printf ("(EE) VFSFileInfo: Invalid pointers to data objects.\n"); - return cVFS_Failed; - } -} - - - - - - -TVFSResult vfs_filelist_list_first(struct VfsFilelistData *data, char *sDir, struct TVFSItem *Item) -{ - data->list_dir_index = -1; - data->list_dir_node = NULL; - - if (sDir == NULL) { - printf("(EE) VFSListFirst: sDir is NULL!\n"); - return cVFS_Failed; - } - - data->list_dir_index = 0; - data->list_dir_node = filelist_tree_find_node_by_path(data->files, sDir); - - // Find the directory in the filelist - if (data->list_dir_node) { - struct PathTree* node = filelist_tree_get_item_by_index(data->list_dir_node, data->list_dir_index); - if (node) { - copy_vfs_item(node->data, Item); - printf("(II) VFSListFirst: found file: %s\n", Item->FName); - return cVFS_OK; - } else { - printf("(II) VFSListFirst: no more files\n"); - return cVFS_No_More_Files; - } - } else { - printf ("(EE) VFSListFirst: Directory '%s' not found.\n", sDir); - return cVFS_Failed; - } -} - -TVFSResult vfs_filelist_list_next(struct VfsFilelistData *data, char *sDir, struct TVFSItem *Item) -{ - if (! data->list_dir_node) { - printf("(EE) VFSListNext: data->list_dir_node is NULL!\n"); - return cVFS_Failed; - } - data->list_dir_index++; - - struct PathTree* node = filelist_tree_get_item_by_index(data->list_dir_node, data->list_dir_index); - if (node) { - copy_vfs_item(node->data, Item); - printf("(II) VFSListNext: found file: %s\n", Item->FName); - return cVFS_OK; - } else { - printf("(II) VFSListNext: no more files\n"); - return cVFS_No_More_Files; - } -} - -TVFSResult vfs_filelist_list_close(struct VfsFilelistData *data) -{ - data->list_dir_index = -1; - data->list_dir_node = NULL; - return cVFS_OK; -} - - -char* vfs_filelist_change_dir(struct VfsFilelistData *data, char *NewPath) -{ - if (NewPath == NULL) { - printf("(EE) VFSChangeDir: NewPath is NULL!\n"); - return NULL; - } - - // Make up the target path - printf ("(--) VFSChangeDir: Going to change dir from '%s'\n", NewPath); - char *ANewPath = exclude_trailing_path_sep(NewPath); - if (strlen(ANewPath) <= 0) ANewPath = strdup("/"); - printf ("(--) VFSChangeDir: Going to change dir to '%s'\n", ANewPath); - - // Find the directory in the filelist - if (filelist_tree_find_node_by_path(data->files, ANewPath)) { - return ANewPath; - } else { - printf ("(EE) VFSChangeDir: Directory '%s' not found.\n", ANewPath); - free(ANewPath); - return NULL; - } -} diff --git a/common/treepath_vfs.h b/common/treepath_vfs.h deleted file mode 100644 index 2f78414..0000000 --- a/common/treepath_vfs.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Tux Commander VFS: basic tree_path routines - * Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net> - * Check for updates on tuxcmd.sourceforge.net - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __TREEPATH_VFS_H__ -#define __TREEPATH_VFS_H__ - - -#include <stdio.h> -#include <string.h> -#include <glib.h> - -#include "vfs_types.h" -#include "treepathutils.h" - - -struct VfsFilelistData { - struct PathTree *files; - - unsigned int list_dir_index; - struct PathTree *list_dir_node; - - gboolean break_get_dir_size; -}; - - -struct VfsFilelistData* vfs_filelist_new(struct PathTree *files); -void vfs_filelist_free(struct VfsFilelistData *data); -void vfs_filelist_set_files(struct VfsFilelistData *data, struct PathTree *files); - -u_int64_t vfs_filelist_get_dir_size(struct VfsFilelistData *data, char *APath); -void vfs_filelist_get_dir_size_break(struct VfsFilelistData *data); - -long vfs_filelist_file_exists(struct VfsFilelistData *data, const char *FileName, const long Use_lstat); -TVFSResult vfs_filelist_file_info(struct VfsFilelistData *data, char *AFileName, struct TVFSItem *Item); - -TVFSResult vfs_filelist_list_first(struct VfsFilelistData *data, char *sDir, struct TVFSItem *Item); -TVFSResult vfs_filelist_list_next(struct VfsFilelistData *data, char *sDir, struct TVFSItem *Item); -TVFSResult vfs_filelist_list_close(struct VfsFilelistData *data); - -char* vfs_filelist_change_dir(struct VfsFilelistData *data, char *NewPath); - - - - -#endif /* __TREEPATH_VFS_H__ */ diff --git a/common/treepathutils.c b/common/treepathutils.c deleted file mode 100644 index c8f2b18..0000000 --- a/common/treepathutils.c +++ /dev/null @@ -1,386 +0,0 @@ -/* Tux Commander VFS: String utilities - * Copyright (C) 2007-2008 Tomas Bzatek <tbzatek@users.sourceforge.net> - * Check for updates on tuxcmd.sourceforge.net - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <glib.h> - -#include "treepathutils.h" -#include "strutils.h" -#include "vfsutils.h" - - - - - - -struct PathTree* filelist_tree_new() -{ - struct PathTree *tree = (struct PathTree*)malloc(sizeof(struct PathTree)); - memset(tree, 0, sizeof(struct PathTree)); - log("filelist_tree_new()\n"); - tree->items = g_ptr_array_new(); - tree->data = NULL; - tree->index = 0; - tree->node = strdup("/"); - tree->original_pathstr = NULL; - - // create placeholder data - tree->data = (struct TVFSItem*)malloc(sizeof(struct TVFSItem)); - memset(tree->data, 0, sizeof(struct TVFSItem)); - tree->data->FName = strdup(tree->node); - tree->data->FDisplayName = strdup(tree->node); - tree->data->ItemType = vDirectory; - tree->data->iMode = S_IRWXO + S_IRWXG + S_IRWXU; - tree->data->iUID = geteuid(); - tree->data->iGID = getegid(); - tree->data->m_time = time(NULL); - tree->data->c_time = tree->data->m_time; - tree->data->a_time = tree->data->m_time; - - return tree; -} - - -void filelist_tree_free(struct PathTree *tree) -{ - if (! tree) { - fprintf(stderr, "filelist_tree_free: tree == NULL !\n"); - return; - } - if (tree) - { - if ((tree->items) && (tree->items->len > 0)) { - unsigned int i; - for (i = 0; i < tree->items->len; i++) - filelist_tree_free((struct PathTree*)g_ptr_array_index(tree->items, i)); - } - if (tree->items) - g_ptr_array_free(tree->items, TRUE); - if (tree->data) { - if (tree->data->FName) free(tree->data->FName); - if (tree->data->FDisplayName) free(tree->data->FDisplayName); - if (tree->data->sLinkTo) free(tree->data->sLinkTo); - free(tree->data); - } - if (tree->node) - free(tree->node); - if (tree->original_pathstr) - free(tree->original_pathstr); - free(tree); - } -} - - -void filelist_tree_print_recurr(struct PathTree *tree, int level) -{ - if (tree) { - char *fill = g_strnfill(level * 2, 32); - printf(" %s#%lu. \"%s\"\n", fill, tree->index, tree->node); - - if ((tree->items) && (tree->items->len > 0)) { - unsigned int i; - for (i = 0; i < tree->items->len; i++) - { - struct PathTree* t = (struct PathTree*)g_ptr_array_index(tree->items, i); - filelist_tree_print_recurr(t, level + 1); - } - } - - g_free(fill); - } -} - - -void filelist_tree_print(struct PathTree *tree) -{ - filelist_tree_print_recurr(tree, 0); -} - - -struct PathTree* filelist_tree_find_node_by_path(struct PathTree *tree, const char *path) -{ - // remove leading './' - if (strstr(path, "./") == path) path += 2; - - // remove leading and trailing '/' if present - char *p; - if (IS_DIR_SEP(*path)) p = exclude_trailing_path_sep(path + 1); - else p = exclude_trailing_path_sep(path); - - log(" filelist_tree_find_node_by_path: path = '%s', p = '%s'\n", path, p); -// log("xx: '%s', '%s'\n", tree->node, path); - - struct PathTree* node = NULL; - if ((tree) && (tree->node) && (strcmp(tree->node, "/") == 0) && (strcmp(path, "/") == 0)) { - log(" filelist_tree_find_node_by_path: matched root '/' element, returning.\n"); - node = tree; - } else - if ((tree) && (tree->items) && (tree->items->len > 0)) { - // split path - char *pos = strstr(p, "/"); - char *first_part; - char *last_part; - if (pos) { - first_part = strndup(p, pos - p); - if (strlen(pos + 1) > 0) last_part = strdup(pos + 1); - else last_part = NULL; - } else { - first_part = strdup(p); - last_part = NULL; - } - log(" filelist_tree_find_node_by_path: pos = '%s'\n", pos); - log(" filelist_tree_find_node_by_path: first_part = '%s'\n", first_part); - log(" filelist_tree_find_node_by_path: last_part = '%s'\n", last_part); - - // find existing node - unsigned int i; - for (i = 0; i < tree->items->len; i++) - { - struct PathTree* t = (struct PathTree*)g_ptr_array_index(tree->items, i); - if (strcmp(t->node, first_part) == 0) { - // this is the final station - if (! last_part) { - node = t; - log(" filelist_tree_find_node_by_path: found final node '%s', returning.\n", t->node); - } else - // recurse to child items - if ((t->items) && (last_part)) { - log(" filelist_tree_find_node_by_path: found node '%s', recursing in deep.\n", t->node); - node = filelist_tree_find_node_by_path(t, last_part); - } else { - // item found but no subitems - log(" filelist_tree_find_node_by_path: found node '%s', but no subitems found.\n", t->node); - } - - break; - } - } - free(first_part); - free(last_part); - } - free(p); - return node; -} - -unsigned long int filelist_find_index_by_path(struct PathTree *tree, const char *path) -{ - struct PathTree* node = filelist_tree_find_node_by_path(tree, path); - if (node) return node->index; - else return 0; -} - -void filelist_tree_add_item_recurr(struct PathTree *tree, const char *path, const char *original_pathstr, struct TVFSItem *item, unsigned long index) -{ - const char *pos = strstr(path, "/"); - char *first_part; - char *last_part; - if (pos) { - first_part = strndup(path, pos - path); - if (strlen(pos + 1) > 0) last_part = strdup(pos + 1); - else last_part = NULL; - } else { - first_part = strdup(path); - last_part = NULL; - } - log(" filelist_tree_add_item_recur: pos = '%s'\n", pos); - log(" filelist_tree_add_item_recur: first_part = '%s'\n", first_part); - log(" filelist_tree_add_item_recur: last_part = '%s'\n", last_part); - - if (! last_part) - { // final destination, create new item here - log(" filelist_tree_add_item_recur: creating new item here.\n"); - struct PathTree *t = (struct PathTree*)malloc(sizeof(struct PathTree)); - memset(t, 0, sizeof(struct PathTree)); - t->items = NULL; - t->data = item; - t->index = index; - t->node = strdup(path); - if (original_pathstr) t->original_pathstr = strdup(original_pathstr); - if (t->data) t->data->FName = strdup(path); - if (t->data) t->data->FDisplayName = strdup(path); - // create new list of subitems and add new item - if (! tree->items) tree->items = g_ptr_array_new(); - g_ptr_array_add(tree->items, t); - } else - { // find parent node or create new one if doesn't exist - log(" filelist_tree_add_item_recur: node '%s', path '%s'\n", tree->node, path); - if (! tree->items) tree->items = g_ptr_array_new(); - - struct PathTree *node = NULL; - if (tree->items->len > 0) { - unsigned int i; - for (i = 0; i < tree->items->len; i++) - { - struct PathTree* t = (struct PathTree*)g_ptr_array_index(tree->items, i); - if (strcmp(t->node, first_part) == 0) { - log(" filelist_tree_add_item_recur: found node '%s'\n", t->node); - node = t; - break; - } - } - } - - // create new path holder node - if (! node) { - log(" filelist_tree_add_item_recur: parent node not found, creating new path holder\n"); - node = (struct PathTree*)malloc(sizeof(struct PathTree)); - memset(node, 0, sizeof(struct PathTree)); - node->items = g_ptr_array_new(); - node->index = 0; - node->node = strdup(first_part); - node->original_pathstr = NULL; - - // create placeholder data - node->data = (struct TVFSItem*)malloc(sizeof(struct TVFSItem)); - memset(node->data, 0, sizeof(struct TVFSItem)); - node->data->FName = strdup(node->node); - node->data->FDisplayName = strdup(node->node); - node->data->ItemType = vDirectory; - node->data->iMode = S_IRWXO + S_IRWXG + S_IRWXU; - node->data->iUID = geteuid(); - node->data->iGID = getegid(); - node->data->m_time = time(NULL); - node->data->c_time = node->data->m_time; - node->data->a_time = node->data->m_time; - - g_ptr_array_add(tree->items, node); - } - - // and recurse one level deeper - filelist_tree_add_item_recurr(node, last_part, original_pathstr, item, index); - } - - free(first_part); - free(last_part); -} - - -gboolean filelist_tree_add_item(struct PathTree *tree, const char *path, const char *original_pathstr, struct TVFSItem *item, unsigned long index) -{ - if (! tree) { - fprintf(stderr, "filelist_tree_add_item: tree == NULL !\n"); - return FALSE; - } - if (! path) { - fprintf(stderr, "filelist_tree_add_item: path == NULL !\n"); - return FALSE; - } - - if ((strcmp(path, "/") == 0) || (strcmp(path, ".") == 0) || (strcmp(path, "..") == 0) || (strcmp(path, "./") == 0)) { - fprintf(stderr, "filelist_tree_add_item: path '%s' is not a valid path\n", path); - return FALSE; - } - - // remove leading './' - if (strstr(path, "./") == path) path += 2; - - // remove leading and trailing '/' if present - char *p; - if (IS_DIR_SEP(*path)) p = exclude_trailing_path_sep(path + 1); - else p = exclude_trailing_path_sep(path); - log(" filelist_tree_add_item: p = '%s'\n", p); - - char *pp; - pp = canonicalize_filename (p); - if (! pp) - pp = strdup (p); - - struct PathTree* found = filelist_tree_find_node_by_path(tree, pp); - - if (found) - { // replace old data with current ones (record might have been created automatically during path building) - log(" filelist_tree_add_item: found old item, replacing data\n"); - found->index = index; - // free old data - if (found->data) free_vfs_item(found->data); - found->data = item; - if (found->data) found->data->FName = strdup(found->node); - if (found->data) found->data->FDisplayName = strdup(found->node); - } else - // create new item recursively - filelist_tree_add_item_recurr(tree, pp, original_pathstr, item, index); - - free(p); - free(pp); - return TRUE; -} - -struct PathTree* filelist_tree_get_item_by_index(struct PathTree *tree, unsigned long index) -{ - struct PathTree* t = NULL; - if ((tree) && (tree->items) && (tree->items->len > index)) { - t = (struct PathTree*)g_ptr_array_index(tree->items, index); - } - return t; -} - - -void filelist_tree_resolve_symlinks_recurr(struct PathTree *tree, struct PathTree *root_tree, const char *path) -{ - if (tree) { - if ((tree->items) && (tree->items->len > 0)) { - unsigned int i; - for (i = 0; i < tree->items->len; i++) - { - struct PathTree* t = (struct PathTree*)g_ptr_array_index(tree->items, i); - gchar *new_path; - - if ((t) && (t->data) && (t->data->ItemType == vSymlink) && (t->data->sLinkTo)) { - log("filelist_tree_resolve_symlinks: found '%s/%s' --> '%s'\n", path, t->node, t->data->sLinkTo); - gchar *rel = resolve_relative(path, t->data->sLinkTo); - log(" filelist_tree_resolve_symlinks: relative = '%s'\n", rel); - if (rel) { - struct PathTree* link_t = filelist_tree_find_node_by_path(root_tree, rel); - if ((link_t) && (link_t->data)) { - /* WARNING: this is dangerous since we're destroying the symlink type */ - // t->data->ItemType = link_t->data->ItemType; - t->data->a_time = link_t->data->a_time; - t->data->c_time = link_t->data->c_time; - t->data->m_time = link_t->data->m_time; - t->data->iGID = link_t->data->iGID; - t->data->iUID = link_t->data->iUID; - t->data->iMode = link_t->data->iMode; - t->data->iSize = link_t->data->iSize; - } - g_free(rel); - } - } - if ((strlen(path) == 1) && (IS_DIR_SEP(*path))) - new_path = g_strconcat("/", t->node, NULL); - else - new_path = g_strconcat(path, "/", t->node, NULL); - - filelist_tree_resolve_symlinks_recurr(t, root_tree, new_path); - g_free(new_path); - } - } - } -} - -void filelist_tree_resolve_symlinks(struct PathTree *tree) -{ - log("filelist_tree_resolve_symlinks: begin\n"); - filelist_tree_resolve_symlinks_recurr(tree, tree, "/"); - log("filelist_tree_resolve_symlinks: end\n"); -} - diff --git a/common/treepathutils.h b/common/treepathutils.h deleted file mode 100644 index a902a33..0000000 --- a/common/treepathutils.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Tux Commander VFS: String utilities - * Copyright (C) 2007-2008 Tomas Bzatek <tbzatek@users.sourceforge.net> - * Check for updates on tuxcmd.sourceforge.net - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __TREEPATHUTILS_H__ -#define __TREEPATHUTILS_H__ - - -#include <stdio.h> -#include <string.h> -#include <glib.h> - -#include "vfs_types.h" - - -struct PathTree { - GPtrArray* items; - struct TVFSItem *data; - unsigned long index; - char *node; - char *original_pathstr; -}; - - -struct PathTree* filelist_tree_new(); -void filelist_tree_free(struct PathTree *tree); -void filelist_tree_print(struct PathTree *tree); - -/* Symlink resolving: strongly discouraged to use at the present state of art. - * We would have to implement full symlink system, do loop checking etc. */ -void filelist_tree_resolve_symlinks(struct PathTree *tree); - -gboolean filelist_tree_add_item(struct PathTree *tree, const char *path, const char *original_pathstr, struct TVFSItem *item, unsigned long index); -struct PathTree* filelist_tree_find_node_by_path(struct PathTree *tree, const char *path); -unsigned long int filelist_find_index_by_path(struct PathTree *tree, const char *path); -struct PathTree* filelist_tree_get_item_by_index(struct PathTree *tree, unsigned long index); - - - - - - -#endif /* __TREEPATHUTILS_H__ */ diff --git a/common/vfs_types.h b/common/tuxcmd-vfs.h index 49c62e9..2ebed6d 100644 --- a/common/vfs_types.h +++ b/common/tuxcmd-vfs.h @@ -1,9 +1,9 @@ /* Tux Commander VFS: Virtual File System types and definitions * - prototypes functions and types - * draft version 3 + * draft version 5 * * Copyright (C) 2003 Radek Cervinka <radek.cervinka@centrum.cz> - * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net> + * Copyright (C) 2008-2009 Tomas Bzatek <tbzatek@users.sourceforge.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,10 +23,12 @@ #ifndef __VFS_TYPES_H__ #define __VFS_TYPES_H__ +#ifdef __cplusplus + extern "C" { +#endif -#include <stdio.h> -#include <stdint.h> -#include <sys/types.h> + +#include <glib.h> typedef int TVFSResult; @@ -49,62 +51,50 @@ typedef enum { } TVFSPasswordSave; -typedef void (* TVFSLogFunc)(const char *s); -typedef void *TVFSFileDes; +typedef void (* TVFSLogFunc) (const char *s); +typedef void * TVFSFileDes; /* Return FALSE to break the operation */ typedef int (* TVFSProgressCallback) - (u_int64_t position, - u_int64_t max, - void *user_data); + (guint64 position, + guint64 max, + void *user_data); /* Return index of the choice selected or negative number when dialog has been cancelled */ typedef void (* TVFSAskQuestionCallback) - (const char *message, + (const char *message, const char **choices, - int *choice, - int cancel_choice, - void *user_data); + int *choice, + int cancel_choice, + void *user_data); typedef int (* TVFSAskPasswordCallback) - (const char *message, - const char *default_user, - const char *default_domain, - const char *default_password, - TVFSAskPasswordFlags flags, - char **username, - char **password, - int *anonymous, - char **domain, - TVFSPasswordSave *password_save, - void *user_data); - - -static const int cVFSVersion = 5; // current version of the VFS API - -// Capabilities -static const int capVFS_nil = 0; -static const int capVFS_List = 1 << 0; -static const int capVFS_CopyOut = 1 << 1; -static const int capVFS_CopyIn = 1 << 2; -static const int capVFS_MkDir = 1 << 3; -static const int capVFS_RmDir = 1 << 4; -static const int capVFS_Multiple = 1 << 5; // support multiple files = background copy & thread safe -static const int capVFS_Delete = 1 << 6; -static const int capVFS_Rename = 1 << 7; -static const int capVFS_Execute = 1 << 8; -static const int capVFS_Append = 1 << 9; - -// Error codes (TVFSResult) + (const char *message, + const char *default_user, + const char *default_domain, + const char *default_password, + TVFSAskPasswordFlags flags, + char **username, + char **password, + int *anonymous, + char **domain, + TVFSPasswordSave *password_save, + void *user_data); + + +/* current version of the VFS API */ +static const int cVFSVersion = 5; + +/* error codes (TVFSResult) */ enum { cVFS_OK = 0, - cVFS_Failed = 1, // also No such file + cVFS_Failed = 1, /* also No such file */ cVFS_Cancelled = 2, cVFS_Not_Supported = 3, cVFS_No_More_Files = 4, cVFS_ReadErr = 5, - cVFS_WriteErr = 6, // also Readonly FileSystem + cVFS_WriteErr = 6, /* also Readonly FileSystem */ cVFS_LoginFailed = 7, cVFS_PermissionDenied = 8, cVFS_NoSpaceLeft = 9, @@ -115,7 +105,7 @@ enum { }; -// Open modes +/* open modes */ enum { cVFS_OpenRead, cVFS_OpenWrite, @@ -123,40 +113,42 @@ enum { }; -// Item Type enum enum TVFSItemType { vRegular = 0, - vSymlink = 1, - vChardev = 2, - vBlockdev = 3, - vDirectory = 4, - vFifo = 5, - vSock = 6, - vOther = 7 + vChardev = 1, + vBlockdev = 2, + vDirectory = 3, + vFifo = 4, + vSock = 5, + vOther = 6 }; struct TVFSItem { - char *FName; - char *FDisplayName; // valid UTF-8 string - int64_t iSize; - int64_t iPackedSize; // set to -1 if plugin doesn't support this feature - __time_t m_time; // numbers should be located before the other variables (bug?) - __time_t a_time; - __time_t c_time; - __mode_t iMode; - char *sLinkTo; - __uid_t iUID; - __gid_t iGID; + char *FName; + char *FDisplayName; /* valid UTF-8 string */ + guint64 iSize; + gint64 iPackedSize; /* set to -1 if plugin doesn't support this feature */ + guint32 m_time; + guint32 a_time; + guint32 c_time; + guint32 iMode; + gboolean IsLink; + char *sLinkTo; + guint32 iUID; + guint32 iGID; enum TVFSItemType ItemType; }; struct TVFSInfo { - char *ID; // unique identifier, not shown in GUI - char *Name; // plugin name, GUI string (UTF-8) - char *About; // GUI string (UTF-8) - char *Copyright; // GUI string (UTF-8) + char *ID; /* unique identifier, not shown in GUI */ + char *Name; /* plugin name, GUI string (UTF-8) */ + char *About; /* GUI string (UTF-8) */ + char *Copyright; /* GUI string (UTF-8) */ }; +#ifdef __cplusplus + } +#endif #endif /* __VFS_TYPES_H__ */ diff --git a/common/vfsutils.c b/common/vfsutils.c index 173c0df..856d9f9 100644 --- a/common/vfsutils.c +++ b/common/vfsutils.c @@ -1,5 +1,5 @@ -/* Tux Commander VFS: String utilities - * Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net> +/* Tux Commander VFS: VFS utilities + * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net> * Check for updates on tuxcmd.sourceforge.net * * This program is free software; you can redistribute it and/or modify @@ -17,52 +17,76 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <stdio.h> +#include <unistd.h> #include <string.h> +#include <sys/stat.h> #include <glib.h> #include "strutils.h" -#include "vfs_types.h" +#include "tuxcmd-vfs.h" -void copy_vfs_item(struct TVFSItem *src, struct TVFSItem *dst) +void +copy_vfs_item (struct TVFSItem *src, struct TVFSItem *dst) { + memcpy (dst, src, sizeof (struct TVFSItem)); dst->FName = g_strdup (src->FName); dst->FDisplayName = g_strdup (src->FDisplayName); - dst->iSize = src->iSize; - dst->iPackedSize = src->iPackedSize; - dst->m_time = src->m_time; - dst->a_time = src->a_time; - dst->c_time = src->c_time; - dst->iMode = src->iMode; dst->sLinkTo = g_strdup (src->sLinkTo); - dst->iUID = src->iUID; - dst->iGID = src->iGID; - dst->ItemType = src->ItemType; } -void free_vfs_item(struct TVFSItem *item) +void +free_vfs_item (struct TVFSItem *item) { if (item) { - if (item->FName) - free(item->FName); - if (item->FDisplayName) - free(item->FDisplayName); - if (item->sLinkTo) - free(item->sLinkTo); - free(item); + g_free (item->FName); + g_free (item->FDisplayName); + g_free (item->sLinkTo); + g_free (item); } } -int compare_two_same_files(const char *Path1, const char *Path2) +/* -------------------------------------------------------------------------------------- */ + +struct TVFSItem * +create_placeholder_item (const char *name, enum TVFSItemType item_type) +{ + struct TVFSItem *data; + + data = g_malloc0 (sizeof (struct TVFSItem)); + data->FName = g_strdup (name); + data->FDisplayName = g_strdup (name); + data->ItemType = item_type; + data->iMode = S_IRWXO + S_IRWXG + S_IRWXU; + data->IsLink = FALSE; + data->iUID = geteuid (); + data->iGID = getegid (); + data->m_time = time (NULL); + data->c_time = data->m_time; + data->a_time = data->m_time; + data->iSize = 0; + data->iPackedSize = -1; + + return data; +} + + +/* -------------------------------------------------------------------------------------- */ + +gboolean +compare_two_same_files (const char *path1, const char *path2) { - char *f1 = exclude_trailing_path_sep(Path1); - char *f2 = exclude_trailing_path_sep(Path2); - gboolean b = strcmp(f1, f2) == 0; - free(f1); - free(f2); + char *f1, *f2; + gboolean b; + + f1 = exclude_trailing_path_sep (path1); + f2 = exclude_trailing_path_sep (path2); + b = (g_strcmp0 (f1, f2) == 0); + g_free (f1); + g_free (f2); + return b; } diff --git a/common/vfsutils.h b/common/vfsutils.h index 5dd61f2..404b313 100644 --- a/common/vfsutils.h +++ b/common/vfsutils.h @@ -1,5 +1,5 @@ -/* Tux Commander VFS: String utilities - * Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net> +/* Tux Commander VFS: VFS utilities + * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net> * Check for updates on tuxcmd.sourceforge.net * * This program is free software; you can redistribute it and/or modify @@ -20,20 +20,28 @@ #ifndef __VFSUTILS_H__ #define __VFSUTILS_H__ +#ifdef __cplusplus + extern "C" { +#endif + -#include <stdio.h> -#include <string.h> #include <glib.h> -#include "vfs_types.h" +#include "tuxcmd-vfs.h" + +void copy_vfs_item (struct TVFSItem *src, struct TVFSItem *dst); +void free_vfs_item (struct TVFSItem *item); -void copy_vfs_item(struct TVFSItem *src, struct TVFSItem *dst); -void free_vfs_item(struct TVFSItem *item); +/* creates a placeholder item */ +struct TVFSItem * create_placeholder_item (const char *name, enum TVFSItemType item_type); -int compare_two_same_files(const char *Path1, const char *Path2); +gboolean compare_two_same_files (const char *path1, const char *path2); +#ifdef __cplusplus + } +#endif #endif /* __VFSUTILS_H__ */ diff --git a/gvfs/Makefile b/gvfs/Makefile index 0e1985c..5e7f996 100644 --- a/gvfs/Makefile +++ b/gvfs/Makefile @@ -1,21 +1,20 @@ # path definitions DESTDIR = /usr -INSTALL=install -c +INSTALL = install -c INSTALL_DATA = ${INSTALL} -m 644 # compiler options CC = gcc -CFLAGS =-I. -I/usr/include \ - -Wall -fPIC -O2 -g \ - -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE +CFLAGS = -I. -I/usr/include \ + -Wall -fPIC -O2 -g \ + -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -LIB_SUFFIX=`if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi` +LIB_SUFFIX = `if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi` -# VFS_COMMON_OBJECTS=strutils.o treepathutils.o treepath_vfs.o vfsutils.o -VFS_COMMON_OBJECTS= +VFS_COMMON_OBJECTS = -VFS_OBJECTS=gvfs.o +VFS_OBJECTS = gvfs.o .SUFFIXES: .c @@ -28,11 +27,6 @@ all shared static: libgvfs_plugin.so libgvfs_plugin.so: $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS) $(CC) -shared -o libgvfs_plugin.so $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS) $(CFLAGS) `pkg-config glib-2.0 gio-2.0 --libs` -strutils.o: strutils.c strutils.h -treepathutils.o: treepathutils.c treepathutils.h -vfsutils.o: vfsutils.c vfsutils.h -treepath_vfs.o: treepath_vfs.c treepath_vfs.h - install:: $(INSTALL) ./libgvfs_plugin.so $(DESTDIR)/lib$(LIB_SUFFIX)/tuxcmd/ diff --git a/gvfs/gvfs.c b/gvfs/gvfs.c index 7b15b5e..d72b417 100644 --- a/gvfs/gvfs.c +++ b/gvfs/gvfs.c @@ -1,5 +1,5 @@ /* GVFS plugin for Tux Commander - * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net> + * Copyright (C) 2008-2009 Tomas Bzatek <tbzatek@users.sourceforge.net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,35 +19,36 @@ #include <stdio.h> #include <string.h> -#include <stdlib.h> -#include <stdint.h> #include <sys/stat.h> -#include <errno.h> +#include <glib.h> #include <gio/gio.h> -#include <glib/gtypes.h> -#include "vfs_types.h" +#include "tuxcmd-vfs.h" -#define VERSION "0.1.10" -#define BUILD_DATE "2009-10-25" +#define VERSION "0.2.0" +#define BUILD_DATE "2009-11-21" #define DEFAULT_BLOCK_SIZE 0x10000 /* 64kB */ -#define CONST_DEFAULT_QUERY_INFO_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_NAME "," \ - G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," G_FILE_ATTRIBUTE_STANDARD_SIZE "," \ - G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET "," G_FILE_ATTRIBUTE_TIME_MODIFIED "," \ - G_FILE_ATTRIBUTE_TIME_ACCESS "," G_FILE_ATTRIBUTE_TIME_CHANGED "," \ +#define CONST_DEFAULT_QUERY_INFO_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "," \ + G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," \ + G_FILE_ATTRIBUTE_STANDARD_SIZE "," G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET "," \ + G_FILE_ATTRIBUTE_TIME_MODIFIED "," G_FILE_ATTRIBUTE_TIME_ACCESS "," G_FILE_ATTRIBUTE_TIME_CHANGED "," \ G_FILE_ATTRIBUTE_UNIX_MODE "," G_FILE_ATTRIBUTE_UNIX_UID "," \ G_FILE_ATTRIBUTE_UNIX_GID struct TVFSGlobs { TVFSLogFunc log_func; GFile *file; - GFileEnumerator *enumerator; GCancellable *cancellable; + GFileEnumerator *enumerator; + GFile *enumerated_file; + gboolean enum_follow_symlinks; + gboolean enum_add_full_path; + GMainLoop *mount_main_loop; TVFSResult mount_result; int mount_try; @@ -120,10 +121,10 @@ g_error_to_TVFSResult (GError *error) } static void -ask_password_cb (GMountOperation *op, - const char *message, - const char *default_user, - const char *default_domain, +ask_password_cb (GMountOperation *op, + const char *message, + const char *default_user, + const char *default_domain, GAskPasswordFlags flags, gpointer user_data) { @@ -236,9 +237,9 @@ ask_question_cb (GMountOperation *op, } static void -mount_done_cb (GObject *object, +mount_done_cb (GObject *object, GAsyncResult *res, - gpointer user_data) + gpointer user_data) { struct TVFSGlobs *globs; gboolean succeeded; @@ -300,6 +301,7 @@ VFSNew (TVFSLogFunc log_func) globs->file = NULL; globs->enumerator = NULL; + globs->enumerated_file = NULL; globs->cancellable = NULL; globs->break_get_dir_size = FALSE; @@ -314,11 +316,11 @@ VFSNew (TVFSLogFunc log_func) } void -VFSSetCallbacks (struct TVFSGlobs *globs, - TVFSAskQuestionCallback ask_question_callback, - TVFSAskPasswordCallback ask_password_callback, - TVFSProgressCallback progress_func, - void *data) +VFSSetCallbacks (struct TVFSGlobs *globs, + TVFSAskQuestionCallback ask_question_callback, + TVFSAskPasswordCallback ask_password_callback, + TVFSProgressCallback progress_func, + void *data) { globs->callback_ask_question = ask_question_callback; globs->callback_ask_password = ask_password_callback; @@ -330,7 +332,7 @@ void VFSFree (struct TVFSGlobs *globs) { globs->log_func ("GVFS plugin: VFSDestroy"); - free (globs); + g_free (globs); } int @@ -387,7 +389,7 @@ VFSGetNetworkServices () } TVFSResult -VFSOpenURI (struct TVFSGlobs *globs, char *sURI) +VFSOpenURI (struct TVFSGlobs *globs, const char *sURI) { GFile *f, *f2; GFileInfo *info; @@ -458,17 +460,17 @@ VFSClose (struct TVFSGlobs *globs) return cVFS_OK; } -char * -VFSGetPath (struct TVFSGlobs *globs) +static char * +get_absolute_path (GFile *file) { GFile *root; char *path, *s; - if (globs->file) { - root = g_file_resolve_relative_path (globs->file, "/"); + if (file) { + root = g_file_resolve_relative_path (file, "/"); if (root == NULL) return NULL; - path = g_file_get_relative_path (root, globs->file); + path = g_file_get_relative_path (root, file); if (path == NULL) { g_object_unref (root); return NULL; @@ -477,7 +479,6 @@ VFSGetPath (struct TVFSGlobs *globs) s = g_strdup_printf ("/%s", path); else s = g_strdup (path); - g_print ("(II) VFSGetPath: '%s'\n", s); g_free (path); g_object_unref (root); return s; @@ -487,6 +488,17 @@ VFSGetPath (struct TVFSGlobs *globs) } char * +VFSGetPath (struct TVFSGlobs *globs) +{ + char *s; + + s = get_absolute_path (globs->file); + g_print ("(II) VFSGetPath: '%s'\n", s); + + return s; +} + +char * VFSGetPathURI (struct TVFSGlobs *globs) { if (globs->file) @@ -495,56 +507,47 @@ VFSGetPathURI (struct TVFSGlobs *globs) return NULL; } -guint64 -VFSGetFileSystemFree (struct TVFSGlobs *globs, char *APath) +TVFSResult +VFSGetFileSystemInfo (struct TVFSGlobs *globs, const char *APath, gint64 *FSSize, gint64 *FSFree, char **FSLabel) { GFileInfo *info; GError *error; - guint64 res; - - if (globs->file == NULL) - return 0; + TVFSResult res; - error = NULL; - info = g_file_query_filesystem_info (globs->file, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, NULL, &error); - if (error) { - g_print ("(EE) VFSGetFileSystemFree: %s\n", error->message); - g_error_free (error); - return 0; - } - res = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE); - g_object_unref (info); - return res; -} - -guint64 -VFSGetFileSystemSize (struct TVFSGlobs *globs, char *APath) -{ - GFileInfo *info; - GError *error; - guint64 res; + if (FSSize) + *FSSize = -1; + if (FSFree) + *FSFree = -1; + if (FSLabel) + *FSLabel = NULL; if (globs->file == NULL) - return 0; + return cVFS_Failed; error = NULL; - info = g_file_query_filesystem_info (globs->file, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE, NULL, &error); + info = g_file_query_filesystem_info (globs->file, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE "," G_FILE_ATTRIBUTE_FILESYSTEM_FREE, NULL, &error); if (error) { - g_print ("(EE) VFSGetFileSystemSize: %s\n", error->message); + g_print ("(EE) VFSGetFileSystemInfo: %s\n", error->message); g_error_free (error); - return 0; + res = cVFS_Failed; } - res = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE); - g_object_unref (info); + else { + if (FSSize) + *FSSize = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE); + if (FSFree) + *FSFree = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE); + res = cVFS_OK; + } + if (info) + g_object_unref (info); return res; } - /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ TVFSResult -VFSChangeDir (struct TVFSGlobs *globs, char *NewPath) +VFSChangeDir (struct TVFSGlobs *globs, const char *NewPath) { GFile *f; GFileEnumerator *en; @@ -616,6 +619,7 @@ VFSChangeDir (struct TVFSGlobs *globs, char *NewPath) } globs->enumerator = en; + globs->enumerated_file = g_file_dup (f); g_object_unref (globs->file); globs->file = f; @@ -627,17 +631,24 @@ VFSChangeDir (struct TVFSGlobs *globs, char *NewPath) /**************************************************************************************************************************************/ static void -g_file_info_to_TVFSItem (GFileInfo *info, struct TVFSItem *Item) +g_file_info_to_TVFSItem (GFileInfo *info, struct TVFSItem *Item, GFile *reference_file, gboolean follow_symlinks, gboolean add_full_path) { + GFileInfo *symlink_info = NULL; + GError *error; + g_assert (info != NULL); g_assert (Item != NULL); - Item->FName = g_strdup (g_file_info_get_name (info)); - Item->FDisplayName = g_strdup (g_file_info_get_display_name (info)); - Item->sLinkTo = g_file_info_get_symlink_target (info) == NULL ? NULL : g_strdup (g_file_info_get_symlink_target (info)); - Item->iSize = g_file_info_get_size (info); - Item->iPackedSize = -1; - Item->iMode = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE); + if (add_full_path) { + Item->FName = get_absolute_path (reference_file); + if (Item->FName == NULL) + Item->FName = g_strdup (g_file_info_get_name (info)); + Item->FDisplayName = g_filename_display_name (Item->FName); + } else { + Item->FName = g_strdup (g_file_info_get_name (info)); + Item->FDisplayName = g_strdup (g_file_info_get_display_name (info)); + } + Item->sLinkTo = g_strdup (g_file_info_get_symlink_target (info)); Item->m_time = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED); Item->a_time = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS); @@ -648,31 +659,38 @@ g_file_info_to_TVFSItem (GFileInfo *info, struct TVFSItem *Item) // g_print ("(II) g_file_info_to_TVFSItem: type = %d\n", g_file_info_get_file_type (info)); // g_print ("(II) g_file_info_to_TVFSItem: UNIX_MODE = %d\n", Item->iMode); - if (g_file_info_get_is_symlink (info)) { - Item->ItemType = vSymlink; - } - else - { - switch (g_file_info_get_file_type (info)) { - case G_FILE_TYPE_REGULAR: - Item->ItemType = vRegular; - break; - case G_FILE_TYPE_DIRECTORY: - case G_FILE_TYPE_SHORTCUT: /* Used in network:/// */ - case G_FILE_TYPE_MOUNTABLE: - Item->ItemType = vDirectory; - break; - case G_FILE_TYPE_SYMBOLIC_LINK: - Item->ItemType = vSymlink; - break; - case G_FILE_TYPE_SPECIAL: /* socket, fifo, blockdev, chardev */ - Item->ItemType = vBlockdev; - break; - case G_FILE_TYPE_UNKNOWN: - default: Item->ItemType = vRegular; + Item->IsLink = g_file_info_get_is_symlink (info); + if (Item->IsLink && follow_symlinks) { + error = NULL; + symlink_info = g_file_query_info (reference_file, CONST_DEFAULT_QUERY_INFO_ATTRIBUTES, + G_FILE_QUERY_INFO_NONE, NULL, &error); + + if (error) { + g_print ("(EE) g_file_info_to_TVFSItem: g_file_query_info() error: %s\n", error->message); + g_error_free (error); } } + Item->iSize = g_file_info_get_size (symlink_info ? symlink_info : info); + Item->iPackedSize = -1; + Item->iMode = g_file_info_get_attribute_uint32 (symlink_info ? symlink_info : info, G_FILE_ATTRIBUTE_UNIX_MODE); + + switch (g_file_info_get_file_type (symlink_info ? symlink_info : info)) { + case G_FILE_TYPE_REGULAR: + Item->ItemType = vRegular; + break; + case G_FILE_TYPE_DIRECTORY: + case G_FILE_TYPE_SHORTCUT: /* Used in network:/// */ + case G_FILE_TYPE_MOUNTABLE: + Item->ItemType = vDirectory; + break; + case G_FILE_TYPE_SPECIAL: /* socket, fifo, blockdev, chardev */ + Item->ItemType = vBlockdev; + break; + case G_FILE_TYPE_UNKNOWN: + default: Item->ItemType = vRegular; + } + /* fallback to default file mode if read fails */ if (Item->iMode == 0) { if (Item->ItemType == vDirectory) @@ -680,14 +698,18 @@ g_file_info_to_TVFSItem (GFileInfo *info, struct TVFSItem *Item) else Item->iMode = S_IRUSR + S_IWUSR + S_IRGRP + S_IROTH; } + + if (symlink_info) + g_object_unref (symlink_info); } TVFSResult -VFSListNext (struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) +VFSListNext (struct TVFSGlobs *globs, struct TVFSItem *Item) { GError *error; GFileInfo *info; TVFSResult res; + GFile *f; if (globs->file == NULL) { g_print ("(EE) VFSListNext: globs->file == NULL !\n"); @@ -708,15 +730,54 @@ VFSListNext (struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) } if (! error && ! info) return cVFS_No_More_Files; - g_file_info_to_TVFSItem (info, Item); + + f = g_file_get_child (globs->enumerated_file, g_file_info_get_name (info)); + g_file_info_to_TVFSItem (info, Item, f, globs->enum_follow_symlinks, globs->enum_add_full_path); + g_object_unref (f); + g_object_unref (info); return cVFS_OK; } TVFSResult -VFSListFirst (struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) +VFSListFirst (struct TVFSGlobs *globs, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath) { - return VFSListNext (globs, sDir, Item); + GFile *list_file; + GError *error; + TVFSResult res; + + list_file = g_file_resolve_relative_path (globs->file, sDir); + if (! list_file) { + g_print ("(EE) VFSListFirst: list_file == NULL !\n"); + return cVFS_Failed; + } + + if (globs->enumerator == NULL || ! g_file_equal (globs->file, list_file)) { + g_print ("(WW) VFSListFirst: resetting enumerator\n"); + if (globs->enumerator) { + g_file_enumerator_close (globs->enumerator, NULL, NULL); + g_object_unref (globs->enumerator); + } + if (globs->enumerated_file) + g_object_unref (globs->enumerated_file); + globs->enumerated_file = NULL; + error = NULL; + globs->enumerator = g_file_enumerate_children (list_file, CONST_DEFAULT_QUERY_INFO_ATTRIBUTES, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error); + if (error) { + g_print ("(EE) VFSListFirst: g_file_enumerate_children() error: %s\n", error->message); + res = g_error_to_TVFSResult (error); + g_error_free (error); + g_object_unref (list_file); + return res; + } + globs->enumerated_file = g_object_ref (list_file); + } + globs->enum_follow_symlinks = FollowSymlinks; + globs->enum_add_full_path = AddFullPath; + + g_object_unref (list_file); + return VFSListNext (globs, Item); } TVFSResult @@ -725,10 +786,6 @@ VFSListClose (struct TVFSGlobs *globs) GError *error; TVFSResult res; - if (globs->file == NULL) { - g_print ("(EE) VFSListClose: globs->file == NULL !\n"); - return cVFS_Failed; - } if (globs->enumerator == NULL) { g_print ("(EE) VFSListClose: globs->enumerator == NULL !\n"); return cVFS_Failed; @@ -739,6 +796,8 @@ VFSListClose (struct TVFSGlobs *globs) g_file_enumerator_close (globs->enumerator, NULL, &error); g_object_unref (globs->enumerator); globs->enumerator = NULL; + g_object_unref (globs->enumerated_file); + globs->enumerated_file = NULL; if (error) { g_print ("(EE) VFSListClose: g_file_enumerator_close() error: %s\n", error->message); res = g_error_to_TVFSResult (error); @@ -751,39 +810,8 @@ VFSListClose (struct TVFSGlobs *globs) /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ -long -VFSFileExists (struct TVFSGlobs *globs, const char *FileName, const long Use_lstat) -{ - GFile *f; - GError *error; - GFileInfo *info; - - if (globs->file == NULL) { - g_print ("(EE) VFSFileExists: globs->file == NULL !\n"); - return cVFS_Failed; - } - - f = g_file_resolve_relative_path (globs->file, FileName); - if (f == NULL) { - g_print ("(EE) VFSMkDir: g_file_resolve_relative_path() failed.\n"); - return cVFS_Failed; - } - - error = NULL; - info = g_file_query_info (f, G_FILE_ATTRIBUTE_STANDARD_NAME, - Use_lstat ? G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS : G_FILE_QUERY_INFO_NONE, NULL, &error); - g_object_unref (f); - if (error) { -// g_print ("(EE) VFSFileExists: g_file_query_info() error: %s\n", error->message); - g_error_free (error); - return FALSE; - } - g_object_unref (info); - return TRUE; -} - TVFSResult -VFSFileInfo (struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item) +VFSFileInfo (struct TVFSGlobs *globs, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath) { GFile *f; GError *error; @@ -804,15 +832,16 @@ VFSFileInfo (struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item) error = NULL; info = g_file_query_info (f, CONST_DEFAULT_QUERY_INFO_ATTRIBUTES, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error); - g_object_unref (f); if (error) { g_print ("(EE) VFSFileInfo: g_file_query_info() error: %s\n", error->message); res = g_error_to_TVFSResult (error); g_error_free (error); + g_object_unref (f); return res; } - g_file_info_to_TVFSItem (info, Item); + g_file_info_to_TVFSItem (info, Item, f, FollowSymlinks, AddFullPath); g_object_unref (info); + g_object_unref (f); return cVFS_OK; } @@ -956,7 +985,7 @@ VFSMakeSymLink (struct TVFSGlobs *globs, const char *NewFileName, const char *Po } TVFSResult -VFSChmod (struct TVFSGlobs *globs, const char *FileName, const uint Mode) +VFSChmod (struct TVFSGlobs *globs, const char *FileName, guint32 Mode) { GFile *f; GError *error; @@ -987,7 +1016,7 @@ VFSChmod (struct TVFSGlobs *globs, const char *FileName, const uint Mode) } TVFSResult -VFSChown (struct TVFSGlobs *globs, const char *FileName, const uint UID, const uint GID) +VFSChown (struct TVFSGlobs *globs, const char *FileName, guint32 UID, guint32 GID) { GFile *f; GError *error; @@ -1027,7 +1056,7 @@ VFSChown (struct TVFSGlobs *globs, const char *FileName, const uint UID, const u } TVFSResult -VFSChangeTimes (struct TVFSGlobs *globs, char *APath, long mtime, long atime) +VFSChangeTimes (struct TVFSGlobs *globs, const char *APath, guint32 mtime, guint32 atime) { GFile *f; GError *error; @@ -1119,12 +1148,13 @@ VFSGetDirSize_recurse (struct TVFSGlobs *globs, GFile *file, guint64 *size) } guint64 -VFSGetDirSize (struct TVFSGlobs *globs, char *APath) +VFSGetDirSize (struct TVFSGlobs *globs, const char *APath) { GFile *f; guint64 size; - if (globs == NULL) return 0; + if (globs == NULL) + return 0; if (globs->file == NULL) { g_print ("(EE) VFSGetDirSize: globs->file == NULL !\n"); return 0; @@ -1192,14 +1222,14 @@ VFSWriteFile (struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, gpointer Buff } void -VFSSetBlockSize (struct TVFSGlobs *globs, int Value) +VFSSetBlockSize (struct TVFSGlobs *globs, guint32 Value) { if (globs) globs->block_size = Value; } gboolean -VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2) +VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks) { GFile *file1, *file2; GFileInfo *info1, *info2; @@ -1224,7 +1254,8 @@ VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2) error = NULL; info1 = g_file_query_info (file1, G_FILE_ATTRIBUTE_ID_FILESYSTEM, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error); + FollowSymlinks ? G_FILE_QUERY_INFO_NONE : G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, &error); if (error) { g_print ("(EE) VFSIsOnSameFS: g_file_query_info() error: %s\n", error->message); g_error_free (error); @@ -1233,7 +1264,8 @@ VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2) return FALSE; } info2 = g_file_query_info (file2, G_FILE_ATTRIBUTE_ID_FILESYSTEM, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error); + FollowSymlinks ? G_FILE_QUERY_INFO_NONE : G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, &error); if (error) { g_print ("(EE) VFSIsOnSameFS: g_file_query_info() error: %s\n", error->message); g_error_free (error); @@ -1256,7 +1288,7 @@ VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2) } gboolean -VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2) +VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks) { GFile *file1, *file2; gboolean res; @@ -1274,10 +1306,11 @@ VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2) } if (file2 == NULL) { g_print ("(EE) VFSTwoSameFiles: g_file_resolve_relative_path() failed.\n"); + g_object_unref (file1); return FALSE; } - /* FIXME: we should do some I/O test, we're esentially comparing strings at the moment */ + /* FIXME: we should do some I/O test here, we're esentially comparing strings at the moment */ res = g_file_equal (file1, file2); g_object_unref (file1); g_object_unref (file2); @@ -1307,7 +1340,7 @@ vfs_copy_progress_callback (goffset current_num_bytes, } } -#define TUXCMD_DEFAULT_COPY_FLAGS G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA +#define TUXCMD_DEFAULT_COPY_FLAGS G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA TVFSResult VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append) diff --git a/gvfs/tuxcmd-vfs.h b/gvfs/tuxcmd-vfs.h new file mode 120000 index 0000000..b7f193e --- /dev/null +++ b/gvfs/tuxcmd-vfs.h @@ -0,0 +1 @@ +../common/tuxcmd-vfs.h
\ No newline at end of file diff --git a/gvfs/vfs_types.h b/gvfs/vfs_types.h deleted file mode 120000 index c2235a2..0000000 --- a/gvfs/vfs_types.h +++ /dev/null @@ -1 +0,0 @@ -../common/vfs_types.h
\ No newline at end of file diff --git a/libarchive/Makefile b/libarchive/Makefile index 595cd5f..26b4502 100644 --- a/libarchive/Makefile +++ b/libarchive/Makefile @@ -1,30 +1,26 @@ # path definitions DESTDIR = /usr -INSTALL=install -c +INSTALL = install -c INSTALL_DATA = ${INSTALL} -m 644 -DIR_COMMON=../common/ -DIR_LIBARCHIVE=./libarchive-2.7.1 +DIR_LIBARCHIVE = ./libarchive-2.7.1 # compiler options CC = gcc -CPP = g++ -CFLAGS =-I. -I/usr/include -I$(DIR_COMMON) \ - -Wall -fPIC -O2 -g \ - -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \ - -D__VERBOSE_DEBUGx +CFLAGS = -I. -I/usr/include \ + -Wall -fPIC -O2 -g \ + -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \ + -D__VERBOSE_DEBUGx -LIB_SUFFIX=`if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi` +LIB_SUFFIX = `if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi` -VFS_COMMON_OBJECTS=strutils.o treepathutils.o treepath_vfs.o vfsutils.o +VFS_COMMON_OBJECTS = filelist.o filelist-vfs-intf.o strutils.o vfsutils.o + +VFS_OBJECTS = libarchive.o -VFS_OBJECTS=libarchive.o - -.SUFFIXES: .c .cpp +.SUFFIXES: .c .c.o: $(CC) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $< -.cpp.o: - $(CPP) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $< all: static @@ -48,10 +44,10 @@ lib_libarchive_compile: fi; -strutils.o: strutils.c strutils.h -treepathutils.o: treepathutils.c treepathutils.h -vfsutils.o: vfsutils.c vfsutils.h -treepath_vfs.o: treepath_vfs.c treepath_vfs.h +filelist.o: filelist.h filelist.c +filelist-vfs-intf.o: filelist-vfs-intf.h filelist-vfs-intf.c +strutils.o: strutils.h strutils.c +vfsutils.o: vfsutils.h vfsutils.c install:: $(INSTALL) ./libarchive_plugin.so $(DESTDIR)/lib$(LIB_SUFFIX)/tuxcmd/ diff --git a/libarchive/filelist-vfs-intf.c b/libarchive/filelist-vfs-intf.c new file mode 120000 index 0000000..68d7a7c --- /dev/null +++ b/libarchive/filelist-vfs-intf.c @@ -0,0 +1 @@ +../common/filelist-vfs-intf.c
\ No newline at end of file diff --git a/libarchive/filelist-vfs-intf.h b/libarchive/filelist-vfs-intf.h new file mode 120000 index 0000000..f7afe49 --- /dev/null +++ b/libarchive/filelist-vfs-intf.h @@ -0,0 +1 @@ +../common/filelist-vfs-intf.h
\ No newline at end of file diff --git a/libarchive/filelist.c b/libarchive/filelist.c new file mode 120000 index 0000000..9504563 --- /dev/null +++ b/libarchive/filelist.c @@ -0,0 +1 @@ +../common/filelist.c
\ No newline at end of file diff --git a/libarchive/filelist.h b/libarchive/filelist.h new file mode 120000 index 0000000..90a52e1 --- /dev/null +++ b/libarchive/filelist.h @@ -0,0 +1 @@ +../common/filelist.h
\ No newline at end of file diff --git a/libarchive/libarchive.c b/libarchive/libarchive.c index e9ecfc0..13039f2 100644 --- a/libarchive/libarchive.c +++ b/libarchive/libarchive.c @@ -1,5 +1,5 @@ /* libarchive plugin for Tux Commander - * version 0.1.7, designed for libarchive v2.5.5 - v2.7.1 (recommended) + * version 0.2.0, 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 * @@ -27,21 +27,15 @@ #include <string.h> #include <stdlib.h> -#include <stdint.h> -#include <sys/stat.h> -#include <sys/types.h> #include <errno.h> #include <fcntl.h> -#include <dirent.h> -#include <fnmatch.h> -#include <unistd.h> #include <glib.h> -#include "vfs_types.h" +#include "tuxcmd-vfs.h" #include "vfsutils.h" #include "strutils.h" -#include "treepathutils.h" -#include "treepath_vfs.h" +#include "filelist.h" +#include "filelist-vfs-intf.h" #include <archive.h> #include <archive_entry.h> @@ -58,8 +52,8 @@ #endif -#define MODULE_VERSION "0.1.7" -#define MODULE_BUILD_DATE "2009-11-17" +#define MODULE_VERSION "0.2.0" +#define MODULE_BUILD_DATE "2009-11-26" #define DEFAULT_BLOCK_SIZE 65536 @@ -70,20 +64,18 @@ /** Auxiliary classes */ /************** ****************/ - - -// Declaration of the global plugin object +/* declaration of the global plugin object */ struct TVFSGlobs { TVFSLogFunc log_func; char *curr_dir; char *archive_path; - unsigned long block_size; + guint32 block_size; struct PathTree *files; struct VfsFilelistData *vfs_filelist; - u_int64_t total_size; + guint64 total_size; TVFSAskQuestionCallback callback_ask_question; TVFSAskPasswordCallback callback_ask_password; @@ -94,18 +86,16 @@ struct TVFSGlobs { +/******************************************************************************************************/ +/** Basic initialization functions */ +/************** ****************/ - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////// -// Basic initialization functions struct TVFSGlobs * VFSNew (TVFSLogFunc log_func) { struct TVFSGlobs * globs; - globs = (struct TVFSGlobs *) malloc (sizeof (struct TVFSGlobs)); - memset (globs, 0, sizeof (struct TVFSGlobs)); + globs = g_malloc0 (sizeof (struct TVFSGlobs)); globs->block_size = DEFAULT_BLOCK_SIZE; @@ -115,17 +105,28 @@ VFSNew (TVFSLogFunc log_func) globs->callback_progress = NULL; globs->log_func = log_func; - if (globs->log_func != NULL) globs->log_func("libarchive plugin: VFSInit"); + if (globs->log_func != NULL) + globs->log_func ("libarchive plugin: VFSInit"); return globs; } + void -VFSSetCallbacks (struct TVFSGlobs *globs, - TVFSAskQuestionCallback ask_question_callback, - TVFSAskPasswordCallback ask_password_callback, - TVFSProgressCallback progress_func, - void *data) +VFSFree (struct TVFSGlobs *globs) +{ + if (globs->log_func != NULL) + globs->log_func ("libarchive plugin: VFSDestroy"); + g_free (globs); +} + + +void +VFSSetCallbacks (struct TVFSGlobs *globs, + TVFSAskQuestionCallback ask_question_callback, + TVFSAskPasswordCallback ask_password_callback, + TVFSProgressCallback progress_func, + void *data) { globs->callback_ask_question = ask_question_callback; globs->callback_ask_password = ask_password_callback; @@ -133,18 +134,13 @@ VFSSetCallbacks (struct TVFSGlobs *globs, globs->callback_data = data; } -void -VFSFree (struct TVFSGlobs *globs) -{ - if (globs->log_func != NULL) globs->log_func("libarchive plugin: VFSDestroy"); - free (globs); -} int VFSVersion() { return cVFSVersion; } + struct TVFSInfo * VFSGetInfo() { @@ -164,15 +160,16 @@ VFSGetInfo() return module_info; } + char * VFSGetArchiveExts () { /* Make sure these end with a semicolon */ -#define BASIC_FORMATS "tar;cpio;iso;a;shar;" -#define BZIP_FORMATS "tar.bz2;tbz2;" -#define ZLIB_FORMATS "tar.gz;tgz;tar.z;deb;" -#define XZ_FORMATS "tar.lzma;tar.xz;" -#define LZMA_FORMATS "tar.lzma;" +#define BASIC_FORMATS "tar;cpio;iso;a;shar;" +#define BZIP_FORMATS "tar.bz2;tbz2;" +#define ZLIB_FORMATS "tar.gz;tgz;tar.z;deb;" +#define XZ_FORMATS "tar.lzma;tar.xz;" +#define LZMA_FORMATS "tar.lzma;" char *formats; @@ -248,172 +245,207 @@ char *formats; /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ -static TVFSResult libarchive_open(struct archive **a, const char *filename, size_t block_size) +static TVFSResult +libarchive_open (struct archive **a, const char *filename, guint32 block_size) { int r; - *a = archive_read_new(); + *a = archive_read_new (); - // Register supported formats + /* Register supported formats */ + archive_read_support_compression_all (*a); + archive_read_support_format_all (*a); - 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_file (*a, filename, block_size); if (r) { - fprintf(stderr, "(EE) libarchive_open: error occured when opening archive: %s\n", archive_error_string(*a)); + fprintf (stderr, "(EE) libarchive_open: error occured when opening archive: %s\n", archive_error_string (*a)); return cVFS_Failed; } return cVFS_OK; } - - -TVFSResult VFSOpenArchive(struct TVFSGlobs *globs, char *sName) +TVFSResult +VFSOpenArchive (struct TVFSGlobs *globs, const char *sName) { - globs->files = filelist_tree_new(); - globs->vfs_filelist = vfs_filelist_new(globs->files); - globs->curr_dir = NULL; - globs->archive_path = strdup(sName); - globs->total_size = 0; - fprintf(stderr, "(--) VFSOpenArchive: trying to open archive '%s'...\n", globs->archive_path); - TVFSResult Result; struct archive *a; struct archive_entry *entry; + struct TVFSItem *item; int r; + char *s; - Result = libarchive_open(&a, globs->archive_path, globs->block_size); - if (Result == cVFS_OK) - { - for (;;) { - entry = NULL; - r = archive_read_next_header(a, &entry); - if (r == ARCHIVE_EOF) { - break; - } else - if (r == ARCHIVE_WARN) { - log("(WW) VFSOpenArchive: file '%s' - libarchive warning: '%s'\n", archive_entry_pathname(entry), archive_error_string(a)); - } else - if (r != ARCHIVE_OK) { - fprintf(stderr, "(EE) VFSOpenArchive: error occured while reading archive: '%s'\n", archive_error_string(a)); - Result = cVFS_Failed; - break; - } - - log("found file: %s, mode = %x\n", archive_entry_pathname(entry), archive_entry_mode(entry)); - - // Create a TVFSItem entry and fill all info - struct TVFSItem *item = (struct TVFSItem*)malloc(sizeof(struct TVFSItem)); - memset(item, 0, sizeof(struct TVFSItem)); - - item->iSize = (int64_t)archive_entry_size(entry); - item->iPackedSize = -1; /* no support */ - globs->total_size += item->iSize; - - mode_t mode = archive_entry_mode(entry); - item->iMode = archive_entry_mode(entry); - if (S_ISREG(mode)) item->ItemType = vRegular; - else if (S_ISDIR(mode)) item->ItemType = vDirectory; - else if (S_ISCHR(mode)) item->ItemType = vChardev; - else if (S_ISBLK(mode)) item->ItemType = vBlockdev; - else if (S_ISFIFO(mode)) item->ItemType = vFifo; - else if (S_ISLNK(mode)) item->ItemType = vSymlink; - else if (S_ISSOCK(mode)) item->ItemType = vSock; - - if (item->ItemType == vSymlink) - item->sLinkTo = strdup(archive_entry_symlink(entry)); - - item->iUID = geteuid(); - item->iGID = getegid(); - item->m_time = archive_entry_mtime(entry); - item->c_time = archive_entry_ctime(entry); - item->a_time = archive_entry_atime(entry); - - char *s; - if (g_utf8_validate (archive_entry_pathname(entry), -1, NULL)) - s = g_strdup (archive_entry_pathname(entry)); - else { - if (archive_entry_pathname_w(entry)) - s = wide_to_utf8 (archive_entry_pathname_w(entry)); - else - s = g_filename_display_name (archive_entry_pathname(entry)); - } -// g_print("file = '%s', wide = '%ls'\n", archive_entry_pathname(entry), archive_entry_pathname_w(entry)); - - // Add item to the global list and continue with next file - filelist_tree_add_item(globs->files, s, archive_entry_pathname(entry), item, 0); - g_free (s); - } - archive_read_close(a); + globs->files = filelist_tree_new (); + globs->vfs_filelist = vfs_filelist_new (globs->files); + globs->curr_dir = NULL; + globs->archive_path = g_strdup (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) { + for (;;) { + entry = NULL; + r = archive_read_next_header (a, &entry); + if (r == ARCHIVE_EOF) { + break; + } else + if (r == ARCHIVE_WARN) { + log ("(WW) VFSOpenArchive: file '%s' - libarchive warning: '%s'\n", archive_entry_pathname (entry), archive_error_string (a)); + } else + if (r != ARCHIVE_OK) { + fprintf (stderr, "(EE) VFSOpenArchive: error occured while reading archive: '%s'\n", archive_error_string (a)); + Result = cVFS_Failed; + break; + } + + log ("found file: %s, mode = %x\n", archive_entry_pathname (entry), archive_entry_mode (entry)); + + /* Create a TVFSItem entry and fill all info */ + item = g_malloc0 (sizeof (struct TVFSItem)); + + item->iSize = (guint64) archive_entry_size (entry); + item->iPackedSize = -1; /* no support */ + globs->total_size += item->iSize; + + item->iMode = archive_entry_mode (entry); + item->ItemType = vRegular; /* fallback */ + item->IsLink = FALSE; + switch (archive_entry_filetype (entry)) { + case AE_IFDIR: + item->ItemType = vDirectory; + break; + case AE_IFIFO: + item->ItemType = vFifo; + break; + case AE_IFCHR: + item->ItemType = vChardev; + break; + case AE_IFBLK: + item->ItemType = vBlockdev; + break; + case AE_IFSOCK: + item->ItemType = vSock; + break; + case AE_IFLNK: + item->IsLink = TRUE; + break; + case AE_IFMT: + item->ItemType = vOther; + break; + case AE_IFREG: + default: + item->ItemType = vRegular; + break; + } + + if (item->IsLink) + item->sLinkTo = g_strdup (archive_entry_symlink (entry)); + +/* item->iUID = geteuid(); + item->iGID = getegid(); */ + item->iUID = archive_entry_uid (entry); + item->iGID = archive_entry_gid (entry); + item->m_time = archive_entry_mtime (entry); + item->c_time = archive_entry_ctime (entry); + item->a_time = archive_entry_atime (entry); + + /* Create valid UTF-8 filename */ + if (g_utf8_validate (archive_entry_pathname (entry), -1, NULL)) + s = g_strdup (archive_entry_pathname (entry)); + else { + if (archive_entry_pathname_w (entry)) + s = wide_to_utf8 (archive_entry_pathname_w (entry)); + else + s = g_filename_display_name (archive_entry_pathname (entry)); + } + + /* Add item to the global tree and continue with next file */ + filelist_tree_add_item (globs->files, s, item, archive_entry_pathname (entry), 0); + g_free (s); + } + archive_read_close (a); } - archive_read_finish(a); - fprintf(stderr, "(II) VFSOpenArchive: done. \n"); + archive_read_finish (a); + fprintf (stderr, "(II) VFSOpenArchive: done. \n"); - /* FIXME: temporarily disabled */ -// filelist_tree_resolve_symlinks(globs->files); + /* Resolve symlinks */ + GTimer *timer = g_timer_new (); + filelist_tree_resolve_symlinks (globs->files); + g_print (" filelist_tree_resolve_symlinks: elapsed %d ms\n", (int) (g_timer_elapsed (timer, NULL) * 1000)); + g_timer_destroy (timer); - printf("\n\nList of items:\n"); - filelist_tree_print(globs->files); + printf ("\n\nList of items:\n"); + filelist_tree_print (globs->files); return Result; } -TVFSResult VFSClose(struct TVFSGlobs *globs) +TVFSResult +VFSClose (struct TVFSGlobs *globs) { if (globs) { - fprintf(stderr, "(II) VFSClose: Freeing objects...\n"); - if (globs->vfs_filelist) vfs_filelist_free(globs->vfs_filelist); - if (globs->files) filelist_tree_free(globs->files); - if (globs->archive_path) free(globs->archive_path); - if (globs->curr_dir) free(globs->curr_dir); + fprintf (stderr, "(II) VFSClose: Freeing objects...\n"); + if (globs->vfs_filelist) + vfs_filelist_free (globs->vfs_filelist); + if (globs->files) + filelist_tree_free (globs->files); + g_free (globs->archive_path); + g_free (globs->curr_dir); } return cVFS_OK; } + char * VFSGetPath (struct TVFSGlobs *globs) { return include_trailing_path_sep (globs->curr_dir); } -u_int64_t VFSGetFileSystemFree(struct TVFSGlobs *globs, char *APath) -{ - return 0; -} -u_int64_t VFSGetFileSystemSize(struct TVFSGlobs *globs, char *APath) +TVFSResult +VFSGetFileSystemInfo (struct TVFSGlobs *globs, const char *APath, gint64 *FSSize, gint64 *FSFree, char **FSLabel) { - return globs->total_size; + if (FSSize) + *FSSize = globs->total_size; + if (FSFree) + *FSFree = 0; + if (FSLabel) + *FSLabel = NULL; + return cVFS_OK; } - - - /******************************************************************************************************/ -TVFSResult VFSChangeDir(struct TVFSGlobs *globs, char *NewPath) +TVFSResult +VFSChangeDir (struct TVFSGlobs *globs, const char *NewPath) { if (NewPath == NULL) { printf("(EE) VFSChangeDir: NewPath is NULL!\n"); return cVFS_Failed; } - globs->curr_dir = vfs_filelist_change_dir(globs->vfs_filelist, NewPath); - if (globs->curr_dir) return cVFS_OK; - else return cVFS_Failed; + globs->curr_dir = vfs_filelist_change_dir (globs->vfs_filelist, NewPath); + if (globs->curr_dir) + return cVFS_OK; + else + return cVFS_Failed; } -int VFSGetPasswordRequired(struct TVFSGlobs *globs) + +gboolean +VFSGetPasswordRequired (struct TVFSGlobs *globs) { + /* no support for encrypted archives in libarchive */ return FALSE; } /******************************************************************************************************/ -TVFSResult VFSListFirst(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) +TVFSResult +VFSListFirst (struct TVFSGlobs *globs, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath) { if (sDir == NULL) { printf("(EE) VFSListFirst: sDir is NULL!\n"); @@ -421,32 +453,32 @@ TVFSResult VFSListFirst(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *It } printf ("(--) VFSListFirst: Going to list all items in '%s'\n", sDir); - return vfs_filelist_list_first(globs->vfs_filelist, sDir, Item); + return vfs_filelist_list_first (globs->vfs_filelist, sDir, Item, FollowSymlinks, AddFullPath); } -TVFSResult VFSListNext(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) +TVFSResult +VFSListNext (struct TVFSGlobs *globs, struct TVFSItem *Item) { - return vfs_filelist_list_next(globs->vfs_filelist, sDir, Item); + return vfs_filelist_list_next (globs->vfs_filelist, Item); } -TVFSResult VFSListClose(struct TVFSGlobs *globs) +TVFSResult +VFSListClose (struct TVFSGlobs *globs) { - return vfs_filelist_list_close(globs->vfs_filelist); + return vfs_filelist_list_close (globs->vfs_filelist); } /******************************************************************************************************/ -long VFSFileExists(struct TVFSGlobs *globs, const char *FileName, const long Use_lstat) -{ - if (! globs) return FALSE; - return vfs_filelist_file_exists(globs->vfs_filelist, FileName, Use_lstat); -} -TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item) +TVFSResult +VFSFileInfo (struct TVFSGlobs *globs, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath) { - printf("(--) VFSFileInfo: requested info for object '%s'\n", AFileName); - if (!globs) return cVFS_Failed; - return vfs_filelist_file_info(globs->vfs_filelist, AFileName, Item); + 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); } @@ -454,16 +486,22 @@ TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem /** Recursive tree size counting */ /************** ****************/ -u_int64_t VFSGetDirSize(struct TVFSGlobs *globs, char *APath) +guint64 +VFSGetDirSize (struct TVFSGlobs *globs, const char *APath) { - if (! globs) return 0; - return vfs_filelist_get_dir_size(globs->vfs_filelist, APath); + if (! globs) + return 0; + + return vfs_filelist_get_dir_size (globs->vfs_filelist, APath); } -void VFSBreakGetDirSize(struct TVFSGlobs *globs) +void +VFSBreakGetDirSize (struct TVFSGlobs *globs) { - printf("(WW) VFSBreakGetDirSize: calling break\n"); - if (globs) vfs_filelist_get_dir_size_break(globs->vfs_filelist); + printf ("(WW) VFSBreakGetDirSize: calling break\n"); + + if (globs) + vfs_filelist_get_dir_size_break (globs->vfs_filelist); } @@ -471,52 +509,52 @@ void VFSBreakGetDirSize(struct TVFSGlobs *globs) /** Methods modifying the archive */ /************** ****************/ -TVFSResult VFSMkDir(struct TVFSGlobs *globs, const char *sDirName) +TVFSResult VFSMkDir (struct TVFSGlobs *globs, const char *sDirName) { - printf("(WW) VFSMkDir: Not supported in libarchive plugin.\n"); + printf ("(WW) VFSMkDir: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSRemove(struct TVFSGlobs *globs, const char *APath) +TVFSResult VFSRemove (struct TVFSGlobs *globs, const char *APath) { - printf("(WW) VFSRemove: Not supported in libarchive plugin.\n"); + printf ("(WW) VFSRemove: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSRename(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName) +TVFSResult VFSRename (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName) { - printf("(WW) VFSRename: Not supported in libarchive plugin.\n"); + printf ("(WW) VFSRename: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSMakeSymLink(struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo) +TVFSResult VFSMakeSymLink (struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo) { - printf("(WW) VFSMakeSymLink: Not supported in libarchive plugin.\n"); + printf ("(WW) VFSMakeSymLink: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSChmod(struct TVFSGlobs *globs, const char *FileName, const uint Mode) +TVFSResult VFSChmod (struct TVFSGlobs *globs, const char *FileName, guint32 Mode) { - printf("(WW) VFSChmod: Not supported in libarchive plugin.\n"); + printf ("(WW) VFSChmod: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSChown(struct TVFSGlobs *globs, const char *FileName, const uint UID, const uint GID) +TVFSResult VFSChown (struct TVFSGlobs *globs, const char *FileName, guint32 UID, guint32 GID) { - printf("(WW) VFSChown: Not supported in libarchive plugin.\n"); + printf ("(WW) VFSChown: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSChangeTimes(struct TVFSGlobs *globs, char *APath, long mtime, long atime) +TVFSResult VFSChangeTimes (struct TVFSGlobs *globs, char *APath, guint32 mtime, guint32 atime) { - printf("(WW) VFSChangeTimes: Not supported in libarchive plugin.\n"); + printf ("(WW) VFSChangeTimes: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////// +/******************************************************************************************************/ +/************** **/ TVFSFileDes VFSOpenFile(struct TVFSGlobs *globs, const char *APath, int Mode, int *Error) { @@ -547,27 +585,30 @@ int VFSWriteFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buff return 0; } -void VFSSetBlockSize(struct TVFSGlobs *globs, int Value) +void +VFSSetBlockSize (struct TVFSGlobs *globs, guint32 Value) { - globs->block_size = Value; + if (globs) + globs->block_size = Value; } -int VFSIsOnSameFS(struct TVFSGlobs *globs, const char *Path1, const char *Path2) +gboolean +VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks) { - printf("(WW) VFSIsOnSameFS: Not supported in libarchive plugin.\n"); + printf ("(WW) VFSIsOnSameFS: Not supported in libarchive plugin.\n"); return TRUE; } -int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path2) +gboolean +VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks) { - printf("(WW) VFSTwoSameFiles: Not supported in libarchive, comparing by paths.\n"); - return compare_two_same_files(Path1, Path2); + printf ("(WW) VFSTwoSameFiles: Not supported in libarchive, comparing by paths.\n"); + return compare_two_same_files (Path1, Path2); } -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////// - +/******************************************************************************************************/ +/************** **/ @@ -576,158 +617,154 @@ int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path * 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, int Append) -{ - int r; - int fd; - const void *buff; - size_t size, bytes_to_write; - ssize_t bytes_written, total_written; - off_t offset; - off_t output_offset; - u_int64_t file_size; - gboolean cancel = FALSE; - - - printf("(II) my_archive_read_data_into_fd: extracting to '%s', Append = %d\n", sDstName, Append); - - if (Append) fd = open(sDstName, O_APPEND | O_WRONLY); - else 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; - } - - total_written = 0; - output_offset = 0; - file_size = (u_int64_t)archive_entry_size(entry); - - while ((r = archive_read_data_block(a, &buff, &size, &offset)) == ARCHIVE_OK) { - const char *p = buff; - if (offset > output_offset) { - lseek(fd, offset - output_offset, SEEK_CUR); - output_offset = offset; - } - while (size > 0) { - if (cancel) break; - bytes_to_write = size; - if (bytes_to_write > max_block) - 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; - } - output_offset += bytes_written; - total_written += bytes_written; - p += bytes_written; - size -= bytes_written; - - 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)) { - cancel = TRUE; - break; - } -// usleep(100000); - } - } - } - - if ((close(fd)) || ((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; - } - 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; - } - printf("(II) my_archive_read_data_into_fd: done.\n"); - return cVFS_OK; -} - - -TVFSResult VFSCopyToLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append) -{ - 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"); +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) +{ + int r; + int fd; + const void *buff; + size_t size, bytes_to_write; + ssize_t bytes_written, total_written; + off_t offset; + off_t output_offset; + guint64 file_size; + gboolean cancel = FALSE; + + + printf ("(II) my_archive_read_data_into_fd: extracting to '%s', Append = %d\n", sDstName, Append); + + if (Append) + fd = open (sDstName, O_APPEND | O_WRONLY); + else + 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; } - printf("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName); - - struct PathTree *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; + total_written = 0; + output_offset = 0; + file_size = (guint64) archive_entry_size (entry); + + while ((r = archive_read_data_block (a, &buff, &size, &offset)) == ARCHIVE_OK) { + const char *p = buff; + if (offset > output_offset) { + lseek (fd, offset - output_offset, SEEK_CUR); + output_offset = offset; + } + while (size > 0) { + if (cancel) + break; + bytes_to_write = size; + if (bytes_to_write > max_block) + 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; + } + output_offset += bytes_written; + total_written += bytes_written; + p += bytes_written; + size -= bytes_written; + + 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)) { + cancel = TRUE; + break; + } + } } - const char *src = node->original_pathstr; - if (! src) { - fprintf(stderr, "(WW) VFSCopyToLocal: cannot determine original filename\n"); - src = sSrcName; + if (close (fd) || (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; + } + 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; } - printf("(II) VFSCopyToLocal: new src path: '%s'\n", src); + printf ("(II) my_archive_read_data_into_fd: done.\n"); + return cVFS_OK; +} +TVFSResult +VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append) +{ + struct PathTree *node; + const char *src; TVFSResult Result; struct archive *a; struct archive_entry *entry; int r; - gboolean found = FALSE; - - Result = libarchive_open(&a, globs->archive_path, globs->block_size); - if (Result == cVFS_OK) - { - for (;;) { - entry = NULL; - r = archive_read_next_header(a, &entry); - if (r == ARCHIVE_EOF) { - break; - } else - if (r == ARCHIVE_WARN) { - log("(WW) VFSOpen: file '%s' - libarchive warning: '%s'\n", archive_entry_pathname(entry), archive_error_string(a)); - } else - if (r != ARCHIVE_OK) { - fprintf(stderr, "(EE) VFSCopyToLocal: error occured while reading archive: '%s'\n", archive_error_string(a)); - Result = cVFS_Failed; - break; - } - -// printf ("found file: %s, mode = %x\n", archive_entry_pathname(entry), archive_entry_mode(entry)); - const char *ssrc = src; - const char *asrc = archive_entry_pathname(entry); - if (IS_DIR_SEP(*ssrc)) ssrc++; - if (IS_DIR_SEP(*asrc)) asrc++; - -// printf ("strcmp: '%s' vs. '%s'\n", ssrc, asrc); - if (strcmp(ssrc, asrc) == 0) { -// printf("--> found file, extracting\n"); - fprintf(stderr, "(II) VFSCopyToLocal: extract_file_path(sDstName) = '%s', extract_file_name(sDstName) = '%s' \n", extract_file_path(sDstName), extract_file_name(sDstName)); - found = TRUE; - - Result = my_archive_read_data_into_fd(globs, a, entry, sDstName, globs->block_size, Append); - break; - } - } - archive_read_close(a); + gboolean found; + + 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; + } + + printf ("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName); + + 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; } - archive_read_finish(a); - if ((! found) && Result == cVFS_OK) { - fprintf(stderr, "(EE) VFSCopyToLocal: file not found in archive.\n"); + src = node->original_pathstr; + if (! src) { + fprintf (stderr, "(WW) VFSCopyToLocal: cannot determine original filename\n"); + src = sSrcName; + } + printf ("(II) VFSCopyToLocal: new src path: '%s'\n", src); + + + found = FALSE; + Result = libarchive_open (&a, globs->archive_path, globs->block_size); + if (Result == cVFS_OK) { + for (;;) { + entry = NULL; + r = archive_read_next_header (a, &entry); + if (r == ARCHIVE_EOF) { + break; + } else + if (r == ARCHIVE_WARN) { + log("(WW) VFSOpen: file '%s' - libarchive warning: '%s'\n", archive_entry_pathname (entry), archive_error_string (a)); + } else + if (r != ARCHIVE_OK) { + fprintf (stderr, "(EE) VFSCopyToLocal: error occured while reading archive: '%s'\n", archive_error_string (a)); + Result = cVFS_Failed; + break; + } + + if (g_strcmp0 (src, archive_entry_pathname (entry)) == 0) { + found = TRUE; + Result = my_archive_read_data_into_fd (globs, a, entry, sDstName, globs->block_size, Append); + break; + } + } + archive_read_close (a); + } + archive_read_finish (a); + + if (! found && Result == cVFS_OK) { + fprintf (stderr, "(EE) VFSCopyToLocal: file not found in archive.\n"); Result = cVFS_ReadErr; } - fprintf(stderr, "(II) VFSCopyToLocal: finished. \n"); + fprintf (stderr, "(II) VFSCopyToLocal: finished. \n"); return Result; } -TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append) + +TVFSResult +VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append) { - printf("(WW) VFSCopyFromLocal: Not supported in libarchive plugin.\n"); + printf ("(WW) VFSCopyFromLocal: Not supported in libarchive plugin.\n"); return cVFS_Not_Supported; } @@ -737,7 +774,6 @@ TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const /********** * TODO: * - * - UTF-8, FName/FDisplayName and absolute/relative paths revision needed! * - archive testing (needs new VFS API) * - write support * - support creating new archives (needs new VFS API) diff --git a/libarchive/treepath_vfs.c b/libarchive/treepath_vfs.c deleted file mode 120000 index f4b41b3..0000000 --- a/libarchive/treepath_vfs.c +++ /dev/null @@ -1 +0,0 @@ -../common/treepath_vfs.c
\ No newline at end of file diff --git a/libarchive/treepath_vfs.h b/libarchive/treepath_vfs.h deleted file mode 120000 index a1e19e7..0000000 --- a/libarchive/treepath_vfs.h +++ /dev/null @@ -1 +0,0 @@ -../common/treepath_vfs.h
\ No newline at end of file diff --git a/libarchive/treepathutils.c b/libarchive/treepathutils.c deleted file mode 120000 index ae760bc..0000000 --- a/libarchive/treepathutils.c +++ /dev/null @@ -1 +0,0 @@ -../common/treepathutils.c
\ No newline at end of file diff --git a/libarchive/treepathutils.h b/libarchive/treepathutils.h deleted file mode 120000 index 4e3c904..0000000 --- a/libarchive/treepathutils.h +++ /dev/null @@ -1 +0,0 @@ -../common/treepathutils.h
\ No newline at end of file diff --git a/libarchive/tuxcmd-vfs.h b/libarchive/tuxcmd-vfs.h new file mode 120000 index 0000000..b7f193e --- /dev/null +++ b/libarchive/tuxcmd-vfs.h @@ -0,0 +1 @@ +../common/tuxcmd-vfs.h
\ No newline at end of file diff --git a/libarchive/vfs_types.h b/libarchive/vfs_types.h deleted file mode 120000 index c2235a2..0000000 --- a/libarchive/vfs_types.h +++ /dev/null @@ -1 +0,0 @@ -../common/vfs_types.h
\ No newline at end of file diff --git a/unrar/Makefile b/unrar/Makefile index 7407cbe..14aa5fc 100644 --- a/unrar/Makefile +++ b/unrar/Makefile @@ -1,23 +1,23 @@ # path definitions DESTDIR = /usr -INSTALL=install -c +INSTALL = install -c INSTALL_DATA = ${INSTALL} -m 644 DIR_UNRAR = unrar # compiler options CC = gcc CPP = g++ -CFLAGS =-I. -I/usr/include -I$(DIR_UNRAR) \ - -Wall -fPIC -O2 -g \ - -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \ - -D__VERBOSE_DEBUGx +CFLAGS = -I. -I/usr/include -I$(DIR_UNRAR) \ + -Wall -fPIC -O2 -g \ + -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \ + -D__VERBOSE_DEBUGx -LIB_SUFFIX=`if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi` +LIB_SUFFIX = `if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi` -UNRAR_LIB_OBJ=$(DIR_UNRAR)/filestr.o $(DIR_UNRAR)/scantree.o $(DIR_UNRAR)/dll.o +UNRAR_LIB_OBJ = $(DIR_UNRAR)/filestr.o $(DIR_UNRAR)/scantree.o $(DIR_UNRAR)/dll.o -UNRAR_OBJECTS=$(DIR_UNRAR)/rar.o $(DIR_UNRAR)/strlist.o $(DIR_UNRAR)/strfn.o \ +UNRAR_OBJECTS = $(DIR_UNRAR)/rar.o $(DIR_UNRAR)/strlist.o $(DIR_UNRAR)/strfn.o \ $(DIR_UNRAR)/pathfn.o $(DIR_UNRAR)/int64.o $(DIR_UNRAR)/savepos.o \ $(DIR_UNRAR)/global.o $(DIR_UNRAR)/file.o $(DIR_UNRAR)/filefn.o \ $(DIR_UNRAR)/filcreat.o $(DIR_UNRAR)/archive.o $(DIR_UNRAR)/arcread.o \ @@ -32,9 +32,9 @@ UNRAR_OBJECTS=$(DIR_UNRAR)/rar.o $(DIR_UNRAR)/strlist.o $(DIR_UNRAR)/strfn.o \ $(DIR_UNRAR)/unpack.o $(DIR_UNRAR)/cmddata.o -VFS_COMMON_OBJECTS=strutils.o treepathutils.o treepath_vfs.o vfsutils.o +VFS_COMMON_OBJECTS = filelist.o filelist-vfs-intf.o strutils.o vfsutils.o -VFS_OBJECTS=unrar.o rarlog.o +VFS_OBJECTS = unrar.o rarlog.o .SUFFIXES: .c .cpp @@ -52,11 +52,11 @@ libunrar_plugin.so: libunrar $(VFS_COMMON_OBJECTS) $(VFS_OBJECTS) libunrar: ( cd $(DIR_UNRAR) && make -f ../Makefile.unrar ) || exit 1 -strutils.o: strutils.c strutils.h -treepathutils.o: treepathutils.c treepathutils.h -vfsutils.o: vfsutils.c vfsutils.h -treepath_vfs.o: treepath_vfs.c treepath_vfs.h -rarlog.o: rarlog.cpp rarlog.hpp +filelist.o: filelist.h filelist.c +filelist-vfs-intf.o: filelist-vfs-intf.h filelist-vfs-intf.c +strutils.o: strutils.h strutils.c +vfsutils.o: vfsutils.h vfsutils.c +rarlog.o: rarlog.hpp rarlog.cpp install:: $(INSTALL) ./libunrar_plugin.so $(DESTDIR)/lib$(LIB_SUFFIX)/tuxcmd/ diff --git a/unrar/filelist-vfs-intf.c b/unrar/filelist-vfs-intf.c new file mode 120000 index 0000000..68d7a7c --- /dev/null +++ b/unrar/filelist-vfs-intf.c @@ -0,0 +1 @@ +../common/filelist-vfs-intf.c
\ No newline at end of file diff --git a/unrar/filelist-vfs-intf.h b/unrar/filelist-vfs-intf.h new file mode 120000 index 0000000..f7afe49 --- /dev/null +++ b/unrar/filelist-vfs-intf.h @@ -0,0 +1 @@ +../common/filelist-vfs-intf.h
\ No newline at end of file diff --git a/unrar/filelist.c b/unrar/filelist.c new file mode 120000 index 0000000..9504563 --- /dev/null +++ b/unrar/filelist.c @@ -0,0 +1 @@ +../common/filelist.c
\ No newline at end of file diff --git a/unrar/filelist.h b/unrar/filelist.h new file mode 120000 index 0000000..90a52e1 --- /dev/null +++ b/unrar/filelist.h @@ -0,0 +1 @@ +../common/filelist.h
\ No newline at end of file diff --git a/unrar/treepath_vfs.c b/unrar/treepath_vfs.c deleted file mode 120000 index f4b41b3..0000000 --- a/unrar/treepath_vfs.c +++ /dev/null @@ -1 +0,0 @@ -../common/treepath_vfs.c
\ No newline at end of file diff --git a/unrar/treepath_vfs.h b/unrar/treepath_vfs.h deleted file mode 120000 index a1e19e7..0000000 --- a/unrar/treepath_vfs.h +++ /dev/null @@ -1 +0,0 @@ -../common/treepath_vfs.h
\ No newline at end of file diff --git a/unrar/treepathutils.c b/unrar/treepathutils.c deleted file mode 120000 index ae760bc..0000000 --- a/unrar/treepathutils.c +++ /dev/null @@ -1 +0,0 @@ -../common/treepathutils.c
\ No newline at end of file diff --git a/unrar/treepathutils.h b/unrar/treepathutils.h deleted file mode 120000 index 4e3c904..0000000 --- a/unrar/treepathutils.h +++ /dev/null @@ -1 +0,0 @@ -../common/treepathutils.h
\ No newline at end of file diff --git a/unrar/tuxcmd-vfs.h b/unrar/tuxcmd-vfs.h new file mode 120000 index 0000000..b7f193e --- /dev/null +++ b/unrar/tuxcmd-vfs.h @@ -0,0 +1 @@ +../common/tuxcmd-vfs.h
\ No newline at end of file diff --git a/unrar/unrar.c b/unrar/unrar.c index 0db1493..61ce4c4 100644 --- a/unrar/unrar.c +++ b/unrar/unrar.c @@ -1,6 +1,6 @@ /* UNRAR plugin for Tux Commander - * version 0.3.7, designed for unrar v3.8.2 - * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net> + * version 0.4.0, designed for unrar v3.8.2 + * Copyright (C) 2007-2009 Tomas Bzatek <tbzatek@users.sourceforge.net> * Check for updates on tuxcmd.sourceforge.net * * Uses UNRAR sources @@ -26,21 +26,17 @@ */ #include <string.h> +#include <stdio.h> #include <stdlib.h> -#include <stdint.h> -#include <sys/stat.h> -#include <sys/types.h> #include <errno.h> -#include <dirent.h> -#include <fnmatch.h> #include <unistd.h> #include <glib.h> -#include "vfs_types.h" +#include "tuxcmd-vfs.h" #include "vfsutils.h" #include "strutils.h" -#include "treepathutils.h" -#include "treepath_vfs.h" +#include "filelist.h" +#include "filelist-vfs-intf.h" #define _UNIX @@ -48,15 +44,20 @@ #include "unrar/dll.hpp" -// Compatibility types from headers.hpp +/* Compatibility types from headers.hpp */ enum HOST_SYSTEM { - HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4, - HOST_BEOS=5,HOST_MAX + HOST_MSDOS = 0, + HOST_OS2 = 1, + HOST_WIN32 = 2, + HOST_UNIX = 3, + HOST_MACOS = 4, + HOST_BEOS = 5, + HOST_MAX }; -#define VERSION "0.3.7" -#define BUILD_DATE "2009-10-25" +#define VERSION "0.4.0" +#define BUILD_DATE "2009-11-26" #define DEFAULT_BLOCK_SIZE 65536 @@ -64,7 +65,7 @@ enum HOST_SYSTEM { -// Declaration of the global plugin object +/* Declaration of the global plugin object */ struct TVFSGlobs { TVFSLogFunc log_func; char *curr_dir; @@ -75,15 +76,15 @@ struct TVFSGlobs { gboolean volume_missing_abort; char *password; - unsigned long block_size; + guint32 block_size; struct PathTree *files; struct VfsFilelistData *vfs_filelist; - int64_t total_size; + guint64 total_size; - int64_t extract_file_size; - int64_t extract_done; + guint64 extract_file_size; + guint64 extract_done; gboolean extract_cancelled; TVFSAskQuestionCallback callback_ask_question; @@ -100,13 +101,13 @@ struct TVFSGlobs { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////// // Basic initialization functions + struct TVFSGlobs * VFSNew (TVFSLogFunc log_func) { struct TVFSGlobs * globs; - globs = (struct TVFSGlobs *) malloc (sizeof (struct TVFSGlobs)); - memset (globs, 0, sizeof (struct TVFSGlobs)); + globs = g_malloc0 (sizeof (struct TVFSGlobs)); globs->block_size = DEFAULT_BLOCK_SIZE; globs->need_password = FALSE; @@ -120,7 +121,8 @@ VFSNew (TVFSLogFunc log_func) globs->callback_progress = NULL; globs->log_func = log_func; - if (globs->log_func != NULL) globs->log_func("unrar plugin: VFSInit"); + if (globs->log_func) + globs->log_func("unrar plugin: VFSInit"); return globs; } @@ -141,19 +143,23 @@ VFSSetCallbacks (struct TVFSGlobs *globs, void VFSFree (struct TVFSGlobs *globs) { - if (globs->log_func != NULL) globs->log_func("unrar plugin: VFSDestroy"); - free (globs); + if (globs->log_func) + globs->log_func("unrar plugin: VFSDestroy"); + g_free (globs); } -int VFSVersion() +int +VFSVersion () { return cVFSVersion; } struct TVFSInfo * -VFSGetInfo() +VFSGetInfo () { - struct TVFSInfo *module_info = g_malloc0 (sizeof (struct TVFSInfo)); + struct TVFSInfo *module_info; + + module_info = g_malloc0 (sizeof (struct TVFSInfo)); module_info->ID = g_strdup ("unrar_plugin"); module_info->Name = g_strdup ("UNRAR plugin"); @@ -174,77 +180,79 @@ VFSGetArchiveExts () /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ -int unrar_callback(UINT msg, LONG UserData, LONG P1, LONG P2) +static int +unrar_callback (UINT msg, LONG UserData, LONG P1, LONG P2) { + struct TVFSGlobs *globs; + // fprintf(stderr, "(II) unrar_callback called: msg = %d, UserData = %lx, sizeof(UserData) = %ld, P1 = %ld, P2 = %ld\n", msg, UserData, sizeof(UserData), P1, P2); if (! UserData) { - fprintf(stderr, "(WW) unrar_callback: UserData == NULL, exiting!\n"); + fprintf (stderr, "(WW) unrar_callback: UserData == NULL, exiting!\n"); return 0; } - struct TVFSGlobs *globs = (struct TVFSGlobs *)UserData; + globs = (struct TVFSGlobs *) UserData; // >= 0 => Weiter, -1 => Stop - switch(msg) - { + switch (msg) { case UCM_CHANGEVOLUME: { if (P2 == RAR_VOL_ASK) { - fprintf(stderr, " (II) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_ASK, P1 = %ld, (char*)P1 = '%s' \n", P1, (char*)P1); - if (P1) { - if (globs->callback_ask_question) { - static const char *choices[] = { - "Abort", /* response = 0 */ - "Ignore", /* response = 1 */ - NULL - }; - char *message, *s; - int choice = -1; - - s = g_filename_to_utf8 ((char *)P1, -1, NULL, NULL, NULL); - message = g_strdup_printf ("Archive is incomplete, volume missing: \n\n%s", s ? s : (char *)P1); - globs->callback_ask_question (message, &choices[0], &choice, 0, - globs->callback_data); - g_free (message); - if (s) g_free (s); - - if (choice != 1) - globs->volume_missing_abort = TRUE; - return -1; - } else { - if (access((char*)P1, R_OK) != 0) { - fprintf(stderr, "(EE) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_ASK: access test failed - missing part? Error = %s \n", strerror(errno)); - return -1; - } - } - } + fprintf (stderr, " (II) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_ASK, P1 = %ld, (char*)P1 = '%s' \n", P1, (char*)P1); + if (P1) { + if (globs->callback_ask_question) { + static const char *choices[] = { + "Abort", /* response = 0 */ + "Ignore", /* response = 1 */ + NULL + }; + char *message, *s; + int choice = -1; + + s = g_filename_display_name((char *)P1); + message = g_strdup_printf ("Archive is incomplete, volume missing: \n\n%s", s ? s : (char *)P1); + globs->callback_ask_question (message, &choices[0], &choice, 0, + globs->callback_data); + g_free (message); + g_free (s); + + if (choice != 1) + globs->volume_missing_abort = TRUE; + return -1; + } else { + if (access((char*)P1, R_OK) != 0) { + fprintf (stderr, "(EE) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_ASK: access test failed - missing part? Error = %s \n", strerror (errno)); + return -1; + } + } + } } else if (P2 == RAR_VOL_NOTIFY) { - fprintf(stderr, " (II) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_NOTIFY, P1 = %ld, (char*)P1 = '%s' \n", P1, (char*)P1); + fprintf (stderr, " (II) unrar_callback: UCM_CHANGEVOLUME message, RAR_VOL_NOTIFY, P1 = %ld, (char*)P1 = '%s' \n", P1, (char*)P1); } break; } case UCM_PROCESSDATA: { - fprintf(stderr, " (II) unrar_callback: UCM_PROCESSDATA message, P1 = %ld, P2 = %ld \n", P1, P2); + fprintf (stderr, " (II) unrar_callback: UCM_PROCESSDATA message, P1 = %ld, P2 = %ld \n", P1, P2); // printf(" (II) unrar_callback: globs = 0x%lX, UserData = 0x%lX \n", (unsigned long int)globs, UserData); - if ((globs) && (globs->callback_progress)) { -// printf(" (II) unrar_callback: globs->extract_callback_func = 0x%lX, globs->extract_callback_data = 0x%lX \n", (unsigned long int)globs->extract_callback_func, (unsigned long int)globs->extract_callback_data); -// 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; - int res = globs->callback_progress(globs->extract_done, globs->extract_file_size, globs->callback_data); - -// fprintf(stderr, " (II) unrar_callback: res = %d \n", res); - if (! res ) { - globs->extract_cancelled = TRUE; - fprintf(stderr, "(WW) unrar_callback: received cancellation result\n"); - return -1; // Cancel operation - } + if (globs && globs->callback_progress) { +// printf(" (II) unrar_callback: globs->extract_callback_func = 0x%lX, globs->extract_callback_data = 0x%lX \n", (unsigned long int)globs->extract_callback_func, (unsigned long int)globs->extract_callback_data); +// 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; + int res = globs->callback_progress(globs->extract_done, globs->extract_file_size, globs->callback_data); + +// fprintf(stderr, " (II) unrar_callback: res = %d \n", res); + if (! res ) { + globs->extract_cancelled = TRUE; + fprintf (stderr, "(WW) unrar_callback: received cancellation result\n"); + return -1; // Cancel operation + } } break; } case UCM_NEEDPASSWORD: { - fprintf(stderr, " (II) unrar_callback: UCM_NEEDPASSWORD message, P1 = %ld, P2 = %ld, (char*)P1 = '%s', maxlen = %ld \n", P1, P2, (char*)P1, P2); + fprintf (stderr, " (II) unrar_callback: UCM_NEEDPASSWORD message, P1 = %ld, P2 = %ld, (char*)P1 = '%s', maxlen = %ld \n", P1, P2, (char*)P1, P2); char *passwd = NULL; int res = FALSE; @@ -258,8 +266,8 @@ int unrar_callback(UINT msg, LONG UserData, LONG P1, LONG P2) if (res && passwd) { fprintf(stderr, " (II) unrar_callback: setting password to '%s'\n", passwd); if (strlen (passwd) > 0) { - strncpy((char *)P1, passwd, P2); - if (globs->password) g_free (globs->password); + strncpy ((char *)P1, passwd, P2); + g_free (globs->password); globs->password = g_strdup (passwd); } g_free (passwd); @@ -277,22 +285,25 @@ int unrar_callback(UINT msg, LONG UserData, LONG P1, LONG P2) return 0; } -int PASCAL unrar_changevol_proc(char *ArcName, int Mode) +static int PASCAL +unrar_changevol_proc (char *ArcName, int Mode) { - fprintf(stderr, "(II) unrar_changevol_proc called: ArcName = '%s', Mode = %d\n", ArcName, Mode); + fprintf (stderr, "(II) unrar_changevol_proc called: ArcName = '%s', Mode = %d\n", ArcName, Mode); return 0; } -int PASCAL unrar_process_data_proc(unsigned char *Addr, int Size) +static int PASCAL +unrar_process_data_proc (unsigned char *Addr, int Size) { - fprintf(stderr, "(II) unrar_process_data_proc called: Addr = '%s', Size = %d\n", Addr, Size); + fprintf (stderr, "(II) unrar_process_data_proc called: Addr = '%s', Size = %d\n", Addr, Size); return 0; } -time_t rar_time_to_unix(unsigned int FileTime) +static time_t +rar_time_to_unix (unsigned int FileTime) { struct tm t; t.tm_sec = (FileTime & 0x1f) * 2; @@ -303,146 +314,155 @@ time_t rar_time_to_unix(unsigned int FileTime) t.tm_year = (FileTime >> 25) + 80; t.tm_isdst = -1; // printf("date: %d-%.2d-%.2d %d:%.2d:%.2d \n", t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); - return(mktime(&t)); + return (mktime(&t)); } -TVFSResult VFSOpenArchive(struct TVFSGlobs *globs, char *sName) +/* ----------------------------------------------------------------------------------------------------------- */ + +TVFSResult +VFSOpenArchive (struct TVFSGlobs *globs, const char *sName) { - TVFSResult Result = cVFS_OK; + TVFSResult Result; + HANDLE PASCAL handle; + struct RAROpenArchiveDataEx *archive_data; - globs->files = filelist_tree_new(); - globs->vfs_filelist = vfs_filelist_new(globs->files); + Result = cVFS_OK; + + globs->files = filelist_tree_new (); + globs->vfs_filelist = vfs_filelist_new (globs->files); globs->curr_dir = NULL; - globs->archive_path = strdup(sName); + globs->archive_path = g_strdup (sName); globs->total_size = 0; globs->failed_passwd_callback = FALSE; globs->volume_missing_abort = FALSE; - fprintf(stderr, "(--) VFSOpenArchive: trying to open archive '%s'...\n", globs->archive_path); - - HANDLE PASCAL handle; - struct RAROpenArchiveDataEx *archive_data; + fprintf (stderr, "(--) VFSOpenArchive: trying to open archive '%s'...\n", globs->archive_path); - archive_data = (struct RAROpenArchiveDataEx*) malloc(sizeof(struct RAROpenArchiveDataEx)); - memset(archive_data, 0, sizeof(struct RAROpenArchiveDataEx)); + /* WARNING: do not use g_malloc0() here, leads to memory corruption */ + archive_data = malloc (sizeof (struct RAROpenArchiveDataEx)); + memset (archive_data, 0, sizeof (struct RAROpenArchiveDataEx)); archive_data->ArcName = globs->archive_path; archive_data->CmtBuf = NULL; archive_data->CmtBufSize = 0; archive_data->OpenMode = RAR_OM_LIST; - handle = RAROpenArchiveEx(archive_data); + handle = RAROpenArchiveEx (archive_data); // printf(" handle = %lu \n", (unsigned long int)handle); // printf(" archive_data->OpenResult = %d \n", archive_data->OpenResult); // printf(" archive_data->CmtState = %d \n", archive_data->CmtState); // printf(" archive_data->CmtSize = %d \n", archive_data->CmtSize); - if ((handle) && (! archive_data->OpenResult)) - { - // Set callbacks - RARSetCallback(handle, unrar_callback, (LONG)globs); -// RARSetChangeVolProc(handle, unrar_changevol_proc); -// RARSetProcessDataProc(handle, unrar_process_data_proc); - - if (globs->password) { - fprintf(stderr, "(II) VFSOpenArchive: Setting password... \n"); - RARSetPassword(handle, globs->password); - } - - struct RARHeaderDataEx *header; - header = (struct RARHeaderDataEx*) malloc(sizeof(struct RARHeaderDataEx)); - memset(header, 0, sizeof(struct RARHeaderDataEx)); - header->CmtBuf = NULL; - header->CmtBufSize = 0; - - int PASCAL res = 0; - while ((res = RARReadHeaderEx(handle, header)) == 0) - { -// printf(" header->FileName = '%s', Flags = 0x%x\n", header->FileName, header->Flags); - - // Create a TVFSItem entry and fill all info - struct TVFSItem *item = (struct TVFSItem*)malloc(sizeof(struct TVFSItem)); - memset(item, 0, sizeof(struct TVFSItem)); - - item->iSize = (int64_t)((int64_t)(header->UnpSizeHigh * 0x100000000) + (int64_t)header->UnpSize); - item->iPackedSize = (int64_t)((int64_t)(header->PackSizeHigh * 0x100000000) + (int64_t)header->PackSize); - globs->total_size += item->iSize; - if ((header->Flags & 0x00e0 /* LHD_WINDOWMASK */ ) == 0x00e0 /* LHD_DIRECTORY */) - item->ItemType = vDirectory; - else item->ItemType = vRegular; - if ((header->Flags & 0x0004) == 0x0004) globs->need_password = TRUE; - - switch (header->HostOS) - { - case HOST_MSDOS: - case HOST_OS2: - case HOST_WIN32: - if (header->FileAttr & 0x10) header->FileAttr = 0x41ff | header->FileAttr; - else - if (header->FileAttr & 1) header->FileAttr = 0x8124 | header->FileAttr; - else header->FileAttr = 0x81b6 | header->FileAttr; - break; - } - - item->iMode = header->FileAttr; - item->iUID = geteuid(); - item->iGID = getegid(); - item->m_time = rar_time_to_unix(header->FileTime); - item->c_time = item->m_time; - item->a_time = item->m_time; - -// g_print (" valid = %d\n", g_utf8_validate (header->FileName, -1, NULL)); - - char *s; - if (g_utf8_validate (header->FileName, -1, NULL)) - s = g_strdup (header->FileName); - else - s = wide_to_utf8 (header->FileNameW); -// g_print (" ansi = '%s'\n wide = '%ls'\n utf8 = '%s'\n", header->FileName, header->FileNameW, s); - - // Add item to the global list and continue with next file - filelist_tree_add_item(globs->files, s, header->FileName, item, 0); - g_free (s); - - int PASCAL res2 = RARProcessFile(handle, RAR_SKIP, NULL, NULL); - if (res2) printf("RARProcessFile result = %d\n", res2); - } -// 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; - if ((res == ERAR_MISSING_PASSWORD) || ((res == ERAR_BAD_DATA) && (globs->failed_passwd_callback))) - Result = cVFS_BadPassword; - } - free(header); - - res = RARCloseArchive(handle); - if (res) { - fprintf(stderr, "(EE) VFSOpenArchive: RARCloseArchive result = %d\n", res); - } + if (handle && ! archive_data->OpenResult) { + // Set callbacks + RARSetCallback (handle, unrar_callback, (LONG)globs); +// RARSetChangeVolProc(handle, unrar_changevol_proc); +// RARSetProcessDataProc(handle, unrar_process_data_proc); + + if (globs->password) { + fprintf (stderr, "(II) VFSOpenArchive: Setting password... \n"); + RARSetPassword (handle, globs->password); + } + + struct RARHeaderDataEx *header; + /* WARNING: do not use g_malloc0() here, leads to memory corruption */ + header = malloc (sizeof (struct RARHeaderDataEx)); + memset (header, 0, sizeof (struct RARHeaderDataEx)); + + int PASCAL res = 0; + while ((res = RARReadHeaderEx(handle, header)) == 0) { +// printf(" header->FileName = '%s', Flags = 0x%x\n", header->FileName, header->Flags); + + /* Create a TVFSItem entry and fill all info */ + struct TVFSItem *item = g_malloc0 (sizeof (struct TVFSItem)); + + item->iSize = (guint64)((guint64)(header->UnpSizeHigh * 0x100000000) + (guint64)header->UnpSize); + item->iPackedSize = (guint64)((guint64)(header->PackSizeHigh * 0x100000000) + (guint64)header->PackSize); + globs->total_size += item->iSize; + if ((header->Flags & 0x00e0 /* LHD_WINDOWMASK */ ) == 0x00e0 /* LHD_DIRECTORY */) + item->ItemType = vDirectory; + else + item->ItemType = vRegular; + if ((header->Flags & 0x0004) == 0x0004) + globs->need_password = TRUE; + + switch (header->HostOS) { + case HOST_MSDOS: + case HOST_OS2: + case HOST_WIN32: + if (header->FileAttr & 0x10) + header->FileAttr = 0x41ff | header->FileAttr; + else + if (header->FileAttr & 1) + header->FileAttr = 0x8124 | header->FileAttr; + else + header->FileAttr = 0x81b6 | header->FileAttr; + break; + } + + item->iMode = header->FileAttr; + item->iUID = geteuid (); + item->iGID = getegid (); + item->m_time = rar_time_to_unix (header->FileTime); + item->c_time = item->m_time; + item->a_time = item->m_time; + +// g_print (" valid = %d\n", g_utf8_validate (header->FileName, -1, NULL)); + + char *s; + if (g_utf8_validate (header->FileName, -1, NULL)) + s = g_strdup (header->FileName); + else + s = wide_to_utf8 (header->FileNameW); +// g_print (" ansi = '%s'\n wide = '%ls'\n utf8 = '%s'\n", header->FileName, header->FileNameW, s); + + // Add item to the global list and continue with next file + filelist_tree_add_item (globs->files, s, item, header->FileName, 0); + g_free (s); + + int PASCAL res2 = RARProcessFile (handle, RAR_SKIP, NULL, NULL); + if (res2) + printf ("RARProcessFile result = %d\n", res2); + } +// 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; + if (res == ERAR_MISSING_PASSWORD || (res == ERAR_BAD_DATA && globs->failed_passwd_callback)) + Result = cVFS_BadPassword; + } + free (header); + + res = RARCloseArchive(handle); + if (res) + 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; + fprintf (stderr, "(EE) VFSOpenArchive: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult); + Result = cVFS_Failed; } - free(archive_data); - fprintf(stderr, "(II) VFSOpenArchive: done. \n"); - if (globs->need_password) printf("Password present.\n"); - printf("\n\nList of items:\n"); - filelist_tree_print(globs->files); + free (archive_data); + fprintf (stderr, "(II) VFSOpenArchive: done. \n"); + if (globs->need_password) + printf ("Password present.\n"); + printf ("\n\nList of items:\n"); + filelist_tree_print (globs->files); return Result; } -TVFSResult VFSClose(struct TVFSGlobs *globs) +TVFSResult +VFSClose (struct TVFSGlobs *globs) { if (globs) { - fprintf(stderr, "(II) VFSClose: Freeing objects...\n"); - if (globs->vfs_filelist) vfs_filelist_free(globs->vfs_filelist); - if (globs->files) filelist_tree_free(globs->files); - if (globs->archive_path) free(globs->archive_path); - if (globs->curr_dir) free(globs->curr_dir); - if (globs->password) free(globs->password); + fprintf (stderr, "(II) VFSClose: Freeing objects...\n"); + if (globs->vfs_filelist) + vfs_filelist_free(globs->vfs_filelist); + if (globs->files) + filelist_tree_free(globs->files); + g_free (globs->archive_path); + g_free (globs->curr_dir); + g_free (globs->password); } return cVFS_OK; } @@ -453,42 +473,48 @@ VFSGetPath (struct TVFSGlobs *globs) return include_trailing_path_sep (globs->curr_dir); } -u_int64_t VFSGetFileSystemFree(struct TVFSGlobs *globs, char *APath) +TVFSResult +VFSGetFileSystemInfo (struct TVFSGlobs *globs, const char *APath, gint64 *FSSize, gint64 *FSFree, char **FSLabel) { - return 0; -} - -u_int64_t VFSGetFileSystemSize(struct TVFSGlobs *globs, char *APath) -{ - return globs->total_size; + if (FSSize) + *FSSize = globs->total_size; + if (FSFree) + *FSFree = 0; + if (FSLabel) + *FSLabel = NULL; + return cVFS_OK; } - - /******************************************************************************************************/ -TVFSResult VFSChangeDir(struct TVFSGlobs *globs, char *NewPath) +TVFSResult +VFSChangeDir (struct TVFSGlobs *globs, const char *NewPath) { if (NewPath == NULL) { - printf("(EE) VFSChangeDir: NewPath is NULL!\n"); + printf ("(EE) VFSChangeDir: NewPath is NULL!\n"); return cVFS_Failed; } - globs->curr_dir = vfs_filelist_change_dir(globs->vfs_filelist, NewPath); - if (globs->curr_dir) return cVFS_OK; - else return cVFS_Failed; + globs->curr_dir = vfs_filelist_change_dir (globs->vfs_filelist, NewPath); + if (globs->curr_dir) + return cVFS_OK; + else + return cVFS_Failed; } -int VFSGetPasswordRequired(struct TVFSGlobs *globs) +gboolean +VFSGetPasswordRequired (struct TVFSGlobs *globs) { - if (globs) return globs->need_password; + if (globs) + return globs->need_password; return FALSE; } -void VFSResetPassword(struct TVFSGlobs *globs) +void +VFSResetPassword (struct TVFSGlobs *globs) { - if (globs && globs->password) { + if (globs) { g_free (globs->password); globs->password = NULL; } @@ -497,40 +523,41 @@ void VFSResetPassword(struct TVFSGlobs *globs) /******************************************************************************************************/ -TVFSResult VFSListFirst(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) +TVFSResult +VFSListFirst (struct TVFSGlobs *globs, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath) { if (sDir == NULL) { - printf("(EE) VFSListFirst: sDir is NULL!\n"); + 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); + return vfs_filelist_list_first (globs->vfs_filelist, sDir, Item, FollowSymlinks, AddFullPath); } -TVFSResult VFSListNext(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) +TVFSResult +VFSListNext (struct TVFSGlobs *globs, struct TVFSItem *Item) { - return vfs_filelist_list_next(globs->vfs_filelist, sDir, Item); + return vfs_filelist_list_next (globs->vfs_filelist, Item); } -TVFSResult VFSListClose(struct TVFSGlobs *globs) +TVFSResult +VFSListClose (struct TVFSGlobs *globs) { - return vfs_filelist_list_close(globs->vfs_filelist); + return vfs_filelist_list_close (globs->vfs_filelist); } /******************************************************************************************************/ -long VFSFileExists(struct TVFSGlobs *globs, const char *FileName, const long Use_lstat) -{ - if (! globs) return FALSE; - return vfs_filelist_file_exists(globs->vfs_filelist, FileName, Use_lstat); -} -TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item) +TVFSResult +VFSFileInfo (struct TVFSGlobs *globs, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath) { - printf("(--) VFSFileInfo: requested info for object '%s'\n", AFileName); - if (!globs) return cVFS_Failed; - return vfs_filelist_file_info(globs->vfs_filelist, AFileName, Item); + 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); } @@ -538,16 +565,21 @@ TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem /** Recursive tree size counting */ /************** ****************/ -u_int64_t VFSGetDirSize(struct TVFSGlobs *globs, char *APath) +guint64 +VFSGetDirSize (struct TVFSGlobs *globs, const char *APath) { - if (! globs) return 0; - return vfs_filelist_get_dir_size(globs->vfs_filelist, APath); + if (! globs) + return 0; + + return vfs_filelist_get_dir_size (globs->vfs_filelist, APath); } -void VFSBreakGetDirSize(struct TVFSGlobs *globs) +void +VFSBreakGetDirSize (struct TVFSGlobs *globs) { - printf("(WW) VFSBreakGetDirSize: calling break\n"); - if (globs) vfs_filelist_get_dir_size_break(globs->vfs_filelist); + printf ("(WW) VFSBreakGetDirSize: calling break\n"); + if (globs) + vfs_filelist_get_dir_size_break (globs->vfs_filelist); } @@ -555,45 +587,45 @@ void VFSBreakGetDirSize(struct TVFSGlobs *globs) /** Methods modifying the archive */ /************** ****************/ -TVFSResult VFSMkDir(struct TVFSGlobs *globs, const char *sDirName) +TVFSResult VFSMkDir (struct TVFSGlobs *globs, const char *sDirName) { - printf("(WW) VFSMkDir: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSMkDir: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSRemove(struct TVFSGlobs *globs, const char *APath) +TVFSResult VFSRemove (struct TVFSGlobs *globs, const char *APath) { - printf("(WW) VFSRemove: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSRemove: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSRename(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName) +TVFSResult VFSRename (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName) { - printf("(WW) VFSRename: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSRename: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSMakeSymLink(struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo) +TVFSResult VFSMakeSymLink (struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo) { - printf("(WW) VFSMakeSymLink: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSMakeSymLink: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSChmod(struct TVFSGlobs *globs, const char *FileName, const uint Mode) +TVFSResult VFSChmod (struct TVFSGlobs *globs, const char *FileName, guint32 Mode) { - printf("(WW) VFSChmod: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSChmod: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSChown(struct TVFSGlobs *globs, const char *FileName, const uint UID, const uint GID) +TVFSResult VFSChown (struct TVFSGlobs *globs, const char *FileName, guint32 UID, guint32 GID) { - printf("(WW) VFSChown: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSChown: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } -TVFSResult VFSChangeTimes(struct TVFSGlobs *globs, char *APath, long mtime, long atime) +TVFSResult VFSChangeTimes (struct TVFSGlobs *globs, const char *APath, guint32 mtime, guint32 atime) { - printf("(WW) VFSChangeTimes: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSChangeTimes: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } @@ -631,21 +663,25 @@ int VFSWriteFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buff return 0; } -void VFSSetBlockSize(struct TVFSGlobs *globs, int Value) +void +VFSSetBlockSize (struct TVFSGlobs *globs, guint32 Value) { - globs->block_size = Value; + if (globs) + globs->block_size = Value; } -int VFSIsOnSameFS(struct TVFSGlobs *globs, const char *Path1, const char *Path2) +gboolean +VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks) { - printf("(WW) VFSIsOnSameFS: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSIsOnSameFS: Not supported in UNRAR plugin.\n"); return TRUE; } -int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path2) +gboolean +VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks) { - printf("(WW) VFSTwoSameFiles: Not supported in RAR archives, comparing by paths.\n"); - return compare_two_same_files(Path1, Path2); + printf ("(WW) VFSTwoSameFiles: Not supported in RAR archives, comparing by paths.\n"); + return compare_two_same_files (Path1, Path2); } @@ -653,168 +689,166 @@ int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path //////////////////////// -TVFSResult VFSCopyToLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append) +TVFSResult +VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append) { - 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"); + struct PathTree *node; + TVFSResult Result; + gboolean found; + char *src; + + 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; } - printf("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName); + printf ("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName); - struct PathTree *node = filelist_tree_find_node_by_path(globs->files, sSrcName); + node = filelist_tree_find_node_by_path (globs->files, sSrcName); if (! node) { - fprintf(stderr, "(EE) VFSCopyToLocal: cannot find file '%s'\n", sSrcName); + fprintf (stderr, "(EE) VFSCopyToLocal: cannot find file '%s'\n", sSrcName); return cVFS_ReadErr; } - TVFSResult Result = cVFS_OK; - gboolean found = FALSE; + Result = cVFS_OK; + found = FALSE; - char *src = node->original_pathstr; + src = node->original_pathstr; if (! src) { - fprintf(stderr, "(WW) VFSCopyToLocal: cannot determine original filename\n"); - src = (char *)sSrcName; + fprintf (stderr, "(WW) VFSCopyToLocal: cannot determine original filename\n"); + src = (char *) sSrcName; } - printf("(II) VFSCopyToLocal: new src path: '%s'\n", src); + printf ("(II) VFSCopyToLocal: new src path: '%s'\n", src); HANDLE PASCAL handle; struct RAROpenArchiveDataEx *archive_data; - archive_data = (struct RAROpenArchiveDataEx*) malloc(sizeof(struct RAROpenArchiveDataEx)); - memset(archive_data, 0, sizeof(struct RAROpenArchiveDataEx)); + /* WARNING: do not use g_malloc0() here, leads to memory corruption */ + archive_data = malloc (sizeof (struct RAROpenArchiveDataEx)); + memset (archive_data, 0, sizeof (struct RAROpenArchiveDataEx)); archive_data->ArcName = globs->archive_path; - archive_data->CmtBuf = NULL; - archive_data->CmtBufSize = 0; archive_data->OpenMode = RAR_OM_EXTRACT; - handle = RAROpenArchiveEx(archive_data); + handle = RAROpenArchiveEx (archive_data); // printf(" handle = %lu \n", (unsigned long int)handle); // printf(" archive_data->OpenResult = %d \n", archive_data->OpenResult); // printf(" archive_data->CmtState = %d \n", archive_data->CmtState); // printf(" archive_data->CmtSize = %d \n", archive_data->CmtSize); // printf("sizeof(TVFSResult) = %ld \n", sizeof(TVFSResult)); - if ((handle) && (! archive_data->OpenResult)) + if (handle && ! archive_data->OpenResult) { - // Set callbacks -// printf(" setting callback: globs = 0x%lX, (unsigned long int)globs = 0x%lX, (LONG)globs = 0x%lX\n", globs, (unsigned long int)globs, (LONG)globs); - RARSetCallback(handle, unrar_callback, (LONG)globs); -// RARSetChangeVolProc(handle, unrar_changevol_proc); -// RARSetProcessDataProc(handle, unrar_process_data_proc); - - if (globs->password) { - printf("(II) VFSCopyToLocal: Setting password... \n"); - RARSetPassword(handle, globs->password); - } - - struct RARHeaderDataEx *header; - header = (struct RARHeaderDataEx*) malloc(sizeof(struct RARHeaderDataEx)); - memset(header, 0, sizeof(struct RARHeaderDataEx)); - header->CmtBuf = NULL; - header->CmtBufSize = 0; - - int res = 0; - while ((res = RARReadHeaderEx(handle, header)) == 0) - { - char *ssrc = src; - char *asrc = header->FileName; - if (IS_DIR_SEP(*ssrc)) ssrc++; - if (IS_DIR_SEP(*asrc)) asrc++; - if (strcmp(ssrc, asrc) == 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 = (int64_t)((int64_t)(header->UnpSizeHigh * 0x100000000) + (int64_t)header->UnpSize); - globs->extract_cancelled = FALSE; - found = TRUE; - - int res2 = RARProcessFile(handle, RAR_EXTRACT, NULL, (char *)sDstName); - - if (globs->extract_cancelled) { - fprintf(stderr, "(WW) VFSCopyToLocal: cancelled !\n"); - Result = cVFS_Cancelled; - } - else - if (res2) { - fprintf(stderr, "(EE) VFSCopyToLocal: RARProcessFile result = %d\n", res2); - Result = cVFS_ReadErr; - } - break; - } else { - int res2 = RARProcessFile(handle, RAR_SKIP, NULL, NULL); - if (res2) { - fprintf(stderr, "(EE) VFSCopyToLocal: RARProcessFile result = %d\n", res2); - Result = cVFS_ReadErr; - } - } - } - - if ((res != ERAR_END_ARCHIVE) && (res)) { - if (globs->extract_cancelled) { - fprintf(stderr, "(WW) VFSCopyToLocal: cancelled !\n"); - Result = cVFS_Cancelled; - } - 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; - if (globs->password) { - g_free (globs->password); - globs->password = NULL; - } - break; - case ERAR_UNKNOWN: - default: - Result = cVFS_WriteErr; - break; - } - } - } - - free(header); - - res = RARCloseArchive(handle); - if (res) { - fprintf(stderr, "(EE) VFSCopyToLocal: RARCloseArchive result = %d\n", res); - Result = cVFS_ReadErr; - } + // Set callbacks +// printf(" setting callback: globs = 0x%lX, (unsigned long int)globs = 0x%lX, (LONG)globs = 0x%lX\n", globs, (unsigned long int)globs, (LONG)globs); + RARSetCallback (handle, unrar_callback, (LONG)globs); +// RARSetChangeVolProc(handle, unrar_changevol_proc); +// RARSetProcessDataProc(handle, unrar_process_data_proc); + + if (globs->password) { + printf ("(II) VFSCopyToLocal: Setting password... \n"); + RARSetPassword (handle, globs->password); + } + + struct RARHeaderDataEx *header; + /* WARNING: do not use g_malloc0() here, leads to memory corruption */ + header = malloc (sizeof (struct RARHeaderDataEx)); + memset (header, 0, sizeof (struct RARHeaderDataEx)); + + int res = 0; + while ((res = RARReadHeaderEx(handle, header)) == 0) { + 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; + + int res2 = RARProcessFile (handle, RAR_EXTRACT, NULL, (char *)sDstName); + + if (globs->extract_cancelled) { + fprintf (stderr, "(WW) VFSCopyToLocal: cancelled !\n"); + Result = cVFS_Cancelled; + } + else + if (res2) { + fprintf (stderr, "(EE) VFSCopyToLocal: RARProcessFile result = %d\n", res2); + Result = cVFS_ReadErr; + } + break; + } else { + int res2 = RARProcessFile (handle, RAR_SKIP, NULL, NULL); + if (res2) { + fprintf (stderr, "(EE) VFSCopyToLocal: RARProcessFile result = %d\n", res2); + Result = cVFS_ReadErr; + } + } + } + + if (res != ERAR_END_ARCHIVE && res) { + if (globs->extract_cancelled) { + fprintf (stderr, "(WW) VFSCopyToLocal: cancelled !\n"); + Result = cVFS_Cancelled; + } + 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; + } + } + } + + free (header); + + res = RARCloseArchive (handle); + if (res) { + fprintf (stderr, "(EE) VFSCopyToLocal: RARCloseArchive result = %d\n", res); + Result = cVFS_ReadErr; + } } else { - fprintf(stderr, "(EE) VFSCopyToLocal: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult); - Result = cVFS_ReadErr; + fprintf (stderr, "(EE) VFSCopyToLocal: error occured when opening archive: OpenResult = %d\n", archive_data->OpenResult); + Result = cVFS_ReadErr; } - free(archive_data); + free (archive_data); - if ((! found) && Result == cVFS_OK) { - fprintf(stderr, "(EE) VFSCopyToLocal: file not found in archive.\n"); + if (! found && Result == cVFS_OK) { + fprintf (stderr, "(EE) VFSCopyToLocal: file not found in archive.\n"); Result = cVFS_ReadErr; } - fprintf(stderr, "(II) VFSCopyToLocal: finished. \n"); + fprintf (stderr, "(II) VFSCopyToLocal: finished. \n"); return Result; } -TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append) +TVFSResult +VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append) { - printf("(WW) VFSCopyFromLocal: Not supported in UNRAR plugin.\n"); + printf ("(WW) VFSCopyFromLocal: Not supported in UNRAR plugin.\n"); return cVFS_Not_Supported; } @@ -824,7 +858,7 @@ TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const /********** * TODO: * - * - UTF-8, FName/FDisplayName and absolute/relative paths revision needed! + * DONE - UTF-8, FName/FDisplayName and absolute/relative paths revision needed! * - find a reliable way to catch bad password errors and free the cached invalid password * - no error reporting when archive is corrupted -- hopefully fixed by ask_question callback * - archive testing (needs new VFS API) diff --git a/unrar/vfs_types.h b/unrar/vfs_types.h deleted file mode 120000 index c2235a2..0000000 --- a/unrar/vfs_types.h +++ /dev/null @@ -1 +0,0 @@ -../common/vfs_types.h
\ No newline at end of file diff --git a/zip/Makefile b/zip/Makefile index 15e4f11..59a2534 100644 --- a/zip/Makefile +++ b/zip/Makefile @@ -1,29 +1,29 @@ # path definitions DESTDIR = /usr -INSTALL=install -c +INSTALL = install -c INSTALL_DATA = ${INSTALL} -m 644 DIR_ZIPARCHIVE = ./ZipArchive/ # compiler options CC = gcc CPP = g++ -CFLAGS =-I. -I$(DIR_ZIPARCHIVE) -I/usr/include \ - -Wall -fPIC -O2 -g \ - -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \ - -D__VERBOSE_DEBUGx +CFLAGS = -I. -I$(DIR_ZIPARCHIVE) -I/usr/include \ + -Wall -fPIC -O2 -g \ + -DG_DISABLE_DEPRECATED -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE \ + -D__VERBOSE_DEBUGx -LIB_SUFFIX=`if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi` +LIB_SUFFIX = `if test \`uname -m\` = x86_64 -o \`uname -m\` = ppc64; then echo 64; fi` -VFS_COMMON_OBJECTS=strutils.o treepathutils.o treepath_vfs.o vfsutils.o +VFS_COMMON_OBJECTS = filelist.o filelist-vfs-intf.o strutils.o vfsutils.o -VFS_C_OBJECTS= -VFS_CPP_OBJECTS=zip.o +VFS_C_OBJECTS = +VFS_CPP_OBJECTS = zip.o .SUFFIXES: .c .cpp .c.o: - $(CPP) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $< + $(CC) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $< .cpp.o: $(CPP) $(CFLAGS) `pkg-config glib-2.0 --cflags` -c $< @@ -36,10 +36,10 @@ libzip_plugin.so: ziparchive $(VFS_COMMON_OBJECTS) $(VFS_CPP_OBJECTS) $(VFS_C_OB ziparchive: ( cd $(DIR_ZIPARCHIVE) && make -f ../Makefile.ziparch ) || exit 1 -strutils.o: strutils.c strutils.h -treepathutils.o: treepathutils.c treepathutils.h -vfsutils.o: vfsutils.c vfsutils.h -treepath_vfs.o: treepath_vfs.c treepath_vfs.h +filelist.o: filelist.h filelist.c +filelist-vfs-intf.o: filelist-vfs-intf.h filelist-vfs-intf.c +strutils.o: strutils.h strutils.c +vfsutils.o: vfsutils.h vfsutils.c install:: diff --git a/zip/filelist-vfs-intf.c b/zip/filelist-vfs-intf.c new file mode 120000 index 0000000..68d7a7c --- /dev/null +++ b/zip/filelist-vfs-intf.c @@ -0,0 +1 @@ +../common/filelist-vfs-intf.c
\ No newline at end of file diff --git a/zip/filelist-vfs-intf.h b/zip/filelist-vfs-intf.h new file mode 120000 index 0000000..f7afe49 --- /dev/null +++ b/zip/filelist-vfs-intf.h @@ -0,0 +1 @@ +../common/filelist-vfs-intf.h
\ No newline at end of file diff --git a/zip/filelist.c b/zip/filelist.c new file mode 120000 index 0000000..9504563 --- /dev/null +++ b/zip/filelist.c @@ -0,0 +1 @@ +../common/filelist.c
\ No newline at end of file diff --git a/zip/filelist.h b/zip/filelist.h new file mode 120000 index 0000000..90a52e1 --- /dev/null +++ b/zip/filelist.h @@ -0,0 +1 @@ +../common/filelist.h
\ No newline at end of file diff --git a/zip/treepath_vfs.c b/zip/treepath_vfs.c deleted file mode 120000 index f4b41b3..0000000 --- a/zip/treepath_vfs.c +++ /dev/null @@ -1 +0,0 @@ -../common/treepath_vfs.c
\ No newline at end of file diff --git a/zip/treepath_vfs.h b/zip/treepath_vfs.h deleted file mode 120000 index a1e19e7..0000000 --- a/zip/treepath_vfs.h +++ /dev/null @@ -1 +0,0 @@ -../common/treepath_vfs.h
\ No newline at end of file diff --git a/zip/treepathutils.c b/zip/treepathutils.c deleted file mode 120000 index ae760bc..0000000 --- a/zip/treepathutils.c +++ /dev/null @@ -1 +0,0 @@ -../common/treepathutils.c
\ No newline at end of file diff --git a/zip/treepathutils.h b/zip/treepathutils.h deleted file mode 120000 index 4e3c904..0000000 --- a/zip/treepathutils.h +++ /dev/null @@ -1 +0,0 @@ -../common/treepathutils.h
\ No newline at end of file diff --git a/zip/tuxcmd-vfs.h b/zip/tuxcmd-vfs.h new file mode 120000 index 0000000..b7f193e --- /dev/null +++ b/zip/tuxcmd-vfs.h @@ -0,0 +1 @@ +../common/tuxcmd-vfs.h
\ No newline at end of file diff --git a/zip/vfs_types.h b/zip/vfs_types.h deleted file mode 120000 index c2235a2..0000000 --- a/zip/vfs_types.h +++ /dev/null @@ -1 +0,0 @@ -../common/vfs_types.h
\ No newline at end of file diff --git a/zip/zip.cpp b/zip/zip.cpp index 8998d8b..0432b6f 100644 --- a/zip/zip.cpp +++ b/zip/zip.cpp @@ -1,6 +1,6 @@ /* ZIP plugin for Tux Commander - * version 0.5.6, designed for ZipArchive v3.2.0 - * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net> + * version 0.6.0, designed for ZipArchive v3.2.0 + * Copyright (C) 2004-2009 Tomas Bzatek <tbzatek@users.sourceforge.net> * Check for updates on tuxcmd.sourceforge.net * * Uses ZipArchive library @@ -35,11 +35,11 @@ #include <unistd.h> #include <glib.h> -#include "vfs_types.h" +#include "tuxcmd-vfs.h" #include "strutils.h" #include "vfsutils.h" -#include "treepathutils.h" -#include "treepath_vfs.h" +#include "filelist.h" +#include "filelist-vfs-intf.h" #include "ZipArchive.h" #include "ZipPlatform.h" @@ -47,8 +47,8 @@ -#define VERSION "0.5.6" -#define BUILD_DATE "2009-10-25" +#define VERSION "0.6.0" +#define BUILD_DATE "2009-11-28" #define DEFAULT_BLOCK_SIZE 65536 @@ -60,7 +60,8 @@ extern "C" { /** Utilities */ /************** ****************/ -TVFSResult get_vfs_errorcode(int m_iCause) +static TVFSResult +get_vfs_errorcode (int m_iCause) { switch (m_iCause) { case 13: return cVFS_WriteErr; // Permission denied @@ -132,9 +133,9 @@ struct TVFSGlobs { CZipArchive *zip; CVFSZipActionCallback *extract_callback; - bool archive_opened; - unsigned long block_size; - bool archive_modified; + gboolean archive_opened; + guint32 block_size; + gboolean archive_modified; struct PathTree *files; struct VfsFilelistData *vfs_filelist; @@ -159,7 +160,7 @@ struct ZIP_API CVFSZipActionCallback : public CZipActionCallback virtual bool Callback(ZIP_SIZE_TYPE uProgress) { - fprintf(stderr, "(II) Callback called, position = %lu; m_uTotalToProcess = %lu; m_uProcessed = %lu\n", + fprintf (stderr, "(II) Callback called, position = %lu; m_uTotalToProcess = %lu; m_uProcessed = %lu\n", uProgress, m_uTotalToProcess, m_uProcessed); bool ret = true; try { @@ -167,7 +168,7 @@ struct ZIP_API CVFSZipActionCallback : public CZipActionCallback ret = globs->callback_progress (m_uProcessed, m_uTotalToProcess, globs->callback_data); } catch (...) { - fprintf(stderr, "(EE) extract_callback: Fatal error occured when calling pCallBackProgress\n"); + fprintf (stderr, "(EE) extract_callback: Fatal error occured when calling pCallBackProgress\n"); } return ret; } @@ -180,60 +181,69 @@ struct ZIP_API CVFSZipActionCallback : public CZipActionCallback * Internal tree functions ********/ -void build_global_filelist(struct TVFSGlobs *globs) +static void +build_global_filelist (struct TVFSGlobs *globs) { - int iCount = globs->zip->GetCount(); - // Ensure the filelist is freed - if (globs->files) filelist_tree_free(globs->files); + int iCount; + int i; + CZipFileHeader *fh; + struct TVFSItem *item; + char *s; + + /* Ensure the filelist is freed */ + if (globs->vfs_filelist) + vfs_filelist_free (globs->vfs_filelist); + if (globs->files) + filelist_tree_free (globs->files); globs->files = filelist_tree_new(); - vfs_filelist_set_files(globs->vfs_filelist, globs->files); + globs->vfs_filelist = vfs_filelist_new (globs->files); - // list files in archive - for (int i = 0; i < iCount; i++) { - CZipFileHeader *fh = globs->zip->GetFileInfo(i); + iCount = globs->zip->GetCount(); + /* list files in the archive */ + for (i = 0; i < iCount; i++) { + fh = globs->zip->GetFileInfo (i); if (fh != NULL) printf(" No: %i, '%s', IsDir: %i, Size: %lu, SystemAttr = 0x%lX, OriginalAttr = 0x%lX, encrypted = %d\n", i, (LPCTSTR)fh->GetFileName(), fh->IsDirectory(), fh->m_uUncomprSize, fh->GetSystemAttr(), fh->GetOriginalAttributes(), fh->IsEncrypted()); } printf("\n\n"); - for (int i = 0; i < iCount; i++) { - CZipFileHeader *fh = globs->zip->GetFileInfo(i); + for (i = 0; i < iCount; i++) { + fh = globs->zip->GetFileInfo (i); if (fh != NULL) { - // Create a TVFSItem entry and fill all info - struct TVFSItem *item = (struct TVFSItem*)malloc(sizeof(struct TVFSItem)); - memset(item, 0, sizeof(struct TVFSItem)); - - item->iSize = (int64_t)fh->m_uUncomprSize; - item->iPackedSize = (int64_t)fh->m_uComprSize; - if (fh->IsDirectory()) - item->ItemType = vDirectory; - else item->ItemType = vRegular; - item->iMode = fh->GetSystemAttr(); - item->iUID = geteuid(); - item->iGID = getegid(); - item->m_time = (__time_t)fh->GetTime(); - item->c_time = item->m_time; - item->a_time = item->m_time; - - if (fh->IsEncrypted()) globs->need_password = TRUE; - - char *s; - - s = g_filename_display_name ((LPCTSTR)fh->GetFileName()); - - // Add item to the global list and continue with next file - filelist_tree_add_item(globs->files, s, s, item, i + 1); - g_free (s); - printf("\n"); + /* Create a TVFSItem entry and fill all info */ + item = (struct TVFSItem *) g_malloc0 (sizeof (struct TVFSItem)); + + item->iSize = (guint64) fh->m_uUncomprSize; + item->iPackedSize = (guint64) fh->m_uComprSize; + if (fh->IsDirectory ()) + item->ItemType = vDirectory; + else + item->ItemType = vRegular; + item->iMode = fh->GetSystemAttr (); + item->iUID = geteuid (); + item->iGID = getegid (); + item->m_time = (__time_t) fh->GetTime (); + item->c_time = item->m_time; + item->a_time = item->m_time; + + if (fh->IsEncrypted ()) + globs->need_password = TRUE; + + /* Add item to the global list and continue with next file */ + s = g_filename_display_name ((LPCTSTR) fh->GetFileName ()); + filelist_tree_add_item (globs->files, s, item, (LPCTSTR) fh->GetFileName (), i + 1); + g_free (s); + printf ("\n"); } } - if (globs->need_password) printf("Password present.\n"); + if (globs->need_password) + printf ("Password present.\n"); - printf("\n\n\n\nPrinting the contents of the global filelist:\n\n"); - filelist_tree_print(globs->files); + printf ("\n\n\n\nPrinting the contents of the global filelist:\n\n"); + filelist_tree_print (globs->files); } @@ -245,12 +255,11 @@ VFSNew (TVFSLogFunc log_func) { struct TVFSGlobs * globs; - globs = (struct TVFSGlobs *) malloc (sizeof (struct TVFSGlobs)); - memset (globs, 0, sizeof (struct TVFSGlobs)); + globs = (struct TVFSGlobs *) g_malloc0 (sizeof (struct TVFSGlobs)); - globs->archive_opened = false; + globs->archive_opened = FALSE; globs->block_size = DEFAULT_BLOCK_SIZE; - globs->archive_modified = false; + globs->archive_modified = FALSE; globs->need_password = FALSE; globs->callback_data = NULL; @@ -259,7 +268,8 @@ VFSNew (TVFSLogFunc log_func) globs->callback_progress = NULL; globs->log_func = log_func; - if (globs->log_func != NULL) globs->log_func("zip plugin: VFSInit"); + if (globs->log_func != NULL) + globs->log_func ("zip plugin: VFSInit"); return globs; } @@ -280,19 +290,23 @@ VFSSetCallbacks (struct TVFSGlobs *globs, void VFSFree (struct TVFSGlobs *globs) { - if (globs->log_func != NULL) globs->log_func("zip plugin: VFSDestroy"); - free (globs); + if (globs->log_func != NULL) + globs->log_func ("zip plugin: VFSFree"); + g_free (globs); } -int VFSVersion() +int +VFSVersion () { return cVFSVersion; } struct TVFSInfo * -VFSGetInfo() +VFSGetInfo () { - struct TVFSInfo *module_info = (TVFSInfo*) g_malloc0 (sizeof (struct TVFSInfo)); + struct TVFSInfo *module_info; + + module_info = (TVFSInfo*) g_malloc0 (sizeof (struct TVFSInfo)); module_info->ID = g_strdup ("zip_plugin"); module_info->Name = g_strdup ("ZIP plugin"); @@ -303,7 +317,7 @@ VFSGetInfo() } char * -VFSGetArchiveExts() +VFSGetArchiveExts () { return g_strdup ("zip"); } @@ -312,110 +326,118 @@ VFSGetArchiveExts() /**************************************************************************************************************************************/ /**************************************************************************************************************************************/ -TVFSResult VFSOpenArchive(struct TVFSGlobs *globs, char *sName) +TVFSResult +VFSOpenArchive (struct TVFSGlobs *globs, const char *sName) { - // Initialize the objects + int iCount; + globs->files = NULL; - globs->vfs_filelist = vfs_filelist_new(NULL); + globs->vfs_filelist = NULL; globs->curr_dir = NULL; globs->zip = new CZipArchive; - try - { - fprintf(stderr, "(--) VFSOpenArchive: trying to open the file...\n"); + try { + fprintf (stderr, "(--) VFSOpenArchive: trying to open the file...\n"); try { - if (! globs->zip->Open(sName, CZipArchive::zipOpen, 0)) { - printf("(EE) VFSOpenArchive: error opening zip archive\n"); - return cVFS_Failed; + if (! globs->zip->Open (sName, CZipArchive::zipOpen, 0)) { + printf ("(EE) VFSOpenArchive: error opening zip archive\n"); + return cVFS_Failed; } } catch (...) { - printf("(!!) VFSOpenArchive: error opening readwrite zip, trying readonly...\n"); + printf ("(!!) VFSOpenArchive: error opening readwrite zip, trying readonly...\n"); try { - // try to open in read only mode (required if there's no write access on the media) - if (! globs->zip->Open(sName, CZipArchive::zipOpenReadOnly, 0)) { - printf("(EE) VFSOpenArchive: error opening readonly zip archive\n"); + /* try to open in read only mode (required if there's no write access on the media) */ + if (! globs->zip->Open (sName, CZipArchive::zipOpenReadOnly, 0)) { + printf ("(EE) VFSOpenArchive: error opening readonly zip archive\n"); return cVFS_Failed; } } catch (...) { - printf("(EE) VFSOpenArchive: error opening readonly zip\n"); + printf ("(EE) VFSOpenArchive: error opening readonly zip\n"); return cVFS_Failed; } } - int iCount = globs->zip->GetCount(false); - printf("(II) VFSOpenArchive: %i records found, %i files.\n", iCount, globs->zip->GetCount(true)); - if (iCount < 1) return cVFS_Failed; + iCount = globs->zip->GetCount (false); + printf ("(II) VFSOpenArchive: %i records found, %i files.\n", iCount, globs->zip->GetCount (true)); + if (iCount < 1) + return cVFS_Failed; - // Build the global file list - build_global_filelist(globs); + /* build global file list */ + build_global_filelist (globs); - // Set the progress callback + /* set progress callback */ globs->extract_callback = new CVFSZipActionCallback; globs->extract_callback->globs = globs; - globs->zip->SetCallback(globs->extract_callback, CZipActionCallback::cbExtract); - globs->zip->SetCallback(globs->extract_callback, CZipActionCallback::cbAdd); + globs->zip->SetCallback (globs->extract_callback, CZipActionCallback::cbExtract); + globs->zip->SetCallback (globs->extract_callback, CZipActionCallback::cbAdd); - // Set automatic flushing of changes to disk - globs->zip->SetAutoFlush(true); + /* set automatic flushing of changes to disk */ + globs->zip->SetAutoFlush (true); } catch (CZipException e) { printf ("(EE) VFSOpenArchive: Error while processing archive %s\n%s\n", (LPCTSTR) sName, (LPCTSTR)e.GetErrorDescription()); - if (e.m_szFileName.IsEmpty()) printf("\n"); - else printf("(EE) VFSOpenArchive: Filename in error object: %s\n\n", (LPCTSTR)e.m_szFileName); - globs->zip->Close(true); + if (e.m_szFileName.IsEmpty()) + printf ("\n"); + else + printf ("(EE) VFSOpenArchive: Filename in error object: %s\n\n", (LPCTSTR)e.m_szFileName); + globs->zip->Close (true); return cVFS_Failed; } catch (...) { printf ("(EE) VFSOpenArchive: Unknown error while processing archive %s\n\n", (LPCTSTR) sName); - globs->zip->Close(true); + globs->zip->Close (true); return cVFS_Failed; } - globs->archive_path = strdup(sName); - globs->archive_modified = false; + globs->archive_path = g_strdup (sName); + globs->archive_modified = FALSE; return cVFS_OK; } -TVFSResult VFSClose(struct TVFSGlobs *globs) +TVFSResult +VFSClose (struct TVFSGlobs *globs) { if (globs) { - // Closing the archive... - fprintf(stderr, "(II) VFSClose: Closing the archive...\n"); - try { - if (globs->archive_modified) globs->zip->Flush(); - globs->zip->Close(CZipArchive::afNoException, false); - //*** In case of inconsistency, try using afWriteDir value - // (Use when an exception was thrown. The Close method writes the - // central directory structure to the archive, so that the archive should be usable.) - } - catch (CZipException e) { - fprintf(stderr, "(EE) VFSClose: Error while closing archive: %s\n", (LPCTSTR)e.GetErrorDescription()); - return cVFS_Failed; - } - - - // Freeing the ZIP objects... - fprintf(stderr, "(II) VFSClose: Freeing ZipArchive objects...\n"); - try { - delete globs->extract_callback; - delete globs->zip; - } - catch (...) { - fprintf(stderr, "(EE) VFSClose: Error freeing ZipArchive objects\n"); - return cVFS_Failed; - } - - // Freeing the filelist - fprintf(stderr, "(II) VFSClose: Freeing filelist...\n"); - if (globs->vfs_filelist) vfs_filelist_free(globs->vfs_filelist); - if (globs->files) filelist_tree_free(globs->files); - - // Free the rest... - free(globs->archive_path); + /* close the archive... */ + fprintf (stderr, "(II) VFSClose: Closing the archive...\n"); + try { + if (globs->archive_modified) + globs->zip->Flush (); + /* In case of inconsistency, try using afWriteDir value. + * (use when an exception was thrown, yhe Close method writes the + * central directory structure to the archive, so that the archive should be usable.) + */ + globs->zip->Close (CZipArchive::afNoException, false); + } + catch (CZipException e) { + fprintf (stderr, "(EE) VFSClose: Error while closing archive: %s\n", (LPCTSTR)e.GetErrorDescription()); + return cVFS_Failed; + } + + /* free the ZIP objects... */ + fprintf (stderr, "(II) VFSClose: Freeing ZipArchive objects...\n"); + try { + delete globs->extract_callback; + delete globs->zip; + } + catch (...) { + fprintf (stderr, "(EE) VFSClose: Error freeing ZipArchive objects\n"); + return cVFS_Failed; + } + + /* free the filelist */ + fprintf (stderr, "(II) VFSClose: Freeing filelist...\n"); + if (globs->vfs_filelist) + vfs_filelist_free (globs->vfs_filelist); + if (globs->files) + filelist_tree_free (globs->files); + + /* free the rest... */ + g_free (globs->archive_path); } return cVFS_OK; } @@ -426,115 +448,108 @@ VFSGetPath (struct TVFSGlobs *globs) return g_strdup (globs->curr_dir); } -u_int64_t VFSGetFileSystemFree(struct TVFSGlobs *globs, char *APath) +TVFSResult +VFSGetFileSystemInfo (struct TVFSGlobs *globs, const char *APath, gint64 *FSSize, gint64 *FSFree, char **FSLabel) { - return 0; -} - -u_int64_t VFSGetFileSystemSize(struct TVFSGlobs *globs, char *APath) -{ - return globs->zip->GetOccupiedSpace(); + if (FSSize) + *FSSize = globs->zip->GetOccupiedSpace (); + if (FSFree) + *FSFree = 0; + if (FSLabel) + *FSLabel = NULL; + return cVFS_OK; } - - /******************************************************************************************************/ -TVFSResult VFSChangeDir(struct TVFSGlobs *globs, char *NewPath) +TVFSResult +VFSChangeDir (struct TVFSGlobs *globs, const char *NewPath) { if (NewPath == NULL) { - printf("(EE) VFSChangeDir: NewPath is NULL!\n"); + printf ("(EE) VFSChangeDir: NewPath is NULL!\n"); return cVFS_Failed; } - globs->curr_dir = vfs_filelist_change_dir(globs->vfs_filelist, NewPath); - if (globs->curr_dir) return cVFS_OK; - else return cVFS_Failed; -} - -/* -int VFSSetPassword(struct TVFSGlobs *globs, char *pass) -{ - printf ("(II) VFSSetPassword: Going to set the password...\n"); - try { - globs->zip->SetPassword(pass); - } - catch (...) - { - printf ("(EE) VFSSetPassword: Changing password failed. Maybe closed archive ?\n"); + globs->curr_dir = vfs_filelist_change_dir (globs->vfs_filelist, NewPath); + if (globs->curr_dir) + return cVFS_OK; + else return cVFS_Failed; - } - return cVFS_OK; } -*/ -int VFSGetPasswordRequired(struct TVFSGlobs *globs) +gboolean +VFSGetPasswordRequired (struct TVFSGlobs *globs) { - if (globs) return globs->need_password; + if (globs) + return globs->need_password; return FALSE; } void -VFSResetPassword(struct TVFSGlobs *globs) +VFSResetPassword (struct TVFSGlobs *globs) { if (globs) - globs->zip->SetPassword(NULL); + globs->zip->SetPassword (NULL); } /******************************************************************************************************/ -TVFSResult VFSListFirst(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) +TVFSResult +VFSListFirst (struct TVFSGlobs *globs, const char *sDir, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath) { if (sDir == NULL) { - printf("(EE) VFSListFirst: sDir is NULL!\n"); + 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); + + return vfs_filelist_list_first (globs->vfs_filelist, sDir, Item, FollowSymlinks, AddFullPath); } -TVFSResult VFSListNext(struct TVFSGlobs *globs, char *sDir, struct TVFSItem *Item) +TVFSResult +VFSListNext (struct TVFSGlobs *globs, struct TVFSItem *Item) { - return vfs_filelist_list_next(globs->vfs_filelist, sDir, Item); + return vfs_filelist_list_next (globs->vfs_filelist, Item); } -TVFSResult VFSListClose(struct TVFSGlobs *globs) +TVFSResult +VFSListClose (struct TVFSGlobs *globs) { - return vfs_filelist_list_close(globs->vfs_filelist); + return vfs_filelist_list_close (globs->vfs_filelist); } /******************************************************************************************************/ -long VFSFileExists(struct TVFSGlobs *globs, const char *FileName, const long Use_lstat) -{ - if (! globs) return FALSE; - return vfs_filelist_file_exists(globs->vfs_filelist, FileName, Use_lstat); -} -TVFSResult VFSFileInfo(struct TVFSGlobs *globs, char *AFileName, struct TVFSItem *Item) +TVFSResult +VFSFileInfo (struct TVFSGlobs *globs, const char *AFileName, struct TVFSItem *Item, gboolean FollowSymlinks, gboolean AddFullPath) { - printf("(--) VFSFileInfo: requested info for object '%s'\n", AFileName); - if (!globs) return cVFS_Failed; - return vfs_filelist_file_info(globs->vfs_filelist, AFileName, Item); + 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); } /******************************************************************************************************/ /** Recursive tree size counting */ /************** ****************/ -u_int64_t VFSGetDirSize(struct TVFSGlobs *globs, char *APath) +guint64 +VFSGetDirSize (struct TVFSGlobs *globs, const char *APath) { - if (! globs) return 0; - return vfs_filelist_get_dir_size(globs->vfs_filelist, APath); + if (! globs) + return 0; + return vfs_filelist_get_dir_size (globs->vfs_filelist, APath); } -void VFSBreakGetDirSize(struct TVFSGlobs *globs) +void +VFSBreakGetDirSize (struct TVFSGlobs *globs) { - printf("(WW) VFSBreakGetDirSize: calling break\n"); - if (globs) vfs_filelist_get_dir_size_break(globs->vfs_filelist); + printf ("(WW) VFSBreakGetDirSize: calling break\n"); + if (globs) + vfs_filelist_get_dir_size_break (globs->vfs_filelist); } @@ -542,133 +557,153 @@ void VFSBreakGetDirSize(struct TVFSGlobs *globs) /** Methods modifying the archive */ /************** ****************/ -TVFSResult VFSMkDir(struct TVFSGlobs *globs, const char *sDirName) +TVFSResult +VFSMkDir (struct TVFSGlobs *globs, const char *sDirName) { - if ((sDirName == NULL) || (strlen(sDirName) < 1)) { - printf("(EE) VFSMkDir: The value of 'sDirName' is NULL or empty\n"); - return cVFS_Failed; + CZipFileHeader header; + char *s; + bool bRet; + + if (sDirName == NULL || strlen (sDirName) < 1) { + printf ("(EE) VFSMkDir: The value of 'sDirName' is NULL or empty\n"); + return cVFS_Failed; } - if ((strlen(sDirName) < 1) || (strcmp(sDirName, "/") == 0)) { - printf("(EE) VFSMkDir: Invalid value '%s' (duplicate root entry?)\n", sDirName); + if (strcmp (sDirName, "/") == 0) { + printf ("(EE) VFSMkDir: Invalid value '%s' (duplicate root entry?)\n", sDirName); return cVFS_Failed; } printf ("(II) VFSMkDir: Going to create new directory '%s'...\n", sDirName); try { - try { - CZipFileHeader header; -// globs->zip->SetFileHeaderAttr(header, 0x41ED0010); // alternatively use ZipPlatform::GetDefaultAttributes(); - globs->zip->SetFileHeaderAttr(header, 0x41ED); // alternatively use ZipPlatform::GetDefaultAttributes(); - char *s = exclude_leading_path_sep(sDirName); + try { +// globs->zip->SetFileHeaderAttr (header, 0x41ED0010); + globs->zip->SetFileHeaderAttr (header, 0x41ED); /* alternatively use ZipPlatform::GetDefaultAttributes(); */ + s = exclude_leading_path_sep (sDirName); header.SetFileName(s); - free(s); - header.SetTime(time(NULL)); - bool bRet = globs->zip->OpenNewFile(header, 0, NULL); - globs->zip->CloseNewFile(); + g_free (s); + header.SetTime (time (NULL)); + bRet = globs->zip->OpenNewFile (header, 0, NULL); + globs->zip->CloseNewFile (); if (! bRet) { - printf("(EE) VFSMkDir: Error creating new directory '%s'\n", sDirName); + printf ("(EE) VFSMkDir: Error creating new directory '%s'\n", sDirName); return cVFS_Failed; } - globs->archive_modified = true; - build_global_filelist(globs); + globs->archive_modified = TRUE; + build_global_filelist (globs); return cVFS_OK; - } + } catch (CZipException e) { - globs->zip->CloseNewFile(true); - fprintf(stderr, "(EE) VFSMkDir: Error creating new directory '%s': [%d] %s, archive closed = %d.\n", - sDirName, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); - return get_vfs_errorcode(e.m_iCause); + globs->zip->CloseNewFile (true); + fprintf (stderr, "(EE) VFSMkDir: Error creating new directory '%s': [%d] %s, archive closed = %d.\n", + sDirName, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed ()); + return get_vfs_errorcode (e.m_iCause); } } catch (...) { - printf("(EE) VFSMkDir: Error creating new directory '%s'\n", sDirName); + printf ("(EE) VFSMkDir: Error creating new directory '%s'\n", sDirName); return cVFS_Failed; } } -TVFSResult VFSRemove(struct TVFSGlobs *globs, const char *APath) + +TVFSResult +VFSRemove (struct TVFSGlobs *globs, const char *APath) { - printf("(II) VFSRemove: Going to remove the file '%s'...\n", APath); + char *AFile, *AFile1, *AFile2, *AFile3; + unsigned long int file_no; + + + printf ("(II) VFSRemove: Going to remove the file '%s'...\n", APath); - char *AFile = exclude_trailing_path_sep(APath); - unsigned long int file_no = filelist_find_index_by_path(globs->files, AFile) - 1; - free(AFile); + AFile = exclude_trailing_path_sep (APath); + file_no = filelist_find_original_index_by_path (globs->files, AFile) - 1; + g_free (AFile); if (file_no < 0) { - printf("(EE) VFSRemove: can't find the file specified: '%s'\n", APath); + printf ("(EE) VFSRemove: can't find the file specified: '%s'\n", APath); return cVFS_Failed; } try { try { - if (! globs->zip->RemoveFile(file_no)) { - printf("(EE) VFSRemove: Delete file '%s' failed.\n", APath); + if (! globs->zip->RemoveFile (file_no)) { + printf ("(EE) VFSRemove: Delete file '%s' failed.\n", APath); return cVFS_Failed; } - build_global_filelist(globs); - globs->archive_modified = true; - printf("(II) VFSRemove OK.\n"); + build_global_filelist (globs); + globs->archive_modified = TRUE; + printf ("(II) VFSRemove OK.\n"); - // Test for the sparse ZIP central directory - char *AFile1 = exclude_trailing_path_sep(APath); - char *AFile2 = g_path_get_dirname(AFile1); - char *AFile3 = exclude_trailing_path_sep(AFile2); - if ((strlen(AFile3) > 0) && (strcmp(AFile3, "/") != 0)) { - printf("(II) VFSRemove: AFile1: '%s', AFile2: '%s', AFile3: '%s'\n", AFile1, AFile2, AFile3); - file_no = filelist_find_index_by_path(globs->files, AFile2) - 1; - printf("(II) VFSRemove: deleted: '%s', parent: '%s', file_no = %ld\n", APath, AFile3, file_no); + /* If we delete last file from a directory, we should make an empty one. + * Some archives store pathnames only with filenames, no separate records for directories. + **/ + AFile1 = exclude_trailing_path_sep (APath); + AFile2 = g_path_get_dirname (AFile1); + AFile3 = exclude_trailing_path_sep (AFile2); + if (strlen (AFile3) > 0 && g_strcmp0 (AFile3, "/") != 0) { + printf ("(II) VFSRemove: AFile1: '%s', AFile2: '%s', AFile3: '%s'\n", AFile1, AFile2, AFile3); + file_no = filelist_find_original_index_by_path (globs->files, AFile2) - 1; + printf ("(II) VFSRemove: deleted: '%s', parent: '%s', file_no = %ld\n", APath, AFile3, file_no); if (file_no < 0) { - printf("(WW) VFSRemove: sparse ZIP archive detected, adding empty directory: '%s'\n", AFile3); - VFSMkDir(globs, AFile3); + printf ("(WW) VFSRemove: sparse ZIP archive detected, adding empty directory: '%s'\n", AFile3); + VFSMkDir (globs, AFile3); } } - free(AFile1); free(AFile2); free(AFile3); + g_free (AFile1); + g_free (AFile2); + g_free (AFile3); return cVFS_OK; } catch (CZipException e) { - fprintf(stderr, "(EE) VFSRemove: Delete file '%s' failed: [%d] %s, archive closed = %d.\n", - APath, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); - return get_vfs_errorcode(e.m_iCause); + fprintf (stderr, "(EE) VFSRemove: Delete file '%s' failed: [%d] %s, archive closed = %d.\n", + APath, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed ()); + return get_vfs_errorcode (e.m_iCause); } } catch (...) { - printf("(EE) VFSRemove: Delete file '%s' failed.\n", APath); + printf ("(EE) VFSRemove: Delete file '%s' failed.\n", APath); return cVFS_Failed; } } -TVFSResult VFSRename(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName) + +TVFSResult +VFSRename (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName) { + char *AFile; + char *ADestFile; + unsigned long int file_no; + printf ("(II) VFSRename: Going to rename/move the file '%s' to '%s'...\n", sSrcName, sDstName); - char *AFile = exclude_trailing_path_sep(sSrcName); - char *ADestFile = exclude_trailing_path_sep(sDstName); - unsigned long int file_no = filelist_find_index_by_path(globs->files, AFile) - 1; - free(AFile); + AFile = exclude_trailing_path_sep (sSrcName); + ADestFile = exclude_trailing_path_sep (sDstName); + file_no = filelist_find_original_index_by_path (globs->files, AFile) - 1; + g_free (AFile); if (file_no < 0) { - printf("(EE) VFSRename: can't find the file specified: '%s'\n", sSrcName); + printf ("(EE) VFSRename: can't find the file specified: '%s'\n", sSrcName); return cVFS_Failed; } try { try { - if (! globs->zip->RenameFile(file_no, ADestFile)) { + if (! globs->zip->RenameFile (file_no, ADestFile)) { printf ("(EE) VFSRename: Rename/move file '%s' failed.\n", sSrcName); return cVFS_Failed; } - free(ADestFile); - build_global_filelist(globs); - globs->archive_modified = true; + g_free (ADestFile); + build_global_filelist (globs); + globs->archive_modified = TRUE; return cVFS_OK; } catch (CZipException e) { - fprintf(stderr, "(EE) VFSRename: Rename/move file '%s' failed: [%d] %s, archive closed = %d.\n", - sSrcName, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); - return get_vfs_errorcode(e.m_iCause); + fprintf (stderr, "(EE) VFSRename: Rename/move file '%s' failed: [%d] %s, archive closed = %d.\n", + sSrcName, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed ()); + return get_vfs_errorcode (e.m_iCause); } } catch (...) @@ -678,37 +713,45 @@ TVFSResult VFSRename(struct TVFSGlobs *globs, const char *sSrcName, const char * } } -TVFSResult VFSMakeSymLink(struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo) + +TVFSResult +VFSMakeSymLink (struct TVFSGlobs *globs, const char *NewFileName, const char *PointTo) { - fprintf(stderr, "(EE) VFSMakeSymLink: Symbolic links not supported in ZIP archives.\n"); + fprintf (stderr, "(EE) VFSMakeSymLink: Symbolic links not supported in ZIP archives.\n"); return cVFS_Not_Supported; } -TVFSResult VFSChmod(struct TVFSGlobs *globs, const char *FileName, const uint Mode) + +TVFSResult +VFSChmod (struct TVFSGlobs *globs, const char *FileName, guint32 Mode) { - printf("(II) VFSChmod: Going to change permissions of the file '%s'...\n", FileName); + char *AFile; + unsigned long int file_no; + CZipFileHeader *header; + + printf ("(II) VFSChmod: Going to change permissions of the file '%s'...\n", FileName); - char *AFile = exclude_trailing_path_sep(FileName); - unsigned long int file_no = filelist_find_index_by_path(globs->files, AFile) - 1; - free(AFile); + AFile = exclude_trailing_path_sep (FileName); + file_no = filelist_find_original_index_by_path (globs->files, AFile) - 1; + g_free (AFile); if (file_no < 0) { - printf("(EE) VFSChmod: can't find the file specified: '%s'\n", FileName); + printf ("(EE) VFSChmod: can't find the file specified: '%s'\n", FileName); return cVFS_Failed; } try { try { - // Set system compatibility first - if (! globs->zip->SetSystemCompatibility(ZipCompatibility::zcUnix)) { - printf("(EE) VFSChmod: Unable to set system compatibility\n"); + /* set system compatibility first */ + if (! globs->zip->SetSystemCompatibility (ZipCompatibility::zcUnix)) { + printf ("(EE) VFSChmod: Unable to set system compatibility\n"); } - // Change the header data - globs->zip->ReadLocalHeader(file_no); - CZipFileHeader *header = globs->zip->GetFileInfo(file_no); + /* change the header data */ + globs->zip->ReadLocalHeader (file_no); + header = globs->zip->GetFileInfo (file_no); if (! header) { - printf("(EE) VFSChmod: Permissions modification of the file '%s' failed: NULL returned by GetFileInfo()\n", FileName); + printf ("(EE) VFSChmod: Permissions modification of the file '%s' failed: NULL returned by GetFileInfo()\n", FileName); return cVFS_Failed; } // We need to change only 0xF000FFFF mask @@ -718,75 +761,82 @@ TVFSResult VFSChmod(struct TVFSGlobs *globs, const char *FileName, const uint Mo // header->GetSystemAttr(), header->GetSystemAttr() & 0xF000FFFF, Mode & 0xFFF, (header->GetSystemAttr() & 0xF000FFFF) + ((Mode & 0xFFF) << 16)); // globs->zip->SetFileHeaderAttr(*header, (header->GetSystemAttr() & 0xF000FFFF) + ((Mode & 0xFFF) << 16)); - printf("(II) VFSChmod: Current permissions: 0x%lX, stripped: 0x%lX, setting to: 0x%X, modified: 0x%lX\n", + printf ("(II) VFSChmod: Current permissions: 0x%lX, stripped: 0x%lX, setting to: 0x%X, modified: 0x%lX\n", header->GetSystemAttr(), header->GetSystemAttr() & 0xFFFFF000, Mode & 0xFFF, (header->GetSystemAttr() & 0xFFFFF000) + (Mode & 0xFFF)); - globs->zip->SetFileHeaderAttr(*header, (header->GetSystemAttr() & 0xFFFFF000) + (Mode & 0xFFF)); + globs->zip->SetFileHeaderAttr (*header, (header->GetSystemAttr() & 0xFFFFF000) + (Mode & 0xFFF)); - // write the local header information - globs->zip->OverwriteLocalHeader(file_no); + /* write local header information */ + globs->zip->OverwriteLocalHeader (file_no); -/* +#if 0 // Re-encrypt the file if (header->IsEncrypted()) { printf("(II) VFSChmod: Re-encrypting the file...\n"); if (! globs->zip->EncryptFile(file_no)) printf("(EE) VFSChmod: Unable to encrypt the file\n"); } -*/ - globs->zip->RemoveCentralDirectoryFromArchive(); - globs->zip->Flush(); +#endif + globs->zip->RemoveCentralDirectoryFromArchive (); + globs->zip->Flush (); - - printf("(II) VFSChmod OK.\n"); - build_global_filelist(globs); - globs->archive_modified = true; + printf ("(II) VFSChmod OK.\n"); + build_global_filelist (globs); + globs->archive_modified = TRUE; return cVFS_OK; } catch (CZipException e) { - globs->zip->CloseNewFile(true); - fprintf(stderr, "(EE) VFSChmod: permissions modification of the file '%s' failed: [%d] %s, archive closed = %d.\n", + globs->zip->CloseNewFile (true); + fprintf (stderr, "(EE) VFSChmod: permissions modification of the file '%s' failed: [%d] %s, archive closed = %d.\n", FileName, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); - return get_vfs_errorcode(e.m_iCause); + return get_vfs_errorcode (e.m_iCause); } } catch (...) { - printf("(EE) VFSChmod: permissions modification of the file '%s' failed.\n", FileName); + printf ("(EE) VFSChmod: permissions modification of the file '%s' failed.\n", FileName); return cVFS_Failed; } } -TVFSResult VFSChown(struct TVFSGlobs *globs, const char *FileName, const uint UID, const uint GID) + +TVFSResult +VFSChown (struct TVFSGlobs *globs, const char *FileName, guint32 UID, guint32 GID) { - fprintf(stderr, "(EE) VFSChown: Owner changing is not supported in ZIP archives.\n"); + fprintf (stderr, "(EE) VFSChown: Owner changing is not supported in ZIP archives.\n"); return cVFS_Not_Supported; } -TVFSResult VFSChangeTimes(struct TVFSGlobs *globs, char *APath, long mtime, long atime) + +TVFSResult +VFSChangeTimes (struct TVFSGlobs *globs, const char *APath, guint32 mtime, guint32 atime) { + char *AFile; + unsigned long int file_no; + CZipFileHeader *header; + printf ("(II) VFSChangeTimes: Going to change date/times of the file '%s'...\n", APath); - char *AFile = exclude_trailing_path_sep(APath); - unsigned long int file_no = filelist_find_index_by_path(globs->files, AFile) - 1; - free(AFile); + AFile = exclude_trailing_path_sep (APath); + file_no = filelist_find_original_index_by_path (globs->files, AFile) - 1; + g_free (AFile); if (file_no < 0) { - printf("(EE) VFSChangeTimes: can't find the file specified: '%s'\n", APath); + printf ("(EE) VFSChangeTimes: can't find the file specified: '%s'\n", APath); return cVFS_Failed; } try { try { - // read the local header information - globs->zip->ReadLocalHeader(file_no); - CZipFileHeader *header = globs->zip->GetFileInfo(file_no); + /* read the local header information */ + globs->zip->ReadLocalHeader (file_no); + header = globs->zip->GetFileInfo (file_no); if (! header) { - printf("(EE) VFSChangeTimes: DateTime modification of the file '%s' failed: NULL returned by GetFileInfo()\n", APath); + printf ("(EE) VFSChangeTimes: DateTime modification of the file '%s' failed: NULL returned by GetFileInfo()\n", APath); return cVFS_Failed; } - // Change the header data - header->SetTime(mtime); + /* change the header data */ + header->SetTime (mtime); /* // Re-encrypt the file if (header->IsEncrypted()) { @@ -795,25 +845,24 @@ TVFSResult VFSChangeTimes(struct TVFSGlobs *globs, char *APath, long mtime, long printf("(EE) VFSChangeTimes: Unable to encrypt the file\n"); } */ - // write the local header information - globs->zip->OverwriteLocalHeader(file_no); - globs->zip->RemoveCentralDirectoryFromArchive(); + /* write local header information */ + globs->zip->OverwriteLocalHeader (file_no); + globs->zip->RemoveCentralDirectoryFromArchive (); - printf("(II) VFSChangeTimes OK.\n"); - build_global_filelist(globs); - globs->archive_modified = true; + printf ("(II) VFSChangeTimes OK.\n"); + build_global_filelist (globs); + globs->archive_modified = TRUE; return cVFS_OK; } catch (CZipException e) { - globs->zip->CloseNewFile(true); - fprintf(stderr, "(EE) VFSChangeTimes: DateTime modification of the file '%s' failed: [%d] %s, archive closed = %d.\n", - APath, e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); - return get_vfs_errorcode(e.m_iCause); + globs->zip->CloseNewFile (true); + fprintf (stderr, "(EE) VFSChangeTimes: DateTime modification of the file '%s' failed: [%d] %s, archive closed = %d.\n", + APath, e.m_iCause, (LPCTSTR)e.GetErrorDescription (), globs->zip->IsClosed ()); + return get_vfs_errorcode (e.m_iCause); } } - catch (...) - { - printf("(EE) VFSChangeTimes: DateTime modification of the file '%s' failed.\n", APath); + catch (...) { + printf ("(EE) VFSChangeTimes: DateTime modification of the file '%s' failed.\n", APath); return cVFS_Failed; } } @@ -852,21 +901,25 @@ int VFSWriteFile(struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, void *Buff return 0; } -void VFSSetBlockSize(struct TVFSGlobs *globs, int Value) +void +VFSSetBlockSize (struct TVFSGlobs *globs, guint32 Value) { - globs->block_size = Value; + if (globs) + globs->block_size = Value; } -int VFSIsOnSameFS(struct TVFSGlobs *globs, const char *Path1, const char *Path2) +gboolean +VFSIsOnSameFS (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks) { - printf("(II) VFSIsOnSameFS: Not supported in ZIP archives.\n"); - return true; + printf ("(II) VFSIsOnSameFS: Not supported in ZIP archives.\n"); + return TRUE; } -int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path2) +gboolean +VFSTwoSameFiles (struct TVFSGlobs *globs, const char *Path1, const char *Path2, gboolean FollowSymlinks) { - printf("(II) VFSTwoSameFiles: Not supported in ZIP archives, comparing by paths.\n"); - return compare_two_same_files(Path1, Path2); + printf ("(II) VFSTwoSameFiles: Not supported in ZIP archives, comparing by paths.\n"); + return compare_two_same_files (Path1, Path2); } @@ -874,108 +927,127 @@ int VFSTwoSameFiles(struct TVFSGlobs *globs, const char *Path1, const char *Path //////////////////////// -// Known issues: - crashes when no space left on NFS mounts, probably unhandled exception in further ZipArchive code (repro: Gentoo, Ubuntu) -TVFSResult VFSCopyToLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append) +/* Known issues: + * - crashes when no space left on NFS mounts, probably unhandled exception in further ZipArchive code (repro: Gentoo, Ubuntu) + * + **/ +TVFSResult +VFSCopyToLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append) { gboolean try_again; + unsigned long int file_no; + char *s; + char *dest_path; + char *dest_filename; + char *passwd; + int res; + - 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"); + 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; } - printf("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName); + printf ("(II) VFSCopyToLocal: copying file '%s' out to '%s'\n", sSrcName, sDstName); - unsigned long int file_no = filelist_find_index_by_path(globs->files, sSrcName) - 1; + file_no = filelist_find_original_index_by_path (globs->files, sSrcName) - 1; if (file_no < 0) { - printf("(EE) VFSCopyToLocal: can't find source file '%s'\n", sSrcName); + printf ("(EE) VFSCopyToLocal: can't find source file '%s'\n", sSrcName); return cVFS_ReadErr; } - char *s = exclude_trailing_path_sep(sDstName); - char *dest_path = extract_file_path(s); - char *dest_filename = extract_file_name(s); - free(s); + s = exclude_trailing_path_sep (sDstName); + dest_path = g_path_get_dirname (s); + dest_filename = g_path_get_basename (s); + g_free (s); - // Perform extract + /* Perform extract */ try { do { try { try_again = FALSE; - if (! globs->zip->ExtractFile(file_no, dest_path, false, dest_filename, globs->block_size)) { - globs->zip->CloseFile(NULL, true); - fprintf(stderr, "(EE) VFSCopyToLocal: Error while copying out, archive closed = %d.\n", globs->zip->IsClosed()); + if (! globs->zip->ExtractFile (file_no, dest_path, false, dest_filename, globs->block_size)) { + globs->zip->CloseFile (NULL, true); + fprintf (stderr, "(EE) VFSCopyToLocal: Error while copying out, archive closed = %d.\n", globs->zip->IsClosed ()); return cVFS_WriteErr; } - fprintf(stderr, "(II) VFSCopyToLocal: copy OK, archive closed = %d.\n", globs->zip->IsClosed()); + fprintf (stderr, "(II) VFSCopyToLocal: copy OK, archive closed = %d.\n", globs->zip->IsClosed ()); } catch (CZipException e) { - globs->zip->CloseFile(NULL, true); - fprintf(stderr, "(EE) VFSCopyToLocal: Error while copying out: [%d] %s, archive closed = %d.\n", - e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); + globs->zip->CloseFile (NULL, true); + fprintf (stderr, "(EE) VFSCopyToLocal: Error while copying out: [%d] %s, archive closed = %d.\n", + e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); switch (e.m_iCause) { case CZipException::badPassword: if (globs->callback_ask_password) { - char *passwd = NULL; - int res = globs->callback_ask_password ("The archive is encrypted and requires password", - NULL, NULL, NULL, (TVFSAskPasswordFlags)(VFS_ASK_PASSWORD_NEED_PASSWORD | VFS_ASK_PASSWORD_ARCHIVE_MODE), - NULL, &passwd, NULL, NULL, NULL, - globs->callback_data); + passwd = NULL; + res = globs->callback_ask_password ("The archive is encrypted and requires password", + NULL, NULL, NULL, (TVFSAskPasswordFlags)(VFS_ASK_PASSWORD_NEED_PASSWORD | VFS_ASK_PASSWORD_ARCHIVE_MODE), + NULL, &passwd, NULL, NULL, NULL, + globs->callback_data); if (res && passwd) { - fprintf(stderr, " (II) VFSCopyToLocal: setting password to '%s'\n", passwd); - globs->zip->SetPassword(passwd); + fprintf (stderr, " (II) VFSCopyToLocal: setting password to '%s'\n", passwd); + globs->zip->SetPassword (passwd); try_again = TRUE; break; } else return cVFS_Cancelled; } default: - return get_vfs_errorcode(e.m_iCause); + return get_vfs_errorcode (e.m_iCause); } } } while (try_again); } catch (...) { - fprintf(stderr, "(EE) VFSCopyToLocal: Fatal error while copying out..., archive closed = %d.\n", globs->zip->IsClosed()); + fprintf (stderr, "(EE) VFSCopyToLocal: Fatal error while copying out..., archive closed = %d.\n", globs->zip->IsClosed()); return cVFS_WriteErr; } + g_free (dest_path); + g_free (dest_filename); - free(dest_path); - free(dest_filename); return cVFS_OK; } -// Known issues: - archive corruption when no space left on device -// - encrypted files are unreadable after copy in -TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, int Append) + +/* Known issues: + * - archive corruption when no space left on device + * - encrypted files are unreadable after copy in + * + **/ +TVFSResult +VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDstName, gboolean Append) { gboolean try_again; + char *s; + char *passwd; + int res; - if ((sSrcName == NULL) || (sDstName == NULL) || (strlen(sSrcName) < 1) || (strlen(sDstName) < 1)) { - printf("(EE) VFSCopyFromLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty\n"); + if (sSrcName == NULL || sDstName == NULL || strlen (sSrcName) < 1 || strlen (sDstName) < 1) { + printf ("(EE) VFSCopyFromLocal: The value of 'sSrcName' or 'sDstName' is NULL or empty\n"); return cVFS_Failed; } - printf("(II) VFSCopyFromLocal: copying file '%s' in to '%s'\n", sSrcName, sDstName); + printf ("(II) VFSCopyFromLocal: copying file '%s' in to '%s'\n", sSrcName, sDstName); try { do { try { try_again = FALSE; - char *s = exclude_leading_path_sep(sDstName); - if (! globs->zip->AddNewFile(sSrcName, s, -1, CZipArchive::zipsmSafeSmart, globs->block_size)) { - globs->zip->CloseNewFile(true); - globs->zip->CloseFile(NULL, true); - build_global_filelist(globs); - fprintf(stderr, "(EE) VFSCopyFromLocal: Error while copying in, archive closed = %d.\n", globs->zip->IsClosed()); + s = exclude_leading_path_sep (sDstName); + if (! globs->zip->AddNewFile (sSrcName, s, -1, CZipArchive::zipsmSafeSmart, globs->block_size)) { + globs->zip->CloseNewFile (true); + globs->zip->CloseFile (NULL, true); + build_global_filelist (globs); + fprintf (stderr, "(EE) VFSCopyFromLocal: Error while copying in, archive closed = %d.\n", globs->zip->IsClosed ()); return cVFS_WriteErr; } - globs->zip->Flush(); - printf("(II) VFSCopyFromLocal: copy OK, archive closed = %d.\n", globs->zip->IsClosed()); - build_global_filelist(globs); - globs->archive_modified = true; + globs->zip->Flush (); + printf ("(II) VFSCopyFromLocal: copy OK, archive closed = %d.\n", globs->zip->IsClosed ()); + build_global_filelist (globs); + globs->archive_modified = TRUE; /* // Encrypt the file if archive contains any encrypted files @@ -991,39 +1063,38 @@ TVFSResult VFSCopyFromLocal(struct TVFSGlobs *globs, const char *sSrcName, const } */ - free(s); + g_free (s); } catch (CZipException e) { - globs->zip->CloseNewFile(true); - globs->zip->CloseFile(NULL, true); - build_global_filelist(globs); - fprintf(stderr, "(EE) VFSCopyFromLocal: Error while copying in: [%d] %s, archive closed = %d.\n", - e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); + globs->zip->CloseNewFile (true); + globs->zip->CloseFile (NULL, true); + build_global_filelist (globs); + fprintf (stderr, "(EE) VFSCopyFromLocal: Error while copying in: [%d] %s, archive closed = %d.\n", + e.m_iCause, (LPCTSTR)e.GetErrorDescription(), globs->zip->IsClosed()); switch (e.m_iCause) { case CZipException::badPassword: if (globs->callback_ask_password) { - char *passwd = NULL; - int res = globs->callback_ask_password ("The archive is encrypted and requires password", - NULL, NULL, NULL, (TVFSAskPasswordFlags)(VFS_ASK_PASSWORD_NEED_PASSWORD | VFS_ASK_PASSWORD_ARCHIVE_MODE), - NULL, &passwd, NULL, NULL, NULL, - globs->callback_data); + passwd = NULL; + res = globs->callback_ask_password ("The archive is encrypted and requires password", + NULL, NULL, NULL, (TVFSAskPasswordFlags)(VFS_ASK_PASSWORD_NEED_PASSWORD | VFS_ASK_PASSWORD_ARCHIVE_MODE), + NULL, &passwd, NULL, NULL, NULL, + globs->callback_data); if (res && passwd) { - fprintf(stderr, " (II) VFSCopyFromLocal: setting password to '%s'\n", passwd); - globs->zip->SetPassword(passwd); + fprintf (stderr, " (II) VFSCopyFromLocal: setting password to '%s'\n", passwd); + globs->zip->SetPassword (passwd); try_again = TRUE; break; } else return cVFS_Cancelled; } default: - return get_vfs_errorcode(e.m_iCause); + return get_vfs_errorcode (e.m_iCause); } } } while (try_again); } - catch (...) - { - fprintf(stderr, "(EE) VFSCopyFromLocal: Fatal error while copying in..., archive closed = %d.\n", globs->zip->IsClosed()); + catch (...) { + fprintf (stderr, "(EE) VFSCopyFromLocal: Fatal error while copying in..., archive closed = %d.\n", globs->zip->IsClosed()); return cVFS_WriteErr; } |
