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)
158 char* _parse_opt(char* opt)
160 char** list = g_strsplit(opt, "opt=", 2);
161 char** opts = g_strsplit(list[1], "+", 32);
166 for (aux = opts[0]; aux != NULL; aux = opts[++i])
167 value = g_strdup_printf("%s %s", value, aux);
176 _uri_parse_args (const GnomeVFSURI *uri)
178 gchar *file = gnome_vfs_unescape_string (uri->text, NULL);
179 gchar **lst = g_strsplit (file, "?", 0);
180 UriArgs *info = g_new0 (UriArgs, 1);
184 prop = g_strsplit_set(lst[0], "/=", 3);
186 info->file_name = g_strdup_printf ("%s://%s",\
191 for (walk = lst[1]; walk != NULL; walk = lst[++i])
193 prop = g_strsplit(walk, "=", 2);
195 if (g_strv_length (prop) == 2) {
196 if (strcmp (prop[0], "mux") == 0) {
197 info->mux = g_strdup (prop[1]);
198 } else if (strcmp (prop[0], "vcodec") == 0) {
199 info->vcodec = g_strdup (prop[1]);
200 } else if (strcmp (prop[0], "vbitrate") == 0) {
201 info->vbitrate = atoi (prop[1]);
202 } else if (strcmp (prop[0], "fps") == 0) {
203 info->fps = g_strtod (prop[1], NULL);
204 } else if (strcmp (prop[0], "acodec") == 0) {
205 info->acodec = g_strdup (prop[1]);
206 } else if (strcmp (prop[0], "abitrate") == 0) {
207 info->abitrate = atoi (prop[1]);
208 } else if (strcmp (prop[0], "width") == 0) {
209 info->width = atoi (prop[1]);
210 } else if (strcmp (prop[0], "height") == 0) {
211 info->height = atoi (prop[1]);
212 } else if (strcmp (prop[0], "opt") == 0) {
213 g_debug("DENTRO DE OPT: %s", walk);
214 char* v = _parse_opt(walk);
215 info->opt = g_strdup (v);
226 static GnomeVFSResult
227 do_open (GnomeVFSMethod *method,
228 GnomeVFSMethodHandle **method_handle,
230 GnomeVFSOpenMode mode,
231 GnomeVFSContext *context)
233 gmsHandle *handle = gmsHandle_new(uri);
236 if (!gmyth_stream_client_connect (handle->stream,
237 gnome_vfs_uri_get_host_name (uri),
238 gnome_vfs_uri_get_host_port (uri))) {
240 return GNOME_VFS_ERROR_INVALID_FILENAME;
243 args = _uri_parse_args (uri);
245 gint ret = gmyth_stream_client_open_stream (handle->stream,
260 gmyth_stream_client_disconnect (handle->stream);
261 return GNOME_VFS_ERROR_INVALID_FILENAME;
264 handle->fd = gmyth_stream_client_play_stream (handle->stream);
266 if (handle->fd == -1) {
267 gmyth_stream_client_disconnect (handle->stream);
268 return GNOME_VFS_ERROR_INVALID_FILENAME;
271 *method_handle = (GnomeVFSMethodHandle *) handle;
275 static GnomeVFSResult
276 do_read (GnomeVFSMethod *method,
277 GnomeVFSMethodHandle *method_handle,
279 GnomeVFSFileSize bytes,
280 GnomeVFSFileSize *bytes_read,
281 GnomeVFSContext *context)
284 gint64 total_read = 0;
285 gmsHandle *handle = (gmsHandle *) method_handle;
287 total_read = recv(handle->fd, buffer, BUFFER_SIZE, 0);
288 *bytes_read = (GnomeVFSFileSize) total_read;
290 if (total_read < 0) return GNOME_VFS_ERROR_INTERNAL;
291 else return GNOME_VFS_OK;
295 static GnomeVFSResult
296 do_close (GnomeVFSMethod * method,
297 GnomeVFSMethodHandle * method_handle,
298 GnomeVFSContext * context)
300 gmsHandle *handle = (gmsHandle *) method_handle;
302 gmyth_stream_client_close_stream (handle->stream);
303 gmyth_stream_client_disconnect (handle->stream);
310 static GnomeVFSResult
311 do_get_file_info (GnomeVFSMethod * method,
313 GnomeVFSFileInfo * file_info,
314 GnomeVFSFileInfoOptions options,
315 GnomeVFSContext * context)
317 file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
318 GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
320 file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
322 file_info->permissions = GNOME_VFS_PERM_USER_READ |
323 GNOME_VFS_PERM_OTHER_READ |
324 GNOME_VFS_PERM_GROUP_READ;
330 static GnomeVFSResult
331 do_get_file_info_from_handle (GnomeVFSMethod *method,
332 GnomeVFSMethodHandle *method_handle,
333 GnomeVFSFileInfo *file_info,
334 GnomeVFSFileInfoOptions options,
335 GnomeVFSContext *context)
337 file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
338 GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
340 file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
342 file_info->permissions = GNOME_VFS_PERM_USER_READ |
343 GNOME_VFS_PERM_OTHER_READ |
344 GNOME_VFS_PERM_GROUP_READ;
351 do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri)