summaryrefslogtreecommitdiff
path: root/programs
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2007-11-27 13:45:55 +0000
committerAlexander Larsson <alexl@src.gnome.org>2007-11-27 13:45:55 +0000
commit630a801327347ca629842c77f68f488bfa6aa489 (patch)
tree32d43cd707aa20d9c26306156dc692d7a7da80f3 /programs
parent6b295b9eb69c50d31c027771b8d4b88b480c6d68 (diff)
downloadgvfs-630a801327347ca629842c77f68f488bfa6aa489.tar.gz
Moved the gio tools from gio-standalone
2007-11-27 Alexander Larsson <alexl@redhat.com> * Makefile.am: * configure.ac: * programs/Makefile.am: * programs/gvfs-cat.c: * programs/gvfs-copy.c: * programs/gvfs-info.c: * programs/gvfs-ls.c: * programs/gvfs-monitor-dir.c: * programs/gvfs-monitor-file.c: * programs/gvfs-mount.c: * programs/gvfs-move.c: * programs/gvfs-rm.c: * programs/gvfs-save.c: * programs/gvfs-trash.c: Moved the gio tools from gio-standalone svn path=/trunk/; revision=1033
Diffstat (limited to 'programs')
-rw-r--r--programs/Makefile.am57
-rw-r--r--programs/gvfs-cat.c128
-rw-r--r--programs/gvfs-copy.c181
-rw-r--r--programs/gvfs-info.c349
-rw-r--r--programs/gvfs-ls.c209
-rw-r--r--programs/gvfs-monitor-dir.c117
-rw-r--r--programs/gvfs-monitor-file.c106
-rw-r--r--programs/gvfs-mount.c207
-rw-r--r--programs/gvfs-move.c172
-rw-r--r--programs/gvfs-rm.c70
-rw-r--r--programs/gvfs-save.c172
-rw-r--r--programs/gvfs-trash.c70
12 files changed, 1838 insertions, 0 deletions
diff --git a/programs/Makefile.am b/programs/Makefile.am
new file mode 100644
index 00000000..5f8bf118
--- /dev/null
+++ b/programs/Makefile.am
@@ -0,0 +1,57 @@
+NULL =
+
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GLIB_CFLAGS) \
+ -DG_DISABLE_DEPRECATED
+
+libraries = \
+ $(GLIB_LIBS)
+
+bin_PROGRAMS = \
+ gvfs-mount \
+ gvfs-cat \
+ gvfs-save \
+ gvfs-ls \
+ gvfs-info \
+ gvfs-trash \
+ gvfs-rm \
+ gvfs-copy \
+ gvfs-move \
+ gvfs-monitor-file \
+ gvfs-monitor-dir \
+ $(NULL)
+
+gvfs_cat_SOURCES = gvfs-cat.c
+gvfs_cat_LDADD = $(libraries)
+
+gvfs_copy_SOURCES = gvfs-copy.c
+gvfs_copy_LDADD = $(libraries)
+
+gvfs_save_SOURCES = gvfs-save.c
+gvfs_save_LDADD = $(libraries)
+
+gvfs_info_SOURCES = gvfs-info.c
+gvfs_info_LDADD = $(libraries)
+
+gvfs_trash_SOURCES = gvfs-trash.c
+gvfs_trash_LDADD = $(libraries)
+
+gvfs_rm_SOURCES = gvfs-rm.c
+gvfs_rm_LDADD = $(libraries)
+
+gvfs_ls_SOURCES = gvfs-ls.c
+gvfs_ls_LDADD = $(libraries)
+
+gvfs_move_SOURCES = gvfs-move.c
+gvfs_move_LDADD = $(libraries)
+
+gvfs_mount_SOURCES = gvfs-mount.c
+gvfs_mount_LDADD = $(libraries)
+
+gvfs_monitor_dir_SOURCES = gvfs-monitor-dir.c
+gvfs_monitor_dir_LDADD = $(libraries)
+
+gvfs_monitor_file_SOURCES = gvfs-monitor-file.c
+gvfs_monitor_file_LDADD = $(libraries)
diff --git a/programs/gvfs-cat.c b/programs/gvfs-cat.c
new file mode 100644
index 00000000..1386c1ab
--- /dev/null
+++ b/programs/gvfs-cat.c
@@ -0,0 +1,128 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <locale.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <gio/gfile.h>
+
+static GOptionEntry entries[] =
+{
+ { NULL }
+};
+
+static void
+cat (GFile *file)
+{
+ GInputStream *in;
+ char buffer[1024*8 + 1];
+ char *p;
+ gssize res;
+ gboolean close_res;
+ GError *error;
+
+ error = NULL;
+ in = (GInputStream *)g_file_read (file, NULL, &error);
+ if (in == NULL)
+ {
+ g_printerr ("Error opening file: %s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ while (1)
+ {
+ res = g_input_stream_read (in, buffer, sizeof (buffer) - 1, NULL, &error);
+ if (res > 0)
+ {
+ ssize_t written;
+
+ p = buffer;
+ while (res > 0)
+ {
+ written = write (STDOUT_FILENO, p, res);
+
+ if (written == -1 && errno != EINTR)
+ {
+ perror ("Error writing to stdout");
+ goto out;
+ }
+ res -= written;
+ p += written;
+ }
+ }
+ else if (res < 0)
+ {
+ g_printerr ("Error reading: %s\n", error->message);
+ g_error_free (error);
+ error = NULL;
+ break;
+ }
+ else if (res == 0)
+ break;
+ }
+
+ out:
+
+ close_res = g_input_stream_close (in, NULL, &error);
+ if (!close_res)
+ {
+ g_printerr ("Error closing: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ GError *error;
+ GOptionContext *context;
+ GFile *file;
+
+ setlocale (LC_ALL, "");
+
+ g_type_init ();
+
+ error = NULL;
+ context = g_option_context_new ("- output files at <location>");
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+
+ if (argc > 1)
+ {
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ file = g_file_new_for_commandline_arg (argv[i]);
+ cat (file);
+ g_object_unref (file);
+ }
+ }
+
+ return 0;
+}
diff --git a/programs/gvfs-copy.c b/programs/gvfs-copy.c
new file mode 100644
index 00000000..05e961d1
--- /dev/null
+++ b/programs/gvfs-copy.c
@@ -0,0 +1,181 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <locale.h>
+#include <errno.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gfile.h>
+
+static gboolean progress = FALSE;
+static gboolean interactive = FALSE;
+static gboolean no_dereference = FALSE;
+static gboolean backup = FALSE;
+static gboolean preserve = FALSE;
+static gboolean no_target_directory = FALSE;
+
+static GOptionEntry entries[] =
+{
+ { "no-target-directory", 'T', 0, G_OPTION_ARG_NONE, &no_target_directory, "no target directory", NULL },
+ { "progress", 'p', 0, G_OPTION_ARG_NONE, &progress, "show progress", NULL },
+ { "interactive", 'i', 0, G_OPTION_ARG_NONE, &interactive, "prompt before overwrite", NULL },
+ { "preserve", 'p', 0, G_OPTION_ARG_NONE, &preserve, "preserve all attributes", NULL },
+ { "backup", 'b', 0, G_OPTION_ARG_NONE, &backup, "backup existing destination files", NULL },
+ { "no-dereference", 'P', 0, G_OPTION_ARG_NONE, &no_dereference, "never follow symbolic links", NULL },
+ { NULL }
+};
+
+static gboolean
+is_dir (GFile *file)
+{
+ GFileInfo *info;
+ gboolean res;
+
+ info = g_file_query_info (file, G_FILE_ATTRIBUTE_STD_TYPE, 0, NULL, NULL);
+ res = info && g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY;
+ if (info)
+ g_object_unref (info);
+ return res;
+}
+
+static void
+show_progress (goffset current_num_bytes,
+ goffset total_num_bytes,
+ gpointer user_data)
+{
+ g_print ("progress %"G_GUINT64_FORMAT"/%"G_GUINT64_FORMAT"\n",
+ current_num_bytes, total_num_bytes);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ GError *error;
+ GOptionContext *context;
+ GFile *source, *dest, *target;
+ gboolean dest_is_dir;
+ char *basename;
+ int i;
+ GFileCopyFlags flags;
+
+ setlocale (LC_ALL, "");
+
+ g_type_init ();
+
+ error = NULL;
+ context = g_option_context_new ("- output files at <location>");
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+
+ if (argc <= 2)
+ {
+ g_printerr ("Missing operand\n");
+ return 1;
+ }
+
+ dest = g_file_new_for_commandline_arg (argv[argc-1]);
+
+ if (no_target_directory && argc > 3)
+ {
+ g_printerr ("Too many arguments\n");
+ g_object_unref (dest);
+ return 1;
+ }
+
+ dest_is_dir = is_dir (dest);
+
+ if (!dest_is_dir && argc > 3)
+ {
+ g_printerr ("Target %s is not a directory\n", argv[argc-1]);
+ g_object_unref (dest);
+ return 1;
+ }
+
+ for (i = 1; i < argc - 1; i++)
+ {
+ source = g_file_new_for_commandline_arg (argv[i]);
+
+ if (dest_is_dir && !no_target_directory)
+ {
+ basename = g_file_get_basename (source);
+ target = g_file_get_child (dest, basename);
+ g_free (basename);
+ }
+ else
+ target = g_object_ref (dest);
+
+ flags = 0;
+ if (backup)
+ flags |= G_FILE_COPY_BACKUP;
+ if (!interactive)
+ flags |= G_FILE_COPY_OVERWRITE;
+ if (no_dereference)
+ flags |= G_FILE_COPY_NOFOLLOW_SYMLINKS;
+ if (preserve)
+ flags |= G_FILE_COPY_ALL_METADATA;
+
+
+ error = NULL;
+ if (!g_file_copy (source, target, flags, NULL, progress?show_progress:NULL, NULL, &error))
+ {
+ if (interactive && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
+ {
+ char line[16];
+
+ g_error_free (error);
+ error = NULL;
+
+ basename = g_file_get_basename (target);
+ g_print ("overwrite %s?", basename);
+ g_free (basename);
+
+ if (fgets(line, sizeof (line), stdin) &&
+ line[0] == 'y')
+ {
+ flags |= G_FILE_COPY_OVERWRITE;
+ if (!g_file_copy (source, target, flags, NULL, NULL, NULL, &error))
+ goto copy_failed;
+ }
+ }
+ else
+ {
+ copy_failed:
+ g_printerr ("Error copying file %s: %s\n", argv[i], error->message);
+ g_error_free (error);
+ }
+ }
+
+ g_object_unref (source);
+ g_object_unref (target);
+ }
+
+ g_object_unref (dest);
+
+ return 0;
+}
diff --git a/programs/gvfs-info.c b/programs/gvfs-info.c
new file mode 100644
index 00000000..55db25df
--- /dev/null
+++ b/programs/gvfs-info.c
@@ -0,0 +1,349 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include <config.h>
+
+#include <glib.h>
+#include <locale.h>
+#include <gio/gfile.h>
+
+static char *attributes = NULL;
+static gboolean nofollow_symlinks = FALSE;
+static gboolean filesystem = FALSE;
+static gboolean writable = FALSE;
+
+static GOptionEntry entries[] =
+{
+ { "query-writable", 'w', 0, G_OPTION_ARG_NONE, &writable, "List writable attributes", NULL },
+ { "filesystem", 'f', 0, G_OPTION_ARG_NONE, &filesystem, "Get filesystem info", NULL },
+ { "attributes", 'a', 0, G_OPTION_ARG_STRING, &attributes, "The attributes to get", NULL },
+ { "nofollow-symlinks", 'n', 0, G_OPTION_ARG_NONE, &nofollow_symlinks, "Don't follow symlinks", NULL },
+ { NULL }
+};
+
+static const char *
+type_to_string (GFileType type)
+{
+ switch (type)
+ {
+ default:
+ return "invalid type";
+
+ case G_FILE_TYPE_UNKNOWN:
+ return "unknown";
+
+ case G_FILE_TYPE_REGULAR:
+ return "regular";
+
+ case G_FILE_TYPE_DIRECTORY:
+ return "directory";
+
+ case G_FILE_TYPE_SYMBOLIC_LINK:
+ return "symlink";
+
+ case G_FILE_TYPE_SPECIAL:
+ return "special";
+
+ case G_FILE_TYPE_SHORTCUT:
+ return "shortcut";
+
+ case G_FILE_TYPE_MOUNTABLE:
+ return "mountable";
+ }
+}
+
+static char *
+escape_string (const char *in)
+{
+ GString *str;
+ static char *hex_digits = "0123456789abcdef";
+ char c;
+
+
+ str = g_string_new ("");
+
+ while ((c = *in++) != 0)
+ {
+ if (c >= 32 && c <= 126 && c != '\\')
+ g_string_append_c (str, c);
+ else
+ {
+ g_string_append (str, "\\x");
+ g_string_append_c (str, hex_digits[(c >> 8) & 0xf]);
+ g_string_append_c (str, hex_digits[c & 0xf]);
+ }
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+static void
+show_attributes (GFileInfo *info)
+{
+ char **attributes;
+ const GFileAttributeValue *value;
+ char *s;
+ int i;
+
+ attributes = g_file_info_list_attributes (info, NULL);
+
+ g_print ("attributes:\n");
+ for (i = 0; attributes[i] != NULL; i++)
+ {
+ value = g_file_info_get_attribute (info, attributes[i]);
+ s = g_file_attribute_value_as_string (value);
+ g_print (" %s: %s\n", attributes[i], s);
+ g_free (s);
+ }
+ g_strfreev (attributes);
+}
+
+static void
+show_info (GFileInfo *info)
+{
+ const char *name, *type;
+ char *escaped;
+ goffset size;
+
+ name = g_file_info_get_display_name (info);
+ if (name)
+ g_print ("display name: %s\n", name);
+
+ name = g_file_info_get_edit_name (info);
+ if (name)
+ g_print ("edit name: %s\n", name);
+
+ name = g_file_info_get_name (info);
+ if (name)
+ {
+ escaped = escape_string (name);
+ g_print ("name: %s\n", escaped);
+ g_free (escaped);
+ }
+
+ type = type_to_string (g_file_info_get_file_type (info));
+ g_print ("type: %s\n", type);
+
+ size = g_file_info_get_size (info);
+ g_print ("size: %"G_GUINT64_FORMAT"\n", (guint64)size);
+
+ if (g_file_info_get_is_hidden (info))
+ g_print ("hidden\n");
+
+ show_attributes (info);
+}
+
+static void
+query_info (GFile *file)
+{
+ GFileQueryInfoFlags flags;
+ GFileInfo *info;
+ GError *error;
+
+ if (file == NULL)
+ return;
+
+ if (attributes == NULL)
+ attributes = "*";
+
+ flags = 0;
+ if (nofollow_symlinks)
+ flags |= G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS;
+
+ error = NULL;
+ if (filesystem)
+ info = g_file_query_filesystem_info (file, attributes, NULL, &error);
+ else
+ info = g_file_query_info (file, attributes, flags, NULL, &error);
+
+ if (info == NULL)
+ {
+ g_printerr ("Error getting info: %s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (filesystem)
+ show_attributes (info);
+ else
+ show_info (info);
+
+ g_object_unref (info);
+}
+
+static char *
+attribute_type_to_string (GFileAttributeType type)
+{
+ switch (type)
+ {
+ case G_FILE_ATTRIBUTE_TYPE_INVALID:
+ return "invalid";
+ case G_FILE_ATTRIBUTE_TYPE_STRING:
+ return "string";
+ case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING:
+ return "bytestring";
+ case G_FILE_ATTRIBUTE_TYPE_BOOLEAN:
+ return "boolean";
+ case G_FILE_ATTRIBUTE_TYPE_UINT32:
+ return "uint32";
+ case G_FILE_ATTRIBUTE_TYPE_INT32:
+ return "int32";
+ case G_FILE_ATTRIBUTE_TYPE_UINT64:
+ return "uint64";
+ case G_FILE_ATTRIBUTE_TYPE_INT64:
+ return "int64";
+ case G_FILE_ATTRIBUTE_TYPE_OBJECT:
+ return "object";
+ default:
+ return "uknown type";
+ }
+}
+
+static char *
+attribute_flags_to_string (GFileAttributeFlags flags)
+{
+ GString *s;
+ int i;
+ gboolean first;
+ struct {
+ guint32 mask;
+ char *descr;
+ } flag_descr[] = {
+ {
+ G_FILE_ATTRIBUTE_FLAGS_COPY_WITH_FILE,
+ "Copy with file"
+ },
+ {
+ G_FILE_ATTRIBUTE_FLAGS_COPY_WHEN_MOVED,
+ "Keep with file when moved"
+ }
+ };
+
+ first = TRUE;
+
+ s = g_string_new ("");
+ for (i = 0; i < G_N_ELEMENTS (flag_descr); i++)
+ {
+ if (flags & flag_descr[i].mask)
+ {
+ if (!first)
+ g_string_append (s, ", ");
+ g_string_append (s, flag_descr[i].descr);
+ first = FALSE;
+ }
+ }
+
+ return g_string_free (s, FALSE);
+}
+
+static void
+get_writable_info (GFile *file)
+{
+ GFileAttributeInfoList *list;
+ GError *error;
+ int i;
+ char *flags;
+
+ if (file == NULL)
+ return;
+
+ error = NULL;
+
+ list = g_file_query_settable_attributes (file, NULL, &error);
+ if (list == NULL)
+ {
+ g_printerr ("Error getting writable attributes: %s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ g_print ("Settable attributes:\n");
+ for (i = 0; i < list->n_infos; i++)
+ {
+ flags = attribute_flags_to_string (list->infos[i].flags);
+ g_print (" %s (%s%s%s)\n",
+ list->infos[i].name,
+ attribute_type_to_string (list->infos[i].type),
+ (*flags != 0)?", ":"", flags);
+ g_free (flags);
+ }
+
+ g_file_attribute_info_list_unref (list);
+
+ list = g_file_query_writable_namespaces (file, NULL, &error);
+ if (list == NULL)
+ {
+ g_printerr ("Error getting writable namespaces: %s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (list->n_infos > 0)
+ {
+ g_print ("Writable attribute namespaces:\n");
+ for (i = 0; i < list->n_infos; i++)
+ {
+ flags = attribute_flags_to_string (list->infos[i].flags);
+ g_print (" %s (%s%s%s)\n",
+ list->infos[i].name,
+ attribute_type_to_string (list->infos[i].type),
+ (*flags != 0)?", ":"", flags);
+ }
+ }
+
+ g_file_attribute_info_list_unref (list);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ GError *error;
+ GOptionContext *context;
+ GFile *file;
+
+ setlocale (LC_ALL, "");
+
+ g_type_init ();
+
+ error = NULL;
+ context = g_option_context_new ("- show info for <location>");
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+
+ if (argc > 1)
+ {
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ file = g_file_new_for_commandline_arg (argv[i]);
+ if (writable)
+ get_writable_info (file);
+ else
+ query_info (file);
+ g_object_unref (file);
+ }
+ }
+
+ return 0;
+}
diff --git a/programs/gvfs-ls.c b/programs/gvfs-ls.c
new file mode 100644
index 00000000..474b1d76
--- /dev/null
+++ b/programs/gvfs-ls.c
@@ -0,0 +1,209 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include <config.h>
+
+#include <glib.h>
+#include <locale.h>
+#include <string.h>
+#include <gio/gfile.h>
+
+static char *attributes = NULL;
+static gboolean show_hidden = FALSE;
+
+static GOptionEntry entries[] =
+{
+ { "attributes", 'a', 0, G_OPTION_ARG_STRING, &attributes, "The attributes to get", NULL },
+ { "hidden", 'h', 0, G_OPTION_ARG_NONE, &show_hidden, "Show hidden files", NULL },
+ { NULL }
+};
+
+static const char *
+type_to_string (GFileType type)
+{
+ switch (type)
+ {
+ default:
+ return "invalid type";
+
+ case G_FILE_TYPE_UNKNOWN:
+ return "unknown";
+
+ case G_FILE_TYPE_REGULAR:
+ return "regular";
+
+ case G_FILE_TYPE_DIRECTORY:
+ return "directory";
+
+ case G_FILE_TYPE_SYMBOLIC_LINK:
+ return "symlink";
+
+ case G_FILE_TYPE_SPECIAL:
+ return "special";
+
+ case G_FILE_TYPE_SHORTCUT:
+ return "shortcut";
+
+ case G_FILE_TYPE_MOUNTABLE:
+ return "mountable";
+ }
+}
+
+static void
+show_info (GFileInfo *info)
+{
+ const char *name, *type;
+ goffset size;
+ char **attributes;
+ int i;
+ gboolean first_attr;
+
+ if ((g_file_info_get_is_hidden (info)) && !show_hidden)
+ return;
+
+ name = g_file_info_get_name (info);
+ if (name == NULL)
+ name = "";
+
+ size = g_file_info_get_size (info);
+ type = type_to_string (g_file_info_get_file_type (info));
+ g_print ("%s\t%"G_GUINT64_FORMAT"\t(%s)", name, (guint64)size, type);
+
+ first_attr = TRUE;
+ attributes = g_file_info_list_attributes (info, NULL);
+ for (i = 0 ; attributes[i] != NULL; i++)
+ {
+ GFileAttributeValue *val;
+ char *val_as_string;
+
+ if (strcmp (attributes[i], G_FILE_ATTRIBUTE_STD_NAME) == 0 ||
+ strcmp (attributes[i], G_FILE_ATTRIBUTE_STD_SIZE) == 0 ||
+ strcmp (attributes[i], G_FILE_ATTRIBUTE_STD_TYPE) == 0)
+ continue;
+
+ if (first_attr)
+ {
+ g_print ("\t");
+ first_attr = FALSE;
+ }
+ else
+ g_print (" ");
+ val = g_file_info_get_attribute (info, attributes[i]);
+ val_as_string = g_file_attribute_value_as_string (val);
+ g_print ("%s=%s", attributes[i], val_as_string);
+ g_free (val_as_string);
+ }
+
+ g_strfreev (attributes);
+
+ g_print ("\n");
+}
+
+static void
+list (GFile *file)
+{
+ GFileEnumerator *enumerator;
+ GFileInfo *info;
+ GError *error;
+
+ if (file == NULL)
+ return;
+
+ error = NULL;
+ enumerator = g_file_enumerate_children (file, attributes, 0, NULL, &error);
+ if (enumerator == NULL)
+ {
+ g_print ("Error: %s\n", error->message);
+ g_error_free (error);
+ error = NULL;
+ return;
+ }
+
+ while ((info = g_file_enumerator_next_file (enumerator, NULL, &error)) != NULL)
+ {
+ show_info (info);
+
+ g_object_unref (info);
+ }
+
+ if (error)
+ {
+ g_print ("Error: %s\n", error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+
+ if (!g_file_enumerator_close (enumerator, NULL, &error))
+ {
+ g_print ("Error closing enumerator: %s\n", error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ GError *error;
+ GOptionContext *context;
+ GFile *file;
+
+ setlocale (LC_ALL, "");
+
+ g_type_init ();
+
+ error = NULL;
+ context = g_option_context_new ("- list files at <location>");
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+
+ attributes = g_strconcat (G_FILE_ATTRIBUTE_STD_NAME "," G_FILE_ATTRIBUTE_STD_TYPE "," G_FILE_ATTRIBUTE_STD_SIZE,
+ attributes != NULL ? "," : "",
+ attributes,
+ NULL);
+
+ if (argc > 1)
+ {
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ file = g_file_new_for_commandline_arg (argv[i]);
+ list (file);
+ g_object_unref (file);
+ }
+ }
+ else
+ {
+ char *cwd;
+
+ cwd = g_get_current_dir ();
+ file = g_file_new_for_path (cwd);
+ g_free (cwd);
+ list (file);
+ g_object_unref (file);
+ }
+
+ g_free (attributes);
+
+ return 0;
+}
diff --git a/programs/gvfs-monitor-dir.c b/programs/gvfs-monitor-dir.c
new file mode 100644
index 00000000..cf8e189d
--- /dev/null
+++ b/programs/gvfs-monitor-dir.c
@@ -0,0 +1,117 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <locale.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <gio/gfile.h>
+#include <gio/gdirectorymonitor.h>
+
+static GMainLoop *main_loop;
+
+static GOptionEntry entries[] = {
+ { NULL }
+};
+
+static gboolean
+dir_monitor_callback (GDirectoryMonitor* monitor,
+ GFile* child,
+ GFile* other_file,
+ GFileMonitorEvent eflags)
+{
+
+ char *name = g_file_get_parse_name (child);
+
+ g_print ("Directory Monitor Event:\n");
+ g_print ("Child = %s\n", name);
+ g_free (name);
+
+ switch (eflags)
+ {
+ case G_FILE_MONITOR_EVENT_CHANGED:
+ g_print ("Event = CHANGED\n");
+ break;
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ g_print ("Event = CHANGES_DONE_HINT\n");
+ break;
+ case G_FILE_MONITOR_EVENT_DELETED:
+ g_print ("Event = DELETED\n");
+ break;
+ case G_FILE_MONITOR_EVENT_CREATED:
+ g_print ("Event = CREATED\n");
+ break;
+ case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
+ g_print ("Event = PRE_UNMOUNT\n");
+ break;
+ case G_FILE_MONITOR_EVENT_UNMOUNTED:
+ g_print ("Event = UNMOUNTED\n");
+ break;
+ case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
+ g_print ("Event = ATTRIB CHANGED\n");
+ break;
+ }
+
+ return TRUE;
+}
+
+int
+main (int argc, char *argv[])
+{
+ GDirectoryMonitor* dmonitor;
+ GError *error;
+ GOptionContext *context;
+ GFile *file;
+
+ setlocale (LC_ALL, "");
+
+ g_type_init ();
+
+ error = NULL;
+ context = g_option_context_new ("- monitor directory <location>");
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+
+ if (argc > 1)
+ {
+ file = g_file_new_for_commandline_arg (argv[1]);
+ dmonitor = g_file_monitor_directory (file, G_FILE_MONITOR_FLAGS_MONITOR_MOUNTS, NULL);
+ if (dmonitor != NULL)
+ g_signal_connect (dmonitor, "changed", (GCallback)dir_monitor_callback, NULL);
+ else
+ {
+ g_print ("Monitoring not supported for %s\n", argv[1]);
+ return 1;
+ }
+ }
+
+ main_loop = g_main_loop_new (NULL, FALSE);
+
+ g_main_loop_run (main_loop);
+
+ return 0;
+}
diff --git a/programs/gvfs-monitor-file.c b/programs/gvfs-monitor-file.c
new file mode 100644
index 00000000..b23e2bc9
--- /dev/null
+++ b/programs/gvfs-monitor-file.c
@@ -0,0 +1,106 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <locale.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <gio/gfile.h>
+#include <gio/gfilemonitor.h>
+
+static GMainLoop *main_loop;
+
+static GOptionEntry entries[] = {
+ { NULL }
+};
+
+static gboolean
+file_monitor_callback (GFileMonitor* monitor,
+ GFile* child,
+ GFile* other_file,
+ GFileMonitorEvent eflags)
+{
+ g_print ("File Monitor Event:\n");
+ g_print ("File = %s\n", g_file_get_parse_name (child));
+ switch (eflags)
+ {
+ case G_FILE_MONITOR_EVENT_CHANGED:
+ g_print ("Event = CHANGED\n");
+ break;
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ g_print ("Event = CHANGES_DONE_HINT\n");
+ break;
+ case G_FILE_MONITOR_EVENT_DELETED:
+ g_print ("Event = DELETED\n");
+ break;
+ case G_FILE_MONITOR_EVENT_CREATED:
+ g_print ("Event = CREATED\n");
+ break;
+ case G_FILE_MONITOR_EVENT_UNMOUNTED:
+ g_print ("Event = UNMOUNTED\n");
+ break;
+ case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
+ g_print ("Event = PRE_UNMOUNT\n");
+ break;
+ case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
+ g_print ("Event = ATTRIB CHANGED\n");
+ break;
+ }
+
+ return TRUE;
+}
+
+int
+main (int argc, char *argv[])
+{
+ GFileMonitor* fmonitor;
+ GError *error;
+ GOptionContext *context;
+ GFile *file;
+
+ setlocale (LC_ALL, "");
+
+ g_type_init ();
+
+ error = NULL;
+ context = g_option_context_new ("- monitor file <location>");
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+
+ if (argc > 1)
+ {
+ file = g_file_new_for_commandline_arg (argv[1]);
+ fmonitor = g_file_monitor_file (file, G_FILE_MONITOR_FLAGS_MONITOR_MOUNTS, NULL);
+ g_signal_connect (fmonitor, "changed", (GCallback)file_monitor_callback, NULL);
+ }
+
+ main_loop = g_main_loop_new (NULL, FALSE);
+
+ g_main_loop_run (main_loop);
+
+ return 0;
+}
diff --git a/programs/gvfs-mount.c b/programs/gvfs-mount.c
new file mode 100644
index 00000000..c9b9fad5
--- /dev/null
+++ b/programs/gvfs-mount.c
@@ -0,0 +1,207 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <glib.h>
+#include <locale.h>
+#include <gio/gfile.h>
+
+static int outstanding_mounts = 0;
+static GMainLoop *main_loop;
+
+
+static gboolean mount_mountable = FALSE;
+
+static GOptionEntry entries[] =
+{
+ { "mountable", 'm', 0, G_OPTION_ARG_NONE, &mount_mountable, "Mount as mountable", NULL },
+ { NULL }
+};
+
+static char *
+prompt_for (const char *prompt, const char *default_value)
+{
+ char data[256];
+ int len;
+
+ if (default_value && *default_value != 0)
+ g_print ("%s [%s]: ", prompt, default_value);
+ else
+ g_print ("%s: ", prompt);
+
+ data[0] = 0;
+ fgets(data, sizeof (data), stdin);
+ len = strlen (data);
+ if (len > 0 && data[len-1] == '\n')
+ data[len-1] = 0;
+
+ if (*data == 0 && default_value)
+ return g_strdup (default_value);
+ return g_strdup (data);
+}
+
+static gboolean
+ask_password_cb (GMountOperation *op,
+ const char *message,
+ const char *default_user,
+ const char *default_domain,
+ GPasswordFlags flags)
+{
+ char *s;
+ g_print ("%s\n", message);
+
+ if (flags & G_PASSWORD_FLAGS_NEED_USERNAME)
+ {
+ s = prompt_for ("User", default_user);
+ g_mount_operation_set_username (op, s);
+ g_free (s);
+ }
+
+ if (flags & G_PASSWORD_FLAGS_NEED_DOMAIN)
+ {
+ s = prompt_for ("Domain", default_domain);
+ g_mount_operation_set_domain (op, s);
+ g_free (s);
+ }
+
+ if (flags & G_PASSWORD_FLAGS_NEED_PASSWORD)
+ {
+ s = prompt_for ("Password", NULL);
+ g_mount_operation_set_password (op, s);
+ g_free (s);
+ }
+
+ g_mount_operation_reply (op, FALSE);
+
+ return TRUE;
+}
+
+static void
+mount_mountable_done_cb (GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GFile *target;
+ GError *error = NULL;
+
+ target = g_file_mount_mountable_finish (G_FILE (object), res, &error);
+
+ if (target == NULL)
+ g_print ("Error mounting location: %s\n", error->message);
+ else
+ g_object_unref (target);
+
+ outstanding_mounts--;
+
+ if (outstanding_mounts == 0)
+ g_main_loop_quit (main_loop);
+}
+
+static void
+mount_done_cb (GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ gboolean succeeded;
+ GError *error = NULL;
+
+ succeeded = g_mount_for_location_finish (G_FILE (object), res, &error);
+
+ if (!succeeded)
+ g_print ("Error mounting location: %s\n", error->message);
+
+ outstanding_mounts--;
+
+ if (outstanding_mounts == 0)
+ g_main_loop_quit (main_loop);
+}
+
+static GMountOperation *
+new_mount_op (void)
+{
+ GMountOperation *op;
+
+ op = g_mount_operation_new ();
+
+ g_signal_connect (op, "ask_password", (GCallback)ask_password_cb, NULL);
+
+ return op;
+}
+
+
+static void
+mount (GFile *file)
+{
+ GMountOperation *op;
+
+ if (file == NULL)
+ return;
+
+ op = new_mount_op ();
+
+ if (mount_mountable)
+ g_file_mount_mountable (file, op, NULL, mount_mountable_done_cb, op);
+ else
+ g_mount_for_location (file, op, NULL, mount_done_cb, op);
+
+ outstanding_mounts++;
+}
+
+int
+main (int argc, char *argv[])
+{
+ GOptionContext *context;
+ GError *error;
+ GFile *file;
+
+ setlocale (LC_ALL, "");
+
+ g_type_init ();
+
+ error = NULL;
+ context = g_option_context_new ("- mount <location>");
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+
+ if (argc > 1)
+ {
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ file = g_file_new_for_commandline_arg (argv[i]);
+ mount (file);
+ g_object_unref (file);
+ }
+ }
+
+ main_loop = g_main_loop_new (NULL, FALSE);
+
+ if (outstanding_mounts > 0)
+ g_main_loop_run (main_loop);
+
+ return 0;
+}
diff --git a/programs/gvfs-move.c b/programs/gvfs-move.c
new file mode 100644
index 00000000..bbda06e0
--- /dev/null
+++ b/programs/gvfs-move.c
@@ -0,0 +1,172 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <locale.h>
+#include <errno.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gfile.h>
+
+static gboolean progress = FALSE;
+static gboolean interactive = FALSE;
+static gboolean backup = FALSE;
+static gboolean no_target_directory = FALSE;
+
+static GOptionEntry entries[] =
+{
+ { "no-target-directory", 'T', 0, G_OPTION_ARG_NONE, &no_target_directory, "no target directory", NULL },
+ { "progress", 'p', 0, G_OPTION_ARG_NONE, &progress, "show progress", NULL },
+ { "interactive", 'i', 0, G_OPTION_ARG_NONE, &interactive, "prompt before overwrite", NULL },
+ { "backup", 'b', 0, G_OPTION_ARG_NONE, &backup, "backup existing destination files", NULL },
+ { NULL }
+};
+
+static gboolean
+is_dir (GFile *file)
+{
+ GFileInfo *info;
+ gboolean res;
+
+ info = g_file_query_info (file, G_FILE_ATTRIBUTE_STD_TYPE, 0, NULL, NULL);
+ res = info && g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY;
+ if (info)
+ g_object_unref (info);
+ return res;
+}
+
+static void
+show_progress (goffset current_num_bytes,
+ goffset total_num_bytes,
+ gpointer user_data)
+{
+ g_print ("progress %"G_GUINT64_FORMAT"/%"G_GUINT64_FORMAT"\n",
+ current_num_bytes, total_num_bytes);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ GError *error;
+ GOptionContext *context;
+ GFile *source, *dest, *target;
+ gboolean dest_is_dir;
+ char *basename;
+ int i;
+ GFileCopyFlags flags;
+
+ setlocale (LC_ALL, "");
+
+ g_type_init ();
+
+ error = NULL;
+ context = g_option_context_new ("- output files at <location>");
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+
+ if (argc <= 2)
+ {
+ g_printerr ("Missing operand\n");
+ return 1;
+ }
+
+ dest = g_file_new_for_commandline_arg (argv[argc-1]);
+
+ if (no_target_directory && argc > 3)
+ {
+ g_printerr ("Too many arguments\n");
+ g_object_unref (dest);
+ return 1;
+ }
+
+ dest_is_dir = is_dir (dest);
+
+ if (!dest_is_dir && argc > 3)
+ {
+ g_printerr ("Target %s is not a directory\n", argv[argc-1]);
+ g_object_unref (dest);
+ return 1;
+ }
+
+ for (i = 1; i < argc - 1; i++)
+ {
+ source = g_file_new_for_commandline_arg (argv[i]);
+
+ if (dest_is_dir && !no_target_directory)
+ {
+ basename = g_file_get_basename (source);
+ target = g_file_get_child (dest, basename);
+ g_free (basename);
+ }
+ else
+ target = g_object_ref (dest);
+
+ flags = 0;
+ if (backup)
+ flags |= G_FILE_COPY_BACKUP;
+ if (!interactive)
+ flags |= G_FILE_COPY_OVERWRITE;
+
+ error = NULL;
+ if (!g_file_move (source, target, flags, NULL, progress?show_progress:NULL, NULL, &error))
+ {
+ if (interactive && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
+ {
+ char line[16];
+
+ g_error_free (error);
+ error = NULL;
+
+ basename = g_file_get_basename (target);
+ g_print ("overwrite %s?", basename);
+ g_free (basename);
+
+ if (fgets(line, sizeof (line), stdin) &&
+ line[0] == 'y')
+ {
+ flags |= G_FILE_COPY_OVERWRITE;
+ if (!g_file_move (source, target, flags, NULL, NULL, NULL, &error))
+ goto move_failed;
+ }
+ }
+ else
+ {
+ move_failed:
+ g_printerr ("Error moving file %s: %s\n", argv[i], error->message);
+ g_error_free (error);
+ }
+ }
+
+ g_object_unref (source);
+ g_object_unref (target);
+ }
+
+ g_object_unref (dest);
+
+ return 0;
+}
diff --git a/programs/gvfs-rm.c b/programs/gvfs-rm.c
new file mode 100644
index 00000000..222026b2
--- /dev/null
+++ b/programs/gvfs-rm.c
@@ -0,0 +1,70 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include <config.h>
+
+#include <glib.h>
+#include <locale.h>
+#include <gio/gfile.h>
+
+
+static GOptionEntry entries[] =
+{
+ { NULL }
+};
+
+
+int
+main (int argc, char *argv[])
+{
+ GError *error;
+ GOptionContext *context;
+ GFile *file;
+
+ setlocale (LC_ALL, "");
+
+ g_type_init ();
+
+ error = NULL;
+ context = g_option_context_new ("- delete files");
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+
+ if (argc > 1)
+ {
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ file = g_file_new_for_commandline_arg (argv[i]);
+ error = NULL;
+ if (!g_file_delete (file, NULL, &error))
+ {
+ g_print ("Error deleting file: %s\n", error->message);
+ g_error_free (error);
+ }
+ g_object_unref (file);
+ }
+ }
+
+ return 0;
+}
diff --git a/programs/gvfs-save.c b/programs/gvfs-save.c
new file mode 100644
index 00000000..98843796
--- /dev/null
+++ b/programs/gvfs-save.c
@@ -0,0 +1,172 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <locale.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <gio/gfile.h>
+
+static char *etag = NULL;
+static gboolean backup = FALSE;
+static gboolean create = FALSE;
+static gboolean append = FALSE;
+static gboolean priv = FALSE;
+static gboolean print_etag = FALSE;
+
+static GOptionEntry entries[] =
+{
+ { "backup", 'b', 0, G_OPTION_ARG_NONE, &backup, "Create backup", NULL },
+ { "create", 'c', 0, G_OPTION_ARG_NONE, &create, "Only create if not existing", NULL },
+ { "append", 'a', 0, G_OPTION_ARG_NONE, &append, "Append to end of file", NULL },
+ { "private", 'p', 0, G_OPTION_ARG_NONE, &priv, "When creating a file, restrict access to the current user only", NULL },
+ { "print_etag", 'v', 0, G_OPTION_ARG_NONE, &print_etag, "Print new etag at end", NULL },
+ { "etag", 'e', 0, G_OPTION_ARG_STRING, &etag, "The etag of the file being overwritten", NULL },
+ { NULL }
+};
+
+static gboolean
+save (GFile *file)
+{
+ GOutputStream *out;
+ GFileCreateFlags flags;
+ char buffer[1025];
+ char *p;
+ gssize res;
+ gboolean close_res;
+ GError *error;
+ gboolean save_res;
+
+ error = NULL;
+
+ flags = priv ? G_FILE_CREATE_FLAGS_PRIVATE : G_FILE_CREATE_FLAGS_NONE;
+
+ if (create)
+ out = (GOutputStream *)g_file_create (file, flags, NULL, &error);
+ else if (append)
+ out = (GOutputStream *)g_file_append_to (file, flags, NULL, &error);
+ else
+ out = (GOutputStream *)g_file_replace (file, etag, backup, flags, NULL, &error);
+ if (out == NULL)
+ {
+ g_printerr ("Error opening file: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ save_res = TRUE;
+
+ while (1)
+ {
+ res = read (STDIN_FILENO, buffer, 1024);
+ if (res > 0)
+ {
+ ssize_t written;
+
+ p = buffer;
+ while (res > 0)
+ {
+ error = NULL;
+ written = g_output_stream_write (out, p, res, NULL, &error);
+ if (written == -1)
+ {
+ save_res = FALSE;
+ g_printerr ("Error writing to stream: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+ res -= written;
+ p += written;
+ }
+ }
+ else if (res < 0)
+ {
+ save_res = FALSE;
+ perror ("Error reading stdin");
+ break;
+ }
+ else if (res == 0)
+ break;
+ }
+
+ out:
+
+ close_res = g_output_stream_close (out, NULL, &error);
+ if (!close_res)
+ {
+ save_res = FALSE;
+ g_printerr ("Error closing: %s\n", error->message);
+ g_error_free (error);
+ }
+
+ if (close_res && print_etag)
+ {
+ char *etag;
+ etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (out));
+
+ if (etag)
+ g_print ("Etag: %s\n", etag);
+ else
+ g_print ("Etag not available\n");
+ g_free (etag);
+ }
+
+ g_object_unref (out);
+
+ return save_res;
+}
+
+int
+main (int argc, char *argv[])
+{
+ GError *error;
+ GOptionContext *context;
+ GFile *file;
+ gboolean res;
+
+ setlocale (LC_ALL, "");
+
+ g_type_init ();
+
+ error = NULL;
+ context = g_option_context_new ("- output files at <location>");
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+
+ res = FALSE;
+
+ if (argc > 1)
+ {
+ file = g_file_new_for_commandline_arg (argv[1]);
+ res = save (file);
+ g_object_unref (file);
+ }
+
+ if (res)
+ return 0;
+ return 1;
+}
diff --git a/programs/gvfs-trash.c b/programs/gvfs-trash.c
new file mode 100644
index 00000000..e59f5339
--- /dev/null
+++ b/programs/gvfs-trash.c
@@ -0,0 +1,70 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include <config.h>
+
+#include <glib.h>
+#include <locale.h>
+#include <gio/gfile.h>
+
+
+static GOptionEntry entries[] =
+{
+ { NULL }
+};
+
+
+int
+main (int argc, char *argv[])
+{
+ GError *error;
+ GOptionContext *context;
+ GFile *file;
+
+ setlocale (LC_ALL, "");
+
+ g_type_init ();
+
+ error = NULL;
+ context = g_option_context_new ("- move files to trash");
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+
+ if (argc > 1)
+ {
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ file = g_file_new_for_commandline_arg (argv[i]);
+ error = NULL;
+ if (!g_file_trash (file, NULL, &error))
+ {
+ g_print ("Error trashing file: %s\n", error->message);
+ g_error_free (error);
+ }
+ g_object_unref (file);
+ }
+ }
+
+ return 0;
+}