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 "giomodule.h" 27#include "giomodule-priv.h" 28#include "gvfs.h" 29#include <gio/gdummyfile.h> 30#include <sys/types.h> 31#ifdef HAVE_PWD_H 32#include <pwd.h> 33#endif 34#include <string.h> 35 36#include "gioalias.h" 37 38struct _GLocalVfs 39{ 40 GVfs parent; 41}; 42 43struct _GLocalVfsClass 44{ 45 GVfsClass parent_class; 46 47}; 48 49#define g_local_vfs_get_type _g_local_vfs_get_type 50G_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)) 56static void 57g_local_vfs_finalize (GObject *object) 58{ 59 /* must chain up */ 60 G_OBJECT_CLASS (g_local_vfs_parent_class)->finalize (object); 61} 62 63static void 64g_local_vfs_init (GLocalVfs *vfs) 65{ 66} 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 **/ 75GVfs * 76_g_local_vfs_new (void) 77{ 78 return g_object_new (G_TYPE_LOCAL_VFS, NULL); 79} 80 81static GFile * 82g_local_vfs_get_file_for_path (GVfs *vfs, 83 const char *path) 84{ 85 return _g_local_file_new (path); 86} 87 88static GFile * 89g_local_vfs_get_file_for_uri (GVfs *vfs, 90 const char *uri) 91{ 92 char *path; 93 GFile *file; 94 char *stripped_uri, *hash; 95 96 if (strchr (uri, '#') != NULL) 97 { 98 stripped_uri = g_strdup (uri); 99 hash = strchr (stripped_uri, '#'); 100 *hash = 0; 101 } 102 else 103 stripped_uri = (char *)uri; 104 105 path = g_filename_from_uri (stripped_uri, NULL, NULL); 106 107 if (stripped_uri != uri) 108 g_free (stripped_uri); 109 110 if (path != NULL) 111 file = _g_local_file_new (path); 112 else 113 file = _g_dummy_file_new (uri); 114 115 g_free (path); 116 117 return file; 118} 119 120static const gchar * const * 121g_local_vfs_get_supported_uri_schemes (GVfs *vfs) 122{ 123 static const gchar * uri_schemes[] = { "file", NULL }; 124 125 return uri_schemes; 126} 127 128static GFile * 129g_local_vfs_parse_name (GVfs *vfs, 130 const char *parse_name) 131{ 132 GFile *file; 133 char *filename; 134 char *user_prefix; 135 const char *user_start, *user_end; 136 char *rest; 137 138 g_return_val_if_fail (G_IS_VFS (vfs), NULL); 139 g_return_val_if_fail (parse_name != NULL, NULL); 140 141 if (g_ascii_strncasecmp ("file:", parse_name, 5) == 0) 142 filename = g_filename_from_uri (parse_name, NULL, NULL); 143 else 144 { 145 if (*parse_name == '~') 146 { 147 parse_name ++; 148 user_start = parse_name; 149 150 while (*parse_name != 0 && *parse_name != '/') 151 parse_name++; 152 153 user_end = parse_name; 154 155 if (user_end == user_start) 156 user_prefix = g_strdup (g_get_home_dir ()); 157 else 158 { 159#ifdef HAVE_PWD_H 160 struct passwd *passwd_file_entry; 161 char *user_name; 162 163 user_name = g_strndup (user_start, user_end - user_start); 164 passwd_file_entry = getpwnam (user_name); 165 g_free (user_name); 166 167 if (passwd_file_entry != NULL && 168 passwd_file_entry->pw_dir != NULL) 169 user_prefix = g_strdup (passwd_file_entry->pw_dir); 170 else 171#endif 172 user_prefix = g_strdup (g_get_home_dir ()); 173 } 174 175 rest = NULL; 176 if (*user_end != 0) 177 rest = g_filename_from_utf8 (user_end, -1, NULL, NULL, NULL); 178 179 filename = g_build_filename (user_prefix, rest, NULL); 180 g_free (rest); 181 g_free (user_prefix); 182 } 183 else 184 filename = g_filename_from_utf8 (parse_name, -1, NULL, NULL, NULL); 185 } 186 187 if (filename == NULL) 188 filename = g_strdup (parse_name); 189 190 file = _g_local_file_new (filename); 191 g_free (filename); 192 193 return file; 194} 195 196static gboolean 197g_local_vfs_is_active (GVfs *vfs) 198{ 199 return TRUE; 200} 201 202static void 203g_local_vfs_class_init (GLocalVfsClass *class) 204{ 205 GObjectClass *object_class; 206 GVfsClass *vfs_class; 207 208 object_class = (GObjectClass *) class; 209 210 object_class->finalize = g_local_vfs_finalize; 211 212 vfs_class = G_VFS_CLASS (class); 213 214 vfs_class->is_active = g_local_vfs_is_active; 215 vfs_class->get_file_for_path = g_local_vfs_get_file_for_path; 216 vfs_class->get_file_for_uri = g_local_vfs_get_file_for_uri; 217 vfs_class->get_supported_uri_schemes = g_local_vfs_get_supported_uri_schemes; 218 vfs_class->parse_name = g_local_vfs_parse_name; 219} 220