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);
189 args = g_slist_append (args, g_strdup (entry->str));
190 entry = g_string_assign (entry, "");
193 g_string_append_c (entry, "//");
195 g_string_append_c (entry, *c);
198 } while (*c != '\0');
200 g_string_free (entry, TRUE);
202 for (walk = args; walk != NULL; walk = walk->next)
204 gchar *arg = (gchar *) walk->data;
205 prop = g_strsplit(arg, "=", 2);
206 g_debug ("arg = %s", arg);
208 if (g_strv_length (prop) == 2) {
209 if (strcmp (prop[0], "file") == 0) {
210 info->file_name = g_strdup (prop[1]);
211 } else if (strcmp (prop[0], "mux") == 0) {
212 info->mux = g_strdup (prop[1]);
213 } else if (strcmp (prop[0], "vcodec") == 0) {
214 info->vcodec = g_strdup (prop[1]);
215 } else if (strcmp (prop[0], "vbitrate") == 0) {
216 info->vbitrate = atoi (prop[1]);
217 } else if (strcmp (prop[0], "fps") == 0) {
218 info->fps = g_strtod (prop[1], NULL);
219 } else if (strcmp (prop[0], "acodec") == 0) {
220 info->acodec = g_strdup (prop[1]);
221 } else if (strcmp (prop[0], "abitrate") == 0) {
222 info->abitrate = atoi (prop[1]);
223 } else if (strcmp (prop[0], "width") == 0) {
224 info->width = atoi (prop[1]);
225 } else if (strcmp (prop[0], "height") == 0) {
226 info->height = atoi (prop[1]);
227 } else if (strcmp (prop[0], "opt") == 0) {
228 g_debug("DENTRO DE OPT: %s", arg);
229 //char* v = _parse_opt(walk);
230 info->opt = g_strdup (arg);
241 static GnomeVFSResult
242 do_open (GnomeVFSMethod *method,
243 GnomeVFSMethodHandle **method_handle,
245 GnomeVFSOpenMode mode,
246 GnomeVFSContext *context)
248 gmsHandle *handle = gmsHandle_new(uri);
251 args = _uri_parse_args (uri);
253 if (!gmyth_stream_client_connect (handle->stream,
254 gnome_vfs_uri_get_host_name (uri),
255 gnome_vfs_uri_get_host_port (uri))) {
257 return GNOME_VFS_ERROR_INVALID_FILENAME;
260 args = _uri_parse_args (uri);
262 gint ret = gmyth_stream_client_open_stream (handle->stream,
277 gmyth_stream_client_disconnect (handle->stream);
278 return GNOME_VFS_ERROR_INVALID_FILENAME;
281 handle->fd = gmyth_stream_client_play_stream (handle->stream);
283 if (handle->fd == -1) {
284 gmyth_stream_client_disconnect (handle->stream);
285 return GNOME_VFS_ERROR_INVALID_FILENAME;
288 *method_handle = (GnomeVFSMethodHandle *) handle;
292 static GnomeVFSResult
293 do_read (GnomeVFSMethod *method,
294 GnomeVFSMethodHandle *method_handle,
296 GnomeVFSFileSize bytes,
297 GnomeVFSFileSize *bytes_read,
298 GnomeVFSContext *context)
301 gint64 total_read = 0;
302 gmsHandle *handle = (gmsHandle *) method_handle;
304 total_read = recv(handle->fd, buffer, BUFFER_SIZE, 0);
305 *bytes_read = (GnomeVFSFileSize) total_read;
307 if (total_read < 0) return GNOME_VFS_ERROR_INTERNAL;
308 else return GNOME_VFS_OK;
312 static GnomeVFSResult
313 do_close (GnomeVFSMethod * method,
314 GnomeVFSMethodHandle * method_handle,
315 GnomeVFSContext * context)
317 gmsHandle *handle = (gmsHandle *) method_handle;
319 gmyth_stream_client_close_stream (handle->stream);
320 gmyth_stream_client_disconnect (handle->stream);
327 static GnomeVFSResult
328 do_get_file_info (GnomeVFSMethod * method,
330 GnomeVFSFileInfo * file_info,
331 GnomeVFSFileInfoOptions options,
332 GnomeVFSContext * context)
334 file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
335 GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
337 file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
339 file_info->permissions = GNOME_VFS_PERM_USER_READ |
340 GNOME_VFS_PERM_OTHER_READ |
341 GNOME_VFS_PERM_GROUP_READ;
347 static GnomeVFSResult
348 do_get_file_info_from_handle (GnomeVFSMethod *method,
349 GnomeVFSMethodHandle *method_handle,
350 GnomeVFSFileInfo *file_info,
351 GnomeVFSFileInfoOptions options,
352 GnomeVFSContext *context)
354 file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
355 GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
357 file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
359 file_info->permissions = GNOME_VFS_PERM_USER_READ |
360 GNOME_VFS_PERM_OTHER_READ |
361 GNOME_VFS_PERM_GROUP_READ;
368 do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri)