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