Branch data Line data Source code
1 : : /* GIO - GLib Input, Output and Streaming Library
2 : : *
3 : : * Copyright (C) 2006-2007 Red Hat, Inc.
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General
18 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 : : *
20 : : * Author: Alexander Larsson <alexl@redhat.com>
21 : : */
22 : :
23 : : #include "config.h"
24 : : #include "glocalvfs.h"
25 : : #include "glocalfile.h"
26 : : #include "giomodule.h"
27 : : #include "giomodule-priv.h"
28 : : #include "gvfs.h"
29 : : #include <gio/gdummyfile.h>
30 : : #include <sys/types.h>
31 : : #ifdef G_OS_UNIX
32 : : #include "glib-unix.h"
33 : : #include <pwd.h>
34 : : #endif
35 : : #include <string.h>
36 : :
37 : :
38 : : struct _GLocalVfs
39 : : {
40 : : GVfs parent;
41 : : };
42 : :
43 : : struct _GLocalVfsClass
44 : : {
45 : : GVfsClass parent_class;
46 : :
47 : : };
48 : :
49 : : #define g_local_vfs_get_type _g_local_vfs_get_type
50 : 271 : G_DEFINE_TYPE_WITH_CODE (GLocalVfs, g_local_vfs, G_TYPE_VFS,
51 : : _g_io_modules_ensure_extension_points_registered ();
52 : : g_io_extension_point_implement (G_VFS_EXTENSION_POINT_NAME,
53 : : g_define_type_id,
54 : : "local",
55 : : 0))
56 : : static void
57 : 0 : g_local_vfs_finalize (GObject *object)
58 : : {
59 : : /* must chain up */
60 : 0 : G_OBJECT_CLASS (g_local_vfs_parent_class)->finalize (object);
61 : 0 : }
62 : :
63 : : static void
64 : 33 : g_local_vfs_init (GLocalVfs *vfs)
65 : : {
66 : 33 : }
67 : :
68 : : /**
69 : : * g_local_vfs_new:
70 : : *
71 : : * Returns a new #GVfs handle for a local vfs.
72 : : *
73 : : * Returns: a new #GVfs handle.
74 : : **/
75 : : GVfs *
76 : 1 : _g_local_vfs_new (void)
77 : : {
78 : 1 : return g_object_new (G_TYPE_LOCAL_VFS, NULL);
79 : : }
80 : :
81 : : static GFile *
82 : 405 : g_local_vfs_get_file_for_path (GVfs *vfs,
83 : : const char *path)
84 : : {
85 : 405 : if (*path == '\0')
86 : 1 : return _g_dummy_file_new (path);
87 : : else
88 : 404 : return _g_local_file_new (path);
89 : : }
90 : :
91 : : static GFile *
92 : 282 : g_local_vfs_get_file_for_uri (GVfs *vfs,
93 : : const char *uri)
94 : : {
95 : : char *path;
96 : : GFile *file;
97 : :
98 : 282 : path = g_filename_from_uri (uri, NULL, NULL);
99 : :
100 : 282 : if (path != NULL)
101 : 247 : file = _g_local_file_new (path);
102 : : else
103 : 35 : file = _g_dummy_file_new (uri);
104 : :
105 : 282 : g_free (path);
106 : :
107 : 282 : return file;
108 : : }
109 : :
110 : : static const gchar * const *
111 : 3 : g_local_vfs_get_supported_uri_schemes (GVfs *vfs)
112 : : {
113 : : static const gchar * uri_schemes[] = { "file", NULL };
114 : :
115 : 3 : return uri_schemes;
116 : : }
117 : :
118 : : static GFile *
119 : 6 : g_local_vfs_parse_name (GVfs *vfs,
120 : : const char *parse_name)
121 : : {
122 : : GFile *file;
123 : : char *filename;
124 : : char *user_prefix;
125 : : const char *user_end;
126 : : char *rest;
127 : :
128 : 6 : g_return_val_if_fail (G_IS_VFS (vfs), NULL);
129 : 6 : g_return_val_if_fail (parse_name != NULL, NULL);
130 : :
131 : 6 : if (g_ascii_strncasecmp ("file:", parse_name, 5) == 0)
132 : 1 : filename = g_filename_from_uri (parse_name, NULL, NULL);
133 : : else
134 : : {
135 : 5 : if (*parse_name == '~')
136 : : {
137 : : #ifdef G_OS_UNIX
138 : : const char *user_start;
139 : 1 : user_start = parse_name + 1;
140 : : #endif
141 : 1 : parse_name ++;
142 : :
143 : 4 : while (*parse_name != 0 && *parse_name != '/')
144 : 3 : parse_name++;
145 : :
146 : 1 : user_end = parse_name;
147 : :
148 : : #ifdef G_OS_UNIX
149 : 1 : if (user_end == user_start)
150 : 0 : user_prefix = g_strdup (g_get_home_dir ());
151 : : else
152 : : {
153 : : struct passwd *passwd_file_entry;
154 : : char *user_name;
155 : :
156 : 1 : user_name = g_strndup (user_start, user_end - user_start);
157 : 1 : passwd_file_entry = g_unix_get_passwd_entry (user_name, NULL);
158 : 1 : g_free (user_name);
159 : :
160 : 1 : if (passwd_file_entry != NULL &&
161 : 0 : passwd_file_entry->pw_dir != NULL)
162 : 0 : user_prefix = g_strdup (passwd_file_entry->pw_dir);
163 : : else
164 : 2 : user_prefix = g_strdup (g_get_home_dir ());
165 : :
166 : 1 : g_free (passwd_file_entry);
167 : : }
168 : : #else
169 : : user_prefix = g_strdup (g_get_home_dir ());
170 : : #endif
171 : :
172 : 1 : rest = NULL;
173 : 1 : if (*user_end != 0)
174 : 0 : rest = g_filename_from_utf8 (user_end, -1, NULL, NULL, NULL);
175 : :
176 : 1 : filename = g_build_filename (user_prefix, rest, NULL);
177 : 1 : g_free (rest);
178 : 1 : g_free (user_prefix);
179 : : }
180 : : else
181 : 4 : filename = g_filename_from_utf8 (parse_name, -1, NULL, NULL, NULL);
182 : : }
183 : :
184 : 6 : if (filename == NULL)
185 : 0 : filename = g_strdup (parse_name);
186 : :
187 : 6 : file = _g_local_file_new (filename);
188 : 6 : g_free (filename);
189 : :
190 : 6 : return file;
191 : : }
192 : :
193 : : static gboolean
194 : 35 : g_local_vfs_is_active (GVfs *vfs)
195 : : {
196 : 35 : return TRUE;
197 : : }
198 : :
199 : : static void
200 : 32 : g_local_vfs_class_init (GLocalVfsClass *class)
201 : : {
202 : : GObjectClass *object_class;
203 : : GVfsClass *vfs_class;
204 : :
205 : 32 : object_class = (GObjectClass *) class;
206 : :
207 : 32 : object_class->finalize = g_local_vfs_finalize;
208 : :
209 : 32 : vfs_class = G_VFS_CLASS (class);
210 : :
211 : 32 : vfs_class->is_active = g_local_vfs_is_active;
212 : 32 : vfs_class->get_file_for_path = g_local_vfs_get_file_for_path;
213 : 32 : vfs_class->get_file_for_uri = g_local_vfs_get_file_for_uri;
214 : 32 : vfs_class->get_supported_uri_schemes = g_local_vfs_get_supported_uri_schemes;
215 : 32 : vfs_class->parse_name = g_local_vfs_parse_name;
216 : 32 : }
|