Imported Upstream version 2.66.6
[platform/upstream/glib.git] / gio / gio-tool-trash.c
1 /*
2  * Copyright 2015 Red Hat, Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16  *
17  * Author: Matthias Clasen <mclasen@redhat.com>
18  */
19
20 #include "config.h"
21
22 #include <gio/gio.h>
23 #include <gi18n.h>
24
25 #include "gio-tool.h"
26
27
28 static gboolean force = FALSE;
29 static gboolean empty = FALSE;
30 static const GOptionEntry entries[] = {
31   { "force", 'f', 0, G_OPTION_ARG_NONE, &force, N_("Ignore nonexistent files, never prompt"), NULL },
32   { "empty", 0, 0, G_OPTION_ARG_NONE, &empty, N_("Empty the trash"), NULL },
33   { NULL }
34 };
35
36 static void
37 delete_trash_file (GFile *file, gboolean del_file, gboolean del_children)
38 {
39   GFileInfo *info;
40   GFile *child;
41   GFileEnumerator *enumerator;
42
43   g_return_if_fail (g_file_has_uri_scheme (file, "trash"));
44
45   if (del_children)
46     {
47       enumerator = g_file_enumerate_children (file,
48                                               G_FILE_ATTRIBUTE_STANDARD_NAME ","
49                                               G_FILE_ATTRIBUTE_STANDARD_TYPE,
50                                               G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
51                                               NULL,
52                                               NULL);
53       if (enumerator)
54         {
55           while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL)
56             {
57               child = g_file_get_child (file, g_file_info_get_name (info));
58
59               /* The g_file_delete operation works differently for locations
60                * provided by the trash backend as it prevents modifications of
61                * trashed items. For that reason, it is enough to call
62                * g_file_delete on top-level items only.
63                */
64               delete_trash_file (child, TRUE, FALSE);
65
66               g_object_unref (child);
67               g_object_unref (info);
68             }
69           g_file_enumerator_close (enumerator, NULL, NULL);
70           g_object_unref (enumerator);
71         }
72     }
73
74   if (del_file)
75     g_file_delete (file, NULL, NULL);
76 }
77
78 int
79 handle_trash (int argc, char *argv[], gboolean do_help)
80 {
81   GOptionContext *context;
82   gchar *param;
83   GError *error = NULL;
84   int retval = 0;
85   GFile *file;
86
87   g_set_prgname ("gio trash");
88
89   /* Translators: commandline placeholder */
90   param = g_strdup_printf ("[%s…]", _("LOCATION"));
91   context = g_option_context_new (param);
92   g_free (param);
93   g_option_context_set_help_enabled (context, FALSE);
94   g_option_context_set_summary (context,
95       _("Move files or directories to the trash."));
96   g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
97
98   if (do_help)
99     {
100       show_help (context, NULL);
101       g_option_context_free (context);
102       return 0;
103     }
104
105   if (!g_option_context_parse (context, &argc, &argv, &error))
106     {
107       show_help (context, error->message);
108       g_error_free (error);
109       g_option_context_free (context);
110       return 1;
111     }
112
113   if (argc > 1)
114     {
115       int i;
116
117       for (i = 1; i < argc; i++)
118         {
119           file = g_file_new_for_commandline_arg (argv[i]);
120           error = NULL;
121           if (!g_file_trash (file, NULL, &error))
122             {
123               if (!force ||
124                   !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
125                 {
126                   print_file_error (file, error->message);
127                   retval = 1;
128                 }
129               g_error_free (error);
130             }
131           g_object_unref (file);
132         }
133     }
134
135   if (empty)
136     {
137       GFile *file;
138       file = g_file_new_for_uri ("trash:");
139       delete_trash_file (file, FALSE, TRUE);
140       g_object_unref (file);
141     }
142
143   if (argc == 1 && !empty)
144     {
145       show_help (context, _("No locations given"));
146       g_option_context_free (context);
147       return 1;
148     }
149
150   g_option_context_free (context);
151
152   return retval;
153 }