| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | /* GIO - GLib Input, Output and Streaming Library
 | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * Copyright (C) 2006-2007 Red Hat, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2022-05-18 09:12:45 +01:00
										 |  |  |  * SPDX-License-Identifier: LGPL-2.1-or-later | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  * This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							| 
									
										
										
										
											2017-05-27 18:21:30 +02:00
										 |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Lesser General | 
					
						
							| 
									
										
										
										
											2014-01-23 12:58:29 +01:00
										 |  |  |  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Author: Alexander Larsson <alexl@redhat.com> | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 15:10:51 +00:00
										 |  |  | #include "config.h"
 | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | #include "glocalvfs.h"
 | 
					
						
							|  |  |  | #include "glocalfile.h"
 | 
					
						
							| 
									
										
										
										
											2008-01-29 00:00:31 +00:00
										 |  |  | #include "giomodule.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-27 15:22:11 +00:00
										 |  |  | #include "giomodule-priv.h"
 | 
					
						
							| 
									
										
										
										
											2008-07-01 06:32:35 +00:00
										 |  |  | #include "gvfs.h"
 | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | #include <gio/gdummyfile.h>
 | 
					
						
							|  |  |  | #include <sys/types.h>
 | 
					
						
							| 
									
										
										
											
												Require POSIX.1 (1990) compliance on unix
Assume unix platforms support the original POSIX.1 standard.
Specifically, assume that if G_OS_UNIX, then we have chown(),
getcwd(), getgrgid(), getpwuid(), link(), <grp.h>, <pwd.h>,
<sys/types.h>, <sys/uio.h>, <sys/wait.h>, and <unistd.h>.
Additionally, since all versions of Windows that we care about also
have <sys/types.h>, we can remove HAVE_SYS_TYPES_H checks everywhere.
Also remove one include of <sys/times.h>, and the corresponding
configure check, since the include is not currently needed (and may
always have just been a typo for <sys/time.h>).
https://bugzilla.gnome.org/show_bug.cgi?id=710519
											
										 
											2013-10-19 13:03:59 -04:00
										 |  |  | #ifdef G_OS_UNIX
 | 
					
						
							| 
									
										
										
										
											2019-02-19 14:09:22 +00:00
										 |  |  | #include "glib-unix.h"
 | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | #include <pwd.h>
 | 
					
						
							| 
									
										
										
										
											2007-12-03 22:37:44 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-03-03 19:02:16 +00:00
										 |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-28 12:39:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | struct _GLocalVfs | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GVfs parent; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct _GLocalVfsClass | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GVfsClass parent_class; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-28 16:01:59 +00:00
										 |  |  | #define g_local_vfs_get_type _g_local_vfs_get_type
 | 
					
						
							| 
									
										
										
										
											2008-01-28 21:06:10 +00:00
										 |  |  | G_DEFINE_TYPE_WITH_CODE (GLocalVfs, g_local_vfs, G_TYPE_VFS, | 
					
						
							| 
									
										
										
										
											2009-02-27 15:22:11 +00:00
										 |  |  | 			 _g_io_modules_ensure_extension_points_registered (); | 
					
						
							| 
									
										
										
										
											2008-01-28 21:06:10 +00:00
										 |  |  | 			 g_io_extension_point_implement (G_VFS_EXTENSION_POINT_NAME, | 
					
						
							|  |  |  | 							 g_define_type_id, | 
					
						
							|  |  |  | 							 "local", | 
					
						
							|  |  |  | 							 0)) | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | static void | 
					
						
							|  |  |  | g_local_vfs_finalize (GObject *object) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   /* must chain up */ | 
					
						
							|  |  |  |   G_OBJECT_CLASS (g_local_vfs_parent_class)->finalize (object); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_local_vfs_init (GLocalVfs *vfs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_local_vfs_new: | 
					
						
							| 
									
										
										
										
											2007-11-28 04:29:02 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Returns a new #GVfs handle for a local vfs. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns: a new #GVfs handle. | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |  **/ | 
					
						
							|  |  |  | GVfs * | 
					
						
							| 
									
										
										
										
											2007-11-28 16:01:59 +00:00
										 |  |  | _g_local_vfs_new (void) | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   return g_object_new (G_TYPE_LOCAL_VFS, NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static GFile * | 
					
						
							| 
									
										
										
										
											2007-11-30 05:11:25 +00:00
										 |  |  | g_local_vfs_get_file_for_path (GVfs       *vfs, | 
					
						
							|  |  |  |                                const char *path) | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-03-10 19:10:38 +00:00
										 |  |  |   if (*path == '\0') | 
					
						
							|  |  |  |     return _g_dummy_file_new (path); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     return _g_local_file_new (path); | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static GFile * | 
					
						
							| 
									
										
										
										
											2007-11-30 05:11:25 +00:00
										 |  |  | g_local_vfs_get_file_for_uri (GVfs       *vfs, | 
					
						
							|  |  |  |                               const char *uri) | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   char *path; | 
					
						
							|  |  |  |   GFile *file; | 
					
						
							| 
									
										
										
										
											2023-07-14 13:02:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-20 19:25:50 +01:00
										 |  |  |   path = g_filename_from_uri (uri, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (path != NULL) | 
					
						
							| 
									
										
										
										
											2007-11-28 16:01:59 +00:00
										 |  |  |     file = _g_local_file_new (path); | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2007-11-28 16:01:59 +00:00
										 |  |  |     file = _g_dummy_file_new (uri); | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   g_free (path); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return file; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const gchar * const * | 
					
						
							|  |  |  | g_local_vfs_get_supported_uri_schemes (GVfs *vfs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   static const gchar * uri_schemes[] = { "file", NULL }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return uri_schemes; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static GFile * | 
					
						
							|  |  |  | g_local_vfs_parse_name (GVfs       *vfs, | 
					
						
							| 
									
										
										
										
											2007-11-30 05:11:25 +00:00
										 |  |  |                         const char *parse_name) | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   GFile *file; | 
					
						
							|  |  |  |   char *filename; | 
					
						
							|  |  |  |   char *user_prefix; | 
					
						
							| 
									
										
										
										
											2018-04-25 16:07:59 +02:00
										 |  |  |   const char *user_end; | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |   char *rest; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_VFS (vfs), NULL); | 
					
						
							|  |  |  |   g_return_val_if_fail (parse_name != NULL, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (g_ascii_strncasecmp ("file:", parse_name, 5) == 0) | 
					
						
							|  |  |  |     filename = g_filename_from_uri (parse_name, NULL, NULL); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (*parse_name == '~') | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-04-25 16:07:59 +02:00
										 |  |  | #ifdef G_OS_UNIX
 | 
					
						
							|  |  |  | 	  const char *user_start; | 
					
						
							|  |  |  | 	  user_start = parse_name + 1; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | 	  parse_name ++; | 
					
						
							|  |  |  | 	   | 
					
						
							|  |  |  | 	  while (*parse_name != 0 && *parse_name != '/') | 
					
						
							|  |  |  | 	    parse_name++; | 
					
						
							|  |  |  | 	   | 
					
						
							|  |  |  | 	  user_end = parse_name; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-25 16:07:59 +02:00
										 |  |  | #ifdef G_OS_UNIX
 | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | 	  if (user_end == user_start) | 
					
						
							| 
									
										
										
										
											2008-01-21 14:02:19 +00:00
										 |  |  | 	    user_prefix = g_strdup (g_get_home_dir ()); | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | 	  else | 
					
						
							|  |  |  | 	    { | 
					
						
							| 
									
										
										
										
											2008-11-28 07:04:43 +00:00
										 |  |  |               struct passwd *passwd_file_entry; | 
					
						
							|  |  |  |               char *user_name; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-19 14:09:22 +00:00
										 |  |  |               user_name = g_strndup (user_start, user_end - user_start); | 
					
						
							|  |  |  |               passwd_file_entry = g_unix_get_passwd_entry (user_name, NULL); | 
					
						
							|  |  |  |               g_free (user_name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               if (passwd_file_entry != NULL && | 
					
						
							|  |  |  |                   passwd_file_entry->pw_dir != NULL) | 
					
						
							|  |  |  |                 user_prefix = g_strdup (passwd_file_entry->pw_dir); | 
					
						
							|  |  |  |               else | 
					
						
							|  |  |  |                 user_prefix = g_strdup (g_get_home_dir ()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               g_free (passwd_file_entry); | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2018-04-25 16:07:59 +02:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	  user_prefix = g_strdup (g_get_home_dir ()); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	  rest = NULL; | 
					
						
							|  |  |  | 	  if (*user_end != 0) | 
					
						
							|  |  |  | 	    rest = g_filename_from_utf8 (user_end, -1, NULL, NULL, NULL); | 
					
						
							|  |  |  | 	   | 
					
						
							|  |  |  | 	  filename = g_build_filename (user_prefix, rest, NULL); | 
					
						
							|  |  |  | 	  g_free (rest); | 
					
						
							|  |  |  | 	  g_free (user_prefix); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  | 	filename = g_filename_from_utf8 (parse_name, -1, NULL, NULL, NULL); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   if (filename == NULL) | 
					
						
							|  |  |  |     filename = g_strdup (parse_name); | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2007-11-28 16:01:59 +00:00
										 |  |  |   file = _g_local_file_new (filename); | 
					
						
							| 
									
										
										
										
											2007-11-26 16:13:05 +00:00
										 |  |  |   g_free (filename); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return file; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean | 
					
						
							|  |  |  | g_local_vfs_is_active (GVfs *vfs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_local_vfs_class_init (GLocalVfsClass *class) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GObjectClass *object_class; | 
					
						
							|  |  |  |   GVfsClass *vfs_class; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   object_class = (GObjectClass *) class; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   object_class->finalize = g_local_vfs_finalize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   vfs_class = G_VFS_CLASS (class); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   vfs_class->is_active = g_local_vfs_is_active; | 
					
						
							|  |  |  |   vfs_class->get_file_for_path = g_local_vfs_get_file_for_path; | 
					
						
							|  |  |  |   vfs_class->get_file_for_uri = g_local_vfs_get_file_for_uri; | 
					
						
							|  |  |  |   vfs_class->get_supported_uri_schemes = g_local_vfs_get_supported_uri_schemes; | 
					
						
							|  |  |  |   vfs_class->parse_name = g_local_vfs_parse_name; | 
					
						
							|  |  |  | } |