Home | History | Annotate | Download | only in gio
      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 (at) 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 
     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 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 g_local_vfs_finalize (GObject *object)
     58 {
     59   /* must chain up */
     60   G_OBJECT_CLASS (g_local_vfs_parent_class)->finalize (object);
     61 }
     62 
     63 static void
     64 g_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  **/
     75 GVfs *
     76 _g_local_vfs_new (void)
     77 {
     78   return g_object_new (G_TYPE_LOCAL_VFS, NULL);
     79 }
     80 
     81 static GFile *
     82 g_local_vfs_get_file_for_path (GVfs       *vfs,
     83                                const char *path)
     84 {
     85   return _g_local_file_new (path);
     86 }
     87 
     88 static GFile *
     89 g_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 
    120 static const gchar * const *
    121 g_local_vfs_get_supported_uri_schemes (GVfs *vfs)
    122 {
    123   static const gchar * uri_schemes[] = { "file", NULL };
    124 
    125   return uri_schemes;
    126 }
    127 
    128 static GFile *
    129 g_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 
    196 static gboolean
    197 g_local_vfs_is_active (GVfs *vfs)
    198 {
    199   return TRUE;
    200 }
    201 
    202 static void
    203 g_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