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
25 #include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
26 #include <stdlib.h> /* for atoi() and exit() */
27 #include <string.h> /* for memset() */
28 #include <unistd.h> /* for close() */
32 #include <glib/gprintf.h>
33 #include <glib/gstdio.h>
34 #include <gmyth-stream-client.h>
36 #include <libgnomevfs/gnome-vfs-module.h>
37 #include <libgnomevfs/gnome-vfs-utils.h>
39 #define BUFFER_SIZE 4096
45 GMythStreamClient *stream;
64 static gmsHandle *gmsHandle_new(GnomeVFSURI * uri);
67 do_open(GnomeVFSMethod * method,
68 GnomeVFSMethodHandle ** method_handle,
70 GnomeVFSOpenMode mode, GnomeVFSContext * context);
73 do_read(GnomeVFSMethod * method,
74 GnomeVFSMethodHandle * method_handle,
76 GnomeVFSFileSize bytes,
77 GnomeVFSFileSize * bytes_read, GnomeVFSContext * context);
80 do_close(GnomeVFSMethod * method,
81 GnomeVFSMethodHandle * method_handle, GnomeVFSContext * context);
84 do_get_file_info(GnomeVFSMethod * method,
86 GnomeVFSFileInfo * file_info,
87 GnomeVFSFileInfoOptions options,
88 GnomeVFSContext * context);
92 do_get_file_info_from_handle(GnomeVFSMethod * method,
93 GnomeVFSMethodHandle * method_handle,
94 GnomeVFSFileInfo * file_info,
95 GnomeVFSFileInfoOptions options,
96 GnomeVFSContext * context);
100 do_is_local(GnomeVFSMethod * method, const GnomeVFSURI * uri);
104 gmsHandle_new(GnomeVFSURI * uri)
106 gmsHandle *handler = (gmsHandle *) g_malloc0(sizeof(gmsHandle));
108 handler->hostname = (gchar *) gnome_vfs_uri_get_host_name(uri);
109 handler->port = gnome_vfs_uri_get_host_port(uri);
110 handler->stream = gmyth_stream_client_new();
115 static GnomeVFSMethod method = {
116 sizeof(GnomeVFSMethod),
119 do_close, /* close */
124 NULL, /* truncate_handle */
125 NULL, /* open_directory */
126 NULL, /* close_directory */
127 NULL, /* read_directory */
128 do_get_file_info, /* get_file_info */
129 do_get_file_info_from_handle, /* get_file_info_from_handle */
130 do_is_local, /* is_local */
131 NULL, /* make_directory */
132 NULL, /* remove_directory */
135 NULL, /* check_same_fs */
136 NULL, /* set_file_info */
138 NULL, /* find_directory */
139 NULL, /* create_symbolic_link */
140 NULL, /* monitor_add */
141 NULL, /* monitor_cancel */
142 NULL /* file_control */
146 vfs_module_init(const char *method_name, const char *args)
152 vfs_module_shutdown(GnomeVFSMethod * method)
158 _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);
180 gchar **list = g_strsplit(file, "\'", 3);
181 gchar **prefix = g_strsplit_set(list[0], "/=", 3);
182 gchar **lst = g_strsplit(list[2], "?", 0);
184 UriArgs *info = g_new0(UriArgs, 1);
188 prop = g_strsplit_set(lst[0], "/=", 3);
190 info->file_name = g_strdup_printf("%s://%s", prefix[1], list[1]);
192 // g_debug("FILENAME: [%s]", info->file_name);
197 for (walk = lst[1]; walk != NULL; walk = lst[++i]) {
198 prop = g_strsplit(walk, "=", 2);
200 if (g_strv_length(prop) == 2) {
201 if (strcmp(prop[0], "mux") == 0) {
202 info->mux = g_strdup(prop[1]);
203 } else if (strcmp(prop[0], "vcodec") == 0) {
204 info->vcodec = g_strdup(prop[1]);
205 } else if (strcmp(prop[0], "vbitrate") == 0) {
206 info->vbitrate = atoi(prop[1]);
207 } else if (strcmp(prop[0], "fps") == 0) {
208 info->fps = g_strtod(prop[1], NULL);
209 } else if (strcmp(prop[0], "acodec") == 0) {
210 info->acodec = g_strdup(prop[1]);
211 } else if (strcmp(prop[0], "abitrate") == 0) {
212 info->abitrate = atoi(prop[1]);
213 } else if (strcmp(prop[0], "width") == 0) {
214 info->width = atoi(prop[1]);
215 } else if (strcmp(prop[0], "height") == 0) {
216 info->height = atoi(prop[1]);
217 } else if (strcmp(prop[0], "opt") == 0) {
218 info->opt = g_strdup(_parse_opt(walk));
231 static GnomeVFSResult
232 do_open(GnomeVFSMethod * method,
233 GnomeVFSMethodHandle ** method_handle,
235 GnomeVFSOpenMode mode, GnomeVFSContext * context)
237 gmsHandle *handle = gmsHandle_new(uri);
240 if (!gmyth_stream_client_connect(handle->stream,
241 gnome_vfs_uri_get_host_name(uri),
242 gnome_vfs_uri_get_host_port(uri))) {
244 return GNOME_VFS_ERROR_HOST_NOT_FOUND;
247 args = _uri_parse_args(uri);
249 gint ret = gmyth_stream_client_open_stream(handle->stream,
264 gmyth_stream_client_disconnect(handle->stream);
265 return GNOME_VFS_ERROR_HOST_NOT_FOUND;
268 handle->fd = gmyth_stream_client_play_stream(handle->stream);
270 if (handle->fd == -1) {
271 gmyth_stream_client_disconnect(handle->stream);
272 return GNOME_VFS_ERROR_HOST_NOT_FOUND;
275 *method_handle = (GnomeVFSMethodHandle *) handle;
279 static GnomeVFSResult
280 do_read(GnomeVFSMethod * method,
281 GnomeVFSMethodHandle * method_handle,
283 GnomeVFSFileSize bytes,
284 GnomeVFSFileSize * bytes_read, GnomeVFSContext * context)
287 gint64 total_read = 0;
288 gmsHandle *handle = (gmsHandle *) method_handle;
290 // g_debug("waiting something");
292 total_read = recv(handle->fd, buffer, BUFFER_SIZE, 0);
293 // g_debug("COULD READ: %d bytes", total_read);
294 *bytes_read = (GnomeVFSFileSize) total_read;
296 // if (total_read < 0) g_debug("ERROR!!!!!!!!!!!!!!!!");
299 return GNOME_VFS_ERROR_INTERNAL;
305 static GnomeVFSResult
306 do_close(GnomeVFSMethod * method,
307 GnomeVFSMethodHandle * method_handle, GnomeVFSContext * context)
309 gmsHandle *handle = (gmsHandle *) method_handle;
311 g_debug("close close close");
313 gmyth_stream_client_close_stream(handle->stream);
314 gmyth_stream_client_disconnect(handle->stream);
321 static GnomeVFSResult
322 do_get_file_info(GnomeVFSMethod * method,
324 GnomeVFSFileInfo * file_info,
325 GnomeVFSFileInfoOptions options,
326 GnomeVFSContext * context)
328 file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
329 GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
331 file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
333 file_info->permissions = GNOME_VFS_PERM_USER_READ |
334 GNOME_VFS_PERM_OTHER_READ | GNOME_VFS_PERM_GROUP_READ;
340 static GnomeVFSResult
341 do_get_file_info_from_handle(GnomeVFSMethod * method,
342 GnomeVFSMethodHandle * method_handle,
343 GnomeVFSFileInfo * file_info,
344 GnomeVFSFileInfoOptions options,
345 GnomeVFSContext * context)
347 file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
348 GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
350 file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
352 file_info->permissions = GNOME_VFS_PERM_USER_READ |
353 GNOME_VFS_PERM_OTHER_READ | GNOME_VFS_PERM_GROUP_READ;
360 do_is_local(GnomeVFSMethod * method, const GnomeVFSURI * uri)