2 * @author Artur Duque de Souza <souza.artur@indt.org.br>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 m * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
24 #include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
25 #include <stdlib.h> /* for atoi() and exit() */
26 #include <string.h> /* for memset() */
27 #include <unistd.h> /* for close() */
31 #include <glib/gprintf.h>
32 #include <glib/gstdio.h>
33 #include <gmyth-stream-client.h>
35 #include <libgnomevfs/gnome-vfs-module.h>
36 #include <libgnomevfs/gnome-vfs-utils.h>
38 #define BUFFER_SIZE 4096
44 GMythStreamClient *stream;
63 static gmsHandle* gmsHandle_new(GnomeVFSURI *uri);
66 do_open (GnomeVFSMethod *method,
67 GnomeVFSMethodHandle **method_handle,
69 GnomeVFSOpenMode mode,
70 GnomeVFSContext *context);
73 do_read (GnomeVFSMethod *method,
74 GnomeVFSMethodHandle *method_handle,
76 GnomeVFSFileSize bytes,
77 GnomeVFSFileSize *bytes_read,
78 GnomeVFSContext *context);
81 do_close (GnomeVFSMethod * method,
82 GnomeVFSMethodHandle * method_handle,
83 GnomeVFSContext * context);
86 do_get_file_info (GnomeVFSMethod * method,
88 GnomeVFSFileInfo * file_info,
89 GnomeVFSFileInfoOptions options,
90 GnomeVFSContext * context);
94 do_get_file_info_from_handle (GnomeVFSMethod *method,
95 GnomeVFSMethodHandle *method_handle,
96 GnomeVFSFileInfo *file_info,
97 GnomeVFSFileInfoOptions options,
98 GnomeVFSContext *context);
102 do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri);
105 static gmsHandle* gmsHandle_new(GnomeVFSURI *uri)
107 gmsHandle* handler = (gmsHandle*)g_malloc0(sizeof(gmsHandle));
109 handler->hostname = (gchar*)gnome_vfs_uri_get_host_name(uri);
110 handler->port = gnome_vfs_uri_get_host_port(uri);
111 handler->stream = gmyth_stream_client_new ();
116 static GnomeVFSMethod method = {
117 sizeof (GnomeVFSMethod),
120 do_close, /* close */
125 NULL, /* truncate_handle */
126 NULL, /* open_directory */
127 NULL, /* close_directory */
128 NULL, /* read_directory */
129 do_get_file_info, /* get_file_info */
130 do_get_file_info_from_handle, /* get_file_info_from_handle */
131 do_is_local, /* is_local */
132 NULL, /* make_directory */
133 NULL, /* remove_directory */
136 NULL, /* check_same_fs */
137 NULL, /* set_file_info */
139 NULL, /* find_directory */
140 NULL, /* create_symbolic_link */
141 NULL, /* monitor_add */
142 NULL, /* monitor_cancel */
143 NULL /* file_control */
147 vfs_module_init (const char *method_name, const char *args)
153 vfs_module_shutdown (GnomeVFSMethod* method)
159 _uri_parse_args (const GnomeVFSURI *uri)
163 UriArgs *info = g_new0 (UriArgs, 1);
167 gboolean open = FALSE;
170 gchar *uri_str = gnome_vfs_uri_to_string (uri,
171 GNOME_VFS_URI_HIDE_USER_NAME |
172 GNOME_VFS_URI_HIDE_PASSWORD |
173 GNOME_VFS_URI_HIDE_HOST_NAME |
174 GNOME_VFS_URI_HIDE_HOST_PORT |
175 GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD);
177 file = gnome_vfs_unescape_string (uri_str, "");
179 entry = g_string_new ("");
182 if ((*c == '\"') || (*c == '\'')) {
186 if (((*c == '?') || (c[1] == '\0')) && !open) {
188 g_string_append_c (entry, *c);
190 args = g_slist_append (args, g_strdup (entry->str));
191 entry = g_string_assign (entry, "");
193 g_string_append_c (entry, *c);
196 } while (*c != '\0');
198 g_string_free (entry, TRUE);
200 for (walk = args; walk != NULL; walk = walk->next)
202 gchar *arg = (gchar *) walk->data;
203 prop = g_strsplit(arg, "=", 2);
204 g_debug ("arg = %s", arg);
206 if (g_strv_length (prop) == 2) {
207 if (strcmp (prop[0], "file") == 0) {
208 info->file_name = g_strdup (prop[1]);
209 } else if (strcmp (prop[0], "mux") == 0) {
210 info->mux = g_strdup (prop[1]);
211 } else if (strcmp (prop[0], "vcodec") == 0) {
212 info->vcodec = g_strdup (prop[1]);
213 } else if (strcmp (prop[0], "vbitrate") == 0) {
214 info->vbitrate = atoi (prop[1]);
215 } else if (strcmp (prop[0], "fps") == 0) {
216 info->fps = g_strtod (prop[1], NULL);
217 } else if (strcmp (prop[0], "acodec") == 0) {
218 info->acodec = g_strdup (prop[1]);
219 } else if (strcmp (prop[0], "abitrate") == 0) {
220 info->abitrate = atoi (prop[1]);
221 } else if (strcmp (prop[0], "width") == 0) {
222 info->width = atoi (prop[1]);
223 } else if (strcmp (prop[0], "height") == 0) {
224 info->height = atoi (prop[1]);
225 } else if (strcmp (prop[0], "opt") == 0) {
226 g_debug("DENTRO DE OPT: %s", arg);
227 //char* v = _parse_opt(walk);
228 info->opt = g_strdup (arg);
239 static GnomeVFSResult
240 do_open (GnomeVFSMethod *method,
241 GnomeVFSMethodHandle **method_handle,
243 GnomeVFSOpenMode mode,
244 GnomeVFSContext *context)
246 gmsHandle *handle = gmsHandle_new(uri);
249 args = _uri_parse_args (uri);
251 if (!gmyth_stream_client_connect (handle->stream,
252 gnome_vfs_uri_get_host_name (uri),
253 gnome_vfs_uri_get_host_port (uri))) {
255 return GNOME_VFS_ERROR_INVALID_FILENAME;
258 args = _uri_parse_args (uri);
260 gint ret = gmyth_stream_client_open_stream (handle->stream,
275 gmyth_stream_client_disconnect (handle->stream);
276 return GNOME_VFS_ERROR_INVALID_FILENAME;
279 handle->fd = gmyth_stream_client_play_stream (handle->stream);
281 if (handle->fd == -1) {
282 gmyth_stream_client_disconnect (handle->stream);
283 return GNOME_VFS_ERROR_INVALID_FILENAME;
286 *method_handle = (GnomeVFSMethodHandle *) handle;
290 static GnomeVFSResult
291 do_read (GnomeVFSMethod *method,
292 GnomeVFSMethodHandle *method_handle,
294 GnomeVFSFileSize bytes,
295 GnomeVFSFileSize *bytes_read,
296 GnomeVFSContext *context)
299 gint64 total_read = 0;
300 gmsHandle *handle = (gmsHandle *) method_handle;
302 total_read = recv(handle->fd, buffer, BUFFER_SIZE, 0);
303 *bytes_read = (GnomeVFSFileSize) total_read;
305 if (total_read < 0) return GNOME_VFS_ERROR_INTERNAL;
306 else return GNOME_VFS_OK;
310 static GnomeVFSResult
311 do_close (GnomeVFSMethod * method,
312 GnomeVFSMethodHandle * method_handle,
313 GnomeVFSContext * context)
315 gmsHandle *handle = (gmsHandle *) method_handle;
317 gmyth_stream_client_close_stream (handle->stream);
318 gmyth_stream_client_disconnect (handle->stream);
325 static GnomeVFSResult
326 do_get_file_info (GnomeVFSMethod * method,
328 GnomeVFSFileInfo * file_info,
329 GnomeVFSFileInfoOptions options,
330 GnomeVFSContext * context)
332 file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
333 GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
335 file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
337 file_info->permissions = GNOME_VFS_PERM_USER_READ |
338 GNOME_VFS_PERM_OTHER_READ |
339 GNOME_VFS_PERM_GROUP_READ;
345 static GnomeVFSResult
346 do_get_file_info_from_handle (GnomeVFSMethod *method,
347 GnomeVFSMethodHandle *method_handle,
348 GnomeVFSFileInfo *file_info,
349 GnomeVFSFileInfoOptions options,
350 GnomeVFSContext *context)
352 file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
353 GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
355 file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
357 file_info->permissions = GNOME_VFS_PERM_USER_READ |
358 GNOME_VFS_PERM_OTHER_READ |
359 GNOME_VFS_PERM_GROUP_READ;
366 do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri)