Coverage Report

Created: 2025-07-01 07:09

/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
}