/* * @author Hallyson Melo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "myth_file_transfer.h" #define GST_MYTHTV_ID_NUM 1 #define MYTHTV_VERSION_DEFAULT 30 static GnomeVFSResult do_read (GnomeVFSMethod *method, GnomeVFSMethodHandle *method_handle, gpointer buffer, GnomeVFSFileSize num_bytes, GnomeVFSFileSize *bytes_read, GnomeVFSContext *context); typedef struct { MythFileTransfer *file_transfer; gint mythtv_version; guint64 content_size; guint64 bytes_read; guint64 read_offset; gboolean live_tv; } MythtvHandle; static GnomeVFSResult do_open (GnomeVFSMethod *method, GnomeVFSMethodHandle **method_handle, GnomeVFSURI *uri, GnomeVFSOpenMode mode, GnomeVFSContext *context) { MythtvHandle *myth_handle = g_new0 (MythtvHandle, 1); const gchar *user, *password, *host, *transfer_uri; guint port; gchar *path; gboolean ret; _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL); _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL); if (mode & GNOME_VFS_OPEN_WRITE) { return GNOME_VFS_ERROR_NOT_PERMITTED; } if ((host = gnome_vfs_uri_get_host_name (uri)) == NULL) { return GNOME_VFS_ERROR_INVALID_HOST_NAME; } /* Parse URI */ path = gnome_vfs_unescape_string (uri->text, NULL); port = gnome_vfs_uri_get_host_port (uri); user = gnome_vfs_uri_get_user_name (uri); password = gnome_vfs_uri_get_password (uri); transfer_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_USER_NAME | GNOME_VFS_URI_HIDE_PASSWORD); /* Initialize mythtv handler*/ myth_handle->file_transfer = NULL; myth_handle->mythtv_version = MYTHTV_VERSION_DEFAULT; myth_handle->bytes_read = 0; myth_handle->content_size = -1; myth_handle->read_offset = 0; myth_handle->live_tv = FALSE; /* Connect to the backend */ myth_handle->file_transfer = myth_file_transfer_new ( GST_MYTHTV_ID_NUM /*mythtv->live_tv_id*/, g_string_new( transfer_uri ), -1, myth_handle->mythtv_version ); if ( myth_handle->file_transfer == NULL ) { return GNOME_VFS_ERROR_NOT_OPEN; } /* sets the Playback monitor connection */ ret = myth_file_transfer_playback_setup( &(myth_handle->file_transfer), myth_handle->live_tv ); if (ret == FALSE) { g_printerr ("Mythtv FileTransfer playback setup error\n"); return GNOME_VFS_ERROR_NOT_OPEN; } /* sets the FileTransfer instance connection (video/audio download) */ ret = myth_file_transfer_setup( &(myth_handle->file_transfer), myth_handle->live_tv ); if ( ret == FALSE ) { g_printerr ("MythTV FileTransfer request failed when setting up socket connection!\n" ); return GNOME_VFS_ERROR_NOT_OPEN; } // TODO: Verify if file exists in the backend myth_handle->content_size = myth_handle->file_transfer->filesize; *method_handle = (GnomeVFSMethodHandle *) myth_handle; return GNOME_VFS_OK; } static GnomeVFSResult do_read (GnomeVFSMethod *method, GnomeVFSMethodHandle *method_handle, gpointer buffer, GnomeVFSFileSize num_bytes, GnomeVFSFileSize *bytes_read, GnomeVFSContext *context) { MythtvHandle *myth_handle = (MythtvHandle *) method_handle; guint len = 0, offset = 0; GnomeVFSFileSize bytes_to_read; g_debug ("do_read(): file size: %llu, already read: %llu, requested: %llu", myth_handle->content_size, myth_handle->bytes_read, num_bytes); *bytes_read = 0; if (myth_handle->bytes_read >= myth_handle->content_size) return GNOME_VFS_ERROR_EOF; // fixme: change this to min math function if (num_bytes > myth_handle->content_size - myth_handle->bytes_read) bytes_to_read = myth_handle->content_size - myth_handle->bytes_read; else bytes_to_read = num_bytes; /* Loop sending the Myth File Transfer request: * Retry whilst authentication fails and we supply it. */ // lock here ??? while ( bytes_to_read > 0 ) { len = myth_file_transfer_read( myth_handle->file_transfer, buffer + offset, bytes_to_read, TRUE ); if ( len > 0 ) { offset += len; bytes_to_read -= len; } else { break; } if ( offset == num_bytes ) break; } if (( offset <= 0 ) && !myth_handle->live_tv ) return GNOME_VFS_ERROR_EOF; myth_handle->read_offset += offset; myth_handle->bytes_read += offset; *bytes_read = offset; return GNOME_VFS_OK; } static GnomeVFSResult do_close (GnomeVFSMethod *method, GnomeVFSMethodHandle *method_handle, GnomeVFSContext *context) { MythtvHandle *myth_handle = (MythtvHandle *) method_handle; if (myth_handle->file_transfer) g_object_unref (myth_handle->file_transfer); g_free (myth_handle); return GNOME_VFS_OK; } static GnomeVFSResult do_get_file_info (GnomeVFSMethod *method, GnomeVFSURI *uri, GnomeVFSFileInfo *file_info, GnomeVFSFileInfoOptions options, GnomeVFSContext *context) { GString *name = g_string_new ("hallyson"); file_info->name = g_string_free (name, FALSE);//"hallyson.txt";//get_base_from_uri (uri); file_info->valid_fields = file_info->valid_fields | GNOME_VFS_FILE_INFO_FIELDS_TYPE | GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE | GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS; file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; file_info->mime_type = "video/x-nuv"; //g_strdup (gnome_vfs_mime_type_from_name (file_info->name)); file_info->permissions = GNOME_VFS_PERM_USER_READ | GNOME_VFS_PERM_OTHER_READ | GNOME_VFS_PERM_GROUP_READ; return GNOME_VFS_OK; } static gboolean do_is_local (GnomeVFSMethod *method, const GnomeVFSURI *uri) { return FALSE; } static GnomeVFSMethod method = { sizeof (GnomeVFSMethod), do_open, NULL, do_close, do_read, NULL, NULL, NULL, NULL, NULL, NULL, NULL, do_get_file_info, NULL, do_is_local, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; GnomeVFSMethod * vfs_module_init (const char *method_name, const char *args) { return &method; } void vfs_module_shutdown (GnomeVFSMethod *method) { }