2 * Copyright 2015 Red Hat, Inc.
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.
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.
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/>.
17 * Author: Matthias Clasen <mclasen@redhat.com>
28 static gboolean show_hidden
= FALSE
;
29 static gboolean follow_symlinks
= FALSE
;
31 static const GOptionEntry entries
[] = {
32 { "hidden", 'h', 0, G_OPTION_ARG_NONE
, &show_hidden
, N_("Show hidden files"), NULL
},
33 { "follow-symlinks", 'l', 0, G_OPTION_ARG_NONE
, &follow_symlinks
, N_("Follow symbolic links, mounts and shortcuts"), NULL
},
38 sort_info_by_name (GFileInfo
*a
, GFileInfo
*b
)
43 na
= g_file_info_get_name (a
);
44 nb
= g_file_info_get_name (b
);
51 return strcmp (na
, nb
);
55 do_tree (GFile
*f
, int level
, guint64 pattern
)
57 GFileEnumerator
*enumerator
;
62 info
= g_file_query_info (f
,
63 G_FILE_ATTRIBUTE_STANDARD_TYPE
","
64 G_FILE_ATTRIBUTE_STANDARD_TARGET_URI
,
69 if (g_file_info_get_attribute_uint32 (info
, G_FILE_ATTRIBUTE_STANDARD_TYPE
) == G_FILE_TYPE_MOUNTABLE
)
71 /* don't process mountables; we avoid these by getting the target_uri below */
72 g_object_unref (info
);
75 g_object_unref (info
);
78 enumerator
= g_file_enumerate_children (f
,
79 G_FILE_ATTRIBUTE_STANDARD_NAME
","
80 G_FILE_ATTRIBUTE_STANDARD_TYPE
","
81 G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN
","
82 G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK
","
83 G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET
","
84 G_FILE_ATTRIBUTE_STANDARD_TARGET_URI
,
88 if (enumerator
!= NULL
)
94 while ((info
= g_file_enumerator_next_file (enumerator
, NULL
, NULL
)) != NULL
)
96 if (g_file_info_get_is_hidden (info
) && !show_hidden
)
98 g_object_unref (info
);
102 info_list
= g_list_prepend (info_list
, info
);
105 g_file_enumerator_close (enumerator
, NULL
, NULL
);
107 info_list
= g_list_sort (info_list
, (GCompareFunc
) sort_info_by_name
);
109 for (l
= info_list
; l
!= NULL
; l
= l
->next
)
112 const char *target_uri
;
114 gboolean is_last_item
;
117 is_last_item
= (l
->next
== NULL
);
119 name
= g_file_info_get_name (info
);
120 type
= g_file_info_get_attribute_uint32 (info
, G_FILE_ATTRIBUTE_STANDARD_TYPE
);
124 for (n
= 0; n
< level
; n
++)
126 if (pattern
& (1<<n
))
138 g_print ("`-- %s", name
);
142 g_print ("|-- %s", name
);
145 target_uri
= g_file_info_get_attribute_string (info
, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI
);
146 if (target_uri
!= NULL
)
148 g_print (" -> %s", target_uri
);
152 if (g_file_info_get_is_symlink (info
))
155 target
= g_file_info_get_symlink_target (info
);
156 g_print (" -> %s", target
);
162 if ((type
& G_FILE_TYPE_DIRECTORY
) &&
163 (follow_symlinks
|| !g_file_info_get_is_symlink (info
)))
169 new_pattern
= pattern
;
171 new_pattern
= pattern
| (1<<level
);
174 if (target_uri
!= NULL
)
177 child
= g_file_new_for_uri (target_uri
);
181 child
= g_file_get_child (f
, name
);
186 do_tree (child
, level
+ 1, new_pattern
);
187 g_object_unref (child
);
191 g_object_unref (info
);
193 g_list_free (info_list
);
197 for (n
= 0; n
< level
; n
++)
199 if (pattern
& (1<<n
))
209 g_print (" [%s]\n", error
->message
);
211 g_error_free (error
);
220 uri
= g_file_get_uri (f
);
221 g_print ("%s\n", uri
);
228 handle_tree (int argc
, char *argv
[], gboolean do_help
)
230 GOptionContext
*context
;
231 GError
*error
= NULL
;
236 g_set_prgname ("gio tree");
238 /* Translators: commandline placeholder */
239 param
= g_strdup_printf ("[%s…]", _("LOCATION"));
240 context
= g_option_context_new (param
);
242 g_option_context_set_help_enabled (context
, FALSE
);
243 g_option_context_set_summary (context
,
244 _("List contents of directories in a tree-like format."));
245 g_option_context_add_main_entries (context
, entries
, GETTEXT_PACKAGE
);
249 show_help (context
, NULL
);
250 g_option_context_free (context
);
254 g_option_context_parse (context
, &argc
, &argv
, &error
);
258 show_help (context
, error
->message
);
259 g_error_free (error
);
260 g_option_context_free (context
);
264 g_option_context_free (context
);
268 for (i
= 1; i
< argc
; i
++)
270 file
= g_file_new_for_commandline_arg (argv
[i
]);
272 g_object_unref (file
);
279 cwd
= g_get_current_dir ();
280 file
= g_file_new_for_path (cwd
);
283 g_object_unref (file
);