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, "");
180 entry = g_string_new ("");
183 if ((*c == '\"') || (*c == '\'')) {
187 if (((*c == '?') || (c + 1 == '\0')) && !open) {
188 args = g_slist_append (args, g_strdup (entry->str));
189 entry = g_string_assign (entry, "");
192 g_string_append (entry, "//");
194 g_string_append_c (entry, *c);
197 } while (*c != '\0');
199 g_string_free (entry, TRUE);
201 for (walk = args; walk != NULL; walk = walk->next)
203 gchar *arg = (gchar *) walk->data;
204 prop = g_strsplit(arg, "=", 2);
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 if (!gmyth_stream_client_connect (handle->stream,
250 gnome_vfs_uri_get_host_name (uri),
251 gnome_vfs_uri_get_host_port (uri))) {
253 return GNOME_VFS_ERROR_INVALID_FILENAME;
256 args = _uri_parse_args (uri);
258 gint ret = gmyth_stream_client_open_stream (handle->stream,
273 gmyth_stream_client_disconnect (handle->stream);
274 return GNOME_VFS_ERROR_INVALID_FILENAME;
277 handle->fd = gmyth_stream_client_play_stream (handle->stream);
279 if (handle->fd == -1) {
280 gmyth_stream_client_disconnect (handle->stream);
281 return GNOME_VFS_ERROR_INVALID_FILENAME;
284 *method_handle = (GnomeVFSMethodHandle *) handle;
288 static GnomeVFSResult
289 do_read (GnomeVFSMethod *method,
290 GnomeVFSMethodHandle *method_handle,
292 GnomeVFSFileSize bytes,
293 GnomeVFSFileSize *bytes_read,
294 GnomeVFSContext *context)
297 gint64 total_read = 0;
298 gmsHandle *handle = (gmsHandle *) method_handle;
300 total_read = recv(handle->fd, buffer, BUFFER_SIZE, 0);
301 *bytes_read = (GnomeVFSFileSize) total_read;
303 if (total_read < 0) return GNOME_VFS_ERROR_INTERNAL;
304 else return GNOME_VFS_OK;
308 static GnomeVFSResult
309 do_close (GnomeVFSMethod * method,
310 GnomeVFSMethodHandle * method_handle,
311 GnomeVFSContext * context)
313 gmsHandle *handle = (gmsHandle *) method_handle;
315 gmyth_stream_client_close_stream (handle->stream);
316 gmyth_stream_client_disconnect (handle->stream);
323 static GnomeVFSResult
324 do_get_file_info (GnomeVFSMethod * method,
326 GnomeVFSFileInfo * file_info,
327 GnomeVFSFileInfoOptions options,
328 GnomeVFSContext * context)
330 file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
331 GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
333 file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
335 file_info->permissions = GNOME_VFS_PERM_USER_READ |
336 GNOME_VFS_PERM_OTHER_READ |
337 GNOME_VFS_PERM_GROUP_READ;
343 static GnomeVFSResult
344 do_get_file_info_from_handle (GnomeVFSMethod *method,
345 GnomeVFSMethodHandle *method_handle,
346 GnomeVFSFileInfo *file_info,
347 GnomeVFSFileInfoOptions options,
348 GnomeVFSContext *context)
350 file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
351 GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
353 file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
355 file_info->permissions = GNOME_VFS_PERM_USER_READ |
356 GNOME_VFS_PERM_OTHER_READ |
357 GNOME_VFS_PERM_GROUP_READ;
364 do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri)