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