1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* pipe-method.c - pipe access method for GNOME Virtual File System
4 Copyright (C) 1999, 2000 Red Hat Inc.
6 The Gnome Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
11 The Gnome Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with the Gnome Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Author: Elliot Lee <sopwith@redhat.com> */
25 #include <glib/gstrfuncs.h>
26 #include <libgnomevfs/gnome-vfs-cancellation.h>
27 #include <libgnomevfs/gnome-vfs-context.h>
28 #include <libgnomevfs/gnome-vfs-method.h>
29 #include <libgnomevfs/gnome-vfs-mime.h>
30 #include <libgnomevfs/gnome-vfs-mime-utils.h>
31 #include <libgnomevfs/gnome-vfs-module-shared.h>
32 #include <libgnomevfs/gnome-vfs-module.h>
33 #include <libgnomevfs/gnome-vfs-utils.h>
41 typedef struct _FileHandle FileHandle;
44 file_handle_new (GnomeVFSURI *uri,
49 new = g_new (FileHandle, 1);
51 new->uri = gnome_vfs_uri_ref (uri);
58 file_handle_destroy (FileHandle *handle)
61 gnome_vfs_uri_unref (handle->uri);
66 str_without_suffix (const char *str)
68 const char *semicolon;
70 semicolon = strchr (str, ';');
72 return g_strndup (str, (semicolon == NULL) ? strlen (str) : semicolon - str);
76 mime_from_uri (const gchar *uri)
81 mime = uri == NULL ? NULL : strstr (uri, ";mime-type=");
83 result = str_without_suffix (mime + 11);
84 if (result[0] == '\0') {
85 /* No mime-type specified */
87 result = g_strdup (GNOME_VFS_MIME_TYPE_UNKNOWN);
90 result = g_strdup (GNOME_VFS_MIME_TYPE_UNKNOWN);
97 set_default_file_info (GnomeVFSFileInfo *file_info,
100 file_info->name = g_strdup (uri->text);
101 file_info->flags = GNOME_VFS_FILE_FLAGS_NONE;
102 file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
103 file_info->permissions = (GNOME_VFS_PERM_USER_READ
104 | GNOME_VFS_PERM_GROUP_READ
105 | GNOME_VFS_PERM_OTHER_READ);
107 file_info->valid_fields = (GNOME_VFS_FILE_INFO_FIELDS_FLAGS
108 | GNOME_VFS_FILE_INFO_FIELDS_TYPE
109 | GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS);
112 #define SAFE_POPEN_CHARACTERS "?'/. +:-_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
115 static GnomeVFSResult
116 do_open (GnomeVFSMethod *method,
117 GnomeVFSMethodHandle **method_handle,
119 GnomeVFSOpenMode mode,
120 GnomeVFSContext *context)
122 FileHandle *file_handle;
126 _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL);
127 _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL);
129 if (!(mode & GNOME_VFS_OPEN_READ))
130 return GNOME_VFS_ERROR_INVALID_OPEN_MODE;
132 real_uri = str_without_suffix (gnome_vfs_unescape_string (uri->text, ""));
134 /* Check that all the characters being passed to popen are "safe" */
135 /* If we allow just any characters through, it's easy to make URIs
136 * that make dangerous command lines here. If we prevent any
137 * interesting characters, then it's just simple parameters passed
138 * to the command that's the first thing passed in, which is much
140 * Without this "man:ls&shutdown -h now" would have undesired effects.
142 if (strspn (real_uri, SAFE_POPEN_CHARACTERS) != strlen (real_uri)) {
143 g_message ("real_uri is %s, has illegal chars, failing", real_uri);
145 return GNOME_VFS_ERROR_NOT_PERMITTED;
148 fh = popen (real_uri, "r");
152 return gnome_vfs_result_from_errno ();
154 file_handle = file_handle_new (uri, fh);
156 *method_handle = (GnomeVFSMethodHandle *) file_handle;
161 static GnomeVFSResult
162 do_close (GnomeVFSMethod *method,
163 GnomeVFSMethodHandle *method_handle,
164 GnomeVFSContext *context)
166 FileHandle *file_handle;
168 g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL);
170 file_handle = (FileHandle *) method_handle;
172 file_handle_destroy (file_handle);
177 static GnomeVFSResult
178 do_read (GnomeVFSMethod *method,
179 GnomeVFSMethodHandle *method_handle,
181 GnomeVFSFileSize num_bytes,
182 GnomeVFSFileSize *bytes_read,
183 GnomeVFSContext *context)
185 FileHandle *file_handle;
188 g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL);
190 file_handle = (FileHandle *) method_handle;
192 read_val = fread (buffer, 1, num_bytes, file_handle->fh);
196 return GNOME_VFS_ERROR_EOF;
198 *bytes_read = read_val;
203 static GnomeVFSResult
204 do_get_file_info (GnomeVFSMethod *method,
206 GnomeVFSFileInfo *file_info,
207 GnomeVFSFileInfoOptions options,
208 GnomeVFSContext *context)
210 set_default_file_info (file_info, uri);
212 file_info->mime_type = mime_from_uri (gnome_vfs_unescape_string (uri->text, ""));
213 file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE;
218 static GnomeVFSResult
219 do_get_file_info_from_handle (GnomeVFSMethod *method,
220 GnomeVFSMethodHandle *method_handle,
221 GnomeVFSFileInfo *file_info,
222 GnomeVFSFileInfoOptions options,
223 GnomeVFSContext *context)
227 handle = (FileHandle *) method_handle;
229 set_default_file_info (file_info, handle->uri);
231 file_info->mime_type = mime_from_uri (gnome_vfs_unescape_string (handle->uri->text, ""));
232 file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE;
238 is_local(GnomeVFSMethod *method,
239 const GnomeVFSURI *uri)
244 static GnomeVFSMethod method = {
245 sizeof (GnomeVFSMethod),
253 NULL, /* truncate_handle */
254 NULL, /* open_directory */
255 NULL, /* close_directory */
256 NULL, /* read_directory */
258 do_get_file_info_from_handle,
260 NULL, /* make_directory */
261 NULL, /* remove_directory */
264 NULL, /* check_same_fs */
265 NULL, /* set_file_info */
267 NULL, /* find_directory */
268 NULL /* create_symbolic_link */
272 vfs_module_init (const char *method_name, const char *args)
278 vfs_module_shutdown (GnomeVFSMethod *method)