I'm attaching a patch I wrote some days ago to get an idea what's going in the Xfer machinery. It might also have some educational value for others. -- Christian Neumair <chris gnome-de org>
Index: programs/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-vfs/programs/Makefile.am,v
retrieving revision 1.4
diff -u -p -r1.4 Makefile.am
--- programs/Makefile.am 11 Apr 2005 13:52:31 -0000 1.4
+++ programs/Makefile.am 11 Jan 2006 18:00:16 -0000
@@ -48,3 +48,4 @@ gnomevfs_mv_LDADD = $(libraries)
gnomevfs_rm_SOURCES = gnomevfs-rm.c
gnomevfs_rm_LDADD = $(libraries)
+EXTRA_DIST = file-transfer-helper.c
Index: programs/file-transfer-helper.c
===================================================================
RCS file: programs/file-transfer-helper.c
diff -N programs/file-transfer-helper.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ programs/file-transfer-helper.c 11 Jan 2006 18:00:16 -0000
@@ -0,0 +1,168 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* file-transfer-helper.c - Mostly debugging-related helpers for gnomevfs-mv
+ * and gnomevfs-copy.
+
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Christian Neumair <chris gnome-de org>
+*/
+
+typedef enum {
+ NADA = 0,
+ VERBOSE,
+ VERY_VERBOSE
+} VerbosityLevel;
+
+/* FIXME may belong into GnomeVFS */
+static char *
+phase_to_str (GnomeVFSXferPhase phase)
+{
+ switch (phase) {
+ case GNOME_VFS_XFER_PHASE_INITIAL:
+ return "initial";
+ case GNOME_VFS_XFER_CHECKING_DESTINATION:
+ return "checking destination";
+ case GNOME_VFS_XFER_PHASE_COLLECTING:
+ return "collecting";
+ case GNOME_VFS_XFER_PHASE_READYTOGO:
+ return "ready to go";
+ case GNOME_VFS_XFER_PHASE_OPENSOURCE:
+ return "open source";
+ case GNOME_VFS_XFER_PHASE_OPENTARGET:
+ return "open target";
+ case GNOME_VFS_XFER_PHASE_COPYING:
+ return "copying";
+ case GNOME_VFS_XFER_PHASE_MOVING:
+ return "moving";
+ case GNOME_VFS_XFER_PHASE_READSOURCE:
+ return "read source";
+ case GNOME_VFS_XFER_PHASE_WRITETARGET:
+ return "write target";
+ case GNOME_VFS_XFER_PHASE_CLOSESOURCE:
+ return "close source";
+ case GNOME_VFS_XFER_PHASE_CLOSETARGET:
+ return "close target";
+ case GNOME_VFS_XFER_PHASE_DELETESOURCE:
+ return "delete source";
+ case GNOME_VFS_XFER_PHASE_SETATTRIBUTES:
+ return "set attributes";
+ case GNOME_VFS_XFER_PHASE_FILECOMPLETED:
+ return "file completed";
+ case GNOME_VFS_XFER_PHASE_CLEANUP:
+ return "cleanup";
+ case GNOME_VFS_XFER_PHASE_COMPLETED:
+ return "completed";
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+}
+
+/* FIXME may belong into GnomeVFS */
+static char *
+status_to_str (GnomeVFSXferProgressStatus status)
+{
+ switch (status) {
+ case GNOME_VFS_XFER_PROGRESS_STATUS_OK:
+ return "OK";
+ case GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR:
+ return "VFS error";
+ case GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE:
+ return "overwrite?";
+ case GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE:
+ return "duplicate name?";
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+}
+
+static void
+debug_progress_info (GnomeVFSXferProgressInfo *info,
+ gboolean include_details)
+{
+ g_debug ("phase: %s", phase_to_str (info->phase));
+ g_debug ("status: %s", status_to_str (info->status));
+ g_debug ("VFS status: %s", gnome_vfs_result_to_string (info->vfs_status));
+ g_debug ("source: %s", info->source_name);
+ g_debug ("target: %s", info->target_name);
+
+ if (include_details) {
+ g_debug ("toplevel item: %s", info->top_level_item ? "TRUE" : "FALSE");
+ g_debug ("file index: %ld", info->file_index);
+ g_debug ("total files: %ld", info->files_total);
+ g_debug ("file size: %lu", (gulong) info->file_size);
+ g_debug ("total size: %lu", (gulong) info->bytes_total);
+ g_debug ("transferred file size: %lu", (gulong) info->bytes_copied);
+ g_debug ("transferred total size: %lu", (gulong) info->total_bytes_copied);
+ g_debug ("duplicate name: %s", info->duplicate_name);
+ g_debug ("duplicate count: %d", info->duplicate_count);
+ }
+}
+
+static int
+file_transfer_progress_callback (GnomeVFSXferProgressInfo *info,
+ gpointer verbosity_level_ptr)
+{
+ VerbosityLevel verbosity_level = GPOINTER_TO_UINT (verbosity_level_ptr);
+
+ g_assert (info != NULL);
+ g_assert (verbosity_level == NADA ||
+ verbosity_level == VERBOSE ||
+ verbosity_level == VERY_VERBOSE);
+
+ if (verbosity_level != NADA) {
+ g_debug ("progress_callback called");
+ debug_progress_info (info, verbosity_level == VERY_VERBOSE);
+ }
+
+ switch (info->status) {
+ case GNOME_VFS_XFER_PROGRESS_STATUS_OK:
+ return 1;
+ case GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR:
+ g_message ("aborting due to VFS error: %s\n",
+ gnome_vfs_result_to_string (info->vfs_status));
+ return GNOME_VFS_XFER_ERROR_ACTION_ABORT;
+ case GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE:
+ g_message ("interrupting due to attempted overwrite\n");
+ return GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT;
+ case GNOME_VFS_XFER_PROGRESS_STATUS_DUPLICATE:
+ g_message ("interrupting due to duplicate request\n");
+ return FALSE;
+ default:
+ g_assert_not_reached ();
+ return FALSE;
+ }
+}
+
+#define PARSE_FILE_TRANSFER_ARGV \
+ if (argc < 3 || argc > 4) { \
+ printf ("Usage: %s [--verbose|-v|--very-verbose|-vv] <src> <dest>\n", argv[0]); \
+ return 1; \
+ } else if (argc == 3) { \
+ verbosity_level = NADA; \
+ } else if (strcmp (argv[1], "-v") == 0 || \
+ strcmp (argv[1], "--verbose") == 0) { \
+ verbosity_level = VERBOSE; \
+ } else if (strcmp (argv[1], "-vv") == 0 || \
+ strcmp (argv[1], "--very-verbose") == 0) { \
+ verbosity_level = VERY_VERBOSE; \
+ } else { \
+ fprintf (stderr, "--verbose, -v, --very-verbose, -vv or nothing expected, got %s", argv[1]); \
+ return 1; \
+ }
Index: programs/gnomevfs-copy.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/programs/gnomevfs-copy.c,v
retrieving revision 1.4
diff -u -p -r1.4 gnomevfs-copy.c
--- programs/gnomevfs-copy.c 5 Jun 2005 17:35:12 -0000 1.4
+++ programs/gnomevfs-copy.c 11 Jan 2006 18:00:16 -0000
@@ -26,8 +26,10 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
+#include "file-transfer-helper.c"
int
main (int argc, char **argv)
@@ -36,23 +38,22 @@ main (int argc, char **argv)
char *text_uri;
GnomeVFSURI *src, *dest;
GnomeVFSFileInfo *info;
-
- if (argc != 3) {
- printf ("Usage: %s <src> <dest>\n", argv[0]);
- return 1;
- }
+ VerbosityLevel verbosity_level;
+ int first_uri_argc = argc - 2;
+
+ PARSE_FILE_TRANSFER_ARGV;
if (!gnome_vfs_init ()) {
fprintf (stderr, "Cannot initialize gnome-vfs.\n");
return 1;
}
- text_uri = gnome_vfs_make_uri_from_shell_arg (argv[1]);
+ text_uri = gnome_vfs_make_uri_from_shell_arg (argv[first_uri_argc]);
src = gnome_vfs_uri_new (text_uri);
g_free (text_uri);
- text_uri = gnome_vfs_make_uri_from_shell_arg (argv[2]);
+ text_uri = gnome_vfs_make_uri_from_shell_arg (argv[first_uri_argc + 1]);
dest = gnome_vfs_uri_new (text_uri);
g_free (text_uri);
@@ -86,13 +87,24 @@ main (int argc, char **argv)
}
+ if (verbosity_level != NADA) {
+ char *src_text, *dest_text;
+
+ src_text = gnome_vfs_uri_to_string (src, GNOME_VFS_URI_HIDE_NONE);
+ dest_text = gnome_vfs_uri_to_string (dest, GNOME_VFS_URI_HIDE_NONE);
+ g_debug ("Copying %s to %s", src_text, dest_text);
+ g_free (src_text);
+ g_free (dest_text);
+ }
+
gnome_vfs_file_info_unref (info);
result = gnome_vfs_xfer_uri (src, dest,
GNOME_VFS_XFER_RECURSIVE,
GNOME_VFS_XFER_ERROR_MODE_ABORT,
GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE,
- NULL, NULL);
+ file_transfer_progress_callback,
+ GUINT_TO_POINTER (verbosity_level));
out:
if (src) {
@@ -105,7 +117,7 @@ out:
if (result != GNOME_VFS_OK) {
fprintf (stderr, "Failed to copy %s to %s\nReason: %s\n",
- argv[1], argv[2], gnome_vfs_result_to_string (result));
+ argv[first_uri_argc], argv[first_uri_argc + 1], gnome_vfs_result_to_string (result));
return 1;
}
Attachment:
signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil