melunko@38: /*
melunko@38:  * @author Hallyson Melo <hallyson.melo@indt.org.br>
melunko@38:  *
melunko@38:  * This program is free software; you can redistribute it and/or modify
melunko@38:  * it under the terms of the GNU Lesser General Public License as published by
melunko@38:  * the Free Software Foundation; either version 2 of the License, or
melunko@38:  * (at your option) any later version.
melunko@38:  *
melunko@38:  * This program is distributed in the hope that it will be useful,
melunko@38:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
melunko@38:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
melunko@38:  * GNU General Public License for more details.
melunko@38:  *
melunko@38:  * You should have received a copy of the GNU Lesser General Public License
melunko@38:  * along with this program; if not, write to the Free Software
melunko@38:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
melunko@38:  */
melunko@38: 
melunko@38: #ifdef HAVE_CONFIG_H
melunko@38: #include <config.h>
melunko@38: #endif
melunko@38: 
melunko@38: #include <string.h>
melunko@38: #include <glib.h>
leo_sobral@441: #include <glib/gprintf.h>
leo_sobral@441: #include <glib/gstdio.h>
melunko@38: #include <math.h>
melunko@38: 
melunko@38: #include <libgnomevfs/gnome-vfs-module.h>
melunko@38: #include <libgnomevfs/gnome-vfs-utils.h>
melunko@38: 
rosfran@547: #include <gmyth/gmyth_file.h>
rosfran@277: #include <gmyth/gmyth_file_transfer.h>
rosfran@547: #include <gmyth/gmyth_file_local.h>
rosfran@277: #include <gmyth/gmyth_livetv.h>
rosfran@277: #include <gmyth/gmyth_uri.h>
rosfran@277: #include <gmyth/gmyth_recorder.h>
rosfran@277: #include <gmyth/gmyth_backendinfo.h>
rosfran@277: #include <gmyth/gmyth_util.h>
rosfran@332: #include <gmyth/gmyth_remote_util.h>
rosfran@332: #include <gmyth/gmyth_tvchain.h>
rosfran@357: #include <gmyth/gmyth_programinfo.h>
melunko@38: 
melunko@38: #define GST_MYTHTV_ID_NUM               1
melunko@38: #define MYTHTV_VERSION_DEFAULT          30
rosfran@277: #define MYTHTV_TRANSFER_MAX_WAITS       100
melunko@38: 
renatofilho@754: /*
renatofilho@754:  * internal GnomeVFS plug-in buffer size ( 120 Kbytes ) 
renatofilho@754:  */
leo_sobral@441: #define MYTHTV_BUFFER_SIZE                          80*1024
renatofilho@754: /*
renatofilho@754:  * internally sized GnomeVFS plug-in buffer ( 4 Kbytes ) 
renatofilho@754:  */
leo_sobral@441: #define MYTHTV_MAX_VFS_BUFFER_SIZE                  4096
renatofilho@754: /*
renatofilho@754:  * maximum number of bytes to be requested to the MythTV backend ( 64
renatofilho@754:  * Kbytes ) 
renatofilho@754:  */
leo_sobral@441: #define MYTHTV_MAX_REQUEST_SIZE                     64*1024
melunko@111: 
renatofilho@754: typedef struct {
renatofilho@754:     GMythFile      *file;
renatofilho@754:     GMythLiveTV    *livetv;
renatofilho@754:     GMythBackendInfo *backend_info;
renatofilho@754:     GMythURI       *gmyth_uri;
renatofilho@754:     GMythRecorder  *live_recorder;
renatofilho@754:     gboolean        started;
renatofilho@754:     gint64          offset;
renatofilho@456: 
renatofilho@754:     gboolean        is_livetv;  /* it is, or not a Live TV content
renatofilho@754:                                  * transfer */
renatofilho@754:     gboolean        is_local_file;  /* tell if the file is local to the
renatofilho@754:                                      * current content transfer */
renatofilho@456: 
renatofilho@754:     gchar          *channel_name;
renatofilho@753: 
renatofilho@754:     gint            mythtv_version;
renatofilho@754:     gboolean        configured;
renatofilho@456: } MythtvHandle;
renatofilho@456: 
renatofilho@456: 
renatofilho@753: static GnomeVFSResult do_read(GnomeVFSMethod * method,
renatofilho@754:                               GnomeVFSMethodHandle * method_handle,
renatofilho@754:                               gpointer buffer,
renatofilho@754:                               GnomeVFSFileSize num_bytes,
renatofilho@754:                               GnomeVFSFileSize * bytes_read,
renatofilho@754:                               GnomeVFSContext * context);
melunko@38: 
renatofilho@753: static GnomeVFSResult myth_connection_start(MythtvHandle * method_handle);
renatofilho@754: static void     myth_destroy_handle(MythtvHandle * method_handle);
renatofilho@753: static GnomeVFSResult myth_handle_new(GnomeVFSURI * uri,
renatofilho@754:                                       MythtvHandle ** method_handle);
renatofilho@753: static GnomeVFSResult myth_get_file_info(MythtvHandle * myth_handle,
renatofilho@754:                                          GnomeVFSURI * uri,
renatofilho@754:                                          GnomeVFSFileInfo * info);
melunko@111: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: myth_handle_new(GnomeVFSURI * uri, MythtvHandle ** method_handle)
renatofilho@753: {
renatofilho@754:     gchar          *tmp_str1;
renatofilho@754:     gchar          *tmp_str2;
renatofilho@456: 
renatofilho@754:     _GNOME_VFS_METHOD_PARAM_CHECK(*method_handle == NULL);
renatofilho@753: 
renatofilho@754:     if (gnome_vfs_uri_get_host_name(uri) == NULL) {
renatofilho@754:         return GNOME_VFS_ERROR_INVALID_HOST_NAME;
renatofilho@754:     }
renatofilho@456: 
renatofilho@754:     *method_handle = g_new0(MythtvHandle, 1);
renatofilho@754:     (*method_handle)->mythtv_version = MYTHTV_VERSION_DEFAULT;
renatofilho@456: 
renatofilho@754:     (*method_handle)->is_livetv = FALSE;
renatofilho@754:     (*method_handle)->is_local_file = FALSE;
renatofilho@619: 
renatofilho@754:     tmp_str1 = gnome_vfs_uri_to_string(uri, GNOME_VFS_URI_HIDE_NONE);
renatofilho@754:     tmp_str2 = gnome_vfs_unescape_string(tmp_str1, "");
renatofilho@456: 
renatofilho@754:     gchar          *tmp_str3 = strstr(tmp_str2, ".nuv.avi");
renatofilho@754:     if (tmp_str3 != NULL) {
renatofilho@754:         tmp_str3[4] = '\0';
renatofilho@754:     }
renatofilho@753: 
renatofilho@754:     (*method_handle)->backend_info =
renatofilho@754:         gmyth_backend_info_new_with_uri(tmp_str2);
renatofilho@754:     (*method_handle)->gmyth_uri = gmyth_uri_new_with_value(tmp_str2);
renatofilho@754:     g_free(tmp_str1);
renatofilho@754:     g_free(tmp_str2);
renatofilho@753: 
renatofilho@754:     return GNOME_VFS_OK;
renatofilho@753: }
renatofilho@456: 
renatofilho@456: static void
renatofilho@753: myth_destroy_handle(MythtvHandle * method_handle)
renatofilho@456: {
renatofilho@754:     // TODO: abort if in tranfer state
renatofilho@456: 
renatofilho@754:     if (method_handle->backend_info != NULL) {
renatofilho@754:         g_object_unref(method_handle->backend_info);
renatofilho@754:         method_handle->backend_info = NULL;
renatofilho@754:     }
renatofilho@456: 
renatofilho@754:     if (method_handle->channel_name != NULL) {
renatofilho@754:         g_free(method_handle->channel_name);
renatofilho@754:         method_handle->channel_name = NULL;
renatofilho@754:     }
renatofilho@456: 
renatofilho@754:     if (method_handle->livetv != NULL) {
renatofilho@754:         g_object_unref(method_handle->livetv);
renatofilho@754:         method_handle->livetv = NULL;
renatofilho@754:     }
renatofilho@456: 
renatofilho@754:     if (method_handle->file != NULL) {
renatofilho@754:         g_object_unref(method_handle->file);
renatofilho@754:         method_handle->file = NULL;
renatofilho@754:     }
renatofilho@753: 
renatofilho@754:     if (method_handle->gmyth_uri != NULL) {
renatofilho@754:         g_object_unref(method_handle->gmyth_uri);
renatofilho@754:         method_handle->gmyth_uri = NULL;
renatofilho@754:     }
renatofilho@753: 
renatofilho@754:     g_free(method_handle);
renatofilho@456: }
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: myth_get_file_info(MythtvHandle * myth_handle,
renatofilho@754:                    GnomeVFSURI * uri, GnomeVFSFileInfo * info)
renatofilho@456: {
renatofilho@754:     GMythURI       *gmyth_uri;
renatofilho@754:     GMythBackendInfo *backend_info;
renatofilho@754:     gboolean        is_livetv;
renatofilho@754:     gboolean        is_local;
renatofilho@456: 
renatofilho@754:     _GNOME_VFS_METHOD_PARAM_CHECK(info != NULL);
renatofilho@456: 
renatofilho@754:     g_debug("%s - %d", __FUNCTION__, __LINE__);
renatofilho@456: 
renatofilho@754:     if (myth_handle == NULL) {
renatofilho@754:         gchar          *tmp_str1;
renatofilho@754:         gchar          *tmp_str2;
rosfran@547: 
renatofilho@754:         tmp_str1 = gnome_vfs_uri_to_string(uri, GNOME_VFS_URI_HIDE_NONE);
renatofilho@754:         tmp_str2 = gnome_vfs_unescape_string(tmp_str1, "");
renatofilho@753: 
renatofilho@754:         backend_info = gmyth_backend_info_new_with_uri(tmp_str2);
renatofilho@754:         gmyth_uri = gmyth_uri_new_with_value(tmp_str2);
renatofilho@753: 
renatofilho@754:         g_free(tmp_str1);
renatofilho@754:         g_free(tmp_str2);
renatofilho@754:     } else {
renatofilho@754:         backend_info = g_object_ref(myth_handle->backend_info);
renatofilho@754:         gmyth_uri = g_object_ref(myth_handle->gmyth_uri);
renatofilho@754:     }
renatofilho@753: 
renatofilho@754:     info->valid_fields = 0;
renatofilho@754:     info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
renatofilho@754:         GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE |
renatofilho@754:         GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
renatofilho@753: 
renatofilho@754:     info->type = GNOME_VFS_FILE_TYPE_REGULAR;
renatofilho@753: 
renatofilho@754:     /*
renatofilho@754:      * fixme: get from file extension? 
renatofilho@754:      */
renatofilho@754:     info->mime_type = g_strdup("video/x-nuv");
renatofilho@754:     info->permissions = GNOME_VFS_PERM_USER_READ |
renatofilho@754:         GNOME_VFS_PERM_OTHER_READ | GNOME_VFS_PERM_GROUP_READ;
renatofilho@753: 
renatofilho@754:     info->name = g_strdup(gmyth_uri_get_path(gmyth_uri));
renatofilho@753: 
renatofilho@754:     /*
renatofilho@754:      * file size for remote files 
renatofilho@754:      */
renatofilho@754:     is_livetv = gmyth_uri_is_livetv(gmyth_uri);
renatofilho@753: 
renatofilho@754:     if (is_livetv == FALSE) {
renatofilho@754:         GMythFile      *file = NULL;
renatofilho@754:         gboolean        ret = FALSE;
renatofilho@753: 
renatofilho@754:         /*
renatofilho@754:          * Verifies if the file exists 
renatofilho@754:          */
renatofilho@754:         if (!gmyth_util_file_exists(backend_info,
renatofilho@754:                                     gmyth_uri_get_path(gmyth_uri))) {
renatofilho@754:             g_object_unref(file);
renatofilho@754:             g_object_unref(backend_info);
renatofilho@754:             g_debug("NOT FOUND %s/%d", __FUNCTION__, __LINE__);
renatofilho@754:             return GNOME_VFS_ERROR_NOT_FOUND;
renatofilho@754:         }
renatofilho@461: 
renatofilho@754:         is_local = gmyth_uri_is_local_file(gmyth_uri);
renatofilho@754:         if (is_local == TRUE) {
renatofilho@754:             file = GMYTH_FILE(gmyth_file_local_new(backend_info));
renatofilho@754:             ret = gmyth_file_local_open(GMYTH_FILE_LOCAL(file));
renatofilho@754:         } else {
renatofilho@754:             file = GMYTH_FILE(gmyth_file_transfer_new(backend_info));
renatofilho@754:             ret = gmyth_file_transfer_open(GMYTH_FILE_TRANSFER(file),
renatofilho@754:                                            gmyth_uri_get_path(gmyth_uri));
renatofilho@754:         }
renatofilho@753: 
renatofilho@754:         if (!ret) {
renatofilho@754:             g_object_unref(file);
renatofilho@754:             g_object_unref(backend_info);
renatofilho@754:             g_debug("NOT FOUND %s/%d", __FUNCTION__, __LINE__);
renatofilho@754:             return GNOME_VFS_ERROR_NOT_FOUND;
renatofilho@754:         }
renatofilho@753: 
renatofilho@754:         info->size = gmyth_file_get_filesize(file);
renatofilho@754:         info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SIZE;
renatofilho@754:         g_object_unref(file);
renatofilho@754:     }
renatofilho@456: 
renatofilho@754:     g_object_unref(backend_info);
renatofilho@754:     g_object_unref(gmyth_uri);
renatofilho@753: 
renatofilho@754:     return GNOME_VFS_OK;
renatofilho@456: }
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: myth_connection_start(MythtvHandle * method_handle)
renatofilho@456: {
renatofilho@754:     GnomeVFSResult  result = GNOME_VFS_OK;
renatofilho@456: 
renatofilho@754:     _GNOME_VFS_METHOD_PARAM_CHECK(method_handle != NULL);
renatofilho@754:     _GNOME_VFS_METHOD_PARAM_CHECK(method_handle->backend_info != NULL);
renatofilho@456: 
renatofilho@754:     /*
renatofilho@754:      * Connect to the backend 
renatofilho@754:      */
renatofilho@754:     if ((method_handle->is_livetv =
renatofilho@754:          gmyth_uri_is_livetv(method_handle->gmyth_uri)) == TRUE) {
renatofilho@754:         method_handle->livetv =
renatofilho@754:             gmyth_livetv_new(method_handle->backend_info);
renatofilho@754:         method_handle->channel_name =
renatofilho@754:             gmyth_uri_get_channel_name(method_handle->gmyth_uri);
renatofilho@753: 
renatofilho@754:         if (method_handle->channel_name != NULL) {
renatofilho@754:             if (gmyth_livetv_channel_name_setup(method_handle->livetv,
renatofilho@754:                                                 method_handle->
renatofilho@754:                                                 channel_name) == FALSE) {
renatofilho@754:                 result = GNOME_VFS_ERROR_INVALID_URI;
renatofilho@754:                 goto error;
renatofilho@754:             }
renatofilho@754:         } else if (gmyth_livetv_setup(method_handle->livetv) == FALSE) {
renatofilho@754:             result = GNOME_VFS_ERROR_INVALID_URI;
renatofilho@754:             goto error;
renatofilho@754:         }
renatofilho@456: 
renatofilho@456: 
renatofilho@754:         method_handle->file =
renatofilho@754:             GMYTH_FILE(gmyth_livetv_create_file_transfer
renatofilho@754:                        (method_handle->livetv));
renatofilho@456: 
renatofilho@754:         if (method_handle->file == NULL) {
renatofilho@754:             result = GNOME_VFS_ERROR_INVALID_URI;
renatofilho@754:             g_debug("MythTV FileTransfer is NULL!\n");
renatofilho@754:             goto error;
renatofilho@754:         }
renatofilho@456: 
renatofilho@754:         if (!gmyth_file_transfer_open
renatofilho@754:             (GMYTH_FILE_TRANSFER(method_handle->file),
renatofilho@754:              method_handle->livetv->uri !=
renatofilho@754:              NULL ? gmyth_uri_get_path(method_handle->livetv->
renatofilho@754:                                        uri) : method_handle->livetv->
renatofilho@754:              proginfo->pathname->str)) {
renatofilho@753: 
renatofilho@754:             g_debug("Couldn't open MythTV FileTransfer is NULL!\n");
renatofilho@754:             result = GNOME_VFS_ERROR_NOT_OPEN;
renatofilho@754:             goto error;
renatofilho@754:         }
renatofilho@754:     } else {
renatofilho@754:         gboolean        ret = TRUE;
renatofilho@754:         /*
renatofilho@754:          * Verifies if the file exists 
renatofilho@754:          */
renatofilho@754:         if (!gmyth_util_file_exists(method_handle->backend_info,
renatofilho@754:                                     gmyth_uri_get_path(method_handle->
renatofilho@754:                                                        gmyth_uri))) {
renatofilho@456: 
renatofilho@754:             g_debug("NOT FOUND %s/%d", __FUNCTION__, __LINE__);
renatofilho@754:             goto error;
renatofilho@754:         }
renatofilho@461: 
renatofilho@754:         if ((method_handle->is_local_file =
renatofilho@754:              gmyth_uri_is_local_file(method_handle->gmyth_uri)) == TRUE) {
renatofilho@754:             method_handle->file =
renatofilho@754:                 GMYTH_FILE(gmyth_file_local_new
renatofilho@754:                            (method_handle->backend_info));
renatofilho@754:             ret =
renatofilho@754:                 gmyth_file_local_open(GMYTH_FILE_LOCAL
renatofilho@754:                                       (method_handle->file));
renatofilho@754:         } else {
renatofilho@754:             method_handle->file =
renatofilho@754:                 GMYTH_FILE(gmyth_file_transfer_new
renatofilho@754:                            (method_handle->backend_info));
renatofilho@754:             ret =
renatofilho@754:                 gmyth_file_transfer_open(GMYTH_FILE_TRANSFER
renatofilho@754:                                          (method_handle->file),
renatofilho@754:                                          gmyth_uri_get_path(method_handle->
renatofilho@754:                                                             gmyth_uri));
renatofilho@754:         }
renatofilho@456: 
renatofilho@754:         /*
renatofilho@754:          * sets the Playback monitor connection 
renatofilho@754:          */
renatofilho@754:         if (!ret) {
renatofilho@456: 
renatofilho@754:             g_debug("NOT FOUND %s/%d", __FUNCTION__, __LINE__);
renatofilho@754:             result = GNOME_VFS_ERROR_NOT_FOUND;
renatofilho@754:             goto error;
renatofilho@754:         }
renatofilho@754:     }                           /* if - LiveTV or not? */
renatofilho@753: 
renatofilho@754:     method_handle->configured = TRUE;
renatofilho@753: 
renatofilho@754:     if (method_handle->file == NULL) {
renatofilho@754:         result = GNOME_VFS_ERROR_NOT_OPEN;
renatofilho@754:     }
renatofilho@456: 
renatofilho@754:   error:
renatofilho@753: 
renatofilho@754:     return result;
renatofilho@456: }
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_open(GnomeVFSMethod * method,
renatofilho@754:         GnomeVFSMethodHandle ** method_handle,
renatofilho@754:         GnomeVFSURI * uri, GnomeVFSOpenMode mode,
renatofilho@754:         GnomeVFSContext * context)
renatofilho@367: {
renatofilho@754:     MythtvHandle   *myth_handle = NULL;
renatofilho@754:     GnomeVFSResult  result = GNOME_VFS_OK;
renatofilho@456: 
renatofilho@754:     _GNOME_VFS_METHOD_PARAM_CHECK(method_handle != NULL);
renatofilho@754:     _GNOME_VFS_METHOD_PARAM_CHECK(uri != NULL);
melunko@38: 
renatofilho@754:     if (mode & GNOME_VFS_OPEN_WRITE) {
renatofilho@754:         return GNOME_VFS_ERROR_INVALID_OPEN_MODE;
renatofilho@754:     }
melunko@38: 
renatofilho@754:     result = myth_handle_new(uri, &myth_handle);
renatofilho@754:     if (result != GNOME_VFS_OK)
renatofilho@754:         return result;
renatofilho@367: 
renatofilho@754:     result = myth_connection_start(myth_handle);
renatofilho@754:     if (result != GNOME_VFS_OK) {
renatofilho@754:         myth_destroy_handle(myth_handle);
renatofilho@754:         myth_handle = NULL;
renatofilho@754:         return result;
renatofilho@754:     }
renatofilho@461: 
renatofilho@754:     *method_handle = (GnomeVFSMethodHandle *) myth_handle;
renatofilho@753: 
renatofilho@754:     return result;
renatofilho@456: }
renatofilho@367: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_create(GnomeVFSMethod * method,
renatofilho@754:           GnomeVFSMethodHandle ** method_handle,
renatofilho@754:           GnomeVFSURI * uri,
renatofilho@754:           GnomeVFSOpenMode mode,
renatofilho@754:           gboolean exclusive, guint perm, GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_NOT_SUPPORTED;
renatofilho@456: }
renatofilho@367: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_close(GnomeVFSMethod * method,
renatofilho@754:          GnomeVFSMethodHandle * method_handle, GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     MythtvHandle   *myth_handle = (MythtvHandle *) method_handle;
leo_sobral@447: 
renatofilho@754:     myth_destroy_handle(myth_handle);
renatofilho@753: 
renatofilho@754:     return GNOME_VFS_OK;
melunko@38: }
melunko@38: 
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_read(GnomeVFSMethod * method,
renatofilho@754:         GnomeVFSMethodHandle * method_handle,
renatofilho@754:         gpointer buffer,
renatofilho@754:         GnomeVFSFileSize num_bytes,
renatofilho@754:         GnomeVFSFileSize * bytes_read, GnomeVFSContext * context)
melunko@38: {
renatofilho@754:     GnomeVFSResult  retval = GNOME_VFS_OK;
renatofilho@754:     MythtvHandle   *myth_handle;
renatofilho@754:     GMythFileReadResult result;
renatofilho@754:     GByteArray     *myth_buffer = g_byte_array_new();
melunko@38: 
renatofilho@754:     _GNOME_VFS_METHOD_PARAM_CHECK(method_handle != NULL);
melunko@38: 
renatofilho@754:     myth_handle = (MythtvHandle *) method_handle;
renatofilho@754:     if (myth_handle->is_local_file)
renatofilho@754:         result = gmyth_file_local_read(GMYTH_FILE_LOCAL(myth_handle->file),
renatofilho@754:                                        myth_buffer,
renatofilho@754:                                        num_bytes, myth_handle->is_livetv);
renatofilho@754:     else
renatofilho@754:         result =
renatofilho@754:             gmyth_file_transfer_read(GMYTH_FILE_TRANSFER
renatofilho@754:                                      (myth_handle->file), myth_buffer,
renatofilho@754:                                      num_bytes, myth_handle->is_livetv);
renatofilho@367: 
renatofilho@754:     if (result == GMYTH_FILE_READ_ERROR) {
renatofilho@754:         retval = GNOME_VFS_ERROR_IO;
renatofilho@754:     }
renatofilho@367: 
renatofilho@754:     if (result == GMYTH_FILE_READ_EOF) {
renatofilho@754:         retval = GNOME_VFS_ERROR_EOF;
renatofilho@754:     }
renatofilho@367: 
renatofilho@754:     if (myth_buffer->len > 0) {
renatofilho@754:         g_memmove(buffer, myth_buffer->data, myth_buffer->len);
renatofilho@754:         *bytes_read = (GnomeVFSFileSize) myth_buffer->len;
renatofilho@754:         myth_handle->offset += myth_buffer->len;
renatofilho@754:         g_byte_array_free(myth_buffer, TRUE);
renatofilho@754:     }
renatofilho@367: 
renatofilho@754:     return retval;
melunko@38: }
melunko@38: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_write(GnomeVFSMethod * method,
renatofilho@754:          GnomeVFSMethodHandle * method_handle,
renatofilho@754:          gconstpointer buffer,
renatofilho@754:          GnomeVFSFileSize num_bytes,
renatofilho@754:          GnomeVFSFileSize * bytes_written, GnomeVFSContext * context)
melunko@38: {
renatofilho@754:     return GNOME_VFS_ERROR_NOT_SUPPORTED;
renatofilho@456: }
melunko@111: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_seek(GnomeVFSMethod * method,
renatofilho@754:         GnomeVFSMethodHandle * method_handle,
renatofilho@754:         GnomeVFSSeekPosition whence,
renatofilho@754:         GnomeVFSFileOffset offset, GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     MythtvHandle   *myth_handle;
renatofilho@754:     guint64         whence_p = 0;
renatofilho@754:     gint64          new_offset = 0;
renatofilho@367: 
renatofilho@754:     _GNOME_VFS_METHOD_PARAM_CHECK(method_handle != NULL);
renatofilho@367: 
renatofilho@754:     myth_handle = (MythtvHandle *) method_handle;
renatofilho@367: 
renatofilho@754:     g_debug("seek offset %" G_GINT64_FORMAT " whence %d", offset, whence);
renatofilho@367: 
renatofilho@754:     if (gmyth_uri_is_livetv(myth_handle->gmyth_uri))
renatofilho@754:         return GNOME_VFS_ERROR_NOT_SUPPORTED;
renatofilho@753: 
renatofilho@754:     switch (whence) {
renatofilho@754:     case GNOME_VFS_SEEK_START:
renatofilho@754:         whence_p = 0;
renatofilho@754:         break;
renatofilho@754:     case GNOME_VFS_SEEK_CURRENT:
renatofilho@754:         whence_p = myth_handle->offset;
renatofilho@754:         break;
renatofilho@754:     case GNOME_VFS_SEEK_END:
renatofilho@754:         return GNOME_VFS_ERROR_NOT_SUPPORTED;
renatofilho@754:     }
renatofilho@753: 
renatofilho@754:     new_offset =
renatofilho@754:         gmyth_file_transfer_seek(myth_handle->file, offset, whence_p);
renatofilho@754:     if (new_offset != 0) {
renatofilho@754:         myth_handle->offset = new_offset;
renatofilho@754:         return GNOME_VFS_OK;
renatofilho@754:     }
renatofilho@753: 
renatofilho@754:     return GNOME_VFS_ERROR_NOT_SUPPORTED;
renatofilho@456: }
renatofilho@367: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_tell(GnomeVFSMethod * method,
renatofilho@754:         GnomeVFSMethodHandle * method_handle,
renatofilho@754:         GnomeVFSFileSize * offset_return)
renatofilho@456: {
renatofilho@754:     MythtvHandle   *myth_handle = NULL;
renatofilho@367: 
renatofilho@754:     _GNOME_VFS_METHOD_PARAM_CHECK(method_handle != NULL);
renatofilho@753: 
renatofilho@754:     myth_handle = (MythtvHandle *) method_handle;
renatofilho@754:     *offset_return = myth_handle->offset;
renatofilho@753: 
renatofilho@754:     return GNOME_VFS_OK;
renatofilho@456: }
renatofilho@367: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_truncate_handle(GnomeVFSMethod * method,
renatofilho@754:                    GnomeVFSMethodHandle * method_handle,
renatofilho@754:                    GnomeVFSFileSize where, GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_READ_ONLY;
renatofilho@456: }
renatofilho@367: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_open_directory(GnomeVFSMethod * method,
renatofilho@754:                   GnomeVFSMethodHandle ** method_handle,
renatofilho@754:                   GnomeVFSURI * uri,
renatofilho@754:                   GnomeVFSFileInfoOptions options,
renatofilho@754:                   GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_NOT_SUPPORTED;
melunko@38: }
melunko@38: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_close_directory(GnomeVFSMethod * method,
renatofilho@754:                    GnomeVFSMethodHandle * method_handle,
renatofilho@754:                    GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_NOT_SUPPORTED;
renatofilho@456: }
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_read_directory(GnomeVFSMethod * method,
renatofilho@754:                   GnomeVFSMethodHandle * method_handle,
renatofilho@754:                   GnomeVFSFileInfo * file_info, GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_NOT_SUPPORTED;
renatofilho@456: }
renatofilho@456: 
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_get_file_info(GnomeVFSMethod * method,
renatofilho@754:                  GnomeVFSURI * uri,
renatofilho@754:                  GnomeVFSFileInfo * file_info,
renatofilho@754:                  GnomeVFSFileInfoOptions options,
renatofilho@754:                  GnomeVFSContext * context)
melunko@38: {
renatofilho@754:     return myth_get_file_info(NULL, uri, file_info);
renatofilho@456: }
leo_sobral@447: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_get_file_info_from_handle(GnomeVFSMethod * method,
renatofilho@754:                              GnomeVFSMethodHandle * method_handle,
renatofilho@754:                              GnomeVFSFileInfo * file_info,
renatofilho@754:                              GnomeVFSFileInfoOptions options,
renatofilho@754:                              GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     MythtvHandle   *myth_handle = (MythtvHandle *) method_handle;
renatofilho@188: 
renatofilho@754:     return myth_get_file_info(myth_handle, NULL, file_info);
melunko@38: }
melunko@38: 
renatofilho@754: static          gboolean
renatofilho@753: do_is_local(GnomeVFSMethod * method, const GnomeVFSURI * uri)
melunko@38: {
renatofilho@754:     return FALSE;
melunko@38: }
melunko@38: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_make_directory(GnomeVFSMethod * method,
renatofilho@754:                   GnomeVFSURI * uri, guint perm, GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_READ_ONLY;
renatofilho@456: }
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_remove_directory(GnomeVFSMethod * method,
renatofilho@754:                     GnomeVFSURI * uri, GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_READ_ONLY;
renatofilho@456: }
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_move(GnomeVFSMethod * method,
renatofilho@754:         GnomeVFSURI * old_uri,
renatofilho@754:         GnomeVFSURI * new_uri,
renatofilho@754:         gboolean force_replace, GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_READ_ONLY;
renatofilho@456: }
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_unlink(GnomeVFSMethod * method,
renatofilho@754:           GnomeVFSURI * uri, GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_READ_ONLY;
renatofilho@456: }
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_check_same_fs(GnomeVFSMethod * method,
renatofilho@754:                  GnomeVFSURI * a,
renatofilho@754:                  GnomeVFSURI * b,
renatofilho@754:                  gboolean * same_fs_return, GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_NOT_SUPPORTED;
renatofilho@456: }
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_set_file_info(GnomeVFSMethod * method,
renatofilho@754:                  GnomeVFSURI * uri,
renatofilho@754:                  const GnomeVFSFileInfo * info,
renatofilho@754:                  GnomeVFSSetFileInfoMask mask, GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_READ_ONLY;
renatofilho@456: }
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_truncate(GnomeVFSMethod * method,
renatofilho@754:             GnomeVFSURI * uri,
renatofilho@754:             GnomeVFSFileSize where, GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_READ_ONLY;
renatofilho@456: }
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_find_directory(GnomeVFSMethod * method,
renatofilho@754:                   GnomeVFSURI * near_uri,
renatofilho@754:                   GnomeVFSFindDirectoryKind kind,
renatofilho@754:                   GnomeVFSURI ** result_uri,
renatofilho@754:                   gboolean create_if_needed,
renatofilho@754:                   gboolean find_if_needed,
renatofilho@754:                   guint permissions, GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_NOT_SUPPORTED;
renatofilho@456: }
renatofilho@456: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_create_symbolic_link(GnomeVFSMethod * method,
renatofilho@754:                         GnomeVFSURI * uri,
renatofilho@754:                         const char *target_reference,
renatofilho@754:                         GnomeVFSContext * context)
renatofilho@456: {
renatofilho@754:     return GNOME_VFS_ERROR_READ_ONLY;
renatofilho@753: }
renatofilho@753: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_monitor_add(GnomeVFSMethod * method,
renatofilho@754:                GnomeVFSMethodHandle ** method_handle_return,
renatofilho@754:                GnomeVFSURI * uri, GnomeVFSMonitorType monitor_type)
renatofilho@753: {
renatofilho@754:     return GNOME_VFS_ERROR_NOT_SUPPORTED;
renatofilho@753: }
renatofilho@753: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_monitor_cancel(GnomeVFSMethod * method,
renatofilho@754:                   GnomeVFSMethodHandle * method_handle)
renatofilho@753: {
renatofilho@754:     return GNOME_VFS_ERROR_NOT_SUPPORTED;
renatofilho@753: }
renatofilho@753: 
renatofilho@754: static          GnomeVFSResult
renatofilho@753: do_file_control(GnomeVFSMethod * method,
renatofilho@754:                 GnomeVFSMethodHandle * method_handle,
renatofilho@754:                 const char *operation,
renatofilho@754:                 gpointer operation_data, GnomeVFSContext * context)
renatofilho@753: {
renatofilho@754:     return GNOME_VFS_ERROR_NOT_SUPPORTED;
renatofilho@456: }
renatofilho@456: 
melunko@38: static GnomeVFSMethod method = {
renatofilho@754:     sizeof(GnomeVFSMethod),
renatofilho@754:     do_open,
renatofilho@754:     do_create,
renatofilho@754:     do_close,
renatofilho@754:     do_read,
renatofilho@754:     do_write,
renatofilho@754:     do_seek,
renatofilho@754:     do_tell,
renatofilho@754:     do_truncate_handle,
renatofilho@754:     do_open_directory,
renatofilho@754:     do_close_directory,
renatofilho@754:     do_read_directory,
renatofilho@754:     do_get_file_info,
renatofilho@754:     do_get_file_info_from_handle,
renatofilho@754:     do_is_local,
renatofilho@754:     do_make_directory,
renatofilho@754:     do_remove_directory,
renatofilho@754:     do_move,
renatofilho@754:     do_unlink,
renatofilho@754:     do_check_same_fs,
renatofilho@754:     do_set_file_info,
renatofilho@754:     do_truncate,
renatofilho@754:     do_find_directory,
renatofilho@754:     do_create_symbolic_link,
renatofilho@754:     do_monitor_add,
renatofilho@754:     do_monitor_cancel,
renatofilho@754:     do_file_control
melunko@38: };
melunko@38: 
melunko@38: 
melunko@38: GnomeVFSMethod *
renatofilho@753: vfs_module_init(const char *method_name, const char *args)
melunko@38: {
renatofilho@754:     return &method;
melunko@38: }
melunko@38: 
melunko@38: void
renatofilho@753: vfs_module_shutdown(GnomeVFSMethod * method)
melunko@38: {
melunko@38: }