Coverage Report

Created: 2025-06-13 06:20

/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
 * SPDX-License-Identifier: LGPL-2.1-or-later
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General
18
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
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 G_OS_UNIX
32
#include "glib-unix.h"
33
#include <pwd.h>
34
#endif
35
#include <string.h>
36
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
0
{
59
  /* must chain up */
60
0
  G_OBJECT_CLASS (g_local_vfs_parent_class)->finalize (object);
61
0
}
62
63
static void
64
g_local_vfs_init (GLocalVfs *vfs)
65
0
{
66
0
}
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
0
{
78
0
  return g_object_new (G_TYPE_LOCAL_VFS, NULL);
79
0
}
80
81
static GFile *
82
g_local_vfs_get_file_for_path (GVfs       *vfs,
83
                               const char *path)
84
0
{
85
0
  if (*path == '\0')
86
0
    return _g_dummy_file_new (path);
87
0
  else
88
0
    return _g_local_file_new (path);
89
0
}
90
91
static GFile *
92
g_local_vfs_get_file_for_uri (GVfs       *vfs,
93
                              const char *uri)
94
0
{
95
0
  char *path;
96
0
  GFile *file;
97
98
0
  path = g_filename_from_uri (uri, NULL, NULL);
99
100
0
  if (path != NULL)
101
0
    file = _g_local_file_new (path);
102
0
  else
103
0
    file = _g_dummy_file_new (uri);
104
105
0
  g_free (path);
106
107
0
  return file;
108
0
}
109
110
static const gchar * const *
111
g_local_vfs_get_supported_uri_schemes (GVfs *vfs)
112
0
{
113
0
  static const gchar * uri_schemes[] = { "file", NULL };
114
115
0
  return uri_schemes;
116
0
}
117
118
static GFile *
119
g_local_vfs_parse_name (GVfs       *vfs,
120
                        const char *parse_name)
121
0
{
122
0
  GFile *file;
123
0
  char *filename;
124
0
  char *user_prefix;
125
0
  const char *user_end;
126
0
  char *rest;
127
  
128
0
  g_return_val_if_fail (G_IS_VFS (vfs), NULL);
129
0
  g_return_val_if_fail (parse_name != NULL, NULL);
130
131
0
  if (g_ascii_strncasecmp ("file:", parse_name, 5) == 0)
132
0
    filename = g_filename_from_uri (parse_name, NULL, NULL);
133
0
  else
134
0
    {
135
0
      if (*parse_name == '~')
136
0
  {
137
0
#ifdef G_OS_UNIX
138
0
    const char *user_start;
139
0
    user_start = parse_name + 1;
140
0
#endif
141
0
    parse_name ++;
142
    
143
0
    while (*parse_name != 0 && *parse_name != '/')
144
0
      parse_name++;
145
    
146
0
    user_end = parse_name;
147
148
0
#ifdef G_OS_UNIX
149
0
    if (user_end == user_start)
150
0
      user_prefix = g_strdup (g_get_home_dir ());
151
0
    else
152
0
      {
153
0
              struct passwd *passwd_file_entry;
154
0
              char *user_name;
155
156
0
              user_name = g_strndup (user_start, user_end - user_start);
157
0
              passwd_file_entry = g_unix_get_passwd_entry (user_name, NULL);
158
0
              g_free (user_name);
159
160
0
              if (passwd_file_entry != NULL &&
161
0
                  passwd_file_entry->pw_dir != NULL)
162
0
                user_prefix = g_strdup (passwd_file_entry->pw_dir);
163
0
              else
164
0
                user_prefix = g_strdup (g_get_home_dir ());
165
166
0
              g_free (passwd_file_entry);
167
0
      }
168
#else
169
    user_prefix = g_strdup (g_get_home_dir ());
170
#endif
171
172
0
    rest = NULL;
173
0
    if (*user_end != 0)
174
0
      rest = g_filename_from_utf8 (user_end, -1, NULL, NULL, NULL);
175
    
176
0
    filename = g_build_filename (user_prefix, rest, NULL);
177
0
    g_free (rest);
178
0
    g_free (user_prefix);
179
0
  }
180
0
      else
181
0
  filename = g_filename_from_utf8 (parse_name, -1, NULL, NULL, NULL);
182
0
    }
183
  
184
0
  if (filename == NULL)
185
0
    filename = g_strdup (parse_name);
186
    
187
0
  file = _g_local_file_new (filename);
188
0
  g_free (filename);
189
190
0
  return file;
191
0
}
192
193
static gboolean
194
g_local_vfs_is_active (GVfs *vfs)
195
0
{
196
0
  return TRUE;
197
0
}
198
199
static void
200
g_local_vfs_class_init (GLocalVfsClass *class)
201
0
{
202
0
  GObjectClass *object_class;
203
0
  GVfsClass *vfs_class;
204
  
205
0
  object_class = (GObjectClass *) class;
206
207
0
  object_class->finalize = g_local_vfs_finalize;
208
209
0
  vfs_class = G_VFS_CLASS (class);
210
211
0
  vfs_class->is_active = g_local_vfs_is_active;
212
0
  vfs_class->get_file_for_path = g_local_vfs_get_file_for_path;
213
0
  vfs_class->get_file_for_uri = g_local_vfs_get_file_for_uri;
214
0
  vfs_class->get_supported_uri_schemes = g_local_vfs_get_supported_uri_schemes;
215
0
  vfs_class->parse_name = g_local_vfs_parse_name;
216
0
}