Register local vfs with prio 0.
[platform/upstream/glib.git] / gio / glocalvfs.c
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 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, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  */
22
23 #include <config.h>
24 #include "glocalvfs.h"
25 #include "glocalfile.h"
26 #include <gio/gdummyfile.h>
27 #include <sys/types.h>
28 #ifdef HAVE_PWD_H
29 #include <pwd.h>
30 #endif
31
32 #include "gioalias.h"
33
34 struct _GLocalVfs
35 {
36   GVfs parent;
37 };
38
39 struct _GLocalVfsClass
40 {
41   GVfsClass parent_class;
42   
43 };
44
45 #define g_local_vfs_get_type _g_local_vfs_get_type
46 G_DEFINE_TYPE_WITH_CODE (GLocalVfs, g_local_vfs, G_TYPE_VFS,
47                          g_io_extension_point_implement (G_VFS_EXTENSION_POINT_NAME,
48                                                          g_define_type_id,
49                                                          "local",
50                                                          0))
51 static void
52 g_local_vfs_finalize (GObject *object)
53 {
54   /* must chain up */
55   G_OBJECT_CLASS (g_local_vfs_parent_class)->finalize (object);
56 }
57
58 static void
59 g_local_vfs_init (GLocalVfs *vfs)
60 {
61 }
62
63 /**
64  * g_local_vfs_new:
65  *
66  * Returns a new #GVfs handle for a local vfs.
67  *
68  * Returns: a new #GVfs handle.
69  **/
70 GVfs *
71 _g_local_vfs_new (void)
72 {
73   return g_object_new (G_TYPE_LOCAL_VFS, NULL);
74 }
75
76 static GFile *
77 g_local_vfs_get_file_for_path (GVfs       *vfs,
78                                const char *path)
79 {
80   return _g_local_file_new (path);
81 }
82
83 static GFile *
84 g_local_vfs_get_file_for_uri (GVfs       *vfs,
85                               const char *uri)
86 {
87   char *path;
88   GFile *file;
89
90   path = g_filename_from_uri (uri, NULL, NULL);
91
92   if (path != NULL)
93     file = _g_local_file_new (path);
94   else
95     file = _g_dummy_file_new (uri);
96
97   g_free (path);
98
99   return file;
100 }
101
102 static const gchar * const *
103 g_local_vfs_get_supported_uri_schemes (GVfs *vfs)
104 {
105   static const gchar * uri_schemes[] = { "file", NULL };
106
107   return uri_schemes;
108 }
109
110 static GFile *
111 g_local_vfs_parse_name (GVfs       *vfs,
112                         const char *parse_name)
113 {
114   GFile *file;
115   char *filename;
116   char *user_name;
117   char *user_prefix;
118   const char *user_start, *user_end;
119   char *rest;
120   struct passwd *passwd_file_entry;
121   
122   g_return_val_if_fail (G_IS_VFS (vfs), NULL);
123   g_return_val_if_fail (parse_name != NULL, NULL);
124
125   if (g_ascii_strncasecmp ("file:", parse_name, 5) == 0)
126     filename = g_filename_from_uri (parse_name, NULL, NULL);
127   else
128     {
129       if (*parse_name == '~')
130         {
131           parse_name ++;
132           user_start = parse_name;
133           
134           while (*parse_name != 0 && *parse_name != '/')
135             parse_name++;
136           
137           user_end = parse_name;
138
139           if (user_end == user_start)
140             user_prefix = g_strdup (g_get_home_dir ());
141           else
142             {
143 #ifdef HAVE_PWD_H
144               user_name = g_strndup (user_start, user_end - user_start);
145               passwd_file_entry = getpwnam (user_name);
146               g_free (user_name);
147               
148               if (passwd_file_entry != NULL &&
149                   passwd_file_entry->pw_dir != NULL)
150                 user_prefix = g_strdup (passwd_file_entry->pw_dir);
151               else
152 #endif
153                 user_prefix = g_strdup (g_get_home_dir ());
154             }
155
156           rest = NULL;
157           if (*user_end != 0)
158             rest = g_filename_from_utf8 (user_end, -1, NULL, NULL, NULL);
159           
160           filename = g_build_filename (user_prefix, rest, NULL);
161           g_free (rest);
162           g_free (user_prefix);
163         }
164       else
165         filename = g_filename_from_utf8 (parse_name, -1, NULL, NULL, NULL);
166     }
167   
168   if (filename == NULL)
169     filename = g_strdup (parse_name);
170     
171   file = _g_local_file_new (filename);
172   g_free (filename);
173
174   return file;
175 }
176
177 static gboolean
178 g_local_vfs_is_active (GVfs *vfs)
179 {
180   return TRUE;
181 }
182
183 static void
184 g_local_vfs_class_init (GLocalVfsClass *class)
185 {
186   GObjectClass *object_class;
187   GVfsClass *vfs_class;
188   
189   object_class = (GObjectClass *) class;
190
191   object_class->finalize = g_local_vfs_finalize;
192
193   vfs_class = G_VFS_CLASS (class);
194
195   vfs_class->is_active = g_local_vfs_is_active;
196   vfs_class->get_file_for_path = g_local_vfs_get_file_for_path;
197   vfs_class->get_file_for_uri = g_local_vfs_get_file_for_uri;
198   vfs_class->get_supported_uri_schemes = g_local_vfs_get_supported_uri_schemes;
199   vfs_class->parse_name = g_local_vfs_parse_name;
200 }