[svn r934] renamed src dir to gmyth trunk
authorrenatofilho
Mon Feb 25 17:51:43 2008 +0000 (2008-02-25)
branchtrunk
changeset 9254a8d56080089
parent 924 c39c60fcfec8
child 926 84b9b65e511f
[svn r934] renamed src dir to gmyth
gmyth/Makefile.am
gmyth/configure.ac
gmyth/gmyth/Makefile.am
gmyth/gmyth/gmyth-indent.sh
gmyth/gmyth/gmyth.h
gmyth/gmyth/gmyth_backendinfo.c
gmyth/gmyth/gmyth_backendinfo.h
gmyth/gmyth/gmyth_common.c
gmyth/gmyth/gmyth_common.h
gmyth/gmyth/gmyth_debug.c
gmyth/gmyth/gmyth_debug.h
gmyth/gmyth/gmyth_epg.c
gmyth/gmyth/gmyth_epg.h
gmyth/gmyth/gmyth_file.c
gmyth/gmyth/gmyth_file.h
gmyth/gmyth/gmyth_file_local.c
gmyth/gmyth/gmyth_file_local.h
gmyth/gmyth/gmyth_file_transfer.c
gmyth/gmyth/gmyth_file_transfer.h
gmyth/gmyth/gmyth_http.c
gmyth/gmyth/gmyth_http.h
gmyth/gmyth/gmyth_jobqueue.c
gmyth/gmyth/gmyth_jobqueue.h
gmyth/gmyth/gmyth_livetv.c
gmyth/gmyth/gmyth_livetv.h
gmyth/gmyth/gmyth_marshal.list
gmyth/gmyth/gmyth_monitor_handler.c
gmyth/gmyth/gmyth_monitor_handler.h
gmyth/gmyth/gmyth_programinfo.c
gmyth/gmyth/gmyth_programinfo.h
gmyth/gmyth/gmyth_query.c
gmyth/gmyth/gmyth_query.h
gmyth/gmyth/gmyth_recorder.c
gmyth/gmyth/gmyth_recorder.h
gmyth/gmyth/gmyth_recprofile.c
gmyth/gmyth/gmyth_recprofile.h
gmyth/gmyth/gmyth_remote_util.c
gmyth/gmyth/gmyth_remote_util.h
gmyth/gmyth/gmyth_scheduler.c
gmyth/gmyth/gmyth_scheduler.h
gmyth/gmyth/gmyth_socket.c
gmyth/gmyth/gmyth_socket.h
gmyth/gmyth/gmyth_stringlist.c
gmyth/gmyth/gmyth_stringlist.h
gmyth/gmyth/gmyth_transcoder.c
gmyth/gmyth/gmyth_transcoder.h
gmyth/gmyth/gmyth_tvchain.c
gmyth/gmyth/gmyth_tvchain.h
gmyth/gmyth/gmyth_uri.c
gmyth/gmyth/gmyth_uri.h
gmyth/gmyth/gmyth_util.c
gmyth/gmyth/gmyth_util.h
gmyth/gmyth/gmyth_vlc.c
gmyth/gmyth/gmyth_vlc.h
gmyth/gmyth/gst-indent.sh
gmyth/samples/Makefile.am
gmyth/src/Makefile.am
gmyth/src/gmyth-indent.sh
gmyth/src/gmyth.h
gmyth/src/gmyth_backendinfo.c
gmyth/src/gmyth_backendinfo.h
gmyth/src/gmyth_common.c
gmyth/src/gmyth_common.h
gmyth/src/gmyth_debug.c
gmyth/src/gmyth_debug.h
gmyth/src/gmyth_epg.c
gmyth/src/gmyth_epg.h
gmyth/src/gmyth_file.c
gmyth/src/gmyth_file.h
gmyth/src/gmyth_file_local.c
gmyth/src/gmyth_file_local.h
gmyth/src/gmyth_file_transfer.c
gmyth/src/gmyth_file_transfer.h
gmyth/src/gmyth_http.c
gmyth/src/gmyth_http.h
gmyth/src/gmyth_jobqueue.c
gmyth/src/gmyth_jobqueue.h
gmyth/src/gmyth_livetv.c
gmyth/src/gmyth_livetv.h
gmyth/src/gmyth_marshal.list
gmyth/src/gmyth_monitor_handler.c
gmyth/src/gmyth_monitor_handler.h
gmyth/src/gmyth_programinfo.c
gmyth/src/gmyth_programinfo.h
gmyth/src/gmyth_query.c
gmyth/src/gmyth_query.h
gmyth/src/gmyth_recorder.c
gmyth/src/gmyth_recorder.h
gmyth/src/gmyth_recprofile.c
gmyth/src/gmyth_recprofile.h
gmyth/src/gmyth_remote_util.c
gmyth/src/gmyth_remote_util.h
gmyth/src/gmyth_scheduler.c
gmyth/src/gmyth_scheduler.h
gmyth/src/gmyth_socket.c
gmyth/src/gmyth_socket.h
gmyth/src/gmyth_stringlist.c
gmyth/src/gmyth_stringlist.h
gmyth/src/gmyth_transcoder.c
gmyth/src/gmyth_transcoder.h
gmyth/src/gmyth_tvchain.c
gmyth/src/gmyth_tvchain.h
gmyth/src/gmyth_uri.c
gmyth/src/gmyth_uri.h
gmyth/src/gmyth_util.c
gmyth/src/gmyth_util.h
gmyth/src/gmyth_vlc.c
gmyth/src/gmyth_vlc.h
gmyth/src/gst-indent.sh
gmyth/tests/Makefile.am
     1.1 --- a/gmyth/Makefile.am	Mon Feb 25 17:45:36 2008 +0000
     1.2 +++ b/gmyth/Makefile.am	Mon Feb 25 17:51:43 2008 +0000
     1.3 @@ -1,4 +1,4 @@
     1.4 -SUBDIRS= src samples tests
     1.5 +SUBDIRS= gmyth samples tests
     1.6  
     1.7  pkgconfigdir = $(libdir)/pkgconfig
     1.8  pkgconfig_DATA = gmyth.pc
     2.1 --- a/gmyth/configure.ac	Mon Feb 25 17:45:36 2008 +0000
     2.2 +++ b/gmyth/configure.ac	Mon Feb 25 17:51:43 2008 +0000
     2.3 @@ -121,7 +121,7 @@
     2.4  
     2.5  AC_OUTPUT(
     2.6  Makefile
     2.7 -src/Makefile
     2.8 +gmyth/Makefile
     2.9  samples/Makefile
    2.10  tests/Makefile
    2.11  gmyth.pc)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/gmyth/gmyth/Makefile.am	Mon Feb 25 17:51:43 2008 +0000
     3.3 @@ -0,0 +1,98 @@
     3.4 +lib_LTLIBRARIES = libgmyth.la
     3.5 +
     3.6 +INCLUDES = -I$(top_srcdir) -I$(top_builddir)/gmyth @GLIB_CFLAGS@ @GOBJECT_CFLAGS@
     3.7 +
     3.8 +BUILT_SOURCES =					\
     3.9 +	gmyth_marshal.c				\
    3.10 +	gmyth_marshal.h
    3.11 +
    3.12 +libgmyth_la_SOURCES =			\
    3.13 +	gmyth_common.c				\
    3.14 +	gmyth_debug.c				\
    3.15 +	gmyth_epg.c 				\
    3.16 +	gmyth_recorder.c			\
    3.17 +	gmyth_remote_util.c			\
    3.18 +	gmyth_tvchain.c				\
    3.19 +	gmyth_scheduler.c 			\
    3.20 +	gmyth_util.c				\
    3.21 +	gmyth_query.c				\
    3.22 +	gmyth_socket.c				\
    3.23 +	gmyth_stringlist.c			\
    3.24 +	gmyth_monitor_handler.c		\
    3.25 +	gmyth_file_transfer.c		\
    3.26 +	gmyth_livetv.c				\
    3.27 +	gmyth_backendinfo.c			\
    3.28 +	gmyth_programinfo.c			\
    3.29 +	gmyth_uri.c					\
    3.30 +	gmyth_http.c				\
    3.31 +	gmyth_vlc.c					\
    3.32 +	gmyth_jobqueue.c			\
    3.33 +	gmyth_transcoder.c			\
    3.34 +	gmyth_recprofile.c			\
    3.35 +	gmyth_file.c				\
    3.36 +	gmyth_file_local.c			\
    3.37 +	$(BUILT_SOURCES)
    3.38 +
    3.39 +EXTRA_libgmyth_la_SOURCES = gmyth_marshal.list
    3.40 +
    3.41 +gmyth_marshal.h: gmyth_marshal.list
    3.42 +	glib-genmarshal --header --prefix=gmyth_marshal gmyth_marshal.list > gmyth_marshal.h.tmp
    3.43 +	mv gmyth_marshal.h.tmp gmyth_marshal.h
    3.44 +
    3.45 +gmyth_marshal.c: gmyth_marshal.list gmyth_marshal.h
    3.46 +	echo "#include \"glib-object.h\"" > gmyth_marshal.c.tmp
    3.47 +	echo "#include \"gmyth_marshal.h\"" >> gmyth_marshal.c.tmp
    3.48 +	glib-genmarshal --body --prefix=gmyth_marshal $(srcdir)/gmyth_marshal.list >> gmyth_marshal.c.tmp
    3.49 +	mv gmyth_marshal.c.tmp gmyth_marshal.c
    3.50 +
    3.51 +libgmyth_la_CFLAGS = 			\
    3.52 +	-DDATADIR=\"$(pkgdatadir)\"	\
    3.53 +	$(GLIB_CFLAGS) 				\
    3.54 +	$(GOBJECT_CFLAGS)			\
    3.55 +	$(GST_CFLAGS) 				\
    3.56 +	$(GSTBASE_CFLAGS)			\
    3.57 +	$(GSTPLUGINSBASE_CFLAGS)	\
    3.58 +	$(MYSQL_CFLAGS)				\
    3.59 +	$(LIBXML_CFLAGS)
    3.60 +
    3.61 +libgmyth_la_LDFLAGS =			\
    3.62 +	-export-dynamic				\
    3.63 +	$(GLIB_CFLAGS)				\
    3.64 +	$(GOBJECT_CFLAGS)			\
    3.65 +	$(MYSQL_LIBS)				\
    3.66 +	$(GST_LIBS)					\
    3.67 +	$(GSTBASE_LIBS)				\
    3.68 +	$(GSTPLUGINS_LIBS)			\
    3.69 +	$(LIBXML_LIBS)
    3.70 +
    3.71 +libgmyth_includedir =			\
    3.72 +	$(pkgincludedir)
    3.73 +
    3.74 +libgmyth_include_HEADERS =		\
    3.75 +	gmyth.h						\
    3.76 +	gmyth_common.h	 			\
    3.77 +	gmyth_debug.h				\
    3.78 +	gmyth_epg.h					\
    3.79 +	gmyth_recorder.h			\
    3.80 +	gmyth_scheduler.h			\
    3.81 +	gmyth_tvchain.h				\
    3.82 +	gmyth_util.h				\
    3.83 +	gmyth_query.h				\
    3.84 +	gmyth_socket.h				\
    3.85 +	gmyth_remote_util.h			\
    3.86 +	gmyth_stringlist.h			\
    3.87 +	gmyth_monitor_handler.h		\
    3.88 +	gmyth_file_transfer.h		\
    3.89 +	gmyth_livetv.h				\
    3.90 +	gmyth_backendinfo.h			\
    3.91 +	gmyth_programinfo.h			\
    3.92 +	gmyth_uri.h					\
    3.93 +	gmyth_http.h				\
    3.94 +	gmyth_vlc.h					\
    3.95 +	gmyth_jobqueue.h			\
    3.96 +	gmyth_transcoder.h			\
    3.97 +	gmyth_recprofile.h			\
    3.98 +	gmyth_file.h				\
    3.99 +	gmyth_file_local.h
   3.100 +
   3.101 +CLEANFILES = $(BUILT_SOURCES)
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/gmyth/gmyth/gmyth-indent.sh	Mon Feb 25 17:51:43 2008 +0000
     4.3 @@ -0,0 +1,25 @@
     4.4 +#!/bin/sh
     4.5 +indent \
     4.6 +	-gnu \
     4.7 +	-i4 \
     4.8 +	-l80 \
     4.9 +	-bfda \
    4.10 +	-nut \
    4.11 +	-pcs \
    4.12 +	-psl \
    4.13 +	-bli0 \
    4.14 +	-cs \
    4.15 +	-cli0 \
    4.16 +	-nbfda \
    4.17 +	-sai \
    4.18 +	-saw \
    4.19 +	-saf \
    4.20 +	-sbi4 \
    4.21 +	-npro \
    4.22 +	-nfca \
    4.23 +	-nsc \
    4.24 +	-ts4 \
    4.25 +	-prs \
    4.26 +	-bap \
    4.27 +	$*
    4.28 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/gmyth/gmyth/gmyth.h	Mon Feb 25 17:51:43 2008 +0000
     5.3 @@ -0,0 +1,57 @@
     5.4 +/**
     5.5 + * GMyth Library
     5.6 + *
     5.7 + * @file gmyth/gmyth.h
     5.8 + * 
     5.9 + *
    5.10 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
    5.11 + * @author Renato Filho <renato.filho@indt.org.br>
    5.12 + *
    5.13 + *//*
    5.14 + * 
    5.15 + * This program is free software; you can redistribute it and/or modify
    5.16 + * it under the terms of the GNU Lesser General Public License as published by
    5.17 + * the Free Software Foundation; either version 2 of the License, or
    5.18 + * (at your option) any later version.
    5.19 + *
    5.20 + * This program is distributed in the hope that it will be useful,
    5.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.23 + * GNU General Public License for more details.
    5.24 + *
    5.25 + * You should have received a copy of the GNU Lesser General Public License
    5.26 + * along with this program; if not, write to the Free Software
    5.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    5.28 + */
    5.29 +
    5.30 +
    5.31 +
    5.32 +#ifndef _GMYTH_H_
    5.33 +#define _GMYTH_H_
    5.34 +
    5.35 +#include <gmyth/gmyth_backendinfo.h>
    5.36 +#include <gmyth/gmyth_common.h>
    5.37 +#include <gmyth/gmyth_debug.h>
    5.38 +#include <gmyth/gmyth_epg.h>
    5.39 +#include <gmyth/gmyth_file.h>
    5.40 +#include <gmyth/gmyth_file_local.h>
    5.41 +#include <gmyth/gmyth_file_transfer.h>
    5.42 +#include <gmyth/gmyth_livetv.h>
    5.43 +#include <gmyth/gmyth_monitor_handler.h>
    5.44 +#include <gmyth/gmyth_programinfo.h>
    5.45 +#include <gmyth/gmyth_query.h>
    5.46 +#include <gmyth/gmyth_recorder.h>
    5.47 +#include <gmyth/gmyth_remote_util.h>
    5.48 +#include <gmyth/gmyth_scheduler.h>
    5.49 +#include <gmyth/gmyth_socket.h>
    5.50 +#include <gmyth/gmyth_stringlist.h>
    5.51 +#include <gmyth/gmyth_tvchain.h>
    5.52 +#include <gmyth/gmyth_uri.h>
    5.53 +#include <gmyth/gmyth_util.h>
    5.54 +#include <gmyth/gmyth_http.h>
    5.55 +#include <gmyth/gmyth_vlc.h>
    5.56 +#include <gmyth/gmyth_jobqueue.h>
    5.57 +#include <gmyth/gmyth_transcoder.h>
    5.58 +#include <gmyth/gmyth_recprofile.h>
    5.59 +
    5.60 +#endif /* _GMYTH_H_ */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/gmyth/gmyth/gmyth_backendinfo.c	Mon Feb 25 17:51:43 2008 +0000
     6.3 @@ -0,0 +1,395 @@
     6.4 +/**
     6.5 + * GMyth Library
     6.6 + *
     6.7 + * @file gmyth/gmyth_backend_info.c
     6.8 + * 
     6.9 + * @brief <p> This component represents all the MythTV backend server
    6.10 + * 						configuration information.
    6.11 + *
    6.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
    6.13 + * @author Hallyson Melo <hallyson.melo@indt.org.br>
    6.14 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
    6.15 + *
    6.16 + * 
    6.17 + * This program is free software; you can redistribute it and/or modify
    6.18 + * it under the terms of the GNU Lesser General Public License as published by
    6.19 + * the Free Software Foundation; either version 2 of the License, or
    6.20 + * (at your option) any later version.
    6.21 + *
    6.22 + * This program is distributed in the hope that it will be useful,
    6.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.25 + * GNU General Public License for more details.
    6.26 + *
    6.27 + * You should have received a copy of the GNU Lesser General Public License
    6.28 + * along with this program; if not, write to the Free Software
    6.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    6.30 + */
    6.31 +
    6.32 +#ifdef HAVE_CONFIG_H
    6.33 +#include "config.h"
    6.34 +#endif
    6.35 +
    6.36 +#include "gmyth_backendinfo.h"
    6.37 +#include "gmyth_uri.h"
    6.38 +#include "gmyth_debug.h"
    6.39 +
    6.40 +static void     gmyth_backend_info_class_init(GMythBackendInfoClass *
    6.41 +                                              klass);
    6.42 +static void     gmyth_backend_info_init(GMythBackendInfo * object);
    6.43 +
    6.44 +static void     gmyth_backend_info_dispose(GObject * object);
    6.45 +static void     gmyth_backend_info_finalize(GObject * object);
    6.46 +
    6.47 +G_DEFINE_TYPE(GMythBackendInfo, gmyth_backend_info, G_TYPE_OBJECT);
    6.48 +static void     gmyth_backend_info_class_init(GMythBackendInfoClass *
    6.49 +                                                  klass)
    6.50 +{
    6.51 +    GObjectClass   *gobject_class;
    6.52 +
    6.53 +    gobject_class = (GObjectClass *) klass;
    6.54 +
    6.55 +    gobject_class->dispose = gmyth_backend_info_dispose;
    6.56 +    gobject_class->finalize = gmyth_backend_info_finalize;
    6.57 +}
    6.58 +
    6.59 +static void
    6.60 +gmyth_backend_info_init(GMythBackendInfo * backend_info)
    6.61 +{
    6.62 +    backend_info->hostname = NULL;
    6.63 +    backend_info->port = -1;
    6.64 +    backend_info->username = NULL;
    6.65 +    backend_info->password = NULL;
    6.66 +    backend_info->db_name = NULL;
    6.67 +    backend_info->db_port = 0;
    6.68 +    backend_info->status_port = -1;
    6.69 +}
    6.70 +
    6.71 +static void
    6.72 +gmyth_backend_info_dispose(GObject * object)
    6.73 +{
    6.74 +    GMythBackendInfo *backend_info = GMYTH_BACKEND_INFO(object);
    6.75 +
    6.76 +    g_free(backend_info->hostname);
    6.77 +    g_free(backend_info->username);
    6.78 +    g_free(backend_info->password);
    6.79 +    g_free(backend_info->db_name);
    6.80 +
    6.81 +    if (backend_info->sock)
    6.82 +        g_object_unref (backend_info->sock);
    6.83 +
    6.84 +    backend_info->hostname = NULL;
    6.85 +    backend_info->port = -1;
    6.86 +    backend_info->username = NULL;
    6.87 +    backend_info->password = NULL;
    6.88 +    backend_info->db_name = NULL;
    6.89 +    backend_info->db_port = 0;
    6.90 +    backend_info->status_port = -1;
    6.91 +    backend_info->sock = NULL;
    6.92 +
    6.93 +    G_OBJECT_CLASS(gmyth_backend_info_parent_class)->dispose(object);
    6.94 +}
    6.95 +
    6.96 +static void
    6.97 +gmyth_backend_info_finalize(GObject * object)
    6.98 +{
    6.99 +    g_signal_handlers_destroy(object);
   6.100 +
   6.101 +    G_OBJECT_CLASS(gmyth_backend_info_parent_class)->finalize(object);
   6.102 +}
   6.103 +
   6.104 +/** 
   6.105 + * Creates a new instance of GMythBackendInfo.
   6.106 + * 
   6.107 + * @return a new instance of GMythBackendInfo.
   6.108 + */
   6.109 +GMythBackendInfo *
   6.110 +gmyth_backend_info_new()
   6.111 +{
   6.112 +    GMythBackendInfo *backend_info =
   6.113 +        GMYTH_BACKEND_INFO(g_object_new(GMYTH_BACKEND_INFO_TYPE, NULL));
   6.114 +
   6.115 +    return backend_info;
   6.116 +}
   6.117 +
   6.118 +/** 
   6.119 + * Creates a new instance of GMythBackendInfo, based on a given set of 
   6.120 + * configuration parameters.
   6.121 + * 
   6.122 + * @param hostname The hostname to the MythTV backend server.
   6.123 + * @param username The user name to the MythTV backend MySQL server.
   6.124 + * @param password The password to the user of the MythTV backend MySQL server.
   6.125 + * @param db_name The database name of the MythTV backend, stored on the MySQL server.
   6.126 + * @param port The port number of the MythTV backend server (commonly is 6543).
   6.127 + * 
   6.128 + * @return a new instance of GMythBackendInfo.
   6.129 + */
   6.130 +GMythBackendInfo *
   6.131 +gmyth_backend_info_new_full(const gchar * hostname, const gchar * username,
   6.132 +                            const gchar * password, const gchar * db_name,
   6.133 +                            gint port)
   6.134 +{
   6.135 +    GMythBackendInfo *backend_info =
   6.136 +        GMYTH_BACKEND_INFO(g_object_new(GMYTH_BACKEND_INFO_TYPE, NULL));
   6.137 +
   6.138 +    gmyth_backend_info_set_hostname(backend_info, hostname);
   6.139 +    gmyth_backend_info_set_username(backend_info, username);
   6.140 +    gmyth_backend_info_set_password(backend_info, password);
   6.141 +    gmyth_backend_info_set_db_name(backend_info, db_name);
   6.142 +    gmyth_backend_info_set_port(backend_info, port);
   6.143 +
   6.144 +    return backend_info;
   6.145 +}
   6.146 +
   6.147 +/** 
   6.148 + * Creates a new instance of GMythBackendInfo, based on the 
   6.149 + * MythTV's backend server URI string.
   6.150 + * 
   6.151 + * @param uri_str The URI string pointing to the MythTV backend server.
   6.152 + * 
   6.153 + * @return a new instance of GMythBackendInfo.
   6.154 + */
   6.155 +GMythBackendInfo *
   6.156 +gmyth_backend_info_new_with_uri(const gchar * uri_str)
   6.157 +{
   6.158 +    GMythBackendInfo *backend_info;
   6.159 +    GMythURI       *uri;
   6.160 +    gchar         **path_parts;
   6.161 +    gchar          *db;
   6.162 +
   6.163 +    backend_info = GMYTH_BACKEND_INFO(g_object_new(GMYTH_BACKEND_INFO_TYPE, NULL));
   6.164 +    uri = gmyth_uri_new_with_value (uri_str);
   6.165 +    path_parts = g_strsplit(gmyth_uri_get_path(uri), "&", -1);
   6.166 +    gmyth_backend_info_set_hostname(backend_info, gmyth_uri_get_host(uri));
   6.167 +    gmyth_backend_info_set_username(backend_info, gmyth_uri_get_user(uri));
   6.168 +    gmyth_backend_info_set_password(backend_info,
   6.169 +                                    gmyth_uri_get_password(uri));
   6.170 +
   6.171 +    /*
   6.172 +     * gets the path info to database name, from the URI, and removes the
   6.173 +     * trash chars 
   6.174 +     */
   6.175 +    if ((path_parts != NULL) && (strlen (path_parts[0]) > 0))
   6.176 +    {
   6.177 +        db =  path_parts[0]+2;
   6.178 +    }
   6.179 +    else
   6.180 +    {
   6.181 +        db = gmyth_uri_get_path(uri);
   6.182 +    }
   6.183 +
   6.184 +    gmyth_backend_info_set_db_name(backend_info, db);
   6.185 +
   6.186 +    gmyth_backend_info_set_port(backend_info, gmyth_uri_get_port(uri));
   6.187 +
   6.188 +    g_object_unref(uri);
   6.189 +    g_strfreev(path_parts);
   6.190 +
   6.191 +    return backend_info;
   6.192 +}
   6.193 +
   6.194 +void
   6.195 +gmyth_backend_info_set_hostname(GMythBackendInfo * backend_info,
   6.196 +                                const gchar * hostname)
   6.197 +{
   6.198 +    g_return_if_fail(backend_info != NULL);
   6.199 +
   6.200 +    if (NULL == hostname || strlen(hostname) <= 0) {
   6.201 +        gmyth_debug("Error trying to set a hostname equals to NULL.");
   6.202 +    } else {
   6.203 +        backend_info->hostname = g_strdup(hostname);
   6.204 +    }
   6.205 +}
   6.206 +
   6.207 +void
   6.208 +gmyth_backend_info_set_username(GMythBackendInfo * backend_info,
   6.209 +                                const gchar * username)
   6.210 +{
   6.211 +    g_return_if_fail(backend_info != NULL);
   6.212 +
   6.213 +    backend_info->username = g_strdup(username);
   6.214 +}
   6.215 +
   6.216 +void
   6.217 +gmyth_backend_info_set_password(GMythBackendInfo * backend_info,
   6.218 +                                const gchar * password)
   6.219 +{
   6.220 +    g_return_if_fail(backend_info != NULL);
   6.221 +
   6.222 +    backend_info->password = g_strdup(password);
   6.223 +}
   6.224 +
   6.225 +void
   6.226 +gmyth_backend_info_set_db_name(GMythBackendInfo * backend_info,
   6.227 +                               const gchar * db_name)
   6.228 +{
   6.229 +    g_return_if_fail(backend_info != NULL);
   6.230 +
   6.231 +    backend_info->db_name = g_strdup(db_name);
   6.232 +}
   6.233 +
   6.234 +void
   6.235 +gmyth_backend_info_set_db_port(GMythBackendInfo * backend_info, gint db_port)
   6.236 +{
   6.237 +    g_return_if_fail(backend_info != NULL);
   6.238 +
   6.239 +    if (db_port <= 0) {
   6.240 +        gmyth_debug("Error trying to set a port less than 0.");
   6.241 +    } else {
   6.242 +        backend_info->db_port = db_port;
   6.243 +    }
   6.244 +}
   6.245 +
   6.246 +void
   6.247 +gmyth_backend_info_set_port(GMythBackendInfo * backend_info, gint port)
   6.248 +{
   6.249 +    g_return_if_fail(backend_info != NULL);
   6.250 +
   6.251 +    if (port <= 0) {
   6.252 +        gmyth_debug("Error trying to set a port less than 0.");
   6.253 +    } else {
   6.254 +        backend_info->port = port;
   6.255 +    }
   6.256 +}
   6.257 +
   6.258 +void
   6.259 +gmyth_backend_info_set_status_port(GMythBackendInfo * backend_info,
   6.260 +                                   gint port)
   6.261 +{
   6.262 +    g_return_if_fail(backend_info != NULL);
   6.263 +
   6.264 +    if (port <= 0) {
   6.265 +        gmyth_debug
   6.266 +            ("Error trying to set the status port to less than zero.");
   6.267 +    } else {
   6.268 +        backend_info->status_port = port;
   6.269 +    }
   6.270 +}
   6.271 +
   6.272 +const gchar    *
   6.273 +gmyth_backend_info_get_hostname(GMythBackendInfo * backend_info)
   6.274 +{
   6.275 +    g_return_val_if_fail(backend_info != NULL, NULL);
   6.276 +
   6.277 +    return backend_info->hostname;
   6.278 +}
   6.279 +
   6.280 +const gchar    *
   6.281 +gmyth_backend_info_get_username(GMythBackendInfo * backend_info)
   6.282 +{
   6.283 +    g_return_val_if_fail(backend_info != NULL, NULL);
   6.284 +
   6.285 +    return backend_info->username;
   6.286 +}
   6.287 +
   6.288 +const gchar    *
   6.289 +gmyth_backend_info_get_password(GMythBackendInfo * backend_info)
   6.290 +{
   6.291 +    g_return_val_if_fail(backend_info != NULL, NULL);
   6.292 +
   6.293 +    return backend_info->password;
   6.294 +}
   6.295 +
   6.296 +const gchar    *
   6.297 +gmyth_backend_info_get_db_name(GMythBackendInfo * backend_info)
   6.298 +{
   6.299 +    g_return_val_if_fail(backend_info != NULL, NULL);
   6.300 +
   6.301 +    return backend_info->db_name;
   6.302 +}
   6.303 +
   6.304 +gint
   6.305 +gmyth_backend_info_get_idb_port(GMythBackendInfo * backend_info)
   6.306 +{
   6.307 +    g_return_val_if_fail(backend_info != NULL, -1);
   6.308 +
   6.309 +    return backend_info->db_port;
   6.310 +}
   6.311 +
   6.312 +
   6.313 +gint
   6.314 +gmyth_backend_info_get_port(GMythBackendInfo * backend_info)
   6.315 +{
   6.316 +    g_return_val_if_fail(backend_info != NULL, -1);
   6.317 +
   6.318 +    return backend_info->port;
   6.319 +}
   6.320 +
   6.321 +/** 
   6.322 + * Creates a new instance of GMythURI, based on the GMythBackendInfo instance to the 
   6.323 + * MythTV's backend server.
   6.324 + * 
   6.325 + * @param backend_info The GMythBackendInfo instance.
   6.326 + * 
   6.327 + * @return an instance of GMythURI, created from a GMythBackendInfo.
   6.328 + */
   6.329 +GMythURI       *
   6.330 +gmyth_backend_info_get_uri(GMythBackendInfo * backend_info)
   6.331 +{
   6.332 +    GMythURI       *uri = NULL;
   6.333 +    gchar          *uri_str = NULL;
   6.334 +    gchar          *user_info = NULL;
   6.335 +    gchar          *db_data = NULL;
   6.336 +
   6.337 +    if ((backend_info->username != NULL
   6.338 +         && strlen(backend_info->username) > 0))
   6.339 +        user_info =
   6.340 +            g_strdup_printf("%s:%s@", backend_info->username,
   6.341 +                            backend_info->password);
   6.342 +
   6.343 +    if (backend_info->db_name != NULL && strlen(backend_info->db_name) > 0) {
   6.344 +        if ((g_strrstr(backend_info->db_name, "_") != NULL))
   6.345 +            db_data = g_strdup(backend_info->db_name);
   6.346 +        else
   6.347 +            db_data = g_strdup_printf("?%s&", backend_info->db_name);
   6.348 +    }
   6.349 +    // else if ( ( ( g_strrstr( backend_info->path, "livetv" ) != NULL )
   6.350 +    // || 
   6.351 +    // ( g_strrstr( backend_info->path, "/?" ) != NULL ) )
   6.352 +
   6.353 +    uri_str = g_strdup_printf("myth://%s%s:%d/%s", user_info != NULL
   6.354 +                              && strlen(user_info) > 0 ? user_info : "",
   6.355 +                              backend_info->hostname, backend_info->port,
   6.356 +                              db_data != NULL
   6.357 +                              && strlen(db_data) > 0 ? db_data : "");
   6.358 +    uri = gmyth_uri_new_with_value(uri_str);
   6.359 +
   6.360 +    if (user_info != NULL)
   6.361 +        g_free(user_info);
   6.362 +
   6.363 +    if (db_data != NULL)
   6.364 +        g_free(db_data);
   6.365 +
   6.366 +    g_free(uri_str);
   6.367 +
   6.368 +    return uri;
   6.369 +}
   6.370 +
   6.371 +gboolean
   6.372 +gmyth_backend_info_is_local_file(GMythBackendInfo * backend_info)
   6.373 +{
   6.374 +    g_return_val_if_fail(backend_info != NULL, FALSE);
   6.375 +
   6.376 +    return
   6.377 +        gmyth_uri_is_local_file(gmyth_backend_info_get_uri(backend_info));
   6.378 +}
   6.379 +
   6.380 +GMythSocket*
   6.381 +gmyth_backend_info_get_connected_socket (GMythBackendInfo *backend_info)
   6.382 +{
   6.383 +    if (backend_info->sock == NULL) {
   6.384 +        gboolean res;
   6.385 +        backend_info->sock = gmyth_socket_new ();
   6.386 +        res =  gmyth_socket_connect_to_backend (backend_info->sock,
   6.387 +                                                backend_info->hostname,
   6.388 +                                                backend_info->port,
   6.389 +                                                TRUE);
   6.390 +        if (res == FALSE) {
   6.391 +            g_object_unref (backend_info->sock);
   6.392 +            backend_info->sock = NULL;
   6.393 +            return NULL;
   6.394 +        }
   6.395 +    }
   6.396 +
   6.397 +    return g_object_ref (backend_info->sock);
   6.398 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/gmyth/gmyth/gmyth_backendinfo.h	Mon Feb 25 17:51:43 2008 +0000
     7.3 @@ -0,0 +1,121 @@
     7.4 +/**
     7.5 + * GMyth Library
     7.6 + *
     7.7 + * @file gmyth/gmyth_backend_info.h
     7.8 + * 
     7.9 + * @brief <p> This component represents all the MythTV backend server
    7.10 + * 						configuration information.
    7.11 + *
    7.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
    7.13 + * @author Hallyson Melo <hallyson.melo@indt.org.br>
    7.14 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
    7.15 + *
    7.16 +* 
    7.17 +* This program is free software; you can redistribute it and/or modify
    7.18 +* it under the terms of the GNU Lesser General Public License as published by
    7.19 +* the Free Software Foundation; either version 2 of the License, or
    7.20 +* (at your option) any later version.
    7.21 +*
    7.22 +* This program is distributed in the hope that it will be useful,
    7.23 +	* but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.24 +	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.25 +	* GNU General Public License for more details.
    7.26 +	*
    7.27 +	* You should have received a copy of the GNU Lesser General Public License
    7.28 +	* along with this program; if not, write to the Free Software
    7.29 +	* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    7.30 +	*/
    7.31 +
    7.32 +#ifndef __GMYTH_BACKEND_INFO_H__
    7.33 +#define __GMYTH_BACKEND_INFO_H__
    7.34 +
    7.35 +#include <glib-object.h>
    7.36 +
    7.37 +#include "gmyth_uri.h"
    7.38 +#include "gmyth_socket.h"
    7.39 +
    7.40 +G_BEGIN_DECLS
    7.41 +#define GMYTH_BACKEND_INFO_TYPE \
    7.42 +    (gmyth_backend_info_get_type ())
    7.43 +#define GMYTH_BACKEND_INFO(obj) \
    7.44 +    (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_BACKEND_INFO_TYPE, GMythBackendInfo))
    7.45 +#define GMYTH_BACKEND_INFO_CLASS(klass) \
    7.46 +    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_BACKEND_INFO_TYPE, GMythBackendInfoClass))
    7.47 +#define IS_GMYTH_BACKEND_INFO(obj) \
    7.48 +    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_BACKEND_INFO_TYPE))
    7.49 +#define IS_GMYTH_BACKEND_INFO_CLASS(klass) \
    7.50 +    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_BACKEND_INFO_TYPE))
    7.51 +#define GMYTH_BACKEND_INFO_GET_CLASS(obj) \
    7.52 +    (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_BACKEND_INFO_TYPE, GMythBackendInfoClass))
    7.53 +
    7.54 +typedef struct _GMythBackendInfo GMythBackendInfo;
    7.55 +typedef struct _GMythBackendInfoClass GMythBackendInfoClass;
    7.56 +
    7.57 +struct _GMythBackendInfoClass {
    7.58 +    GObjectClass    parent_class;
    7.59 +
    7.60 +    /*
    7.61 +     * callbacks 
    7.62 +     */
    7.63 +    /*
    7.64 +     * no one for now 
    7.65 +     */
    7.66 +};
    7.67 +
    7.68 +struct _GMythBackendInfo {
    7.69 +    GObject parent;
    7.70 +    /** The backend hostname or ip address. */
    7.71 +    gchar  *hostname;
    7.72 +    /** The backend port. */
    7.73 +    gint  port;
    7.74 +    /** The username to connect to the mysql server. */
    7.75 +    gchar *username;
    7.76 +    /** The password to connect to the mysql server. */
    7.77 +    gchar *password;
    7.78 +    /** The mythtv's mysql database name. */
    7.79 +    gchar *db_name;
    7.80 +    /** The mysql database port */
    7.81 +    gint  db_port;
    7.82 +    /** The backend status port for http connection */
    7.83 +    gint  status_port;
    7.84 +
    7.85 +    /* Private */
    7.86 +    GMythSocket *sock;
    7.87 +};
    7.88 +
    7.89 +
    7.90 +GType               gmyth_backend_info_get_type         (void) G_GNUC_CONST;
    7.91 +GMythBackendInfo*   gmyth_backend_info_new              (void);
    7.92 +GMythBackendInfo*   gmyth_backend_info_new_full         (const gchar        *hostname,
    7.93 +                                                         const gchar        *username,
    7.94 +                                                         const gchar        *password,
    7.95 +                                                         const gchar        *db_name,
    7.96 +                                                         gint               port);
    7.97 +GMythBackendInfo*   gmyth_backend_info_new_with_uri     (const gchar        *uri_str);
    7.98 +void                gmyth_backend_info_set_hostname     (GMythBackendInfo   *backend_info,
    7.99 +                                                         const gchar        *hostname);
   7.100 +void                gmyth_backend_info_set_username     (GMythBackendInfo   *backend_info,
   7.101 +                                                         const gchar        *username);
   7.102 +void                gmyth_backend_info_set_password     (GMythBackendInfo   *backend_info,
   7.103 +                                                         const gchar        *password);
   7.104 +void                gmyth_backend_info_set_db_name      (GMythBackendInfo   *backend_info,
   7.105 +                                                         const gchar        *db_name);
   7.106 +void                gmyth_backend_info_set_db_port      (GMythBackendInfo   *backend_info,
   7.107 +                                                         gint               db_port);
   7.108 +void                gmyth_backend_info_set_port         (GMythBackendInfo   *backend_info,
   7.109 +                                                         gint               port);
   7.110 +void                gmyth_backend_info_set_status_port  (GMythBackendInfo   *backend_info,
   7.111 +                                                         gint               port);
   7.112 +const gchar*        gmyth_backend_info_get_hostname     (GMythBackendInfo   *backend_info);
   7.113 +const gchar*        gmyth_backend_info_get_username     (GMythBackendInfo   *backend_info);
   7.114 +const gchar*        gmyth_backend_info_get_password     (GMythBackendInfo   *backend_info);
   7.115 +const gchar*        gmyth_backend_info_get_db_name      (GMythBackendInfo   *backend_info);
   7.116 +gint                gmyth_backend_info_get_db_port         (GMythBackendInfo   *backend_info);
   7.117 +gint                gmyth_backend_info_get_port         (GMythBackendInfo   *backend_info);
   7.118 +GMythURI*           gmyth_backend_info_get_uri          (GMythBackendInfo   *backend_info);
   7.119 +gboolean            gmyth_backend_info_is_local_file    (GMythBackendInfo   *backend_info);
   7.120 +GMythSocket*        gmyth_backend_info_get_connected_socket
   7.121 +                                                        (GMythBackendInfo   *backend_info);
   7.122 +
   7.123 +G_END_DECLS
   7.124 +#endif                          /* __GMYTH_BACKEND_INFO_H__ */
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/gmyth/gmyth/gmyth_common.c	Mon Feb 25 17:51:43 2008 +0000
     8.3 @@ -0,0 +1,154 @@
     8.4 +/**
     8.5 + * GMyth Library
     8.6 + *
     8.7 + * @file gmyth/gmyth_common.c
     8.8 + * 
     8.9 + * @brief <p> This file contains basic common functions for the gmyth library.
    8.10 + *
    8.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
    8.12 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
    8.13 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
    8.14 + *
    8.15 + * 
    8.16 + * This program is free software; you can redistribute it and/or modify
    8.17 + * it under the terms of the GNU Lesser General Public License as published by
    8.18 + * the Free Software Foundation; either version 2 of the License, or
    8.19 + * (at your option) any later version.
    8.20 + *
    8.21 + * This program is distributed in the hope that it will be useful,
    8.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.24 + * GNU General Public License for more details.
    8.25 + *
    8.26 + * You should have received a copy of the GNU Lesser General Public License
    8.27 + * along with this program; if not, write to the Free Software
    8.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.29 + */
    8.30 +
    8.31 +#ifdef HAVE_CONFIG_H
    8.32 +#include "config.h"
    8.33 +#endif
    8.34 +
    8.35 +#include "gmyth_common.h"
    8.36 +#include "gmyth_debug.h"
    8.37 +#include "gmyth_util.h"
    8.38 +
    8.39 +static void     free_channel_data(gpointer data, gpointer user_data);
    8.40 +static void     free_program_data(gpointer data, gpointer user_data);
    8.41 +
    8.42 +/** 
    8.43 +* Frees the memory allocated to the GMythChannelInfo objects inside list.
    8.44 +* The list memory is also released by g_list_free(). If LIST is NULL it
    8.45 +* simply returns.
    8.46 +* 
    8.47 +* @param list the GList containing a list of GMythChannelInfo to free.
    8.48 +*/
    8.49 +void
    8.50 +gmyth_free_channel_list(GList * list)
    8.51 +{
    8.52 +    g_return_if_fail(list != NULL);
    8.53 +
    8.54 +    g_list_foreach(list, free_channel_data, NULL);
    8.55 +    g_list_free(list);
    8.56 +}
    8.57 +
    8.58 +/** 
    8.59 + * Frees the memory allocated to the GMythProgramInfo objects inside list.
    8.60 + * The list memory is also released by g_list_free(). If list is NULL it
    8.61 + * simply returns.
    8.62 + * 
    8.63 + * @param list the GList containing a list of GMythProgramInfo to free.
    8.64 + */
    8.65 +void
    8.66 +gmyth_free_program_list(GList * list)
    8.67 +{
    8.68 +    g_return_if_fail(list != NULL);
    8.69 +
    8.70 +    g_list_foreach(list, free_program_data, NULL);
    8.71 +    g_list_free(list);
    8.72 +}
    8.73 +
    8.74 +void
    8.75 +gmyth_channel_info_free(GMythChannelInfo * channel)
    8.76 +{
    8.77 +    g_return_if_fail(channel != NULL);
    8.78 +
    8.79 +    if (channel->channel_num)
    8.80 +        g_string_free(channel->channel_num, TRUE);
    8.81 +
    8.82 +    if (channel->channel_name)
    8.83 +        g_string_free(channel->channel_name, TRUE);
    8.84 +
    8.85 +    if (channel->channel_icon)
    8.86 +        g_string_free(channel->channel_icon, TRUE);
    8.87 +
    8.88 +    g_free(channel);
    8.89 +}
    8.90 +
    8.91 +/**
    8.92 + * Prints the channel info to the standard output. The gmyth debug must be enabled.
    8.93 + * @param channel_info the GMythChannelInfo instance
    8.94 + */
    8.95 +void
    8.96 +gmyth_channel_info_print(GMythChannelInfo * channel_info)
    8.97 +{
    8.98 +#ifdef GMYTH_USE_DEBUG
    8.99 +    if (channel_info != NULL) {
   8.100 +        g_return_if_fail(channel_info->channel_name != NULL);
   8.101 +        g_return_if_fail(channel_info->channel_num != NULL);
   8.102 +
   8.103 +        gmyth_debug("ChannelInfo (Name, Num, ID) = (%s, %s, %d)",
   8.104 +                    channel_info->channel_name->str,
   8.105 +                    channel_info->channel_num->str,
   8.106 +                    channel_info->channel_ID);
   8.107 +
   8.108 +    }
   8.109 +#endif
   8.110 +}
   8.111 +
   8.112 +/**
   8.113 + * Prints the program info to the standard output. The gmyth debug must be enabled.
   8.114 + * @param channel_info the GMythProgramInfo instance
   8.115 + */
   8.116 +void
   8.117 +gmyth_program_info_print(GMythProgramInfo * program_info)
   8.118 +{
   8.119 +#ifdef GMYTH_USE_DEBUG
   8.120 +    g_return_if_fail(program_info);
   8.121 +
   8.122 +    gmyth_debug("ProgramInfo\n\tTitle = %s\n\t"
   8.123 +                "Description = %s\n\t"
   8.124 +                "Start time= %s\t"
   8.125 +                "End time = %s\n"
   8.126 +                "Path name = %s\n"
   8.127 +                "File size = %lld\n",
   8.128 +                program_info->title ? program_info->title->str : "NULL",
   8.129 +                program_info->description ? program_info->description->
   8.130 +                str : "NULL",
   8.131 +                gmyth_util_time_to_string_from_time_val(program_info->
   8.132 +                                                        startts),
   8.133 +                gmyth_util_time_to_string_from_time_val(program_info->
   8.134 +                                                        endts),
   8.135 +                program_info->pathname ? program_info->pathname->
   8.136 +                str : "NULL", program_info->filesize);
   8.137 +#endif
   8.138 +}
   8.139 +
   8.140 +static void
   8.141 +free_channel_data(gpointer data, gpointer user_data)
   8.142 +{
   8.143 +    /*
   8.144 +     * Frees the GMythChannelInfo structure 
   8.145 +     */
   8.146 +    GMythChannelInfo *channel = (GMythChannelInfo *) data;
   8.147 +
   8.148 +    gmyth_channel_info_free(channel);
   8.149 +}
   8.150 +
   8.151 +static void
   8.152 +free_program_data(gpointer data, gpointer user_data)
   8.153 +{
   8.154 +    g_return_if_fail(data != NULL);
   8.155 +
   8.156 +    g_object_unref((GMythProgramInfo *) data);
   8.157 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/gmyth/gmyth/gmyth_common.h	Mon Feb 25 17:51:43 2008 +0000
     9.3 @@ -0,0 +1,62 @@
     9.4 +/**
     9.5 + * GMyth Library
     9.6 + * 
     9.7 + * @file gmyth/gmyth_common.h
     9.8 + * 
     9.9 + * @brief <p> This file contains basic common functions for the gmyth library.
    9.10 + *
    9.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
    9.12 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
    9.13 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
    9.14 + *
    9.15 + * 
    9.16 + * This program is free software; you can redistribute it and/or modify
    9.17 + * it under the terms of the GNU Lesser General Public License as published by
    9.18 + * the Free Software Foundation; either version 2 of the License, or
    9.19 + * (at your option) any later version.
    9.20 + *
    9.21 + * This program is distributed in the hope that it will be useful,
    9.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9.24 + * GNU General Public License for more details.
    9.25 + *
    9.26 + * You should have received a copy of the GNU Lesser General Public License
    9.27 + * along with this program; if not, write to the Free Software
    9.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    9.29 + */
    9.30 +
    9.31 +#ifndef GMYTH_COMMON_H_
    9.32 +#define GMYTH_COMMON_H_
    9.33 +
    9.34 +#include <glib.h>
    9.35 +#include <time.h>
    9.36 +
    9.37 +#include "gmyth_programinfo.h"
    9.38 +
    9.39 +G_BEGIN_DECLS
    9.40 +    /**
    9.41 +    * The GMythChannelInfo structure represents the channel information
    9.42 +    * stored in the backend database.
    9.43 +    */
    9.44 +    typedef struct {
    9.45 +    /** The channel ID in backend database */
    9.46 +    gint            channel_ID;
    9.47 +
    9.48 +    /** The channel number */
    9.49 +    GString        *channel_num;
    9.50 +
    9.51 +    /** The channel name in backend database */
    9.52 +    GString        *channel_name;
    9.53 +
    9.54 +    /** The channel icon path in the backend database */
    9.55 +    GString        *channel_icon;
    9.56 +} GMythChannelInfo;
    9.57 +
    9.58 +void            gmyth_free_channel_list     (GList *list);
    9.59 +void            gmyth_free_program_list     (GList *list);
    9.60 +void            gmyth_channel_info_free     (GMythChannelInfo *channel_info);
    9.61 +void            gmyth_channel_info_print    (GMythChannelInfo *channel_info);
    9.62 +void            gmyth_program_info_print    (GMythProgramInfo *program_info);
    9.63 +
    9.64 +G_END_DECLS
    9.65 +#endif                          /* GMYTH_COMMON_H_ */
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/gmyth/gmyth/gmyth_debug.c	Mon Feb 25 17:51:43 2008 +0000
    10.3 @@ -0,0 +1,54 @@
    10.4 +/**
    10.5 + * GMyth Library
    10.6 + *
    10.7 + * @file gmyth/gmyth_debug.c
    10.8 + * 
    10.9 + *
   10.10 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   10.11 + * @author Renato Filho <renato.filho@indt.org.br>
   10.12 + *
   10.13 + * 
   10.14 + * This program is free software; you can redistribute it and/or modify
   10.15 + * it under the terms of the GNU Lesser General Public License as published by
   10.16 + * the Free Software Foundation; either version 2 of the License, or
   10.17 + * (at your option) any later version.
   10.18 + *
   10.19 + * This program is distributed in the hope that it will be useful,
   10.20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.22 + * GNU General Public License for more details.
   10.23 + *
   10.24 + * You should have received a copy of the GNU Lesser General Public License
   10.25 + * along with this program; if not, write to the Free Software
   10.26 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   10.27 + */
   10.28 +
   10.29 +#ifdef HAVE_CONFIG_H
   10.30 +#include "config.h"
   10.31 +#endif
   10.32 +
   10.33 +#include "gmyth_debug.h"
   10.34 +
   10.35 +void
   10.36 +gmyth_debug_real(const char *func,
   10.37 +                 const char *file, const int line, gboolean newline,
   10.38 +                 const char *format, ...)
   10.39 +{
   10.40 +    va_list         args;
   10.41 +    char            buffer[1025];
   10.42 +    char            str_time[255];
   10.43 +    time_t          the_time;
   10.44 +
   10.45 +    va_start(args, format);
   10.46 +
   10.47 +    g_vsnprintf(buffer, 1024, format, args);
   10.48 +
   10.49 +    va_end(args);
   10.50 +
   10.51 +    time(&the_time);
   10.52 +    strftime(str_time, 254, "%H:%M:%S", localtime(&the_time));
   10.53 +
   10.54 +    g_printerr(newline ? "(%s) [%p] [%s] %s:%d: %s\n" :
   10.55 +               "(%s) [%p] [%s] %s:%d: %s", str_time, g_thread_self(), func,
   10.56 +               file, line, buffer);
   10.57 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/gmyth/gmyth/gmyth_debug.h	Mon Feb 25 17:51:43 2008 +0000
    11.3 @@ -0,0 +1,46 @@
    11.4 +/**
    11.5 + * GMyth Library
    11.6 + *
    11.7 + * @file gmyth/gmyth_debug.h
    11.8 + * 
    11.9 + *
   11.10 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   11.11 + * @author Renato Filho <renato.filho@indt.org.br>
   11.12 + *
   11.13 +* 
   11.14 +* This program is free software; you can redistribute it and/or modify
   11.15 +* it under the terms of the GNU Lesser General Public License as published by
   11.16 +* the Free Software Foundation; either version 2 of the License, or
   11.17 +* (at your option) any later version.
   11.18 +*
   11.19 +* This program is distributed in the hope that it will be useful,
   11.20 +	* but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.21 +	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.22 +	* GNU General Public License for more details.
   11.23 +	*
   11.24 +	* You should have received a copy of the GNU Lesser General Public License
   11.25 +	* along with this program; if not, write to the Free Software
   11.26 +	* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   11.27 +	*/
   11.28 +
   11.29 +#ifndef __GMYTH_DEBUG_H__
   11.30 +#define __GMYTH_DEBUG_H__
   11.31 +
   11.32 +#include <stdarg.h>
   11.33 +#include <glib.h>
   11.34 +#include <time.h>
   11.35 +
   11.36 +G_BEGIN_DECLS
   11.37 +#ifdef GMYTH_USE_DEBUG
   11.38 +#define gmyth_debug(...) gmyth_debug_real (__FUNCTION__, __FILE__, __LINE__, TRUE, __VA_ARGS__)
   11.39 +#else
   11.40 +#define gmyth_debug(...)
   11.41 +#endif
   11.42 +    void
   11.43 +gmyth_debug_real(const char *func,
   11.44 +                 const char *file, int line, gboolean newline,
   11.45 +                 const char *format, ...)
   11.46 +G_GNUC_PRINTF(5, 6);
   11.47 +
   11.48 +G_END_DECLS
   11.49 +#endif
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/gmyth/gmyth/gmyth_epg.c	Mon Feb 25 17:51:43 2008 +0000
    12.3 @@ -0,0 +1,446 @@
    12.4 +/**
    12.5 + * GMyth Library
    12.6 + *
    12.7 + * @file gmyth/gmyth_epg.c
    12.8 + * 
    12.9 + * @brief <p> GMythEPG class provides access to the program and channel data
   12.10 + * from the Electronic Program Guide (EPG) of the Mythtv backend.
   12.11 + *
   12.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   12.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   12.14 + * 
   12.15 + * This program is free software; you can redistribute it and/or modify
   12.16 + * it under the terms of the GNU Lesser General Public License as published by
   12.17 + * the Free Software Foundation; either version 2 of the License, or
   12.18 + * (at your option) any later version.
   12.19 + *
   12.20 + * This program is distributed in the hope that it will be useful,
   12.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.23 + * GNU General Public License for more details.
   12.24 + *
   12.25 + * You should have received a copy of the GNU Lesser General Public License
   12.26 + * along with this program; if not, write to the Free Software
   12.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   12.28 + */
   12.29 +
   12.30 +#ifdef HAVE_CONFIG_H
   12.31 +#include "config.h"
   12.32 +#endif
   12.33 +
   12.34 +#include <mysql/mysql.h>
   12.35 +#include <stdlib.h>
   12.36 +#include <string.h>
   12.37 +#include <assert.h>
   12.38 +
   12.39 +#include "gmyth_epg.h"
   12.40 +#include "gmyth_programinfo.h"
   12.41 +#include "gmyth_util.h"
   12.42 +#include "gmyth_file_transfer.h"
   12.43 +#include "gmyth_debug.h"
   12.44 +
   12.45 +#define CONNECT_TIMEOUT 6
   12.46 +
   12.47 +static void     gmyth_epg_class_init(GMythEPGClass * klass);
   12.48 +static void     gmyth_epg_init(GMythEPG * object);
   12.49 +
   12.50 +static void     gmyth_epg_dispose(GObject * object);
   12.51 +static void     gmyth_epg_finalize(GObject * object);
   12.52 +
   12.53 +G_DEFINE_TYPE(GMythEPG, gmyth_epg, G_TYPE_OBJECT)
   12.54 +    static void     gmyth_epg_class_init(GMythEPGClass * klass)
   12.55 +{
   12.56 +    GObjectClass   *gobject_class = G_OBJECT_CLASS(klass);
   12.57 +
   12.58 +    gobject_class->dispose = gmyth_epg_dispose;
   12.59 +    gobject_class->finalize = gmyth_epg_finalize;
   12.60 +}
   12.61 +
   12.62 +static void
   12.63 +gmyth_epg_init(GMythEPG * gmyth_epg)
   12.64 +{
   12.65 +
   12.66 +}
   12.67 +
   12.68 +static void
   12.69 +gmyth_epg_dispose(GObject * object)
   12.70 +{
   12.71 +    GMythEPG       *gmyth_epg = GMYTH_EPG(object);
   12.72 +
   12.73 +    if (gmyth_epg->sqlquery != NULL) {
   12.74 +        g_object_unref(gmyth_epg->sqlquery);
   12.75 +        gmyth_epg->sqlquery = NULL;
   12.76 +    }
   12.77 +
   12.78 +    G_OBJECT_CLASS(gmyth_epg_parent_class)->dispose(object);
   12.79 +}
   12.80 +
   12.81 +static void
   12.82 +gmyth_epg_finalize(GObject * object)
   12.83 +{
   12.84 +    g_signal_handlers_destroy(object);
   12.85 +
   12.86 +    G_OBJECT_CLASS(gmyth_epg_parent_class)->finalize(object);
   12.87 +}
   12.88 +
   12.89 +/**
   12.90 + * Creates a new instance of GMythEPG.
   12.91 + * 
   12.92 + * @return a new instance of GMythEPG.
   12.93 + */
   12.94 +GMythEPG       *
   12.95 +gmyth_epg_new(void)
   12.96 +{
   12.97 +    GMythEPG       *epg = GMYTH_EPG(g_object_new(GMYTH_EPG_TYPE, NULL));
   12.98 +
   12.99 +    return epg;
  12.100 +}
  12.101 +
  12.102 +/** Connects to the Mysql database in the backend. The backend address
  12.103 + * is loaded from the GMythSettings instance.
  12.104 + *
  12.105 + * @param gmyth_epg the GMythEPG instance to be connected.
  12.106 + * @return true if connection was success, false if failed.
  12.107 + */
  12.108 +gboolean
  12.109 +gmyth_epg_connect(GMythEPG * gmyth_epg, GMythBackendInfo * backend_info)
  12.110 +{
  12.111 +    g_return_val_if_fail(gmyth_epg != NULL, FALSE);
  12.112 +
  12.113 +    if (gmyth_epg->sqlquery == NULL) {
  12.114 +        gmyth_debug("[%s] Creating gmyth_query", __FUNCTION__);
  12.115 +        gmyth_epg->sqlquery = gmyth_query_new();
  12.116 +    }
  12.117 +
  12.118 +    if (!gmyth_query_connect_with_timeout(gmyth_epg->sqlquery,
  12.119 +                                          backend_info, CONNECT_TIMEOUT)) {
  12.120 +        gmyth_debug("[%s] Error while connecting to db", __FUNCTION__);
  12.121 +        return FALSE;
  12.122 +    }
  12.123 +
  12.124 +    gmyth_epg->backend_info = backend_info;
  12.125 +    g_object_ref(backend_info);
  12.126 +
  12.127 +    return TRUE;
  12.128 +}
  12.129 +
  12.130 +/** Disconnects from the Mysql database in the backend.
  12.131 + *
  12.132 + * @param gmyth_epg the GMythEPG instance to be disconnected
  12.133 + * @return true if disconnection was success, false if failed.
  12.134 + */
  12.135 +gboolean
  12.136 +gmyth_epg_disconnect(GMythEPG * gmyth_epg)
  12.137 +{
  12.138 +    g_return_val_if_fail(gmyth_epg != NULL, FALSE);
  12.139 +
  12.140 +    if (gmyth_epg->sqlquery != NULL) {
  12.141 +        gmyth_query_disconnect(gmyth_epg->sqlquery);
  12.142 +        g_object_unref(gmyth_epg->sqlquery);
  12.143 +        gmyth_epg->sqlquery = NULL;
  12.144 +    }
  12.145 +
  12.146 +    if (gmyth_epg->backend_info != NULL) {
  12.147 +        g_object_unref(gmyth_epg->backend_info);
  12.148 +        gmyth_epg->backend_info = NULL;
  12.149 +    }
  12.150 +
  12.151 +    return TRUE;
  12.152 +}
  12.153 +
  12.154 +/** Retrieves the available list of channels from the backend Mysql database.
  12.155 + * 
  12.156 + * @param gmyth_epg the GMythEPG instance.
  12.157 + * @param glist_ptr the GSList pointer to be filled with the loaded list address.
  12.158 + * @return The amount of channels retrieved from database,  or -1 if error.
  12.159 + */
  12.160 +gint
  12.161 +gmyth_epg_get_channel_list(GMythEPG * gmyth_epg, GList ** glist_ptr)
  12.162 +{
  12.163 +    MYSQL_RES      *msql_res;
  12.164 +
  12.165 +    g_return_val_if_fail(gmyth_epg != NULL, -1);
  12.166 +
  12.167 +    msql_res = gmyth_query_process_statement(gmyth_epg->sqlquery,
  12.168 +                                             "SELECT chanid, channum, name, icon FROM channel;");
  12.169 +
  12.170 +    (*glist_ptr) = NULL;
  12.171 +
  12.172 +    if (msql_res == NULL) {
  12.173 +        gmyth_debug("[%s] msql query returned NULL MYSQL_RES",
  12.174 +                    __FUNCTION__);
  12.175 +        return -1;
  12.176 +    } else {
  12.177 +        MYSQL_ROW       row;
  12.178 +        GMythChannelInfo *channel_info;
  12.179 +
  12.180 +        while ((row = mysql_fetch_row(msql_res)) != NULL) {
  12.181 +
  12.182 +            channel_info = g_new0(GMythChannelInfo, 1);
  12.183 +            channel_info->channel_ID =
  12.184 +                (gint) g_ascii_strtoull(row[0], NULL, 10);
  12.185 +            channel_info->channel_num = g_string_new(row[1]);
  12.186 +            channel_info->channel_name = g_string_new(row[2]);
  12.187 +            channel_info->channel_icon = g_string_new(row[3]);
  12.188 +#ifdef GMYTH_USE_DEBUG
  12.189 +            gmyth_channel_info_print(channel_info);
  12.190 +#endif
  12.191 +            (*glist_ptr) = g_list_append((*glist_ptr), channel_info);
  12.192 +        }
  12.193 +    }
  12.194 +    mysql_free_result(msql_res);
  12.195 +
  12.196 +    return (!(*glist_ptr)) ? 0 : g_list_length(*glist_ptr);
  12.197 +}
  12.198 +
  12.199 +GMythChannelInfo *
  12.200 +gmyth_epg_get_channel_info(GMythEPG * gmyth_epg, gint channel_id)
  12.201 +{
  12.202 +    GMythChannelInfo *channel_info = NULL;
  12.203 +    MYSQL_RES      *msql_res;
  12.204 +    gchar          *query_str;
  12.205 +
  12.206 +    g_return_val_if_fail(gmyth_epg != NULL, NULL);
  12.207 +
  12.208 +    query_str =
  12.209 +        g_strdup_printf
  12.210 +        ("SELECT channum, name, icon FROM channel WHERE chanid=%d;",
  12.211 +         channel_id);
  12.212 +    msql_res =
  12.213 +        gmyth_query_process_statement(gmyth_epg->sqlquery, query_str);
  12.214 +
  12.215 +    if (msql_res == NULL) {
  12.216 +        gmyth_debug("[%s] msql query returned NULL MYSQL_RES",
  12.217 +                    __FUNCTION__);
  12.218 +        return NULL;
  12.219 +    } else {
  12.220 +        MYSQL_ROW       row;
  12.221 +
  12.222 +        if ((row = mysql_fetch_row(msql_res)) != NULL) {
  12.223 +
  12.224 +            channel_info = g_new0(GMythChannelInfo, 1);
  12.225 +            channel_info->channel_ID = channel_id;
  12.226 +            channel_info->channel_num = g_string_new(row[0]);
  12.227 +            channel_info->channel_name = g_string_new(row[1]);
  12.228 +            channel_info->channel_icon = g_string_new(row[2]);
  12.229 +#ifdef GMYTH_USE_DEBUG
  12.230 +            gmyth_channel_info_print(channel_info);
  12.231 +#endif
  12.232 +        }
  12.233 +    }
  12.234 +    mysql_free_result(msql_res);
  12.235 +
  12.236 +    return channel_info;
  12.237 +}
  12.238 +
  12.239 +/** 
  12.240 + * Retrieves the available list of channels from the backend Mysql database.
  12.241 + * 
  12.242 + * @param gmyth_epg the GMythEPG instance.
  12.243 + * @param proglist the GSList pointer to be filled with the loaded list.
  12.244 + * @param chan_num the channel num on which to search for program.
  12.245 + * @param starttime the start time to search for programs.
  12.246 + * @param endtime the end time to search for programs.
  12.247 + * @return The amount of channels retrieved from database, or -1 if error.
  12.248 + */
  12.249 +gint
  12.250 +gmyth_epg_get_program_list(GMythEPG * gmyth_epg, GList ** proglist,
  12.251 +                           const gint chan_num, GTimeVal * starttime,
  12.252 +                           GTimeVal * endtime)
  12.253 +{
  12.254 +
  12.255 +    gchar          *startts =
  12.256 +        gmyth_util_time_to_string_from_time_val(starttime);
  12.257 +    gchar          *endts =
  12.258 +        gmyth_util_time_to_string_from_time_val(endtime);
  12.259 +    MYSQL_ROW       row;
  12.260 +    GString        *querystr;
  12.261 +
  12.262 +    assert(gmyth_epg);
  12.263 +
  12.264 +    querystr =
  12.265 +        g_string_new
  12.266 +        ("SELECT DISTINCT program.chanid, program.starttime, program.endtime, "
  12.267 +         "    program.title, program.subtitle, program.description, "
  12.268 +         "    program.category, channel.channum, channel.callsign, "
  12.269 +         "    channel.name, program.previouslyshown, channel.commfree, "
  12.270 +         "    channel.outputfilters, program.seriesid, program.programid, "
  12.271 +         "    program.airdate, program.stars, program.originalairdate, "
  12.272 +         "    program.category_type, record.recordid, "
  12.273 +         "    oldrecstatus.rectype, oldrecstatus.recstatus, "
  12.274 +         "    oldrecstatus.findid "
  12.275 +         "FROM program "
  12.276 +         "LEFT JOIN channel ON program.chanid = channel.chanid "
  12.277 +         "LEFT JOIN record ON "
  12.278 +         "    program.chanid = record.chanid AND "
  12.279 +         "    DATE (program.starttime) = record.startdate AND "
  12.280 +         "    TIME (program.starttime) = record.starttime AND "
  12.281 +         "    DATE (program.endtime) = record.enddate AND "
  12.282 +         "    TIME (program.endtime) = record.endtime "
  12.283 +         "LEFT JOIN oldrecorded AS oldrecstatus ON "
  12.284 +         "    program.title = oldrecstatus.title AND "
  12.285 +         "    channel.callsign = oldrecstatus.station AND "
  12.286 +         "    program.starttime = oldrecstatus.starttime ");
  12.287 +
  12.288 +    g_string_append_printf(querystr,
  12.289 +                           "WHERE program.chanid = %d "
  12.290 +                           "  AND program.endtime >= '%s' "
  12.291 +                           "  AND program.starttime <= '%s' "
  12.292 +                           "  AND program.manualid = 0 ", chan_num,
  12.293 +                           startts, endts);
  12.294 +
  12.295 +    if (!g_strrstr(querystr->str, " GROUP BY "))
  12.296 +        querystr = g_string_append(querystr,
  12.297 +                                   " GROUP BY program.starttime, channel.channum, "
  12.298 +                                   "  channel.callsign, program.title ");
  12.299 +
  12.300 +    if (!g_strrstr(querystr->str, " LIMIT "))
  12.301 +        querystr = g_string_append(querystr, " LIMIT 1000 ");
  12.302 +
  12.303 +    MYSQL_RES      *res_set =
  12.304 +        gmyth_query_process_statement(gmyth_epg->sqlquery, querystr->str);
  12.305 +
  12.306 +    if (res_set == NULL) {
  12.307 +        gmyth_debug("[%s] msql query returned NULL MYSQL_RES",
  12.308 +                    __FUNCTION__);
  12.309 +        return -1;
  12.310 +    }
  12.311 +
  12.312 +    *proglist = NULL;
  12.313 +    while ((row = mysql_fetch_row(res_set)) != NULL) {
  12.314 +
  12.315 +        GMythProgramInfo *p = gmyth_program_info_new();
  12.316 +
  12.317 +        p->channel_id = (int) g_ascii_strtoull (row[0], NULL, 10);
  12.318 +
  12.319 +        p->startts = gmyth_util_string_to_time_val(row[1]);
  12.320 +        p->endts = gmyth_util_string_to_time_val(row[2]);
  12.321 +
  12.322 +        p->recstartts = g_new0(GTimeVal, 1);
  12.323 +        p->recstartts->tv_sec = p->startts->tv_sec;
  12.324 +        p->recstartts->tv_usec = p->startts->tv_usec;
  12.325 +
  12.326 +        p->recendts = g_new0(GTimeVal, 1);
  12.327 +        p->recendts->tv_sec = p->endts->tv_sec;
  12.328 +        p->recendts->tv_usec = p->endts->tv_usec;
  12.329 +
  12.330 +        p->lastmodified = g_new0(GTimeVal, 1);
  12.331 +        p->lastmodified->tv_sec = p->startts->tv_sec;
  12.332 +        p->lastmodified->tv_usec = p->startts->tv_usec;
  12.333 +
  12.334 +
  12.335 +        p->title = g_string_new(row[3]);
  12.336 +        p->subtitle = g_string_new(row[4]);
  12.337 +        p->description = g_string_new(row[5]);
  12.338 +        p->category = g_string_new(row[6]);
  12.339 +        p->chanstr = g_string_new(row[7]);
  12.340 +        p->chansign = g_string_new(row[8]);
  12.341 +        p->channame = g_string_new(row[9]);
  12.342 +        p->repeat = g_ascii_strtoull(row[10], NULL, 10);
  12.343 +        p->chancommfree = g_ascii_strtoull(row[11], NULL, 10);
  12.344 +        p->chanOutputFilters = g_string_new(row[12]);
  12.345 +        p->seriesid = g_string_new(row[13]);
  12.346 +        p->program_id = g_string_new(row[14]);
  12.347 +        p->year = g_string_new(row[15]);
  12.348 +        p->stars = g_ascii_strtod(row[16], NULL);
  12.349 +
  12.350 +        if (!row[17] || !strcmp(row[17], "")) {
  12.351 +            p->originalAirDate = 0;
  12.352 +            p->hasAirDate = FALSE;
  12.353 +        } else {
  12.354 +            p->originalAirDate = gmyth_util_string_to_time_val(row[17]);
  12.355 +            p->hasAirDate = TRUE;
  12.356 +        }
  12.357 +
  12.358 +        p->catType = g_string_new(row[18]);
  12.359 +        if (row[19] != NULL)
  12.360 +            p->recordid =  g_ascii_strtoull(row[19], NULL, 10);
  12.361 +
  12.362 +        *proglist = g_list_append(*proglist, p);
  12.363 +
  12.364 +#ifdef GMYTH_USE_DEBUG
  12.365 +        gmyth_program_info_print(p);
  12.366 +#endif
  12.367 +    }
  12.368 +
  12.369 +    /*
  12.370 +     * deallocate 
  12.371 +     */
  12.372 +    mysql_free_result(res_set);
  12.373 +    g_string_free(querystr, TRUE);
  12.374 +
  12.375 +    return g_list_length (*proglist);
  12.376 +}
  12.377 +
  12.378 +gboolean
  12.379 +gmyth_epg_channel_has_icon(GMythEPG * gmyth_epg,
  12.380 +                           GMythChannelInfo * channel_info)
  12.381 +{
  12.382 +    gboolean        res = FALSE;
  12.383 +
  12.384 +    g_return_val_if_fail(gmyth_epg != NULL, FALSE);
  12.385 +    g_return_val_if_fail(channel_info != NULL, FALSE);
  12.386 +
  12.387 +    if (channel_info->channel_icon != NULL) {
  12.388 +        res = gmyth_util_file_exists(gmyth_epg->backend_info,
  12.389 +                                     channel_info->channel_icon->str);
  12.390 +    }
  12.391 +
  12.392 +    return res;
  12.393 +
  12.394 +}
  12.395 +
  12.396 +/**
  12.397 + * 
  12.398 + * @param data the data pointer to be filled with icon binary data. It must be freed by the calling function.
  12.399 + * @return TRUE if success, FALSE if any error happens.
  12.400 + */
  12.401 +gboolean
  12.402 +gmyth_epg_channel_get_icon(GMythEPG * gmyth_epg,
  12.403 +                           GMythChannelInfo * channel_info, guint8 ** data,
  12.404 +                           guint * length)
  12.405 +{
  12.406 +    gboolean res = FALSE;
  12.407 +
  12.408 +    g_return_val_if_fail(gmyth_epg != NULL, FALSE);
  12.409 +    g_return_val_if_fail(channel_info != NULL, FALSE);
  12.410 +
  12.411 +    if (gmyth_epg_channel_has_icon(gmyth_epg, channel_info)) {
  12.412 +        GMythFileTransfer *transfer =
  12.413 +            gmyth_file_transfer_new(gmyth_epg->backend_info);
  12.414 +
  12.415 +        GMythFileReadResult gmyth_res;
  12.416 +        GByteArray *icon_data;
  12.417 +        guint64 icon_length = 0;
  12.418 +
  12.419 +        res = gmyth_file_transfer_open(transfer,
  12.420 +                                       channel_info->channel_icon->str);
  12.421 +        if (!res) {
  12.422 +            gmyth_debug("Channel icon could not be opened");
  12.423 +            return FALSE;
  12.424 +        }
  12.425 +
  12.426 +        icon_length = gmyth_file_transfer_get_filesize(transfer);
  12.427 +        if (icon_length <= 0) {
  12.428 +            gmyth_debug("Channel icon file size is zero or negative");
  12.429 +            return FALSE;
  12.430 +        }
  12.431 +
  12.432 +        icon_data = g_byte_array_new();
  12.433 +        gmyth_res = gmyth_file_transfer_read(transfer,
  12.434 +                                             icon_data,
  12.435 +                                             icon_length, FALSE);
  12.436 +        if (gmyth_res == GMYTH_FILE_READ_EOF) {
  12.437 +            *length = icon_length;
  12.438 +            *data = icon_data->data;
  12.439 +            g_byte_array_free(icon_data, FALSE);
  12.440 +            res = TRUE;
  12.441 +        } else {
  12.442 +            *length = 0;
  12.443 +            *data = NULL;
  12.444 +            g_byte_array_free(icon_data, TRUE);
  12.445 +        }
  12.446 +    }
  12.447 +
  12.448 +    return res;
  12.449 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/gmyth/gmyth/gmyth_epg.h	Mon Feb 25 17:51:43 2008 +0000
    13.3 @@ -0,0 +1,85 @@
    13.4 +/**
    13.5 + * GMyth Library
    13.6 + *
    13.7 + * @file gmyth/gmyth_epg.h
    13.8 + * 
    13.9 + * @brief <p> GMythEPG class provides access to the program and channel data
   13.10 + * from the Electronic Program Guide (EPG) of the Mythtv backend.
   13.11 + *
   13.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   13.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   13.14 + * 
   13.15 + * This program is free software; you can redistribute it and/or modify
   13.16 + * it under the terms of the GNU Lesser General Public License as published by
   13.17 + * the Free Software Foundation; either version 2 of the License, or
   13.18 + * (at your option) any later version.
   13.19 + *
   13.20 + * This program is distributed in the hope that it will be useful,
   13.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.23 + * GNU General Public License for more details.
   13.24 + *
   13.25 + * You should have received a copy of the GNU Lesser General Public License
   13.26 + * along with this program; if not, write to the Free Software
   13.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   13.28 + */
   13.29 +
   13.30 +#ifndef GMYTH_EPG_H_
   13.31 +#define GMYTH_EPG_H_
   13.32 +
   13.33 +#include <glib-object.h>
   13.34 +
   13.35 +#include "gmyth_query.h"
   13.36 +#include "gmyth_common.h"
   13.37 +
   13.38 +G_BEGIN_DECLS
   13.39 +#define GMYTH_EPG_TYPE               (gmyth_epg_get_type ())
   13.40 +#define GMYTH_EPG(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_EPG_TYPE, GMythEPG))
   13.41 +#define GMYTH_EPG_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE, GMythEPGClass))
   13.42 +#define IS_GMYTH_EPG(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_EPG_TYPE))
   13.43 +#define IS_GMYTH_EPG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE))
   13.44 +#define GMYTH_EPG_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_EPG_TYPE, GMythEPGClass))
   13.45 +typedef struct _GMythEPG GMythEPG;
   13.46 +typedef struct _GMythEPGClass GMythEPGClass;
   13.47 +
   13.48 +struct _GMythEPGClass {
   13.49 +    GObjectClass    parent_class;
   13.50 +
   13.51 +    /*
   13.52 +     * callbacks 
   13.53 +     */
   13.54 +    /*
   13.55 +     * no one for now 
   13.56 +     */
   13.57 +};
   13.58 +
   13.59 +struct _GMythEPG {
   13.60 +    GObject         parent;
   13.61 +
   13.62 +    GMythQuery     *sqlquery;
   13.63 +    GMythBackendInfo *backend_info;
   13.64 +};
   13.65 +
   13.66 +GType           gmyth_epg_get_type              (void) G_GNUC_CONST;;
   13.67 +GMythEPG*       gmyth_epg_new                   (void);
   13.68 +gboolean        gmyth_epg_connect               (GMythEPG           *gmyth_epg,
   13.69 +                                                 GMythBackendInfo   *backend_info);
   13.70 +gboolean        gmyth_epg_disconnect            (GMythEPG           *gmyth_epg);
   13.71 +gint            gmyth_epg_get_channel_list      (GMythEPG           *gmyth_epg,
   13.72 +                                                 GList              **glist_ptr);
   13.73 +gint            gmyth_epg_get_program_list      (GMythEPG           *gmyth_epg,
   13.74 +                                                 GList              **proglist,
   13.75 +                                                 gint               chanNum,
   13.76 +                                                 GTimeVal           *starttime,
   13.77 +                                                 GTimeVal           *endtime);
   13.78 +GMythChannelInfo*gmyth_epg_get_channel_info     (GMythEPG           *gmyth_epg,
   13.79 +                                                 gint               channel_id);
   13.80 +gboolean        gmyth_epg_channel_has_icon      (GMythEPG           *gmyth_epg,
   13.81 +                                                 GMythChannelInfo   *channel);
   13.82 +gboolean        gmyth_epg_channel_get_icon      (GMythEPG           *gmyth_epg,
   13.83 +                                                 GMythChannelInfo   *channel,
   13.84 +                                                 guint8             **data, 
   13.85 +                                                 guint              *length);
   13.86 +
   13.87 +G_END_DECLS
   13.88 +#endif                          /* GMYTH_EPG_H_ */
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/gmyth/gmyth/gmyth_file.c	Mon Feb 25 17:51:43 2008 +0000
    14.3 @@ -0,0 +1,515 @@
    14.4 +/**
    14.5 + * GMyth Library
    14.6 + *
    14.7 + * @file gmyth/gmyth_file.c
    14.8 + * 
    14.9 + * @brief <p> GMythFile deals with the file streaming media remote/local
   14.10 + * transfering to the MythTV frontend.
   14.11 + *
   14.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   14.13 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   14.14 + *
   14.15 + * 
   14.16 + * This program is free software; you can redistribute it and/or modify
   14.17 + * it under the terms of the GNU Lesser General Public License as published by
   14.18 + * the Free Software Foundation; either version 2 of the License, or
   14.19 + * (at your option) any later version.
   14.20 + *
   14.21 + * This program is distributed in the hope that it will be useful,
   14.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14.24 + * GNU General Public License for more details.
   14.25 + *
   14.26 + * You should have received a copy of the GNU Lesser General Public License
   14.27 + * along with this program; if not, write to the Free Software
   14.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   14.29 + */
   14.30 +
   14.31 +#ifdef HAVE_CONFIG_H
   14.32 +#include "config.h"
   14.33 +#endif
   14.34 +
   14.35 +#include "gmyth_file.h"
   14.36 +#include "gmyth_recorder.h"
   14.37 +#include "gmyth_util.h"
   14.38 +#include "gmyth_socket.h"
   14.39 +#include "gmyth_stringlist.h"
   14.40 +#include "gmyth_debug.h"
   14.41 +#include "gmyth_uri.h"
   14.42 +#include "gmyth_marshal.h"
   14.43 +
   14.44 +#include <unistd.h>
   14.45 +#include <glib.h>
   14.46 +
   14.47 +#include <arpa/inet.h>
   14.48 +#include <sys/types.h>
   14.49 +#include <sys/socket.h>
   14.50 +#include <netdb.h>
   14.51 +#include <errno.h>
   14.52 +#include <stdlib.h>
   14.53 +#include <assert.h>
   14.54 +
   14.55 +#define GMYTH_FILE_GET_PRIVATE(obj) \
   14.56 +	(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_FILE_TYPE, GMythFilePrivate))
   14.57 +
   14.58 +struct _GMythFilePrivate {
   14.59 +    gboolean        disposed;
   14.60 +    gint64          offset;
   14.61 +    guint64         filesize;
   14.62 +
   14.63 +    GMythBackendInfo *backend_info;
   14.64 +
   14.65 +    /*
   14.66 +     * Myth URI structure 
   14.67 +     */
   14.68 +    gchar          *filename;
   14.69 +
   14.70 +    gint            file_id;
   14.71 +};
   14.72 +
   14.73 +enum {
   14.74 +    PROP_GMYTH_FILE_DUMMY,
   14.75 +    PROP_GMYTH_FILE_FILENAME,
   14.76 +    PROP_GMYTH_FILE_OFFSET,
   14.77 +    PROP_GMYTH_FILE_FILESIZE,
   14.78 +    PROP_GMYTH_FILE_BACKEND_INFO,
   14.79 +    PROP_GMYTH_FILE_FILEID
   14.80 +};
   14.81 +
   14.82 +static void     gmyth_file_set_property(GObject * object, guint prop_id,
   14.83 +                                        const GValue * value,
   14.84 +                                        GParamSpec * pspec);
   14.85 +static void     gmyth_file_get_property(GObject * object, guint prop_id,
   14.86 +                                        GValue * value,
   14.87 +                                        GParamSpec * pspec);
   14.88 +
   14.89 +static void     gmyth_file_class_init(GMythFileClass * klass);
   14.90 +static void     gmyth_file_init(GMythFile * object);
   14.91 +static void     gmyth_file_dispose(GObject * object);
   14.92 +static void     gmyth_file_finalize(GObject * object);
   14.93 +
   14.94 +G_DEFINE_TYPE(GMythFile, gmyth_file, G_TYPE_OBJECT)
   14.95 +    static void     gmyth_file_class_init(GMythFileClass * klass)
   14.96 +{
   14.97 +    GObjectClass   *gobject_class;
   14.98 +    GMythFileClass *gtransfer_class;
   14.99 +
  14.100 +    gobject_class = (GObjectClass *) klass;
  14.101 +    gtransfer_class = (GMythFileClass *) gobject_class;
  14.102 +
  14.103 +    gobject_class->dispose = gmyth_file_dispose;
  14.104 +    gobject_class->finalize = gmyth_file_finalize;
  14.105 +
  14.106 +    gobject_class->set_property = gmyth_file_set_property;
  14.107 +    gobject_class->get_property = gmyth_file_get_property;
  14.108 +
  14.109 +    g_object_class_install_property
  14.110 +        (gobject_class, PROP_GMYTH_FILE_FILENAME,
  14.111 +         g_param_spec_string("filename", "filename",
  14.112 +                             "The file name.",
  14.113 +                             "",
  14.114 +                             G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
  14.115 +                             G_PARAM_STATIC_BLURB | G_PARAM_READABLE |
  14.116 +                             G_PARAM_WRITABLE));
  14.117 +
  14.118 +    g_object_class_install_property
  14.119 +        (gobject_class, PROP_GMYTH_FILE_OFFSET,
  14.120 +         g_param_spec_int64("file-offset", "file-offset",
  14.121 +                            "The offset (position) of this file", 0,
  14.122 +                            G_MAXINT64, 0,
  14.123 +                            G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
  14.124 +                            G_PARAM_STATIC_BLURB | G_PARAM_READABLE |
  14.125 +                            G_PARAM_WRITABLE));
  14.126 +
  14.127 +    g_object_class_install_property
  14.128 +        (gobject_class, PROP_GMYTH_FILE_FILESIZE,
  14.129 +         g_param_spec_uint64("file-size", "file-size",
  14.130 +                             "The file size in bytes",
  14.131 +                             0, G_MAXUINT64, 0,
  14.132 +                             G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
  14.133 +                             G_PARAM_STATIC_BLURB | G_PARAM_READABLE |
  14.134 +                             G_PARAM_WRITABLE));
  14.135 +
  14.136 +    g_object_class_install_property
  14.137 +        (gobject_class, PROP_GMYTH_FILE_BACKEND_INFO,
  14.138 +         g_param_spec_object("backend-info", "backend-info",
  14.139 +                             "The Backend Information about the remote server",
  14.140 +                             G_TYPE_OBJECT,
  14.141 +                             G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
  14.142 +                             G_PARAM_STATIC_BLURB | G_PARAM_READABLE |
  14.143 +                             G_PARAM_WRITABLE));
  14.144 +
  14.145 +    g_object_class_install_property
  14.146 +        (gobject_class, PROP_GMYTH_FILE_FILEID,
  14.147 +         g_param_spec_int("file-id", "file-id",
  14.148 +                          "The file ID", 0, G_MAXINT, 0,
  14.149 +                          G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
  14.150 +                          G_PARAM_STATIC_BLURB | G_PARAM_READABLE |
  14.151 +                          G_PARAM_WRITABLE));
  14.152 +
  14.153 +    g_type_class_add_private(gobject_class, sizeof(GMythFilePrivate));
  14.154 +
  14.155 +}
  14.156 +
  14.157 +static void
  14.158 +gmyth_file_init(GMythFile * file)
  14.159 +{
  14.160 +    g_return_if_fail(file != NULL);
  14.161 +
  14.162 +    file->priv = GMYTH_FILE_GET_PRIVATE(file);
  14.163 +}
  14.164 +
  14.165 +static void
  14.166 +gmyth_file_dispose(GObject * object)
  14.167 +{
  14.168 +    GMythFilePrivate *priv;
  14.169 +    GMythFile      *file = GMYTH_FILE(object);
  14.170 +
  14.171 +    g_return_if_fail(file != NULL);
  14.172 +
  14.173 +    priv = GMYTH_FILE_GET_PRIVATE(file);
  14.174 +
  14.175 +    if (priv->disposed) {
  14.176 +        /*
  14.177 +         * If dispose did already run, return. 
  14.178 +         */
  14.179 +        return;
  14.180 +    }
  14.181 +
  14.182 +    /*
  14.183 +     * Make sure dispose does not run twice. 
  14.184 +     */
  14.185 +    priv->disposed = TRUE;
  14.186 +
  14.187 +    if (priv->backend_info != NULL) {
  14.188 +        g_object_unref(priv->backend_info);
  14.189 +        priv->backend_info = NULL;
  14.190 +    }
  14.191 +
  14.192 +    if (priv->filename != NULL) {
  14.193 +        g_free(priv->filename);
  14.194 +        priv->filename = NULL;
  14.195 +    }
  14.196 +
  14.197 +    G_OBJECT_CLASS(gmyth_file_parent_class)->dispose(object);
  14.198 +}
  14.199 +
  14.200 +static void
  14.201 +gmyth_file_finalize(GObject * object)
  14.202 +{
  14.203 +    g_signal_handlers_destroy(object);
  14.204 +
  14.205 +    G_OBJECT_CLASS(gmyth_file_parent_class)->finalize(object);
  14.206 +}
  14.207 +
  14.208 +/** 
  14.209 + * Creates a new instance of GMythFile.
  14.210 + * 
  14.211 + * @param backend_info The BackendInfo instance, with all the MythTV network 
  14.212 + * 										 configuration data.
  14.213 + * 
  14.214 + * @return a new instance of the File Transfer. 
  14.215 + */
  14.216 +GMythFile      *
  14.217 +gmyth_file_new(GMythBackendInfo * backend_info)
  14.218 +{
  14.219 +    GMythFile      *file = NULL;
  14.220 +
  14.221 +    g_return_val_if_fail(backend_info != NULL, NULL);
  14.222 +
  14.223 +    GParameter     *__params = g_new0(GParameter, 1);
  14.224 +    GParameter     *__params_it = __params;
  14.225 +
  14.226 +    (__params_it->name =
  14.227 +     "backend-info", g_value_init(&__params_it->value, G_TYPE_OBJECT),
  14.228 +     g_value_set_object(&__params_it->value, backend_info), __params_it++);
  14.229 +    file =
  14.230 +        g_object_newv(GMYTH_FILE_TYPE, __params_it - __params, __params);
  14.231 +
  14.232 +    return file;
  14.233 +}
  14.234 +
  14.235 +gchar          *
  14.236 +gmyth_file_get_file_name(GMythFile * file)
  14.237 +{
  14.238 +    GMythFilePrivate *priv = GMYTH_FILE_GET_PRIVATE(file);
  14.239 +
  14.240 +    g_return_val_if_fail(file != NULL, NULL);
  14.241 +
  14.242 +    return priv->filename;
  14.243 +}
  14.244 +
  14.245 +void
  14.246 +gmyth_file_set_file_name(GMythFile * file, const gchar * filename)
  14.247 +{
  14.248 +    g_return_if_fail(file != NULL);
  14.249 +    g_return_if_fail(filename != NULL);
  14.250 +
  14.251 +    gchar          *__temp2 = NULL;
  14.252 +    const gchar    *__temp1 = NULL;
  14.253 +
  14.254 +    file->priv->filename = (__temp2 =
  14.255 +                            (__temp1 =
  14.256 +                             filename,
  14.257 +                             (__temp1 == NULL ? NULL : g_strdup(__temp1))),
  14.258 +                            (file->priv->filename ==
  14.259 +                             NULL ? NULL : (file->priv->filename =
  14.260 +                                            (g_free(file->priv->filename),
  14.261 +                                             NULL))), __temp2);
  14.262 +}
  14.263 +
  14.264 +/** 
  14.265 + * Creates a new instance of GMythFile.
  14.266 + * 
  14.267 + * @param uri_str The URI poiting to the MythTV backend server.
  14.268 + * 
  14.269 + * @return a new instance of the File Transfer. 
  14.270 + */
  14.271 +GMythFile      *
  14.272 +gmyth_file_new_with_uri(const gchar * uri_str)
  14.273 +{
  14.274 +    GMythFile      *file = GMYTH_FILE(g_object_new(GMYTH_FILE_TYPE, NULL));
  14.275 +    GMythFilePrivate *priv = GMYTH_FILE_GET_PRIVATE(file);
  14.276 +
  14.277 +    priv->backend_info = gmyth_backend_info_new_with_uri(uri_str);
  14.278 +    return file;
  14.279 +}
  14.280 +
  14.281 +/** 
  14.282 + * Open a File Transfer connection in order to get a remote file.
  14.283 + * 
  14.284 + * @param file The actual File Transfer instance. 
  14.285 + * @param filename The file name of the remote file to be transfered to the client.
  14.286 + * 
  14.287 + * @return <code>true</code>, if the connection opening had been done successfully. 
  14.288 + */
  14.289 +gboolean
  14.290 +gmyth_file_setup(GMythFile * file, const gchar * filename)
  14.291 +{
  14.292 +    gboolean        ret = TRUE;
  14.293 +    GMythFilePrivate *priv;
  14.294 +
  14.295 +    g_return_val_if_fail(file != NULL, FALSE);
  14.296 +    g_return_val_if_fail(filename != NULL && strlen(filename) > 0, FALSE);
  14.297 +
  14.298 +    priv = GMYTH_FILE_GET_PRIVATE(file);
  14.299 +
  14.300 +    if (priv->filename != NULL) {
  14.301 +        gmyth_file_close(file);
  14.302 +    }
  14.303 +
  14.304 +    priv->filename = g_strdup(filename);
  14.305 +
  14.306 +    return ret;
  14.307 +}
  14.308 +
  14.309 +/** 
  14.310 + * Closes a remote File Transfer connection.
  14.311 + * 
  14.312 + * @param file The actual File Transfer instance. 
  14.313 + */
  14.314 +void
  14.315 +gmyth_file_close(GMythFile * file)
  14.316 +{
  14.317 +    GMythFilePrivate *priv;
  14.318 +
  14.319 +    priv = GMYTH_FILE_GET_PRIVATE(file);
  14.320 +
  14.321 +    if (priv->filename) {
  14.322 +        g_free(priv->filename);
  14.323 +        priv->filename = NULL;
  14.324 +    }
  14.325 +
  14.326 +}
  14.327 +
  14.328 +/** 
  14.329 + * Gets the actual file size of the binary content.
  14.330 + * 
  14.331 + * @param file The actual File Transfer instance.
  14.332 + * 
  14.333 + * @return The actual file size in bytes. 
  14.334 + */
  14.335 +guint64
  14.336 +gmyth_file_get_filesize(GMythFile * file)
  14.337 +{
  14.338 +    GMythFilePrivate *priv;
  14.339 +
  14.340 +    g_return_val_if_fail(file != NULL, 0);
  14.341 +
  14.342 +    priv = GMYTH_FILE_GET_PRIVATE(file);
  14.343 +    return priv->filesize;
  14.344 +}
  14.345 +
  14.346 +/** 
  14.347 + * Sets the actual file size.
  14.348 + * 
  14.349 + * @param file The actual File Transfer instance.
  14.350 + * @param filesize The actual File Transfer size, in bytes.
  14.351 + */
  14.352 +void
  14.353 +gmyth_file_set_filesize(GMythFile * file, guint64 filesize)
  14.354 +{
  14.355 +    GMythFilePrivate *priv;
  14.356 +
  14.357 +    priv = GMYTH_FILE_GET_PRIVATE(file);
  14.358 +
  14.359 +    priv->filesize = filesize;
  14.360 +}
  14.361 +
  14.362 +/** 
  14.363 + * Gets the actual offset of the binary content.
  14.364 + * 
  14.365 + * @param file The actual File Transfer instance.
  14.366 + * 
  14.367 + * @return The actual file offset in bytes. 
  14.368 + */
  14.369 +gint64
  14.370 +gmyth_file_get_offset(GMythFile * file)
  14.371 +{
  14.372 +    g_return_val_if_fail(file != NULL, 0);
  14.373 +
  14.374 +    return file->priv->offset;
  14.375 +}
  14.376 +
  14.377 +/**
  14.378 + * Sets the actual file offset.
  14.379 + * 
  14.380 + * @param file The actual File instance.
  14.381 + * @param filesize The actual File offset, in bytes.
  14.382 + */
  14.383 +void
  14.384 +gmyth_file_set_offset(GMythFile * file, gint64 offset)
  14.385 +{
  14.386 +    GMythFilePrivate *priv;
  14.387 +
  14.388 +    priv = GMYTH_FILE_GET_PRIVATE(file);
  14.389 +
  14.390 +    priv->offset = offset;
  14.391 +}
  14.392 +
  14.393 +gchar          *
  14.394 +gmyth_file_get_uri(GMythFile * file)
  14.395 +{
  14.396 +    GMythFilePrivate *priv = GMYTH_FILE_GET_PRIVATE(file);
  14.397 +    gchar          *uri = NULL;
  14.398 +
  14.399 +    g_return_val_if_fail(file != NULL, NULL);
  14.400 +
  14.401 +    if (g_strstr_len(priv->filename, strlen(priv->filename), "://") !=
  14.402 +        NULL)
  14.403 +        uri = g_strdup(priv->filename);
  14.404 +    else
  14.405 +        uri =
  14.406 +            g_strdup_printf("myth://%s:%d/%s",
  14.407 +                            gmyth_backend_info_get_hostname(priv->
  14.408 +                                                            backend_info),
  14.409 +                            gmyth_backend_info_get_port(priv->
  14.410 +                                                        backend_info),
  14.411 +                            priv->filename);
  14.412 +
  14.413 +    return uri;
  14.414 +}
  14.415 +
  14.416 +static void
  14.417 +gmyth_file_set_property(GObject * object, guint prop_id,
  14.418 +                        const GValue * value, GParamSpec * pspec)
  14.419 +{
  14.420 +    GMythFilePrivate *priv = GMYTH_FILE_GET_PRIVATE(GMYTH_FILE(object));
  14.421 +
  14.422 +    switch (prop_id) {
  14.423 +    case PROP_GMYTH_FILE_FILENAME:
  14.424 +        {
  14.425 +            if (!g_value_get_string(value)) {
  14.426 +                break;
  14.427 +            }
  14.428 +
  14.429 +            if (priv->filename != NULL) {
  14.430 +                g_free(priv->filename);
  14.431 +                priv->filename = NULL;
  14.432 +            }
  14.433 +
  14.434 +            priv->filename = g_value_dup_string(value);
  14.435 +            gmyth_debug("Changed the filename to [%s]!", priv->filename);
  14.436 +            break;
  14.437 +        }
  14.438 +    case PROP_GMYTH_FILE_OFFSET:
  14.439 +        {
  14.440 +            priv->offset = g_value_get_int64(value);
  14.441 +            break;
  14.442 +        }
  14.443 +    case PROP_GMYTH_FILE_FILESIZE:
  14.444 +        {
  14.445 +            priv->filesize = g_value_get_uint64(value);
  14.446 +            break;
  14.447 +        }
  14.448 +    case PROP_GMYTH_FILE_BACKEND_INFO:
  14.449 +        {
  14.450 +            if (!g_value_get_object(value)) {
  14.451 +                break;
  14.452 +            }
  14.453 +
  14.454 +            if (priv->backend_info != NULL) {
  14.455 +                g_object_unref(priv->backend_info);
  14.456 +                priv->backend_info = NULL;
  14.457 +            }
  14.458 +
  14.459 +            priv->backend_info = g_value_get_object(value);
  14.460 +            gmyth_debug("Changed the backend info to [%s]!",
  14.461 +                        gmyth_backend_info_get_hostname(priv->
  14.462 +                                                        backend_info));
  14.463 +            break;
  14.464 +        }
  14.465 +    case PROP_GMYTH_FILE_FILEID:
  14.466 +        {
  14.467 +            priv->file_id = g_value_get_int(value);
  14.468 +            break;
  14.469 +        }
  14.470 +
  14.471 +    default:
  14.472 +        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
  14.473 +        break;
  14.474 +    }
  14.475 +
  14.476 +}
  14.477 +
  14.478 +static void
  14.479 +gmyth_file_get_property(GObject * object, guint prop_id,
  14.480 +                        GValue * value, GParamSpec * pspec)
  14.481 +{
  14.482 +    GMythFilePrivate *priv = GMYTH_FILE_GET_PRIVATE(GMYTH_FILE(object));
  14.483 +
  14.484 +    switch (prop_id) {
  14.485 +    case PROP_GMYTH_FILE_FILENAME:
  14.486 +        {
  14.487 +            gmyth_debug("Got the filename to [%s]!", priv->filename);
  14.488 +            g_value_set_string(value, priv->filename);
  14.489 +            break;
  14.490 +        }
  14.491 +    case PROP_GMYTH_FILE_OFFSET:
  14.492 +        {
  14.493 +            g_value_set_int64(value, priv->offset);
  14.494 +            break;
  14.495 +        }
  14.496 +    case PROP_GMYTH_FILE_FILESIZE:
  14.497 +        {
  14.498 +            g_value_set_uint64(value, priv->filesize);
  14.499 +            break;
  14.500 +        }
  14.501 +    case PROP_GMYTH_FILE_BACKEND_INFO:
  14.502 +        {
  14.503 +            g_value_set_object(value, priv->backend_info);
  14.504 +            break;
  14.505 +        }
  14.506 +    case PROP_GMYTH_FILE_FILEID:
  14.507 +        {
  14.508 +            g_value_set_int(value, priv->file_id);
  14.509 +            break;
  14.510 +        }
  14.511 +    default:
  14.512 +        {
  14.513 +            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
  14.514 +            break;
  14.515 +        }
  14.516 +    }
  14.517 +
  14.518 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/gmyth/gmyth/gmyth_file.h	Mon Feb 25 17:51:43 2008 +0000
    15.3 @@ -0,0 +1,90 @@
    15.4 +/**
    15.5 + * GMyth Library
    15.6 + *
    15.7 + * @file gmyth/gmyth_file.h
    15.8 + * 
    15.9 + * @brief <p> GMythFile is the parent GMObject that deals with the file streaming 
   15.10 + * media remote/local transfering to the MythTV frontend.
   15.11 + *
   15.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   15.13 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   15.14 + *
   15.15 + * 
   15.16 + * This program is free software; you can redistribute it and/or modify
   15.17 + * it under the terms of the GNU Lesser General Public License as published by
   15.18 + * the Free Software Foundation; either version 2 of the License, or
   15.19 + * (at your option) any later version.
   15.20 + *
   15.21 + * This program is distributed in the hope that it will be useful,
   15.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15.24 + * GNU General Public License for more details.
   15.25 + *
   15.26 + * You should have received a copy of the GNU Lesser General Public License
   15.27 + * along with this program; if not, write to the Free Software
   15.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   15.29 + */
   15.30 +
   15.31 +#ifndef __GMYTH_FILE_H__
   15.32 +#define __GMYTH_FILE_H__
   15.33 +
   15.34 +#include <glib-object.h>
   15.35 +#include <glib.h>
   15.36 +
   15.37 +#include "gmyth_uri.h"
   15.38 +#include "gmyth_backendinfo.h"
   15.39 +
   15.40 +#include <stdio.h>
   15.41 +#include <stdlib.h>
   15.42 +#include <string.h>
   15.43 +#include <netdb.h>
   15.44 +#include <sys/socket.h>
   15.45 +#include <unistd.h>
   15.46 +
   15.47 +G_BEGIN_DECLS
   15.48 +#define GMYTH_FILE_TYPE               (gmyth_file_get_type ())
   15.49 +#define GMYTH_FILE(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_FILE_TYPE, GMythFile))
   15.50 +#define GMYTH_FILE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TYPE, GMythFileClass))
   15.51 +#define IS_GMYTH_FILE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_FILE_TYPE))
   15.52 +#define IS_GMYTH_FILE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TYPE))
   15.53 +#define GMYTH_FILE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_FILE_TYPE, GMythFileClass))
   15.54 +
   15.55 +typedef enum {
   15.56 +    GMYTH_FILE_READ_OK = 0,
   15.57 +    GMYTH_FILE_READ_NEXT_PROG_CHAIN = 1,
   15.58 +    GMYTH_FILE_READ_ERROR = 2,
   15.59 +    GMYTH_FILE_READ_EOF = 3
   15.60 +} GMythFileReadResult;
   15.61 +
   15.62 +typedef struct _GMythFile GMythFile;
   15.63 +typedef struct _GMythFileClass GMythFileClass;
   15.64 +typedef struct _GMythFilePrivate GMythFilePrivate;
   15.65 +
   15.66 +struct _GMythFile {
   15.67 +    GObject         parent;
   15.68 +    GMythFilePrivate *priv;
   15.69 +};
   15.70 +
   15.71 +struct _GMythFileClass {
   15.72 +    GObjectClass    parent_class;
   15.73 +};
   15.74 +
   15.75 +GType           gmyth_file_get_type                 (void);
   15.76 +GMythFile      *gmyth_file_new                      (GMythBackendInfo   *backend_info);
   15.77 +gchar          *gmyth_file_get_file_name            (GMythFile          *file);
   15.78 +void            gmyth_file_set_file_name            (GMythFile          *file,
   15.79 +                                                     const gchar        *filename);
   15.80 +gboolean        gmyth_file_setup                    (GMythFile          *file, 
   15.81 +                                                     const gchar        *filename);
   15.82 +void            gmyth_file_close                    (GMythFile          *file);
   15.83 +gboolean        gmyth_file_is_open                  (GMythFile          *file);
   15.84 +guint64         gmyth_file_get_filesize             (GMythFile          *file);
   15.85 +void            gmyth_file_set_filesize             (GMythFile          *file,
   15.86 +                                                     guint64            filesize);
   15.87 +gint64          gmyth_file_get_offset               (GMythFile          *file);
   15.88 +void            gmyth_file_set_offset               (GMythFile          *file, 
   15.89 +                                                     gint64             offset);
   15.90 +gchar          *gmyth_file_get_uri                  (GMythFile          *file);
   15.91 +
   15.92 +G_END_DECLS
   15.93 +#endif                          /* __GMYTH_FILE_H__ */
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/gmyth/gmyth/gmyth_file_local.c	Mon Feb 25 17:51:43 2008 +0000
    16.3 @@ -0,0 +1,464 @@
    16.4 +/**
    16.5 + * GMyth Library
    16.6 + *
    16.7 + * @file_local gmyth/gmyth_file_local.c
    16.8 + * 
    16.9 + * @brief <p> GMythFileLocal deals with the file_local streaming media remote/local
   16.10 + * transfering to the MythTV frontend.
   16.11 + *
   16.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   16.13 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   16.14 + *
   16.15 + * 
   16.16 + * This program is free software; you can redistribute it and/or modify
   16.17 + * it under the terms of the GNU Lesser General Public License as published by
   16.18 + * the Free Software Foundation; either version 2 of the License, or
   16.19 + * (at your option) any later version.
   16.20 + *
   16.21 + * This program is distributed in the hope that it will be useful,
   16.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.24 + * GNU General Public License for more details.
   16.25 + *
   16.26 + * You should have received a copy of the GNU Lesser General Public License
   16.27 + * along with this program; if not, write to the Free Software
   16.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   16.29 + */
   16.30 +
   16.31 +#ifdef HAVE_CONFIG_H
   16.32 +#include "config.h"
   16.33 +#endif
   16.34 +
   16.35 +#include "gmyth_file_local.h"
   16.36 +#include "gmyth_recorder.h"
   16.37 +#include "gmyth_util.h"
   16.38 +#include "gmyth_socket.h"
   16.39 +#include "gmyth_stringlist.h"
   16.40 +#include "gmyth_debug.h"
   16.41 +#include "gmyth_uri.h"
   16.42 +#include "gmyth_marshal.h"
   16.43 +
   16.44 +#include <unistd.h>
   16.45 +#include <glib.h>
   16.46 +
   16.47 +#include <arpa/inet.h>
   16.48 +#include <sys/types.h>
   16.49 +#include <sys/socket.h>
   16.50 +#include <netdb.h>
   16.51 +#include <errno.h>
   16.52 +#include <stdlib.h>
   16.53 +#include <assert.h>
   16.54 +
   16.55 +#define GMYTH_FILE_LOCAL_GET_PRIVATE(obj) \
   16.56 +	(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_FILE_LOCAL_TYPE, GMythFileLocalPrivate))
   16.57 +
   16.58 +struct _GMythFileLocalPrivate {
   16.59 +
   16.60 +    gboolean        disposed;
   16.61 +
   16.62 +    GMutex         *mutex;
   16.63 +
   16.64 +    gint            fd;
   16.65 +
   16.66 +    GIOChannel     *file_io;
   16.67 +
   16.68 +};
   16.69 +
   16.70 +static void     gmyth_file_local_class_init(GMythFileLocalClass * klass);
   16.71 +static void     gmyth_file_local_init(GMythFileLocal * object);
   16.72 +static void     gmyth_file_local_dispose(GObject * object);
   16.73 +static void     gmyth_file_local_finalize(GObject * object);
   16.74 +
   16.75 +static gboolean _control_acquire_context(GMythFileLocal * file_local,
   16.76 +                                         gboolean do_wait);
   16.77 +
   16.78 +static gboolean _control_release_context(GMythFileLocal * file_local);
   16.79 +
   16.80 +G_DEFINE_TYPE(GMythFileLocal, gmyth_file_local, GMYTH_FILE_TYPE)
   16.81 +    static void     gmyth_file_local_class_init(GMythFileLocalClass *
   16.82 +                                                klass)
   16.83 +{
   16.84 +    GObjectClass   *gobject_class;
   16.85 +    GMythFileLocalClass *gtransfer_class;
   16.86 +
   16.87 +    gobject_class = (GObjectClass *) klass;
   16.88 +    gtransfer_class = (GMythFileLocalClass *) gobject_class;
   16.89 +
   16.90 +    gobject_class->dispose = gmyth_file_local_dispose;
   16.91 +    gobject_class->finalize = gmyth_file_local_finalize;
   16.92 +
   16.93 +    g_type_class_add_private(gobject_class, sizeof(GMythFileLocalPrivate));
   16.94 +
   16.95 +}
   16.96 +
   16.97 +static void
   16.98 +gmyth_file_local_init(GMythFileLocal * file_local)
   16.99 +{
  16.100 +    GMythFileLocalPrivate *priv;
  16.101 +
  16.102 +    g_return_if_fail(file_local != NULL);
  16.103 +
  16.104 +    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  16.105 +
  16.106 +    priv->mutex = g_mutex_new();
  16.107 +}
  16.108 +
  16.109 +static void
  16.110 +gmyth_file_local_dispose(GObject * object)
  16.111 +{
  16.112 +    GMythFileLocalPrivate *priv;
  16.113 +    GMythFileLocal *file_local = GMYTH_FILE_LOCAL(object);
  16.114 +
  16.115 +    g_return_if_fail(file_local != NULL);
  16.116 +
  16.117 +    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  16.118 +
  16.119 +    if (priv->disposed) {
  16.120 +        /*
  16.121 +         * If dispose did already run, return. 
  16.122 +         */
  16.123 +        return;
  16.124 +    }
  16.125 +
  16.126 +    /*
  16.127 +     * Make sure dispose does not run twice. 
  16.128 +     */
  16.129 +    priv->disposed = TRUE;
  16.130 +
  16.131 +    if (priv->mutex != NULL) {
  16.132 +        g_mutex_free(priv->mutex);
  16.133 +        priv->mutex = NULL;
  16.134 +    }
  16.135 +
  16.136 +    if (priv->file_io != NULL) {
  16.137 +        g_io_channel_unref(priv->file_io);
  16.138 +        priv->file_io = NULL;
  16.139 +    }
  16.140 +
  16.141 +    G_OBJECT_CLASS(gmyth_file_local_parent_class)->dispose(object);
  16.142 +}
  16.143 +
  16.144 +static void
  16.145 +gmyth_file_local_finalize(GObject * object)
  16.146 +{
  16.147 +    g_signal_handlers_destroy(object);
  16.148 +
  16.149 +    G_OBJECT_CLASS(gmyth_file_local_parent_class)->finalize(object);
  16.150 +}
  16.151 +
  16.152 +/** 
  16.153 + * Creates a new instance of GMythFileLocal.
  16.154 + * 
  16.155 + * @param backend_info The BackendInfo instance, with all the MythTV network 
  16.156 + * 										 configuration data.
  16.157 + * 
  16.158 + * @return a new instance of the File Transfer. 
  16.159 + */
  16.160 +GMythFileLocal *
  16.161 +gmyth_file_local_new(GMythBackendInfo * backend_info)
  16.162 +{
  16.163 +    GMythFileLocal *file_local =
  16.164 +        GMYTH_FILE_LOCAL(g_object_new(GMYTH_FILE_LOCAL_TYPE, NULL));
  16.165 +
  16.166 +    g_object_set(GMYTH_FILE(file_local), "backend-info", &backend_info,
  16.167 +                 NULL);
  16.168 +
  16.169 +    return file_local;
  16.170 +}
  16.171 +
  16.172 +/** 
  16.173 + * Creates a new instance of GMythFileLocal.
  16.174 + * 
  16.175 + * @param uri_str The URI poiting to the MythTV backend server.
  16.176 + * 
  16.177 + * @return a new instance of the File Transfer.
  16.178 + */
  16.179 +GMythFileLocal *
  16.180 +gmyth_file_local_new_with_uri(const gchar * uri_str)
  16.181 +{
  16.182 +    GMythFileLocal *file_local =
  16.183 +        GMYTH_FILE_LOCAL(g_object_new(GMYTH_FILE_LOCAL_TYPE, NULL));
  16.184 +    GMythURI       *uri = gmyth_uri_new_with_value(uri_str);
  16.185 +
  16.186 +    gmyth_debug("GMythURI path segment = %s", gmyth_uri_get_path(uri));
  16.187 +
  16.188 +    g_object_set(GMYTH_FILE(file_local),
  16.189 +                 "backend-info", gmyth_backend_info_new_with_uri(uri_str),
  16.190 +                 "filename", g_strdup(gmyth_uri_get_path(uri)), NULL);
  16.191 +
  16.192 +    g_object_unref(uri);
  16.193 +
  16.194 +    return file_local;
  16.195 +}
  16.196 +
  16.197 +gchar          *
  16.198 +gmyth_file_local_get_file_name(GMythFileLocal * file_local)
  16.199 +{
  16.200 +    return gmyth_file_get_file_name(GMYTH_FILE(file_local));
  16.201 +}
  16.202 +
  16.203 +void
  16.204 +gmyth_file_local_set_file_name(GMythFileLocal * file_local,
  16.205 +                               const gchar * filename)
  16.206 +{
  16.207 +    gmyth_file_set_file_name(GMYTH_FILE(file_local), filename);
  16.208 +}
  16.209 +
  16.210 +/** 
  16.211 + * Open a File in order to get a local file.
  16.212 + * 
  16.213 + * @param file_local The actual File Transfer instance. 
  16.214 + * 
  16.215 + * @return <code>true</code>, if the connection opening had been done successfully. 
  16.216 + */
  16.217 +gboolean
  16.218 +gmyth_file_local_open(GMythFileLocal * file_local)
  16.219 +{
  16.220 +    gboolean        ret = TRUE;
  16.221 +    GMythFileLocalPrivate *priv;
  16.222 +    gchar          *file_name_uri = NULL;
  16.223 +
  16.224 +    g_return_val_if_fail(file_local != NULL, FALSE);
  16.225 +
  16.226 +    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  16.227 +    file_name_uri = gmyth_file_local_get_file_name(file_local);
  16.228 +
  16.229 +    if (file_name_uri != NULL) {
  16.230 +        priv->file_io =
  16.231 +            g_io_channel_new_file(g_strdup(file_name_uri), "r+", NULL);
  16.232 +        g_free(file_name_uri);
  16.233 +    }
  16.234 +
  16.235 +    if (priv->file_io < 0)
  16.236 +        ret = FALSE;
  16.237 +
  16.238 +    return ret;
  16.239 +}
  16.240 +
  16.241 +/** 
  16.242 + * Closes a remote File Transfer connection.
  16.243 + * 
  16.244 + * @param file_local The actual File Transfer instance. 
  16.245 + */
  16.246 +void
  16.247 +gmyth_file_local_close(GMythFileLocal * file_local)
  16.248 +{
  16.249 +    g_return_if_fail(file_local != NULL);
  16.250 +}
  16.251 +
  16.252 +/** 
  16.253 + * Acquire access to a local file read/write pointer.
  16.254 + * 
  16.255 + * @param transfer The actual File Local instance.
  16.256 + * @param do_wait Waits or not on a GCond, when trying to read from the remote socket.
  16.257 + * 
  16.258 + * @return <code>true</code>, if the acquire had been got. 
  16.259 + */
  16.260 +static          gboolean
  16.261 +_control_acquire_context(GMythFileLocal * file_local, gboolean do_wait)
  16.262 +{
  16.263 +    gboolean        ret = TRUE;
  16.264 +    GMythFileLocalPrivate *priv;
  16.265 +
  16.266 +    g_return_val_if_fail(file_local != NULL, FALSE);
  16.267 +    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  16.268 +
  16.269 +    g_mutex_lock(priv->mutex);
  16.270 +    return ret;
  16.271 +}
  16.272 +
  16.273 +/** 
  16.274 + * Release access to a local file read/write pointer.
  16.275 + * 
  16.276 + * @param transfer The actual File Transfer instance.
  16.277 + * 
  16.278 + * @return <code>true</code>, if the local file read/write permissions had been releaseds. 
  16.279 + */
  16.280 +static          gboolean
  16.281 +_control_release_context(GMythFileLocal * file_local)
  16.282 +{
  16.283 +    gboolean        ret = TRUE;
  16.284 +    GMythFileLocalPrivate *priv;
  16.285 +
  16.286 +    g_return_val_if_fail(file_local != NULL, FALSE);
  16.287 +    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  16.288 +
  16.289 +    g_mutex_unlock(priv->mutex);
  16.290 +
  16.291 +    return ret;
  16.292 +}
  16.293 +
  16.294 +/** 
  16.295 + * Reads a block from a remote file.
  16.296 + * 
  16.297 + * @param transfer The actual File Transfer instance.
  16.298 + * @param data A GByteArray instance, where all the binary data representing 
  16.299 + *                       the remote file will be stored.
  16.300 + * @param size The block size, in bytes, to be requested from a remote file.
  16.301 + * @param read_unlimited Tells the backend to read indefinitely (LiveTV), or only 
  16.302 + *                                           gets the actual size
  16.303 + * 
  16.304 + * @return The actual block size (in bytes) returned by REQUEST_BLOCK message,
  16.305 + *              or the error code. 
  16.306 + */
  16.307 +GMythFileReadResult
  16.308 +gmyth_file_local_read(GMythFileLocal * file_local, GByteArray * data,
  16.309 +                      gint size, gboolean read_unlimited)
  16.310 +{
  16.311 +    gsize           bytes_read = 0;
  16.312 +    gint64          total_read = 0;
  16.313 +    GMythFileReadResult retval = GMYTH_FILE_READ_OK;
  16.314 +    GMythFileLocalPrivate *priv;
  16.315 +
  16.316 +    GError         *error = NULL;
  16.317 +
  16.318 +    GIOCondition    io_cond;
  16.319 +    GIOStatus       io_status = G_IO_STATUS_NORMAL;
  16.320 +
  16.321 +    g_return_val_if_fail(file_local != NULL, FALSE);
  16.322 +    g_return_val_if_fail(data != NULL, GMYTH_FILE_READ_ERROR);
  16.323 +
  16.324 +    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  16.325 +
  16.326 +    io_status = g_io_channel_set_encoding(priv->file_io, NULL, &error);
  16.327 +    if (io_status == G_IO_STATUS_NORMAL)
  16.328 +        gmyth_debug("Setting encoding to binary file data stream.\n");
  16.329 +
  16.330 +    io_cond = g_io_channel_get_buffer_condition(priv->file_io);
  16.331 +
  16.332 +    _control_acquire_context(file_local, TRUE);
  16.333 +
  16.334 +    if (size > 0) {
  16.335 +        gchar          *data_buffer = g_new0(gchar, size);
  16.336 +
  16.337 +        io_status = g_io_channel_read_chars(priv->file_io,
  16.338 +                                            data_buffer, (gsize) size,
  16.339 +                                            &bytes_read, &error);
  16.340 +
  16.341 +        if (io_status != G_IO_STATUS_NORMAL) {
  16.342 +            gmyth_debug("Error on io_channel");
  16.343 +            g_free(data_buffer);
  16.344 +            retval = GMYTH_FILE_READ_ERROR;
  16.345 +            goto error;
  16.346 +        }
  16.347 +
  16.348 +        /*
  16.349 +         * append new data to the increasing byte array 
  16.350 +         */
  16.351 +        data =
  16.352 +            g_byte_array_append(data, (const guint8 *) data_buffer,
  16.353 +                                bytes_read);
  16.354 +        total_read += bytes_read;
  16.355 +
  16.356 +        if (!read_unlimited
  16.357 +            && (gmyth_file_local_get_filesize(file_local) > 0)
  16.358 +            && (gmyth_file_local_get_offset(file_local) ==
  16.359 +                gmyth_file_local_get_filesize(file_local))) {
  16.360 +            retval = GMYTH_FILE_READ_EOF;
  16.361 +            goto error;
  16.362 +        }
  16.363 +
  16.364 +        g_free(data_buffer);
  16.365 +    } else {
  16.366 +        retval = GMYTH_FILE_READ_ERROR;
  16.367 +    }
  16.368 +
  16.369 +  error:
  16.370 +    _control_release_context(file_local);
  16.371 +
  16.372 +    if (error != NULL) {
  16.373 +        gmyth_debug("Cleaning-up ERROR: [msg = %s, code = %d]\n",
  16.374 +                    error->message, error->code);
  16.375 +        g_error_free(error);
  16.376 +    }
  16.377 +
  16.378 +    if (total_read > 0)
  16.379 +        gmyth_file_local_set_offset(file_local,
  16.380 +                                    (gmyth_file_local_get_offset
  16.381 +                                     (file_local) + total_read));
  16.382 +
  16.383 +    return retval;
  16.384 +}
  16.385 +
  16.386 +gint64
  16.387 +gmyth_file_local_seek(GMythFileLocal * file_local, gint64 pos,
  16.388 +                      GSeekType whence)
  16.389 +{
  16.390 +    GMythFileLocalPrivate *priv;
  16.391 +
  16.392 +    GError         *error;
  16.393 +
  16.394 +    GIOStatus       io_status = G_IO_STATUS_NORMAL;
  16.395 +
  16.396 +    g_return_val_if_fail(file_local != NULL, -1);
  16.397 +
  16.398 +    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  16.399 +
  16.400 +    io_status =
  16.401 +        g_io_channel_seek_position(priv->file_io, pos, whence, &error);
  16.402 +
  16.403 +    if (io_status == G_IO_STATUS_ERROR)
  16.404 +        pos = -1;
  16.405 +
  16.406 +    return pos;
  16.407 +
  16.408 +}
  16.409 +
  16.410 +/** 
  16.411 + * Gets the actual file_local size of the binary content.
  16.412 + * 
  16.413 + * @param file_local The actual File Transfer instance.
  16.414 + * 
  16.415 + * @return The actual file_local size in bytes. 
  16.416 + */
  16.417 +guint64
  16.418 +gmyth_file_local_get_filesize(GMythFileLocal * file_local)
  16.419 +{
  16.420 +    g_return_val_if_fail(file_local != NULL, 0);
  16.421 +
  16.422 +    return gmyth_file_get_filesize(GMYTH_FILE(file_local));
  16.423 +}
  16.424 +
  16.425 +/** 
  16.426 + * Sets the actual file_local size.
  16.427 + * 
  16.428 + * @param file_local The actual File Transfer instance.
  16.429 + * @param filesize The actual File Transfer size, in bytes.
  16.430 + */
  16.431 +void
  16.432 +gmyth_file_local_set_filesize(GMythFileLocal * file_local,
  16.433 +                              guint64 filesize)
  16.434 +{
  16.435 +    g_return_if_fail(file_local != NULL);
  16.436 +
  16.437 +    gmyth_file_set_filesize(GMYTH_FILE(file_local), filesize);
  16.438 +}
  16.439 +
  16.440 +/** 
  16.441 + * Gets the actual file offset of the binary content.
  16.442 + * 
  16.443 + * @param file_local The actual File Transfer instance.
  16.444 + * 
  16.445 + * @return The actual file offset in bytes.
  16.446 + */
  16.447 +gint64
  16.448 +gmyth_file_local_get_offset(GMythFileLocal * file_local)
  16.449 +{
  16.450 +    g_return_val_if_fail(file_local != NULL, 0);
  16.451 +
  16.452 +    return gmyth_file_get_offset(GMYTH_FILE(file_local));
  16.453 +}
  16.454 +
  16.455 +/** 
  16.456 + * Sets the actual file offset.
  16.457 + * 
  16.458 + * @param file_local The actual File Local instance.
  16.459 + * @param offset The actual File Local offset, in bytes.
  16.460 + */
  16.461 +void
  16.462 +gmyth_file_local_set_offset(GMythFileLocal * file_local, gint64 offset)
  16.463 +{
  16.464 +    g_return_if_fail(file_local != NULL);
  16.465 +
  16.466 +    gmyth_file_set_offset(GMYTH_FILE(file_local), offset);
  16.467 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/gmyth/gmyth/gmyth_file_local.h	Mon Feb 25 17:51:43 2008 +0000
    17.3 @@ -0,0 +1,93 @@
    17.4 +/**
    17.5 + * GMyth Library
    17.6 + *
    17.7 + * @file gmyth/gmyth_file_local_local.h
    17.8 + * 
    17.9 + * @brief <p> GMythFileLocal is the parent GMythFile that deals with the file streaming 
   17.10 + * media local transfering from the MythTV backend.
   17.11 + *
   17.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   17.13 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   17.14 + *
   17.15 + * 
   17.16 + * This program is free software; you can redistribute it and/or modify
   17.17 + * it under the terms of the GNU Lesser General Public License as published by
   17.18 + * the Free Software Foundation; either version 2 of the License, or
   17.19 + * (at your option) any later version.
   17.20 + *
   17.21 + * This program is distributed in the hope that it will be useful,
   17.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.24 + * GNU General Public License for more details.
   17.25 + *
   17.26 + * You should have received a copy of the GNU Lesser General Public License
   17.27 + * along with this program; if not, write to the Free Software
   17.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   17.29 + */
   17.30 +
   17.31 +#ifndef __GMYTH_FILE_LOCAL_H__
   17.32 +#define __GMYTH_FILE_LOCAL_H__
   17.33 +
   17.34 +#include <glib-object.h>
   17.35 +#include <glib.h>
   17.36 +
   17.37 +#include "gmyth_file.h"
   17.38 +#include "gmyth_uri.h"
   17.39 +#include "gmyth_backendinfo.h"
   17.40 +
   17.41 +#include <stdio.h>
   17.42 +#include <stdlib.h>
   17.43 +#include <string.h>
   17.44 +#include <netdb.h>
   17.45 +#include <sys/socket.h>
   17.46 +#include <unistd.h>
   17.47 +
   17.48 +G_BEGIN_DECLS
   17.49 +#define GMYTH_FILE_LOCAL_TYPE               (gmyth_file_local_get_type ())
   17.50 +#define GMYTH_FILE_LOCAL(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_FILE_LOCAL_TYPE, GMythFileLocal))
   17.51 +#define GMYTH_FILE_LOCAL_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_LOCAL_TYPE, GMythFileLocalClass))
   17.52 +#define IS_GMYTH_FILE_LOCAL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_FILE_LOCAL_TYPE))
   17.53 +#define IS_GMYTH_FILE_LOCAL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_LOCAL_TYPE))
   17.54 +#define GMYTH_FILE_LOCAL_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_FILE_LOCAL_TYPE, GMythFileLocalClass))
   17.55 +typedef struct _GMythFileLocal GMythFileLocal;
   17.56 +typedef struct _GMythFileLocalClass GMythFileLocalClass;
   17.57 +typedef struct _GMythFileLocalPrivate GMythFileLocalPrivate;
   17.58 +
   17.59 +struct _GMythFileLocal {
   17.60 +    GMythFile       parent;
   17.61 +};
   17.62 +
   17.63 +struct _GMythFileLocalClass {
   17.64 +    GMythFileClass  parent_class;
   17.65 +};
   17.66 +
   17.67 +
   17.68 +GType           gmyth_file_local_get_type(void);
   17.69 +GMythFileLocal *gmyth_file_local_new(GMythBackendInfo * backend_info);
   17.70 +GMythFileLocal *gmyth_file_local_new_with_uri(const gchar * uri);
   17.71 +gchar          *gmyth_file_local_get_file_name(GMythFileLocal *
   17.72 +                                               file_local);
   17.73 +void            gmyth_file_local_set_file_name(GMythFileLocal * file_local,
   17.74 +                                               const gchar * filename);
   17.75 +gboolean        gmyth_file_local_open(GMythFileLocal * file_local);
   17.76 +void            gmyth_file_local_close(GMythFileLocal * file_local);
   17.77 +gboolean        gmyth_file_local_is_open(GMythFileLocal * file_local);
   17.78 +
   17.79 +GMythFileReadResult
   17.80 +gmyth_file_local_read(GMythFileLocal * file_local,
   17.81 +                      GByteArray * data, gint size,
   17.82 +                      gboolean read_unlimited);
   17.83 +
   17.84 +gint64          gmyth_file_local_seek(GMythFileLocal * file_local,
   17.85 +                                      gint64 pos, GSeekType whence);
   17.86 +
   17.87 +guint64         gmyth_file_local_get_filesize(GMythFileLocal * file_local);
   17.88 +void            gmyth_file_local_set_filesize(GMythFileLocal * file,
   17.89 +                                              guint64 filesize);
   17.90 +
   17.91 +gint64          gmyth_file_local_get_offset(GMythFileLocal * file_local);
   17.92 +void            gmyth_file_local_set_offset(GMythFileLocal * file_local,
   17.93 +                                            gint64 offset);
   17.94 +
   17.95 +G_END_DECLS
   17.96 +#endif                          /* __GMYTH_FILE_LOCAL_H__ */
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/gmyth/gmyth/gmyth_file_transfer.c	Mon Feb 25 17:51:43 2008 +0000
    18.3 @@ -0,0 +1,1014 @@
    18.4 +/**
    18.5 + * GMyth Library
    18.6 + *
    18.7 + * @file gmyth/gmyth_file_transfer.c
    18.8 + * 
    18.9 + * @brief <p> GMythFileTransfer deals with the file streaming media remote/local
   18.10 + * transfering to the MythTV frontend.
   18.11 + *
   18.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   18.13 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   18.14 + *
   18.15 + * 
   18.16 + * This program is free software; you can redistribute it and/or modify
   18.17 + * it under the terms of the GNU Lesser General Public License as published by
   18.18 + * the Free Software Foundation; either version 2 of the License, or
   18.19 + * (at your option) any later version.
   18.20 + *
   18.21 + * This program is distributed in the hope that it will be useful,
   18.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   18.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18.24 + * GNU General Public License for more details.
   18.25 + *
   18.26 + * You should have received a copy of the GNU Lesser General Public License
   18.27 + * along with this program; if not, write to the Free Software
   18.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   18.29 + *
   18.30 + * GStreamer MythTV plug-in properties:
   18.31 + * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv]
   18.32 + * - path (qurl - remote file to be opened)
   18.33 + * - port number *   
   18.34 + */
   18.35 +
   18.36 +#ifdef HAVE_CONFIG_H
   18.37 +#include "config.h"
   18.38 +#endif
   18.39 +
   18.40 +#include "gmyth_file_transfer.h"
   18.41 +#include "gmyth_recorder.h"
   18.42 +#include "gmyth_util.h"
   18.43 +#include "gmyth_socket.h"
   18.44 +#include "gmyth_stringlist.h"
   18.45 +#include "gmyth_debug.h"
   18.46 +#include "gmyth_uri.h"
   18.47 +#include "gmyth_marshal.h"
   18.48 +
   18.49 +#include <unistd.h>
   18.50 +#include <glib.h>
   18.51 +
   18.52 +#include <arpa/inet.h>
   18.53 +#include <sys/types.h>
   18.54 +#include <sys/socket.h>
   18.55 +#include <netdb.h>
   18.56 +#include <errno.h>
   18.57 +#include <stdlib.h>
   18.58 +#include <assert.h>
   18.59 +
   18.60 +#define GMYTHTV_QUERY_HEADER		"QUERY_FILETRANSFER "
   18.61 +
   18.62 +
   18.63 +#define GMYTH_FILE_TRANSFER_GET_PRIVATE(obj) \
   18.64 +	(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferPrivate))
   18.65 +
   18.66 +enum myth_sock_types {
   18.67 +    GMYTH_PLAYBACK_TYPE = 0,
   18.68 +    GMYTH_MONITOR_TYPE,
   18.69 +    GMYTH_FILETRANSFER_TYPE,
   18.70 +    GMYTH_RINGBUFFER_TYPE
   18.71 +};
   18.72 +
   18.73 +struct _GMythFileTransferPrivate {
   18.74 +    GMythRecorder  *recorder;
   18.75 +
   18.76 +    gboolean        do_next_program_chain;
   18.77 +    gboolean        disposed;
   18.78 +    gboolean        livetv_wait;
   18.79 +
   18.80 +    /*
   18.81 +     * MythTV version number 
   18.82 +     */
   18.83 +    gint            mythtv_version;
   18.84 +
   18.85 +    /*
   18.86 +     * socket descriptors 
   18.87 +     */
   18.88 +    GMythSocket    *control_sock;
   18.89 +    GMythSocket    *sock;
   18.90 +    GMutex         *mutex;
   18.91 +    gint            file_id;
   18.92 +};
   18.93 +
   18.94 +static void     gmyth_file_transfer_class_init(GMythFileTransferClass *
   18.95 +                                               klass);
   18.96 +static void     gmyth_file_transfer_init(GMythFileTransfer * object);
   18.97 +static void     gmyth_file_transfer_dispose(GObject * object);
   18.98 +static void     gmyth_file_transfer_finalize(GObject * object);
   18.99 +static void     _file_transfer_program_info_changed(GMythFileTransfer *
  18.100 +                                                    transfer,
  18.101 +                                                    gint msg_code,
  18.102 +                                                    gpointer
  18.103 +                                                    livetv_recorder);
  18.104 +static gboolean _connect_to_backend(GMythFileTransfer * transfer);
  18.105 +static gboolean _control_acquire_context(GMythFileTransfer * transfer,
  18.106 +                                         gboolean do_wait);
  18.107 +static gboolean _control_release_context(GMythFileTransfer * transfer);
  18.108 +
  18.109 +G_DEFINE_TYPE(GMythFileTransfer, gmyth_file_transfer, GMYTH_FILE_TYPE)
  18.110 +    static void     gmyth_file_transfer_class_init(GMythFileTransferClass *
  18.111 +                                                   klass)
  18.112 +{
  18.113 +    GObjectClass   *gobject_class;
  18.114 +    GMythFileTransferClass *gtransfer_class;
  18.115 +
  18.116 +    gobject_class = (GObjectClass *) klass;
  18.117 +    gtransfer_class = (GMythFileTransferClass *) gobject_class;
  18.118 +
  18.119 +    gobject_class->dispose = gmyth_file_transfer_dispose;
  18.120 +    gobject_class->finalize = gmyth_file_transfer_finalize;
  18.121 +
  18.122 +    g_type_class_add_private(gobject_class,
  18.123 +                             sizeof(GMythFileTransferPrivate));
  18.124 +
  18.125 +    gtransfer_class->program_info_changed_handler =
  18.126 +        _file_transfer_program_info_changed;
  18.127 +
  18.128 +    gtransfer_class->program_info_changed_handler_signal_id =
  18.129 +        g_signal_new("program-info-changed",
  18.130 +                     G_TYPE_FROM_CLASS(gtransfer_class),
  18.131 +                     G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
  18.132 +                     G_SIGNAL_NO_HOOKS, 0, NULL, NULL,
  18.133 +                     gmyth_marshal_VOID__INT_POINTER, G_TYPE_NONE, 2,
  18.134 +                     G_TYPE_INT, G_TYPE_POINTER);
  18.135 +
  18.136 +}
  18.137 +
  18.138 +static void
  18.139 +gmyth_file_transfer_init(GMythFileTransfer * transfer)
  18.140 +{
  18.141 +    g_return_if_fail(transfer != NULL);
  18.142 +
  18.143 +    transfer->priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  18.144 +    transfer->priv->mutex = g_mutex_new();
  18.145 +
  18.146 +    g_signal_connect(G_OBJECT(transfer), "program-info-changed",
  18.147 +                     (GCallback) (GMYTH_FILE_TRANSFER_GET_CLASS
  18.148 +                         (transfer)->program_info_changed_handler),
  18.149 +                         NULL);
  18.150 +}
  18.151 +
  18.152 +static void
  18.153 +gmyth_file_transfer_dispose(GObject * object)
  18.154 +{
  18.155 +    GMythFileTransferPrivate *priv;
  18.156 +    GMythFileTransfer *transfer = GMYTH_FILE_TRANSFER(object);
  18.157 +
  18.158 +    g_return_if_fail(transfer != NULL);
  18.159 +
  18.160 +    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  18.161 +
  18.162 +    if (priv->disposed) {
  18.163 +        /*
  18.164 +         * If dispose did already run, return. 
  18.165 +         */
  18.166 +        return;
  18.167 +    }
  18.168 +
  18.169 +    /*
  18.170 +     * Make sure dispose does not run twice. 
  18.171 +     */
  18.172 +    priv->disposed = TRUE;
  18.173 +
  18.174 +    if (priv->mutex != NULL) {
  18.175 +        g_mutex_free(priv->mutex);
  18.176 +        priv->mutex = NULL;
  18.177 +    }
  18.178 +
  18.179 +    if (priv->control_sock != NULL) {
  18.180 +        g_object_unref(priv->control_sock);
  18.181 +        priv->control_sock = NULL;
  18.182 +    }
  18.183 +
  18.184 +    if (priv->sock != NULL) {
  18.185 +        g_object_unref(priv->sock);
  18.186 +        priv->sock = NULL;
  18.187 +    }
  18.188 +
  18.189 +    if (priv->recorder != NULL) {
  18.190 +        g_object_unref(priv->recorder);
  18.191 +        priv->recorder = NULL;
  18.192 +    }
  18.193 +
  18.194 +    G_OBJECT_CLASS(gmyth_file_transfer_parent_class)->dispose(object);
  18.195 +}
  18.196 +
  18.197 +static void
  18.198 +gmyth_file_transfer_finalize(GObject * object)
  18.199 +{
  18.200 +    g_signal_handlers_destroy(object);
  18.201 +
  18.202 +    G_OBJECT_CLASS(gmyth_file_transfer_parent_class)->finalize(object);
  18.203 +}
  18.204 +
  18.205 +/** 
  18.206 + * Creates a new instance of GMythFileTransfer.
  18.207 + * 
  18.208 + * @param backend_info The BackendInfo instance, with all the MythTV network 
  18.209 + * 										 configuration data.
  18.210 + * 
  18.211 + * @return a new instance of the File Transfer. 
  18.212 + */
  18.213 +GMythFileTransfer *
  18.214 +gmyth_file_transfer_new(GMythBackendInfo * backend_info)
  18.215 +{
  18.216 +    GMythFileTransfer *transfer = g_object_new(GMYTH_FILE_TRANSFER_TYPE,
  18.217 +                                               "backend-info",
  18.218 +                                               backend_info,
  18.219 +                                               NULL);
  18.220 +
  18.221 +    // GValue val = {0,}; 
  18.222 +    // backend_info = g_object_ref( backend_info );
  18.223 +    gmyth_debug("Creating FileTransfer BackendInfo hostname = %s",
  18.224 +                gmyth_backend_info_get_hostname(backend_info));
  18.225 +    // GMythBackendInfo *backend_info = gmyth_backend_info_new_with_uri
  18.226 +    // (uri_str);
  18.227 +    // g_value_init (&val, G_TYPE_OBJECT);
  18.228 +    // g_value_set_object (&val, backend_info); 
  18.229 +    // g_object_set (G_OBJECT (transfer), "backend-info", &val, NULL);
  18.230 +
  18.231 +    return transfer;
  18.232 +}
  18.233 +
  18.234 +gchar          *
  18.235 +gmyth_file_transfer_get_file_name(GMythFileTransfer * transfer)
  18.236 +{
  18.237 +    gchar          *filename;
  18.238 +
  18.239 +    g_object_get(G_OBJECT(transfer), "filename", &filename, NULL);
  18.240 +
  18.241 +    return filename;
  18.242 +}
  18.243 +
  18.244 +/** 
  18.245 + * Creates a new instance of GMythFileTransfer.
  18.246 + * 
  18.247 + * @param uri_str The URI poiting to the MythTV backend server.
  18.248 + * 
  18.249 + * @return a new instance of the File Transfer. 
  18.250 + */
  18.251 +GMythFileTransfer *
  18.252 +gmyth_file_transfer_new_with_uri(const gchar * uri_str)
  18.253 +{
  18.254 +    GMythFileTransfer *transfer =
  18.255 +        GMYTH_FILE_TRANSFER(g_object_new(GMYTH_FILE_TRANSFER_TYPE, NULL));
  18.256 +    gmyth_debug("URI str = %s", uri_str);
  18.257 +    // GMythBackendInfo *backend_info = gmyth_backend_info_new_with_uri
  18.258 +    // (uri_str);
  18.259 +    GValue          val = { 0, };
  18.260 +    g_value_init(&val, G_TYPE_OBJECT);
  18.261 +    g_value_set_object(&val, gmyth_backend_info_new_with_uri(uri_str));
  18.262 +    g_object_set(G_OBJECT(transfer), "backend-info", &val, NULL);
  18.263 +
  18.264 +    return transfer;
  18.265 +}
  18.266 +
  18.267 +/** 
  18.268 + * Open a File Transfer connection in order to get a remote file.
  18.269 + * 
  18.270 + * @param transfer The actual File Transfer instance. 
  18.271 + * @param filename The file name of the remote file to be transferred to the client.
  18.272 + * 
  18.273 + * @return <code>true</code>, if the connection opening had been done successfully. 
  18.274 + */
  18.275 +gboolean
  18.276 +gmyth_file_transfer_open(GMythFileTransfer * transfer,
  18.277 +                         const gchar * filename)
  18.278 +{
  18.279 +    gboolean        ret = TRUE;
  18.280 +    GMythFileTransferPrivate *priv;
  18.281 +
  18.282 +    g_return_val_if_fail(transfer != NULL, FALSE);
  18.283 +    g_return_val_if_fail(filename != NULL && strlen(filename) > 0, FALSE);
  18.284 +
  18.285 +    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  18.286 +
  18.287 +    gmyth_debug("Opening the FileTransfer... (%s)", filename);
  18.288 +
  18.289 +    g_object_set(GMYTH_FILE(transfer), "filename", filename, NULL);
  18.290 +
  18.291 +    /*
  18.292 +     * configure the control socket 
  18.293 +     */
  18.294 +    if (TRUE /* priv->control_sock == NULL */ ) {
  18.295 +        if (!_connect_to_backend(transfer)) {
  18.296 +            gmyth_debug("Connection to backend failed (Control Socket).");
  18.297 +            ret = FALSE;
  18.298 +        }
  18.299 +
  18.300 +        if (priv->do_next_program_chain) {
  18.301 +            priv->do_next_program_chain = FALSE;    // fixme
  18.302 +            gmyth_debug
  18.303 +                ("New file available before the current file was opened");
  18.304 +            GMythProgramInfo *prog_info =
  18.305 +                gmyth_recorder_get_current_program_info(priv->recorder);
  18.306 +
  18.307 +            if (prog_info != NULL && prog_info->pathname != NULL
  18.308 +                && strlen(prog_info->pathname->str) > 0
  18.309 +                && g_ascii_strcasecmp(prog_info->pathname->str,
  18.310 +                                      gmyth_file_get_file_name(GMYTH_FILE
  18.311 +                                                               (transfer)))
  18.312 +                != 0)
  18.313 +                ret =
  18.314 +                    gmyth_file_transfer_open(transfer,
  18.315 +                                             g_strrstr(prog_info->
  18.316 +                                                       pathname->str,
  18.317 +                                                       "/"));
  18.318 +
  18.319 +            if (prog_info != NULL)
  18.320 +                g_object_unref(prog_info);
  18.321 +
  18.322 +            if (!ret)
  18.323 +                gmyth_debug("Cannot change to the next program info!");
  18.324 +            else
  18.325 +                gmyth_debug("OK!!! MOVED to the next program info [%s]!",
  18.326 +                            gmyth_file_get_file_name(GMYTH_FILE
  18.327 +                                                     (transfer)));
  18.328 +
  18.329 +        } else {
  18.330 +            gmyth_debug
  18.331 +                ("None new file found. We continue with the same file opened before");
  18.332 +        }
  18.333 +
  18.334 +    } else {
  18.335 +        gmyth_debug("Remote transfer control socket already created.");
  18.336 +    }
  18.337 +
  18.338 +    gmyth_debug("Got file with size = %lld.\n",
  18.339 +                gmyth_file_get_filesize(GMYTH_FILE(transfer)));
  18.340 +
  18.341 +    return ret;
  18.342 +}
  18.343 +
  18.344 +/** 
  18.345 + * Connect a File Transfer binary client socket to a remote file.
  18.346 + * 
  18.347 + * @param transfer The actual File Transfer instance. 
  18.348 + * 
  18.349 + * @return <code>true</code>, if the connection had been configured successfully. 
  18.350 + */
  18.351 +static          gboolean
  18.352 +_connect_to_backend(GMythFileTransfer * transfer)
  18.353 +{
  18.354 +    GString        *base_str = NULL;
  18.355 +    GString        *hostname = NULL;
  18.356 +    GMythStringList *strlist = NULL;
  18.357 +    gboolean        ret = TRUE;
  18.358 +    GMythFileTransferPrivate *priv;
  18.359 +    GMythBackendInfo *backend_info;
  18.360 +
  18.361 +    g_return_val_if_fail(transfer != NULL, FALSE);
  18.362 +
  18.363 +    g_object_get(GMYTH_FILE(transfer), "backend-info", &backend_info,
  18.364 +                 NULL);
  18.365 +
  18.366 +    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  18.367 +    _control_acquire_context(transfer, TRUE);
  18.368 +
  18.369 +    /*
  18.370 +     * Creates the control socket 
  18.371 +     */
  18.372 +
  18.373 +    if (priv->control_sock != NULL) {
  18.374 +        g_object_unref(priv->control_sock);
  18.375 +        priv->control_sock = NULL;
  18.376 +    }
  18.377 +
  18.378 +    base_str = g_string_new("");
  18.379 +
  18.380 +    priv->control_sock = gmyth_socket_new();
  18.381 +    // Connects the socket, send Mythtv ANN command and verify Mythtv
  18.382 +    // protocol version 
  18.383 +    if (!gmyth_socket_connect_to_backend(priv->control_sock,
  18.384 +                                         backend_info->hostname,
  18.385 +                                         backend_info->port, TRUE)) {
  18.386 +
  18.387 +        _control_release_context(transfer);
  18.388 +        g_object_unref(priv->control_sock);
  18.389 +        priv->control_sock = NULL;
  18.390 +        return FALSE;
  18.391 +    }
  18.392 +
  18.393 +    /*
  18.394 +     * Creates the data socket 
  18.395 +     */
  18.396 +    if (priv->sock != NULL) {
  18.397 +        g_object_unref(priv->sock);
  18.398 +        priv->sock = NULL;
  18.399 +    }
  18.400 +
  18.401 +    priv->sock = gmyth_socket_new();
  18.402 +    gmyth_socket_connect(priv->sock, backend_info->hostname,
  18.403 +                         backend_info->port);
  18.404 +    gmyth_debug("Connecting file transfer... (%s, %d)",
  18.405 +                backend_info->hostname, backend_info->port);
  18.406 +
  18.407 +    strlist = gmyth_string_list_new();
  18.408 +    hostname = gmyth_socket_get_local_hostname();
  18.409 +    gmyth_debug("[%s] MythTV version (from backend) = %d.\n", __FUNCTION__,
  18.410 +                priv->control_sock->mythtv_version);
  18.411 +    if (priv->control_sock->mythtv_version > 26)
  18.412 +        g_string_printf(base_str, "ANN FileTransfer %s 1 -1",
  18.413 +                        hostname->str);
  18.414 +    else
  18.415 +        g_string_printf(base_str, "ANN FileTransfer %s", hostname->str);
  18.416 +
  18.417 +    gmyth_string_list_append_string(strlist, base_str);
  18.418 +    gmyth_string_list_append_char_array(strlist,
  18.419 +                                        gmyth_file_get_file_name(GMYTH_FILE
  18.420 +                                                                 (transfer)));
  18.421 +
  18.422 +    gmyth_socket_write_stringlist(priv->sock, strlist);
  18.423 +
  18.424 +    /*
  18.425 +     * MONITOR Handler - DVB TV Chain update messages!!! 
  18.426 +     */
  18.427 +
  18.428 +    gmyth_socket_read_stringlist(priv->sock, strlist);
  18.429 +
  18.430 +    /*
  18.431 +     * file identification used in future file transfer requests to
  18.432 +     * backend 
  18.433 +     */
  18.434 +    priv->file_id = gmyth_string_list_get_int(strlist, 1);
  18.435 +
  18.436 +    /*
  18.437 +     * Myth URI stream file size - decoded using two 8-bytes sequences (64 
  18.438 +     * bits/long long types) 
  18.439 +     */
  18.440 +    gmyth_file_set_filesize(GMYTH_FILE(transfer),
  18.441 +                            gmyth_string_list_get_int64(strlist, 2));
  18.442 +
  18.443 +    gmyth_debug("***** Received: recordernum = %d, filesize = %"
  18.444 +                G_GUINT64_FORMAT "\n", priv->file_id,
  18.445 +                gmyth_file_get_filesize(GMYTH_FILE(transfer)));
  18.446 +
  18.447 +    if (gmyth_file_get_filesize(GMYTH_FILE(transfer)) < 0) {
  18.448 +        gmyth_debug
  18.449 +            ("Got filesize equals to %llu is lesser than 0 [invalid stream file]\n",
  18.450 +             gmyth_file_get_filesize(GMYTH_FILE(transfer)));
  18.451 +        g_object_unref(priv->sock);
  18.452 +        priv->sock = NULL;
  18.453 +        ret = FALSE;
  18.454 +    }
  18.455 +
  18.456 +    _control_release_context(transfer);
  18.457 +
  18.458 +    if (strlist != NULL)
  18.459 +        g_object_unref(strlist);
  18.460 +
  18.461 +    if (base_str != NULL)
  18.462 +        g_string_free(base_str, TRUE);
  18.463 +
  18.464 +    if (hostname != NULL)
  18.465 +        g_string_free(hostname, TRUE);
  18.466 +
  18.467 +    return ret;
  18.468 +}
  18.469 +
  18.470 +/** 
  18.471 + * Receives a GObject signal coming from a LiveTV instance, all the time a 
  18.472 + * program info changes.
  18.473 + * 
  18.474 + * @param transfer The actual File Transfer instance. 
  18.475 + * @param msg_code The MythTV backend message status code.
  18.476 + * @param live_tv A pointer to the LiveTV instance. * 
  18.477 + */
  18.478 +void
  18.479 +gmyth_file_transfer_emit_program_info_changed_signal(GMythFileTransfer *
  18.480 +                                                     transfer,
  18.481 +                                                     gint msg_code,
  18.482 +                                                     gpointer
  18.483 +                                                     live_tv_recorder)
  18.484 +{
  18.485 +    gmyth_debug("Calling signal handler... [FILE_TRANSFER]");
  18.486 +
  18.487 +    g_signal_emit(transfer, GMYTH_FILE_TRANSFER_GET_CLASS(transfer)->program_info_changed_handler_signal_id, 0, /* details 
  18.488 +                                                                                                                 */
  18.489 +                  msg_code, live_tv_recorder);
  18.490 +
  18.491 +}
  18.492 +
  18.493 +/** 
  18.494 + * Checks if the actual File Transfer connection is open.
  18.495 + * 
  18.496 + * @param transfer The actual File Transfer instance. 
  18.497 + * 
  18.498 + * @return <code>true</code>, if the File Transfer connection is opened. 
  18.499 + */
  18.500 +gboolean
  18.501 +gmyth_file_transfer_is_open(GMythFileTransfer * transfer)
  18.502 +{
  18.503 +    GMythStringList *strlist;
  18.504 +    GMythFileTransferPrivate *priv;
  18.505 +    GString        *query;
  18.506 +
  18.507 +    g_return_val_if_fail(transfer != NULL, FALSE);
  18.508 +
  18.509 +    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  18.510 +    g_return_val_if_fail(priv->control_sock != NULL, FALSE);
  18.511 +    g_return_val_if_fail(priv->sock != NULL, FALSE);
  18.512 +
  18.513 +    _control_acquire_context(transfer, TRUE);
  18.514 +
  18.515 +    strlist = gmyth_string_list_new();
  18.516 +    query = g_string_new(GMYTHTV_QUERY_HEADER);
  18.517 +    g_string_append_printf(query, "%d", priv->file_id);
  18.518 +
  18.519 +    gmyth_string_list_append_string(strlist, query);
  18.520 +    gmyth_string_list_append_char_array(strlist, "IS_OPEN");
  18.521 +
  18.522 +    gmyth_socket_write_stringlist(priv->control_sock, strlist);
  18.523 +    gmyth_socket_read_stringlist(priv->control_sock, strlist);
  18.524 +
  18.525 +    _control_release_context(transfer);
  18.526 +
  18.527 +    g_string_free(query, TRUE);
  18.528 +    g_object_unref(strlist);
  18.529 +
  18.530 +    return (strlist != NULL && gmyth_string_list_get_int(strlist, 0) == 1);
  18.531 +}
  18.532 +
  18.533 +/** 
  18.534 + * Closes a remote File Transfer connection.
  18.535 + * 
  18.536 + * @param transfer The actual File Transfer instance. 
  18.537 + */
  18.538 +void
  18.539 +gmyth_file_transfer_close(GMythFileTransfer * transfer)
  18.540 +{
  18.541 +    GMythStringList *strlist;
  18.542 +    GMythFileTransferPrivate *priv;
  18.543 +    GString        *query;
  18.544 +
  18.545 +    g_return_if_fail(transfer != NULL);
  18.546 +
  18.547 +    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  18.548 +
  18.549 +    if (priv->control_sock == NULL)
  18.550 +        return;
  18.551 +
  18.552 +    _control_acquire_context(transfer, TRUE);
  18.553 +
  18.554 +    strlist = gmyth_string_list_new();
  18.555 +    query = g_string_new(GMYTHTV_QUERY_HEADER);
  18.556 +    g_string_append_printf(query, "%d", priv->file_id);
  18.557 +
  18.558 +    gmyth_string_list_append_string(strlist, query);
  18.559 +    gmyth_string_list_append_char_array(strlist, "DONE");
  18.560 +
  18.561 +    if (gmyth_socket_sendreceive_stringlist(priv->control_sock, strlist) <=
  18.562 +        0) {
  18.563 +        // fixme: time out???
  18.564 +        gmyth_debug("Remote file timeout.\n");
  18.565 +    }
  18.566 +
  18.567 +    g_string_free(query, TRUE);
  18.568 +    g_object_unref(strlist);
  18.569 +
  18.570 +    if (priv->sock) {
  18.571 +        g_object_unref(priv->sock);
  18.572 +        priv->sock = NULL;
  18.573 +    }
  18.574 +
  18.575 +    if (priv->control_sock) {
  18.576 +        g_object_unref(priv->control_sock);
  18.577 +        priv->control_sock = NULL;
  18.578 +    }
  18.579 +
  18.580 +    _control_release_context(transfer);
  18.581 +}
  18.582 +
  18.583 +/** 
  18.584 + * Do a seek operation (moves the read/write file pointer) on a remote file.
  18.585 + * 
  18.586 + * @param transfer The actual File Transfer instance. 
  18.587 + * @param pos The position to be moved in the remote file.
  18.588 + * @param whence Tells to what direction seek movement should be done.
  18.589 + * 
  18.590 + * @return The actual position on the remote file (after seek has been done). 
  18.591 + */
  18.592 +gint64
  18.593 +gmyth_file_transfer_seek(GMythFileTransfer * transfer, guint64 pos,
  18.594 +                         gint whence)
  18.595 +{
  18.596 +    GMythStringList *strlist = gmyth_string_list_new();
  18.597 +    GMythFileTransferPrivate *priv;
  18.598 +    GString        *query;
  18.599 +
  18.600 +    g_return_val_if_fail(transfer != NULL, FALSE);
  18.601 +    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  18.602 +
  18.603 +    g_return_val_if_fail(priv->sock != NULL, -1);
  18.604 +    g_return_val_if_fail(priv->control_sock != NULL, -1);
  18.605 +
  18.606 +    strlist = gmyth_string_list_new();
  18.607 +    query = g_string_new(GMYTHTV_QUERY_HEADER);
  18.608 +    g_string_append_printf(query, "%d", priv->file_id);
  18.609 +
  18.610 +    /*
  18.611 +     * myth_control_acquire_context( transfer, TRUE ); 
  18.612 +     */
  18.613 +
  18.614 +    gmyth_string_list_append_string(strlist, query);
  18.615 +    gmyth_string_list_append_char_array(strlist, "SEEK");
  18.616 +    gmyth_string_list_append_uint64(strlist, pos);
  18.617 +
  18.618 +    gmyth_string_list_append_int(strlist, whence);
  18.619 +
  18.620 +    if (pos > 0)
  18.621 +        gmyth_string_list_append_uint64(strlist, pos);
  18.622 +    else
  18.623 +        gmyth_string_list_append_uint64(strlist,
  18.624 +                                        gmyth_file_get_offset(GMYTH_FILE
  18.625 +                                                              (transfer)));
  18.626 +
  18.627 +    gmyth_socket_sendreceive_stringlist(priv->control_sock, strlist);
  18.628 +
  18.629 +    gint64          retval = gmyth_string_list_get_int64(strlist, 0);
  18.630 +
  18.631 +    gmyth_file_set_offset(GMYTH_FILE(transfer), retval);
  18.632 +    gmyth_debug("Got reading position pointer from the streaming = %lld\n",
  18.633 +                retval);
  18.634 +
  18.635 +    g_object_unref(strlist);
  18.636 +    g_string_free(query, TRUE);
  18.637 +
  18.638 +    /*
  18.639 +     * myth_control_release_context( transfer ); 
  18.640 +     */
  18.641 +
  18.642 +    return retval;
  18.643 +}
  18.644 +
  18.645 +/** 
  18.646 + * Acquire access to a remote file socket read/write pointer.
  18.647 + * 
  18.648 + * @param transfer The actual File Transfer instance.
  18.649 + * @param do_wait Waits or not on a GCond, when trying to read from the remote socket.
  18.650 + * 
  18.651 + * @return <code>true</code>, if the acquire had been got. 
  18.652 + */
  18.653 +static          gboolean
  18.654 +_control_acquire_context(GMythFileTransfer * transfer, gboolean do_wait)
  18.655 +{
  18.656 +    gboolean        ret = TRUE;
  18.657 +    GMythFileTransferPrivate *priv;
  18.658 +
  18.659 +    g_return_val_if_fail(transfer != NULL, FALSE);
  18.660 +    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  18.661 +
  18.662 +    g_mutex_lock(priv->mutex);
  18.663 +    return ret;
  18.664 +}
  18.665 +
  18.666 +/** 
  18.667 + * Release access to a remote file socket read/write pointer.
  18.668 + * 
  18.669 + * @param transfer The actual File Transfer instance.
  18.670 + * 
  18.671 + * @return <code>true</code>, if the socket read/write permissions had been releaseds. 
  18.672 + */
  18.673 +static          gboolean
  18.674 +_control_release_context(GMythFileTransfer * transfer)
  18.675 +{
  18.676 +    gboolean        ret = TRUE;
  18.677 +    GMythFileTransferPrivate *priv;
  18.678 +
  18.679 +    g_return_val_if_fail(transfer != NULL, FALSE);
  18.680 +    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  18.681 +
  18.682 +    g_mutex_unlock(priv->mutex);
  18.683 +
  18.684 +    return ret;
  18.685 +}
  18.686 +
  18.687 +/** 
  18.688 + * Reads a block from a remote file.
  18.689 + * 
  18.690 + * @param transfer The actual File Transfer instance.
  18.691 + * @param data A GByteArray instance, where all the binary data representing 
  18.692 + * 						 the remote file will be stored.
  18.693 + * @param size The block size, in bytes, to be requested from a remote file.
  18.694 + * @param read_unlimited Tells the backend to read indefinitely (LiveTV), or only 
  18.695 + * 			 gets the actual size
  18.696 + * 
  18.697 + * @return The actual block size (in bytes) returned by REQUEST_BLOCK message,
  18.698 + * 				or the error code. 
  18.699 + */
  18.700 +GMythFileReadResult
  18.701 +gmyth_file_transfer_read(GMythFileTransfer * transfer, GByteArray * data,
  18.702 +                         gint size, gboolean read_unlimited)
  18.703 +{
  18.704 +    gint            bytes_sent = 0;
  18.705 +    gsize           bytes_read = 0;
  18.706 +    gint64          total_read = 0;
  18.707 +    GMythFileReadResult retval = GMYTH_FILE_READ_OK;
  18.708 +    GMythFileTransferPrivate *priv;
  18.709 +
  18.710 +    GError         *error = NULL;
  18.711 +
  18.712 +    GIOChannel     *io_channel;
  18.713 +    GIOChannel     *io_channel_control;
  18.714 +
  18.715 +    GIOCondition    io_cond;
  18.716 +    GIOCondition    io_cond_control;
  18.717 +    GIOStatus       io_status = G_IO_STATUS_NORMAL;
  18.718 +    GIOStatus       io_status_control = G_IO_STATUS_NORMAL;
  18.719 +
  18.720 +    GMythStringList *strlist;
  18.721 +    GMythStringList *ret_strlist = NULL;
  18.722 +    gboolean        ret = TRUE;
  18.723 +    GString        *query;
  18.724 +
  18.725 +    g_return_val_if_fail(transfer != NULL, FALSE);
  18.726 +    g_return_val_if_fail(data != NULL, GMYTH_FILE_READ_ERROR);
  18.727 +
  18.728 +    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  18.729 +
  18.730 +    strlist = gmyth_string_list_new();
  18.731 +
  18.732 +    io_channel = priv->sock->sd_io_ch;
  18.733 +    io_channel_control = priv->control_sock->sd_io_ch;
  18.734 +
  18.735 +    io_status = g_io_channel_set_encoding(io_channel, NULL, &error);
  18.736 +    if (io_status == G_IO_STATUS_NORMAL)
  18.737 +        gmyth_debug("[%s] Setting encoding to binary data socket).\n",
  18.738 +                    __FUNCTION__);
  18.739 +
  18.740 +    io_cond = g_io_channel_get_buffer_condition(io_channel);
  18.741 +
  18.742 +    io_cond_control = g_io_channel_get_buffer_condition(io_channel);
  18.743 +    if (priv->sock == NULL || (io_status == G_IO_STATUS_ERROR)) {
  18.744 +        g_printerr
  18.745 +            ("gmyth_file_transfer_read(): Called with no raw socket.\n");
  18.746 +        return GMYTH_FILE_READ_ERROR;
  18.747 +    }
  18.748 +
  18.749 +    if (priv->control_sock == NULL
  18.750 +        || (io_status_control == G_IO_STATUS_ERROR)) {
  18.751 +        g_printerr
  18.752 +            ("gmyth_file_transfer_read(): Called with no control socket.\n");
  18.753 +        return GMYTH_FILE_READ_ERROR;
  18.754 +    }
  18.755 +
  18.756 +    query = g_string_new(GMYTHTV_QUERY_HEADER);
  18.757 +    g_string_append_printf(query, "%d", priv->file_id);
  18.758 +    gmyth_debug("[%s] Transfer_query = %s\n", __FUNCTION__, query->str);
  18.759 +
  18.760 +    _control_acquire_context(transfer, TRUE);
  18.761 +    // Do Read
  18.762 +    gmyth_string_list_append_char_array(strlist, query->str);
  18.763 +    gmyth_string_list_append_char_array(strlist, "REQUEST_BLOCK");
  18.764 +    gmyth_string_list_append_int(strlist, size - total_read);
  18.765 +
  18.766 +    guint           iter_count = 3;
  18.767 +
  18.768 +    do {
  18.769 +        bytes_sent = 0;
  18.770 +
  18.771 +        // Request the block to the backend
  18.772 +        gmyth_socket_write_stringlist(priv->control_sock, strlist);
  18.773 +
  18.774 +        if (ret_strlist != NULL)
  18.775 +            g_object_unref(ret_strlist);
  18.776 +
  18.777 +        ret_strlist = gmyth_string_list_new();
  18.778 +        // Receives the backand answer 
  18.779 +        gmyth_socket_read_stringlist(priv->control_sock, ret_strlist);
  18.780 +
  18.781 +        if (ret_strlist != NULL
  18.782 +            && gmyth_string_list_length(ret_strlist) > 0) {
  18.783 +            bytes_sent = gmyth_string_list_get_int(ret_strlist, 0); // -1
  18.784 +            // on
  18.785 +            // backend 
  18.786 +            // error
  18.787 +            gmyth_debug("[%s] got SENT buffer message = %d\n",
  18.788 +                        __FUNCTION__, bytes_sent);
  18.789 +        }
  18.790 +
  18.791 +        if (read_unlimited && (bytes_sent == 0)) {
  18.792 +            g_usleep(300);
  18.793 +        }
  18.794 +
  18.795 +        --iter_count;
  18.796 +
  18.797 +    }
  18.798 +    while (read_unlimited && (bytes_sent == 0) && iter_count > 0);
  18.799 +
  18.800 +    if (bytes_sent > 0) {
  18.801 +        gchar          *data_buffer = g_new0(gchar, bytes_sent);
  18.802 +
  18.803 +        io_status = g_io_channel_read_chars(io_channel,
  18.804 +                                            data_buffer,
  18.805 +                                            (gsize) bytes_sent,
  18.806 +                                            &bytes_read, &error);
  18.807 +
  18.808 +        if (io_status != G_IO_STATUS_NORMAL) {
  18.809 +            gmyth_debug("Error on io_channel");
  18.810 +            g_free(data_buffer);
  18.811 +            g_object_unref(strlist);
  18.812 +            retval = GMYTH_FILE_READ_ERROR;
  18.813 +            goto error;
  18.814 +        }
  18.815 +
  18.816 +        /*
  18.817 +         * append new data to the increasing byte array 
  18.818 +         */
  18.819 +        data =
  18.820 +            g_byte_array_append(data, (const guint8 *) data_buffer,
  18.821 +                                bytes_read);
  18.822 +        gmyth_file_set_offset(GMYTH_FILE(transfer),
  18.823 +                              gmyth_file_get_offset(GMYTH_FILE(transfer)) +
  18.824 +                              bytes_read);
  18.825 +
  18.826 +        if (!read_unlimited
  18.827 +            && (gmyth_file_get_filesize(GMYTH_FILE(transfer)) > 0)
  18.828 +            && (gmyth_file_get_offset(GMYTH_FILE(transfer)) ==
  18.829 +                gmyth_file_get_filesize(GMYTH_FILE(transfer)))) {
  18.830 +            retval = GMYTH_FILE_READ_EOF;
  18.831 +            goto error;
  18.832 +        }
  18.833 +
  18.834 +        g_free(data_buffer);
  18.835 +    } else {
  18.836 +        retval = GMYTH_FILE_READ_ERROR;
  18.837 +    }
  18.838 +
  18.839 +    if (strlist != NULL) {
  18.840 +        g_object_unref(strlist);
  18.841 +        strlist = NULL;
  18.842 +    }
  18.843 +
  18.844 +    if (ret_strlist != NULL) {
  18.845 +        g_object_unref(ret_strlist);
  18.846 +        ret_strlist = NULL;
  18.847 +    }
  18.848 +
  18.849 +    if (read_unlimited && (bytes_sent == 0)) {
  18.850 +        gmyth_debug("Trying to move to the next program chain...");
  18.851 +        if (priv->recorder != NULL && priv->do_next_program_chain) {
  18.852 +            priv->do_next_program_chain = FALSE;
  18.853 +            retval = GMYTH_FILE_READ_NEXT_PROG_CHAIN;
  18.854 +            GMythProgramInfo *prog_info =
  18.855 +                gmyth_recorder_get_current_program_info(priv->recorder);
  18.856 +
  18.857 +            gmyth_debug
  18.858 +                ("Comparing if the current prog. info = %s [strlen == %d] is equals to "
  18.859 +                 " %s [strlen == %d]...", prog_info->pathname->str,
  18.860 +                 strlen(prog_info->pathname->str),
  18.861 +                 gmyth_file_get_file_name(GMYTH_FILE(transfer)),
  18.862 +                 strlen(gmyth_file_get_file_name(GMYTH_FILE(transfer))));
  18.863 +
  18.864 +            if (prog_info != NULL && prog_info->pathname != NULL
  18.865 +                && strlen(prog_info->pathname->str) > 0
  18.866 +                && (NULL ==
  18.867 +                    g_strstr_len(prog_info->pathname->str,
  18.868 +                                 strlen(prog_info->pathname->str),
  18.869 +                                 gmyth_file_get_file_name(GMYTH_FILE
  18.870 +                                                          (transfer))))) {
  18.871 +                /*
  18.872 +                 * releasing context got at this function starting... 
  18.873 +                 */
  18.874 +                _control_release_context(transfer);
  18.875 +                ret =
  18.876 +                    gmyth_file_transfer_open(transfer,
  18.877 +                                             g_strrstr(prog_info->
  18.878 +                                                       pathname->str,
  18.879 +                                                       "/"));
  18.880 +                _control_acquire_context(transfer, TRUE);
  18.881 +                /*
  18.882 +                 * acquiring context released at this function stopping... 
  18.883 +                 */
  18.884 +
  18.885 +                if (prog_info != NULL)
  18.886 +                    g_object_unref(prog_info);
  18.887 +
  18.888 +                if (!ret)
  18.889 +                    gmyth_debug("Cannot change to the next program info!");
  18.890 +                else
  18.891 +                    gmyth_debug
  18.892 +                        ("OK!!! MOVED to the next program info [%s]!",
  18.893 +                         gmyth_file_get_file_name(GMYTH_FILE(transfer)));
  18.894 +            }
  18.895 +
  18.896 +        }
  18.897 +
  18.898 +    }
  18.899 +    /*
  18.900 +     * if 
  18.901 +     */
  18.902 +  error:
  18.903 +
  18.904 +    _control_release_context(transfer);
  18.905 +    g_string_free(query, TRUE);
  18.906 +
  18.907 +    if (error != NULL) {
  18.908 +        gmyth_debug("Cleaning-up ERROR: %s [msg = %s, code = %d]\n",
  18.909 +                    __FUNCTION__, error->message, error->code);
  18.910 +        g_error_free(error);
  18.911 +    }
  18.912 +
  18.913 +    if (total_read > 0)
  18.914 +        gmyth_file_set_offset(GMYTH_FILE(transfer),
  18.915 +                              gmyth_file_get_offset(GMYTH_FILE
  18.916 +                                                    (transfer)) +
  18.917 +                              total_read);
  18.918 +
  18.919 +    return retval;
  18.920 +}
  18.921 +
  18.922 +static void
  18.923 +_file_transfer_program_info_changed(GMythFileTransfer * transfer,
  18.924 +                                    gint msg_code,
  18.925 +                                    gpointer livetv_recorder)
  18.926 +{
  18.927 +    GMythRecorder  *recorder;
  18.928 +    GMythFileTransferPrivate *priv;
  18.929 +
  18.930 +    g_return_if_fail(transfer != NULL);
  18.931 +
  18.932 +    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  18.933 +
  18.934 +    recorder = GMYTH_RECORDER(livetv_recorder);
  18.935 +    gmyth_debug
  18.936 +        ("Program info changed! ( file transfer orig. = %p, ptr. = [%s] )",
  18.937 +         transfer, livetv_recorder != NULL ? "[NOT NULL]" : "[NULL]");
  18.938 +
  18.939 +    if (NULL != recorder) {
  18.940 +        gmyth_debug
  18.941 +            ("YES, the requested program info movement on the LiveTV transfer is authentical!");
  18.942 +    }
  18.943 +
  18.944 +    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  18.945 +    g_object_ref(recorder);
  18.946 +    priv->recorder = recorder;
  18.947 +    priv->do_next_program_chain = TRUE;
  18.948 +}
  18.949 +
  18.950 +/** 
  18.951 + * Sets the timeout flag of a file being transfered.
  18.952 + * 
  18.953 + * @param transfer The actual File Transfer instance.
  18.954 + * @param fast If this is <code>true</code>, sets the remote timeout to be as fast
  18.955 + * 						as possible.
  18.956 + * 
  18.957 + * @return <code>true</code>, if the acquire had been got. 
  18.958 + */
  18.959 +gboolean
  18.960 +gmyth_file_transfer_settimeout(GMythFileTransfer * transfer, gboolean fast)
  18.961 +{
  18.962 +    GMythFileTransferPrivate *priv;
  18.963 +    GMythStringList *strlist = NULL;
  18.964 +
  18.965 +    g_return_val_if_fail(transfer != NULL, FALSE);
  18.966 +
  18.967 +    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  18.968 +
  18.969 +    g_return_val_if_fail(priv->sock != NULL, FALSE);
  18.970 +    g_return_val_if_fail(priv->control_sock != NULL, FALSE);
  18.971 +
  18.972 +    _control_acquire_context(transfer, TRUE);
  18.973 +
  18.974 +    strlist = gmyth_string_list_new();
  18.975 +    gmyth_string_list_append_char_array(strlist, GMYTHTV_QUERY_HEADER);
  18.976 +    gmyth_string_list_append_char_array(strlist, "SET_TIMEOUT");
  18.977 +    gmyth_string_list_append_int(strlist, fast);
  18.978 +
  18.979 +    gint            strlist_len =
  18.980 +        gmyth_socket_sendreceive_stringlist(priv->control_sock,
  18.981 +                                            strlist);
  18.982 +
  18.983 +    if (strlist_len > 0)
  18.984 +        gmyth_debug("Yes, timeout was changed: %s.",
  18.985 +                    gmyth_string_list_get_char_array(strlist, 0));
  18.986 +    else
  18.987 +        gmyth_debug("Timeout cannot be changed!");
  18.988 +
  18.989 +    _control_release_context(transfer);
  18.990 +
  18.991 +    gmyth_debug("%s setting timeout flag of this file transfer = %s\n",
  18.992 +                strlist_len > 0 ? "Yes," : "NOT",
  18.993 +                fast ? "FAST" : "NOT FAST");
  18.994 +
  18.995 +    g_object_unref(strlist);
  18.996 +
  18.997 +    return TRUE;
  18.998 +}
  18.999 +
 18.1000 +/** 
 18.1001 + * Gets the actual file size of the binary content.
 18.1002 + * 
 18.1003 + * @param transfer The actual File Transfer instance.
 18.1004 + * 
 18.1005 + * @return The actual file size in bytes. 
 18.1006 + */
 18.1007 +guint64
 18.1008 +gmyth_file_transfer_get_filesize(GMythFileTransfer * transfer)
 18.1009 +{
 18.1010 +    guint64         filesize;
 18.1011 +
 18.1012 +    g_return_val_if_fail(transfer != NULL, 0);
 18.1013 +
 18.1014 +    g_object_get(GMYTH_FILE(transfer), "file-size", &filesize, NULL);
 18.1015 +
 18.1016 +    return filesize;
 18.1017 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/gmyth/gmyth/gmyth_file_transfer.h	Mon Feb 25 17:51:43 2008 +0000
    19.3 @@ -0,0 +1,111 @@
    19.4 +/**
    19.5 + * GMyth Library
    19.6 + *
    19.7 + * @file gmyth/gmyth_file_transfer.h
    19.8 + * 
    19.9 + * @brief <p> GMythFileTransfer deals with the file streaming media remote/local
   19.10 + * transfering to the MythTV frontend.
   19.11 + *
   19.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   19.13 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   19.14 + *
   19.15 + * 
   19.16 + * This program is free software; you can redistribute it and/or modify
   19.17 + * it under the terms of the GNU Lesser General Public License as published by
   19.18 + * the Free Software Foundation; either version 2 of the License, or
   19.19 + * (at your option) any later version.
   19.20 + *
   19.21 + * This program is distributed in the hope that it will be useful,
   19.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   19.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19.24 + * GNU General Public License for more details.
   19.25 + *
   19.26 + * You should have received a copy of the GNU Lesser General Public License
   19.27 + * along with this program; if not, write to the Free Software
   19.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   19.29 + */
   19.30 +
   19.31 +#ifndef __GMYTH_FILE_TRANSFER_H__
   19.32 +#define __GMYTH_FILE_TRANSFER_H__
   19.33 +
   19.34 +#include <glib-object.h>
   19.35 +#include <glib.h>
   19.36 +
   19.37 +#include "gmyth_file.h"
   19.38 +#include "gmyth_socket.h"
   19.39 +#include "gmyth_uri.h"
   19.40 +#include "gmyth_backendinfo.h"
   19.41 +
   19.42 +#include <stdio.h>
   19.43 +#include <stdlib.h>
   19.44 +#include <string.h>
   19.45 +#include <netdb.h>
   19.46 +#include <sys/socket.h>
   19.47 +#include <unistd.h>
   19.48 +
   19.49 +G_BEGIN_DECLS
   19.50 +#define GMYTH_FILE_TRANSFER_TYPE               (gmyth_file_transfer_get_type ())
   19.51 +#define GMYTH_FILE_TRANSFER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransfer))
   19.52 +#define GMYTH_FILE_TRANSFER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferClass))
   19.53 +#define IS_GMYTH_FILE_TRANSFER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_FILE_TRANSFER_TYPE))
   19.54 +#define IS_GMYTH_FILE_TRANSFER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TRANSFER_TYPE))
   19.55 +#define GMYTH_FILE_TRANSFER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferClass))
   19.56 +typedef struct _GMythFileTransfer GMythFileTransfer;
   19.57 +typedef struct _GMythFileTransferClass GMythFileTransferClass;
   19.58 +typedef struct _GMythFileTransferPrivate GMythFileTransferPrivate;
   19.59 +
   19.60 +struct _GMythFileTransfer {
   19.61 +    GMythFile       parent;
   19.62 +    GMythFileTransferPrivate *priv;
   19.63 +};
   19.64 +
   19.65 +struct _GMythFileTransferClass {
   19.66 +    GMythFileClass  parent_class;
   19.67 +
   19.68 +    /*
   19.69 +     * callbacks 
   19.70 +     */
   19.71 +    guint           program_info_changed_handler_signal_id;
   19.72 +
   19.73 +    /*
   19.74 +     * signal default handlers 
   19.75 +     */
   19.76 +    void            (*program_info_changed_handler) (GMythFileTransfer *
   19.77 +                                                     transfer,
   19.78 +                                                     gint msg_code,
   19.79 +                                                     gpointer
   19.80 +                                                     livetv_recorder);
   19.81 +};
   19.82 +
   19.83 +
   19.84 +GType           gmyth_file_transfer_get_type(void);
   19.85 +GMythFileTransfer *gmyth_file_transfer_new(GMythBackendInfo *
   19.86 +                                           backend_info);
   19.87 +gchar          *gmyth_file_transfer_get_file_name(GMythFileTransfer *
   19.88 +                                                  transfer);
   19.89 +gboolean        gmyth_file_transfer_open(GMythFileTransfer * transfer,
   19.90 +                                         const gchar * filename);
   19.91 +void            gmyth_file_transfer_close(GMythFileTransfer * transfer);
   19.92 +gboolean        gmyth_file_transfer_is_open(GMythFileTransfer * transfer);
   19.93 +
   19.94 +GMythFileReadResult
   19.95 +gmyth_file_transfer_read(GMythFileTransfer * transfer,
   19.96 +                         GByteArray * data, gint size,
   19.97 +                         gboolean read_unlimited);
   19.98 +gint64          gmyth_file_transfer_seek(GMythFileTransfer * transfer,
   19.99 +                                         guint64 pos, gint whence);
  19.100 +gboolean        gmyth_file_transfer_settimeout(GMythFileTransfer *
  19.101 +                                               transfer, gboolean fast);
  19.102 +guint64         gmyth_file_transfer_get_filesize(GMythFileTransfer *
  19.103 +                                                 transfer);
  19.104 +
  19.105 +void
  19.106 +                gmyth_file_transfer_emit_program_info_changed_signal(GMythFileTransfer *
  19.107 +                                                                     transfer,
  19.108 +                                                                     gint
  19.109 +                                                                     msg_code,
  19.110 +                                                                     gpointer
  19.111 +                                                                     live_tv_recorder);
  19.112 +
  19.113 +G_END_DECLS
  19.114 +#endif                          /* __GMYTH_FILE_TRANSFER_H__ */
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/gmyth/gmyth/gmyth_http.c	Mon Feb 25 17:51:43 2008 +0000
    20.3 @@ -0,0 +1,1037 @@
    20.4 +/**
    20.5 + * GMyth Library
    20.6 + *
    20.7 + * @file gmyth/gmyth_http.c
    20.8 + * 
    20.9 + * @brief <p> GMythHttp library provides a wrapper to access
   20.10 + * data from the database using http+xml
   20.11 + *
   20.12 + * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   20.13 + * @author Artur Duque de Souza <artur.souza@indt.org.br>
   20.14 + *
   20.15 + * 
   20.16 + * This program is free software; you can redistribute it and/or modify
   20.17 + * it under the terms of the GNU Lesser General Public License as published by
   20.18 + * the Free Software Foundation; either version 2 of the License, or
   20.19 + * (at your option) any later version.
   20.20 + *
   20.21 + * This program is distributed in the hope that it will be useful,
   20.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   20.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20.24 + * GNU General Public License for more details.
   20.25 + *
   20.26 + * You should have received a copy of the GNU Lesser General Public License
   20.27 + * along with this program; if not, write to the Free Software
   20.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   20.29 + */
   20.30 +
   20.31 +#ifdef HAVE_CONFIG_H
   20.32 +#include "config.h"
   20.33 +#endif
   20.34 +
   20.35 +#include <assert.h>
   20.36 +#include <libxml/parser.h>
   20.37 +#include <libxml/tree.h>
   20.38 +#include <libxml/xpath.h>
   20.39 +#include <libxml/uri.h>
   20.40 +
   20.41 +#include "gmyth_http.h"
   20.42 +#include "gmyth_debug.h"
   20.43 +#include "gmyth_socket.h"
   20.44 +
   20.45 +xmlXPathObjectPtr
   20.46 +getnodeset(xmlDocPtr doc, xmlChar * xpath)
   20.47 +{
   20.48 +
   20.49 +    xmlXPathContextPtr context;
   20.50 +    xmlXPathObjectPtr result;
   20.51 +
   20.52 +    context = xmlXPathNewContext(doc);
   20.53 +    result = xmlXPathEvalExpression(xpath, context);
   20.54 +
   20.55 +    if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {
   20.56 +        g_fprintf(stderr, "Error: No result at XPath\n");
   20.57 +        return NULL;
   20.58 +    }
   20.59 +
   20.60 +    xmlXPathFreeContext(context);
   20.61 +    return result;
   20.62 +}
   20.63 +
   20.64 +
   20.65 +xmlDocPtr
   20.66 +XMLParse(const char *content, int length)
   20.67 +{
   20.68 +    xmlDocPtr       doc;        /* the resulting document tree */
   20.69 +
   20.70 +    doc = xmlReadMemory(content, length, NULL, NULL, 0);
   20.71 +    if (doc == NULL) {
   20.72 +        g_fprintf(stderr, "Error: Failed to parse XML document\n");
   20.73 +        return NULL;
   20.74 +    }
   20.75 +
   20.76 +    return doc;
   20.77 +}
   20.78 +
   20.79 +xmlXPathObjectPtr
   20.80 +getXPath(xmlChar * xpath, xmlDocPtr doc)
   20.81 +{
   20.82 +    xmlXPathObjectPtr result;
   20.83 +
   20.84 +    result = getnodeset(doc, xpath);
   20.85 +    return result;
   20.86 +}
   20.87 +
   20.88 +
   20.89 +/** Retrieves the Progam List from the Channel
   20.90 + *
   20.91 + * @param nodeTab A pointer to a node inside the XML
   20.92 + * @return A GSList containing a list of all the programs
   20.93 + */
   20.94 +GSList         *
   20.95 +get_Program_List(xmlNodePtr node)
   20.96 +{
   20.97 +    GSList         *program_list = NULL;
   20.98 +
   20.99 +    while (node != NULL) {
  20.100 +        if (g_ascii_strcasecmp((char *) node->name, "text") != 0) {
  20.101 +            GMythProgram   *program = (GMythProgram *)
  20.102 +                g_malloc(sizeof(struct _GMythProgram));
  20.103 +
  20.104 +            program->title = g_strdup((char *)
  20.105 +                                      xmlGetProp(node,
  20.106 +                                                 (xmlChar *) "title"));
  20.107 +
  20.108 +            program->subtitle = g_strdup((char *)
  20.109 +                                         xmlGetProp(node, (xmlChar *)
  20.110 +                                                    "subtitle"));
  20.111 +
  20.112 +            program->catType = g_strdup((char *)
  20.113 +                                        xmlGetProp(node, (xmlChar *)
  20.114 +                                                   "catType"));
  20.115 +
  20.116 +            program->category = g_strdup((char *)
  20.117 +                                         xmlGetProp(node, (xmlChar *)
  20.118 +                                                    "category"));
  20.119 +
  20.120 +            sscanf((char *) xmlGetProp(node, (xmlChar *) "repeat"),
  20.121 +                   "%d", &(program->repeat));
  20.122 +
  20.123 +            program->startTime = gmyth_util_string_to_time_val
  20.124 +                ((char *) xmlGetProp(node, (xmlChar *) "startTime"));
  20.125 +
  20.126 +            program->endTime = gmyth_util_string_to_time_val
  20.127 +                ((char *) xmlGetProp(node, (xmlChar *) "endTime"));
  20.128 +
  20.129 +            program_list = g_slist_append(program_list, program);
  20.130 +        }
  20.131 +
  20.132 +        node = node->next;
  20.133 +    }
  20.134 +
  20.135 +    return program_list;
  20.136 +}
  20.137 +
  20.138 +/** Retrieves the Channel List from the ProgramGuide
  20.139 + *
  20.140 + * @param node A pointer to a node inside the XML
  20.141 + * @param epg The struct where is the current epg
  20.142 + * @return The epg from "param" updated
  20.143 + */
  20.144 +void
  20.145 +get_Channel_List(xmlNodePtr node, GMythEpg * epg)
  20.146 +{
  20.147 +    epg->channelList = NULL;
  20.148 +
  20.149 +    while (node != NULL) {
  20.150 +
  20.151 +        if (g_ascii_strcasecmp((char *) node->name, "text") != 0) {
  20.152 +            GMythChannel   *channel = (GMythChannel *) g_malloc
  20.153 +                (sizeof(struct _GMythChannel));
  20.154 +
  20.155 +            channel->channelName = g_strdup((char *)
  20.156 +                                            xmlGetProp(node, (xmlChar *)
  20.157 +                                                       "channelName"));
  20.158 +
  20.159 +            channel->chanNum = g_strdup((char *)
  20.160 +                                        xmlGetProp(node, (xmlChar *)
  20.161 +                                                   "chanNum"));
  20.162 +
  20.163 +            sscanf((char *) xmlGetProp(node, (xmlChar *) "chanId"),
  20.164 +                   "%d", &(channel->chanId));
  20.165 +
  20.166 +            sscanf((char *) xmlGetProp(node, (xmlChar *) "callSign"),
  20.167 +                   "%d", &(channel->callSign));
  20.168 +
  20.169 +            channel->programList = get_Program_List(node->children);
  20.170 +
  20.171 +            epg->channelList = g_slist_append(epg->channelList, channel);
  20.172 +
  20.173 +        }
  20.174 +
  20.175 +        node = node->next;
  20.176 +    }
  20.177 +}
  20.178 +
  20.179 +/** Retrieves the properties from the ProgramGuide
  20.180 + *
  20.181 + * @param nodeTab A pointer to a node inside the XML
  20.182 + * @param epg The struct where is the current epg
  20.183 + * @return The epg from "param" updated
  20.184 + */
  20.185 +void
  20.186 +get_ProgramGuide_Properties(xmlNodePtr nodeTab, GMythEpg * epg)
  20.187 +{
  20.188 +
  20.189 +    xmlNode        *ptr = nodeTab->children->next->children;
  20.190 +
  20.191 +    epg->startTime = gmyth_util_string_to_time_val((char *) ptr->content);
  20.192 +
  20.193 +    ptr = ptr->parent->next->next->children;
  20.194 +    epg->endTime = gmyth_util_string_to_time_val((char *) ptr->content);
  20.195 +
  20.196 +    ptr = ptr->parent->next->next->children;
  20.197 +    sscanf((char *) ptr->content, "%d", &(epg->startChanId));
  20.198 +
  20.199 +    ptr = ptr->parent->next->next->children;
  20.200 +    sscanf((char *) ptr->content, "%d", &(epg->endChanId));
  20.201 +
  20.202 +    ptr = ptr->parent->next->next->children;
  20.203 +    sscanf((char *) ptr->content, "%d", &(epg->numOfChannels));
  20.204 +
  20.205 +    ptr = ptr->parent->next->next->children;
  20.206 +    sscanf((char *) ptr->content, "%d", &(epg->details));
  20.207 +
  20.208 +    ptr = ptr->parent->next->next->children;
  20.209 +    sscanf((char *) ptr->content, "%d", &(epg->totalCount));
  20.210 +
  20.211 +    ptr = ptr->parent->next->next->children;
  20.212 +    epg->asOf = gmyth_util_string_to_time_val((char *) ptr->content);
  20.213 +
  20.214 +    ptr = ptr->parent->next->next->children;
  20.215 +    epg->version = g_strdup((char *) ptr->content);
  20.216 +
  20.217 +    ptr = ptr->parent->next->next->children;
  20.218 +    sscanf((char *) ptr->content, "%d", &(epg->protoVer));
  20.219 +
  20.220 +    ptr = ptr->parent->next->next->children;
  20.221 +    // go to Channel section and retrieve Channels and Programs
  20.222 +    if (epg->numOfChannels > 0)
  20.223 +        get_Channel_List(ptr, epg);
  20.224 +    else
  20.225 +        epg->channelList = NULL;
  20.226 +}
  20.227 +
  20.228 +/** Aux function to retrieve the Eletronic Program Guide
  20.229 + *
  20.230 + * @param doc An XML document (xmlDocPtr)
  20.231 + * @return The epg
  20.232 + */
  20.233 +void
  20.234 +getEpg(xmlDocPtr doc, GMythEpg * epg)
  20.235 +{
  20.236 +    xmlXPathObjectPtr result;
  20.237 +    xmlNodeSetPtr   nodeset;
  20.238 +    xmlChar        *keyword;
  20.239 +
  20.240 +    int             i;
  20.241 +
  20.242 +    result = getXPath((xmlChar *) "/*", doc);
  20.243 +
  20.244 +    if (result) {
  20.245 +        nodeset = result->nodesetval;
  20.246 +        for (i = 0; i < nodeset->nodeNr; i++) {
  20.247 +            keyword = (xmlChar *) nodeset->nodeTab[i]->name;
  20.248 +            if (g_ascii_strcasecmp
  20.249 +                ((char *) keyword, "GetProgramGuideResponse") == 0) {
  20.250 +                get_ProgramGuide_Properties(nodeset->nodeTab[i], epg);
  20.251 +                break;
  20.252 +            }
  20.253 +        }
  20.254 +        xmlXPathFreeObject(result);
  20.255 +    }
  20.256 +
  20.257 +}
  20.258 +
  20.259 +
  20.260 +
  20.261 +/** Retrieves the Eletronic Program Guide from the backend
  20.262 + *
  20.263 + * @param doc An XML document (xmlDocPtr)
  20.264 + * @return The epg
  20.265 + */
  20.266 +GMythEpg
  20.267 +gmyth_http_retrieve_epg(GMythBackendInfo * backend_info,
  20.268 +                        GTimeVal * StartTime, GTimeVal * EndTime,
  20.269 +                        gint StartChanId, gint NumOfChannels,
  20.270 +                        gchar * Details)
  20.271 +{
  20.272 +    GMythEpg        epg;
  20.273 +    MemoryStruct    chunk;
  20.274 +
  20.275 +    chunk.memory = NULL;        /* we expect realloc(NULL, size) to work */
  20.276 +    chunk.size = 0;             /* no data at this point */
  20.277 +
  20.278 +    gchar          *starttime;
  20.279 +
  20.280 +    starttime = (gchar *) xmlURIEscapeStr((const xmlChar *)
  20.281 +                                          gmyth_util_time_to_mythformat_from_time_val
  20.282 +                                          (StartTime), NULL);
  20.283 +
  20.284 +    gchar          *endtime;
  20.285 +
  20.286 +    endtime = (gchar *) xmlURIEscapeStr((const xmlChar *)
  20.287 +                                        gmyth_util_time_to_mythformat_from_time_val
  20.288 +                                        (EndTime), NULL);
  20.289 +
  20.290 +    GString        *command = g_string_new("");
  20.291 +
  20.292 +    g_string_printf(command,
  20.293 +                    "GetProgramGuide?StartTime=%s&EndTime=%s&StartChanId=%d"
  20.294 +                    "&NumOfChannels=%d&Details=%s", starttime, endtime,
  20.295 +                    StartChanId, NumOfChannels, Details);
  20.296 +    gmyth_debug("HTTP Request command = %s\n", command->str);
  20.297 +
  20.298 +    chunk = gmyth_http_request(backend_info, command);
  20.299 +    if (chunk.memory != NULL) {
  20.300 +        xmlDocPtr       doc = XMLParse(chunk.memory, strlen(chunk.memory));
  20.301 +
  20.302 +        getEpg(doc, &epg);
  20.303 +        free(chunk.memory);
  20.304 +    }
  20.305 +
  20.306 +    return epg;
  20.307 +}
  20.308 +
  20.309 +
  20.310 +GMythRecorded_Recording
  20.311 +retrieve_recorded_recording(xmlNodePtr node)
  20.312 +{
  20.313 +    GMythRecorded_Recording recording;
  20.314 +
  20.315 +    if (g_ascii_strcasecmp((char *) node->name, "text") != 0) {
  20.316 +
  20.317 +        sscanf((char *) xmlGetProp(node, (xmlChar *) "dupInType"),
  20.318 +               "%d", &(recording.dupInType));
  20.319 +
  20.320 +        sscanf((char *) xmlGetProp(node, (xmlChar *) "dupMethod"),
  20.321 +               "%d", &(recording.dupMethod));
  20.322 +
  20.323 +        sscanf((char *) xmlGetProp(node, (xmlChar *) "recStatus"),
  20.324 +               "%d", &(recording.recStatus));
  20.325 +
  20.326 +        sscanf((char *) xmlGetProp(node, (xmlChar *) "encoderId"),
  20.327 +               "%d", &(recording.encoderId));
  20.328 +
  20.329 +        sscanf((char *) xmlGetProp(node, (xmlChar *) "recordId"),
  20.330 +               "%d", &(recording.recordId));
  20.331 +
  20.332 +        sscanf((char *) xmlGetProp(node, (xmlChar *) "recType"),
  20.333 +               "%d", &(recording.recType));
  20.334 +
  20.335 +        recording.playGroup = g_strdup((char *)
  20.336 +                                       xmlGetProp(node, (xmlChar *)
  20.337 +                                                  "playGroup"));
  20.338 +
  20.339 +        recording.recGroup = g_strdup((char *)
  20.340 +                                      xmlGetProp(node,
  20.341 +                                                 (xmlChar *) "recGroup"));
  20.342 +
  20.343 +        recording.recProfile = g_strdup((char *)
  20.344 +                                        xmlGetProp(node, (xmlChar *)
  20.345 +                                                   "recProfile"));
  20.346 +
  20.347 +        sscanf((char *) xmlGetProp(node, (xmlChar *) "recPriority"),
  20.348 +               "%d", &(recording.recPriority));
  20.349 +
  20.350 +        recording.recStartTs = gmyth_util_string_to_time_val
  20.351 +            ((char *) xmlGetProp(node, (xmlChar *) "recStartTs"));
  20.352 +
  20.353 +        recording.recEndTs = gmyth_util_string_to_time_val
  20.354 +            ((char *) xmlGetProp(node, (xmlChar *) "recEndTs"));
  20.355 +    }
  20.356 +
  20.357 +    return recording;
  20.358 +}
  20.359 +
  20.360 +
  20.361 +GMythRecorded_Channel
  20.362 +retrieve_recorded_channel(xmlNodePtr node)
  20.363 +{
  20.364 +    GMythRecorded_Channel channel;
  20.365 +
  20.366 +    if (g_ascii_strcasecmp((char *) node->name, "text") != 0) {
  20.367 +
  20.368 +        channel.chanFilters = g_strdup((char *)
  20.369 +                                       xmlGetProp(node, (xmlChar *)
  20.370 +                                                  "chanFilters"));
  20.371 +
  20.372 +        channel.channelName = g_strdup((char *)
  20.373 +                                       xmlGetProp(node, (xmlChar *)
  20.374 +                                                  "channelName"));
  20.375 +
  20.376 +        sscanf((char *) xmlGetProp(node, (xmlChar *) "chanNum"),
  20.377 +               "%d", &(channel.chanNum));
  20.378 +
  20.379 +        sscanf((char *) xmlGetProp(node, (xmlChar *) "sourceId"),
  20.380 +               "%d", &(channel.sourceId));
  20.381 +
  20.382 +        sscanf((char *) xmlGetProp(node, (xmlChar *) "commFree"),
  20.383 +               "%d", &(channel.commFree));
  20.384 +
  20.385 +        sscanf((char *) xmlGetProp(node, (xmlChar *) "inputId"),
  20.386 +               "%d", &(channel.inputId));
  20.387 +
  20.388 +        sscanf((char *) xmlGetProp(node, (xmlChar *) "chanId"),
  20.389 +               "%d", &(channel.chanId));
  20.390 +
  20.391 +        sscanf((char *) xmlGetProp(node, (xmlChar *) "callSign"),
  20.392 +               "%d", &(channel.callSign));
  20.393 +    }
  20.394 +
  20.395 +    return channel;
  20.396 +}
  20.397 +
  20.398 +
  20.399 +
  20.400 +/** Retrieves all the programs from Recorded XML
  20.401 + *
  20.402 + * @param nodeTab A pointer to a node inside the XML
  20.403 + * @param recorded The struct where is the current epg
  20.404 + * @return list with all the recorded programs
  20.405 + */
  20.406 +GSList         *
  20.407 +get_Recorded_Programs(xmlNodePtr node)
  20.408 +{
  20.409 +    GSList         *programList = NULL;
  20.410 +
  20.411 +    while (node != NULL) {
  20.412 +
  20.413 +        if (g_ascii_strcasecmp((char *) node->name, "text") != 0) {
  20.414 +
  20.415 +            GMythRecorded_Program *program = (GMythRecorded_Program *)
  20.416 +                g_malloc(sizeof(struct _GMythRecorded_Program));
  20.417 +
  20.418 +            sscanf((char *)
  20.419 +                   xmlGetProp(node, (xmlChar *) "programFlags"), "%d",
  20.420 +                   &(program->programFlags));
  20.421 +
  20.422 +            program->title = g_strdup((char *)
  20.423 +                                      xmlGetProp(node,
  20.424 +                                                 (xmlChar *) "title"));
  20.425 +
  20.426 +            sscanf((char *) xmlGetProp(node, (xmlChar *) "programId"),
  20.427 +                   "%d", &(program->programId));
  20.428 +
  20.429 +            program->catType = g_strdup((char *)
  20.430 +                                        xmlGetProp(node, (xmlChar *)
  20.431 +                                                   "catType"));
  20.432 +
  20.433 +            program->category = g_strdup((char *)
  20.434 +                                         xmlGetProp(node, (xmlChar *)
  20.435 +                                                    "category"));
  20.436 +
  20.437 +            sscanf((char *) xmlGetProp(node, (xmlChar *) "seriesId"),
  20.438 +                   "%d", &(program->seriesId));
  20.439 +
  20.440 +
  20.441 +            program->startTime = gmyth_util_string_to_time_val
  20.442 +                ((char *) xmlGetProp(node, (xmlChar *) "startTime"));
  20.443 +
  20.444 +            program->endTime = gmyth_util_string_to_time_val
  20.445 +                ((char *) xmlGetProp(node, (xmlChar *) "endTime"));
  20.446 +
  20.447 +            program->lastModified = gmyth_util_string_to_time_val((char *)
  20.448 +                                                                  xmlGetProp
  20.449 +                                                                  (node,
  20.450 +                                                                   (xmlChar
  20.451 +                                                                    *)
  20.452 +                                                                   "lastModified"));
  20.453 +
  20.454 +            /*
  20.455 +             * TODO: FIX ME at gmyth_util program->asOf =
  20.456 +             * gmyth_util_string_to_time_val\ ((char *)xmlGetProp(node,
  20.457 +             * (xmlChar *)"airdate")); 
  20.458 +             */
  20.459 +
  20.460 +            program->subTitle = g_strdup((char *)
  20.461 +                                         xmlGetProp(node, (xmlChar *)
  20.462 +                                                    "subTitle"));
  20.463 +
  20.464 +            sscanf((char *) xmlGetProp(node, (xmlChar *) "stars"),
  20.465 +                   "%d", &(program->stars));
  20.466 +
  20.467 +            sscanf((char *) xmlGetProp(node, (xmlChar *) "repeat"),
  20.468 +                   "%d", &(program->repeat));
  20.469 +
  20.470 +            sscanf((char *) xmlGetProp(node, (xmlChar *) "fileSize"),
  20.471 +                   "%d", &(program->repeat));
  20.472 +
  20.473 +            program->hostname = g_strdup((char *)
  20.474 +                                         xmlGetProp(node, (xmlChar *)
  20.475 +                                                    "hostname"));
  20.476 +
  20.477 +            program->channel = retrieve_recorded_channel(node->children);
  20.478 +
  20.479 +            // Skip the \n
  20.480 +            program->recording =
  20.481 +                retrieve_recorded_recording(node->children->next->next);
  20.482 +
  20.483 +            // add to the list
  20.484 +            programList = g_slist_append(programList, program);
  20.485 +        }
  20.486 +
  20.487 +        node = node->next;
  20.488 +    }
  20.489 +
  20.490 +    return programList;
  20.491 +}
  20.492 +
  20.493 +/** Retrieves the properties from Recorded XML
  20.494 + *
  20.495 + * @param nodeTab A pointer to a node inside the XML
  20.496 + * @param recorded The struct where is the current epg
  20.497 + * @return "recorded" from "param" updated
  20.498 + */
  20.499 +void
  20.500 +get_Recorded_Properties(xmlNodePtr nodeTab, GMythRecorded * recorded)
  20.501 +{
  20.502 +    xmlNode        *ptr = nodeTab->children->next->children;
  20.503 +
  20.504 +    sscanf((char *) ptr->content, "%d", &(recorded->totalCount));
  20.505 +
  20.506 +
  20.507 +    ptr = ptr->parent->next->next->children;
  20.508 +    recorded->asOf = gmyth_util_string_to_time_val((char *) ptr->content);
  20.509 +
  20.510 +    ptr = ptr->parent->next->next->children;
  20.511 +    recorded->version = g_strdup((char *) ptr->content);
  20.512 +
  20.513 +    ptr = ptr->parent->next->next->children;
  20.514 +    sscanf((char *) ptr->content, "%d", &(recorded->protoVer));
  20.515 +
  20.516 +    ptr = ptr->parent->next->next->children;
  20.517 +    if (recorded->totalCount > 0)
  20.518 +        recorded->programList = get_Recorded_Programs(ptr->children);
  20.519 +
  20.520 +}
  20.521 +
  20.522 +
  20.523 +/** Aux function to retrieve Recorded programs
  20.524 + *
  20.525 + * @param doc An XML document (xmlDocPtr)
  20.526 + * @return The recorded var updated
  20.527 + */
  20.528 +void
  20.529 +getRecorded(xmlDocPtr doc, GMythRecorded * recorded)
  20.530 +{
  20.531 +    xmlXPathObjectPtr result;
  20.532 +    xmlNodeSetPtr   nodeset;
  20.533 +    xmlChar        *keyword;
  20.534 +
  20.535 +    int             i;
  20.536 +
  20.537 +    result = getXPath((xmlChar *) "/*", doc);
  20.538 +
  20.539 +    if (result) {
  20.540 +        nodeset = result->nodesetval;
  20.541 +        for (i = 0; i < nodeset->nodeNr; i++) {
  20.542 +            keyword = (xmlChar *) nodeset->nodeTab[i]->name;
  20.543 +            if (g_ascii_strcasecmp
  20.544 +                ((char *) keyword, "GetRecordedResponse") == 0) {
  20.545 +                get_Recorded_Properties(nodeset->nodeTab[i], recorded);
  20.546 +                break;
  20.547 +            }
  20.548 +        }
  20.549 +        xmlXPathFreeObject(result);
  20.550 +    }
  20.551 +
  20.552 +}
  20.553 +
  20.554 +
  20.555 +/** Function to retrieve the files that are recorded
  20.556 + *
  20.557 + */
  20.558 +GMythRecorded
  20.559 +gmyth_http_retrieve_recorded(GMythBackendInfo * backend_info)
  20.560 +{
  20.561 +    GMythRecorded   recorded;
  20.562 +    MemoryStruct    chunk;
  20.563 +
  20.564 +    chunk.memory = NULL;
  20.565 +    chunk.size = 0;
  20.566 +
  20.567 +    GString        *command = g_string_new("");
  20.568 +
  20.569 +    g_string_printf(command, "GetRecorded");
  20.570 +
  20.571 +    chunk = gmyth_http_request(backend_info, command);
  20.572 +    if (chunk.memory != NULL) {
  20.573 +        xmlDocPtr       doc = XMLParse(chunk.memory, strlen(chunk.memory));
  20.574 +
  20.575 +        getRecorded(doc, &recorded);
  20.576 +        free(chunk.memory);
  20.577 +    }
  20.578 +
  20.579 +    return recorded;
  20.580 +}
  20.581 +
  20.582 +
  20.583 +
  20.584 +/** Function to retrieve jobqueue status
  20.585 + *
  20.586 + */
  20.587 +gint
  20.588 +gmyth_http_retrieve_job_status(GMythBackendInfo * backend_info,
  20.589 +                               gint chanid, GTimeVal * start)
  20.590 +{
  20.591 +    gint            status = 0;
  20.592 +    gint            count = 0;
  20.593 +    gint            temp_chanid = 0;
  20.594 +    GTimeVal       *temp_start = NULL;
  20.595 +    int             i;
  20.596 +
  20.597 +    xmlXPathObjectPtr result;
  20.598 +    xmlNodeSetPtr   nodeset;
  20.599 +    xmlNodePtr      node;
  20.600 +    MemoryStruct    chunk;
  20.601 +
  20.602 +    chunk.memory = NULL;
  20.603 +    chunk.size = 0;
  20.604 +
  20.605 +    GString        *command = g_string_new("");
  20.606 +
  20.607 +    g_string_printf(command, "GetStatus");
  20.608 +
  20.609 +    chunk = gmyth_http_request(backend_info, command);
  20.610 +
  20.611 +    if (chunk.memory != NULL) {
  20.612 +        xmlDocPtr       doc = XMLParse(chunk.memory, strlen(chunk.memory));
  20.613 +
  20.614 +        result = getXPath((xmlChar *) "/Status/JobQueue", doc);
  20.615 +        if (result) {
  20.616 +            nodeset = result->nodesetval;
  20.617 +            node = nodeset->nodeTab[0];
  20.618 +            sscanf((char *) xmlGetProp(node, (xmlChar *) "count"),
  20.619 +                   "%d", &count);
  20.620 +
  20.621 +            if (count > 0) {
  20.622 +
  20.623 +                // Get the first child
  20.624 +                node = node->children->next;
  20.625 +
  20.626 +                for (i = 0; i < count; i++) {
  20.627 +
  20.628 +                    sscanf((char *)
  20.629 +                           xmlGetProp(node, (xmlChar *) "chanId"), "%d",
  20.630 +                           &temp_chanid);
  20.631 +
  20.632 +                    if (chanid == temp_chanid) {
  20.633 +                        temp_start = gmyth_util_string_to_time_val((char *)
  20.634 +                                                                   xmlGetProp
  20.635 +                                                                   (node,
  20.636 +                                                                    (xmlChar
  20.637 +                                                                     *)
  20.638 +                                                                    "startTime"));
  20.639 +
  20.640 +                        if ((temp_start->tv_sec == start->tv_sec) &&
  20.641 +                            (temp_start->tv_usec == start->tv_usec))
  20.642 +                            sscanf((char *)
  20.643 +                                   xmlGetProp(node,
  20.644 +                                              (xmlChar *) "status"),
  20.645 +                                   "%d", &status);
  20.646 +                    }
  20.647 +                    // Escape "text" node
  20.648 +                    node = node->next->next;
  20.649 +                }
  20.650 +            }
  20.651 +
  20.652 +        }
  20.653 +
  20.654 +        xmlXPathFreeObject(result);
  20.655 +        free(chunk.memory);
  20.656 +
  20.657 +    }
  20.658 +
  20.659 +    return status;
  20.660 +}
  20.661 +
  20.662 +
  20.663 +
  20.664 +/** Function to retrieve settings on the backend
  20.665 + *
  20.666 + * @param backend_info infos about the backend
  20.667 + * @param key the key you want to retrieve
  20.668 + * @param hostname the hostname that the key is set up
  20.669 + * @return the value of the key
  20.670 + */
  20.671 +gchar          *
  20.672 +gmyth_http_retrieve_setting(GMythBackendInfo * backend_info,
  20.673 +                            gchar * key, gchar * hostname)
  20.674 +{
  20.675 +    xmlXPathObjectPtr result;
  20.676 +    xmlNodeSetPtr   nodeset;
  20.677 +    xmlChar        *keyword;
  20.678 +    MemoryStruct    chunk;
  20.679 +    gchar          *value = NULL;
  20.680 +
  20.681 +    chunk.memory = NULL;
  20.682 +    chunk.size = 0;
  20.683 +
  20.684 +    GString        *command = g_string_new("");
  20.685 +
  20.686 +    g_string_printf(command, "GetSetting?Key=%s&HostName=%s&Default=NULL",
  20.687 +                    key, hostname);
  20.688 +
  20.689 +    chunk = gmyth_http_request(backend_info, command);
  20.690 +
  20.691 +    if (chunk.memory != NULL) {
  20.692 +        xmlDocPtr       doc = XMLParse(chunk.memory, strlen(chunk.memory));
  20.693 +
  20.694 +        result = getXPath((xmlChar *) "/GetSettingResponse/Values/*", doc);
  20.695 +
  20.696 +        if (result) {
  20.697 +            nodeset = result->nodesetval;
  20.698 +            keyword = (xmlChar *) nodeset->nodeTab[0]->name;
  20.699 +            if (g_ascii_strcasecmp((char *) keyword, "Value") == 0) {
  20.700 +                // Here we have the value
  20.701 +                value = (gchar *) nodeset->nodeTab[0]->children->content;
  20.702 +            }
  20.703 +            xmlXPathFreeObject(result);
  20.704 +        }
  20.705 +
  20.706 +        free(chunk.memory);
  20.707 +    }
  20.708 +
  20.709 +    return value;
  20.710 +}
  20.711 +
  20.712 +/** Common steps for rec_profile's functions
  20.713 + *
  20.714 + * @param backend_info infos about the backend
  20.715 + * @param id the profile's id that you want to delete
  20.716 + * @return 0 if OK
  20.717 + */
  20.718 +gint
  20.719 +rec_profile_common(GMythBackendInfo * backend_info, GString * command)
  20.720 +{
  20.721 +    xmlXPathObjectPtr result;
  20.722 +    xmlNodeSetPtr   nodeset;
  20.723 +    xmlChar        *keyword;
  20.724 +    MemoryStruct    chunk;
  20.725 +
  20.726 +    chunk.memory = NULL;
  20.727 +    chunk.size = 0;
  20.728 +
  20.729 +    int             ret = -1;
  20.730 +
  20.731 +    chunk = gmyth_http_request(backend_info, command);
  20.732 +
  20.733 +    if (chunk.memory != NULL) {
  20.734 +        xmlDocPtr       doc = XMLParse(chunk.memory, strlen(chunk.memory));
  20.735 +
  20.736 +        result = getXPath((xmlChar *) "/*", doc);
  20.737 +
  20.738 +        if (result) {
  20.739 +            nodeset = result->nodesetval;
  20.740 +            keyword = (xmlChar *) nodeset->nodeTab[0]->name;
  20.741 +
  20.742 +            if (g_ascii_strcasecmp((char *) keyword, "Success") == 0)
  20.743 +                ret = 0;
  20.744 +
  20.745 +            xmlXPathFreeObject(result);
  20.746 +        }
  20.747 +
  20.748 +        free(chunk.memory);
  20.749 +    }
  20.750 +
  20.751 +    return ret;
  20.752 +}
  20.753 +
  20.754 +
  20.755 +/** Function to delete recording profiles
  20.756 + *
  20.757 + * @param backend_info infos about the backend
  20.758 + * @param id the profile's id that you want to delete
  20.759 + * @return 0 if OK
  20.760 + */
  20.761 +gint
  20.762 +gmyth_http_del_rec_profile(GMythBackendInfo * backend_info, gint id)
  20.763 +{
  20.764 +
  20.765 +    GString        *command = g_string_new("");
  20.766 +
  20.767 +    g_string_printf(command, "delRecProfiles?id=%d", id);
  20.768 +
  20.769 +
  20.770 +    return rec_profile_common(backend_info, command);
  20.771 +}
  20.772 +
  20.773 +/** Function to create recording profiles
  20.774 + *
  20.775 + * @param backend_info infos about the backend
  20.776 + * @param profilename the name of profile you want to use
  20.777 + * @param groupname the name of groupname you want to use
  20.778 + * @param vcodec the name of the video codec you want to use
  20.779 + * @param acodec the name of the audo codec you want to use
  20.780 + * @return 0 if OK
  20.781 + */
  20.782 +gint
  20.783 +gmyth_http_create_rec_profile(GMythBackendInfo * backend_info,
  20.784 +                              GMythRecProfile * profile)
  20.785 +{
  20.786 +
  20.787 +    if (profile->name != NULL && profile->group != NULL &&
  20.788 +        profile->vcodec && profile->acodec && profile->options != NULL) {
  20.789 +        GString        *command = g_string_new("");
  20.790 +
  20.791 +        g_string_printf(command, "createRecProfiles?profilename=%s&"
  20.792 +                        "groupname=%s&vcodec=%s&acodec=%s&"
  20.793 +                        "transcodelossless=%d&transcoderesize=%d&"
  20.794 +                        "width=%d&height=%d&rtjpegquality=%d&"
  20.795 +                        "rtjpeglumafilter=%d&rtjpegchromafilter=%d&"
  20.796 +                        "mpeg4bitrate=%d&mpeg4maxquality=%d&"
  20.797 +                        "mpeg4minquality=%d&mpeg4qualdiff=%d&"
  20.798 +                        "mpeg4scalebitrate=%d&mpeg4optionvhq=%d&"
  20.799 +                        "mpeg4option4mv=%d&mpeg4optionidct=%d&"
  20.800 +                        "mpeg4optionime=%d&hardwaremjpegquality=%d&"
  20.801 +                        "hardwaremjpeghdecimation=%d&hardwaremjpegvdecimation=%d&"
  20.802 +                        "mpeg2streamtype=%s&mpeg2aspectratio=%s&"
  20.803 +                        "mpeg2bitrate=%d&mpeg2maxbitrate=%d&"
  20.804 +                        "samplerate=%d&mp3quality=%d&"
  20.805 +                        "volume=%d&mpeg2audtype=%s&"
  20.806 +                        "mpeg2audbitratel1=%d&mpeg2audbitratel2=%d&"
  20.807 +                        "mpeg2audvolume=%d",
  20.808 +                        profile->name, profile->group,
  20.809 +                        profile->vcodec, profile->acodec,
  20.810 +                        profile->options->transcodelossless,
  20.811 +                        profile->options->transcoderesize,
  20.812 +                        profile->options->width,
  20.813 +                        profile->options->height,
  20.814 +                        profile->options->rtjpegquality,
  20.815 +                        profile->options->rtjpeglumafilter,
  20.816 +                        profile->options->rtjpegchromafilter,
  20.817 +                        profile->options->mpeg4bitrate,
  20.818 +                        profile->options->mpeg4maxquality,
  20.819 +                        profile->options->mpeg4minquality,
  20.820 +                        profile->options->mpeg4qualdiff,
  20.821 +                        profile->options->mpeg4scalebitrate,
  20.822 +                        profile->options->mpeg4optionvhq,
  20.823 +                        profile->options->mpeg4option4mv,
  20.824 +                        profile->options->mpeg4optionidct,
  20.825 +                        profile->options->mpeg4optionime,
  20.826 +                        profile->options->hardwaremjpegquality,
  20.827 +                        profile->options->hardwaremjpeghdecimation,
  20.828 +                        profile->options->hardwaremjpegvdecimation,
  20.829 +                        profile->options->mpeg2streamtype,
  20.830 +                        profile->options->mpeg2aspectratio,
  20.831 +                        profile->options->mpeg2bitrate,
  20.832 +                        profile->options->mpeg2maxbitrate,
  20.833 +                        profile->options->samplerate,
  20.834 +                        profile->options->mp3quality,
  20.835 +                        profile->options->volume,
  20.836 +                        profile->options->mpeg2audtype,
  20.837 +                        profile->options->mpeg2audbitratel1,
  20.838 +                        profile->options->mpeg2audbitratel2,
  20.839 +                        profile->options->mpeg2audvolume);
  20.840 +
  20.841 +
  20.842 +        return rec_profile_common(backend_info, command);
  20.843 +    } else
  20.844 +        return -1;
  20.845 +}
  20.846 +
  20.847 +/** Function to retrieve recording profiles
  20.848 + *
  20.849 + * @param backend_info infos about the backend
  20.850 + * @param groupname the name of group you want to retrieve
  20.851 + * @return the list of profiles
  20.852 + */
  20.853 +GSList         *
  20.854 +gmyth_http_retrieve_rec_profiles(GMythBackendInfo * backend_info,
  20.855 +                                 gchar * groupname)
  20.856 +{
  20.857 +    xmlXPathObjectPtr result;
  20.858 +    xmlNodeSetPtr   nodeset;
  20.859 +    xmlChar        *keyword;
  20.860 +    MemoryStruct    chunk;
  20.861 +    GSList         *profiles = NULL;
  20.862 +
  20.863 +    chunk.memory = NULL;
  20.864 +    chunk.size = 0;
  20.865 +
  20.866 +    GString        *command = g_string_new("");
  20.867 +
  20.868 +    g_string_printf(command, "GetRecProfiles?groupname=%s", groupname);
  20.869 +
  20.870 +    chunk = gmyth_http_request(backend_info, command);
  20.871 +
  20.872 +    if (chunk.memory != NULL) {
  20.873 +        xmlDocPtr       doc = XMLParse(chunk.memory, strlen(chunk.memory));
  20.874 +
  20.875 +        result = getXPath((xmlChar *) "/*", doc);
  20.876 +
  20.877 +        if (result) {
  20.878 +            nodeset = result->nodesetval;
  20.879 +            keyword = (xmlChar *) nodeset->nodeTab[0]->name;
  20.880 +
  20.881 +            if (g_ascii_strcasecmp((char *) keyword, "Profiles") == 0) {
  20.882 +                xmlNodePtr      node = nodeset->nodeTab[0]->children->next;
  20.883 +                GMythRecProfile *profile;
  20.884 +
  20.885 +                while (node != NULL) {
  20.886 +                    if (g_ascii_strcasecmp((char *) node->name, "text") !=
  20.887 +                        0) {
  20.888 +                        profile = gmyth_recprofile_new();
  20.889 +
  20.890 +                        sscanf((char *) xmlGetProp(node, (xmlChar *)
  20.891 +                                                   "id"), "%d",
  20.892 +                               &(profile->id));
  20.893 +
  20.894 +                        profile->name = g_strdup((char *)
  20.895 +                                                 xmlGetProp(node,
  20.896 +                                                            (xmlChar *)
  20.897 +                                                            "name"));
  20.898 +
  20.899 +                        profile->vcodec = g_strdup((char *)
  20.900 +                                                   xmlGetProp(node,
  20.901 +                                                              (xmlChar *)
  20.902 +                                                              "vcodec"));
  20.903 +
  20.904 +                        profile->acodec = g_strdup((char *)
  20.905 +                                                   xmlGetProp(node,
  20.906 +                                                              (xmlChar *)
  20.907 +                                                              "acodec"));
  20.908 +
  20.909 +                        profile->group = g_strdup(groupname);
  20.910 +
  20.911 +                        profiles = g_slist_append(profiles, profile);
  20.912 +                    }
  20.913 +                    node = node->next;
  20.914 +                }
  20.915 +
  20.916 +            }
  20.917 +            xmlXPathFreeObject(result);
  20.918 +        }
  20.919 +
  20.920 +        free(chunk.memory);
  20.921 +    }
  20.922 +
  20.923 +    return profiles;
  20.924 +}
  20.925 +
  20.926 +
  20.927 +
  20.928 +/*
  20.929 + * Aux functions got from libcurl 
  20.930 + */
  20.931 +void           *
  20.932 +myrealloc(void *ptr, size_t size)
  20.933 +{
  20.934 +    /*
  20.935 +     * There might be a realloc() out there that doesn't like reallocing
  20.936 +     * NULL pointers, so we take care of it here 
  20.937 +     */
  20.938 +    if (ptr)
  20.939 +        return realloc(ptr, size);
  20.940 +    else
  20.941 +        return malloc(size);
  20.942 +}
  20.943 +
  20.944 +size_t
  20.945 +WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
  20.946 +{
  20.947 +    size_t          realsize = size * nmemb;
  20.948 +    MemoryStruct   *mem = (struct _MemoryStruct *) data;
  20.949 +
  20.950 +    mem->memory =
  20.951 +        (char *) myrealloc(mem->memory, mem->size + realsize + 1);
  20.952 +    if (mem->memory) {
  20.953 +        memcpy(&(mem->memory[mem->size]), ptr, realsize);
  20.954 +        mem->size += realsize;
  20.955 +        mem->memory[mem->size] = 0;
  20.956 +    }
  20.957 +
  20.958 +    return realsize;
  20.959 +}
  20.960 +
  20.961 +
  20.962 +/** Send HTTP Command and receives the result of it
  20.963 + *
  20.964 + * @return A string with the response from the server
  20.965 + *          NULL if there is no response.
  20.966 + */
  20.967 +MemoryStruct
  20.968 +gmyth_http_request(GMythBackendInfo * backend_info, GString * command)
  20.969 +{
  20.970 +    LIBXML_TEST_VERSION
  20.971 +        size_t size =
  20.972 +        strlen(backend_info->hostname) + strlen(command->str) + 20;
  20.973 +
  20.974 +    gchar          *URL = (gchar *) g_malloc(sizeof(gchar) * size);
  20.975 +    gchar          *mid = (gchar *) g_malloc(sizeof(gchar) * 6);
  20.976 +
  20.977 +    mid = "";
  20.978 +
  20.979 +    if (g_ascii_strcasecmp(command->str, "GetStatus") &&
  20.980 +        g_ascii_strcasecmp(command->str, "GetStatusHTML")) {
  20.981 +        mid = "Myth/";
  20.982 +    }
  20.983 +
  20.984 +    g_snprintf(URL, size, "http://%s:%d/%s%s",
  20.985 +               backend_info->hostname, backend_info->status_port, mid,
  20.986 +               command->str);
  20.987 +
  20.988 +    CURL           *curl_handle;
  20.989 +
  20.990 +    MemoryStruct    chunk;
  20.991 +
  20.992 +    chunk.memory = NULL;        /* we expect realloc(NULL, size) to work */
  20.993 +    chunk.size = 0;             /* no data at this point */
  20.994 +
  20.995 +    curl_global_init(CURL_GLOBAL_ALL);
  20.996 +
  20.997 +    /*
  20.998 +     * init the curl session 
  20.999 +     */
 20.1000 +    curl_handle = curl_easy_init();
 20.1001 +
 20.1002 +    /*
 20.1003 +     * specify URL to get 
 20.1004 +     */
 20.1005 +    curl_easy_setopt(curl_handle, CURLOPT_URL, URL);
 20.1006 +
 20.1007 +    /*
 20.1008 +     * send all data to this function 
 20.1009 +     */
 20.1010 +    curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION,
 20.1011 +                     WriteMemoryCallback);
 20.1012 +
 20.1013 +    /*
 20.1014 +     * we pass our 'chunk' struct to the callback function 
 20.1015 +     */
 20.1016 +    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &chunk);
 20.1017 +
 20.1018 +    /*
 20.1019 +     * some servers don't like requests that are made without a user-agent
 20.1020 +     * field, so we provide one 
 20.1021 +     */
 20.1022 +    curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
 20.1023 +
 20.1024 +    /*
 20.1025 +     * set timeout 
 20.1026 +     */
 20.1027 +    curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, 20);
 20.1028 +
 20.1029 +    /*
 20.1030 +     * get it! 
 20.1031 +     */
 20.1032 +    curl_easy_perform(curl_handle);
 20.1033 +
 20.1034 +    /*
 20.1035 +     * cleanup curl stuff 
 20.1036 +     */
 20.1037 +    curl_easy_cleanup(curl_handle);
 20.1038 +
 20.1039 +    return chunk;
 20.1040 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/gmyth/gmyth/gmyth_http.h	Mon Feb 25 17:51:43 2008 +0000
    21.3 @@ -0,0 +1,204 @@
    21.4 +/**
    21.5 + * GMyth Library
    21.6 + *
    21.7 + * @file gmyth/gmyth_http.h
    21.8 + * 
    21.9 + * @brief <p> GMythHttp library provides a wrapper to access
   21.10 + * data from the database using http+xml
   21.11 + *
   21.12 + * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   21.13 + * @author Artur Duque de Souza <artur.souza@indt.org.br>
   21.14 + *
   21.15 + *
   21.16 + * This program is free software; you can redistribute it and/or modify
   21.17 + * it under the terms of the GNU Lesser General Public License as published by
   21.18 + * the Free Software Foundation; either version 2 of the License, or
   21.19 + * (at your option) any later version.
   21.20 + *
   21.21 + * This program is distributed in the hope that it will be useful,
   21.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   21.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21.24 + * GNU General Public License for more details.
   21.25 + *
   21.26 + * You should have received a copy of the GNU Lesser General Public License
   21.27 + * along with this program; if not, write to the Free Software
   21.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   21.29 + */
   21.30 +
   21.31 +#ifndef __GMYTH_HTTP_H__
   21.32 +#define __GMYTH_HTTP_H__
   21.33 +
   21.34 +#include <glib-object.h>
   21.35 +
   21.36 +#include <stdio.h>
   21.37 +#include <stdlib.h>
   21.38 +#include <string.h>
   21.39 +#include <stdarg.h>
   21.40 +#include <glib.h>
   21.41 +#include <glib/gprintf.h>
   21.42 +
   21.43 +#include "gmyth_backendinfo.h"
   21.44 +#include "gmyth_util.h"
   21.45 +#include "gmyth_recprofile.h"
   21.46 +
   21.47 +#include <curl/curl.h>
   21.48 +#include <curl/types.h>
   21.49 +#include <curl/easy.h>
   21.50 +
   21.51 +G_BEGIN_DECLS
   21.52 +#define MYTH_PORT_STATUS 6544
   21.53 +#define JOB_UNKNOWN   0x0000
   21.54 +#define JOB_QUEUED    0x0001
   21.55 +#define JOB_PENDING   0x0002
   21.56 +#define JOB_STARTING  0x0003
   21.57 +#define JOB_RUNNING   0x0004
   21.58 +#define JOB_STOPPING  0x0005
   21.59 +#define JOB_PAUSED    0x0006
   21.60 +#define JOB_RETRY     0x0007
   21.61 +#define JOB_ERRORING  0x0008
   21.62 +#define JOB_ABORTING  0x0009
   21.63 +    // JOB_DONE is a mask to indicate the job is done
   21.64 +    // whatever the status is
   21.65 +#define JOB_DONE      0x0100
   21.66 +#define JOB_FINISHED  0x0110
   21.67 +#define JOB_ABORTED   0x0120
   21.68 +#define JOB_ERRORED   0x0130
   21.69 +#define JOB_CANCELLED 0x0140
   21.70 +typedef struct _GMythRecorded_Recording GMythRecorded_Recording;
   21.71 +typedef struct _GMythRecorded_Channel GMythRecorded_Channel;
   21.72 +typedef struct _GMythRecorded_Program GMythRecorded_Program;
   21.73 +typedef struct _GMythRecorded GMythRecorded;
   21.74 +typedef struct _GMythProgram GMythProgram;
   21.75 +typedef struct _GMythChannel GMythChannel;
   21.76 +typedef struct _GMythEpg GMythEpg;
   21.77 +typedef struct _MemoryStruct MemoryStruct;
   21.78 +
   21.79 +struct _MemoryStruct {
   21.80 +    char           *memory;
   21.81 +    size_t          size;
   21.82 +};
   21.83 +
   21.84 +struct _GMythProgram {
   21.85 +    gchar          *title;
   21.86 +    gchar          *subtitle;
   21.87 +    gchar          *catType;
   21.88 +    gchar          *category;
   21.89 +    gint            repeat;
   21.90 +    GTimeVal       *startTime;
   21.91 +    GTimeVal       *endTime;
   21.92 +};
   21.93 +
   21.94 +struct _GMythChannel {
   21.95 +    gchar          *channelName;
   21.96 +    gchar          *chanNum;
   21.97 +    gint            chanId;
   21.98 +    gint            callSign;
   21.99 +    GSList         *programList;
  21.100 +};
  21.101 +
  21.102 +struct _GMythEpg {
  21.103 +    gint            startChanId;
  21.104 +    gint            endChanId;
  21.105 +    gchar          *version;
  21.106 +    gint            protoVer;
  21.107 +    gint            totalCount;
  21.108 +    gint            numOfChannels;
  21.109 +    GTimeVal       *asOf;
  21.110 +    GTimeVal       *startTime;
  21.111 +    GTimeVal       *endTime;
  21.112 +    gint            details;
  21.113 +    GSList         *channelList;
  21.114 +};
  21.115 +
  21.116 +
  21.117 +struct _GMythRecorded_Recording {
  21.118 +    gint            dupInType;
  21.119 +    gint            dupMethod;
  21.120 +    gchar          *playGroup;
  21.121 +    gchar          *recGroup;
  21.122 +    gchar          *recProfile;
  21.123 +    gint            recPriority;
  21.124 +    gint            recStatus;
  21.125 +    gint            encoderId;
  21.126 +    gint            recordId;
  21.127 +    gint            recType;
  21.128 +    GTimeVal       *recStartTs;
  21.129 +    GTimeVal       *recEndTs;
  21.130 +};
  21.131 +
  21.132 +
  21.133 +struct _GMythRecorded_Channel {
  21.134 +    gchar          *chanFilters;
  21.135 +    gchar          *channelName;
  21.136 +    gint            chanNum;
  21.137 +    gint            sourceId;
  21.138 +    gint            commFree;
  21.139 +    gint            inputId;
  21.140 +    gint            chanId;
  21.141 +    gint            callSign;
  21.142 +};
  21.143 +
  21.144 +
  21.145 +struct _GMythRecorded_Program {
  21.146 +    gint            programFlags;
  21.147 +    gchar          *title;
  21.148 +    gint            programId;
  21.149 +    gchar          *catType;
  21.150 +    gchar          *category;
  21.151 +    gint            seriesId;
  21.152 +    GTimeVal       *startTime;
  21.153 +    GTimeVal       *endTime;
  21.154 +    GTimeVal       *airdate;    // ?
  21.155 +    GTimeVal       *lastModified;
  21.156 +    gchar          *subTitle;
  21.157 +    gint            stars;
  21.158 +    gint            repeat;
  21.159 +    gint            fileSize;
  21.160 +    gchar          *hostname;
  21.161 +    GMythRecorded_Channel channel;
  21.162 +    GMythRecorded_Recording recording;
  21.163 +};
  21.164 +
  21.165 +struct _GMythRecorded {
  21.166 +    gchar          *version;
  21.167 +    gint            protoVer;
  21.168 +    gint            totalCount;
  21.169 +    GTimeVal       *asOf;
  21.170 +    GSList         *programList;
  21.171 +};
  21.172 +
  21.173 +
  21.174 +gint            gmyth_http_retrieve_job_status(GMythBackendInfo *
  21.175 +                                               backend_info, gint chanid,
  21.176 +                                               GTimeVal * start);
  21.177 +
  21.178 +gchar          *gmyth_http_retrieve_setting(GMythBackendInfo *
  21.179 +                                            backend_info, gchar * key,
  21.180 +                                            gchar * hostname);
  21.181 +
  21.182 +GMythEpg        gmyth_http_retrieve_epg(GMythBackendInfo * backend_info,
  21.183 +                                        GTimeVal * StartTime,
  21.184 +                                        GTimeVal * EndTime,
  21.185 +                                        gint StartChanId,
  21.186 +                                        gint NumOfChannels,
  21.187 +                                        gchar * Details);
  21.188 +
  21.189 +GMythRecorded   gmyth_http_retrieve_recorded(GMythBackendInfo *
  21.190 +                                             backend_info);
  21.191 +
  21.192 +GSList         *gmyth_http_retrieve_rec_profiles(GMythBackendInfo *
  21.193 +                                                 backend_info,
  21.194 +                                                 gchar * groupname);
  21.195 +
  21.196 +gint            gmyth_http_create_rec_profile(GMythBackendInfo *
  21.197 +                                              backend_info,
  21.198 +                                              GMythRecProfile * profile);
  21.199 +
  21.200 +gint            gmyth_http_del_rec_profile(GMythBackendInfo * backend_info,
  21.201 +                                           gint id);
  21.202 +
  21.203 +MemoryStruct    gmyth_http_request(GMythBackendInfo * backend_info,
  21.204 +                                   GString * command);
  21.205 +
  21.206 +G_END_DECLS
  21.207 +#endif                          /* __GMYTH_HTTP_H__ */
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/gmyth/gmyth/gmyth_jobqueue.c	Mon Feb 25 17:51:43 2008 +0000
    22.3 @@ -0,0 +1,200 @@
    22.4 +/**
    22.5 + * GMyth Library
    22.6 + *
    22.7 + * @file gmyth/gmyth_jobqueue.c
    22.8 + * 
    22.9 + * @brief <p> Library to use JobQueue from mythbackend
   22.10 + *
   22.11 + * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   22.12 + * @author Artur Duque de Souza <artur.souza@indt.org.br>
   22.13 + *
   22.14 + * 
   22.15 + * This program is free software; you can redistribute it and/or modify
   22.16 + * it under the terms of the GNU Lesser General Public License as published by
   22.17 + * the Free Software Foundation; either version 2 of the License, or
   22.18 + * (at your option) any later version.
   22.19 + *
   22.20 + * This program is distributed in the hope that it will be useful,
   22.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   22.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   22.23 + * GNU General Public License for more details.
   22.24 + *
   22.25 + * You should have received a copy of the GNU Lesser General Public License
   22.26 + * along with this program; if not, write to the Free Software
   22.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   22.28 + */
   22.29 +
   22.30 +#ifdef HAVE_CONFIG_H
   22.31 +#include "config.h"
   22.32 +#endif
   22.33 +
   22.34 +#include "gmyth_jobqueue.h"
   22.35 +#include "gmyth_http.h"
   22.36 +#include "gmyth_debug.h"
   22.37 +#include "gmyth_socket.h"
   22.38 +
   22.39 +/** Function to connect
   22.40 + *
   22.41 + * @param backend_info the backendinfo
   22.42 + * @return gboolean - result of connection
   22.43 + *
   22.44 + */
   22.45 +static GMythSocket *
   22.46 +backend_connect(GMythBackendInfo * backend_info)
   22.47 +{
   22.48 +    GMythSocket    *socket = gmyth_socket_new();
   22.49 +
   22.50 +    if (gmyth_socket_connect_to_backend(socket,
   22.51 +                                        gmyth_backend_info_get_hostname
   22.52 +                                        (backend_info),
   22.53 +                                        gmyth_backend_info_get_port
   22.54 +                                        (backend_info), TRUE) == TRUE) {
   22.55 +        gmyth_debug("Backend socket connection success");
   22.56 +        return socket;
   22.57 +    } else {
   22.58 +        gmyth_debug("Connection failed");
   22.59 +        return NULL;
   22.60 +    }
   22.61 +}
   22.62 +
   22.63 +
   22.64 +/** Function to send a command to the backend
   22.65 + *
   22.66 + * @param socket pointer to a socket
   22.67 + * @param action the action itself
   22.68 + * @param job the action itself
   22.69 + * @param chanid the action itself
   22.70 + * @param starttime the action itself
   22.71 + * @param options the action itself
   22.72 + * @return the value returned by the backend
   22.73 + *
   22.74 + */
   22.75 +static gchar   *
   22.76 +send_command(GMythSocket * socket, gchar * action,
   22.77 +             gchar * job, gint chanid, gchar * starttime, gchar * options)
   22.78 +{
   22.79 +    GString        *command = g_string_new("");
   22.80 +    GString        *ret_str;
   22.81 +    gchar          *ret;
   22.82 +
   22.83 +    GMythStringList *retlist = gmyth_string_list_new();
   22.84 +
   22.85 +    g_string_printf(command, "JOBQUEUE %s %s %d %s %s", action, job,
   22.86 +                    chanid, starttime, options);
   22.87 +
   22.88 +    gmyth_string_list_append_string(retlist, command);
   22.89 +    gmyth_socket_write_stringlist(socket, retlist);
   22.90 +
   22.91 +    // receive answer
   22.92 +    gmyth_socket_read_stringlist(socket, retlist);
   22.93 +    ret_str = gmyth_string_list_get_string(retlist, 0);
   22.94 +
   22.95 +    // ret = ret_str->str;
   22.96 +    ret = g_string_free(ret_str, FALSE);
   22.97 +    g_string_free(command, TRUE);
   22.98 +
   22.99 +    gmyth_string_list_clear_all(retlist);
  22.100 +    g_object_unref(retlist);
  22.101 +
  22.102 +    return ret;
  22.103 +}
  22.104 +
  22.105 +
  22.106 +/** Function to analyze the response from the backend
  22.107 + *
  22.108 + * @param ret the msg returned by the backend
  22.109 + * @param value the expected value
  22.110 + * @return 0 if success and -1 if error
  22.111 + *
  22.112 + */
  22.113 +static          gboolean
  22.114 +test_result(gchar * ret, gchar * value)
  22.115 +{
  22.116 +    if (g_ascii_strcasecmp(ret, value) == 0) {
  22.117 +        return TRUE;
  22.118 +    } else {
  22.119 +        gmyth_debug("JobQueue Error: %s", ret);
  22.120 +        return FALSE;
  22.121 +    }
  22.122 +}
  22.123 +
  22.124 +/** Function to add a job inside JOBQUEUE
  22.125 + *
  22.126 + * @param transcode object holding all the info about the transcoding
  22.127 + * @param job the job you want to add the action
  22.128 + * @return TRUE if the job was added, FALSE if not
  22.129 + *
  22.130 + */
  22.131 +gboolean
  22.132 +gmyth_jobqueue_add_job(GMythTranscoder * transcode, gchar * job)
  22.133 +{
  22.134 +    GMythSocket    *socket = backend_connect(transcode->backend_info);
  22.135 +    gboolean        res = FALSE;
  22.136 +
  22.137 +    if (socket != NULL) {
  22.138 +        GString        *options = g_string_new("");
  22.139 +        gchar          *ret = NULL;
  22.140 +
  22.141 +        if (g_ascii_strcasecmp(job, "JOB_TRANSCODE") == 0) {
  22.142 +            if (transcode->cutlist)
  22.143 +                g_string_append(options, " JOB_USE_CUTLIST");
  22.144 +
  22.145 +            if (transcode->output)
  22.146 +                g_string_append_printf(options, " JOB_OUTPUT %s",
  22.147 +                                       transcode->output_filename);
  22.148 +
  22.149 +            if (transcode->profile != NULL)
  22.150 +                g_string_append_printf(options, " %s", transcode->profile);
  22.151 +        }
  22.152 +        ret = send_command(socket, "ADD", job, transcode->chanid,
  22.153 +                           transcode->starttime, options->str);
  22.154 +        res = test_result(ret, "JOBQUEUE_OK");
  22.155 +        gmyth_socket_close_connection(socket);
  22.156 +
  22.157 +        g_object_unref(socket);
  22.158 +
  22.159 +        g_string_free(options, TRUE);
  22.160 +
  22.161 +        if (ret)
  22.162 +            g_free(ret);
  22.163 +
  22.164 +    } else {
  22.165 +        gmyth_debug("JobQueue Connection Failed");
  22.166 +    }
  22.167 +
  22.168 +    return res;
  22.169 +}
  22.170 +
  22.171 +/** Function to change a job cmd inside JOBQUEUE
  22.172 + *
  22.173 + * @param transcode object holding all the info about the transcoding
  22.174 + * @param action the action (ADD)
  22.175 + * @param job the job you want to add the action
  22.176 + * @return the value of the key
  22.177 + *
  22.178 + */
  22.179 +gboolean
  22.180 +gmyth_jobqueue_change_cmd(GMythTranscoder * transcode, gchar * action,
  22.181 +                          gchar * job)
  22.182 +{
  22.183 +    GMythSocket    *socket = backend_connect(transcode->backend_info);
  22.184 +    gboolean        res = FALSE;
  22.185 +
  22.186 +    if (socket != NULL) {
  22.187 +        gchar          *ret = send_command(socket, action, job,
  22.188 +                                           transcode->chanid,
  22.189 +                                           transcode->starttime, "");
  22.190 +
  22.191 +        res = test_result(ret, "JOBQUEUE_CHANGED_CMD_OK");
  22.192 +
  22.193 +        gmyth_socket_close_connection(socket);
  22.194 +        g_object_unref(socket);
  22.195 +
  22.196 +        g_free(ret);
  22.197 +
  22.198 +    } else {
  22.199 +        gmyth_debug("JobQueue Connection Failed");
  22.200 +    }
  22.201 +
  22.202 +    return res;
  22.203 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/gmyth/gmyth/gmyth_jobqueue.h	Mon Feb 25 17:51:43 2008 +0000
    23.3 @@ -0,0 +1,52 @@
    23.4 +/**
    23.5 + * GMyth Library
    23.6 + *
    23.7 + * @file gmyth/gmyth_jobqueue.h
    23.8 + *
    23.9 + * @brief <p> Library to use JobQueue from mythbackend
   23.10 + *
   23.11 + * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   23.12 + * @author Artur Duque de Souza <artur.souza@indt.org.br>
   23.13 + *
   23.14 + *
   23.15 + * This program is free software; you can redistribute it and/or modify
   23.16 + * it under the terms of the GNU Lesser General Public License as published by
   23.17 + * the Free Software Foundation; either version 2 of the License, or
   23.18 + * (at your option) any later version.
   23.19 + *
   23.20 + * This program is distributed in the hope that it will be useful,
   23.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   23.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   23.23 + * GNU General Public License for more details.
   23.24 + *
   23.25 + * You should have received a copy of the GNU Lesser General Public License
   23.26 + * along with this program; if not, write to the Free Software
   23.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23.28 + */
   23.29 +
   23.30 +#ifndef __GMYTH_JOBQUEUE_H__
   23.31 +#define __GMYTH_JOBQUEUE_H__
   23.32 +
   23.33 +#include <glib-object.h>
   23.34 +
   23.35 +#include <stdio.h>
   23.36 +#include <stdlib.h>
   23.37 +#include <string.h>
   23.38 +#include <stdarg.h>
   23.39 +#include <glib.h>
   23.40 +#include <glib/gprintf.h>
   23.41 +
   23.42 +#include "gmyth_stringlist.h"
   23.43 +#include "gmyth_backendinfo.h"
   23.44 +#include "gmyth_transcoder.h"
   23.45 +#include "gmyth_socket.h"
   23.46 +#include "gmyth_util.h"
   23.47 +
   23.48 +G_BEGIN_DECLS
   23.49 +    gboolean gmyth_jobqueue_add_job(GMythTranscoder * transcoder,
   23.50 +                                    gchar * job);
   23.51 +gboolean        gmyth_jobqueue_change_cmd(GMythTranscoder * transcoder,
   23.52 +                                          gchar * action, gchar * job);
   23.53 +
   23.54 +G_END_DECLS
   23.55 +#endif                          /* __GMYTH_JOBQUEUE_H__ */
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/gmyth/gmyth/gmyth_livetv.c	Mon Feb 25 17:51:43 2008 +0000
    24.3 @@ -0,0 +1,980 @@
    24.4 +/**
    24.5 + * GMyth Library
    24.6 + *
    24.7 + * @file gmyth/gmyth_livetv.c
    24.8 + * 
    24.9 + * @brief <p> GMythLiveTV starts a remote TV session with the MythTV backend.
   24.10 + *
   24.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   24.12 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   24.13 + *
   24.14 + * 
   24.15 + * This program is free software; you can redistribute it and/or modify
   24.16 + * it under the terms of the GNU Lesser General Public License as published by
   24.17 + * the Free Software Foundation; either version 2 of the License, or
   24.18 + * (at your option) any later version.
   24.19 + *
   24.20 + * This program is distributed in the hope that it will be useful,
   24.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   24.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   24.23 + * GNU General Public License for more details.
   24.24 + *
   24.25 + * You should have received a copy of the GNU Lesser General Public License
   24.26 + * along with this program; if not, write to the Free Software
   24.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   24.28 + */
   24.29 +
   24.30 +#ifdef HAVE_CONFIG_H
   24.31 +#include "config.h"
   24.32 +#endif
   24.33 +
   24.34 +#include "gmyth_livetv.h"
   24.35 +#include "gmyth_remote_util.h"
   24.36 +#include "gmyth_tvchain.h"
   24.37 +#include "gmyth_socket.h"
   24.38 +#include "gmyth_backendinfo.h"
   24.39 +#include "gmyth_debug.h"
   24.40 +
   24.41 +#include "gmyth_file.h"
   24.42 +#include "gmyth_file_transfer.h"
   24.43 +#include "gmyth_file_local.h"
   24.44 +#include "gmyth_monitor_handler.h"
   24.45 +
   24.46 +#include "gmyth_common.h"
   24.47 +#include "gmyth_util.h"
   24.48 +
   24.49 +static void     gmyth_livetv_class_init(GMythLiveTVClass * klass);
   24.50 +static void     gmyth_livetv_init(GMythLiveTV * object);
   24.51 +
   24.52 +static void     gmyth_livetv_dispose(GObject * object);
   24.53 +static void     gmyth_livetv_finalize(GObject * object);
   24.54 +
   24.55 +static gint     tvchain_curr_index = -1;
   24.56 +
   24.57 +/*
   24.58 + * static GStaticMutex lock = G_STATIC_MUTEX_INIT;
   24.59 + */
   24.60 +
   24.61 +#define GMYTHTV_TRANSFER_MAX_WAITS	    100
   24.62 +
   24.63 +G_DEFINE_TYPE(GMythLiveTV, gmyth_livetv, G_TYPE_OBJECT)
   24.64 +    static void     gmyth_livetv_class_init(GMythLiveTVClass * klass)
   24.65 +{
   24.66 +    GObjectClass   *gobject_class;
   24.67 +
   24.68 +    gobject_class = (GObjectClass *) klass;
   24.69 +
   24.70 +    gobject_class->dispose = gmyth_livetv_dispose;
   24.71 +    gobject_class->finalize = gmyth_livetv_finalize;
   24.72 +}
   24.73 +
   24.74 +static void
   24.75 +gmyth_livetv_init(GMythLiveTV * livetv)
   24.76 +{
   24.77 +    livetv->monitor = NULL;
   24.78 +    livetv->backend_info = NULL;
   24.79 +    livetv->local_hostname = NULL;
   24.80 +    livetv->file = NULL;
   24.81 +    livetv->setup_done = FALSE;
   24.82 +
   24.83 +    livetv->socket = NULL;
   24.84 +    livetv->recorder = NULL;
   24.85 +    livetv->tvchain = NULL;
   24.86 +    livetv->proginfo = NULL;
   24.87 +    livetv->uri = NULL;
   24.88 +
   24.89 +    livetv->mutex = g_mutex_new();
   24.90 +}
   24.91 +
   24.92 +static void
   24.93 +gmyth_livetv_dispose(GObject * object)
   24.94 +{
   24.95 +    GMythLiveTV    *livetv = GMYTH_LIVETV(object);
   24.96 +
   24.97 +
   24.98 +    if (livetv->disposed) {
   24.99 +        /*
  24.100 +         * If dispose did already run, return. 
  24.101 +         */
  24.102 +        return;
  24.103 +    }
  24.104 +
  24.105 +    /*
  24.106 +     * Make sure dispose does not run twice. 
  24.107 +     */
  24.108 +    livetv->disposed = TRUE;
  24.109 +
  24.110 +    if (livetv->monitor != NULL) {
  24.111 +        g_object_unref(livetv->monitor);
  24.112 +        livetv->monitor = NULL;
  24.113 +    }
  24.114 +
  24.115 +
  24.116 +    if (livetv->file != NULL) {
  24.117 +        g_object_unref(livetv->file);
  24.118 +        livetv->file = NULL;
  24.119 +    }
  24.120 +
  24.121 +    if (livetv->recorder != NULL) {
  24.122 +        // gmyth_recorder_close(livetv->recorder);
  24.123 +        g_object_unref(livetv->recorder);
  24.124 +        livetv->recorder = NULL;
  24.125 +    }
  24.126 +
  24.127 +    if (livetv->socket != NULL) {
  24.128 +        g_object_unref(livetv->socket);
  24.129 +        livetv->socket = NULL;
  24.130 +    }
  24.131 +
  24.132 +    if (livetv->tvchain != NULL) {
  24.133 +        g_object_unref(livetv->tvchain);
  24.134 +        livetv->tvchain = NULL;
  24.135 +    }
  24.136 +
  24.137 +    if (livetv->proginfo != NULL) {
  24.138 +        g_object_unref(livetv->proginfo);
  24.139 +        livetv->proginfo = NULL;
  24.140 +    }
  24.141 +
  24.142 +    if (livetv->backend_info != NULL) {
  24.143 +        g_object_unref(livetv->backend_info);
  24.144 +        livetv->backend_info = NULL;
  24.145 +    }
  24.146 +
  24.147 +    if (livetv->uri != NULL) {
  24.148 +        g_object_unref(livetv->uri);
  24.149 +        livetv->uri = NULL;
  24.150 +    }
  24.151 +
  24.152 +    if (livetv->mutex != NULL) {
  24.153 +        g_mutex_free(livetv->mutex);
  24.154 +        livetv->mutex = NULL;
  24.155 +    }
  24.156 +
  24.157 +    if (livetv->local_hostname != NULL) {
  24.158 +        g_string_free(livetv->local_hostname, TRUE);
  24.159 +        livetv->local_hostname = NULL;
  24.160 +    }
  24.161 +
  24.162 +    G_OBJECT_CLASS(gmyth_livetv_parent_class)->dispose(object);
  24.163 +}
  24.164 +
  24.165 +static void
  24.166 +gmyth_livetv_finalize(GObject * object)
  24.167 +{
  24.168 +    g_signal_handlers_destroy(object);
  24.169 +
  24.170 +    G_OBJECT_CLASS(gmyth_livetv_parent_class)->finalize(object);
  24.171 +}
  24.172 +
  24.173 +/**
  24.174 + * Creates a new GMythLiveTV instance
  24.175 + * 
  24.176 + * @return a newly allocated GMythLiveTV instance
  24.177 + */
  24.178 +GMythLiveTV    *
  24.179 +gmyth_livetv_new(GMythBackendInfo * backend_info)
  24.180 +{
  24.181 +    GMythLiveTV    *livetv =
  24.182 +        GMYTH_LIVETV(g_object_new(GMYTH_LIVETV_TYPE, NULL));
  24.183 +
  24.184 +    livetv->backend_info = backend_info;
  24.185 +    g_object_ref(livetv->backend_info);
  24.186 +
  24.187 +    return livetv;
  24.188 +}
  24.189 +
  24.190 +/**
  24.191 + * The GObject signal handler function, from which all status messages 
  24.192 + * from the Monitor Handler will be advertized, all time it receives
  24.193 + * LiveTV status messages from the MythTV backend
  24.194 + * 
  24.195 + * @param monitor a GMythMonitorHandler instance
  24.196 + * @param msg_code the MythTV's server numeric status code
  24.197 + * @param message the message's string description
  24.198 + * @param user_data pointer to the GMythLiveTV instance
  24.199 + */
  24.200 +static void
  24.201 +gmyth_livetv_monitor_signal_handler(GMythMonitorHandler * monitor,
  24.202 +                                    gint msg_code, gchar * message,
  24.203 +                                    gpointer user_data)
  24.204 +{
  24.205 +    GMythLiveTV    *live_tv = GMYTH_LIVETV(user_data);
  24.206 +
  24.207 +    gmyth_debug
  24.208 +        ("LIVETV Signal handler ( msg = %s, code = %d, live_tv param = %s, user_data = %s )\n",
  24.209 +         message, msg_code, live_tv != NULL ? "" : "NULL",
  24.210 +         user_data != NULL ? "" : "NULL");
  24.211 +
  24.212 +    if (NULL == live_tv || !IS_GMYTH_FILE_TRANSFER(live_tv->file)) {
  24.213 +        gmyth_debug("LiveTV_obj is equals to NULL!!!");
  24.214 +        return;
  24.215 +    }
  24.216 +
  24.217 +    switch (msg_code) {
  24.218 +
  24.219 +    case GMYTH_BACKEND_PROGRAM_INFO_CHANGED:
  24.220 +        {
  24.221 +            gmyth_debug
  24.222 +                ("LIVETV Program Changed request received [ msg = %s ]. Watching if the new "
  24.223 +                 "TV Chain ID is the same as the old one...\n", message);
  24.224 +            if (g_ascii_strcasecmp
  24.225 +                (message,
  24.226 +                 (gmyth_tvchain_get_id(live_tv->tvchain))->str) != 0) {
  24.227 +                gmyth_debug
  24.228 +                    ("OK!!! MOVED to the next program chain [actual == %s]!",
  24.229 +                     (gmyth_tvchain_get_id(live_tv->tvchain))->str);
  24.230 +                /*
  24.231 +                 * advertises the FileTransfer about the program info
  24.232 +                 * changed 
  24.233 +                 */
  24.234 +                if (live_tv->file != NULL) {
  24.235 +                    gmyth_debug
  24.236 +                        ("Emitting signal to the FileTransfer... [ \"program-info-changed \" ]");
  24.237 +
  24.238 +                    gmyth_file_transfer_emit_program_info_changed_signal
  24.239 +                        (GMYTH_FILE_TRANSFER(live_tv->file), msg_code,
  24.240 +                         (gpointer) (live_tv->recorder));
  24.241 +
  24.242 +                    /*
  24.243 +                     * gmyth_livetv_monitor_handler_stop( live_tv ); 
  24.244 +                     */
  24.245 +                } else
  24.246 +                    gmyth_debug
  24.247 +                        ("LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");
  24.248 +            }
  24.249 +            break;
  24.250 +        }
  24.251 +    case GMYTH_BACKEND_DONE_RECORDING:
  24.252 +        {
  24.253 +            gmyth_debug
  24.254 +                ("LIVETV Program Changed request received [ msg = %s ]. Watching if the new "
  24.255 +                 "TV Chain ID is the same as the old one...\n", message);
  24.256 +            if (g_ascii_strcasecmp
  24.257 +                (message,
  24.258 +                 (gmyth_tvchain_get_id(live_tv->tvchain))->str) != 0) {
  24.259 +                gmyth_debug
  24.260 +                    ("OK!!! MOVED to the next program chain [actual == %s]!",
  24.261 +                     (gmyth_tvchain_get_id(live_tv->tvchain))->str);
  24.262 +                /*
  24.263 +                 * advertises the FileTransfer about the program info
  24.264 +                 * changed 
  24.265 +                 */
  24.266 +                if (live_tv->file != NULL) {
  24.267 +                    gmyth_debug
  24.268 +                        ("Emitting signal to the FileTransfer... [ \"backend-done-recording\" ]");
  24.269 +
  24.270 +                    gmyth_file_transfer_emit_program_info_changed_signal
  24.271 +                        (GMYTH_FILE_TRANSFER(live_tv->file), msg_code,
  24.272 +                         (gpointer) (live_tv->recorder));
  24.273 +
  24.274 +                } else
  24.275 +                    gmyth_debug
  24.276 +                        ("LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");
  24.277 +            }
  24.278 +            break;
  24.279 +        }
  24.280 +    case GMYTH_BACKEND_STOP_LIVETV:
  24.281 +        {
  24.282 +            gmyth_debug
  24.283 +                ("LIVETV Stop LiveTV request received [ msg = %s ]. Going out the "
  24.284 +                 "LiveTV...\n", message);
  24.285 +            /*
  24.286 +             * stops the LiveTV 
  24.287 +             */
  24.288 +            if (live_tv != NULL) {
  24.289 +                gmyth_debug("Going out the LiveTV... [ \"quit-livetv\" ]");
  24.290 +
  24.291 +                g_object_unref(live_tv);
  24.292 +            } else
  24.293 +                gmyth_debug
  24.294 +                    ("LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");
  24.295 +
  24.296 +            break;
  24.297 +        }
  24.298 +    default:
  24.299 +        break;
  24.300 +    }                           /* switch (Monitor Handler messages) */
  24.301 +
  24.302 +}
  24.303 +
  24.304 +/**
  24.305 + * Starts the Monitor Handler to this GMythLiveTV session, in order
  24.306 + * to receive the status messages from the MythTV's backend server 
  24.307 + * 
  24.308 + * @param live_tv the GMythLiveTV instance
  24.309 + * 
  24.310 + * @return <code>true</code> if the Monitor Handler start-up process
  24.311 + * 	   had been concluded succcesfully 
  24.312 + */
  24.313 +gboolean
  24.314 +gmyth_livetv_monitor_handler_start(GMythLiveTV * livetv)
  24.315 +{
  24.316 +    gboolean        res = TRUE;
  24.317 +
  24.318 +    if (livetv->monitor != NULL) {
  24.319 +        g_object_unref(livetv->monitor);
  24.320 +        livetv->monitor = NULL;
  24.321 +    }
  24.322 +
  24.323 +    livetv->monitor = gmyth_monitor_handler_new();
  24.324 +    res =
  24.325 +        gmyth_monitor_handler_open(livetv->monitor,
  24.326 +                                   livetv->backend_info->hostname,
  24.327 +                                   livetv->backend_info->port);
  24.328 +
  24.329 +    if (res == TRUE) {
  24.330 +        gmyth_debug
  24.331 +            ("Connect MythTV Monitor event socket! Trying to start the message handler...");
  24.332 +
  24.333 +        res = gmyth_monitor_handler_start(livetv->monitor);
  24.334 +
  24.335 +        if (res) {
  24.336 +            gmyth_debug
  24.337 +                ("MythTV Monitor event socket connected and listening!");
  24.338 +            g_signal_connect(G_OBJECT(livetv->monitor),
  24.339 +                             "backend-events-handler", (GCallback)
  24.340 +                             gmyth_livetv_monitor_signal_handler, livetv);
  24.341 +        } else {
  24.342 +            gmyth_debug
  24.343 +                ("Problems when trying to start MythTV Monitor event socket!");
  24.344 +            goto error;
  24.345 +        }
  24.346 +    }
  24.347 +
  24.348 +  error:
  24.349 +    return res;
  24.350 +
  24.351 +}
  24.352 +
  24.353 +/**
  24.354 + * Stops the Monitor Handler to this GMythLiveTV session, in order
  24.355 + * to stop receiving the status messages from the MythTV's backend server 
  24.356 + * 
  24.357 + * @param live_tv the GMythLiveTV instance
  24.358 + * 
  24.359 + * @return <code>true</code> if the Monitor Handler shutdown process
  24.360 + * 	   had been concluded succcesfully 
  24.361 + */
  24.362 +void
  24.363 +gmyth_livetv_monitor_handler_stop(GMythLiveTV * livetv)
  24.364 +{
  24.365 +
  24.366 +    if (livetv->monitor != NULL) {
  24.367 +        g_object_unref(livetv->monitor);
  24.368 +        livetv->monitor = NULL;
  24.369 +    }
  24.370 +
  24.371 +}
  24.372 +
  24.373 +#if 0
  24.374 +static gchar   *
  24.375 +gmyth_livetv_create_remote_url(GMythLiveTV * livetv)
  24.376 +{
  24.377 +    gchar          *uri = g_strdup("");
  24.378 +
  24.379 +    gmyth_backend_info_get_remote_h
  24.380 +        // gmyth_backend(livetv->backend_info)
  24.381 +        return uri;
  24.382 +}
  24.383 +#endif
  24.384 +
  24.385 +/**
  24.386 + * Configures the GMythLiveTV session, sends SPAWN_LIVETV message, 
  24.387 + * sets the channel name, and gets the first program info about the
  24.388 + * actual recording 
  24.389 + * 
  24.390 + * @param live_tv the GMythLiveTV instance
  24.391 + * @param channel the channel name (the chan_name field, from the tvchain table)
  24.392 + * @param backend_info the GMythBackendInfo describing the remote server
  24.393 + * 
  24.394 + * @return <code>true</code> if the LiveTV's recorder instance configuration 
  24.395 + * 				had been concluded succcesfully 
  24.396 + */
  24.397 +static gboolean
  24.398 +gmyth_livetv_setup_recorder_channel_name(GMythLiveTV * livetv,
  24.399 +                                         gchar * channel)
  24.400 +{
  24.401 +    gboolean        res = TRUE;
  24.402 +
  24.403 +    g_return_val_if_fail(livetv != NULL, FALSE);
  24.404 +
  24.405 +    g_mutex_lock(livetv->mutex);
  24.406 +
  24.407 +    if (livetv->socket == NULL) {
  24.408 +        livetv->socket = gmyth_socket_new();
  24.409 +        /*
  24.410 +         * FIME: Implement this at gmyth_socket 
  24.411 +         */
  24.412 +        res =
  24.413 +            gmyth_socket_connect_to_backend(livetv->socket,
  24.414 +                                            livetv->backend_info->hostname,
  24.415 +                                            livetv->backend_info->port,
  24.416 +                                            TRUE);
  24.417 +        if (!res) {
  24.418 +            gmyth_debug("[%s] LiveTV can not connect to backend",
  24.419 +                        __FUNCTION__);
  24.420 +            res = FALSE;
  24.421 +            goto error;
  24.422 +        }
  24.423 +    }
  24.424 +
  24.425 +    livetv->is_livetv = TRUE;
  24.426 +
  24.427 +    livetv->local_hostname = gmyth_socket_get_local_hostname();
  24.428 +
  24.429 +    if (livetv->local_hostname == NULL) {
  24.430 +        g_warning("livetv could not retrieve the local hostname");
  24.431 +        res = FALSE;
  24.432 +        goto error;
  24.433 +    } else {
  24.434 +        gmyth_debug("Local hostname: %s", livetv->local_hostname->str);
  24.435 +    }
  24.436 +
  24.437 +    if (livetv->recorder != NULL) {
  24.438 +        g_object_unref(livetv->recorder);
  24.439 +        livetv->recorder = NULL;
  24.440 +    }
  24.441 +
  24.442 +    if (gmyth_remote_util_get_free_recorder_count(livetv->socket) <= 0) {
  24.443 +        gmyth_debug("No free remote encoder available.");
  24.444 +        res = FALSE;
  24.445 +        goto error;
  24.446 +    }
  24.447 +
  24.448 +    /*
  24.449 +     * Gets the recorder num 
  24.450 +     */
  24.451 +    livetv->recorder =
  24.452 +        remote_request_next_free_recorder(livetv->socket, -1);
  24.453 +    gmyth_socket_close_connection(livetv->socket);
  24.454 +
  24.455 +    if (NULL == livetv->recorder) {
  24.456 +        gmyth_debug("[%s] None remote encoder available", __FUNCTION__);
  24.457 +        res = FALSE;
  24.458 +        goto error;
  24.459 +    }
  24.460 +
  24.461 +    /*
  24.462 +     * Init remote encoder. Opens its control socket. 
  24.463 +     */
  24.464 +    res = gmyth_recorder_setup(livetv->recorder);
  24.465 +    if (!res) {
  24.466 +        gmyth_debug("[%s] Fail while setting remote encoder\n",
  24.467 +                    __FUNCTION__);
  24.468 +        res = FALSE;
  24.469 +        goto error;
  24.470 +    }
  24.471 +
  24.472 +    /*
  24.473 +     * Creates livetv chain handler 
  24.474 +     */
  24.475 +    livetv->tvchain = gmyth_tvchain_new();
  24.476 +    gmyth_tvchain_initialize(livetv->tvchain, livetv->backend_info);
  24.477 +
  24.478 +    if (livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL) {
  24.479 +        res = FALSE;
  24.480 +        goto error;
  24.481 +    }
  24.482 +    // Spawn live tv. Uses the socket to send mythprotocol data to start
  24.483 +    // livetv in the backend (remotelly)
  24.484 +    res = gmyth_recorder_spawntv(livetv->recorder,
  24.485 +                                 gmyth_tvchain_get_id(livetv->tvchain));
  24.486 +    if (!res) {
  24.487 +        gmyth_debug("[%s] Fail while spawn tv\n", __FUNCTION__);
  24.488 +        res = FALSE;
  24.489 +        goto error;
  24.490 +    }
  24.491 +
  24.492 +    if (res == TRUE) {
  24.493 +        /*
  24.494 +         * loop finished, set the max tries variable to zero again... 
  24.495 +         */
  24.496 +        gint            wait_to_transfer = 0;
  24.497 +
  24.498 +        while (wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS &&
  24.499 +               (gmyth_recorder_is_recording(livetv->recorder) == FALSE))
  24.500 +            g_usleep(300);
  24.501 +
  24.502 +        if (channel != NULL) {
  24.503 +            /*
  24.504 +             * Pauses remote encoder. 
  24.505 +             */
  24.506 +            res = gmyth_recorder_pause_recording(livetv->recorder);
  24.507 +            if (!res) {
  24.508 +                gmyth_debug("[%s] Fail while pausing remote encoder\n",
  24.509 +                            __FUNCTION__);
  24.510 +                res = FALSE;
  24.511 +                goto error;
  24.512 +            }
  24.513 +
  24.514 +            if (gmyth_recorder_check_channel_name
  24.515 +                (livetv->recorder, channel)) {
  24.516 +                if (gmyth_recorder_set_channel_name
  24.517 +                    (livetv->recorder, channel)) {
  24.518 +                    gmyth_debug("Channel changed!!! [%s].\n", channel);
  24.519 +                }
  24.520 +            }
  24.521 +
  24.522 +        }
  24.523 +        /*
  24.524 +         * if - changes the channel number 
  24.525 +         */
  24.526 +        /*
  24.527 +         * sleep (5); 
  24.528 +         */
  24.529 +        /*
  24.530 +         * FIXME: this is evil (tpm) 
  24.531 +         */
  24.532 +    }
  24.533 +
  24.534 +    /*
  24.535 +     * DEBUG message 
  24.536 +     */
  24.537 +    GMythProgramInfo *prog_info =
  24.538 +        gmyth_recorder_get_current_program_info(livetv->recorder);
  24.539 +
  24.540 +    if (NULL == prog_info) {
  24.541 +        gmyth_debug("ProgramInfo is equals to NULL!!!");
  24.542 +
  24.543 +        gint            i;
  24.544 +        gchar          *channame = NULL;
  24.545 +
  24.546 +        gmyth_debug("Problem getting current proginfo!\n");
  24.547 +
  24.548 +        /*
  24.549 +         * mythbackend must not be tuned in to a channel, so keep
  24.550 +         * changing channels until we find a valid one, or until
  24.551 +         * we decide to give up.
  24.552 +         */
  24.553 +        for (i = 1; i < 1000; i++) {
  24.554 +            if (channame != NULL)
  24.555 +                g_free(channame);
  24.556 +            channame = g_strdup_printf("%d", i);
  24.557 +            if (gmyth_recorder_set_channel_name(livetv->recorder, channame)
  24.558 +                < 0) {
  24.559 +                continue;
  24.560 +            }
  24.561 +            prog_info =
  24.562 +                gmyth_recorder_get_next_program_info(livetv->recorder,
  24.563 +                                                     BROWSE_DIRECTION_UP);
  24.564 +            gmyth_program_info_print(prog_info);
  24.565 +            if (prog_info != NULL)
  24.566 +                break;
  24.567 +        }
  24.568 +
  24.569 +    }
  24.570 +
  24.571 +    /*
  24.572 +     * if - Program Info 
  24.573 +     */
  24.574 +    /*
  24.575 +     * prints program info data text 
  24.576 +     */
  24.577 +    gmyth_debug("New ProgramInfo...\n");
  24.578 +    gmyth_program_info_print(prog_info);
  24.579 +
  24.580 +    /*
  24.581 +     * check if the program chain could be obtained from the MythTV
  24.582 +     * protocol message 
  24.583 +     */
  24.584 +    if (prog_info != NULL) {
  24.585 +        gmyth_backend_info_set_username(livetv->tvchain->backend_info,
  24.586 +                                        "mythtv");
  24.587 +        gmyth_backend_info_set_password(livetv->tvchain->backend_info,
  24.588 +                                        "mythtv");
  24.589 +        gmyth_backend_info_set_db_name(livetv->tvchain->backend_info,
  24.590 +                                       "mythconverg");
  24.591 +        GList          *prog_list =
  24.592 +            gmyth_tvchain_get_program_info_from_channel(livetv->tvchain,
  24.593 +                                                        channel);
  24.594 +        GMythProgramInfo *ch_prog = NULL;
  24.595 +
  24.596 +        if (prog_list != NULL && g_list_length(prog_list) > 0) {
  24.597 +            ch_prog = (GMythProgramInfo *) g_list_nth_data(prog_list, 0);
  24.598 +            gmyth_debug
  24.599 +                ("Channel program info (from a list with size = %d)!",
  24.600 +                 g_list_length(prog_list));
  24.601 +            gmyth_program_info_print(ch_prog);
  24.602 +        }
  24.603 +
  24.604 +        gmyth_debug("Program Info: %s\n",
  24.605 +                    gmyth_program_info_to_string(prog_info));
  24.606 +        livetv->proginfo = prog_info;
  24.607 +        /*
  24.608 +         * testing change channel 
  24.609 +         */
  24.610 +        // gmyth_recorder_spawntv_no_tvchain( livetv->recorder );
  24.611 +    } else {
  24.612 +
  24.613 +        /*
  24.614 +         * check for the program info in the TV program chain could be
  24.615 +         * obtained from the MythTV MySQL database 
  24.616 +         */
  24.617 +
  24.618 +        /*
  24.619 +         * Reload all TV chain from Mysql database. 
  24.620 +         */
  24.621 +        gmyth_tvchain_reload_all(livetv->tvchain);
  24.622 +
  24.623 +        if (livetv->tvchain == NULL) {
  24.624 +            res = FALSE;
  24.625 +            goto error;
  24.626 +        }
  24.627 +
  24.628 +        /*
  24.629 +         * Get program info from database using chanid and starttime 
  24.630 +         */
  24.631 +        livetv->proginfo =
  24.632 +            gmyth_tvchain_get_program_at(livetv->tvchain,
  24.633 +                                         tvchain_curr_index++);
  24.634 +        if (livetv->proginfo == NULL) {
  24.635 +            gmyth_debug("LiveTV not successfully started.\n");
  24.636 +            res = FALSE;
  24.637 +            goto error;
  24.638 +        } else {
  24.639 +            res = TRUE;
  24.640 +            gmyth_debug
  24.641 +                ("GMythLiveTV: All requests to backend to start TV were OK. [%s]\n",
  24.642 +                 livetv->proginfo->pathname->str);
  24.643 +        }
  24.644 +
  24.645 +    }
  24.646 +
  24.647 +    livetv->uri =
  24.648 +        (GMythURI *) gmyth_backend_info_get_uri(livetv->backend_info);
  24.649 +
  24.650 +    g_mutex_unlock(livetv->mutex);
  24.651 +
  24.652 +    if (!gmyth_livetv_monitor_handler_start(livetv)) {
  24.653 +        res = FALSE;
  24.654 +        gmyth_debug("LiveTV MONITOR handler error on setup!");
  24.655 +        goto error;
  24.656 +    }
  24.657 +
  24.658 +    livetv->setup_done = TRUE;
  24.659 +
  24.660 +    return res;
  24.661 +
  24.662 +  error:
  24.663 +    g_mutex_unlock(livetv->mutex);
  24.664 +
  24.665 +    gmyth_debug("[%s] ERROR running LiveTV setup.\n", __FUNCTION__);
  24.666 +
  24.667 +    res = FALSE;
  24.668 +
  24.669 +    if (livetv->local_hostname != NULL) {
  24.670 +        g_string_free(livetv->local_hostname, TRUE);
  24.671 +        livetv->local_hostname = NULL;
  24.672 +    }
  24.673 +
  24.674 +    gmyth_debug("[%s] ERROR running LiveTV setup.\n", __FUNCTION__);
  24.675 +
  24.676 +    if (livetv->recorder != NULL) {
  24.677 +        g_object_unref(livetv->recorder);
  24.678 +        livetv->recorder = NULL;
  24.679 +    }
  24.680 +
  24.681 +    gmyth_debug("[%s] ERROR running LiveTV setup.\n", __FUNCTION__);
  24.682 +
  24.683 +    if (livetv->tvchain != NULL) {
  24.684 +        g_object_unref(livetv->tvchain);
  24.685 +        livetv->tvchain = NULL;
  24.686 +    }
  24.687 +
  24.688 +    gmyth_debug("[%s] ERROR running LiveTV setup.\n", __FUNCTION__);
  24.689 +
  24.690 +    if (livetv->proginfo != NULL) {
  24.691 +        g_object_unref(livetv->proginfo);
  24.692 +        livetv->proginfo = NULL;
  24.693 +    }
  24.694 +
  24.695 +    gmyth_debug("[%s] ERROR running LiveTV setup.\n", __FUNCTION__);
  24.696 +
  24.697 +    if (livetv->monitor != NULL) {
  24.698 +        g_object_unref(livetv->monitor);
  24.699 +        livetv->monitor = NULL;
  24.700 +    }
  24.701 +
  24.702 +
  24.703 +    gmyth_debug("[%s] ERROR running LiveTV setup.\n", __FUNCTION__);
  24.704 +
  24.705 +    return res;
  24.706 +
  24.707 +}
  24.708 +
  24.709 +/**
  24.710 + * Setup the GMythLiveTV session, sends SPAWN_LIVETV message, 
  24.711 + * sets the channel name, and gets the first program info about the
  24.712 + * actual recording 
  24.713 + * 
  24.714 + * @param live_tv the GMythLiveTV instance
  24.715 + * @param channel the channel name, in numerical format
  24.716 + * @param backend_info the GMythBackendInfo describing the remote server
  24.717 + * 
  24.718 + * @return <code>true</code> if the LiveTV's recorder instance configuration 
  24.719 + * 				had been concluded succcesfully 
  24.720 + */
  24.721 +static          gboolean
  24.722 +gmyth_livetv_setup_recorder(GMythLiveTV * livetv, gint channel)
  24.723 +{
  24.724 +    return gmyth_livetv_setup_recorder_channel_name(livetv,
  24.725 +                                                    (channel !=
  24.726 +                                                     -1) ?
  24.727 +                                                    g_strdup_printf("%d",
  24.728 +                                                                    channel)
  24.729 +                                                    : NULL);
  24.730 +}
  24.731 +
  24.732 +/**
  24.733 + * Setup the GMythLiveTV session, sends SPAWN_LIVETV message, 
  24.734 + * sets the channel name (numerical format), and gets the first program info about the
  24.735 + * actual recording 
  24.736 + * 
  24.737 + * @param live_tv the GMythLiveTV instance
  24.738 + * @param channel the channel name, in numerical format
  24.739 + * @param backend_info the GMythBackendInfo describing the remote server
  24.740 + * 
  24.741 + * @return <code>true</code> if the LiveTV's recorder instance configuration 
  24.742 + * 				had been concluded succcesfully 
  24.743 + */
  24.744 +gboolean
  24.745 +gmyth_livetv_channel_setup(GMythLiveTV * livetv, gint channel)
  24.746 +{
  24.747 +    return gmyth_livetv_setup_recorder(livetv, channel);
  24.748 +}
  24.749 +
  24.750 +/**
  24.751 + * Setup the GMythLiveTV session, sends SPAWN_LIVETV message, 
  24.752 + * sets the channel name (string format), and gets the first program info about the
  24.753 + * actual recording 
  24.754 + * 
  24.755 + * @param live_tv the GMythLiveTV instance
  24.756 + * @param channel the channel name, in numerical format
  24.757 + * @param backend_info the GMythBackendInfo describing the remote server
  24.758 + * 
  24.759 + * @return <code>true</code> if the LiveTV's recorder instance configuration 
  24.760 + * 				had been concluded succcesfully 
  24.761 + */
  24.762 +gboolean
  24.763 +gmyth_livetv_channel_name_setup(GMythLiveTV * livetv, gchar * channel)
  24.764 +{
  24.765 +    return gmyth_livetv_setup_recorder_channel_name(livetv, channel);
  24.766 +}
  24.767 +
  24.768 +/**
  24.769 + * Setup the GMythLiveTV session, sends SPAWN_LIVETV message, 
  24.770 + * and gets the first program info about the actual recording
  24.771 + * (doesn't changes the channel). 
  24.772 + * 
  24.773 + * @param live_tv the GMythLiveTV instance
  24.774 + * @param backend_info the GMythBackendInfo describing the remote server
  24.775 + * 
  24.776 + * @return <code>true</code> if the LiveTV's recorder instance configuration 
  24.777 + * 				had been concluded succcesfully 
  24.778 + */
  24.779 +gboolean
  24.780 +gmyth_livetv_setup(GMythLiveTV * livetv)
  24.781 +{
  24.782 +    return gmyth_livetv_setup_recorder(livetv, -1);
  24.783 +}
  24.784 +
  24.785 +/**
  24.786 + * Gets the next program info from this GMythLiveTV session.
  24.787 + * 
  24.788 + * @param live_tv the GMythLiveTV instance
  24.789 + * 
  24.790 + * @return <code>true</code> if the next program info could be got 
  24.791 + */
  24.792 +gboolean
  24.793 +gmyth_livetv_next_program_chain(GMythLiveTV * livetv)
  24.794 +{
  24.795 +    gboolean        res = TRUE;
  24.796 +    GMythProgramInfo *prog_info = NULL;
  24.797 +
  24.798 +    if (!livetv->setup_done) {
  24.799 +        gmyth_debug("Call the setup function first!");
  24.800 +        goto error;
  24.801 +    }
  24.802 +
  24.803 +    gmyth_debug("Current ProgramInfo...\n");
  24.804 +    prog_info = gmyth_recorder_get_current_program_info(livetv->recorder);
  24.805 +
  24.806 +    if (prog_info != NULL) {
  24.807 +        livetv->proginfo = prog_info;
  24.808 +    } else {
  24.809 +        gmyth_debug
  24.810 +            ("ProgramInfo equals to NULL!!! Getting the next program info...");
  24.811 +        prog_info =
  24.812 +            gmyth_recorder_get_next_program_info(livetv->recorder,
  24.813 +                                                 BROWSE_DIRECTION_RIGHT);
  24.814 +        livetv->proginfo = prog_info;
  24.815 +    }
  24.816 +    /*
  24.817 +     * prints program info data text 
  24.818 +     */
  24.819 +    gmyth_program_info_print(prog_info);
  24.820 +
  24.821 +    if (prog_info != NULL) {
  24.822 +        res = TRUE;
  24.823 +        livetv->proginfo = prog_info;
  24.824 +        gmyth_debug
  24.825 +            ("GMythLiveTV: All requests to backend to start TV were OK, program info changed.");
  24.826 +    } else {
  24.827 +        gmyth_debug
  24.828 +            ("[%s] LiveTV not successfully started on the next program chain.\n",
  24.829 +             __FUNCTION__);
  24.830 +        goto error;
  24.831 +    }
  24.832 +
  24.833 +    livetv->setup_done = TRUE;
  24.834 +
  24.835 +    return res;
  24.836 +
  24.837 +  error:
  24.838 +    gmyth_debug("ERROR running LiveTV setup.\n");
  24.839 +
  24.840 +    res = FALSE;
  24.841 +
  24.842 +    g_string_free(livetv->local_hostname, TRUE);
  24.843 +
  24.844 +    if (livetv->recorder != NULL) {
  24.845 +        g_object_unref(livetv->recorder);
  24.846 +        livetv->recorder = NULL;
  24.847 +    }
  24.848 +
  24.849 +    if (livetv->tvchain != NULL) {
  24.850 +        g_object_unref(livetv->tvchain);
  24.851 +        livetv->tvchain = NULL;
  24.852 +    }
  24.853 +
  24.854 +    if (livetv->proginfo != NULL) {
  24.855 +        g_object_unref(livetv->proginfo);
  24.856 +        livetv->proginfo = NULL;
  24.857 +    }
  24.858 +
  24.859 +    return res;
  24.860 +}
  24.861 +
  24.862 +/**
  24.863 + * Creates a File Transfer session, using all configuration information
  24.864 + * got from the actual program info.
  24.865 + * 
  24.866 + * @param live_tv the GMythLiveTV instance
  24.867 + * 
  24.868 + * @return the actual GMythFileTransfer instance, generated using the
  24.869 + * 		data got from the actual program info.
  24.870 + */
  24.871 +GMythFile*
  24.872 +gmyth_livetv_create_file_transfer(GMythLiveTV * livetv)
  24.873 +{
  24.874 +    // GMythURI* uri = NULL;
  24.875 +
  24.876 +    if (NULL == livetv)
  24.877 +        return NULL;
  24.878 +
  24.879 +    if (!livetv->setup_done) {
  24.880 +        gmyth_debug
  24.881 +            ("Error: You must do the LiveTV setup, just before generating the FileTransfer from LiveTV source!");
  24.882 +        return NULL;
  24.883 +    }
  24.884 +
  24.885 +    if (livetv->proginfo != NULL)
  24.886 +        gmyth_debug("URI path (from program info) = %s.\n",
  24.887 +                    livetv->proginfo->pathname->str);
  24.888 +    else
  24.889 +        gmyth_debug("URI path (from URI) = %s.\n", livetv->uri->uri->str);
  24.890 +
  24.891 +    g_mutex_lock(livetv->mutex);
  24.892 +
  24.893 +    if (livetv->file != NULL) {
  24.894 +        /*
  24.895 +         * gmyth_file_transfer_close( livetv->file ); 
  24.896 +         */
  24.897 +        g_object_unref(livetv->file);
  24.898 +        livetv->file = NULL;
  24.899 +    }
  24.900 +
  24.901 +    if (livetv->uri != NULL) {
  24.902 +        gmyth_debug
  24.903 +            ("URI is not NULL, creating from the ProgramInfo pathname... (%s)",
  24.904 +             livetv->proginfo->pathname->str);
  24.905 +        livetv->uri->path = g_string_erase(livetv->uri->path, 0, -1);
  24.906 +        livetv->uri->path =
  24.907 +            g_string_new(g_strrstr(livetv->proginfo->pathname->str, "/"));
  24.908 +    } else {
  24.909 +        gmyth_debug
  24.910 +            ("URI is NULL, creating from the ProgramInfo pathname... (%s)",
  24.911 +             livetv->proginfo->pathname->str);
  24.912 +        livetv->uri =
  24.913 +            gmyth_uri_new_with_value(livetv->proginfo->pathname->str);
  24.914 +    }
  24.915 +
  24.916 +    if (NULL == livetv->uri) {
  24.917 +        gmyth_debug("Couldn't parse the URI to start LiveTV! [ uri = %s ]",
  24.918 +                    livetv->proginfo->pathname->str);
  24.919 +        goto done;
  24.920 +    }
  24.921 +
  24.922 +    if (gmyth_uri_is_local_file(livetv->uri))
  24.923 +        livetv->file =
  24.924 +            GMYTH_FILE(gmyth_file_local_new(livetv->backend_info));
  24.925 +    else {
  24.926 +        livetv->file =
  24.927 +            GMYTH_FILE(gmyth_file_transfer_new(livetv->backend_info));
  24.928 +        /*
  24.929 +         * gmyth_file_transfer_settimeout(
  24.930 +         * GMYTH_FILE_TRANSFER(livetv->file), TRUE ); 
  24.931 +         */
  24.932 +    }
  24.933 +
  24.934 +    if (NULL == livetv->file) {
  24.935 +        gmyth_debug
  24.936 +            ("Error: couldn't create the FileTransfer from LiveTV source!");
  24.937 +        goto done;
  24.938 +    }
  24.939 +
  24.940 +    g_object_ref(livetv->file);
  24.941 +
  24.942 +done:
  24.943 +    g_mutex_unlock(livetv->mutex);
  24.944 +    return livetv->file;
  24.945 +}
  24.946 +
  24.947 +/**
  24.948 + * Stops this LiveTV session.
  24.949 + * 
  24.950 + * @param live_tv the GMythLiveTV instance
  24.951 + */
  24.952 +void
  24.953 +gmyth_livetv_stop_playing(GMythLiveTV * livetv)
  24.954 +{
  24.955 +    gmyth_debug("Stopping the LiveTV...\n");
  24.956 +
  24.957 +    if (livetv->is_livetv) {
  24.958 +        if (!gmyth_recorder_stop_livetv(livetv->recorder)) {
  24.959 +            gmyth_debug("[%s] Error while stoping remote encoder",
  24.960 +                        __FUNCTION__);
  24.961 +        }
  24.962 +
  24.963 +        if (!gmyth_recorder_finish_recording(livetv->recorder)) {
  24.964 +            gmyth_debug
  24.965 +                ("[%s] Error while finishing recording on remote encoder",
  24.966 +                 __FUNCTION__);
  24.967 +        }
  24.968 +    }
  24.969 +}
  24.970 +
  24.971 +gboolean
  24.972 +gmyth_livetv_is_playing(GMythLiveTV * livetv)
  24.973 +{
  24.974 +    return TRUE;
  24.975 +}
  24.976 +
  24.977 +void
  24.978 +gmyth_livetv_start_playing(GMythLiveTV * livetv)
  24.979 +{
  24.980 +
  24.981 +    // TODO
  24.982 +
  24.983 +}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/gmyth/gmyth/gmyth_livetv.h	Mon Feb 25 17:51:43 2008 +0000
    25.3 @@ -0,0 +1,103 @@
    25.4 +/**
    25.5 + * GMyth Library
    25.6 + *
    25.7 + * @file gmyth/gmyth_livetv.h
    25.8 + * 
    25.9 + * @brief <p> GMythLiveTV starts a remote TV session with the MythTV backend.
   25.10 + *
   25.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   25.12 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   25.13 + *
   25.14 +* 
   25.15 +* This program is free software; you can redistribute it and/or modify
   25.16 +* it under the terms of the GNU Lesser General Public License as published by
   25.17 +* the Free Software Foundation; either version 2 of the License, or
   25.18 +* (at your option) any later version.
   25.19 +*
   25.20 +* This program is distributed in the hope that it will be useful,
   25.21 +	* but WITHOUT ANY WARRANTY; without even the implied warranty of
   25.22 +	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   25.23 +	* GNU General Public License for more details.
   25.24 +	*
   25.25 +	* You should have received a copy of the GNU Lesser General Public License
   25.26 +	* along with this program; if not, write to the Free Software
   25.27 +	* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   25.28 +	*/
   25.29 +
   25.30 +#ifndef GMYTH_LIVETV_H_
   25.31 +#define GMYTH_LIVETV_H_
   25.32 +
   25.33 +#include <glib.h>
   25.34 +#include <glib-object.h>
   25.35 +
   25.36 +#include "gmyth_recorder.h"
   25.37 +#include "gmyth_tvchain.h"
   25.38 +#include "gmyth_monitor_handler.h"
   25.39 +#include "gmyth_file.h"
   25.40 +#include "gmyth_programinfo.h"
   25.41 +#include "gmyth_backendinfo.h"
   25.42 +
   25.43 +G_BEGIN_DECLS
   25.44 +#define GMYTH_LIVETV_TYPE               (gmyth_livetv_get_type ())
   25.45 +#define GMYTH_LIVETV(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_LIVETV_TYPE, GMythLiveTV))
   25.46 +#define GMYTH_LIVETV_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_LIVETV_TYPE, GMythLiveTVClass))
   25.47 +#define IS_GMYTH_LIVETV(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_LIVETV_TYPE))
   25.48 +#define IS_GMYTH_LIVETV_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_LIVETV_TYPE))
   25.49 +#define GMYTH_LIVETV_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_LIVETV_TYPE, GMythLiveTVClass))
   25.50 +typedef struct _GMythLiveTV GMythLiveTV;
   25.51 +typedef struct _GMythLiveTVClass GMythLiveTVClass;
   25.52 +
   25.53 +struct _GMythLiveTVClass {
   25.54 +    GObjectClass    parent_class;
   25.55 +
   25.56 +    /*
   25.57 +     * callbacks 
   25.58 +     */
   25.59 +};
   25.60 +
   25.61 +struct _GMythLiveTV {
   25.62 +    GObject         parent;
   25.63 +
   25.64 +    GMythSocket    *socket;
   25.65 +
   25.66 +    GString        *local_hostname;
   25.67 +
   25.68 +    GMythBackendInfo *backend_info;
   25.69 +
   25.70 +    GMythRecorder  *recorder;
   25.71 +    GMythTVChain   *tvchain;
   25.72 +    GMythProgramInfo *proginfo;
   25.73 +
   25.74 +    GMythFile      *file;
   25.75 +
   25.76 +    GMythMonitorHandler *monitor;
   25.77 +    GMythURI       *uri;
   25.78 +
   25.79 +    gboolean        is_livetv;
   25.80 +    gboolean        setup_done;
   25.81 +
   25.82 +    GMutex         *mutex;
   25.83 +    gboolean        disposed;
   25.84 +};
   25.85 +
   25.86 +GType           gmyth_livetv_get_type(void);
   25.87 +
   25.88 +GMythLiveTV    *gmyth_livetv_new(GMythBackendInfo * backend_info);
   25.89 +
   25.90 +void            gmyth_livetv_start_playing(GMythLiveTV * livetv);
   25.91 +void            gmyth_livetv_stop_playing(GMythLiveTV * livetv);
   25.92 +
   25.93 +gboolean        gmyth_livetv_setup(GMythLiveTV * livetv);
   25.94 +gboolean        gmyth_livetv_channel_setup(GMythLiveTV * livetv,
   25.95 +                                           gint channel);
   25.96 +gboolean        gmyth_livetv_channel_name_setup(GMythLiveTV * livetv,
   25.97 +                                                gchar * channel);
   25.98 +gboolean        gmyth_livetv_next_program_chain(GMythLiveTV * livetv);
   25.99 +
  25.100 +GMythFile      *gmyth_livetv_create_file_transfer(GMythLiveTV * livetv);
  25.101 +
  25.102 +gboolean        gmyth_livetv_monitor_handler_start(GMythLiveTV * livetv);
  25.103 +void            gmyth_livetv_monitor_handler_stop(GMythLiveTV * livetv);
  25.104 +
  25.105 +G_END_DECLS
  25.106 +#endif                          /* GMYTH_LIVETV_H_ */
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/gmyth/gmyth/gmyth_marshal.list	Mon Feb 25 17:51:43 2008 +0000
    26.3 @@ -0,0 +1,2 @@
    26.4 +VOID:INT,STRING
    26.5 +VOID:INT,POINTER
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/gmyth/gmyth/gmyth_monitor_handler.c	Mon Feb 25 17:51:43 2008 +0000
    27.3 @@ -0,0 +1,593 @@
    27.4 +/**
    27.5 + * GMyth Library
    27.6 + *
    27.7 + * @file gmyth/gmyth_monitor_handler.c
    27.8 + * 
    27.9 + * @brief <p> GMythMonitorHandler deals with the streaming media events remote/local
   27.10 + * that are sent to the MythTV frontend.
   27.11 + *
   27.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   27.13 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   27.14 + *
   27.15 + * 
   27.16 + * This program is free software; you can redistribute it and/or modify
   27.17 + * it under the terms of the GNU Lesser General Public License as published by
   27.18 + * the Free Software Foundation; either version 2 of the License, or
   27.19 + * (at your option) any later version.
   27.20 + *
   27.21 + * This program is distributed in the hope that it will be useful,
   27.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   27.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   27.24 + * GNU General Public License for more details.
   27.25 + *
   27.26 + * You should have received a copy of the GNU Lesser General Public License
   27.27 + * along with this program; if not, write to the Free Software
   27.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   27.29 + *
   27.30 + * GStreamer MythTV plug-in properties:
   27.31 + * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv]
   27.32 + * - path (qurl - remote file to be opened)
   27.33 + * - port number *   
   27.34 + */
   27.35 +
   27.36 +#ifdef HAVE_CONFIG_H
   27.37 +#include "config.h"
   27.38 +#endif
   27.39 +
   27.40 +#include <unistd.h>
   27.41 +#include <glib.h>
   27.42 +#include <arpa/inet.h>
   27.43 +#include <sys/types.h>
   27.44 +#include <sys/socket.h>
   27.45 +#include <netdb.h>
   27.46 +#include <errno.h>
   27.47 +#include <stdlib.h>
   27.48 +#include <assert.h>
   27.49 +
   27.50 +#include "gmyth_marshal.h"
   27.51 +
   27.52 +#include "gmyth_monitor_handler.h"
   27.53 +#include "gmyth_debug.h"
   27.54 +
   27.55 +#define GMYTHTV_QUERY_HEADER		"QUERY_FILETRANSFER "
   27.56 +
   27.57 +#define GMYTHTV_VERSION							30
   27.58 +
   27.59 +#define GMYTHTV_TRANSFER_MAX_WAITS	700
   27.60 +
   27.61 +#define GMYTHTV_BUFFER_SIZE					8*1024
   27.62 +
   27.63 +#ifdef GMYTHTV_ENABLE_DEBUG
   27.64 +#define GMYTHTV_ENABLE_DEBUG				1
   27.65 +#else
   27.66 +#undef GMYTHTV_ENABLE_DEBUG
   27.67 +#endif
   27.68 +
   27.69 +/*
   27.70 + * this NDEBUG is to maintain compatibility with GMyth library 
   27.71 + */
   27.72 +#ifndef NDEBUG
   27.73 +#define GMYTHTV_ENABLE_DEBUG				1
   27.74 +#endif
   27.75 +
   27.76 +static gboolean gmyth_monitor_handler_listener  (GIOChannel *io_channel,
   27.77 +                                                 GIOCondition condition,
   27.78 +                                                 gpointer data);
   27.79 +
   27.80 +static void     gmyth_monitor_handler_default_listener(GMythMonitorHandler
   27.81 +                                                       * monitor,
   27.82 +                                                       gint msg_code,
   27.83 +                                                       gchar * message);
   27.84 +
   27.85 +static void     gmyth_monitor_handler_class_init(GMythMonitorHandlerClass *
   27.86 +                                                 klass);
   27.87 +static void     gmyth_monitor_handler_init(GMythMonitorHandler * object);
   27.88 +
   27.89 +static void     gmyth_monitor_handler_dispose(GObject * object);
   27.90 +static void     gmyth_monitor_handler_finalize(GObject * object);
   27.91 +
   27.92 +static gboolean gmyth_connect_to_backend_monitor(GMythMonitorHandler *
   27.93 +                                                 monitor);
   27.94 +
   27.95 +static gboolean gmyth_monitor_handler_setup(GMythMonitorHandler * monitor,
   27.96 +                                            GIOChannel * channel);
   27.97 +
   27.98 +void            gmyth_monitor_handler_close(GMythMonitorHandler * monitor);
   27.99 +
  27.100 +G_DEFINE_TYPE(GMythMonitorHandler, gmyth_monitor_handler, G_TYPE_OBJECT);
  27.101 +
  27.102 +static void
  27.103 +gmyth_monitor_handler_class_init(GMythMonitorHandlerClass * klass)
  27.104 +{
  27.105 +    GObjectClass   *gobject_class;
  27.106 +    GMythMonitorHandlerClass *gmonitor_class;
  27.107 +
  27.108 +    gobject_class = (GObjectClass *) klass;
  27.109 +    gmonitor_class = (GMythMonitorHandlerClass *) gobject_class;
  27.110 +
  27.111 +    gobject_class->dispose = gmyth_monitor_handler_dispose;
  27.112 +    gobject_class->finalize = gmyth_monitor_handler_finalize;
  27.113 +
  27.114 +    gmonitor_class->backend_events_handler_signal_id =
  27.115 +        g_signal_new("backend-events-handler",
  27.116 +                     G_TYPE_FROM_CLASS(gmonitor_class),
  27.117 +                     G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
  27.118 +                     G_SIGNAL_NO_HOOKS, 0, NULL, NULL,
  27.119 +                     gmyth_marshal_VOID__INT_STRING, G_TYPE_NONE, 2,
  27.120 +                     G_TYPE_INT, G_TYPE_STRING);
  27.121 +
  27.122 +    gmonitor_class->backend_events_handler =
  27.123 +        gmyth_monitor_handler_default_listener;
  27.124 +
  27.125 +}
  27.126 +
  27.127 +static void
  27.128 +gmyth_monitor_handler_init(GMythMonitorHandler * monitor)
  27.129 +{
  27.130 +    g_return_if_fail(monitor != NULL);
  27.131 +
  27.132 +    monitor->event_sock = NULL;
  27.133 +    monitor->hostname = NULL;
  27.134 +    monitor->port = 0;
  27.135 +    monitor->actual_index = 0;
  27.136 +    monitor->allow_msgs_listener = FALSE;
  27.137 +    /*
  27.138 +     * it is used for signalizing the event socket consumer thread 
  27.139 +     */
  27.140 +    monitor->mutex = g_mutex_new();
  27.141 +}
  27.142 +
  27.143 +static void
  27.144 +gmyth_monitor_handler_dispose(GObject * object)
  27.145 +{
  27.146 +    GMythMonitorHandler *monitor = GMYTH_MONITOR_HANDLER(object);
  27.147 +
  27.148 +    gmyth_monitor_handler_close(monitor);
  27.149 +
  27.150 +    monitor->allow_msgs_listener = FALSE;
  27.151 +
  27.152 +    if (monitor->io_source != 0) {
  27.153 +        g_source_remove (monitor->io_source);
  27.154 +        monitor->io_source = 0;
  27.155 +    }
  27.156 +
  27.157 +    /*
  27.158 +     * mutex to control access to the event socket consumer thread 
  27.159 +     */
  27.160 +    if (monitor->mutex != NULL) {
  27.161 +        // g_mutex_unlock( monitor->mutex );
  27.162 +        g_mutex_free(monitor->mutex);
  27.163 +        monitor->mutex = NULL;
  27.164 +    }
  27.165 +
  27.166 +    if (monitor->event_sock != NULL) {
  27.167 +        g_object_unref(monitor->event_sock);
  27.168 +        monitor->event_sock = NULL;
  27.169 +    }
  27.170 +
  27.171 +    if (monitor->hostname != NULL) {
  27.172 +        g_free(monitor->hostname);
  27.173 +        monitor->hostname = NULL;
  27.174 +    }
  27.175 +
  27.176 +
  27.177 +    if (monitor->backend_msgs != NULL) {
  27.178 +        g_hash_table_destroy(monitor->backend_msgs);
  27.179 +        monitor->backend_msgs = NULL;
  27.180 +    }
  27.181 +
  27.182 +    /*
  27.183 +     * if ( io_watcher_cond != NULL ) { g_cond_free( io_watcher_cond );
  27.184 +     * io_watcher_cond = NULL; } 
  27.185 +     */
  27.186 +
  27.187 +
  27.188 +    G_OBJECT_CLASS(gmyth_monitor_handler_parent_class)->dispose(object);
  27.189 +}
  27.190 +
  27.191 +static void
  27.192 +gmyth_monitor_handler_finalize(GObject * object)
  27.193 +{
  27.194 +    g_signal_handlers_destroy(object);
  27.195 +
  27.196 +    G_OBJECT_CLASS(gmyth_monitor_handler_parent_class)->finalize(object);
  27.197 +}
  27.198 +
  27.199 +/** 
  27.200 + * Creates a new instance of GMyth Monitor Handler.
  27.201 + * 
  27.202 + * @return a new instance of the Monitor Handler. 
  27.203 + */
  27.204 +GMythMonitorHandler *
  27.205 +gmyth_monitor_handler_new(void)
  27.206 +{
  27.207 +    GMythMonitorHandler *monitor =
  27.208 +        GMYTH_MONITOR_HANDLER(g_object_new
  27.209 +                              (GMYTH_MONITOR_HANDLER_TYPE, FALSE));
  27.210 +
  27.211 +    return monitor;
  27.212 +}
  27.213 +
  27.214 +/** 
  27.215 + * Acquire the mutex to have access to the IO Watcher listener.
  27.216 + * 
  27.217 + * @param monitor The GMythMonitorHandler instance.
  27.218 + * @param do_wait Tells the IO Watcher to wait on the GCond. (obsolete)
  27.219 + * 
  27.220 + * @return <code>true</code>, if the access to IO Watcher was acquired. 
  27.221 + */
  27.222 +static          gboolean
  27.223 +myth_control_acquire_context(GMythMonitorHandler * monitor,
  27.224 +                             gboolean do_wait)
  27.225 +{
  27.226 +
  27.227 +    gboolean        ret = TRUE;
  27.228 +
  27.229 +    g_mutex_lock(monitor->mutex);
  27.230 +
  27.231 +    return ret;
  27.232 +
  27.233 +}
  27.234 +
  27.235 +/** 
  27.236 + * Release the mutex to have access to the IO Watcher listener.
  27.237 + * 
  27.238 + * @param monitor The GMythMonitorHandler instance.
  27.239 + * 
  27.240 + * @return <code>true</code>, if the access to IO Watcher was released. 
  27.241 + */
  27.242 +static          gboolean
  27.243 +myth_control_release_context(GMythMonitorHandler * monitor)
  27.244 +{
  27.245 +
  27.246 +    gboolean        ret = TRUE;
  27.247 +
  27.248 +    g_mutex_unlock(monitor->mutex);
  27.249 +
  27.250 +    return ret;
  27.251 +}
  27.252 +
  27.253 +void
  27.254 +gmyth_monitor_handler_close(GMythMonitorHandler * monitor)
  27.255 +{
  27.256 +    monitor->allow_msgs_listener = FALSE;
  27.257 +
  27.258 +#if 0
  27.259 +    if (monitor->monitor_th != NULL) {
  27.260 +        g_thread_pool_free(monitor->monitor_th, TRUE, FALSE);
  27.261 +        // g_thread_exit( monitor->monitor_th );
  27.262 +        /*
  27.263 +         * if ( monitor->monitor_th != NULL ) g_object_unref(
  27.264 +         * monitor->monitor_th ); 
  27.265 +         */
  27.266 +        monitor->monitor_th = NULL;
  27.267 +    }
  27.268 +
  27.269 +    if (monitor->event_sock != NULL) {
  27.270 +        gmyth_socket_close_connection(monitor->event_sock);
  27.271 +    }
  27.272 +#endif
  27.273 +
  27.274 +}
  27.275 +
  27.276 +/** 
  27.277 + * Opens connection the the Monitor socket on MythTV backend server,
  27.278 + * where all status messages are notified to the client.
  27.279 + * 
  27.280 + * @param monitor The GMythMonitorHandler instance.
  27.281 + * @param hostname The remote host name of the MythTV backend server.
  27.282 + * @param port The remote port number of the MythTV backend server.
  27.283 + * 
  27.284 + * @return <code>true</code>, if the connection was successfully opened.
  27.285 + */
  27.286 +gboolean
  27.287 +gmyth_monitor_handler_open(GMythMonitorHandler * monitor,
  27.288 +                           const gchar * hostname, gint port)
  27.289 +{
  27.290 +    gboolean        ret = TRUE;
  27.291 +
  27.292 +    g_return_val_if_fail(hostname != NULL, FALSE);
  27.293 +
  27.294 +    if (monitor->hostname != NULL) {
  27.295 +        g_free(monitor->hostname);
  27.296 +        monitor->hostname = NULL;
  27.297 +    }
  27.298 +
  27.299 +    monitor->hostname = g_strdup(hostname);
  27.300 +    monitor->port = port;
  27.301 +
  27.302 +    gmyth_debug("Monitor event socket --- hostname: %s, port %d\n",
  27.303 +                monitor->hostname, monitor->port);
  27.304 +
  27.305 +    if (monitor->event_sock != NULL) {
  27.306 +        g_object_unref(monitor->event_sock);
  27.307 +        monitor->event_sock = NULL;
  27.308 +    }
  27.309 +
  27.310 +    /*
  27.311 +     * configure the event socket
  27.312 +     */
  27.313 +    if (!gmyth_connect_to_backend_monitor(monitor)) {
  27.314 +        gmyth_debug("Connection to backend failed (Event Socket)!");
  27.315 +        ret = FALSE;
  27.316 +    } else {
  27.317 +        gmyth_debug ("Remote monitor event socket had been succesfully create");
  27.318 +    }
  27.319 +
  27.320 +    return ret;
  27.321 +}
  27.322 +
  27.323 +/** 
  27.324 + * Reads the data got from the connection to the Monitor socket,
  27.325 + * and looks for some important status messages.
  27.326 + * 
  27.327 + * @param monitor The GMythMonitorHandler instance.
  27.328 + * @param strlist The GMythStringList instance got from the Monitor remote socket.
  27.329 + * @param back_msg_action A string pointer to the status message detailed description.
  27.330 + * 
  27.331 + * @return The backend status message code ID.
  27.332 + */
  27.333 +static          gint
  27.334 +gmyth_monitor_handler_is_backend_message(GMythMonitorHandler * monitor,
  27.335 +                                         GMythStringList * strlist,
  27.336 +                                         gchar ** back_msg_action)
  27.337 +{
  27.338 +    gint            msg_type = GMYTH_BACKEND_NO_MESSAGE;
  27.339 +    GString        *back_msg = NULL;
  27.340 +
  27.341 +    if (gmyth_string_list_length(strlist) > 0) {
  27.342 +
  27.343 +        back_msg = gmyth_string_list_get_string(strlist, 0);
  27.344 +        if (back_msg != NULL && back_msg->str != NULL &&
  27.345 +            strstr(back_msg->str, "BACKEND") != NULL) {
  27.346 +            gmyth_debug("MONITOR HANDLER - Received backend message = %s",
  27.347 +                        back_msg->str);
  27.348 +            *back_msg_action =
  27.349 +                gmyth_string_list_get_char_array(strlist, 1);
  27.350 +
  27.351 +            if (back_msg_action != NULL) {
  27.352 +
  27.353 +                if (g_strstr_len
  27.354 +                    (*back_msg_action, strlen(*back_msg_action),
  27.355 +                     "LIVETV_CHAIN")
  27.356 +                    || g_strstr_len(*back_msg_action,
  27.357 +                                    strlen(*back_msg_action),
  27.358 +                                    "RECORDING_LIST_CHANGE")
  27.359 +                    || g_strstr_len(*back_msg_action,
  27.360 +                                    strlen(*back_msg_action),
  27.361 +                                    "SCHEDULE_CHANGE")
  27.362 +                    || g_strstr_len(*back_msg_action,
  27.363 +                                    strlen(*back_msg_action),
  27.364 +                                    "LIVETV_WATCH")) {
  27.365 +                    gmyth_debug
  27.366 +                        ("MONITOR: message type == GMYTH_BACKEND_PROGRAM_INFO_CHANGED, msg = %s",
  27.367 +                         *back_msg_action);
  27.368 +                    msg_type = GMYTH_BACKEND_PROGRAM_INFO_CHANGED;
  27.369 +                } else if (g_strstr_len
  27.370 +                           (*back_msg_action, strlen(*back_msg_action),
  27.371 +                            "DONE_RECORDING")) {
  27.372 +                    gmyth_debug
  27.373 +                        ("MONITOR: message type == GMYTH_BACKEND_DONE_RECORDING, msg = %s",
  27.374 +                         *back_msg_action);
  27.375 +                    msg_type = GMYTH_BACKEND_DONE_RECORDING;
  27.376 +                } else if (g_strstr_len
  27.377 +                           (*back_msg_action, strlen(*back_msg_action),
  27.378 +                            "QUIT")) {
  27.379 +                    gmyth_debug
  27.380 +                        ("MONITOR: message type == GMYTH_BACKEND_STOP_LIVETV, msg = %s",
  27.381 +                         *back_msg_action);
  27.382 +                    msg_type = GMYTH_BACKEND_STOP_LIVETV;
  27.383 +                }
  27.384 +
  27.385 +                /*
  27.386 +                 * g_hash_table_insert ( monitor->backend_msgs,
  27.387 +                 * &(monitor->actual_index), *back_msg_action ); 
  27.388 +                 */
  27.389 +
  27.390 +            }
  27.391 +            /*
  27.392 +             * if 
  27.393 +             */
  27.394 +        }
  27.395 +        /*
  27.396 +         * if 
  27.397 +         */
  27.398 +        if (back_msg != NULL) {
  27.399 +            g_string_free(back_msg, TRUE);
  27.400 +            back_msg = NULL;
  27.401 +        }
  27.402 +
  27.403 +    }                           /* if - Does Monitor got any message from
  27.404 +                                 * * * backend? */
  27.405 +    else {
  27.406 +        *back_msg_action = g_strdup("");
  27.407 +    }
  27.408 +
  27.409 +    return msg_type;
  27.410 +
  27.411 +}
  27.412 +
  27.413 +static void
  27.414 +gmyth_monitor_handler_default_listener(GMythMonitorHandler * monitor,
  27.415 +                                       gint msg_code, gchar * message)
  27.416 +{
  27.417 +    // assert( message!= NULL ); 
  27.418 +    gmyth_debug("DEFAULT Signal handler ( msg = %s, code = %d )\n",
  27.419 +                message, msg_code);
  27.420 +}
  27.421 +
  27.422 +static void
  27.423 +gmyth_monitor_handler_print(GString * str, gpointer ptr)
  27.424 +{
  27.425 +    gmyth_debug("Backend message event: %s --- ", str->str);
  27.426 +}
  27.427 +
  27.428 +/** 
  27.429 + * Opens connection the the Monitor socket on MythTV backend server,
  27.430 + * where all status messages are notified to the client.
  27.431 + * 
  27.432 + * @param data Pointer to the GMythMonitorHandler.
  27.433 + * 
  27.434 + * @return Pointer to a gboolean <code>true</code> value, if the data was 
  27.435 + * 	successfully read.
  27.436 + */
  27.437 +static gboolean
  27.438 +gmyth_monitor_handler_listener (GIOChannel *io_channel,
  27.439 +                                GIOCondition io_cond,
  27.440 +                                gpointer data)
  27.441 +{
  27.442 +    GMythMonitorHandler *monitor;
  27.443 +    guint           recv = 0;
  27.444 +    gsize           len = 0;
  27.445 +    GMythStringList *strlist = NULL;
  27.446 +    gint bytes_sent = 0;
  27.447 +
  27.448 +    monitor = (GMythMonitorHandler *) data;
  27.449 +
  27.450 +    gmyth_debug("Entering MONITOR handler listener...");
  27.451 +
  27.452 +    myth_control_acquire_context(monitor, TRUE);
  27.453 +
  27.454 +    if (((io_cond & G_IO_HUP) != 0) ||
  27.455 +        ((io_cond & G_IO_ERR) != 0)) {
  27.456 +        goto clean_up;
  27.457 +    }
  27.458 +
  27.459 +
  27.460 +    gmyth_debug("Listening on Monitor socket...!\n");
  27.461 +    strlist = gmyth_string_list_new();
  27.462 +
  27.463 +    len = gmyth_socket_read_stringlist(monitor->event_sock, strlist);
  27.464 +    if ((len > 0) && strlist != NULL && gmyth_string_list_length(strlist) > 0) {
  27.465 +        gchar *back_msg_action;
  27.466 +        gint msg_type;
  27.467 +
  27.468 +        bytes_sent = gmyth_string_list_get_int(strlist, 0);
  27.469 +        // on  backend  error
  27.470 +        gmyth_debug ("received data buffer from IO event channel... %d strings gone!\n", len);
  27.471 +        recv += len;
  27.472 +
  27.473 +        /*
  27.474 +         * debug purpose: prints out all the string list
  27.475 +         * elements
  27.476 +         */
  27.477 +        g_list_foreach(strlist->glist,
  27.478 +                       (GFunc) gmyth_monitor_handler_print,
  27.479 +                       NULL);
  27.480 +
  27.481 +         back_msg_action = g_new0(gchar, 1);
  27.482 +         msg_type = gmyth_monitor_handler_is_backend_message(monitor,
  27.483 +            strlist,
  27.484 +            &back_msg_action);
  27.485 +
  27.486 +        if (msg_type != GMYTH_BACKEND_NO_MESSAGE) {
  27.487 +            g_signal_emit(monitor,
  27.488 +                          GMYTH_MONITOR_HANDLER_GET_CLASS(monitor)->backend_events_handler_signal_id,
  27.489 +                          0, msg_type, back_msg_action);
  27.490 +        }
  27.491 +
  27.492 +        if (back_msg_action != NULL)
  27.493 +            g_free(back_msg_action);
  27.494 +
  27.495 +        g_object_unref(strlist);
  27.496 +    }
  27.497 +
  27.498 +clean_up:
  27.499 +    myth_control_release_context(monitor);
  27.500 +    return TRUE;
  27.501 +}
  27.502 +
  27.503 +/**
  27.504 + * Opens connection events' socket the the Monitor socket on 
  27.505 + * MythTV backend server.
  27.506 + * 
  27.507 + * @param monitor The GMythMonitorHandler instance.
  27.508 + * 
  27.509 + * @return <code>true</code>, if the socket was successfully opened.
  27.510 + */
  27.511 +static gboolean
  27.512 +gmyth_connect_to_backend_monitor(GMythMonitorHandler * monitor)
  27.513 +{
  27.514 +    gboolean        ret = TRUE;
  27.515 +
  27.516 +    monitor->event_sock = gmyth_socket_new();
  27.517 +
  27.518 +    /*
  27.519 +     * Connects the socket, send Mythtv ANN Monitor and verify Mythtv
  27.520 +     * protocol version
  27.521 +     */
  27.522 +    if (!gmyth_socket_connect_to_backend_events(monitor->event_sock,
  27.523 +                                                monitor->hostname,
  27.524 +                                                monitor->port, FALSE)) {
  27.525 +        g_object_unref(monitor->event_sock);
  27.526 +        monitor->event_sock = NULL;
  27.527 +        ret = FALSE;
  27.528 +    }
  27.529 +
  27.530 +    return ret;
  27.531 +}
  27.532 +
  27.533 +/**
  27.534 + * Opens connection the the Monitor socket on MythTV backend server,
  27.535 + * where all status messages are notified to the client.
  27.536 + *
  27.537 + * @param monitor The GMythMonitorHandler instance.
  27.538 + * @param channel The GIOChannel instance to the Monitor socket.
  27.539 + *
  27.540 + * @return Pointer to the boolean value, and it is <code>true</code> only if the 
  27.541 + * GMythMonitorHandler could be configured.
  27.542 + */
  27.543 +static gboolean
  27.544 +gmyth_monitor_handler_setup(GMythMonitorHandler * monitor,
  27.545 +                            GIOChannel * channel)
  27.546 +{
  27.547 +    gboolean ret = TRUE;
  27.548 +
  27.549 +    if (channel != NULL) {
  27.550 +        monitor->allow_msgs_listener = TRUE;
  27.551 +        monitor->io_source = g_io_add_watch (channel, G_IO_IN | G_IO_ERR | G_IO_HUP,
  27.552 +                                             gmyth_monitor_handler_listener,
  27.553 +                                             monitor);
  27.554 +    } else {
  27.555 +        ret = FALSE;
  27.556 +    }
  27.557 +    return ret;
  27.558 +}
  27.559 +
  27.560 +/**
  27.561 + * Starts the MonitorHandler thread to the GIOWatcher.
  27.562 + *
  27.563 + * @param monitor The GMythMonitorHandler instance.
  27.564 + *
  27.565 + * @return <code>true</code>, if the MonitorHandler was started.
  27.566 + */
  27.567 +gboolean
  27.568 +gmyth_monitor_handler_start(GMythMonitorHandler * monitor)
  27.569 +{
  27.570 +    gboolean        ret = TRUE;
  27.571 +
  27.572 +    if (!(ret = g_thread_supported())) {
  27.573 +        gmyth_debug("Thread system wasn't initialized, starting NOW!!!");
  27.574 +        g_thread_init(NULL);
  27.575 +    }
  27.576 +
  27.577 +    ret =
  27.578 +        gmyth_monitor_handler_setup(monitor,
  27.579 +                                    monitor->event_sock->sd_io_ch);
  27.580 +    if (ret) {
  27.581 +        gmyth_debug
  27.582 +            ("\n[%s]\tOK! Starting listener on the MONITOR event socket...[thread location = %p]\n",
  27.583 +             __FUNCTION__, g_thread_self());
  27.584 +    } else {
  27.585 +        gmyth_debug
  27.586 +            ("\n[%s]\tERROR! Coudn't start listener on the MONITOR event socket...[thread location = %p]\n",
  27.587 +             __FUNCTION__, g_thread_self());
  27.588 +        ret = FALSE;
  27.589 +    }
  27.590 +
  27.591 +    gmyth_debug
  27.592 +        ("[%s] Watch listener function over the IO control channel? %s!!!\n",
  27.593 +         __FUNCTION__, (ret == TRUE ? "YES" : "NO"));
  27.594 +
  27.595 +    return ret;
  27.596 +}
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/gmyth/gmyth/gmyth_monitor_handler.h	Mon Feb 25 17:51:43 2008 +0000
    28.3 @@ -0,0 +1,122 @@
    28.4 +/**
    28.5 + * GMyth Library
    28.6 + *
    28.7 + * @file gmyth/gmyth_monitor_handler.h
    28.8 + * 
    28.9 + * @brief <p> GMythMonitorHandler deals with the streaming media events remote/local
   28.10 + * that are sent to the MythTV frontend.
   28.11 + *
   28.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   28.13 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   28.14 + *
   28.15 + * 
   28.16 + * This program is free software; you can redistribute it and/or modify
   28.17 + * it under the terms of the GNU Lesser General Public License as published by
   28.18 + * the Free Software Foundation; either version 2 of the License, or
   28.19 + * (at your option) any later version.
   28.20 + *
   28.21 + * This program is distributed in the hope that it will be useful,
   28.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   28.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   28.24 + * GNU General Public License for more details.
   28.25 + *
   28.26 + * You should have received a copy of the GNU Lesser General Public License
   28.27 + * along with this program; if not, write to the Free Software
   28.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   28.29 + */
   28.30 +
   28.31 +#ifndef __GMYTH_MONITOR_HANDLER_H__
   28.32 +#define __GMYTH_MONITOR_HANDLER_H__
   28.33 +
   28.34 +#include <glib-object.h>
   28.35 +#include <glib.h>
   28.36 +#include <stdio.h>
   28.37 +#include <stdlib.h>
   28.38 +#include <string.h>
   28.39 +
   28.40 +#include <netdb.h>
   28.41 +#include <sys/socket.h>
   28.42 +#include <unistd.h>
   28.43 +
   28.44 +#include "gmyth_socket.h"
   28.45 +#include "gmyth_uri.h"
   28.46 +
   28.47 +G_BEGIN_DECLS
   28.48 +#define GMYTH_MONITOR_HANDLER_TYPE               (gmyth_monitor_handler_get_type ())
   28.49 +#define GMYTH_MONITOR_HANDLER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_MONITOR_HANDLER_TYPE, GMythMonitorHandler))
   28.50 +#define GMYTH_MONITOR_HANDLER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_MONITOR_HANDLER_TYPE, GMythMonitorHandlerClass))
   28.51 +#define IS_GMYTH_MONITOR_HANDLER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_MONITOR_HANDLER_TYPE))
   28.52 +#define IS_GMYTH_MONITOR_HANDLER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_MONITOR_HANDLER_TYPE))
   28.53 +#define GMYTH_MONITOR_HANDLER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_MONITOR_HANDLER_TYPE, GMythMonitorHandlerClass))
   28.54 +#define GMYTHTV_MONITOR_HANDLER_READ_ERROR	-314
   28.55 +    enum {
   28.56 +    GMYTH_BACKEND_NO_MESSAGE = 0,
   28.57 +    GMYTH_BACKEND_PROGRAM_INFO_CHANGED,
   28.58 +    GMYTH_BACKEND_DONE_RECORDING,
   28.59 +    GMYTH_BACKEND_STOP_LIVETV
   28.60 +};
   28.61 +
   28.62 +typedef struct _GMythMonitorHandler GMythMonitorHandler;
   28.63 +typedef struct _GMythMonitorHandlerClass GMythMonitorHandlerClass;
   28.64 +
   28.65 +struct _GMythMonitorHandlerClass {
   28.66 +    GObjectClass    parent_class;
   28.67 +
   28.68 +    /*
   28.69 +     * callbacks
   28.70 +     */
   28.71 +    guint           backend_events_handler_signal_id;
   28.72 +
   28.73 +    /*
   28.74 +     * signal default handlers
   28.75 +     */
   28.76 +    void            (*backend_events_handler) (GMythMonitorHandler *
   28.77 +                                               monitor, gint msg_code,
   28.78 +                                               gchar * message);
   28.79 +};
   28.80 +
   28.81 +struct _GMythMonitorHandler {
   28.82 +    GObject         parent;
   28.83 +
   28.84 +    /*
   28.85 +     * MythTV version number 
   28.86 +     */
   28.87 +    gint            mythtv_version;
   28.88 +
   28.89 +    /*
   28.90 +     * socket descriptors 
   28.91 +     */
   28.92 +    GMythSocket    *event_sock;
   28.93 +
   28.94 +    //gpointer(*gmyth_monitor_handler_listener) (gpointer data);
   28.95 +
   28.96 +    gchar          *hostname;
   28.97 +    gint            port;
   28.98 +
   28.99 +    gint64          actual_index;
  28.100 +
  28.101 +    gboolean        allow_msgs_listener;
  28.102 +
  28.103 +    /*
  28.104 +     * stores the messages coming from the backend 
  28.105 +     */
  28.106 +    GHashTable     *backend_msgs;
  28.107 +
  28.108 +    GMutex         *mutex;
  28.109 +    guint           io_source;
  28.110 +};
  28.111 +
  28.112 +GType           gmyth_monitor_handler_get_type(void);
  28.113 +
  28.114 +GMythMonitorHandler *gmyth_monitor_handler_new(void);
  28.115 +
  28.116 +gboolean        gmyth_monitor_handler_open(GMythMonitorHandler * monitor,
  28.117 +                                           const gchar * hostname,
  28.118 +                                           gint port);
  28.119 +
  28.120 +gboolean        gmyth_monitor_handler_start(GMythMonitorHandler * monitor);
  28.121 +
  28.122 +void            gmyth_monitor_handler_close(GMythMonitorHandler * monitor);
  28.123 +
  28.124 +G_END_DECLS
  28.125 +#endif                          /* __GMYTH_MONITOR_HANDLER_H__ */
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/gmyth/gmyth/gmyth_programinfo.c	Mon Feb 25 17:51:43 2008 +0000
    29.3 @@ -0,0 +1,582 @@
    29.4 +/**
    29.5 + * GMyth Library
    29.6 + *
    29.7 + * @file gmyth/gmyth_programinfo.c
    29.8 + * 
    29.9 + * @brief <p> GMythProgramInfo representing the program info, with the
   29.10 + * configuration data to the actual remote file in the TV chain.
   29.11 + *
   29.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   29.13 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
   29.14 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   29.15 + *
   29.16 + * 
   29.17 + * This program is free software; you can redistribute it and/or modify
   29.18 + * it under the terms of the GNU Lesser General Public License as published by
   29.19 + * the Free Software Foundation; either version 2 of the License, or
   29.20 + * (at your option) any later version.
   29.21 + *
   29.22 + * This program is distributed in the hope that it will be useful,
   29.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   29.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   29.25 + * GNU General Public License for more details.
   29.26 + *
   29.27 + * You should have received a copy of the GNU Lesser General Public License
   29.28 + * along with this program; if not, write to the Free Software
   29.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   29.30 + *
   29.31 + */
   29.32 +
   29.33 +#ifdef HAVE_CONFIG_H
   29.34 +#include "config.h"
   29.35 +#endif
   29.36 +
   29.37 +#include <stdlib.h>
   29.38 +#include <string.h>
   29.39 +#include <assert.h>
   29.40 +
   29.41 +#include "gmyth_programinfo.h"
   29.42 +#include "gmyth_util.h"
   29.43 +#include "gmyth_debug.h"
   29.44 +
   29.45 +static void     gmyth_program_info_class_init(GMythProgramInfoClass *
   29.46 +                                              klass);
   29.47 +static void     gmyth_program_info_init(GMythProgramInfo * object);
   29.48 +
   29.49 +static void     gmyth_program_info_dispose(GObject * object);
   29.50 +static void     gmyth_program_info_finalize(GObject * object);
   29.51 +
   29.52 +G_DEFINE_TYPE(GMythProgramInfo, gmyth_program_info, G_TYPE_OBJECT)
   29.53 +    static const gchar *gmyth_program_info_non_null_value(const GString *
   29.54 +                                                          str);
   29.55 +
   29.56 +    static void     gmyth_program_info_class_init(GMythProgramInfoClass *
   29.57 +                                                  klass)
   29.58 +{
   29.59 +    GObjectClass   *gobject_class = G_OBJECT_CLASS(klass);
   29.60 +
   29.61 +    gobject_class->dispose = gmyth_program_info_dispose;
   29.62 +    gobject_class->finalize = gmyth_program_info_finalize;
   29.63 +}
   29.64 +
   29.65 +static void
   29.66 +gmyth_program_info_init(GMythProgramInfo * gmyth_program_info)
   29.67 +{
   29.68 +    gmyth_program_info->chancommfree = 0;
   29.69 +
   29.70 +    /** A flag informing if the program has video or not. */
   29.71 +    gmyth_program_info->isVideo = FALSE;
   29.72 +    gmyth_program_info->lenMins = 0;
   29.73 +
   29.74 +    gmyth_program_info->stars = 0.0f;
   29.75 +    gmyth_program_info->repeat = 0;
   29.76 +
   29.77 +    gmyth_program_info->hasAirDate = FALSE;
   29.78 +
   29.79 +    gmyth_program_info->spread = 0;
   29.80 +    gmyth_program_info->startCol = 0;
   29.81 +
   29.82 +    gmyth_program_info->recpriority2 = 0;
   29.83 +    gmyth_program_info->reactivate = 0;
   29.84 +
   29.85 +    gmyth_program_info->recordid = 0;
   29.86 +    gmyth_program_info->parentid = 0;
   29.87 +
   29.88 +    /** The backend video source id associated to this program.*/
   29.89 +    gmyth_program_info->sourceid = 0;
   29.90 +    /** the backend input id associated to this program.*/
   29.91 +    gmyth_program_info->inputid = 0;
   29.92 +    /** The backend card id associated to this program.*/
   29.93 +    gmyth_program_info->cardid = 0;
   29.94 +    gmyth_program_info->shareable = FALSE;
   29.95 +    gmyth_program_info->duplicate = FALSE;
   29.96 +
   29.97 +    gmyth_program_info->findid = 0;
   29.98 +
   29.99 +    gmyth_program_info->programflags = 0;
  29.100 +    gmyth_program_info->transcoder = 0;
  29.101 +
  29.102 +    gmyth_program_info->recpriority = 0;
  29.103 +
  29.104 +    /** The file size of the recorded program.*/
  29.105 +    gmyth_program_info->filesize = -1;
  29.106 +}
  29.107 +
  29.108 +static void
  29.109 +gmyth_program_info_dispose(GObject * object)
  29.110 +{
  29.111 +    GMythProgramInfo *gmyth_program_info = GMYTH_PROGRAM_INFO(object);
  29.112 +
  29.113 +    /** The program start time. */
  29.114 +    g_free(gmyth_program_info->startts);
  29.115 +
  29.116 +    /** The program end time. */
  29.117 +    g_free(gmyth_program_info->endts);
  29.118 +
  29.119 +    /** The recording schedule start time. */
  29.120 +    g_free(gmyth_program_info->recstartts);
  29.121 +
  29.122 +    /** The recording schedule end time */
  29.123 +    g_free(gmyth_program_info->recendts);
  29.124 +
  29.125 +    /** The program title. */
  29.126 +    if (gmyth_program_info->title != NULL) {
  29.127 +        g_string_free(gmyth_program_info->title, TRUE);
  29.128 +        gmyth_program_info->title = NULL;
  29.129 +    }
  29.130 +
  29.131 +    /** The program subtitle. */
  29.132 +    if (gmyth_program_info->subtitle != NULL) {
  29.133 +        g_string_free(gmyth_program_info->subtitle, TRUE);
  29.134 +        gmyth_program_info->subtitle = NULL;
  29.135 +    }
  29.136 +
  29.137 +    /** The program description. */
  29.138 +    if (gmyth_program_info->description != NULL) {
  29.139 +        g_string_free(gmyth_program_info->description, TRUE);
  29.140 +        gmyth_program_info->description = NULL;
  29.141 +    }
  29.142 +
  29.143 +    /** The program category. */
  29.144 +    if (gmyth_program_info->category != NULL) {
  29.145 +        g_string_free(gmyth_program_info->category, TRUE);
  29.146 +        gmyth_program_info->category = NULL;
  29.147 +    }
  29.148 +
  29.149 +    if (gmyth_program_info->chanstr != NULL) {
  29.150 +        g_string_free(gmyth_program_info->chanstr, TRUE);
  29.151 +        gmyth_program_info->chanstr = NULL;
  29.152 +    }
  29.153 +
  29.154 +    if (gmyth_program_info->chansign != NULL) {
  29.155 +        g_string_free(gmyth_program_info->chansign, TRUE);
  29.156 +        gmyth_program_info->chansign = NULL;
  29.157 +    }
  29.158 +
  29.159 +    /** The associated channel name. */
  29.160 +    if (gmyth_program_info->channame != NULL) {
  29.161 +        g_string_free(gmyth_program_info->channame, TRUE);
  29.162 +        gmyth_program_info->channame = NULL;
  29.163 +    }
  29.164 +
  29.165 +    if (gmyth_program_info->chanOutputFilters != NULL) {
  29.166 +        g_string_free(gmyth_program_info->chanOutputFilters, TRUE);
  29.167 +        gmyth_program_info->chanOutputFilters = NULL;
  29.168 +    }
  29.169 +
  29.170 +    if (gmyth_program_info->seriesid != NULL) {
  29.171 +        g_string_free(gmyth_program_info->seriesid, TRUE);
  29.172 +        gmyth_program_info->chanOutputFilters = NULL;
  29.173 +    }
  29.174 +
  29.175 +    /** The program unique id. */
  29.176 +    if (gmyth_program_info->program_id != NULL) {
  29.177 +        g_string_free (gmyth_program_info->program_id, TRUE);
  29.178 +        gmyth_program_info->program_id = NULL;
  29.179 +    }
  29.180 +
  29.181 +    if (gmyth_program_info->catType != NULL) {
  29.182 +        g_string_free(gmyth_program_info->catType, TRUE);
  29.183 +        gmyth_program_info->catType = NULL;
  29.184 +    }
  29.185 +
  29.186 +    if (gmyth_program_info->sortTitle != NULL) {
  29.187 +        g_string_free(gmyth_program_info->sortTitle, TRUE);
  29.188 +        gmyth_program_info->sortTitle = NULL;
  29.189 +    }
  29.190 +
  29.191 +    if (gmyth_program_info->year != NULL) {
  29.192 +        g_string_free(gmyth_program_info->year, TRUE);
  29.193 +        gmyth_program_info->year = NULL;
  29.194 +    }
  29.195 +
  29.196 +    g_free(gmyth_program_info->originalAirDate);
  29.197 +
  29.198 +    g_free(gmyth_program_info->lastmodified);
  29.199 +
  29.200 +    g_free(gmyth_program_info->lastInUseTime);
  29.201 +
  29.202 +    if (gmyth_program_info->schedulerid != NULL) {
  29.203 +        g_string_free(gmyth_program_info->schedulerid, TRUE);
  29.204 +        gmyth_program_info->schedulerid = NULL;
  29.205 +    }
  29.206 +
  29.207 +    if (gmyth_program_info->recgroup != NULL) {
  29.208 +        g_string_free(gmyth_program_info->recgroup, TRUE);
  29.209 +        gmyth_program_info->recgroup = NULL;
  29.210 +    }
  29.211 +
  29.212 +    if (gmyth_program_info->playgroup != NULL) {
  29.213 +        g_string_free(gmyth_program_info->playgroup, TRUE);
  29.214 +        gmyth_program_info->playgroup = NULL;
  29.215 +    }
  29.216 +
  29.217 +    /** The file name of the recorded program.*/
  29.218 +    if (gmyth_program_info->pathname != NULL) {
  29.219 +        g_string_free(gmyth_program_info->pathname, TRUE);
  29.220 +        gmyth_program_info->pathname = NULL;
  29.221 +    }
  29.222 +
  29.223 +    if (gmyth_program_info->hostname != NULL) {
  29.224 +        g_string_free(gmyth_program_info->hostname, TRUE);
  29.225 +        gmyth_program_info->hostname = NULL;
  29.226 +    }
  29.227 +
  29.228 +    G_OBJECT_CLASS(gmyth_program_info_parent_class)->dispose(object);
  29.229 +}
  29.230 +
  29.231 +static void
  29.232 +gmyth_program_info_finalize(GObject * object)
  29.233 +{
  29.234 +    g_signal_handlers_destroy(object);
  29.235 +
  29.236 +    G_OBJECT_CLASS(gmyth_program_info_parent_class)->finalize(object);
  29.237 +}
  29.238 +
  29.239 +/**
  29.240 + * Creates a new instance of GMythProgramInfo.
  29.241 + * 
  29.242 + * @return a new instance of GMythProgramInfo.
  29.243 + */
  29.244 +GMythProgramInfo *
  29.245 +gmyth_program_info_new(void)
  29.246 +{
  29.247 +    GMythProgramInfo *program_info =
  29.248 +        GMYTH_PROGRAM_INFO(g_object_new(GMYTH_PROGRAM_INFO_TYPE, NULL));
  29.249 +
  29.250 +    return program_info;
  29.251 +}
  29.252 +
  29.253 +/**
  29.254 + * Converts an instance of a GMythProgramInfo, to a GMythStringList.
  29.255 + * 
  29.256 + * @param prog A GMythProgramInfo instance.
  29.257 + * @param slist The GMythStringList to be passed to this function, in order to
  29.258 + * 							give the responsibility of the string list creation to the
  29.259 + * 						  API user.
  29.260 + * 
  29.261 + * @return a GMythStringList with the program info fields.
  29.262 + */
  29.263 +GMythStringList *
  29.264 +gmyth_program_info_to_string_list(GMythProgramInfo * prog,
  29.265 +                                  GMythStringList * slist)
  29.266 +{
  29.267 +    g_return_val_if_fail(prog != NULL, NULL);
  29.268 +    g_return_val_if_fail(slist != NULL, NULL);
  29.269 +
  29.270 +    gmyth_string_list_append_string(slist, prog->title);    /* 0 */
  29.271 +    gmyth_string_list_append_string(slist, prog->subtitle); /* 1 */
  29.272 +    gmyth_string_list_append_string(slist, prog->description);  /* 2 */
  29.273 +    gmyth_string_list_append_string(slist, prog->category); /* 3 */
  29.274 +    gmyth_string_list_append_int (slist, prog->channel_id);   /* 4 */
  29.275 +    gmyth_string_list_append_string(slist, prog->chanstr);  /* 5 */
  29.276 +    gmyth_string_list_append_string(slist, prog->chansign); /* 6 */
  29.277 +    gmyth_string_list_append_string(slist, prog->channame); /* 7 */
  29.278 +    gmyth_string_list_append_string(slist, prog->pathname); /* 8 */
  29.279 +    gmyth_string_list_append_int64(slist, 0);   /* 9 */
  29.280 +
  29.281 +    // fixme
  29.282 +    // gmyth_string_list_append_int64 (slist, 100/*prog->filesize*/); /* 9 
  29.283 +    // 
  29.284 +    // 
  29.285 +    // */
  29.286 +    // gmyth_string_list_append_int (slist, 0); /* 10 */
  29.287 +
  29.288 +    if (prog->startts)
  29.289 +        gmyth_string_list_append_int(slist, prog->startts->tv_sec); /* 11 */// DATETIME_TO_LIST(startts)
  29.290 +    else
  29.291 +        gmyth_string_list_append_int(slist, 0);
  29.292 +
  29.293 +    if (prog->endts)
  29.294 +        gmyth_string_list_append_int(slist, prog->endts->tv_sec);   /* 12 */// DATETIME_TO_LIST(endts)
  29.295 +    else
  29.296 +        gmyth_string_list_append_int(slist, 0);
  29.297 +
  29.298 +    gmyth_string_list_append_int(slist, prog->duplicate);   /* 13 */
  29.299 +    gmyth_string_list_append_int(slist, prog->shareable);   /* 14 */
  29.300 +    gmyth_string_list_append_int(slist, prog->findid);  /* 15 */
  29.301 +    gmyth_string_list_append_string(slist, prog->hostname); /* 16 */
  29.302 +    gmyth_string_list_append_int(slist, prog->sourceid);    /* 17 */
  29.303 +    gmyth_string_list_append_int(slist, prog->cardid);  /* 18 */
  29.304 +    gmyth_string_list_append_int(slist, prog->inputid); /* 19 */
  29.305 +    gmyth_string_list_append_int(slist, prog->recpriority); /* 20 */
  29.306 +    gmyth_string_list_append_int(slist, 0 /* prog->recstatus */ );  /* 21 */
  29.307 +    gmyth_string_list_append_int(slist, prog->recordid);    /* 22 */
  29.308 +    gmyth_string_list_append_int(slist, 0 /* prog->rectype */ );    /* 23 */
  29.309 +    gmyth_string_list_append_int(slist, 0 /* prog->dupin */ );  /* 24 */
  29.310 +    gmyth_string_list_append_int(slist, 0 /* prog->dupmethod */ );  /* 25 */
  29.311 +    gmyth_string_list_append_int(slist, prog->recstartts != NULL ? prog->recstartts->tv_sec : 0);   /* 26 
  29.312 +     */// DATETIME_TO_LIST(recstartts)
  29.313 +    gmyth_string_list_append_int(slist, prog->recendts != NULL ? prog->recendts->tv_sec : 0);   /* 27 
  29.314 +     */// DATETIME_TO_LIST(recendts)
  29.315 +    gmyth_string_list_append_int(slist, prog->repeat);  /* 28 */
  29.316 +    gmyth_string_list_append_int(slist, prog->programflags);    /* 29 */
  29.317 +    gmyth_string_list_append_char_array(slist, "Default");  /* 30 */// prog->(recgroup 
  29.318 +                                                            // 
  29.319 +    // 
  29.320 +    // != "") ?
  29.321 +    // recgroup :
  29.322 +    // "Default")
  29.323 +    gmyth_string_list_append_int(slist, prog->chancommfree);    /* 31 */
  29.324 +    gmyth_string_list_append_string(slist, prog->chanOutputFilters);    /* 32 
  29.325 +                                                                         */
  29.326 +    gmyth_string_list_append_string(slist, prog->seriesid); /* 33 */
  29.327 +    gmyth_string_list_append_string(slist, prog->program_id);    /* 34 */
  29.328 +    gmyth_string_list_append_char_array(slist, ""); /* 35 */
  29.329 +    gmyth_string_list_append_int(slist, prog->lastmodified != NULL ? prog->lastmodified->tv_sec : 0);   /* 36 
  29.330 +     */// DATETIME_TO_LIST(lastmodified)
  29.331 +    gmyth_string_list_append_int(slist, 0); /* 37 */// FLOAT_TO_LIST(stars)
  29.332 +    gmyth_string_list_append_int(slist, prog->originalAirDate != NULL ? prog->originalAirDate->tv_sec : 0); /* 38 
  29.333 +     */// DATETIME_TO_LIST(QDateTime(originalAirDate))
  29.334 +    gmyth_string_list_append_int(slist, prog->hasAirDate);  /* 39 */
  29.335 +    gmyth_string_list_append_char_array(slist, "Default");  /* 40 */// prog->(playgroup 
  29.336 +                                                            // 
  29.337 +    // 
  29.338 +    // != "") ?
  29.339 +    // playgroup : 
  29.340 +    // "Default")
  29.341 +    gmyth_string_list_append_int(slist, prog->recpriority2);    /* 41 */
  29.342 +
  29.343 +    return slist;
  29.344 +}
  29.345 +
  29.346 +/**
  29.347 + * Converts an instance of a GMythStringList, to a GMythProgramInfo.
  29.348 + * 
  29.349 + * @param slist The GMythStringList got from the MythTV backend server.
  29.350 + * @param pos   The position in the GMythStringList to start getting the fields.
  29.351 + * 
  29.352 + * @return a GMythProgramInfo representing the string list got from network.
  29.353 + */
  29.354 +GMythProgramInfo *
  29.355 +gmyth_program_info_from_string_list_from_pos(GMythStringList * slist,
  29.356 +                                             guint pos)
  29.357 +{
  29.358 +    GMythProgramInfo *prog = gmyth_program_info_new();
  29.359 +
  29.360 +    g_return_val_if_fail(slist != NULL &&
  29.361 +                         gmyth_string_list_get_string(slist, pos) != NULL,
  29.362 +                         NULL);
  29.363 +
  29.364 +    prog->title = gmyth_string_list_get_string(slist, pos);
  29.365 +    prog->subtitle = gmyth_string_list_get_string(slist, pos + 1);
  29.366 +    prog->description = gmyth_string_list_get_string(slist, pos + 2);
  29.367 +    prog->category = gmyth_string_list_get_string(slist, pos + 3);
  29.368 +    prog->channel_id = gmyth_string_list_get_int (slist, pos + 4);
  29.369 +    prog->channame = gmyth_string_list_get_string(slist, pos + 5);
  29.370 +    prog->chanstr = gmyth_string_list_get_string(slist, pos + 6);
  29.371 +    prog->chansign = gmyth_string_list_get_string(slist, pos + 7);
  29.372 +    prog->pathname = gmyth_string_list_get_string(slist, pos + 8);
  29.373 +
  29.374 +    prog->filesize = gmyth_string_list_get_int64(slist, pos + 9);
  29.375 +
  29.376 +    gmyth_debug("Prog info: [ %s, %s, %s, %s, %s, %s, %s, %s, %d ]\n",
  29.377 +                gmyth_program_info_non_null_value(prog->title),
  29.378 +                gmyth_program_info_non_null_value(prog->subtitle),
  29.379 +                gmyth_program_info_non_null_value(prog->description),
  29.380 +                gmyth_program_info_non_null_value(prog->category),
  29.381 +                gmyth_program_info_non_null_value(prog->channame),
  29.382 +                gmyth_program_info_non_null_value(prog->chanstr),
  29.383 +                gmyth_program_info_non_null_value(prog->chansign),
  29.384 +                gmyth_program_info_non_null_value(prog->pathname),
  29.385 +                gmyth_string_list_get_int(slist, pos + 11));
  29.386 +
  29.387 +    prog->startts = gmyth_util_string_to_time_val((gmyth_util_time_to_isoformat((time_t) gmyth_string_list_get_int(slist, pos + 11)))->str);    // DATETIME_TO_LIST(startts)
  29.388 +    prog->endts = gmyth_util_string_to_time_val((gmyth_util_time_to_isoformat((time_t) gmyth_string_list_get_int(slist, pos + 12)))->str);  // DATETIME_TO_LIST(endts)
  29.389 +    prog->duplicate = gmyth_string_list_get_int(slist, pos + 13);
  29.390 +    prog->shareable = gmyth_string_list_get_int(slist, pos + 14);
  29.391 +    prog->findid = gmyth_string_list_get_int(slist, pos + 15);
  29.392 +    prog->hostname = gmyth_string_list_get_string(slist, pos + 16);
  29.393 +    prog->sourceid = gmyth_string_list_get_int(slist, pos + 17);
  29.394 +    prog->cardid = gmyth_string_list_get_int(slist, pos + 18);
  29.395 +    prog->inputid = gmyth_string_list_get_int(slist, pos + 19);
  29.396 +    prog->recpriority = gmyth_string_list_get_int(slist, pos + 20);
  29.397 +    prog->reactivate = gmyth_string_list_get_int(slist, pos + 21);
  29.398 +    prog->recordid = gmyth_string_list_get_int(slist, pos + 22);
  29.399 +    gmyth_string_list_get_int(slist, pos + 23);
  29.400 +    gmyth_string_list_get_int(slist, pos + 24);
  29.401 +    gmyth_string_list_get_int(slist, pos + 25);
  29.402 +    prog->recstartts = gmyth_util_string_to_time_val((gmyth_util_time_to_isoformat((time_t) gmyth_string_list_get_int(slist, pos + 26)))->str); // DATETIME_TO_LIST(recstartts)
  29.403 +    prog->recendts = gmyth_util_string_to_time_val((gmyth_util_time_to_isoformat((time_t) gmyth_string_list_get_int(slist, pos + 27)))->str);   // DATETIME_TO_LIST(recendts)
  29.404 +    prog->repeat = gmyth_string_list_get_int(slist, pos + 28);
  29.405 +    prog->programflags = gmyth_string_list_get_int(slist, pos + 29);
  29.406 +    prog->recgroup = gmyth_string_list_get_string(slist, pos + 30); // prog->(recgroup 
  29.407 +                                                                    // 
  29.408 +    // 
  29.409 +    // !=
  29.410 +    // "") 
  29.411 +    // ?
  29.412 +    // recgroup 
  29.413 +    // :
  29.414 +    // "Default")
  29.415 +    prog->chancommfree = gmyth_string_list_get_int(slist, pos + 31);
  29.416 +    prog->chanOutputFilters =
  29.417 +        gmyth_string_list_get_string(slist, pos + 32);
  29.418 +    prog->seriesid = gmyth_string_list_get_string(slist, pos + 33);
  29.419 +    prog->program_id = gmyth_string_list_get_string(slist, pos + 34);
  29.420 +    gmyth_string_list_get_string(slist, pos + 35);
  29.421 +    prog->lastmodified = gmyth_util_string_to_time_val((gmyth_util_time_to_isoformat((time_t) gmyth_string_list_get_int(slist, pos + 36)))->str);   // DATETIME_TO_LIST(lastmodified)
  29.422 +    gmyth_string_list_get_int(slist, pos + 37); // FLOAT_TO_LIST(stars)
  29.423 +    prog->originalAirDate = gmyth_util_string_to_time_val((gmyth_util_time_to_isoformat((time_t) gmyth_string_list_get_int(slist, pos + 38)))->str);    // DATETIME_TO_LIST(QDateTime(originalAirDate))
  29.424 +    prog->hasAirDate = gmyth_string_list_get_int(slist, pos + 39);
  29.425 +    prog->playgroup = gmyth_string_list_get_string(slist, pos + 40);    // prog->(playgroup 
  29.426 +                                                                        // 
  29.427 +    // 
  29.428 +    // != 
  29.429 +    // "") 
  29.430 +    // ? 
  29.431 +    // playgroup 
  29.432 +    // : 
  29.433 +    // "Default")
  29.434 +    prog->recpriority2 = gmyth_string_list_get_int(slist, pos + 41);
  29.435 +
  29.436 +    return prog;
  29.437 +}
  29.438 +
  29.439 +/**
  29.440 + * Converts an instance of a GMythStringList, to a GMythProgramInfo.
  29.441 + * 
  29.442 + * @param slist The GMythStringList got from the MythTV backend server.
  29.443 + * 
  29.444 + * @return a GMythProgramInfo representing the string list got from network.
  29.445 + */
  29.446 +GMythProgramInfo *
  29.447 +gmyth_program_info_from_string_list(GMythStringList * slist)
  29.448 +{
  29.449 +    GMythProgramInfo *prog = NULL;
  29.450 +
  29.451 +    g_return_val_if_fail(slist != NULL, NULL);
  29.452 +
  29.453 +    prog = gmyth_program_info_from_string_list_from_pos(slist, 0);
  29.454 +
  29.455 +    return prog;
  29.456 +}
  29.457 +
  29.458 +/**
  29.459 + * Converts an instance of a GMythStringList, to a GMythProgramInfo ( NEXT_PROGRAM_INFO ).
  29.460 + * 
  29.461 + * @param slist The GMythStringList got from the MythTV backend server.
  29.462 + * 
  29.463 + * @return a GMythProgramInfo representing the string list got from network.
  29.464 + */
  29.465 +GMythProgramInfo *
  29.466 +gmyth_program_info_from_string_list_next_prog(GMythStringList * slist)
  29.467 +{
  29.468 +    GMythProgramInfo *prog = gmyth_program_info_new();
  29.469 +
  29.470 +    g_return_val_if_fail(slist != NULL, NULL);
  29.471 +
  29.472 +    /*
  29.473 +     * {Home Improvement[]:[]No, No, Godot[]:[] US sitcom about a
  29.474 +     * DIY-obsessed father of three. When Tim tries to sell off his extra 
  29.475 +     * ticket for an ice hockey game, he is arrested as a tout.[]:[]
  29.476 +     * Sitcom[]:[]2007-04-18T15:30:00[]:[]2007-04-18T16:00:00[]:[]ABC1[]:[]
  29.477 +     * /home/hmelo/.mythtv/channels/abc1.jpg[]:[]abc1[]:[]2000[]:[]25725844[]:[] 
  29.478 +     * } 
  29.479 +     */
  29.480 +
  29.481 +    prog->title = gmyth_string_list_get_string(slist, 0);
  29.482 +    prog->subtitle = gmyth_string_list_get_string(slist, 1);
  29.483 +    prog->description = gmyth_string_list_get_string(slist, 2);
  29.484 +    prog->category = gmyth_string_list_get_string(slist, 3);
  29.485 +    prog->startts = gmyth_util_string_to_time_val(gmyth_string_list_get_char_array(slist, 4));  // DATETIME_TO_LIST(startts)
  29.486 +    prog->endts = gmyth_util_string_to_time_val(gmyth_string_list_get_char_array(slist, 5));    // DATETIME_TO_LIST(endts)
  29.487 +    prog->channame = gmyth_string_list_get_string(slist, 6);
  29.488 +    prog->chansign = gmyth_string_list_get_string(slist, 7);
  29.489 +    prog->chanstr = gmyth_string_list_get_string(slist, 8);
  29.490 +    prog->channel_id = gmyth_string_list_get_int (slist, 9);
  29.491 +    prog->filesize = gmyth_string_list_get_int64(slist, 10);
  29.492 +
  29.493 +    gmyth_debug
  29.494 +        ("NEXT program info: [ %s, %s, %s, %s, %s, %s, %s, %s ]\n",
  29.495 +         gmyth_program_info_non_null_value(prog->title),
  29.496 +         gmyth_program_info_non_null_value(prog->subtitle),
  29.497 +         gmyth_program_info_non_null_value(prog->description),
  29.498 +         gmyth_program_info_non_null_value(prog->category),
  29.499 +         gmyth_program_info_non_null_value(prog->channame),
  29.500 +         gmyth_program_info_non_null_value(prog->chanstr),
  29.501 +         gmyth_program_info_non_null_value(prog->chansign),
  29.502 +         gmyth_program_info_non_null_value(prog->pathname));
  29.503 +
  29.504 +    return prog;
  29.505 +}
  29.506 +
  29.507 +static const gchar *
  29.508 +gmyth_program_info_non_null_value(const GString * str)
  29.509 +{
  29.510 +    return (str != NULL && str->str != NULL
  29.511 +            && strlen(str->str) > 0 ? str->str : " ");
  29.512 +}
  29.513 +
  29.514 +/**
  29.515 + * Prints out an instance of a GMythProgramInfo.
  29.516 + * 
  29.517 + * @param prog A GMythProgramInfo instance.
  29.518 + * 
  29.519 + * @return a string representing the program info.
  29.520 + */
  29.521 +const gchar    *
  29.522 +gmyth_program_info_to_string(const GMythProgramInfo * prog)
  29.523 +{
  29.524 +    return
  29.525 +        g_strdup_printf
  29.526 +        ("Title: %s, Subtitle: %s, Description: %s, Category: %s, Channel ID: %d, "
  29.527 +         "Channel Name: %s, Chan str: %s, Channel Sign: %s, Path Name: %s, File Size: %lld, \n"
  29.528 +         "Start TS: %s, End TS: %s, Duplicate: %d, Shareable: %d, Find ID: %d, Hostname: %s, "
  29.529 +         "Source ID: %d, Vard ID: %d, Input ID: %d, Rec Priority: %d, Reactivate: %d, \n"
  29.530 +         "Record ID: %d, Rec Start TS: %s, Rec End TS: %s, Repeat: %d, Program Flags: %d, "
  29.531 +         "Rec Group: %s, Channel Comm Free: %d, Channel Output Filters: %s, Series ID: %s, \n"
  29.532 +         "Program ID: %s, Last Modified Date: %s, Original Air Date: %s, Has Air Date: %d, "
  29.533 +         "Play Group: %s.\n",
  29.534 +         gmyth_program_info_non_null_value(prog->title),
  29.535 +         gmyth_program_info_non_null_value(prog->subtitle),
  29.536 +         gmyth_program_info_non_null_value(prog->description),
  29.537 +         gmyth_program_info_non_null_value(prog->category),
  29.538 +         prog->channel_id,
  29.539 +         gmyth_program_info_non_null_value(prog->channame),
  29.540 +         gmyth_program_info_non_null_value(prog->chanstr),
  29.541 +         gmyth_program_info_non_null_value(prog->chansign),
  29.542 +         gmyth_program_info_non_null_value(prog->pathname), prog->filesize,
  29.543 +         gmyth_util_time_to_string_from_time_val(prog->startts),
  29.544 +         gmyth_util_time_to_string_from_time_val(prog->endts),
  29.545 +         prog->duplicate, prog->shareable, prog->findid,
  29.546 +         gmyth_program_info_non_null_value(prog->hostname), prog->sourceid,
  29.547 +         prog->cardid, prog->inputid, prog->recpriority, prog->reactivate,
  29.548 +         prog->recordid,
  29.549 +         gmyth_util_time_to_string_from_time_val(prog->recstartts),
  29.550 +         gmyth_util_time_to_string_from_time_val(prog->recendts),
  29.551 +         prog->repeat, prog->programflags,
  29.552 +         gmyth_program_info_non_null_value(prog->recgroup),
  29.553 +         prog->chancommfree,
  29.554 +         gmyth_program_info_non_null_value(prog->chanOutputFilters),
  29.555 +         gmyth_program_info_non_null_value(prog->seriesid),
  29.556 +         gmyth_program_info_non_null_value(prog->program_id),
  29.557 +         gmyth_util_time_to_string_from_time_val(prog->lastmodified),
  29.558 +         gmyth_util_time_to_string_from_time_val(prog->originalAirDate),
  29.559 +         prog->hasAirDate,
  29.560 +         gmyth_program_info_non_null_value(prog->playgroup));
  29.561 +}
  29.562 +
  29.563 +/**
  29.564 + * Say if an instance of a GMythProgramInfo is equals to another one.
  29.565 + * 
  29.566 + * @param prog The first GMythProgramInfo instance.
  29.567 + * @param prog The second GMythProgramInfo instance.
  29.568 + * 
  29.569 + * @return <code>true</code>, if the program infos are equals.
  29.570 + */
  29.571 +gboolean
  29.572 +gmyth_program_info_is_equals(const GMythProgramInfo * prog1,
  29.573 +                             const GMythProgramInfo * prog2)
  29.574 +{
  29.575 +    if ((strcmp(gmyth_program_info_non_null_value(prog1->title),
  29.576 +                gmyth_program_info_non_null_value(prog2->title)) == 0)
  29.577 +        ||
  29.578 +        (strcmp
  29.579 +         (gmyth_program_info_non_null_value(prog1->pathname),
  29.580 +          gmyth_program_info_non_null_value(prog2->pathname)) == 0))
  29.581 +        return TRUE;
  29.582 +    else
  29.583 +        return FALSE;
  29.584 +
  29.585 +}
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/gmyth/gmyth/gmyth_programinfo.h	Mon Feb 25 17:51:43 2008 +0000
    30.3 @@ -0,0 +1,180 @@
    30.4 +/**
    30.5 + * GMyth Library
    30.6 + *
    30.7 + * @file gmyth/gmyth_programinfo.h
    30.8 + * 
    30.9 + * @brief <p> GMythProgramInfo representing the program info, with the
   30.10 + * configuration data to the actual remote file in the TV chain.
   30.11 + *
   30.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   30.13 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
   30.14 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   30.15 + *
   30.16 + * 
   30.17 + * This program is free software; you can redistribute it and/or modify
   30.18 + * it under the terms of the GNU Lesser General Public License as published by
   30.19 + * the Free Software Foundation; either version 2 of the License, or
   30.20 + * (at your option) any later version.
   30.21 + *
   30.22 + * This program is distributed in the hope that it will be useful,
   30.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   30.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   30.25 + * GNU General Public License for more details.
   30.26 + *
   30.27 + * You should have received a copy of the GNU Lesser General Public License
   30.28 + * along with this program; if not, write to the Free Software
   30.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   30.30 + *
   30.31 + */
   30.32 +
   30.33 +#ifndef _GMYTH_PROGRAMINFO_H
   30.34 +#define _GMYTH_PROGRAMINFO_H
   30.35 +
   30.36 +#include <glib.h>
   30.37 +#include <glib-object.h>
   30.38 +
   30.39 +#include "gmyth_stringlist.h"
   30.40 +
   30.41 +G_BEGIN_DECLS
   30.42 +#define GMYTH_PROGRAM_INFO_TYPE               (gmyth_program_info_get_type ())
   30.43 +#define GMYTH_PROGRAM_INFO(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_PROGRAM_INFO_TYPE, GMythProgramInfo))
   30.44 +#define GMYTH_PROGRAM_INFO_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_PROGRAM_INFO_TYPE, GMythProgramInfoClass))
   30.45 +#define IS_GMYTH_PROGRAM_INFO(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_PROGRAM_INFO_TYPE))
   30.46 +#define IS_GMYTH_PROGRAM_INFO_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_PROGRAM_INFO_TYPE))
   30.47 +#define GMYTH_PROGRAM_INFO_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_PROGRAM_INFO_TYPE, GMythProgramInfoClass))
   30.48 +typedef struct _GMythProgramInfo GMythProgramInfo;
   30.49 +typedef struct _GMythProgramInfoClass GMythProgramInfoClass;
   30.50 +
   30.51 +struct _GMythProgramInfoClass {
   30.52 +    GObjectClass    parent_class;
   30.53 +
   30.54 +    /*
   30.55 +     * callbacks 
   30.56 +     */
   30.57 +};
   30.58 +
   30.59 +/**
   30.60 + * The GMythProgramInfo structure represents a program information
   30.61 + * stored in the database. It could be a program from the EPG data,
   30.62 + * a program scheduled to be recorded, or a program already recorded.
   30.63 + */
   30.64 +struct _GMythProgramInfo {
   30.65 +    GObject         parent;
   30.66 +
   30.67 +    /** The channel unique ID. */
   30.68 +    gint            channel_id;
   30.69 +    /** The program start time. */
   30.70 +    GTimeVal       *startts;
   30.71 +    /** The program end time. */
   30.72 +    GTimeVal       *endts;
   30.73 +    /** The recording schedule start time. */
   30.74 +    GTimeVal       *recstartts;
   30.75 +    /** The recording schedule end time */
   30.76 +    GTimeVal       *recendts;
   30.77 +
   30.78 +    /** The program title. */
   30.79 +    GString        *title;
   30.80 +    /** The program subtitle. */
   30.81 +    GString        *subtitle;
   30.82 +    /** The program description. */
   30.83 +    GString        *description;
   30.84 +    /** The program category. */
   30.85 +    GString        *category;
   30.86 +
   30.87 +    GString        *chanstr;
   30.88 +    GString        *chansign;
   30.89 +    /** The associated channel name. */
   30.90 +    GString        *channame;
   30.91 +    gint            chancommfree;
   30.92 +    GString        *chanOutputFilters;
   30.93 +
   30.94 +    GString        *seriesid;
   30.95 +    /** The program unique id. */
   30.96 +    GString        *program_id;
   30.97 +    GString        *catType;
   30.98 +
   30.99 +    GString        *sortTitle;
  30.100 +
  30.101 +    /** A flag informing if the program has video or not. */
  30.102 +    gboolean        isVideo;
  30.103 +    gint            lenMins;
  30.104 +
  30.105 +    GString        *year;
  30.106 +    gdouble         stars;
  30.107 +    gint            repeat;
  30.108 +
  30.109 +    GTimeVal       *originalAirDate;
  30.110 +    GTimeVal       *lastmodified;
  30.111 +    GTimeVal       *lastInUseTime;
  30.112 +
  30.113 +    gboolean        hasAirDate;
  30.114 +
  30.115 +    gint            spread;
  30.116 +    gint            startCol;
  30.117 +
  30.118 +    gint            recpriority2;
  30.119 +    gint            reactivate;
  30.120 +
  30.121 +    gint            recordid;
  30.122 +    gint            parentid;
  30.123 +
  30.124 +    /** The backend video source id associated to this program.*/
  30.125 +    gint            sourceid;
  30.126 +    /** the backend input id associated to this program.*/
  30.127 +    gint            inputid;
  30.128 +    /** The backend card id associated to this program.*/
  30.129 +    gint            cardid;
  30.130 +    gboolean        shareable;
  30.131 +    gboolean        duplicate;
  30.132 +
  30.133 +    GString        *schedulerid;
  30.134 +    gint            findid;
  30.135 +
  30.136 +    gint            programflags;
  30.137 +    gint            transcoder;
  30.138 +
  30.139 +    GString        *recgroup;
  30.140 +    GString        *playgroup;
  30.141 +    gint            rectype;
  30.142 +    gint            recstatus;
  30.143 +    gint            recpriority;
  30.144 +    gint            dupin;
  30.145 +    gint            dupmethod;
  30.146 +
  30.147 +    /** The file size of the recorded program.*/
  30.148 +    gint64          filesize;
  30.149 +
  30.150 +    /** The file name of the recorded program.*/
  30.151 +    GString        *pathname;
  30.152 +    GString        *hostname;
  30.153 +};
  30.154 +
  30.155 +GType           gmyth_program_info_get_type(void);
  30.156 +
  30.157 +GMythProgramInfo *gmyth_program_info_new(void);
  30.158 +
  30.159 +GMythStringList *gmyth_program_info_to_string_list(GMythProgramInfo * prog,
  30.160 +                                                   GMythStringList *
  30.161 +                                                   slist);
  30.162 +
  30.163 +GMythProgramInfo
  30.164 +    * gmyth_program_info_from_string_list_from_pos(GMythStringList * slist,
  30.165 +                                                   guint pos);
  30.166 +
  30.167 +GMythProgramInfo *gmyth_program_info_from_string_list(GMythStringList *
  30.168 +                                                      slist);
  30.169 +
  30.170 +GMythProgramInfo
  30.171 +    * gmyth_program_info_from_string_list_next_prog(GMythStringList *
  30.172 +                                                    slist);
  30.173 +
  30.174 +const gchar    *gmyth_program_info_to_string(const GMythProgramInfo *
  30.175 +                                             prog);
  30.176 +
  30.177 +gboolean        gmyth_program_info_is_equals(const GMythProgramInfo *
  30.178 +                                             prog1,
  30.179 +                                             const GMythProgramInfo *
  30.180 +                                             prog2);
  30.181 +
  30.182 +G_END_DECLS
  30.183 +#endif /*_GMYTH_PROGRAMINFO_H*/
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/gmyth/gmyth/gmyth_query.c	Mon Feb 25 17:51:43 2008 +0000
    31.3 @@ -0,0 +1,280 @@
    31.4 +/**
    31.5 + * GMyth Library
    31.6 + *
    31.7 + * @file gmyth/gmyth_query.c
    31.8 + * 
    31.9 + * @brief <p> GMythQuery class provides a wrapper for accessing
   31.10 + * the libmysqlclient funtions.
   31.11 + *
   31.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   31.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   31.14 + *
   31.15 + * 
   31.16 + * This program is free software; you can redistribute it and/or modify
   31.17 + * it under the terms of the GNU Lesser General Public License as published by
   31.18 + * the Free Software Foundation; either version 2 of the License, or
   31.19 + * (at your option) any later version.
   31.20 + *
   31.21 + * This program is distributed in the hope that it will be useful,
   31.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   31.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   31.24 + * GNU General Public License for more details.
   31.25 + *
   31.26 + * You should have received a copy of the GNU Lesser General Public License
   31.27 + * along with this program; if not, write to the Free Software
   31.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   31.29 + */
   31.30 +
   31.31 +#ifdef HAVE_CONFIG_H
   31.32 +#include "config.h"
   31.33 +#endif
   31.34 +
   31.35 +#include <stdlib.h>
   31.36 +#include <stdio.h>
   31.37 +#include <assert.h>
   31.38 +
   31.39 +#include "gmyth_query.h"
   31.40 +#include "gmyth_debug.h"
   31.41 +
   31.42 +static void     gmyth_query_class_init(GMythQueryClass * klass);
   31.43 +static void     gmyth_query_init(GMythQuery * object);
   31.44 +
   31.45 +static void     gmyth_query_dispose(GObject * object);
   31.46 +static void     gmyth_query_finalize(GObject * object);
   31.47 +
   31.48 +static void     gmyth_query_print_error(MYSQL * conn, char *message);
   31.49 +
   31.50 +G_DEFINE_TYPE(GMythQuery, gmyth_query, G_TYPE_OBJECT)
   31.51 +    static void     gmyth_query_class_init(GMythQueryClass * klass)
   31.52 +{
   31.53 +    GObjectClass   *gobject_class;
   31.54 +
   31.55 +    gobject_class = (GObjectClass *) klass;
   31.56 +
   31.57 +    gobject_class->dispose = gmyth_query_dispose;
   31.58 +    gobject_class->finalize = gmyth_query_finalize;
   31.59 +}
   31.60 +
   31.61 +static void
   31.62 +gmyth_query_init(GMythQuery * gmyth_query)
   31.63 +{
   31.64 +    gmyth_query->backend_info = NULL;
   31.65 +
   31.66 +    /*
   31.67 +     * initialize connection handler 
   31.68 +     */
   31.69 +    gmyth_query->conn = mysql_init(NULL);
   31.70 +
   31.71 +    if (!(gmyth_query->conn))
   31.72 +        g_warning("[%s] MSQL structure not initialized", __FUNCTION__);
   31.73 +}
   31.74 +
   31.75 +static void
   31.76 +gmyth_query_dispose(GObject * object)
   31.77 +{
   31.78 +    GMythQuery     *gmyth_query = GMYTH_QUERY(object);
   31.79 +
   31.80 +    if (gmyth_query->conn != NULL) {
   31.81 +        gmyth_query_disconnect(gmyth_query);
   31.82 +    }
   31.83 +
   31.84 +    if (gmyth_query->backend_info) {
   31.85 +        g_object_unref(gmyth_query->backend_info);
   31.86 +        gmyth_query->backend_info = NULL;
   31.87 +    }
   31.88 +
   31.89 +    G_OBJECT_CLASS(gmyth_query_parent_class)->dispose(object);
   31.90 +}
   31.91 +
   31.92 +static void
   31.93 +gmyth_query_finalize(GObject * object)
   31.94 +{
   31.95 +    g_signal_handlers_destroy(object);
   31.96 +
   31.97 +    G_OBJECT_CLASS(gmyth_query_parent_class)->finalize(object);
   31.98 +}
   31.99 +
  31.100 +/** Creates a new instance of GMythQuery.
  31.101 + *
  31.102 + * @return a new instance of GMythQuery.
  31.103 + */
  31.104 +GMythQuery     *
  31.105 +gmyth_query_new()
  31.106 +{
  31.107 +    GMythQuery     *sql_query =
  31.108 +        GMYTH_QUERY(g_object_new(GMYTH_QUERY_TYPE, NULL));
  31.109 +
  31.110 +    return sql_query;
  31.111 +}
  31.112 +
  31.113 +gboolean
  31.114 +gmyth_query_connect_with_timeout(GMythQuery * gmyth_query,
  31.115 +                                 GMythBackendInfo * backend_info,
  31.116 +                                 guint timeout)
  31.117 +{
  31.118 +    assert(gmyth_query);
  31.119 +
  31.120 +    if (gmyth_query->conn == NULL)
  31.121 +        gmyth_query->conn = mysql_init(NULL);
  31.122 +
  31.123 +    if (timeout != 0) {
  31.124 +      /*
  31.125 +       * sets connection timeout
  31.126 +       */
  31.127 +        mysql_options(gmyth_query->conn, MYSQL_OPT_CONNECT_TIMEOUT,
  31.128 +                      (gchar *) & timeout);
  31.129 +    }
  31.130 +
  31.131 +    return gmyth_query_connect(gmyth_query, backend_info);
  31.132 +}
  31.133 +
  31.134 +/** Connects to the Mysql database in the backend. The backend address
  31.135 + * is loaded from the GMythBackendInfo instance.
  31.136 + *
  31.137 + * @param gmyth_query the GMythEPG instance to be connected.
  31.138 + * @return true if connection was success, false if failed.
  31.139 + */
  31.140 +gboolean
  31.141 +gmyth_query_connect(GMythQuery * gmyth_query,
  31.142 +                    GMythBackendInfo * backend_info)
  31.143 +{
  31.144 +    assert(gmyth_query);
  31.145 +    g_return_val_if_fail(backend_info != NULL, FALSE);
  31.146 +    g_return_val_if_fail(backend_info->hostname != NULL, FALSE);
  31.147 +    g_return_val_if_fail(backend_info->username != NULL, FALSE);
  31.148 +    g_return_val_if_fail(backend_info->password != NULL, FALSE);
  31.149 +    g_return_val_if_fail(backend_info->db_name != NULL, FALSE);
  31.150 +
  31.151 +    if (gmyth_query->backend_info != NULL) {
  31.152 +        g_object_unref(gmyth_query->backend_info);
  31.153 +    }
  31.154 +    gmyth_query->backend_info = g_object_ref(backend_info);
  31.155 +
  31.156 +    if (gmyth_query->conn == NULL) {
  31.157 +        gmyth_query->conn = mysql_init(NULL);
  31.158 +    }
  31.159 +
  31.160 +    /*
  31.161 +     * connect to server
  31.162 +     */
  31.163 +    if (mysql_real_connect(gmyth_query->conn,
  31.164 +                           gmyth_query->backend_info->hostname,
  31.165 +                           gmyth_query->backend_info->username,
  31.166 +                           gmyth_query->backend_info->password,
  31.167 +                           gmyth_query->backend_info->db_name, 
  31.168 +                           gmyth_query->backend_info->db_port, 
  31.169 +                           NULL,
  31.170 +                           0) == NULL) {
  31.171 +        gmyth_query_print_error(gmyth_query->conn,
  31.172 +                                "mysql_real_connect() failed");
  31.173 +        return FALSE;
  31.174 +    }
  31.175 +
  31.176 +    gmyth_debug
  31.177 +        ("[%s] Connection to Mysql server succeeded! (host = %s, user = %s, "
  31.178 +         "password = %s, db name = %s)", __FUNCTION__,
  31.179 +         gmyth_query->backend_info->hostname,
  31.180 +         gmyth_query->backend_info->username,
  31.181 +         gmyth_query->backend_info->password,
  31.182 +         gmyth_query->backend_info->db_name);
  31.183 +
  31.184 +    return TRUE;
  31.185 +}
  31.186 +
  31.187 +/** Disconnects from the Mysql database in the backend.
  31.188 + * 
  31.189 + * @param gmyth_query the GMythQuery instance to be disconnected
  31.190 + * @return true if disconnection was success, false if failed.
  31.191 + */
  31.192 +gboolean
  31.193 +gmyth_query_disconnect(GMythQuery * gmyth_query)
  31.194 +{
  31.195 +    g_return_val_if_fail(gmyth_query != NULL, FALSE);
  31.196 +    g_return_val_if_fail(gmyth_query->conn != NULL, FALSE);
  31.197 +
  31.198 +    /*
  31.199 +     * TODO: Check how to return error 
  31.200 +     */
  31.201 +    gmyth_debug("[%s] Closing gmyth_query->conn", __FUNCTION__);
  31.202 +
  31.203 +    mysql_close(gmyth_query->conn);
  31.204 +    gmyth_query->conn = NULL;
  31.205 +
  31.206 +    return TRUE;
  31.207 +}
  31.208 +
  31.209 +static void
  31.210 +gmyth_query_print_error(MYSQL * conn, char *message)
  31.211 +{
  31.212 +    gmyth_debug("%s", message);
  31.213 +
  31.214 +    if (conn != NULL) {
  31.215 +#if MYSQL_VERSION_ID >= 40101
  31.216 +        gmyth_debug("Error %u (%s): %s\n",
  31.217 +                    mysql_errno(conn), mysql_sqlstate(conn),
  31.218 +                    mysql_error(conn));
  31.219 +#else
  31.220 +        gmyth_debug("Error %u: %s\n", mysql_errno(conn),
  31.221 +                    mysql_error(conn));
  31.222 +#endif
  31.223 +    }
  31.224 +}
  31.225 +
  31.226 +/** Sends the given query to the backend returning the query result as
  31.227 + * MYSQL_RES pointer.
  31.228 + * 
  31.229 + * FIXME: this function is returning NULL whether any error happens
  31.230 + * or no rows are returned (e.g. UPDATE or REPLACE).
  31.231 + * 
  31.232 + * @param gmyth_query the GMythQuery instance.
  31.233 + * @param stmt_str the query text.
  31.234 + * @return the MYSQL_RES result pointer or NULL if any error happens.
  31.235 + */
  31.236 +MYSQL_RES*
  31.237 +gmyth_query_process_statement(GMythQuery * gmyth_query, char *stmt_str)
  31.238 +{
  31.239 +    assert(gmyth_query);
  31.240 +
  31.241 +    gmyth_debug("[%s] Running mysql query %s", __FUNCTION__, stmt_str);
  31.242 +
  31.243 +    if (gmyth_query == NULL)
  31.244 +        return NULL;
  31.245 +
  31.246 +    //the statement failed
  31.247 +    if (mysql_query(gmyth_query->conn, stmt_str) != 0) {
  31.248 +        gmyth_query_print_error(gmyth_query->conn,
  31.249 +                                "Could not execute statement");
  31.250 +        return NULL;
  31.251 +    }
  31.252 +
  31.253 +    //the statement succeeded; determine whether it returned data
  31.254 +    return mysql_store_result(gmyth_query->conn);
  31.255 +}
  31.256 +
  31.257 +MYSQL_RES*
  31.258 +gmyth_query_process_statement_with_increment(GMythQuery * gmyth_query,
  31.259 +                                             char *stmt_str, gulong * id)
  31.260 +{
  31.261 +    assert(gmyth_query);
  31.262 +
  31.263 +    gmyth_debug("[%s] Running mysql query %s", __FUNCTION__, stmt_str);
  31.264 +
  31.265 +    if (gmyth_query == NULL)
  31.266 +        return NULL;
  31.267 +
  31.268 +    /*
  31.269 +     * the statement failed
  31.270 +     */
  31.271 +    if (mysql_query(gmyth_query->conn, stmt_str) != 0) {
  31.272 +        gmyth_query_print_error(gmyth_query->conn,
  31.273 +                                "Could not execute statement");
  31.274 +        return NULL;
  31.275 +    }
  31.276 +
  31.277 +    *id = (my_ulonglong) mysql_insert_id(gmyth_query->conn);
  31.278 +
  31.279 +    /*
  31.280 +     * the statement succeeded; determine whether it returned data 
  31.281 +     */
  31.282 +    return mysql_store_result(gmyth_query->conn);
  31.283 +}
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/gmyth/gmyth/gmyth_query.h	Mon Feb 25 17:51:43 2008 +0000
    32.3 @@ -0,0 +1,93 @@
    32.4 +/**
    32.5 + * GMyth Library
    32.6 + *
    32.7 + * @file gmyth/gmyth_query.h
    32.8 + * 
    32.9 + * @brief <p> GMythQuery class provides a wrapper for accessing
   32.10 + * the libmysqlclient funtions.
   32.11 + *
   32.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   32.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   32.14 + *
   32.15 + * 
   32.16 + * This program is free software; you can redistribute it and/or modify
   32.17 + * it under the terms of the GNU Lesser General Public License as published by
   32.18 + * the Free Software Foundation; either version 2 of the License, or
   32.19 + * (at your option) any later version.
   32.20 + *
   32.21 + * This program is distributed in the hope that it will be useful,
   32.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   32.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   32.24 + * GNU General Public License for more details.
   32.25 + *
   32.26 + * You should have received a copy of the GNU Lesser General Public License
   32.27 + * along with this program; if not, write to the Free Software
   32.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   32.29 + */
   32.30 +
   32.31 +#ifndef __GMYTH_QUERY_H__
   32.32 +#define __GMYTH_QUERY_H__
   32.33 +
   32.34 +#include <glib-object.h>
   32.35 +
   32.36 +/*
   32.37 + * MYSQL includes 
   32.38 + */
   32.39 +#include <mysql/mysql.h>
   32.40 +
   32.41 +#include "gmyth_backendinfo.h"
   32.42 +
   32.43 +G_BEGIN_DECLS
   32.44 +#define GMYTH_QUERY_TYPE               (gmyth_query_get_type ())
   32.45 +#define GMYTH_QUERY(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE, GMythQuery))
   32.46 +#define GMYTH_QUERY_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE, GMythQueryClass))
   32.47 +#define IS_GMYTH_QUERY(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_QUERY_TYPE))
   32.48 +#define IS_GMYTH_QUERY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE))
   32.49 +#define GMYTH_QUERY_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_QUERY_TYPE, GMythQueryClass))
   32.50 +typedef struct _GMythQuery GMythQuery;
   32.51 +typedef struct _GMythQueryClass GMythQueryClass;
   32.52 +
   32.53 +struct _GMythQueryClass {
   32.54 +    GObjectClass    parent_class;
   32.55 +
   32.56 +    /*
   32.57 +     * callbacks 
   32.58 +     */
   32.59 +    /*
   32.60 +     * no one for now 
   32.61 +     */
   32.62 +};
   32.63 +
   32.64 +struct _GMythQuery {
   32.65 +    GObject         parent;
   32.66 +
   32.67 +    GMythBackendInfo *backend_info;
   32.68 +
   32.69 +    /*
   32.70 +     * pointer to connection handler 
   32.71 +     */
   32.72 +    MYSQL          *conn;
   32.73 +};
   32.74 +
   32.75 +
   32.76 +GType           gmyth_query_get_type(void);
   32.77 +
   32.78 +GMythQuery     *gmyth_query_new(void);
   32.79 +MYSQL_RES      *gmyth_query_process_statement(GMythQuery * gmyth_query,
   32.80 +                                              gchar * stmt_str);
   32.81 +MYSQL_RES      *gmyth_query_process_statement_with_increment(GMythQuery *
   32.82 +                                                             gmyth_query,
   32.83 +                                                             char
   32.84 +                                                             *stmt_str,
   32.85 +                                                             gulong * id);
   32.86 +
   32.87 +gboolean        gmyth_query_connect(GMythQuery * gmyth_query,
   32.88 +                                    GMythBackendInfo * backend_info);
   32.89 +gboolean        gmyth_query_connect_with_timeout(GMythQuery * gmyth_query,
   32.90 +                                                 GMythBackendInfo *
   32.91 +                                                 backend_info,
   32.92 +                                                 guint timeout);
   32.93 +gboolean        gmyth_query_disconnect(GMythQuery * gmyth_query);
   32.94 +
   32.95 +G_END_DECLS
   32.96 +#endif                          /* __GMYTH_QUERY_H__ */
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/gmyth/gmyth/gmyth_recorder.c	Mon Feb 25 17:51:43 2008 +0000
    33.3 @@ -0,0 +1,1388 @@
    33.4 +/**
    33.5 + * GMyth Library
    33.6 + *
    33.7 + * @file gmyth/gmyth_recorder.c
    33.8 + * 
    33.9 + * @brief <p> GMythRecorder defines functions for playing live tv.
   33.10 + *
   33.11 + * The remote encoder is used by gmyth_tvplayer to setup livetv. 
   33.12 + *
   33.13 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   33.14 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   33.15 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
   33.16 + *
   33.17 + * 
   33.18 + * This program is free software; you can redistribute it and/or modify
   33.19 + * it under the terms of the GNU Lesser General Public License as published by
   33.20 + * the Free Software Foundation; either version 2 of the License, or
   33.21 + * (at your option) any later version.
   33.22 + *
   33.23 + * This program is distributed in the hope that it will be useful,
   33.24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   33.25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   33.26 + * GNU General Public License for more details.
   33.27 + *
   33.28 + * You should have received a copy of the GNU Lesser General Public License
   33.29 + * along with this program; if not, write to the Free Software
   33.30 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   33.31 + */
   33.32 +
   33.33 +#ifdef HAVE_CONFIG_H
   33.34 +#include "config.h"
   33.35 +#endif
   33.36 +
   33.37 +#include "gmyth_recorder.h"
   33.38 +
   33.39 +#include <assert.h>
   33.40 +
   33.41 +#include "gmyth_stringlist.h"
   33.42 +#include "gmyth_util.h"
   33.43 +#include "gmyth_common.h"
   33.44 +#include "gmyth_debug.h"
   33.45 +
   33.46 +#define	 GMYTHTV_RECORDER_HEADER			"QUERY_RECORDER"
   33.47 +
   33.48 +static void     gmyth_recorder_class_init(GMythRecorderClass * klass);
   33.49 +static void     gmyth_recorder_init(GMythRecorder * object);
   33.50 +
   33.51 +static void     gmyth_recorder_dispose(GObject * object);
   33.52 +static void     gmyth_recorder_finalize(GObject * object);
   33.53 +
   33.54 +G_DEFINE_TYPE(GMythRecorder, gmyth_recorder, G_TYPE_OBJECT)
   33.55 +    static void     gmyth_recorder_class_init(GMythRecorderClass * klass)
   33.56 +{
   33.57 +    GObjectClass   *gobject_class;
   33.58 +
   33.59 +    gobject_class = (GObjectClass *) klass;
   33.60 +
   33.61 +    gobject_class->dispose = gmyth_recorder_dispose;
   33.62 +    gobject_class->finalize = gmyth_recorder_finalize;
   33.63 +}
   33.64 +
   33.65 +static void
   33.66 +gmyth_recorder_init(GMythRecorder * gmyth_remote_encoder)
   33.67 +{
   33.68 +}
   33.69 +
   33.70 +static void
   33.71 +gmyth_recorder_dispose(GObject * object)
   33.72 +{
   33.73 +    GMythRecorder  *recorder = GMYTH_RECORDER(object);
   33.74 +
   33.75 +    gmyth_recorder_close(recorder);
   33.76 +
   33.77 +    if (recorder->mutex != NULL) {
   33.78 +        g_mutex_free(recorder->mutex);
   33.79 +        recorder->mutex = NULL;
   33.80 +    }
   33.81 +
   33.82 +    if (recorder->myth_socket != NULL) {
   33.83 +        g_object_unref(recorder->myth_socket);
   33.84 +        recorder->myth_socket = NULL;
   33.85 +    }
   33.86 +
   33.87 +    if (recorder->progs_info_list != NULL)
   33.88 +        gmyth_free_program_list(recorder->progs_info_list);
   33.89 +
   33.90 +    if (recorder->hostname != NULL)
   33.91 +        g_string_free(recorder->hostname, TRUE);
   33.92 +
   33.93 +    G_OBJECT_CLASS(gmyth_recorder_parent_class)->dispose(object);
   33.94 +}
   33.95 +
   33.96 +static void
   33.97 +gmyth_recorder_finalize(GObject * object)
   33.98 +{
   33.99 +    g_signal_handlers_destroy(object);
  33.100 +
  33.101 +    G_OBJECT_CLASS(gmyth_recorder_parent_class)->finalize(object);
  33.102 +}
  33.103 +
  33.104 +void
  33.105 +gmyth_recorder_close(GMythRecorder * recorder)
  33.106 +{
  33.107 +    if (recorder != NULL && recorder->recorder_num != -1) {
  33.108 +        g_mutex_lock(recorder->mutex);
  33.109 +
  33.110 +        gmyth_recorder_stop_playing(recorder);
  33.111 +        gmyth_recorder_stop_livetv(recorder);
  33.112 +        gmyth_recorder_finish_recording(recorder);
  33.113 +        gmyth_recorder_free_tuner(recorder);
  33.114 +
  33.115 +        g_mutex_unlock(recorder->mutex);
  33.116 +    }
  33.117 +}
  33.118 +
  33.119 +/** Creates a new instance of GMythRecorder.
  33.120 + * 
  33.121 + * @return a new instance of GMythRecorder.
  33.122 + */
  33.123 +GMythRecorder  *
  33.124 +gmyth_recorder_new(int num, GString * hostname, gshort port)
  33.125 +{
  33.126 +    GMythRecorder  *encoder =
  33.127 +        GMYTH_RECORDER(g_object_new(GMYTH_RECORDER_TYPE, FALSE));
  33.128 +
  33.129 +    encoder->recorder_num = num;
  33.130 +    encoder->hostname = g_string_new(hostname->str);
  33.131 +    encoder->port = port;
  33.132 +
  33.133 +    encoder->mutex = g_mutex_new();
  33.134 +
  33.135 +    encoder->progs_info_list = NULL;
  33.136 +
  33.137 +    return encoder;
  33.138 +}
  33.139 +
  33.140 +/** Configures the remote encoder instance connecting it to Mythtv backend.
  33.141 + * 
  33.142 + * @param recorder the GMythRecorder instance.
  33.143 + * 
  33.144 + * @return TRUE if successfull, FALSE if any error happens.
  33.145 + */
  33.146 +gboolean
  33.147 +gmyth_recorder_setup(GMythRecorder * recorder)
  33.148 +{
  33.149 +    assert(recorder);
  33.150 +    gmyth_debug("[%s] Creating socket and connecting to backend",
  33.151 +                __FUNCTION__);
  33.152 +
  33.153 +    if (recorder->myth_socket == NULL) {
  33.154 +        recorder->myth_socket = gmyth_socket_new();
  33.155 +
  33.156 +        if (!gmyth_socket_connect_to_backend(recorder->myth_socket,
  33.157 +                                             recorder->hostname->str,
  33.158 +                                             recorder->port, TRUE)) {
  33.159 +            gmyth_debug
  33.160 +                ("GMythRemoteEncoder: Connection to backend failed");
  33.161 +            return FALSE;
  33.162 +        }
  33.163 +    } else {
  33.164 +        gmyth_debug("Remote encoder socket already created\n");
  33.165 +    }
  33.166 +
  33.167 +    return TRUE;
  33.168 +}
  33.169 +
  33.170 +/** Sends the SPAWN_LIVETV command through Mythtv protocol. This command
  33.171 + * requests the backend to start capturing TV content.
  33.172 + * 
  33.173 + * @param recorder The GMythRecorder instance.
  33.174 + * @param tvchain_id The tvchain unique id.
  33.175 + * @return true if success, false if any error happens.
  33.176 + */
  33.177 +gboolean
  33.178 +gmyth_recorder_spawntv(GMythRecorder * recorder, GString * tvchain_id)
  33.179 +{
  33.180 +    GMythStringList *str_list;
  33.181 +    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  33.182 +    gboolean        ret = TRUE;
  33.183 +
  33.184 +    gmyth_debug("[%s] Spawntv with tvchain_id = %s", __FUNCTION__,
  33.185 +                tvchain_id->str);
  33.186 +
  33.187 +    str_list = gmyth_string_list_new();
  33.188 +
  33.189 +    g_mutex_lock(recorder->mutex);
  33.190 +
  33.191 +    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  33.192 +
  33.193 +    gmyth_string_list_append_string(str_list, tmp_str);
  33.194 +    g_string_free(tmp_str, TRUE);
  33.195 +
  33.196 +    gmyth_string_list_append_char_array(str_list, "SPAWN_LIVETV");
  33.197 +
  33.198 +    gmyth_string_list_append_string(str_list, tvchain_id);
  33.199 +    gmyth_string_list_append_int(str_list, 0);  // PIP = FALSE (0)
  33.200 +
  33.201 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  33.202 +
  33.203 +    tmp_str = gmyth_string_list_get_string(str_list, 0);
  33.204 +
  33.205 +    if (tmp_str == NULL) {
  33.206 +        gmyth_debug("[%s] Spawntv request returned %s", __FUNCTION__,
  33.207 +                    tmp_str->str);
  33.208 +        ret = FALSE;
  33.209 +        goto cleanup;
  33.210 +    }
  33.211 +
  33.212 +    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
  33.213 +        gmyth_debug("[%s] Spawntv request returned %s", __FUNCTION__,
  33.214 +                    tmp_str->str);
  33.215 +        ret = FALSE;
  33.216 +        goto cleanup;
  33.217 +    }
  33.218 +
  33.219 +  cleanup:
  33.220 +    g_mutex_unlock(recorder->mutex);
  33.221 +
  33.222 +    g_string_free(tmp_str, TRUE);
  33.223 +    g_object_unref(str_list);
  33.224 +
  33.225 +    return ret;
  33.226 +}
  33.227 +
  33.228 +/** 
  33.229 + * Sends the SPAWN_LIVETV command through Mythtv protocol. This command
  33.230 + * requests the backend to start capturing TV content, but it doesn't need
  33.231 + * the TV chain ID.
  33.232 + * 
  33.233 + * @param recorder The GMythRecorder instance.
  33.234 + * @return true if success, false if any error happens.
  33.235 + */
  33.236 +gboolean
  33.237 +gmyth_recorder_spawntv_no_tvchain(GMythRecorder * recorder)
  33.238 +{
  33.239 +    GMythStringList *str_list;
  33.240 +    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  33.241 +    gboolean        ret = TRUE;
  33.242 +
  33.243 +    gmyth_debug("[%s] Spawntv, no TV chain!", __FUNCTION__);
  33.244 +
  33.245 +    str_list = gmyth_string_list_new();
  33.246 +
  33.247 +    g_mutex_lock(recorder->mutex);
  33.248 +
  33.249 +    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  33.250 +
  33.251 +    gmyth_string_list_append_string(str_list, tmp_str);
  33.252 +    g_string_free(tmp_str, TRUE);
  33.253 +
  33.254 +    gmyth_string_list_append_char_array(str_list, "SPAWN_LIVETV");
  33.255 +
  33.256 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  33.257 +
  33.258 +    tmp_str = gmyth_string_list_get_string(str_list, 0);
  33.259 +
  33.260 +    if (tmp_str == NULL) {
  33.261 +        gmyth_debug("[%s] Spawntv request returned %s", __FUNCTION__,
  33.262 +                    tmp_str->str);
  33.263 +        ret = FALSE;
  33.264 +        goto cleanup;
  33.265 +    }
  33.266 +
  33.267 +    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
  33.268 +        gmyth_debug("[%s] Spawntv request returned %s", __FUNCTION__,
  33.269 +                    tmp_str->str);
  33.270 +        ret = FALSE;
  33.271 +        goto cleanup;
  33.272 +    }
  33.273 +
  33.274 +  cleanup:
  33.275 +    g_mutex_unlock(recorder->mutex);
  33.276 +
  33.277 +    g_string_free(tmp_str, TRUE);
  33.278 +    g_object_unref(str_list);
  33.279 +
  33.280 +    return ret;
  33.281 +}
  33.282 +
  33.283 +/** Sends the command STOP_LIVETV to Mythtv backend.
  33.284 + * 
  33.285 + * @param recorder the GMythRecorder instance.
  33.286 + * @return true if success, false if any error happens.
  33.287 + */
  33.288 +gboolean
  33.289 +gmyth_recorder_stop_livetv(GMythRecorder * recorder)
  33.290 +{
  33.291 +    GMythStringList *str_list;
  33.292 +    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  33.293 +    gboolean        ret = TRUE;
  33.294 +
  33.295 +    gmyth_debug("[%s]", __FUNCTION__);
  33.296 +
  33.297 +    str_list = gmyth_string_list_new();
  33.298 +
  33.299 +    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  33.300 +
  33.301 +    gmyth_string_list_append_string(str_list, tmp_str);
  33.302 +    g_string_free(tmp_str, TRUE);
  33.303 +
  33.304 +    gmyth_string_list_append_char_array(str_list, "STOP_LIVETV");
  33.305 +
  33.306 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  33.307 +
  33.308 +    tmp_str = gmyth_string_list_get_string(str_list, 0);
  33.309 +
  33.310 +    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
  33.311 +        gmyth_debug("[%s] Stop livetv request returned %s", __FUNCTION__,
  33.312 +                    tmp_str->str);
  33.313 +        ret = FALSE;
  33.314 +        goto cleanup;
  33.315 +    }
  33.316 +
  33.317 +  cleanup:
  33.318 +    g_string_free(tmp_str, TRUE);
  33.319 +    g_object_unref(str_list);
  33.320 +
  33.321 +    return ret;
  33.322 +}
  33.323 +
  33.324 +/** Sends the FRONTEND_READY command through Mythtv protocol. This command
  33.325 + * advertises the backend to start capturing TV content.
  33.326 + * 
  33.327 + * @param recorder The GMythRecorder instance.
  33.328 + * @return TRUE if success, FALSE if any error happens.
  33.329 + */
  33.330 +gboolean
  33.331 +gmyth_recorder_send_frontend_ready_command(GMythRecorder * recorder)
  33.332 +{
  33.333 +    GMythStringList *str_list;
  33.334 +    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  33.335 +    gboolean        ret = TRUE;
  33.336 +
  33.337 +    gmyth_debug("[%s] FRONTEND_READY with recorder id = %d", __FUNCTION__,
  33.338 +                recorder->recorder_num);
  33.339 +
  33.340 +    str_list = gmyth_string_list_new();
  33.341 +
  33.342 +    g_mutex_lock(recorder->mutex);
  33.343 +
  33.344 +    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  33.345 +
  33.346 +    gmyth_string_list_append_string(str_list, tmp_str);
  33.347 +    g_string_free(tmp_str, TRUE);
  33.348 +
  33.349 +    gmyth_string_list_append_char_array(str_list, "FRONTEND_READY");
  33.350 +
  33.351 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  33.352 +
  33.353 +    tmp_str = gmyth_string_list_get_string(str_list, 0);
  33.354 +
  33.355 +    if (tmp_str == NULL) {
  33.356 +        gmyth_debug
  33.357 +            ("[%s] FRONTEND_READY command request couldn't returns, reason: %s",
  33.358 +             __FUNCTION__, tmp_str->str);
  33.359 +        ret = FALSE;
  33.360 +        goto cleanup;
  33.361 +    }
  33.362 +
  33.363 +    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
  33.364 +        gmyth_debug("[%s] FRONTEND_READY request returned %s",
  33.365 +                    __FUNCTION__, tmp_str->str);
  33.366 +        ret = FALSE;
  33.367 +        goto cleanup;
  33.368 +    }
  33.369 +
  33.370 +  cleanup:
  33.371 +    g_mutex_unlock(recorder->mutex);
  33.372 +    g_string_free(tmp_str, TRUE);
  33.373 +    g_object_unref(str_list);
  33.374 +
  33.375 +    return ret;
  33.376 +}
  33.377 +
  33.378 +/** Send a CHECK_CHANNEL command request to the backend, in order to find if a 
  33.379 + * certain channel actually exists.
  33.380 + * 
  33.381 + * @param recorder The GMythRecorder instance.
  33.382 + * @param channel	 The new channel to be checked (string format).
  33.383 + * @return true if success, false if any error happens.
  33.384 + */
  33.385 +gboolean
  33.386 +gmyth_recorder_check_channel_name(GMythRecorder * recorder,
  33.387 +                                  gchar * channel)
  33.388 +{
  33.389 +    GMythStringList *str_list;
  33.390 +    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  33.391 +    gboolean        ret = TRUE;
  33.392 +
  33.393 +    gmyth_debug("[%s] CHECK_CHANNEL with channel = %s", __FUNCTION__,
  33.394 +                channel);
  33.395 +
  33.396 +    str_list = gmyth_string_list_new();
  33.397 +
  33.398 +    g_mutex_lock(recorder->mutex);
  33.399 +
  33.400 +    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  33.401 +
  33.402 +    gmyth_string_list_append_string(str_list, tmp_str);
  33.403 +    g_string_free(tmp_str, TRUE);
  33.404 +
  33.405 +    gmyth_string_list_append_char_array(str_list, "CHECK_CHANNEL");
  33.406 +
  33.407 +    gmyth_string_list_append_char_array(str_list, channel);
  33.408 +
  33.409 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  33.410 +
  33.411 +    tmp_str = gmyth_string_list_get_string(str_list, 0);
  33.412 +
  33.413 +    if (tmp_str == NULL) {
  33.414 +        gmyth_debug("[%s] CHECK_CHANNEL request returned %s", __FUNCTION__,
  33.415 +                    tmp_str->str);
  33.416 +        ret = FALSE;
  33.417 +        goto cleanup;
  33.418 +    }
  33.419 +
  33.420 +    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2) == 0
  33.421 +        || g_ascii_strncasecmp(tmp_str->str, "0", 1) == 0) {
  33.422 +        gmyth_debug("[%s] CHECK_CHANNEL request returned %s", __FUNCTION__,
  33.423 +                    tmp_str->str);
  33.424 +        ret = FALSE;
  33.425 +        goto cleanup;
  33.426 +    }
  33.427 +
  33.428 +  cleanup:
  33.429 +    g_mutex_unlock(recorder->mutex);
  33.430 +    g_string_free(tmp_str, TRUE);
  33.431 +    g_object_unref(str_list);
  33.432 +
  33.433 +    return ret;
  33.434 +}
  33.435 +
  33.436 +/** Send a CHECK_CHANNEL command request to the backend, in order to find if a 
  33.437 + * certain channel actually exists.
  33.438 + * 
  33.439 + * @param recorder The GMythRecorder instance.
  33.440 + * @param channel	 The new channel to be checked (decimal integer value).
  33.441 + * @return true if success, false if any error happens.
  33.442 + */
  33.443 +gboolean
  33.444 +gmyth_recorder_check_channel(GMythRecorder * recorder, gint channel)
  33.445 +{
  33.446 +    return gmyth_recorder_check_channel_name(recorder,
  33.447 +                                             g_strdup_printf("%d",
  33.448 +                                                             channel));
  33.449 +}
  33.450 +
  33.451 +/** Send a SET_CHANNEL command request to the backend, to start streaming on another 
  33.452 + * TV content channel.
  33.453 + * 
  33.454 + * @param recorder The GMythRecorder instance.
  33.455 + * @param channel	 The new channel to be loaded.
  33.456 + * @return true if success, false if any error happens.
  33.457 + */
  33.458 +gboolean
  33.459 +gmyth_recorder_set_channel(GMythRecorder * recorder, gint channel)
  33.460 +{
  33.461 +    GMythStringList *str_list;
  33.462 +    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  33.463 +    gboolean        ret = TRUE;
  33.464 +
  33.465 +    gmyth_debug("[%s] SET_CHANNEL with channel = %d", __FUNCTION__,
  33.466 +                channel);
  33.467 +
  33.468 +    str_list = gmyth_string_list_new();
  33.469 +
  33.470 +    g_mutex_lock(recorder->mutex);
  33.471 +
  33.472 +    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  33.473 +
  33.474 +    gmyth_string_list_append_string(str_list, tmp_str);
  33.475 +    g_string_free(tmp_str, TRUE);
  33.476 +
  33.477 +    gmyth_string_list_append_char_array(str_list, "SET_CHANNEL");
  33.478 +
  33.479 +    gmyth_string_list_append_int(str_list, channel);
  33.480 +
  33.481 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  33.482 +
  33.483 +    tmp_str = gmyth_string_list_get_string(str_list, 0);
  33.484 +
  33.485 +    if (tmp_str == NULL) {
  33.486 +        gmyth_debug("[%s] SET_CHANNEL request returned %s", __FUNCTION__,
  33.487 +                    tmp_str->str);
  33.488 +        ret = FALSE;
  33.489 +        goto cleanup;
  33.490 +    }
  33.491 +
  33.492 +    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
  33.493 +        gmyth_debug("[%s] SET_CHANNEL request returned %s", __FUNCTION__,
  33.494 +                    tmp_str->str);
  33.495 +        ret = FALSE;
  33.496 +        goto cleanup;
  33.497 +    }
  33.498 +
  33.499 +  cleanup:
  33.500 +    g_mutex_unlock(recorder->mutex);
  33.501 +    g_string_free(tmp_str, TRUE);
  33.502 +    g_object_unref(str_list);
  33.503 +
  33.504 +    return ret;
  33.505 +}
  33.506 +
  33.507 +/** Send a SET_CHANNEL command request to the backend, to start streaming on another 
  33.508 + * TV content channel.
  33.509 + * 
  33.510 + * @param recorder The GMythRecorder instance.
  33.511 + * @param channel	 The new channel to be loaded.
  33.512 + * @return true if success, false if any error happens.
  33.513 + */
  33.514 +gboolean
  33.515 +gmyth_recorder_set_channel_name(GMythRecorder * recorder,
  33.516 +                                const gchar * channel)
  33.517 +{
  33.518 +    GMythStringList *str_list;
  33.519 +    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  33.520 +    gboolean        ret = TRUE;
  33.521 +
  33.522 +    gmyth_debug("[%s] SET_CHANNEL with channel name = %s", __FUNCTION__,
  33.523 +                channel);
  33.524 +
  33.525 +    str_list = gmyth_string_list_new();
  33.526 +
  33.527 +    g_mutex_lock(recorder->mutex);
  33.528 +
  33.529 +    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  33.530 +
  33.531 +    gmyth_string_list_append_string(str_list, tmp_str);
  33.532 +    g_string_free(tmp_str, TRUE);
  33.533 +
  33.534 +    gmyth_string_list_append_char_array(str_list, "SET_CHANNEL");
  33.535 +    gmyth_string_list_append_char_array(str_list, channel);
  33.536 +
  33.537 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  33.538 +
  33.539 +    tmp_str = gmyth_string_list_get_string(str_list, 0);
  33.540 +
  33.541 +    if (tmp_str == NULL) {
  33.542 +        gmyth_debug("[%s] SET_CHANNEL name request returned NULL!",
  33.543 +                    __FUNCTION__);
  33.544 +        ret = FALSE;
  33.545 +        goto cleanup;
  33.546 +    }
  33.547 +
  33.548 +    if (tmp_str != NULL && g_ascii_strncasecmp(tmp_str->str, "ok", 2)
  33.549 +        /*
  33.550 +         * || g_ascii_strtoull( tmp_str->str, NULL, 10 ) == 0 
  33.551 +         */
  33.552 +        ) {
  33.553 +        g_warning("[%s] SET_CHANNEL name request returned not ok",
  33.554 +                  __FUNCTION__);
  33.555 +        ret = FALSE;
  33.556 +        goto cleanup;
  33.557 +    }
  33.558 +
  33.559 +  cleanup:
  33.560 +    g_mutex_unlock(recorder->mutex);
  33.561 +    g_string_free(tmp_str, TRUE);
  33.562 +    g_object_unref(str_list);
  33.563 +
  33.564 +    return ret;
  33.565 +}
  33.566 +
  33.567 +/**
  33.568 + * Changes the channel of the actual Recorder.
  33.569 + * 
  33.570 + * CHANNEL_DIRECTION_UP       - Go up one channel in the listing
  33.571 + *
  33.572 + * CHANNEL_DIRECTION_DOWN     - Go down one channel in the listing
  33.573 + *
  33.574 + * CHANNEL_DIRECTION_FAVORITE - Go to the next favorite channel
  33.575 + *
  33.576 + * CHANNEL_DIRECTION_SAME     - Stay
  33.577 + * 
  33.578 + * @param recorder 	 The GMythRecorder instance.
  33.579 + * @param direction	 The new channel direction where to move to.
  33.580 + * @return true if success, false if any error happens.
  33.581 + */
  33.582 +gboolean
  33.583 +gmyth_recorder_change_channel(GMythRecorder * recorder,
  33.584 +                              const GMythRecorderChannelChangeDirection
  33.585 +                              direction)
  33.586 +{
  33.587 +    GMythStringList *str_list;
  33.588 +    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  33.589 +    gboolean        ret = TRUE;
  33.590 +
  33.591 +    gmyth_debug("[%s] CHANGE_CHANNEL to the channel direction = %u",
  33.592 +                __FUNCTION__, direction);
  33.593 +
  33.594 +    str_list = gmyth_string_list_new();
  33.595 +
  33.596 +    g_mutex_lock(recorder->mutex);
  33.597 +
  33.598 +    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  33.599 +
  33.600 +    gmyth_string_list_append_string(str_list, tmp_str);
  33.601 +    g_string_free(tmp_str, TRUE);
  33.602 +
  33.603 +    gmyth_string_list_append_char_array(str_list, "CHANGE_CHANNEL");
  33.604 +    gmyth_string_list_append_int(str_list, direction);
  33.605 +
  33.606 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  33.607 +
  33.608 +    tmp_str = gmyth_string_list_get_string(str_list, 0);
  33.609 +
  33.610 +    if (tmp_str == NULL) {
  33.611 +        gmyth_debug("[%s] CHANGE_CHANNEL name request returned %s",
  33.612 +                    __FUNCTION__, tmp_str->str);
  33.613 +        ret = FALSE;
  33.614 +        goto cleanup;
  33.615 +    }
  33.616 +
  33.617 +    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)
  33.618 +        || g_ascii_strtoull(tmp_str->str, NULL, 10) == 0) {
  33.619 +        gmyth_debug("[%s] CHANGE_CHANNEL name request returned %s",
  33.620 +                    __FUNCTION__, tmp_str->str);
  33.621 +        ret = FALSE;
  33.622 +        goto cleanup;
  33.623 +    }
  33.624 +
  33.625 +  cleanup:
  33.626 +    g_mutex_unlock(recorder->mutex);
  33.627 +    g_string_free(tmp_str, TRUE);
  33.628 +    g_object_unref(str_list);
  33.629 +
  33.630 +    return ret;
  33.631 +}
  33.632 +
  33.633 +/** 
  33.634 + * Gets the channel's list from the MythTV backend server.
  33.635 + * 
  33.636 + * @param recorder The GMythRecorder instance.
  33.637 + * 
  33.638 + * @return a GList* instance with all the channel names.
  33.639 + */
  33.640 +GList          *
  33.641 +gmyth_recorder_get_channel_list(GMythRecorder * recorder)
  33.642 +{
  33.643 +
  33.644 +    GList          *channel_list = NULL;
  33.645 +    gchar          *channel = NULL;
  33.646 +    guint           i;
  33.647 +
  33.648 +    for (i = 0; i < 1000; i++) {
  33.649 +        channel = g_strdup_printf("%u", i);
  33.650 +
  33.651 +        if (gmyth_recorder_check_channel_name(recorder, channel)) {
  33.652 +            channel_list = g_list_append(channel_list, g_strdup(channel));
  33.653 +        }
  33.654 +
  33.655 +    }                           /* for - channel list */
  33.656 +
  33.657 +    g_free(channel);
  33.658 +
  33.659 +    return channel_list;
  33.660 +
  33.661 +}
  33.662 +
  33.663 +/** Send a PAUSE command request to the backend, to pause streaming on another 
  33.664 + * TV content channel.
  33.665 + * 
  33.666 + * @param recorder The GMythRecorder instance.
  33.667 + * @return true if success, false if any error happens.
  33.668 + */
  33.669 +gboolean
  33.670 +gmyth_recorder_pause_recording(GMythRecorder * recorder)
  33.671 +{
  33.672 +    GMythStringList *str_list;
  33.673 +    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  33.674 +    gboolean        ret = TRUE;
  33.675 +
  33.676 +    gmyth_debug("[%s] PAUSE", __FUNCTION__);
  33.677 +
  33.678 +    str_list = gmyth_string_list_new();
  33.679 +
  33.680 +    g_mutex_lock(recorder->mutex);
  33.681 +
  33.682 +    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  33.683 +
  33.684 +    gmyth_string_list_append_string(str_list, tmp_str);
  33.685 +    g_string_free(tmp_str, TRUE);
  33.686 +
  33.687 +    gmyth_string_list_append_char_array(str_list, "PAUSE");
  33.688 +
  33.689 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  33.690 +
  33.691 +    tmp_str = gmyth_string_list_get_string(str_list, 0);
  33.692 +
  33.693 +    if (tmp_str == NULL) {
  33.694 +        gmyth_debug("[%s] PAUSE name request returned %s", __FUNCTION__,
  33.695 +                    tmp_str->str);
  33.696 +        ret = FALSE;
  33.697 +        goto cleanup;
  33.698 +    }
  33.699 +
  33.700 +    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
  33.701 +        gmyth_debug("[%s] PAUSE name request returned %s", __FUNCTION__,
  33.702 +                    tmp_str->str);
  33.703 +        ret = FALSE;
  33.704 +        goto cleanup;
  33.705 +    }
  33.706 +
  33.707 +  cleanup:
  33.708 +    g_mutex_unlock(recorder->mutex);
  33.709 +    g_string_free(tmp_str, TRUE);
  33.710 +    g_object_unref(str_list);
  33.711 +
  33.712 +    return ret;
  33.713 +}
  33.714 +
  33.715 +static          gboolean
  33.716 +gmyth_recorder_find_if_program_exists(GMythRecorder * recorder,
  33.717 +                                      GMythProgramInfo * prog)
  33.718 +{
  33.719 +    GList          *lst = NULL;
  33.720 +
  33.721 +    g_return_val_if_fail(recorder != NULL
  33.722 +                         && recorder->progs_info_list != NULL, FALSE);
  33.723 +
  33.724 +    for (lst = recorder->progs_info_list; lst != NULL;
  33.725 +         lst = g_list_next(lst)) {
  33.726 +        gmyth_debug("Got program info from list = [%s]",
  33.727 +                    gmyth_program_info_to_string((GMythProgramInfo *)
  33.728 +                                                 lst->data));
  33.729 +        if (gmyth_program_info_is_equals
  33.730 +            (prog, (GMythProgramInfo *) lst->data))
  33.731 +            return TRUE;
  33.732 +    }
  33.733 +
  33.734 +    return FALSE;
  33.735 +}
  33.736 +
  33.737 +/**
  33.738 + * Requests the actual program info from the MythTV backend server.
  33.739 + * 
  33.740 + * @param recorder The GMythRecorder instance.
  33.741 + * @return The actual program info.
  33.742 + */
  33.743 +GMythProgramInfo *
  33.744 +gmyth_recorder_get_current_program_info(GMythRecorder * recorder)
  33.745 +{
  33.746 +    GMythStringList *str_list = NULL;
  33.747 +    GMythProgramInfo *program_info = NULL;
  33.748 +    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  33.749 +
  33.750 +    str_list = gmyth_string_list_new();
  33.751 +
  33.752 +    g_mutex_lock(recorder->mutex);
  33.753 +
  33.754 +    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  33.755 +
  33.756 +    gmyth_string_list_append_string(str_list, tmp_str);
  33.757 +
  33.758 +    if (recorder->myth_socket->mythtv_version >= 26)
  33.759 +        gmyth_string_list_append_char_array(str_list,
  33.760 +                                            "GET_CURRENT_RECORDING");
  33.761 +    else
  33.762 +        gmyth_string_list_append_char_array(str_list, "GET_PROGRAM_INFO");
  33.763 +
  33.764 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  33.765 +
  33.766 +    if (str_list == NULL) {
  33.767 +        gmyth_debug
  33.768 +            ("[%s] GET_PROGRAM_INFO request returned. Error getting program info, string list equals to NULL!",
  33.769 +             __FUNCTION__);
  33.770 +        goto cleanup;
  33.771 +    }
  33.772 +
  33.773 +    program_info = gmyth_program_info_from_string_list(str_list);
  33.774 +
  33.775 +    if (NULL == program_info || NULL == program_info->pathname
  33.776 +        || program_info->pathname->len <= 0) {
  33.777 +        gmyth_debug
  33.778 +            ("GET_PROGRAM_INFO request returned. Error getting program info, it is equals to NULL!!!");
  33.779 +
  33.780 +        if (program_info)
  33.781 +            g_object_unref(program_info);
  33.782 +
  33.783 +        program_info = NULL;
  33.784 +
  33.785 +        goto cleanup;
  33.786 +    }
  33.787 +
  33.788 +    if (!gmyth_recorder_find_if_program_exists(recorder, program_info))
  33.789 +        recorder->progs_info_list =
  33.790 +            g_list_append(recorder->progs_info_list,
  33.791 +                          g_object_ref(program_info));
  33.792 +  cleanup:
  33.793 +    g_mutex_unlock(recorder->mutex);
  33.794 +    g_string_free(tmp_str, TRUE);
  33.795 +    g_object_unref(str_list);
  33.796 +
  33.797 +    return program_info;
  33.798 +}
  33.799 +
  33.800 +/**
  33.801 + * Requests the actual program info from the MythTV backend server.
  33.802 + * 
  33.803 + * @param rec_id The GMythRecorder record number.
  33.804 + * @return The GMythRecorder instance.
  33.805 + */
  33.806 +GMythRecorder  *
  33.807 +gmyth_recorder_get_recorder_from_num(gint rec_id)
  33.808 +{
  33.809 +    GMythRecorder  *recorder = NULL;
  33.810 +    GMythStringList *str_list;
  33.811 +    GString        *tmp_str = g_string_new("GET_RECORDER_FROM_NUM");
  33.812 +    gint            command_size = 0;
  33.813 +
  33.814 +    gchar          *recorder_host = NULL;
  33.815 +    gint            recorder_port;
  33.816 +
  33.817 +    str_list = gmyth_string_list_new();
  33.818 +
  33.819 +    /*
  33.820 +     * g_string_append_printf ( tmp_str, " %d", recorder->recorder_num ); 
  33.821 +     */
  33.822 +
  33.823 +    g_mutex_lock(recorder->mutex);
  33.824 +
  33.825 +    gmyth_string_list_append_string(str_list, tmp_str);
  33.826 +
  33.827 +    gmyth_string_list_append_int(str_list, rec_id);
  33.828 +
  33.829 +    command_size =
  33.830 +        gmyth_socket_sendreceive_stringlist(recorder->myth_socket,
  33.831 +                                            str_list);
  33.832 +
  33.833 +    if (str_list == NULL) {
  33.834 +        gmyth_debug
  33.835 +            ("[%s] GET_RECORDER_FROM_NUM request returned. Error getting recorder number %d, it is equals to NULL!!!",
  33.836 +             __FUNCTION__, rec_id);
  33.837 +        return NULL;
  33.838 +    }
  33.839 +
  33.840 +    if (command_size > 0) {
  33.841 +        recorder_host = gmyth_string_list_get_char_array(str_list, 0);
  33.842 +        recorder_port = gmyth_string_list_get_int(str_list, 1);
  33.843 +
  33.844 +        if (g_strstr_len(recorder_host, strlen(recorder_host), "nohost")
  33.845 +            != NULL) {
  33.846 +            gmyth_debug
  33.847 +                ("No available recorder with the recorder ID number %d!",
  33.848 +                 rec_id);
  33.849 +        } else {
  33.850 +
  33.851 +            recorder = gmyth_recorder_new(rec_id,
  33.852 +                                          g_string_new(recorder_host),
  33.853 +                                          (gshort) recorder_port);
  33.854 +
  33.855 +            if (NULL == recorder) {
  33.856 +                gmyth_debug
  33.857 +                    ("[%s] GET_RECORDER_FROM_NUM request returned. Error getting recorder number %d, it is equals to NULL!!!",
  33.858 +                     __FUNCTION__, rec_id);
  33.859 +                g_object_unref(recorder);
  33.860 +                return NULL;
  33.861 +            }
  33.862 +
  33.863 +        }
  33.864 +
  33.865 +    } else {
  33.866 +        gmyth_debug
  33.867 +            ("Cannot find a valuable recorder with the recorder ID number %d, backend server error!",
  33.868 +             rec_id);
  33.869 +    }
  33.870 +
  33.871 +    g_mutex_unlock(recorder->mutex);
  33.872 +
  33.873 +    g_object_unref(str_list);
  33.874 +
  33.875 +    g_string_free(tmp_str, TRUE);
  33.876 +
  33.877 +    g_free(recorder_host);
  33.878 +
  33.879 +    return recorder;
  33.880 +
  33.881 +}
  33.882 +
  33.883 +/**
  33.884 + * Requests the actual program info from the MythTV backend server.
  33.885 + * 
  33.886 + * @param recorder The GMythRecorder instance.
  33.887 + * @param direction The direction to move based on the current channel (forward, backward,
  33.888 + *            up, down).
  33.889 + * 
  33.890 + * @return The GMythProgramInfo next program info instance.
  33.891 + */
  33.892 +GMythProgramInfo *
  33.893 +gmyth_recorder_get_next_program_info(GMythRecorder * recorder,
  33.894 +                                     const GMythRecorderBrowseDirection
  33.895 +                                     direction)
  33.896 +{
  33.897 +    GMythProgramInfo *actual_proginfo = NULL;
  33.898 +    GMythProgramInfo *program_info = NULL;
  33.899 +    GMythStringList *str_list;
  33.900 +    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  33.901 +
  33.902 +    gchar          *date = NULL;
  33.903 +    struct tm      *tm = NULL;
  33.904 +    time_t          t;
  33.905 +
  33.906 +    actual_proginfo = gmyth_recorder_get_current_program_info(recorder);
  33.907 +
  33.908 +    str_list = gmyth_string_list_new();
  33.909 +
  33.910 +    g_mutex_lock(recorder->mutex);
  33.911 +
  33.912 +    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  33.913 +
  33.914 +    t = time(NULL);
  33.915 +    tm = localtime(&t);
  33.916 +    date = g_strdup_printf("%.4d%.2d%.2d%.2d%.2d%.2d", tm->tm_year + 1900,
  33.917 +                           tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
  33.918 +                           tm->tm_min, tm->tm_sec);
  33.919 +
  33.920 +    gmyth_string_list_append_string(str_list, tmp_str);
  33.921 +    gmyth_string_list_append_char_array(str_list, "GET_NEXT_PROGRAM_INFO");
  33.922 +    gmyth_string_list_append_string(str_list, actual_proginfo->channame);
  33.923 +    gmyth_string_list_append_int(str_list, actual_proginfo->channel_id);
  33.924 +    gmyth_string_list_append_int(str_list, direction);
  33.925 +    gmyth_string_list_append_char_array(str_list, date);
  33.926 +
  33.927 +    if (gmyth_socket_sendreceive_stringlist
  33.928 +        (recorder->myth_socket, str_list)
  33.929 +        > 0) {
  33.930 +
  33.931 +        if (str_list == NULL) {
  33.932 +            gmyth_debug
  33.933 +                ("[%s] GET_NEXT_PROGRAM_INFO request returned. Error getting program info, it is equals to NULL!!!",
  33.934 +                 __FUNCTION__);
  33.935 +            goto done;
  33.936 +        }
  33.937 +        program_info =
  33.938 +            gmyth_program_info_from_string_list_next_prog(str_list);
  33.939 +
  33.940 +        if (NULL == program_info) {
  33.941 +            gmyth_debug
  33.942 +                ("[%s] GET_NEXT_PROGRAM_INFO request returned. Error getting next program info, it is equals to NULL!!!",
  33.943 +                 __FUNCTION__);
  33.944 +            g_object_unref(program_info);
  33.945 +            goto done;
  33.946 +        }
  33.947 +
  33.948 +        if (                    /* ( program_info->chanid != NULL &&
  33.949 +                                 * strlen( program_info->chanid->str ) > 0 
  33.950 +                                 * * * * * * ) && */
  33.951 +               (program_info->chansign != NULL
  33.952 +                && strlen(program_info->chansign->str) > 0)) {
  33.953 +            gmyth_debug("OK!!! Got the next program info... [%s].",
  33.954 +                        program_info->chansign->str);
  33.955 +        } else {
  33.956 +            gmyth_debug
  33.957 +                ("GET_NEXT_PROGRAM_INFO request returned. Error getting next program info, it is equals to NULL!!!");
  33.958 +            g_object_unref(program_info);
  33.959 +            program_info = NULL;
  33.960 +        }
  33.961 +
  33.962 +    }
  33.963 +    /*
  33.964 +     * if 
  33.965 +     */
  33.966 +  done:
  33.967 +
  33.968 +    g_mutex_unlock(recorder->mutex);
  33.969 +
  33.970 +    if (actual_proginfo != NULL)
  33.971 +        g_object_unref(actual_proginfo);
  33.972 +
  33.973 +    if (str_list != NULL)
  33.974 +        g_object_unref(str_list);
  33.975 +
  33.976 +    if (tmp_str != NULL)
  33.977 +        g_string_free(tmp_str, TRUE);
  33.978 +
  33.979 +    if (date != NULL)
  33.980 +        g_free(date);
  33.981 +    // if ( tm != NULL)
  33.982 +    // g_free (tm);
  33.983 +
  33.984 +    return program_info;
  33.985 +}
  33.986 +
  33.987 +/**
  33.988 + * Requests the program info from the MythTV backend server, based on its 
  33.989 + * channel name.
  33.990 + * 
  33.991 + * @param recorder The GMythRecorder instance.
  33.992 + * @return The GMythProgramInfo next program info instance.
  33.993 + */
  33.994 +GMythProgramInfo *
  33.995 +gmyth_recorder_get_program_info_from_channel_name(GMythRecorder * recorder,
  33.996 +                                                  const gchar * channel)
  33.997 +{
  33.998 +    // GMythProgramInfo* actual_proginfo= NULL;
  33.999 +    GMythProgramInfo *program_info = NULL;
 33.1000 +    GMythStringList *str_list;
 33.1001 +    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
 33.1002 +
 33.1003 +    /*
 33.1004 +     * gchar *date = NULL; struct tm *tm = NULL; time_t t;
 33.1005 +     * 
 33.1006 +     * actual_proginfo =
 33.1007 +     * gmyth_recorder_get_current_program_info(recorder); 
 33.1008 +     */
 33.1009 +
 33.1010 +    str_list = gmyth_string_list_new();
 33.1011 +
 33.1012 +    g_mutex_lock(recorder->mutex);
 33.1013 +
 33.1014 +    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
 33.1015 +
 33.1016 +    /*
 33.1017 +     * t = time(NULL); tm = localtime(&t); date =
 33.1018 +     * g_strdup_printf("%.4d%.2d%.2d%.2d%.2d%.2d", tm->tm_year + 1900,
 33.1019 +     * tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); 
 33.1020 +     */
 33.1021 +
 33.1022 +    gmyth_string_list_append_string(str_list, tmp_str);
 33.1023 +    gmyth_string_list_append_char_array(str_list, "GET_NEXT_PROGRAM_INFO");
 33.1024 +    gmyth_string_list_append_char_array(str_list, channel);
 33.1025 +    gmyth_string_list_append_char_array(str_list, "0");
 33.1026 +    gmyth_string_list_append_int(str_list, BROWSE_DIRECTION_UP);
 33.1027 +    gmyth_string_list_append_char_array(str_list, "0");
 33.1028 +
 33.1029 +    do {
 33.1030 +
 33.1031 +        if (str_list != NULL &&
 33.1032 +            gmyth_socket_sendreceive_stringlist(recorder->myth_socket,
 33.1033 +                                                str_list) > 0) {
 33.1034 +
 33.1035 +            if (str_list == NULL) {
 33.1036 +                gmyth_debug
 33.1037 +                    ("[%s] GET_NEXT_PROGRAM_INFO request returned. Error getting program info, it is equals to NULL!!!",
 33.1038 +                     __FUNCTION__);
 33.1039 +                goto done;
 33.1040 +            }
 33.1041 +            program_info =
 33.1042 +                gmyth_program_info_from_string_list_next_prog(str_list);
 33.1043 +
 33.1044 +            if (NULL == program_info) {
 33.1045 +                gmyth_debug
 33.1046 +                    ("[%s] GET_NEXT_PROGRAM_INFO request returned. Error getting next program info, it is equals to NULL!!!",
 33.1047 +                     __FUNCTION__);
 33.1048 +                g_object_unref(program_info);
 33.1049 +                goto done;
 33.1050 +            }
 33.1051 +
 33.1052 +            if (                /* ( program_info->chanid != NULL &&
 33.1053 +                                 * strlen( program_info->chanid->str ) > 0 
 33.1054 +                                 * * * * * * ) && */
 33.1055 +                   (program_info->chansign != NULL
 33.1056 +                    && strlen(program_info->chansign->str) > 0)) {
 33.1057 +                gmyth_debug("OK!!! Got the next program info... [%s].",
 33.1058 +                            program_info->chansign->str);
 33.1059 +            } else {
 33.1060 +                gmyth_debug
 33.1061 +                    ("GET_NEXT_PROGRAM_INFO request returned. Error getting "
 33.1062 +                     "next program info, it is equals to NULL!!!");
 33.1063 +                g_object_unref(program_info);
 33.1064 +                program_info = NULL;
 33.1065 +            }
 33.1066 +
 33.1067 +        }
 33.1068 +        /*
 33.1069 +         * if 
 33.1070 +         */
 33.1071 +    }
 33.1072 +    while (str_list != NULL);
 33.1073 +
 33.1074 +  done:
 33.1075 +
 33.1076 +    g_mutex_unlock(recorder->mutex);
 33.1077 +
 33.1078 +    if (str_list != NULL)
 33.1079 +        g_object_unref(str_list);
 33.1080 +
 33.1081 +    if (tmp_str != NULL)
 33.1082 +        g_string_free(tmp_str, TRUE);
 33.1083 +
 33.1084 +    return program_info;
 33.1085 +}
 33.1086 +
 33.1087 +/**
 33.1088 + * Requests the actual remote file position on a LiveTV instance.
 33.1089 + * 
 33.1090 + * @param recorder The GMythRecorder instance.
 33.1091 + * 
 33.1092 + * @return The position, in bytes, of the offset to the read header.
 33.1093 + */
 33.1094 +gint64
 33.1095 +gmyth_recorder_get_file_position(GMythRecorder * recorder)
 33.1096 +{
 33.1097 +    gint64          pos = 0;
 33.1098 +    GString        *query = g_string_new(GMYTHTV_RECORDER_HEADER);
 33.1099 +
 33.1100 +    GMythStringList *str_list = gmyth_string_list_new();
 33.1101 +
 33.1102 +    g_mutex_lock(recorder->mutex);
 33.1103 +
 33.1104 +    g_string_append_printf(query, " %d", recorder->recorder_num);
 33.1105 +
 33.1106 +    gmyth_string_list_append_string(str_list, query);
 33.1107 +    gmyth_string_list_append_char_array(str_list, "GET_FILE_POSITION");
 33.1108 +
 33.1109 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
 33.1110 +
 33.1111 +    if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
 33.1112 +        GString        *str = NULL;
 33.1113 +
 33.1114 +        if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL
 33.1115 +            && strstr(str->str, "bad") == NULL)
 33.1116 +            pos = gmyth_string_list_get_int64(str_list, 0);
 33.1117 +        g_string_free(str, TRUE);
 33.1118 +    }
 33.1119 +#ifndef GMYTHTV_ENABLE_DEBUG
 33.1120 +    gmyth_debug("[%s] Got file position = %lld\n", __FUNCTION__, pos);
 33.1121 +#endif
 33.1122 +
 33.1123 +    g_mutex_unlock(recorder->mutex);
 33.1124 +
 33.1125 +    if (str_list != NULL)
 33.1126 +        g_object_unref(str_list);
 33.1127 +
 33.1128 +    g_string_free(query, TRUE);
 33.1129 +
 33.1130 +    return pos;
 33.1131 +}
 33.1132 +
 33.1133 +/**
 33.1134 + * Asks MythTV backend server about if it started to record the remote file.
 33.1135 + * 
 33.1136 + * @param recorder The GMythRecorder instance.
 33.1137 + * 
 33.1138 + * @return <code>true</code>, if the actual remote file is bein recorded.
 33.1139 + */
 33.1140 +gboolean
 33.1141 +gmyth_recorder_is_recording(GMythRecorder * recorder)
 33.1142 +{
 33.1143 +    gboolean        ret = TRUE;
 33.1144 +
 33.1145 +    g_return_val_if_fail(recorder != NULL, FALSE);
 33.1146 +
 33.1147 +    GMythStringList *str_list = gmyth_string_list_new();
 33.1148 +    GString        *message = g_string_new("");
 33.1149 +
 33.1150 +    g_mutex_lock(recorder->mutex);
 33.1151 +
 33.1152 +    g_string_printf(message, "%s %d", GMYTHTV_RECORDER_HEADER,
 33.1153 +                    recorder->recorder_num);
 33.1154 +    gmyth_string_list_append_string(str_list, message);
 33.1155 +    gmyth_string_list_append_char_array(str_list, "IS_RECORDING");
 33.1156 +
 33.1157 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
 33.1158 +
 33.1159 +    if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
 33.1160 +        GString        *str = NULL;
 33.1161 +
 33.1162 +        if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL
 33.1163 +            && strcmp(str->str, "bad") != 0) {
 33.1164 +            gint            is_rec =
 33.1165 +                gmyth_string_list_get_int(str_list, 0);
 33.1166 +
 33.1167 +            if (is_rec != 0)
 33.1168 +                ret = TRUE;
 33.1169 +            else
 33.1170 +                ret = FALSE;
 33.1171 +        }
 33.1172 +        g_string_free(str, TRUE);
 33.1173 +    }
 33.1174 +
 33.1175 +    gmyth_debug("%s, stream is %s being recorded!\n", ret ? "YES" : "NO",
 33.1176 +                ret ? "" : "NOT");
 33.1177 +    // g_static_mutex_unlock (&mutex);
 33.1178 +
 33.1179 +    g_mutex_unlock(recorder->mutex);
 33.1180 +
 33.1181 +    if (str_list != NULL)
 33.1182 +        g_object_unref(str_list);
 33.1183 +
 33.1184 +    g_string_free(message, TRUE);
 33.1185 +
 33.1186 +    return ret;
 33.1187 +
 33.1188 +}
 33.1189 +
 33.1190 +/**
 33.1191 + * Finish remote file recording process.
 33.1192 + * 
 33.1193 + * @param recorder The GMythRecorder instance.
 33.1194 + * 
 33.1195 + * @return <code>true</code>, if the recording had been actually closed.
 33.1196 + */
 33.1197 +gboolean
 33.1198 +gmyth_recorder_finish_recording(GMythRecorder * recorder)
 33.1199 +{
 33.1200 +    gboolean        ret = TRUE;
 33.1201 +
 33.1202 +    g_return_val_if_fail(recorder != NULL, FALSE);
 33.1203 +
 33.1204 +    GMythStringList *str_list = gmyth_string_list_new();
 33.1205 +    GString        *message = g_string_new("");
 33.1206 +
 33.1207 +    g_string_printf(message, "%s %d", GMYTHTV_RECORDER_HEADER,
 33.1208 +                    recorder->recorder_num);
 33.1209 +    gmyth_string_list_append_string(str_list, message);
 33.1210 +    gmyth_string_list_append_char_array(str_list, "FINISH_RECORDING");
 33.1211 +
 33.1212 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
 33.1213 +
 33.1214 +    if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
 33.1215 +        GString        *str = NULL;
 33.1216 +
 33.1217 +        if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL &&
 33.1218 +            strcmp(str->str, "ok") != 0) {
 33.1219 +            gint            is_rec =
 33.1220 +                gmyth_string_list_get_int(str_list, 0);
 33.1221 +
 33.1222 +            if (is_rec != 0)
 33.1223 +                ret = TRUE;
 33.1224 +            else
 33.1225 +                ret = FALSE;
 33.1226 +        }
 33.1227 +        g_string_free(str, TRUE);
 33.1228 +    }
 33.1229 +
 33.1230 +    gmyth_debug("%s, stream is %s finished!\n", ret ? "YES" : "NO",
 33.1231 +                ret ? "" : "NOT");
 33.1232 +    // g_static_mutex_unlock (&mutex);
 33.1233 +
 33.1234 +    if (str_list != NULL)
 33.1235 +        g_object_unref(str_list);
 33.1236 +
 33.1237 +    g_string_free(message, TRUE);
 33.1238 +
 33.1239 +    return ret;
 33.1240 +}
 33.1241 +
 33.1242 +
 33.1243 +/**
 33.1244 + * Stops playing the remote file.
 33.1245 + * 
 33.1246 + * @param recorder The GMythRecorder instance.
 33.1247 + * 
 33.1248 + * @return <code>true</code>, if the recording had been actually stopped.
 33.1249 + */
 33.1250 +gboolean
 33.1251 +gmyth_recorder_stop_playing(GMythRecorder * recorder)
 33.1252 +{
 33.1253 +    gboolean        ret = TRUE;
 33.1254 +
 33.1255 +    g_return_val_if_fail(recorder != NULL, FALSE);
 33.1256 +
 33.1257 +    GMythStringList *str_list = gmyth_string_list_new();
 33.1258 +    GString        *message = g_string_new("");
 33.1259 +
 33.1260 +    g_string_printf(message, "%s %d", GMYTHTV_RECORDER_HEADER,
 33.1261 +                    recorder->recorder_num);
 33.1262 +    gmyth_string_list_append_string(str_list, message);
 33.1263 +    gmyth_string_list_append_char_array(str_list, "STOP_PLAYING");
 33.1264 +
 33.1265 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
 33.1266 +
 33.1267 +    if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
 33.1268 +        GString        *str = NULL;
 33.1269 +
 33.1270 +        if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL &&
 33.1271 +            strcmp(str->str, "ok") != 0) {
 33.1272 +            gint            is_rec =
 33.1273 +                gmyth_string_list_get_int(str_list, 0);
 33.1274 +
 33.1275 +            if (is_rec != 0)
 33.1276 +                ret = TRUE;
 33.1277 +            else
 33.1278 +                ret = FALSE;
 33.1279 +        }
 33.1280 +        g_string_free(str, TRUE);
 33.1281 +    }
 33.1282 +
 33.1283 +    gmyth_debug("%s, stream is %s stopped!\n", ret ? "YES" : "NO",
 33.1284 +                ret ? "" : "NOT");
 33.1285 +
 33.1286 +    if (str_list != NULL)
 33.1287 +        g_object_unref(str_list);
 33.1288 +
 33.1289 +    g_string_free(message, TRUE);
 33.1290 +
 33.1291 +    return ret;
 33.1292 +}
 33.1293 +
 33.1294 +/**
 33.1295 + * Free the tuner responsible for recording this channel.
 33.1296 + * 
 33.1297 + * @param recorder The GMythRecorder instance.
 33.1298 + * 
 33.1299 + * @return <code>true</code>, if the tuner had been freed.
 33.1300 + */
 33.1301 +gboolean
 33.1302 +gmyth_recorder_free_tuner(GMythRecorder * recorder)
 33.1303 +{
 33.1304 +    gboolean        ret = TRUE;
 33.1305 +
 33.1306 +    g_return_val_if_fail(recorder != NULL, FALSE);
 33.1307 +
 33.1308 +    GMythStringList *str_list = gmyth_string_list_new();
 33.1309 +    GString        *message = g_string_new("");
 33.1310 +
 33.1311 +    g_string_printf(message, "%s %d", "FREE_TUNER",
 33.1312 +                    recorder->recorder_num);
 33.1313 +    gmyth_string_list_append_string(str_list, message);
 33.1314 +
 33.1315 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
 33.1316 +
 33.1317 +    if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
 33.1318 +        GString        *str = NULL;
 33.1319 +
 33.1320 +        if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL &&
 33.1321 +            g_ascii_strncasecmp(str->str, "ok", 2) != 0) {
 33.1322 +            gint            is_rec =
 33.1323 +                gmyth_string_list_get_int(str_list, 0);
 33.1324 +
 33.1325 +            if (is_rec != 0)
 33.1326 +                ret = TRUE;
 33.1327 +            else
 33.1328 +                ret = FALSE;
 33.1329 +        }
 33.1330 +        g_string_free(str, TRUE);
 33.1331 +    }
 33.1332 +
 33.1333 +    gmyth_debug("%s, tuner is %s freed!\n", ret ? "YES" : "NO",
 33.1334 +                ret ? "" : "NOT");
 33.1335 +
 33.1336 +    if (str_list != NULL)
 33.1337 +        g_object_unref(str_list);
 33.1338 +
 33.1339 +    g_string_free(message, TRUE);
 33.1340 +
 33.1341 +    return ret;
 33.1342 +}
 33.1343 +
 33.1344 +/**
 33.1345 + * Asks the MythTV backend server about the frame rate 
 33.1346 + * of this LiveTV instance.
 33.1347 + * 
 33.1348 + * @param recorder The GMythRecorder instance.
 33.1349 + * 
 33.1350 + * @return The framerate (double value) of the current video.
 33.1351 + */
 33.1352 +gdouble
 33.1353 +gmyth_recorder_get_framerate(GMythRecorder * recorder)
 33.1354 +{
 33.1355 +    gdouble         fr = 0.0f;
 33.1356 +    GString        *query = g_string_new(GMYTHTV_RECORDER_HEADER);
 33.1357 +
 33.1358 +    GMythStringList *str_list = gmyth_string_list_new();
 33.1359 +
 33.1360 +    g_mutex_lock(recorder->mutex);
 33.1361 +
 33.1362 +    g_string_append_printf(query, " %d", recorder->recorder_num);
 33.1363 +
 33.1364 +    gmyth_string_list_append_string(str_list, query);
 33.1365 +    gmyth_string_list_append_char_array(str_list, "GET_FRAMERATE");
 33.1366 +
 33.1367 +    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
 33.1368 +
 33.1369 +    if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
 33.1370 +        GString        *str = NULL;
 33.1371 +
 33.1372 +        if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL
 33.1373 +            && strstr(str->str, "bad") == NULL)
 33.1374 +            fr = g_ascii_strtod(str->str, NULL);
 33.1375 +
 33.1376 +        g_string_free(str, TRUE);
 33.1377 +    }
 33.1378 +#ifndef GMYTHTV_ENABLE_DEBUG
 33.1379 +    gmyth_debug("[%s] Got file position = %f\n", __FUNCTION__, fr);
 33.1380 +#endif
 33.1381 +
 33.1382 +    g_mutex_unlock(recorder->mutex);
 33.1383 +
 33.1384 +    if (str_list != NULL)
 33.1385 +        g_object_unref(str_list);
 33.1386 +
 33.1387 +    g_string_free(query, TRUE);
 33.1388 +
 33.1389 +    return fr;
 33.1390 +
 33.1391 +}
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/gmyth/gmyth/gmyth_recorder.h	Mon Feb 25 17:51:43 2008 +0000
    34.3 @@ -0,0 +1,162 @@
    34.4 +/**
    34.5 + * GMyth Library
    34.6 + *
    34.7 + * @file gmyth/gmyth_recorder.h
    34.8 + * 
    34.9 + * @brief <p> GMythRecorder defines functions for playing live tv.
   34.10 + *
   34.11 + * The remote encoder is used by gmyth_tvplayer to setup livetv. 
   34.12 + *
   34.13 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   34.14 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   34.15 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
   34.16 + *
   34.17 + * 
   34.18 + * This program is free software; you can redistribute it and/or modify
   34.19 + * it under the terms of the GNU Lesser General Public License as published by
   34.20 + * the Free Software Foundation; either version 2 of the License, or
   34.21 + * (at your option) any later version.
   34.22 + *
   34.23 + * This program is distributed in the hope that it will be useful,
   34.24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   34.25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   34.26 + * GNU General Public License for more details.
   34.27 + *
   34.28 + * You should have received a copy of the GNU Lesser General Public License
   34.29 + * along with this program; if not, write to the Free Software
   34.30 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   34.31 + */
   34.32 +
   34.33 +#ifndef __GMYTH_RECORDER_H__
   34.34 +#define __GMYTH_RECORDER_H__
   34.35 +
   34.36 +#include <glib-object.h>
   34.37 +
   34.38 +#include "gmyth_socket.h"
   34.39 +#include "gmyth_programinfo.h"
   34.40 +
   34.41 +#include <stdio.h>
   34.42 +#include <stdlib.h>
   34.43 +#include <string.h>
   34.44 +#include <netdb.h>
   34.45 +#include <sys/socket.h>
   34.46 +#include <unistd.h>
   34.47 +
   34.48 +G_BEGIN_DECLS
   34.49 +#define GMYTH_RECORDER_TYPE               (gmyth_recorder_get_type ())
   34.50 +#define GMYTH_RECORDER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_RECORDER_TYPE, GMythRecorder))
   34.51 +#define GMYTH_RECORDER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_RECORDER_TYPE, GMythRecorderClass))
   34.52 +#define IS_GMYTH_RECORDER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_RECORDER_TYPE))
   34.53 +#define IS_GMYTH_RECORDER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_RECORDER_TYPE))
   34.54 +#define GMYTH_RECORDER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_RECORDER_TYPE, GMythRecorderClass))
   34.55 +typedef struct _GMythRecorder GMythRecorder;
   34.56 +typedef struct _GMythRecorderClass GMythRecorderClass;
   34.57 +
   34.58 +struct _GMythRecorderClass {
   34.59 +    GObjectClass    parent_class;
   34.60 +
   34.61 +    /*
   34.62 +     * callbacks 
   34.63 +     */
   34.64 +    /*
   34.65 +     * no one for now 
   34.66 +     */
   34.67 +};
   34.68 +
   34.69 +struct _GMythRecorder {
   34.70 +    GObject         parent;
   34.71 +
   34.72 +    /*
   34.73 +     * socket descriptor 
   34.74 +     */
   34.75 +    GMythSocket    *myth_socket;
   34.76 +
   34.77 +    gint            recorder_num;
   34.78 +    GString        *hostname;
   34.79 +    gint            port;
   34.80 +
   34.81 +    GList          *progs_info_list;
   34.82 +
   34.83 +    GMutex         *mutex;
   34.84 +};
   34.85 +
   34.86 +typedef enum _GMythRecorderChannelChangeDirection {
   34.87 +    CHANNEL_DIRECTION_UP = 0,
   34.88 +    CHANNEL_DIRECTION_DOWN,
   34.89 +    CHANNEL_DIRECTION_FAVORITE,
   34.90 +    CHANNEL_DIRECTION_SAME
   34.91 +} GMythRecorderChannelChangeDirection;
   34.92 +
   34.93 +typedef enum _GMythRecorderBrowseDirection {
   34.94 +    BROWSE_DIRECTION_SAME = 0,  /* Stay in the same place */
   34.95 +    BROWSE_DIRECTION_UP,        /* Move up one slot (down one channel) */
   34.96 +    BROWSE_DIRECTION_DOWN,      /* Move down one slot (up one channel) */
   34.97 +    BROWSE_DIRECTION_LEFT,      /* Move left one slot (down one time slot) 
   34.98 +                                 */
   34.99 +    BROWSE_DIRECTION_RIGHT,     /* Move right one slot (up one time slot) */
  34.100 +    BROWSE_DIRECTION_FAVORITE   /* Move to the next favorite slot */
  34.101 +} GMythRecorderBrowseDirection;
  34.102 +
  34.103 +GType           gmyth_recorder_get_type(void);
  34.104 +
  34.105 +GMythRecorder  *gmyth_recorder_new(int num, GString * hostname,
  34.106 +                                   gshort port);
  34.107 +
  34.108 +void            gmyth_recorder_close(GMythRecorder * recorder);
  34.109 +
  34.110 +gboolean        gmyth_recorder_setup(GMythRecorder * recorder);
  34.111 +gboolean        gmyth_recorder_spawntv(GMythRecorder * recorder,
  34.112 +                                       GString * tvchain_id);
  34.113 +
  34.114 +gboolean        gmyth_recorder_spawntv_no_tvchain(GMythRecorder *
  34.115 +                                                  recorder);
  34.116 +
  34.117 +gboolean        gmyth_recorder_stop_livetv(GMythRecorder * recorder);
  34.118 +
  34.119 +gboolean        gmyth_recorder_send_frontend_ready_command(GMythRecorder *
  34.120 +                                                           recorder);
  34.121 +
  34.122 +gboolean        gmyth_recorder_check_channel(GMythRecorder * recorder,
  34.123 +                                             gint channel);
  34.124 +
  34.125 +gboolean        gmyth_recorder_check_channel_name(GMythRecorder * recorder,
  34.126 +                                                  gchar * channel);
  34.127 +
  34.128 +gboolean        gmyth_recorder_set_channel(GMythRecorder * recorder,
  34.129 +                                           gint channel);
  34.130 +
  34.131 +gboolean        gmyth_recorder_set_channel_name(GMythRecorder * recorder,
  34.132 +                                                const gchar * channel);
  34.133 +
  34.134 +gboolean        gmyth_recorder_change_channel(GMythRecorder * recorder, const
  34.135 +                                              GMythRecorderChannelChangeDirection
  34.136 +                                              direction);
  34.137 +
  34.138 +GList          *gmyth_recorder_get_channel_list(GMythRecorder * recorder);
  34.139 +
  34.140 +gboolean        gmyth_recorder_pause_recording(GMythRecorder * recorder);
  34.141 +
  34.142 +GMythProgramInfo *gmyth_recorder_get_current_program_info(GMythRecorder *
  34.143 +                                                          recorder);
  34.144 +
  34.145 +GMythProgramInfo *gmyth_recorder_get_next_program_info(GMythRecorder *
  34.146 +                                                       recorder, const
  34.147 +                                                       GMythRecorderBrowseDirection
  34.148 +                                                       direction);
  34.149 +
  34.150 +GMythRecorder  *gmyth_recorder_get_recorder_from_num(gint rec_id);
  34.151 +
  34.152 +gint64          gmyth_recorder_get_file_position(GMythRecorder * recorder);
  34.153 +
  34.154 +gboolean        gmyth_recorder_is_recording(GMythRecorder * recorder);
  34.155 +
  34.156 +gboolean        gmyth_recorder_finish_recording(GMythRecorder * recorder);
  34.157 +
  34.158 +gboolean        gmyth_recorder_stop_playing(GMythRecorder * recorder);
  34.159 +
  34.160 +gboolean        gmyth_recorder_free_tuner(GMythRecorder * recorder);
  34.161 +
  34.162 +gdouble         gmyth_recorder_get_framerate(GMythRecorder * recorder);
  34.163 +
  34.164 +G_END_DECLS
  34.165 +#endif                          /* __GMYTH_REMOTE_ENCODER_H__ */
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/gmyth/gmyth/gmyth_recprofile.c	Mon Feb 25 17:51:43 2008 +0000
    35.3 @@ -0,0 +1,264 @@
    35.4 +/**
    35.5 + * GMyth Library
    35.6 + * 
    35.7 + * @file gmyth/gmyth_recprofile.c
    35.8 + * 
    35.9 + * @brief <p> This file contains the recprofile class.
   35.10 + *
   35.11 + * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   35.12 + * @author Artur Duque de Souza <artur.souza@indt.org.br>
   35.13 + *
   35.14 + * This program is free software; you can redistribute it and/or modify
   35.15 + * it under the terms of the GNU Lesser General Public License as published by
   35.16 + * the Free Software Foundation; either version 2 of the License, or
   35.17 + * (at your option) any later version.
   35.18 + *
   35.19 + * This program is distributed in the hope that it will be useful,
   35.20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   35.21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   35.22 + * GNU General Public License for more details.
   35.23 + *
   35.24 + * You should have received a copy of the GNU Lesser General Public License
   35.25 + * along with this program; if not, write to the Free Software
   35.26 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   35.27 + */
   35.28 +
   35.29 +
   35.30 +#ifdef HAVE_CONFIG_H
   35.31 +#include "config.h"
   35.32 +#endif
   35.33 +
   35.34 +#include <stdlib.h>
   35.35 +#include <string.h>
   35.36 +#include <assert.h>
   35.37 +
   35.38 +#include "gmyth_recprofile.h"
   35.39 +#include "gmyth_util.h"
   35.40 +#include "gmyth_debug.h"
   35.41 +#include "gmyth_http.h"
   35.42 +
   35.43 +static void     gmyth_recprofile_class_init(GMythRecProfileClass * klass);
   35.44 +static void     gmyth_recprofile_init(GMythRecProfile * object);
   35.45 +
   35.46 +static void     gmyth_recprofile_dispose(GObject * object);
   35.47 +static void     gmyth_recprofile_finalize(GObject * object);
   35.48 +
   35.49 +G_DEFINE_TYPE(GMythRecProfile, gmyth_recprofile, G_TYPE_OBJECT)
   35.50 +    static void     gmyth_recprofile_class_init(GMythRecProfileClass *
   35.51 +                                                klass)
   35.52 +{
   35.53 +    GObjectClass   *gobject_class = G_OBJECT_CLASS(klass);
   35.54 +
   35.55 +    gobject_class->dispose = gmyth_recprofile_dispose;
   35.56 +    gobject_class->finalize = gmyth_recprofile_finalize;
   35.57 +}
   35.58 +
   35.59 +static void
   35.60 +gmyth_recprofile_init(GMythRecProfile * recprofile)
   35.61 +{
   35.62 +}
   35.63 +
   35.64 +static void
   35.65 +gmyth_recprofile_dispose(GObject * object)
   35.66 +{
   35.67 +    GMythRecProfile *recprofile = GMYTH_RECPROFILE(object);
   35.68 +
   35.69 +    if (recprofile->name)
   35.70 +        g_free(recprofile->name);
   35.71 +
   35.72 +    if (recprofile->group)
   35.73 +        g_free(recprofile->group);
   35.74 +
   35.75 +    if (recprofile->vcodec)
   35.76 +        g_free(recprofile->vcodec);
   35.77 +
   35.78 +    if (recprofile->acodec)
   35.79 +        g_free(recprofile->acodec);
   35.80 +
   35.81 +    if (recprofile->options)
   35.82 +        g_free(recprofile->options);
   35.83 +
   35.84 +    G_OBJECT_CLASS(gmyth_recprofile_parent_class)->dispose(object);
   35.85 +}
   35.86 +
   35.87 +static void
   35.88 +gmyth_recprofile_finalize(GObject * object)
   35.89 +{
   35.90 +    g_signal_handlers_destroy(object);
   35.91 +    G_OBJECT_CLASS(gmyth_recprofile_parent_class)->finalize(object);
   35.92 +}
   35.93 +
   35.94 +/**
   35.95 + * Creates a new instance of GMythRecProfile.
   35.96 + * 
   35.97 + * @return a new instance of GMythRecProfile.
   35.98 + **/
   35.99 +GMythRecProfile *
  35.100 +gmyth_recprofile_new(void)
  35.101 +{
  35.102 +    GMythRecProfile *recprofile = GMYTH_RECPROFILE
  35.103 +        (g_object_new(GMYTH_RECPROFILE_TYPE, NULL));
  35.104 +
  35.105 +    recprofile->id = 0;
  35.106 +    recprofile->name = NULL;
  35.107 +    recprofile->group = NULL;
  35.108 +    recprofile->vcodec = NULL;
  35.109 +    recprofile->acodec = NULL;
  35.110 +    recprofile->options = NULL;
  35.111 +
  35.112 +    return recprofile;
  35.113 +}
  35.114 +
  35.115 +
  35.116 +/**
  35.117 + *
  35.118 + * gmyth_recprofile_get_profile_list
  35.119 + * @brief get profile list from the backend
  35.120 + * @param backend_info GMythBackendInfo*
  35.121 + * @return GSList
  35.122 + *
  35.123 + **/
  35.124 +GSList         *
  35.125 +gmyth_recprofile_get_profile_list(GMythBackendInfo * backend_info)
  35.126 +{
  35.127 +    return gmyth_http_retrieve_rec_profiles(backend_info, "Transcoders");
  35.128 +}
  35.129 +
  35.130 +/**
  35.131 + *
  35.132 + * gmyth_recprofile_create_profile
  35.133 + * @brief get profile list from the backend
  35.134 + * @param backend_info GMythBackendInfo*
  35.135 + * @param profile GMythRecProfile*
  35.136 + * @return gint representing the result
  35.137 + *
  35.138 + **/
  35.139 +gint
  35.140 +gmyth_recprofile_create_profile(GMythBackendInfo * backend_info,
  35.141 +                                GMythRecProfile * profile)
  35.142 +{
  35.143 +    return gmyth_http_create_rec_profile(backend_info, profile);
  35.144 +}
  35.145 +
  35.146 +/**
  35.147 + *
  35.148 + * gmyth_recprofile_del_profile
  35.149 + * @brief del profile from the backend
  35.150 + * @param backend_info GMythBackendInfo*
  35.151 + * @param id profile's id
  35.152 + * @return gint representing the result
  35.153 + *
  35.154 + **/
  35.155 +gint
  35.156 +gmyth_recprofile_del_profile_list(GMythBackendInfo * backend_info, gint id)
  35.157 +{
  35.158 +    return gmyth_http_del_rec_profile(backend_info, id);
  35.159 +}
  35.160 +
  35.161 +/**
  35.162 + *
  35.163 + * gmyth_recprofile_set_id
  35.164 + * @brief set recprofile's id
  35.165 + * @param rec GMythRecProfile*
  35.166 + * @param id profile's id
  35.167 + * @return gint representing the result
  35.168 + *
  35.169 + **/
  35.170 +gint
  35.171 +gmyth_recprofile_set_id(GMythRecProfile * rec, gint id)
  35.172 +{
  35.173 +    rec->id = id;
  35.174 +    return 0;
  35.175 +}
  35.176 +
  35.177 +/**
  35.178 + *
  35.179 + * gmyth_recprofile_set
  35.180 + * @brief set recprofile's property
  35.181 + * @param rec GMythRecProfile*
  35.182 + * @param member the member you want to modify
  35.183 + * @param value the value
  35.184 + * @return gint representing the result
  35.185 + *
  35.186 + **/
  35.187 +gint
  35.188 +gmyth_recprofile_set(GMythRecProfile * rec, gchar * member, gchar * value)
  35.189 +{
  35.190 +    int             ret = 0;
  35.191 +
  35.192 +    if (value != NULL) {
  35.193 +        if (g_ascii_strcasecmp(member, "name") == 0)
  35.194 +            rec->name = g_strndup(value, strlen(value));
  35.195 +        else if (g_ascii_strcasecmp(member, "group") == 0)
  35.196 +            rec->group = g_strndup(value, strlen(value));
  35.197 +        else if (g_ascii_strcasecmp(member, "vcodec") == 0)
  35.198 +            rec->vcodec = g_strndup(value, strlen(value));
  35.199 +        else if (g_ascii_strcasecmp(member, "acodec") == 0)
  35.200 +            rec->acodec = g_strndup(value, strlen(value));
  35.201 +        else
  35.202 +            ret = -1;
  35.203 +    } else
  35.204 +        ret = -1;
  35.205 +
  35.206 +    return ret;
  35.207 +}
  35.208 +
  35.209 +/**
  35.210 + *
  35.211 + * gmyth_recprofile_set_name
  35.212 + * @brief set recprofile's name
  35.213 + * @param rec GMythRecProfile*
  35.214 + * @param name profile's name
  35.215 + * @return gint representing the result
  35.216 + *
  35.217 + **/
  35.218 +gint
  35.219 +gmyth_recprofile_set_name(GMythRecProfile * rec, gchar * name)
  35.220 +{
  35.221 +    return gmyth_recprofile_set(rec, "name", name);
  35.222 +}
  35.223 +
  35.224 +/**
  35.225 + *
  35.226 + * gmyth_recprofile_set_group
  35.227 + * @brief set recprofile's group
  35.228 + * @param rec GMythRecProfile*
  35.229 + * @param group profile's group
  35.230 + * @return gint representing the result
  35.231 + *
  35.232 + **/
  35.233 +gint
  35.234 +gmyth_recprofile_set_group(GMythRecProfile * rec, gchar * group)
  35.235 +{
  35.236 +    return gmyth_recprofile_set(rec, "group", group);
  35.237 +}
  35.238 +
  35.239 +/**
  35.240 + *
  35.241 + * gmyth_recprofile_set_vcodec
  35.242 + * @brief set recprofile's vcodec
  35.243 + * @param rec GMythRecProfile*
  35.244 + * @param vcodec profile's vcodec
  35.245 + * @return gint representing the result
  35.246 + *
  35.247 + **/
  35.248 +gint
  35.249 +gmyth_recprofile_set_vcodec(GMythRecProfile * rec, gchar * vcodec)
  35.250 +{
  35.251 +    return gmyth_recprofile_set(rec, "vcodec", vcodec);
  35.252 +}
  35.253 +
  35.254 +/**
  35.255 + *
  35.256 + * gmyth_recprofile_set_acodec
  35.257 + * @brief set recprofile's acodec
  35.258 + * @param rec GMythRecProfile*
  35.259 + * @param acodec profile's acodec
  35.260 + * @return gint representing the result
  35.261 + *
  35.262 + **/
  35.263 +gint
  35.264 +gmyth_recprofile_set_acodec(GMythRecProfile * rec, gchar * acodec)
  35.265 +{
  35.266 +    return gmyth_recprofile_set(rec, "acodec", acodec);
  35.267 +}
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/gmyth/gmyth/gmyth_recprofile.h	Mon Feb 25 17:51:43 2008 +0000
    36.3 @@ -0,0 +1,123 @@
    36.4 +/**
    36.5 + * GMyth Library
    36.6 + * 
    36.7 + * @file gmyth/gmyth_recprofile.h
    36.8 + * 
    36.9 + * @brief <p> This file contains the recprofile class.
   36.10 + *
   36.11 + * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   36.12 + * @author Artur Duque de Souza <artur.souza@indt.org.br>
   36.13 + *
   36.14 + * 
   36.15 + * This program is free software; you can redistribute it and/or modify
   36.16 + * it under the terms of the GNU Lesser General Public License as published by
   36.17 + * the Free Software Foundation; either version 2 of the License, or
   36.18 + * (at your option) any later version.
   36.19 + *
   36.20 + * This program is distributed in the hope that it will be useful,
   36.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   36.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   36.23 + * GNU General Public License for more details.
   36.24 + *
   36.25 + * You should have received a copy of the GNU Lesser General Public License
   36.26 + * along with this program; if not, write to the Free Software
   36.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   36.28 + */
   36.29 +
   36.30 +#ifndef _GMYTH_RECPROFILE_H
   36.31 +#define _GMYTH_RECPROFILE_H
   36.32 +
   36.33 +#include <glib.h>
   36.34 +#include <glib-object.h>
   36.35 +
   36.36 +#include "gmyth_stringlist.h"
   36.37 +#include "gmyth_backendinfo.h"
   36.38 +#include "gmyth_socket.h"
   36.39 +
   36.40 +G_BEGIN_DECLS
   36.41 +#define GMYTH_RECPROFILE_TYPE               (gmyth_recprofile_get_type ())
   36.42 +#define GMYTH_RECPROFILE(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_RECPROFILE_TYPE, GMythRecProfile))
   36.43 +#define GMYTH_RECPROFILE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_RECPROFILE_TYPE, GMythRecProfileClass))
   36.44 +#define IS_GMYTH_RECPROFILE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_RECPROFILE_TYPE))
   36.45 +#define IS_GMYTH_RECPROFILE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_RECPROFILE_TYPE))
   36.46 +#define GMYTH_RECPROFILE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_RECPROFILE_TYPE, GMythRecProfileClass))
   36.47 +typedef struct _Options Options;
   36.48 +typedef struct _GMythRecProfile GMythRecProfile;
   36.49 +typedef struct _GMythRecProfileClass GMythRecProfileClass;
   36.50 +
   36.51 +struct _GMythRecProfileClass {
   36.52 +    GObjectClass    parent_class;
   36.53 +    gint            teste;
   36.54 +    /*
   36.55 +     * callbacks 
   36.56 +     */
   36.57 +};
   36.58 +
   36.59 +struct _GMythRecProfile {
   36.60 +    gint            id;
   36.61 +    gchar          *name;
   36.62 +    gchar          *group;
   36.63 +    gchar          *vcodec;
   36.64 +    gchar          *acodec;
   36.65 +    Options        *options;
   36.66 +};
   36.67 +
   36.68 +struct _Options {
   36.69 +    gint            transcodelossless;
   36.70 +    gint            transcoderesize;
   36.71 +    gint            width;
   36.72 +    gint            height;
   36.73 +    gint            rtjpegquality;
   36.74 +    gint            rtjpeglumafilter;
   36.75 +    gint            rtjpegchromafilter;
   36.76 +    gint            mpeg4bitrate;
   36.77 +    gint            mpeg4maxquality;
   36.78 +    gint            mpeg4minquality;
   36.79 +    gint            mpeg4qualdiff;
   36.80 +    gint            mpeg4scalebitrate;
   36.81 +    gint            mpeg4optionvhq;
   36.82 +    gint            mpeg4option4mv;
   36.83 +    gint            mpeg4optionidct;
   36.84 +    gint            mpeg4optionime;
   36.85 +    gint            hardwaremjpegquality;
   36.86 +    gint            hardwaremjpeghdecimation;
   36.87 +    gint            hardwaremjpegvdecimation;
   36.88 +    gchar          *mpeg2streamtype;
   36.89 +    gchar          *mpeg2aspectratio;
   36.90 +    gint            mpeg2bitrate;
   36.91 +    gint            mpeg2maxbitrate;
   36.92 +    gint            samplerate;
   36.93 +    gint            mp3quality;
   36.94 +    gint            volume;
   36.95 +    gchar          *mpeg2audtype;
   36.96 +    gint            mpeg2audbitratel1;
   36.97 +    gint            mpeg2audbitratel2;
   36.98 +    gint            mpeg2audvolume;
   36.99 +};
  36.100 +
  36.101 +GType           gmyth_recprofile_type(void);
  36.102 +
  36.103 +GMythRecProfile *gmyth_recprofile_new(void);
  36.104 +
  36.105 +GSList         *gmyth_recprofile_get_profile_list(GMythBackendInfo *
  36.106 +                                                  backend_info);
  36.107 +
  36.108 +gint            gmyth_recprofile_create_profile(GMythBackendInfo *
  36.109 +                                                backend_info,
  36.110 +                                                GMythRecProfile * profile);
  36.111 +
  36.112 +gint            gmyth_recprofile_del_profile_list(GMythBackendInfo *
  36.113 +                                                  backend_info, gint id);
  36.114 +
  36.115 +gint            gmyth_recprofile_set_acodec(GMythRecProfile * rec,
  36.116 +                                            gchar * acodec);
  36.117 +gint            gmyth_recprofile_set_vcodec(GMythRecProfile * rec,
  36.118 +                                            gchar * vcodec);
  36.119 +gint            gmyth_recprofile_set_group(GMythRecProfile * rec,
  36.120 +                                           gchar * group);
  36.121 +gint            gmyth_recprofile_set_name(GMythRecProfile * rec,
  36.122 +                                          gchar * name);
  36.123 +gint            gmyth_recprofile_set_id(GMythRecProfile * rec, gint id);
  36.124 +
  36.125 +G_END_DECLS
  36.126 +#endif /*_GMYTH_RECPROFILE_H*/
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/gmyth/gmyth/gmyth_remote_util.c	Mon Feb 25 17:51:43 2008 +0000
    37.3 @@ -0,0 +1,126 @@
    37.4 +/**
    37.5 + * GMyth Library
    37.6 + *
    37.7 + * @file gmyth/gmyth_remote_util.c
    37.8 + * 
    37.9 + * @brief <p> This component provides utility functions for accessing remote data.
   37.10 + *
   37.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   37.12 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   37.13 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
   37.14 + *
   37.15 + * 
   37.16 + * This program is free software; you can redistribute it and/or modify
   37.17 + * it under the terms of the GNU Lesser General Public License as published by
   37.18 + * the Free Software Foundation; either version 2 of the License, or
   37.19 + * (at your option) any later version.
   37.20 + *
   37.21 + * This program is distributed in the hope that it will be useful,
   37.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   37.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   37.24 + * GNU General Public License for more details.
   37.25 + *
   37.26 + * You should have received a copy of the GNU Lesser General Public License
   37.27 + * along with this program; if not, write to the Free Software
   37.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   37.29 + */
   37.30 +
   37.31 +#ifdef HAVE_CONFIG_H
   37.32 +#include "config.h"
   37.33 +#endif
   37.34 +
   37.35 +#include "gmyth_remote_util.h"
   37.36 +
   37.37 +#include "gmyth_recorder.h"
   37.38 +#include "gmyth_stringlist.h"
   37.39 +#include "gmyth_debug.h"
   37.40 +
   37.41 +/** 
   37.42 + * Requests the Mythtv backend for a free remote recorder.
   37.43 + * 
   37.44 + * @param socket The socket instance where to send the command.
   37.45 + * @param curr The recorder index, or -1 to consider the first one.
   37.46 + * 
   37.47 + * @return the remote encoder instance available, or NULL if any error happens.
   37.48 + */
   37.49 +GMythRecorder  *
   37.50 +remote_request_next_free_recorder(GMythSocket * socket, gint curr)
   37.51 +{
   37.52 +    GMythRecorder  *recorder = NULL;
   37.53 +    GString        *hostname;
   37.54 +    gint            num,
   37.55 +                    port;
   37.56 +
   37.57 +    GMythStringList *strlist = gmyth_string_list_new();
   37.58 +
   37.59 +    gmyth_debug("[%s] Request next free recorder in the backend",
   37.60 +                __FUNCTION__);
   37.61 +
   37.62 +    gmyth_string_list_append_char_array(strlist, "GET_NEXT_FREE_RECORDER");
   37.63 +    gmyth_string_list_append_int(strlist, curr);
   37.64 +
   37.65 +    if (!gmyth_socket_sendreceive_stringlist(socket, strlist)) {
   37.66 +        g_warning("GET_NEXT_FREE_RECORDER request error!\n");
   37.67 +        return NULL;
   37.68 +    }
   37.69 +
   37.70 +    num = gmyth_string_list_get_int(strlist, 0);
   37.71 +    hostname = gmyth_string_list_get_string(strlist, 1);
   37.72 +    port = gmyth_string_list_get_int(strlist, 2);
   37.73 +
   37.74 +    if (num < 0 || port < 0)
   37.75 +        goto clean_up;
   37.76 +
   37.77 +    gmyth_debug
   37.78 +        ("[%s] Free recorder info received: num: %d, hostname: %s, port: %d",
   37.79 +         __FUNCTION__, num, hostname->str, port);
   37.80 +
   37.81 +    recorder = gmyth_recorder_new(num, hostname, port);
   37.82 +
   37.83 +  clean_up:
   37.84 +
   37.85 +    g_string_free(hostname, TRUE);
   37.86 +    g_object_unref(strlist);
   37.87 +
   37.88 +    return recorder;
   37.89 +}
   37.90 +
   37.91 +/** 
   37.92 + * Requests the Mythtv backend for the number of free remote recorders.
   37.93 + * 
   37.94 + * @param socket The socket instance where to send the command.
   37.95 + * 
   37.96 + * @return the number of remote encoders instance available, or 0 if no one is actually free..
   37.97 + */
   37.98 +gint
   37.99 +gmyth_remote_util_get_free_recorder_count(GMythSocket * socket)
  37.100 +{
  37.101 +    gint            num_recs = 0;
  37.102 +
  37.103 +    GMythStringList *strlist = gmyth_string_list_new();
  37.104 +
  37.105 +    gmyth_debug("[%s] Request next free recorder in the backend",
  37.106 +                __FUNCTION__);
  37.107 +
  37.108 +    gmyth_string_list_append_char_array(strlist,
  37.109 +                                        "GET_FREE_RECORDER_COUNT");
  37.110 +
  37.111 +    if (!gmyth_socket_sendreceive_stringlist(socket, strlist)) {
  37.112 +        gmyth_debug("GET_FREE_RECORDER_COUNT request error!");
  37.113 +        return 0;
  37.114 +    }
  37.115 +
  37.116 +    num_recs = gmyth_string_list_get_int(strlist, 0);
  37.117 +
  37.118 +    if (num_recs < 0)
  37.119 +        goto clean_up;
  37.120 +
  37.121 +    gmyth_debug("[%s] Free recorder info received: num recorders: %d",
  37.122 +                __FUNCTION__, num_recs);
  37.123 +
  37.124 +  clean_up:
  37.125 +
  37.126 +    g_object_unref(strlist);
  37.127 +
  37.128 +    return num_recs;
  37.129 +}
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/gmyth/gmyth/gmyth_remote_util.h	Mon Feb 25 17:51:43 2008 +0000
    38.3 @@ -0,0 +1,41 @@
    38.4 +/**
    38.5 + * GMyth Library
    38.6 + *
    38.7 + * @file gmyth/gmyth_remote_util.h
    38.8 + * 
    38.9 + * @brief <p> This component provides utility functions for accessing remote data.
   38.10 + *
   38.11 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   38.12 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   38.13 + *
   38.14 + * 
   38.15 + * This program is free software; you can redistribute it and/or modify
   38.16 + * it under the terms of the GNU Lesser General Public License as published by
   38.17 + * the Free Software Foundation; either version 2 of the License, or
   38.18 + * (at your option) any later version.
   38.19 + *
   38.20 + * This program is distributed in the hope that it will be useful,
   38.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   38.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   38.23 + * GNU General Public License for more details.
   38.24 + *
   38.25 + * You should have received a copy of the GNU Lesser General Public License
   38.26 + * along with this program; if not, write to the Free Software
   38.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   38.28 + */
   38.29 +
   38.30 +#ifndef __REMOTE_UTIL_H__
   38.31 +#define __REMOTE_UTIL_H__
   38.32 +
   38.33 +#include <glib.h>
   38.34 +#include "gmyth_recorder.h"
   38.35 +#include "gmyth_socket.h"
   38.36 +
   38.37 +G_BEGIN_DECLS
   38.38 +    GMythRecorder * remote_request_next_free_recorder(GMythSocket * socket,
   38.39 +                                                      gint curr);
   38.40 +gint            gmyth_remote_util_get_free_recorder_count(GMythSocket *
   38.41 +                                                          socket);
   38.42 +
   38.43 +G_END_DECLS
   38.44 +#endif
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/gmyth/gmyth/gmyth_scheduler.c	Mon Feb 25 17:51:43 2008 +0000
    39.3 @@ -0,0 +1,1266 @@
    39.4 +/**
    39.5 + * GMyth Library
    39.6 + *
    39.7 + * @file gmyth/gmyth_scheduler.c
    39.8 + *
    39.9 + * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
   39.10 + * and modifying the recorded content.
   39.11 + *
   39.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   39.13 + * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
   39.14 + *
   39.15 + *
   39.16 + * This program is free software; you can redistribute it and/or modify
   39.17 + * it under the terms of the GNU Lesser General Public License as published by
   39.18 + * the Free Software Foundation; either version 2 of the License, or
   39.19 + * (at your option) any later version.
   39.20 + *
   39.21 + * This program is distributed in the hope that it will be useful,
   39.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   39.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   39.24 + * GNU General Public License for more details.
   39.25 + *
   39.26 + * You should have received a copy of the GNU Lesser General Public License
   39.27 + * along with this program; if not, write to the Free Software
   39.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   39.29 + */
   39.30 +
   39.31 +#ifdef HAVE_CONFIG_H
   39.32 +#include "config.h"
   39.33 +#endif
   39.34 +
   39.35 +#include <assert.h>
   39.36 +
   39.37 +#include <glib.h>
   39.38 +#include <glib/gprintf.h>
   39.39 +
   39.40 +#include "gmyth_scheduler.h"
   39.41 +#include "gmyth_util.h"
   39.42 +#include "gmyth_query.h"
   39.43 +#include "gmyth_socket.h"
   39.44 +#include "gmyth_debug.h"
   39.45 +
   39.46 +static void     gmyth_scheduler_class_init(GMythSchedulerClass * klass);
   39.47 +static void     gmyth_scheduler_init(GMythScheduler * object);
   39.48 +
   39.49 +static void     gmyth_scheduler_dispose(GObject * object);
   39.50 +static void     gmyth_scheduler_finalize(GObject * object);
   39.51 +
   39.52 +static gboolean update_backend(GMythScheduler * scheduler, gint record_id);
   39.53 +
   39.54 +G_DEFINE_TYPE(GMythScheduler, gmyth_scheduler, G_TYPE_OBJECT)
   39.55 +    static void     gmyth_scheduler_class_init(GMythSchedulerClass * klass)
   39.56 +{
   39.57 +    GObjectClass   *gobject_class;
   39.58 +
   39.59 +    gobject_class = (GObjectClass *) klass;
   39.60 +
   39.61 +    gobject_class->dispose = gmyth_scheduler_dispose;
   39.62 +    gobject_class->finalize = gmyth_scheduler_finalize;
   39.63 +}
   39.64 +
   39.65 +static void
   39.66 +gmyth_scheduler_init(GMythScheduler * sched)
   39.67 +{
   39.68 +    sched->recordid = 0;
   39.69 +    sched->type = 0;
   39.70 +    sched->search = 0;
   39.71 +    sched->profile = g_string_new("");
   39.72 +
   39.73 +    sched->dupin = 0;
   39.74 +    sched->dupmethod = 0;
   39.75 +    sched->autoexpire = 0;
   39.76 +    sched->autotranscode = 0;
   39.77 +    sched->transcoder = 0;
   39.78 +
   39.79 +    sched->autocommflag = 0;
   39.80 +    sched->autouserjob1 = 0;
   39.81 +    sched->autouserjob2 = 0;
   39.82 +    sched->autouserjob3 = 0;
   39.83 +    sched->autouserjob4 = 0;
   39.84 +
   39.85 +    sched->startoffset = 0;
   39.86 +    sched->endoffset = 0;
   39.87 +    sched->maxepisodes = 0;
   39.88 +    sched->maxnewest = 0;
   39.89 +
   39.90 +    sched->recpriority = 0;
   39.91 +    sched->recgroup = g_string_new("");
   39.92 +    sched->playgroup = g_string_new("");
   39.93 +
   39.94 +    sched->prefinput = 0;
   39.95 +    sched->inactive = 0;
   39.96 +
   39.97 +    sched->search_type = g_string_new("");
   39.98 +    sched->search_what = g_string_new("");
   39.99 +
  39.100 +    sched->msqlquery = gmyth_query_new();
  39.101 +}
  39.102 +
  39.103 +static void
  39.104 +gmyth_scheduler_dispose(GObject * object)
  39.105 +{
  39.106 +    GMythScheduler *scheduler = GMYTH_SCHEDULER(object);
  39.107 +
  39.108 +    if (scheduler->backend_info) {
  39.109 +        g_object_unref(scheduler->backend_info);
  39.110 +        scheduler->backend_info = NULL;
  39.111 +    }
  39.112 +
  39.113 +    if (scheduler->msqlquery) {
  39.114 +        g_object_unref(scheduler->msqlquery);
  39.115 +        scheduler->msqlquery = NULL;
  39.116 +    }
  39.117 +
  39.118 +    g_string_free(scheduler->profile, TRUE);
  39.119 +    g_string_free(scheduler->recgroup, TRUE);
  39.120 +    g_string_free(scheduler->playgroup, TRUE);
  39.121 +    g_string_free(scheduler->search_type, TRUE);
  39.122 +    g_string_free(scheduler->search_what, TRUE);
  39.123 +
  39.124 +    G_OBJECT_CLASS(gmyth_scheduler_parent_class)->dispose(object);
  39.125 +}
  39.126 +
  39.127 +static void
  39.128 +gmyth_scheduler_finalize(GObject * object)
  39.129 +{
  39.130 +    g_signal_handlers_destroy(object);
  39.131 +
  39.132 +    G_OBJECT_CLASS(gmyth_scheduler_parent_class)->finalize(object);
  39.133 +}
  39.134 +
  39.135 +/** Creates a new instance of GMythScheduler.
  39.136 + * 
  39.137 + * @return a new instance of GMythScheduler.
  39.138 + */
  39.139 +GMythScheduler *
  39.140 +gmyth_scheduler_new()
  39.141 +{
  39.142 +    GMythScheduler *scheduler =
  39.143 +        GMYTH_SCHEDULER(g_object_new(GMYTH_SCHEDULER_TYPE, NULL));
  39.144 +
  39.145 +    return scheduler;
  39.146 +}
  39.147 +
  39.148 +gboolean
  39.149 +gmyth_scheduler_connect(GMythScheduler * scheduler,
  39.150 +                        GMythBackendInfo * backend_info)
  39.151 +{
  39.152 +    return gmyth_scheduler_connect_with_timeout(scheduler, backend_info,
  39.153 +                                                0);
  39.154 +}
  39.155 +
  39.156 +/** Connects to the Mysql database in the backend. The backend address
  39.157 + * is loaded from the GMythSettings instance.
  39.158 + *
  39.159 + * @param scheduler the GMythScheduler instance to be connected.
  39.160 + * @return true if connection was success, false if failed.
  39.161 + */
  39.162 +gboolean
  39.163 +gmyth_scheduler_connect_with_timeout(GMythScheduler * scheduler,
  39.164 +                                     GMythBackendInfo * backend_info,
  39.165 +                                     guint timeout)
  39.166 +{
  39.167 +    assert(scheduler);
  39.168 +    g_return_val_if_fail(backend_info != NULL, FALSE);
  39.169 +
  39.170 +    if (scheduler->backend_info)
  39.171 +        g_object_unref(scheduler->backend_info);
  39.172 +
  39.173 +    scheduler->backend_info = g_object_ref(backend_info);
  39.174 +
  39.175 +    if (scheduler->msqlquery == NULL) {
  39.176 +        g_warning("[%s] GMythScheduler db initializing", __FUNCTION__);
  39.177 +        scheduler->msqlquery = gmyth_query_new();
  39.178 +    }
  39.179 +
  39.180 +    if (!gmyth_query_connect_with_timeout(scheduler->msqlquery,
  39.181 +                                          scheduler->backend_info,
  39.182 +                                          timeout)) {
  39.183 +        g_warning("[%s] Error while connecting to db", __FUNCTION__);
  39.184 +        return FALSE;
  39.185 +    }
  39.186 +
  39.187 +    return TRUE;
  39.188 +}
  39.189 +
  39.190 +/** Disconnects from the Mysql database in the backend.
  39.191 + *
  39.192 + * @param scheduler the GMythScheduler instance to be disconnected
  39.193 + * @return true if disconnection was success, false if failed.
  39.194 + */
  39.195 +gboolean
  39.196 +gmyth_scheduler_disconnect(GMythScheduler * scheduler)
  39.197 +{
  39.198 +    assert(scheduler);
  39.199 +
  39.200 +    if (scheduler->msqlquery != NULL) {
  39.201 +        gmyth_query_disconnect(scheduler->msqlquery);
  39.202 +    }
  39.203 +
  39.204 +    return TRUE;
  39.205 +}
  39.206 +
  39.207 +/** Retrieves from the backend Mysql database the list of recording schedules.
  39.208 + * 
  39.209 + * @param scheduler The GMythScheduler instance.
  39.210 + * @param schedule_list the GList pointer to be filled with the loaded list of ScheduleInfo items.
  39.211 + * @return The amount of schedules retrieved from database, or -1 if error.
  39.212 + */
  39.213 +gint
  39.214 +gmyth_scheduler_get_schedule_list(GMythScheduler * scheduler,
  39.215 +                                  GList ** schedule_list)
  39.216 +{
  39.217 +    ScheduleInfo   *schedule;
  39.218 +    MYSQL_RES      *msql_res;
  39.219 +    GString        *query_str = g_string_new("");
  39.220 +    gchar          *date_time = NULL;
  39.221 +
  39.222 +    assert(scheduler);
  39.223 +
  39.224 +    g_string_printf(query_str,
  39.225 +                    "SELECT recordid,programid,chanid,starttime,startdate,"
  39.226 +                    "endtime,enddate,title,subtitle,description,category,type,parentid,seriesid FROM record;");
  39.227 +
  39.228 +    if (scheduler->msqlquery == NULL) {
  39.229 +        g_warning("[%s] Scheduler db connection not initialized",
  39.230 +                  __FUNCTION__);
  39.231 +        return -1;
  39.232 +    }
  39.233 +    msql_res =
  39.234 +        gmyth_query_process_statement(scheduler->msqlquery,
  39.235 +                                      query_str->str);
  39.236 +
  39.237 +    if (msql_res == NULL) {
  39.238 +        g_warning("DB retrieval of schedule list failed");
  39.239 +        return -1;
  39.240 +    } else {
  39.241 +        MYSQL_ROW       row;
  39.242 +
  39.243 +        *schedule_list = NULL;
  39.244 +
  39.245 +        while ((row = mysql_fetch_row(msql_res)) != NULL) {
  39.246 +            schedule = g_new0(ScheduleInfo, 1);
  39.247 +            gint type = 0;
  39.248 +
  39.249 +            schedule->schedule_id =
  39.250 +                (guint) g_ascii_strtoull(row[0], NULL, 10);
  39.251 +            schedule->program_id = g_string_new (row[1]);
  39.252 +            schedule->channel_id = (gint) g_ascii_strtoull (row[2], NULL, 10);
  39.253 +
  39.254 +            /*
  39.255 +             * generate a time_t from a time and a date db field 
  39.256 +             */
  39.257 +            date_time = g_strdup_printf("%sT%s", row[4], row[3]);
  39.258 +            schedule->start_time =
  39.259 +                gmyth_util_string_to_time_val(date_time);
  39.260 +            g_free(date_time);
  39.261 +
  39.262 +            /*
  39.263 +             * generate a time_t from a time and a date db field 
  39.264 +             */
  39.265 +            date_time = g_strdup_printf("%sT%s", row[6], row[5]);
  39.266 +            schedule->end_time = gmyth_util_string_to_time_val(date_time);
  39.267 +            g_free(date_time);
  39.268 +
  39.269 +            schedule->title = g_string_new(row[7]);
  39.270 +            schedule->subtitle = g_string_new(row[8]);
  39.271 +            schedule->description = g_string_new(row[9]);
  39.272 +            schedule->category = g_string_new(row[10]);
  39.273 +            type = g_ascii_strtoull (row[11], NULL, 10);
  39.274 +            if (type == 4) {
  39.275 +                schedule->type = GMYTH_SCHEDULE_ALL_OCCURRENCES;
  39.276 +            } else if (type == 1) {
  39.277 +                schedule->type = GMYTH_SCHEDULE_ONE_OCCURRENCE;
  39.278 +            } else if (type == 8) {
  39.279 +                schedule->type = GMYTH_SCHEDULE_EXCEPTION;
  39.280 +                schedule->parentid = (gint) g_ascii_strtoull (row[12], NULL, 10);
  39.281 +            }
  39.282 +
  39.283 +            schedule->seriesid = g_string_new (row[13]);
  39.284 +
  39.285 +            (*schedule_list) = g_list_append(*(schedule_list), schedule);
  39.286 +        }
  39.287 +    }
  39.288 +
  39.289 +    mysql_free_result(msql_res);
  39.290 +    g_string_free(query_str, TRUE);
  39.291 +
  39.292 +    return (*schedule_list == NULL) ? 0 : g_list_length(*schedule_list);
  39.293 +}
  39.294 +
  39.295 +/** Retrieves from the backend Mysql database the list of recorded programs.
  39.296 + * 
  39.297 + * @param scheduler The GMythScheduler instance.
  39.298 + * @param recorded_list the GList pointer to be filled with the loaded RecordInfo items.
  39.299 + * @return The amount of recorded retrieved from database, or -1 if error.
  39.300 + */
  39.301 +gint
  39.302 +gmyth_scheduler_get_recorded_list(GMythScheduler * scheduler,
  39.303 +                                  GList ** recorded_list)
  39.304 +{
  39.305 +    RecordedInfo   *record;
  39.306 +    MYSQL_RES      *msql_res;
  39.307 +    GString        *query_str = g_string_new("");
  39.308 +
  39.309 +    assert(scheduler);
  39.310 +
  39.311 +    g_string_printf(query_str,
  39.312 +                    "SELECT recordid,programid,chanid,starttime,progstart,"
  39.313 +                    "endtime,progend,title,subtitle,description,category,"
  39.314 +                    "filesize,basename,seriesid FROM recorded WHERE recgroup != 'LiveTV'");
  39.315 +
  39.316 +    if (scheduler->msqlquery == NULL) {
  39.317 +        g_warning("[%s] Scheduler db connection not initialized",
  39.318 +                  __FUNCTION__);
  39.319 +        return -1;
  39.320 +    }
  39.321 +
  39.322 +    msql_res =
  39.323 +        gmyth_query_process_statement(scheduler->msqlquery,
  39.324 +                                      query_str->str);
  39.325 +
  39.326 +    if (msql_res == NULL) {
  39.327 +        g_warning("DB retrieval of recording list failed");
  39.328 +        return -1;
  39.329 +    } else {
  39.330 +        MYSQL_ROW       row;
  39.331 +
  39.332 +        (*recorded_list) = NULL;
  39.333 +
  39.334 +        while ((row = mysql_fetch_row(msql_res)) != NULL) {
  39.335 +            record = g_new0(RecordedInfo, 1);
  39.336 +
  39.337 +            record->record_id = (guint) g_ascii_strtoull(row[0], NULL, 10);
  39.338 +            record->program_id = g_string_new (row[1]);
  39.339 +            record->channel_id = (gint) g_ascii_strtoull(row[2], NULL, 10);
  39.340 +            record->start_time = gmyth_util_string_to_time_val(row[3]);
  39.341 +            record->end_time = gmyth_util_string_to_time_val(row[5]);
  39.342 +
  39.343 +            record->title = g_string_new(row[7]);
  39.344 +            record->subtitle = g_string_new(row[8]);
  39.345 +            record->description = g_string_new(row[9]);
  39.346 +            record->category = g_string_new(row[10]);
  39.347 +            record->filesize = g_ascii_strtoull(row[11], NULL, 10);
  39.348 +            record->basename = g_string_new(row[12]);
  39.349 +            record->seriesid = g_string_new(row[13]);
  39.350 +
  39.351 +            (*recorded_list) = g_list_append((*recorded_list), record);
  39.352 +        }
  39.353 +    }
  39.354 +
  39.355 +    mysql_free_result(msql_res);
  39.356 +    g_string_free(query_str, TRUE);
  39.357 +
  39.358 +    return (*recorded_list == NULL) ? 0 : g_list_length(*recorded_list);
  39.359 +}
  39.360 +
  39.361 +RecordedInfo*
  39.362 +gmyth_scheduler_get_recorded_info (GMythScheduler *scheduler,
  39.363 +                                   const gchar* basename)
  39.364 +{
  39.365 +    RecordedInfo   *record = NULL;
  39.366 +    MYSQL_RES      *msql_res;
  39.367 +    GString        *query_str = g_string_new("");
  39.368 +
  39.369 +    assert(scheduler);
  39.370 +
  39.371 +    g_string_printf(query_str,
  39.372 +                    "SELECT recordid,programid,chanid,starttime,progstart,"
  39.373 +                    "endtime,progend,title,subtitle,description,category,"
  39.374 +                    "filesize,basename,seriesid FROM recorded "
  39.375 +                    "WHERE recgroup != 'LiveTV' AND basename = '%s'", basename);
  39.376 +
  39.377 +    if (scheduler->msqlquery == NULL) {
  39.378 +        g_warning("[%s] Scheduler db connection not initialized", 
  39.379 +                        __FUNCTION__);
  39.380 +        return NULL;
  39.381 +    }
  39.382 +
  39.383 +    msql_res =
  39.384 +        gmyth_query_process_statement(scheduler->msqlquery,
  39.385 +                                      query_str->str);
  39.386 +
  39.387 +    if (msql_res == NULL) {
  39.388 +        g_warning("DB retrieval of recording list failed");
  39.389 +        return NULL;
  39.390 +    } else {
  39.391 +        MYSQL_ROW       row;
  39.392 +        row = mysql_fetch_row(msql_res);
  39.393 +        if (row != NULL) {
  39.394 +            record = g_new0(RecordedInfo, 1);
  39.395 +            record->record_id = (guint) g_ascii_strtoull(row[0], NULL, 10);
  39.396 +            record->program_id = g_string_new (row[1]);
  39.397 +            record->channel_id = (gint) g_ascii_strtoull(row[2], NULL, 10);
  39.398 +            record->start_time = gmyth_util_string_to_time_val(row[3]);
  39.399 +            record->end_time = gmyth_util_string_to_time_val(row[5]);
  39.400 +            record->title = g_string_new(row[7]);
  39.401 +            record->subtitle = g_string_new(row[8]);
  39.402 +            record->description = g_string_new(row[9]);
  39.403 +            record->category = g_string_new(row[10]);
  39.404 +            record->filesize = g_ascii_strtoull(row[11], NULL, 10);
  39.405 +            record->basename = g_string_new(row[12]);
  39.406 +            record->seriesid = g_string_new(row[13]);
  39.407 +        }
  39.408 +    }
  39.409 +
  39.410 +    mysql_free_result(msql_res);
  39.411 +    g_string_free(query_str, TRUE);
  39.412 +
  39.413 +    return record;
  39.414 +}
  39.415 +
  39.416 +
  39.417 +static void
  39.418 +_set_value(GMythQuery * myth_query, char *field, gchar * value,
  39.419 +           gint rec_id)
  39.420 +{
  39.421 +    gchar          *query =
  39.422 +        g_strdup_printf
  39.423 +        ("UPDATE record SET recordid = %d, %s = \"%s\" WHERE recordid = %d;",
  39.424 +         rec_id, field, value, rec_id);
  39.425 +
  39.426 +    gmyth_query_process_statement(myth_query, query);
  39.427 +    g_free(query);
  39.428 +}
  39.429 +
  39.430 +static void
  39.431 +_set_int_value(GMythQuery * myth_query, char *field, gint value,
  39.432 +               gint rec_id)
  39.433 +{
  39.434 +    gchar *str_value = g_strdup_printf("%d", value);
  39.435 +
  39.436 +    _set_value(myth_query, field, str_value, rec_id);
  39.437 +    g_free(str_value);
  39.438 +}
  39.439 +
  39.440 +ScheduleInfo*
  39.441 +gmyth_scheduler_add_schedule_program (GMythScheduler * scheduler,
  39.442 +                                      GMythProgramInfo *program,
  39.443 +                                      GMythScheduleType type)
  39.444 +{
  39.445 +    ScheduleInfo *info;
  39.446 +
  39.447 +    info = g_new0 (ScheduleInfo, 1);
  39.448 +    info->program_id = g_string_new (program->program_id->str);
  39.449 +    info->channel_id = program->channel_id;
  39.450 +    info->start_time = g_new0 (GTimeVal, 1);
  39.451 +    *info->start_time = *program->startts;
  39.452 +    info->end_time = g_new0 (GTimeVal, 1);
  39.453 +    *info->end_time = *program->endts;
  39.454 +    info->seriesid = g_string_new (program->seriesid->str);
  39.455 +    info->title = g_string_new (program->title->str);
  39.456 +    info->subtitle = g_string_new (program->subtitle->str);
  39.457 +    info->description = g_string_new (program->description->str);
  39.458 +    info->category = g_string_new (program->category->str);
  39.459 +    info->type = type;
  39.460 +
  39.461 +    if (gmyth_scheduler_add_schedule_full (scheduler, info, type))
  39.462 +    {
  39.463 +        if (!program->recstartts)
  39.464 +            program->recstartts = g_new0 (GTimeVal, 1);
  39.465 +        *program->recstartts = *info->start_time;
  39.466 +
  39.467 +        if (!program->recendts)
  39.468 +            program->recendts = g_new0 (GTimeVal, 1);
  39.469 +        *program->recendts = *info->end_time;
  39.470 +
  39.471 +        program->recordid = info->schedule_id;
  39.472 +        return info;
  39.473 +    }
  39.474 +
  39.475 +    gmyth_schedule_info_free (info);
  39.476 +    return NULL;
  39.477 +}
  39.478 +
  39.479 +
  39.480 +gboolean
  39.481 +gmyth_scheduler_add_schedule_full (GMythScheduler * scheduler,
  39.482 +                             ScheduleInfo * schedule_info, GMythScheduleType type)
  39.483 +{
  39.484 +    MYSQL_RES      *msql_res;
  39.485 +    gchar          *query_str = "INSERT record (recordid) VALUE (0);";
  39.486 +    gchar          *station = NULL;
  39.487 +    gulong          rec_id;
  39.488 +
  39.489 +    g_return_val_if_fail (IS_GMYTH_SCHEDULER (scheduler), FALSE);
  39.490 +
  39.491 +    if (scheduler->msqlquery == NULL) {
  39.492 +        g_warning("[%s] Scheduler db connection not initialized",
  39.493 +                  __FUNCTION__);
  39.494 +        return FALSE;
  39.495 +    }
  39.496 +
  39.497 +    msql_res =
  39.498 +        gmyth_query_process_statement_with_increment(scheduler->msqlquery,
  39.499 +                                                     query_str, &rec_id);
  39.500 +    mysql_free_result(msql_res);
  39.501 +
  39.502 +    // Retrieves the station info
  39.503 +    query_str =
  39.504 +        g_strdup_printf
  39.505 +        ("SELECT callsign FROM channel WHERE chanid = %d;",
  39.506 +         schedule_info->channel_id);
  39.507 +    msql_res =
  39.508 +        gmyth_query_process_statement(scheduler->msqlquery, query_str);
  39.509 +    if (msql_res == NULL) {
  39.510 +        g_warning("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
  39.511 +        return FALSE;
  39.512 +    } else {
  39.513 +        MYSQL_ROW       row;
  39.514 +
  39.515 +        if ((row = mysql_fetch_row(msql_res)) != NULL) {
  39.516 +            station = g_strdup(row[0]);
  39.517 +        }
  39.518 +    }
  39.519 +    mysql_free_result(msql_res);
  39.520 +    g_free(query_str);
  39.521 +
  39.522 +    // _set_value (field, value, id);
  39.523 +    _set_int_value(scheduler->msqlquery, "chanid",
  39.524 +                   schedule_info->channel_id, rec_id);
  39.525 +    _set_value(scheduler->msqlquery, "station", station, rec_id);
  39.526 +    _set_value(scheduler->msqlquery, "title", schedule_info->title->str,
  39.527 +               rec_id);
  39.528 +    // / subtitle, description 
  39.529 +    _set_value(scheduler->msqlquery, "starttime",
  39.530 +               gmyth_util_time_to_string_only_time(schedule_info->
  39.531 +                                                   start_time), rec_id);
  39.532 +    _set_value(scheduler->msqlquery, "startdate",
  39.533 +               gmyth_util_time_to_string_only_date(schedule_info->
  39.534 +                                                   start_time), rec_id);
  39.535 +    _set_value(scheduler->msqlquery, "endtime",
  39.536 +               gmyth_util_time_to_string_only_time(schedule_info->
  39.537 +                                                   end_time), rec_id);
  39.538 +    _set_value(scheduler->msqlquery, "enddate",
  39.539 +               gmyth_util_time_to_string_only_date(schedule_info->
  39.540 +                                                   end_time), rec_id);
  39.541 +    // / category, series id, program id
  39.542 +    // _set_value (scheduler->msqlquery, "findday",
  39.543 +    // (gmyth_util_time_val_to_date( schedule_info->start_time
  39.544 +    // ))->tm_wday, rec_id);
  39.545 +    // _set_value (scheduler->msqlquery, "findtime",
  39.546 +    // gmyth_util_time_to_string_only_time( schedule_info->start_time),
  39.547 +    // rec_id);
  39.548 +    // _set_int_value (scheduler->msqlquery, "findid",
  39.549 +    // (gint)(schedule_info->start_time->tv_sec/60/60/24 + 719528),
  39.550 +    // rec_id);
  39.551 +
  39.552 +    if (schedule_info->seriesid)
  39.553 +       _set_value(scheduler->msqlquery, "seriesid",
  39.554 +                  schedule_info->seriesid->str, rec_id);
  39.555 + 
  39.556 +    _set_value(scheduler->msqlquery, "parentid", "0", rec_id);
  39.557 +    _set_value(scheduler->msqlquery, "search", "0", rec_id);
  39.558 +
  39.559 +    if (type == GMYTH_SCHEDULE_ALL_OCCURRENCES) {
  39.560 +        _set_int_value(scheduler->msqlquery, "type", 3, rec_id);
  39.561 +    } else if (type == GMYTH_SCHEDULE_ONE_OCCURRENCE) {
  39.562 +        _set_int_value(scheduler->msqlquery, "type", 1, rec_id);
  39.563 +    } else if (type == GMYTH_SCHEDULE_EXCEPTION) {
  39.564 +        _set_int_value(scheduler->msqlquery, "type", 8, rec_id);
  39.565 +        _set_int_value(scheduler->msqlquery, "parentid", schedule_info->parentid,
  39.566 +		       rec_id);
  39.567 +    }
  39.568 +
  39.569 +    _set_value(scheduler->msqlquery, "recpriority", "0", rec_id);
  39.570 +    _set_value(scheduler->msqlquery, "startoffset", "0", rec_id);
  39.571 +    _set_value(scheduler->msqlquery, "endoffset", "0", rec_id);
  39.572 +    _set_value(scheduler->msqlquery, "dupmethod", "6", rec_id); // ?
  39.573 +    _set_value(scheduler->msqlquery, "dupin", "15", rec_id);    // ?
  39.574 +
  39.575 +    _set_value(scheduler->msqlquery, "prefinput", "0", rec_id);
  39.576 +    _set_value(scheduler->msqlquery, "inactive", "0", rec_id);
  39.577 +    _set_value(scheduler->msqlquery, "profile", "Default", rec_id);
  39.578 +    _set_value(scheduler->msqlquery, "recgroup", "Default", rec_id);
  39.579 +    _set_value(scheduler->msqlquery, "storagegroup", "Default", rec_id);
  39.580 +    _set_value(scheduler->msqlquery, "playgroup", "Default", rec_id);
  39.581 +    _set_value(scheduler->msqlquery, "autoexpire", "1", rec_id);
  39.582 +    _set_value(scheduler->msqlquery, "maxepisodes", "0", rec_id);
  39.583 +    _set_value(scheduler->msqlquery, "maxnewest", "0", rec_id);
  39.584 +    _set_value(scheduler->msqlquery, "autocommflag", "1", rec_id);
  39.585 +    _set_value(scheduler->msqlquery, "autotranscode", "0", rec_id);
  39.586 +    _set_value(scheduler->msqlquery, "transcoder", "0", rec_id);
  39.587 +
  39.588 +    _set_value(scheduler->msqlquery, "autouserjob1", "0", rec_id);
  39.589 +    _set_value(scheduler->msqlquery, "autouserjob2", "0", rec_id);
  39.590 +    _set_value(scheduler->msqlquery, "autouserjob3", "0", rec_id);
  39.591 +    _set_value(scheduler->msqlquery, "autouserjob4", "0", rec_id);
  39.592 +
  39.593 +    schedule_info->schedule_id = rec_id;
  39.594 +
  39.595 +    /* Notify the backend of changes */
  39.596 +    return update_backend(scheduler, rec_id);
  39.597 +}
  39.598 +
  39.599 +/** Requests the Mysql database in the backend to add a new schedule.
  39.600 + * 
  39.601 + * @param scheduler the GMythScheduler instance.
  39.602 + * @param schedule_info the ScheduleInfo with recording schedule information
  39.603 + * to be added. record_id = -1 to add a new schedule, otherwise this
  39.604 + * function will update the schedule in the db
  39.605 + * @return gboolean returns FALSE if some error occurs, TRUE otherwise
  39.606 + */
  39.607 +gboolean
  39.608 +gmyth_scheduler_add_schedule (GMythScheduler * scheduler,
  39.609 +                             ScheduleInfo * schedule_info)
  39.610 +{
  39.611 +    return gmyth_scheduler_add_schedule_full (scheduler, schedule_info, 
  39.612 +                                              GMYTH_SCHEDULE_ONE_OCCURRENCE);
  39.613 +}
  39.614 +
  39.615 +/** Requests the Mysql database in the backend to remove an existing schedule.
  39.616 + * 
  39.617 + * @param scheduler the GMythScheduler instance.
  39.618 + * @param schedule_id The schedule's record id to be removed
  39.619 + * @return gboolean TRUE if success, FALSE if error
  39.620 + */
  39.621 +gboolean
  39.622 +gmyth_scheduler_delete_schedule(GMythScheduler * scheduler, gint schedule_id)
  39.623 +{
  39.624 +
  39.625 +    MYSQL_RES      *msql_res;
  39.626 +    GString        *query_str = NULL;
  39.627 +
  39.628 +    g_return_val_if_fail (scheduler != NULL, FALSE);
  39.629 +
  39.630 +
  39.631 +    if (scheduler->msqlquery == NULL) {
  39.632 +        g_warning("[%s] Scheduler db connection not initialized",
  39.633 +                  __FUNCTION__);
  39.634 +        return FALSE;
  39.635 +    }
  39.636 +
  39.637 +    query_str = g_string_new("");
  39.638 +    g_string_printf(query_str,
  39.639 +                    "DELETE FROM record WHERE recordid=%d", schedule_id);
  39.640 +
  39.641 +    msql_res =
  39.642 +        gmyth_query_process_statement(scheduler->msqlquery,
  39.643 +                                      query_str->str);
  39.644 +
  39.645 +
  39.646 +    mysql_free_result(msql_res);
  39.647 +    g_string_free(query_str, TRUE);
  39.648 +
  39.649 +    // Notify the backend of the changes
  39.650 +    return update_backend(scheduler, schedule_id);
  39.651 +}
  39.652 +
  39.653 +/*
  39.654 + * Add an exception program to be removed from the schedule list, when programs
  39.655 + * where scheduled with the GMYTH_SCHEDULE_ALL_OCCURRENCES option.
  39.656 + * @param scheduler the GMythScheduler instance.
  39.657 + * @param schedule_id the schedule id of the all occurrence schedule to be changed
  39.658 + * @param exception_info the ScheduleInfo to be removed from all schedule occurrences
  39.659 + * @return TRUE if success, FALSE if any error happens
  39.660 + */
  39.661 +gboolean
  39.662 +gmyth_scheduler_add_exception (GMythScheduler *scheduler, gint schedule_id,
  39.663 +			       ScheduleInfo *exception_info)
  39.664 +{
  39.665 +    gboolean res;
  39.666 +
  39.667 +    g_return_val_if_fail (scheduler != NULL, FALSE);
  39.668 +    g_return_val_if_fail (exception_info != NULL, FALSE);
  39.669 +
  39.670 +    exception_info->parentid = schedule_id;
  39.671 +    res = gmyth_scheduler_add_schedule_full (scheduler, exception_info, GMYTH_SCHEDULE_EXCEPTION);
  39.672 +
  39.673 +    return res;
  39.674 +}
  39.675 +
  39.676 +/** Requests the Mysql database in the backend to remove an existing recorded item.
  39.677 + * 
  39.678 + * @param scheduler the GMythScheduler instance.
  39.679 + * @param record_id The recorded item id to be removed
  39.680 + * @return gboolean TRUE if success, FALSE if error
  39.681 + */
  39.682 +gboolean
  39.683 +gmyth_scheduler_delete_recorded(GMythScheduler * scheduler, gint record_id)
  39.684 +{
  39.685 +
  39.686 +    MYSQL_RES      *msql_res;
  39.687 +
  39.688 +    GString        *query_str = g_string_new("");
  39.689 +
  39.690 +    assert(scheduler);
  39.691 +
  39.692 +    if (scheduler->msqlquery == NULL) {
  39.693 +        g_warning("[%s] Scheduler db connection not initialized",
  39.694 +                  __FUNCTION__);
  39.695 +        return FALSE;
  39.696 +    }
  39.697 +    // ========================================
  39.698 +    g_string_printf(query_str,
  39.699 +                    "DELETE FROM recorded WHERE recordid=%d", record_id);
  39.700 +
  39.701 +    // FIXME: Mythtv implementation runs also: DELETE FROM oldfind WHERE
  39.702 +    // recordid = x
  39.703 +
  39.704 +    msql_res =
  39.705 +        gmyth_query_process_statement(scheduler->msqlquery,
  39.706 +                                      query_str->str);
  39.707 +
  39.708 +    mysql_free_result(msql_res);
  39.709 +    g_string_free(query_str, TRUE);
  39.710 +
  39.711 +    // Notify the backend of the changes
  39.712 +    return update_backend(scheduler, record_id);
  39.713 +}
  39.714 +
  39.715 +
  39.716 +gboolean gmyth_scheduler_was_recorded_before(GMythScheduler* scheduler, gint channel_id,
  39.717 +                                             time_t start_time)
  39.718 +{
  39.719 +    MYSQL_RES      *msql_res;
  39.720 +    GString        *query_str = g_string_new("");
  39.721 +
  39.722 +    assert(scheduler);
  39.723 +    g_string_printf(query_str, "SELECT callsign FROM channel "
  39.724 +                    "WHERE chanid = \"%d\"", channel_id);
  39.725 +
  39.726 +    msql_res = gmyth_query_process_statement(scheduler->msqlquery, query_str->str);
  39.727 +
  39.728 +    if (msql_res) {
  39.729 +        MYSQL_ROW msql_row = mysql_fetch_row(msql_res);
  39.730 +        if (msql_row) {
  39.731 +            GString* callsign = g_string_new(msql_row[0]);
  39.732 +            GString* startts = gmyth_util_time_to_string(start_time);
  39.733 +            g_string_printf(query_str, "SELECT * FROM oldrecorded "
  39.734 +                            "WHERE station = \"%s\" AND starttime = \"%s\"",
  39.735 +                            callsign->str, startts->str);
  39.736 +            msql_res = gmyth_query_process_statement(scheduler->msqlquery, query_str->str);
  39.737 +            g_string_free(callsign, TRUE);
  39.738 +            g_string_free(startts, TRUE);
  39.739 +            g_string_free(query_str, TRUE);
  39.740 +            if (mysql_fetch_row(msql_res)) return TRUE;
  39.741 +        }
  39.742 +    }
  39.743 +    return FALSE;
  39.744 +}
  39.745 +
  39.746 +
  39.747 +gboolean gmyth_scheduler_reactivate_schedule(GMythScheduler* scheduler, gint channel_id,
  39.748 +                                             time_t start_time)
  39.749 +
  39.750 +{
  39.751 +    MYSQL_RES      *msql_res;
  39.752 +    GString        *query_str = g_string_new("");
  39.753 +
  39.754 +    assert(scheduler);
  39.755 +    g_string_printf(query_str, "SELECT callsign FROM channel "
  39.756 +                    "WHERE chanid = \"%d\"", channel_id);
  39.757 +
  39.758 +    msql_res = gmyth_query_process_statement(scheduler->msqlquery, query_str->str);
  39.759 +    if (msql_res) {
  39.760 +        MYSQL_ROW msql_row = mysql_fetch_row(msql_res);
  39.761 +        if (msql_row) {
  39.762 +            GString* callsign = g_string_new(msql_row[0]);
  39.763 +            GString* startts = gmyth_util_time_to_string(start_time);
  39.764 +            g_string_printf(query_str, "UPDATE oldrecorded SET reactivate = 1 "
  39.765 +                            "WHERE station = \"%s\" AND starttime = \"%s\"",
  39.766 +                            callsign->str, startts->str);
  39.767 +            gmyth_query_process_statement(scheduler->msqlquery, query_str->str);
  39.768 +            g_string_free(callsign, TRUE);
  39.769 +            g_string_free(startts, TRUE);
  39.770 +            g_string_free(query_str, TRUE);
  39.771 +            return TRUE;
  39.772 +        }
  39.773 +
  39.774 +    }
  39.775 +
  39.776 +    return FALSE;
  39.777 +}
  39.778 +
  39.779 +
  39.780 +/*
  39.781 + * This should only be used in special situations. We do not know the time that
  39.782 + * the recording was set. We just know that it is an "ongoing" record and then
  39.783 + * we have to use this to get it's info. It's always the oldest one -> first on list
  39.784 + *
  39.785 + */
  39.786 +GMythProgramInfo*
  39.787 +gmyth_scheduler_get_recorded_on_time(GMythScheduler* scheduler,
  39.788 +                                     guint channel_id)
  39.789 +{
  39.790 +    MYSQL_RES      *msql_res;
  39.791 +    GMythProgramInfo *proginfo = NULL;
  39.792 +    GString        *query_str = g_string_new("");
  39.793 +
  39.794 +    assert(scheduler);
  39.795 +
  39.796 +    g_string_printf(query_str,
  39.797 +                    "SELECT recorded.chanid,starttime,endtime,title,"
  39.798 +                    "subtitle,description,channel.channum,"
  39.799 +                    "channel.callsign,channel.name,channel.commfree,"
  39.800 +                    "channel.outputfilters,seriesid,programid,filesize,"
  39.801 +                    "lastmodified,stars,previouslyshown,originalairdate,"
  39.802 +                    "hostname,recordid,transcoder,playgroup,"
  39.803 +                    "recorded.recpriority,progstart,progend,basename,recgroup,"
  39.804 +                    "category,findid,duplicate "
  39.805 +                    "FROM recorded " "LEFT JOIN channel "
  39.806 +                    "ON recorded.chanid = channel.chanid "
  39.807 +                    "WHERE recorded.chanid = %d "
  39.808 +                    "ORDER BY starttime DESC", channel_id);
  39.809 +
  39.810 +    msql_res =
  39.811 +        gmyth_query_process_statement(scheduler->msqlquery, query_str->str);
  39.812 +
  39.813 +    if (msql_res) {
  39.814 +        MYSQL_ROW msql_row = mysql_fetch_row(msql_res);
  39.815 +
  39.816 +        if (msql_row) {
  39.817 +            proginfo = gmyth_program_info_new();
  39.818 +
  39.819 +            proginfo->channel_id = (gint) g_ascii_strtoull (msql_row[0], NULL, 10);
  39.820 +            proginfo->recstartts = gmyth_util_string_to_time_val(msql_row[1]);
  39.821 +            proginfo->recendts = gmyth_util_string_to_time_val(msql_row[2]);
  39.822 +
  39.823 +            proginfo->title = g_string_new(msql_row[3]);
  39.824 +            proginfo->subtitle = g_string_new(msql_row[4]);
  39.825 +            proginfo->description = g_string_new(msql_row[5]);
  39.826 +
  39.827 +            proginfo->chanstr = g_string_new(msql_row[6]);
  39.828 +            proginfo->chansign = g_string_new(msql_row[7]);
  39.829 +            proginfo->channame = g_string_new(msql_row[8]);
  39.830 +            proginfo->chancommfree = (gint) g_ascii_strtoull(msql_row[9], NULL, 10);
  39.831 +            proginfo->chanOutputFilters = g_string_new(msql_row[10]);
  39.832 +            proginfo->seriesid = g_string_new(msql_row[11]);
  39.833 +            proginfo->program_id = g_string_new(msql_row[12]);
  39.834 +            proginfo->filesize = g_ascii_strtoull(msql_row[13], NULL, 10);
  39.835 +
  39.836 +            proginfo->lastmodified = gmyth_util_string_to_time_val(msql_row[14]);
  39.837 +            proginfo->stars = g_ascii_strtod(msql_row[15], NULL);
  39.838 +            proginfo->repeat = (gint)g_ascii_strtoull(msql_row[16], NULL, 10);
  39.839 +
  39.840 +            if (msql_row[17] == NULL) {
  39.841 +                proginfo->originalAirDate = 0;
  39.842 +                proginfo->hasAirDate = FALSE;
  39.843 +            } else {
  39.844 +                proginfo->originalAirDate = gmyth_util_string_to_time_val(msql_row[17]);
  39.845 +                proginfo->hasAirDate = TRUE;
  39.846 +            }
  39.847 +
  39.848 +            proginfo->hostname = g_string_new(msql_row[18]);
  39.849 +            proginfo->recordid = (gint) g_ascii_strtoull(msql_row[19], NULL, 10);
  39.850 +            proginfo->transcoder = (gint) g_ascii_strtoull(msql_row[20], NULL, 10);
  39.851 +
  39.852 +            proginfo->playgroup = g_string_new(msql_row[21]);
  39.853 +            proginfo->recpriority = (gint) g_ascii_strtoull(msql_row[22], NULL, 10);
  39.854 +
  39.855 +            proginfo->startts = gmyth_util_string_to_time_val(msql_row[23]);
  39.856 +            proginfo->endts = gmyth_util_string_to_time_val(msql_row[24]);
  39.857 +            proginfo->pathname = g_string_new(g_strdup(msql_row[25]));
  39.858 +            proginfo->recgroup = g_string_new(msql_row[26]);
  39.859 +            proginfo->category = g_string_new(msql_row[27]);
  39.860 +            proginfo->findid = (gint) g_ascii_strtoull(msql_row[28], NULL, 10);
  39.861 +
  39.862 +            proginfo->recpriority2 = 0;
  39.863 +
  39.864 +            g_string_printf(query_str,
  39.865 +                            "SELECT dupmethod,dupin,parentid,type "
  39.866 +                            "FROM record WHERE recordid = \"%d\"", proginfo->recordid);
  39.867 +
  39.868 +            msql_res =
  39.869 +                gmyth_query_process_statement(scheduler->msqlquery,
  39.870 +                                              query_str->str);
  39.871 +
  39.872 +            if (msql_res) {
  39.873 +                MYSQL_ROW msql_row = mysql_fetch_row(msql_res);
  39.874 +
  39.875 +                if (msql_row) {
  39.876 +                    proginfo->dupmethod = (gint) g_ascii_strtoull(msql_row[0], NULL, 10);
  39.877 +                    proginfo->dupin = (gint) g_ascii_strtoull(msql_row[1], NULL, 10);
  39.878 +                    proginfo->parentid = (gint) g_ascii_strtoull(msql_row[2], NULL, 10);
  39.879 +                    proginfo->rectype = 0;
  39.880 +                }
  39.881 +            }
  39.882 +
  39.883 +
  39.884 +            g_string_printf(query_str,
  39.885 +                            "SELECT sourceid,cardid,cardinputid,shareable "
  39.886 +                            "FROM cardinput");
  39.887 +
  39.888 +            msql_res =
  39.889 +                gmyth_query_process_statement(scheduler->msqlquery,
  39.890 +                                              query_str->str);
  39.891 +
  39.892 +            if (msql_res) {
  39.893 +                MYSQL_ROW msql_row = mysql_fetch_row(msql_res);
  39.894 +
  39.895 +                if (msql_row) {
  39.896 +                    proginfo->sourceid = 0;
  39.897 +                    proginfo->cardid = 0;
  39.898 +                    proginfo->inputid = 0;
  39.899 +                    if (msql_row[3] != NULL && g_ascii_strcasecmp("Y", msql_row[3]) == 0)
  39.900 +                        proginfo->shareable = 1;
  39.901 +                    else
  39.902 +                        proginfo->shareable = 0;
  39.903 +                }
  39.904 +            }
  39.905 +
  39.906 +
  39.907 +
  39.908 +        }
  39.909 +    }
  39.910 +
  39.911 +    g_string_free(query_str, TRUE);
  39.912 +    return proginfo;
  39.913 +}
  39.914 +
  39.915 +/** Retrieves an existing recorded item information from database. The information
  39.916 + * is used to fill the returned GMythProgramInfo.
  39.917 + * 
  39.918 + * @param scheduler The GMythScheduler instance.
  39.919 + * @param channel The channel associated to the record
  39.920 + * @param starttime The record start time
  39.921 + * @return A GMythProgramInfo struct with the requested record item
  39.922 + * information, or NULL if error.
  39.923 + */
  39.924 +GMythProgramInfo *
  39.925 +gmyth_scheduler_get_recorded(GMythScheduler * scheduler,
  39.926 +                             GString * channel, GTimeVal * starttime)
  39.927 +{
  39.928 +    MYSQL_RES      *msql_res;
  39.929 +    GMythProgramInfo *proginfo = NULL;
  39.930 +    GString        *query_str = g_string_new("");
  39.931 +    gchar          *time_str =
  39.932 +        gmyth_util_time_to_string_from_time_val(starttime);
  39.933 +
  39.934 +    assert(scheduler);
  39.935 +
  39.936 +    gmyth_debug("[%s] channel: %s", __FUNCTION__, channel->str);
  39.937 +
  39.938 +    if (scheduler->msqlquery == NULL) {
  39.939 +        g_warning("[%s] Scheduler db connection not initialized",
  39.940 +                  __FUNCTION__);
  39.941 +        return NULL;
  39.942 +    }
  39.943 +
  39.944 +    g_string_printf(query_str,
  39.945 +                    "SELECT recorded.chanid,starttime,endtime,title, "
  39.946 +                    "subtitle,description,channel.channum, "
  39.947 +                    "channel.callsign,channel.name,channel.commfree, "
  39.948 +                    "channel.outputfilters,seriesid,programid,filesize, "
  39.949 +                    "lastmodified,stars,previouslyshown,originalairdate, "
  39.950 +                    "hostname,recordid,transcoder,playgroup, "
  39.951 +                    "recorded.recpriority,progstart,progend,basename,recgroup "
  39.952 +                    "FROM recorded " "LEFT JOIN channel "
  39.953 +                    "ON recorded.chanid = channel.chanid "
  39.954 +                    "WHERE recorded.chanid = \"%s\" "
  39.955 +                    "AND starttime = \"%s\" ;", channel->str, time_str);
  39.956 +
  39.957 +    msql_res =
  39.958 +        gmyth_query_process_statement(scheduler->msqlquery,
  39.959 +                                      query_str->str);
  39.960 +
  39.961 +    if (msql_res /* && query.size() > 0 */ ) {
  39.962 +        MYSQL_ROW       msql_row = mysql_fetch_row(msql_res);
  39.963 +
  39.964 +        if (msql_row) {
  39.965 +            proginfo = gmyth_program_info_new();
  39.966 +
  39.967 +            proginfo->channel_id = (gint) g_ascii_strtoull (msql_row[0], NULL, 10);
  39.968 +            proginfo->startts =
  39.969 +                gmyth_util_string_to_time_val(msql_row[23]);
  39.970 +            proginfo->endts = gmyth_util_string_to_time_val(msql_row[24]);
  39.971 +            proginfo->recstartts =
  39.972 +                gmyth_util_string_to_time_val(msql_row[1]);
  39.973 +            proginfo->recendts =
  39.974 +                gmyth_util_string_to_time_val(msql_row[2]);
  39.975 +            proginfo->title = g_string_new(msql_row[3]);
  39.976 +            proginfo->subtitle = g_string_new(msql_row[4]);
  39.977 +            proginfo->description = g_string_new(msql_row[5]);
  39.978 +
  39.979 +            proginfo->chanstr = g_string_new(msql_row[6]);
  39.980 +            proginfo->chansign = g_string_new(msql_row[7]);
  39.981 +            proginfo->channame = g_string_new(msql_row[0]);
  39.982 +            proginfo->chancommfree =
  39.983 +                (gint) g_ascii_strtoull(msql_row[9], NULL, 10);
  39.984 +            proginfo->chanOutputFilters = g_string_new(msql_row[10]);
  39.985 +            proginfo->seriesid = g_string_new(msql_row[11]);
  39.986 +            proginfo->program_id = g_string_new(msql_row[12]);
  39.987 +            proginfo->filesize = g_ascii_strtoull(msql_row[13], NULL, 10);
  39.988 +
  39.989 +            proginfo->lastmodified =
  39.990 +                gmyth_util_string_to_time_val(msql_row[14]);
  39.991 +            proginfo->stars = g_ascii_strtod(msql_row[15], NULL);
  39.992 +            proginfo->repeat =
  39.993 +                (gint) g_ascii_strtoull(msql_row[16], NULL, 10);
  39.994 +
  39.995 +            if (msql_row[17] == NULL) {
  39.996 +                proginfo->originalAirDate = 0;
  39.997 +                proginfo->hasAirDate = FALSE;
  39.998 +            } else {
  39.999 +                proginfo->originalAirDate =
 39.1000 +                    gmyth_util_string_to_time_val(msql_row[17]);
 39.1001 +                proginfo->hasAirDate = TRUE;
 39.1002 +            }
 39.1003 +
 39.1004 +            proginfo->hostname = g_string_new(msql_row[18]);
 39.1005 +            proginfo->recordid =
 39.1006 +                (gint) g_ascii_strtoull(msql_row[19], NULL, 10);
 39.1007 +            proginfo->transcoder =
 39.1008 +                (gint) g_ascii_strtoull(msql_row[20], NULL, 10);
 39.1009 +            // proginfo->spread = -1;
 39.1010 +            // proginfo->programflags = proginfo->getProgramFlags();
 39.1011 +
 39.1012 +            proginfo->recgroup = g_string_new(msql_row[26]);
 39.1013 +            proginfo->playgroup = g_string_new(msql_row[21]);
 39.1014 +            proginfo->recpriority =
 39.1015 +                (gint) g_ascii_strtoull(msql_row[22], NULL, 10);
 39.1016 +
 39.1017 +            proginfo->pathname = g_string_new(g_strdup(msql_row[25]));
 39.1018 +
 39.1019 +            gmyth_debug("One program info loaded from mysql database\n");
 39.1020 +        }
 39.1021 +    }
 39.1022 +
 39.1023 +    mysql_free_result(msql_res);
 39.1024 +    g_string_free(query_str, TRUE);
 39.1025 +    g_free(time_str);
 39.1026 +
 39.1027 +    return proginfo;
 39.1028 +}
 39.1029 +
 39.1030 +gboolean
 39.1031 +gmyth_scheduler_stop_recording (GMythScheduler * scheduler,
 39.1032 +                                gint channel_id)
 39.1033 +{
 39.1034 +    GMythProgramInfo *program;
 39.1035 +    GMythSocket    *socket;
 39.1036 +    gboolean        res = FALSE;
 39.1037 +    GMythStringList *slist;
 39.1038 +
 39.1039 +    socket = gmyth_backend_info_get_connected_socket (scheduler->backend_info);
 39.1040 +    program = gmyth_scheduler_get_recorded_on_time (scheduler, channel_id);
 39.1041 +
 39.1042 +    if (program) {
 39.1043 +        slist = gmyth_string_list_new();
 39.1044 +        gmyth_string_list_append_char_array(slist, "STOP_RECORDING");
 39.1045 +
 39.1046 +        gmyth_string_list_append_string(slist, program->title);        /* 0 */
 39.1047 +        gmyth_string_list_append_string(slist, program->subtitle);     /* 1 */
 39.1048 +        gmyth_string_list_append_string(slist, program->description);  /* 2 */
 39.1049 +        gmyth_string_list_append_string(slist, program->category);     /* 3 */
 39.1050 +        gmyth_string_list_append_int(slist, program->channel_id);   /* 4 */
 39.1051 +        gmyth_string_list_append_string(slist, program->chanstr);      /* 5 */
 39.1052 +        gmyth_string_list_append_string(slist, program->chansign);     /* 6 */
 39.1053 +        gmyth_string_list_append_string(slist, program->channame);     /* 7 */
 39.1054 +        gmyth_string_list_append_string(slist, program->pathname);     /* 8 */
 39.1055 +        gmyth_string_list_append_int64(slist, program->filesize);      /* 9 */
 39.1056 +
 39.1057 +        if (program->startts)
 39.1058 +            gmyth_string_list_append_int(slist, program->startts->tv_sec); /* 10 */
 39.1059 +        else
 39.1060 +            gmyth_string_list_append_int(slist, 0);
 39.1061 +
 39.1062 +        if (program->endts)
 39.1063 +            gmyth_string_list_append_int(slist, program->endts->tv_sec);   /* 11 */
 39.1064 +        else
 39.1065 +            gmyth_string_list_append_int(slist, 0);
 39.1066 +
 39.1067 +        gmyth_string_list_append_int(slist, program->duplicate);   /* 12 */
 39.1068 +        gmyth_string_list_append_int(slist, program->shareable);   /* 13 */
 39.1069 +        gmyth_string_list_append_int(slist, program->findid);      /* 14 */
 39.1070 +        gmyth_string_list_append_string(slist, program->hostname); /* 15 */
 39.1071 +        gmyth_string_list_append_int(slist, program->sourceid);    /* 16 */
 39.1072 +        gmyth_string_list_append_int(slist, program->cardid);      /* 17 */
 39.1073 +        gmyth_string_list_append_int(slist, program->inputid);     /* 18 */
 39.1074 +        gmyth_string_list_append_int(slist, program->recpriority); /* 19 */
 39.1075 +
 39.1076 +        // recstatus == recording
 39.1077 +        gmyth_string_list_append_int(slist, -3);                   /* 20 */
 39.1078 +
 39.1079 +        gmyth_string_list_append_int(slist, program->recordid);    /* 21 */
 39.1080 +        gmyth_string_list_append_int(slist, program->rectype);     /* 22 */
 39.1081 +        gmyth_string_list_append_int(slist, program->dupin);       /* 23 */
 39.1082 +        gmyth_string_list_append_int(slist, program->dupmethod);   /* 24 */
 39.1083 +
 39.1084 +
 39.1085 +        //fixme
 39.1086 +        program->recstartts->tv_sec -= (60*60);
 39.1087 +
 39.1088 +        gmyth_string_list_append_int(slist, 
 39.1089 +                                     program->recstartts != NULL ?
 39.1090 +                                     program->recstartts->tv_sec : 0);   /* 26 */
 39.1091 +
 39.1092 +        gmyth_string_list_append_int(slist, 
 39.1093 +                                     program->recendts != NULL ?
 39.1094 +                                     program->recendts->tv_sec : 0);    /* 27 */
 39.1095 +
 39.1096 +        gmyth_string_list_append_int(slist, program->repeat);       /* 28 */
 39.1097 +        gmyth_string_list_append_int(slist, program->programflags); /* 29 */
 39.1098 +
 39.1099 +        gmyth_string_list_append_char_array(slist, 
 39.1100 +                                            program->recgroup != NULL ?
 39.1101 +                                            program->recgroup->str : "Default");  /* 30 */
 39.1102 +
 39.1103 +        gmyth_string_list_append_int(slist, program->chancommfree);         /* 31 */
 39.1104 +        gmyth_string_list_append_string(slist, program->chanOutputFilters); /* 32 */
 39.1105 +        gmyth_string_list_append_string(slist, program->seriesid);          /* 33 */
 39.1106 +        gmyth_string_list_append_string(slist, program->program_id);     /* 34 */
 39.1107 +
 39.1108 +        gmyth_string_list_append_int(slist,
 39.1109 +                                     program->lastmodified != NULL ?
 39.1110 +                                     program->lastmodified->tv_sec : 0);   /* 35 */
 39.1111 +
 39.1112 +        gmyth_string_list_append_float(slist, program->stars); /* 36 */
 39.1113 +
 39.1114 +        gmyth_string_list_append_int(slist,
 39.1115 +                                     program->originalAirDate != NULL ?
 39.1116 +                                     program->originalAirDate->tv_sec : 0); /* 37 */
 39.1117 +
 39.1118 +        gmyth_string_list_append_int(slist, program->hasAirDate);  /* 38 */
 39.1119 +
 39.1120 +        gmyth_string_list_append_char_array(slist,
 39.1121 +                                            program->playgroup != NULL ?
 39.1122 +                                            program->playgroup->str : "Default");  /* 39 */
 39.1123 +
 39.1124 +        gmyth_string_list_append_int(slist, program->recpriority2); /* 40 */
 39.1125 +        gmyth_string_list_append_int(slist, program->recpriority2); /* 40 */
 39.1126 +
 39.1127 +        gmyth_socket_sendreceive_stringlist(socket, slist);
 39.1128 +        res = (gmyth_string_list_get_int(slist, 0) == 1);
 39.1129 +
 39.1130 +        g_object_unref (program);
 39.1131 +        g_object_unref (slist);
 39.1132 +    }
 39.1133 +
 39.1134 +    g_object_unref (socket);
 39.1135 +    return res;
 39.1136 +}
 39.1137 +
 39.1138 +
 39.1139 +/** Notifies the backend of an update in the db.
 39.1140 + * 
 39.1141 + * @param record_id the id of the modified recording.
 39.1142 + */
 39.1143 +// fixme: put void and discovery record_id inside
 39.1144 +static gboolean
 39.1145 +update_backend (GMythScheduler * scheduler, 
 39.1146 +                gint record_id)  
 39.1147 +{
 39.1148 +    GMythSocket    *socket;
 39.1149 +    GMythStringList *strlist = gmyth_string_list_new();
 39.1150 +    GString        *datastr = g_string_new("RESCHEDULE_RECORDINGS ");
 39.1151 +    gboolean        ret = FALSE;
 39.1152 +
 39.1153 +    g_string_append_printf(datastr, "%d", record_id);
 39.1154 +    gmyth_string_list_append_string(strlist, datastr);
 39.1155 +
 39.1156 +    socket = gmyth_backend_info_get_connected_socket (scheduler->backend_info);
 39.1157 +    if (socket != NULL) { 
 39.1158 +        ret = (gmyth_socket_sendreceive_stringlist(socket, strlist) > 0);
 39.1159 +        g_object_unref (socket);
 39.1160 +    } else {
 39.1161 +        g_warning("[%s] Connection to backend failed!", __FUNCTION__);
 39.1162 +    }
 39.1163 +
 39.1164 +    g_string_free(datastr, TRUE);
 39.1165 +    g_object_unref(strlist);
 39.1166 +    return ret;
 39.1167 +}
 39.1168 +
 39.1169 +void
 39.1170 +gmyth_scheduler_recorded_info_get_preview(RecordedInfo * info,
 39.1171 +                                          GByteArray * data)
 39.1172 +{
 39.1173 +}
 39.1174 +
 39.1175 +void
 39.1176 +gmyth_recorded_info_free(RecordedInfo * info)
 39.1177 +{
 39.1178 +    g_return_if_fail (info != NULL);
 39.1179 +
 39.1180 +    if (info->program_id)
 39.1181 +        g_string_free (info->program_id, TRUE);
 39.1182 +
 39.1183 +    if (info->title != NULL)
 39.1184 +        g_string_free(info->title, TRUE);
 39.1185 +
 39.1186 +    if (info->subtitle != NULL)
 39.1187 +        g_string_free(info->subtitle, TRUE);
 39.1188 +
 39.1189 +    if (info->description != NULL)
 39.1190 +        g_string_free(info->description, TRUE);
 39.1191 +
 39.1192 +    if (info->category != NULL)
 39.1193 +        g_string_free(info->category, TRUE);
 39.1194 +
 39.1195 +    if (info->basename != NULL)
 39.1196 +        g_string_free(info->basename, TRUE);
 39.1197 +
 39.1198 +    if (info != NULL)
 39.1199 +        g_free(info->start_time);
 39.1200 +
 39.1201 +    if (info != NULL)
 39.1202 +        g_free(info->end_time);
 39.1203 +
 39.1204 +    g_free(info);
 39.1205 +}
 39.1206 +
 39.1207 +static void
 39.1208 +free_recorded_info_item(gpointer data, gpointer user_data)
 39.1209 +{
 39.1210 +    RecordedInfo   *info = (RecordedInfo *) data;
 39.1211 +
 39.1212 +    gmyth_recorded_info_free(info);
 39.1213 +}
 39.1214 +
 39.1215 +void
 39.1216 +gmyth_recorded_info_list_free(GList * list)
 39.1217 +{
 39.1218 +    g_return_if_fail(list != NULL);
 39.1219 +
 39.1220 +    g_list_foreach(list, free_recorded_info_item, NULL);
 39.1221 +    g_list_free(list);
 39.1222 +}
 39.1223 +
 39.1224 +void
 39.1225 +gmyth_schedule_info_free(ScheduleInfo * info)
 39.1226 +{
 39.1227 +
 39.1228 +    g_return_if_fail(info != NULL);
 39.1229 +
 39.1230 +    if (info->program_id)
 39.1231 +        g_string_free (info->program_id, TRUE);
 39.1232 +
 39.1233 +    if (info->title != NULL)
 39.1234 +        g_string_free(info->title, TRUE);
 39.1235 +
 39.1236 +    if (info->subtitle != NULL)
 39.1237 +        g_string_free(info->subtitle, TRUE);
 39.1238 +
 39.1239 +    if (info->description != NULL)
 39.1240 +        g_string_free(info->description, TRUE);
 39.1241 +
 39.1242 +    if (info->category != NULL)
 39.1243 +        g_string_free(info->category, TRUE);
 39.1244 +
 39.1245 +    if (info != NULL)
 39.1246 +        g_free(info->start_time);
 39.1247 +
 39.1248 +    if (info != NULL)
 39.1249 +        g_free(info->end_time);
 39.1250 +
 39.1251 +    g_free(info);
 39.1252 +}
 39.1253 +
 39.1254 +static void
 39.1255 +free_schedule_info_item(gpointer data, gpointer user_data)
 39.1256 +{
 39.1257 +    ScheduleInfo   *info = (ScheduleInfo *) data;
 39.1258 +
 39.1259 +    gmyth_schedule_info_free(info);
 39.1260 +}
 39.1261 +
 39.1262 +void
 39.1263 +gmyth_schedule_info_list_free(GList * list)
 39.1264 +{
 39.1265 +    g_return_if_fail(list != NULL);
 39.1266 +
 39.1267 +    g_list_foreach(list, free_schedule_info_item, NULL);
 39.1268 +    g_list_free(list);
 39.1269 +}
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/gmyth/gmyth/gmyth_scheduler.h	Mon Feb 25 17:51:43 2008 +0000
    40.3 @@ -0,0 +1,194 @@
    40.4 +/**
    40.5 + * GMyth Library
    40.6 + *
    40.7 + * @file gmyth/gmyth_scheduler.h
    40.8 + *
    40.9 + * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
   40.10 + * and modifying the recorded content.
   40.11 + *
   40.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   40.13 + * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
   40.14 + *
   40.15 + *
   40.16 + * This program is free software; you can redistribute it and/or modify
   40.17 + * it under the terms of the GNU Lesser General Public License as published by
   40.18 + * the Free Software Foundation; either version 2 of the License, or
   40.19 + * (at your option) any later version.
   40.20 + *
   40.21 + * This program is distributed in the hope that it will be useful,
   40.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   40.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   40.24 + * GNU General Public License for more details.
   40.25 + *
   40.26 + * You should have received a copy of the GNU Lesser General Public License
   40.27 + * along with this program; if not, write to the Free Software
   40.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   40.29 + */
   40.30 +
   40.31 +#ifndef __GMYTH_SCHEDULER_H__
   40.32 +#define __GMYTH_SCHEDULER_H__
   40.33 +
   40.34 +#include <glib-object.h>
   40.35 +#include <time.h>
   40.36 +
   40.37 +#include "gmyth_common.h"
   40.38 +#include "gmyth_query.h"
   40.39 +#include "gmyth_backendinfo.h"
   40.40 +
   40.41 +G_BEGIN_DECLS
   40.42 +
   40.43 +typedef enum {
   40.44 +    GMYTH_SCHEDULE_ONE_OCCURRENCE,
   40.45 +    GMYTH_SCHEDULE_ALL_OCCURRENCES,
   40.46 +    GMYTH_SCHEDULE_EXCEPTION
   40.47 +} GMythScheduleType;
   40.48 +
   40.49 +
   40.50 +#define GMYTH_SCHEDULER_TYPE               (gmyth_scheduler_get_type ())
   40.51 +#define GMYTH_SCHEDULER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SCHEDULER_TYPE, GMythScheduler))
   40.52 +#define GMYTH_SCHEDULER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
   40.53 +#define IS_GMYTH_SCHEDULER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_SCHEDULER_TYPE))
   40.54 +#define IS_GMYTH_SCHEDULER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE))
   40.55 +#define GMYTH_SCHEDULER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
   40.56 +
   40.57 +typedef struct _GMythScheduler GMythScheduler;
   40.58 +typedef struct _GMythSchedulerClass GMythSchedulerClass;
   40.59 +
   40.60 +struct _GMythSchedulerClass {
   40.61 +    GObjectClass    parent_class;
   40.62 +};
   40.63 +
   40.64 +struct _GMythScheduler {
   40.65 +    GObject         parent;
   40.66 +
   40.67 +    unsigned long   recordid;
   40.68 +    unsigned long   type;
   40.69 +    unsigned long   search;
   40.70 +    GString        *profile;
   40.71 +
   40.72 +    long            dupin;
   40.73 +    long            dupmethod;
   40.74 +    long            autoexpire;
   40.75 +    short int       autotranscode;
   40.76 +    long            transcoder;
   40.77 +
   40.78 +    short int       autocommflag;
   40.79 +    short int       autouserjob1;
   40.80 +    short int       autouserjob2;
   40.81 +    short int       autouserjob3;
   40.82 +    short int       autouserjob4;
   40.83 +
   40.84 +    long            startoffset;
   40.85 +    long            endoffset;
   40.86 +    long            maxepisodes;
   40.87 +    long            maxnewest;
   40.88 +
   40.89 +    long            recpriority;
   40.90 +    GString        *recgroup;
   40.91 +    GString        *playgroup;
   40.92 +
   40.93 +    long            prefinput;
   40.94 +    short int       inactive;
   40.95 +
   40.96 +    GString        *search_type;
   40.97 +    GString        *search_what;
   40.98 +
   40.99 +    GMythQuery     *msqlquery;
  40.100 +    GMythBackendInfo *backend_info;
  40.101 +};
  40.102 +
  40.103 +typedef struct {
  40.104 +    guint           schedule_id;
  40.105 +    gint            channel_id;
  40.106 +    GString        *program_id;
  40.107 +
  40.108 +    GTimeVal       *start_time;
  40.109 +    GTimeVal       *end_time;
  40.110 +
  40.111 +    GString        *seriesid;
  40.112 +    GString        *title;
  40.113 +    GString        *subtitle;
  40.114 +    GString        *description;
  40.115 +    GString        *category;
  40.116 +
  40.117 +    GMythScheduleType type;
  40.118 +
  40.119 +    gint parentid;
  40.120 +
  40.121 +} ScheduleInfo;
  40.122 +
  40.123 +typedef struct {
  40.124 +    guint           record_id;
  40.125 +    gint            channel_id;
  40.126 +    GString        *program_id;
  40.127 +
  40.128 +    GTimeVal       *start_time;
  40.129 +    GTimeVal       *end_time;
  40.130 +
  40.131 +    GString         *seriesid;
  40.132 +    GString        *title;
  40.133 +    GString        *subtitle;
  40.134 +    GString        *description;
  40.135 +    GString        *category;
  40.136 +
  40.137 +    GString        *basename;
  40.138 +
  40.139 +    guint64         filesize;
  40.140 +
  40.141 +} RecordedInfo;
  40.142 +
  40.143 +
  40.144 +GType               gmyth_scheduler_get_type                (void);
  40.145 +
  40.146 +GMythScheduler*     gmyth_scheduler_new                     (void);
  40.147 +gboolean            gmyth_scheduler_connect                 (GMythScheduler * scheduler,
  40.148 +                                                             GMythBackendInfo * backend_info);
  40.149 +gboolean            gmyth_scheduler_connect_with_timeout    (GMythScheduler * scheduler,
  40.150 +                                                             GMythBackendInfo * backend_info,
  40.151 +                                                             guint timeout);
  40.152 +gboolean            gmyth_scheduler_disconnect              (GMythScheduler * scheduler);
  40.153 +gint                gmyth_scheduler_get_schedule_list       (GMythScheduler * scheduler,
  40.154 +                                                             GList ** sched_list);
  40.155 +gint                gmyth_scheduler_get_recorded_list       (GMythScheduler * scheduler,
  40.156 +                                                             GList ** rec_list);
  40.157 +RecordedInfo*       gmyth_scheduler_get_recorded_info       (GMythScheduler *scheduler,
  40.158 +                                                             const char *basename);
  40.159 +gboolean            gmyth_scheduler_was_recorded_before     (GMythScheduler* scheduler,
  40.160 +                                                             gint channel_id,
  40.161 +                                                             time_t start_time);
  40.162 +gboolean            gmyth_scheduler_reactivate_schedule     (GMythScheduler* scheduler,
  40.163 +                                                             gint channel_id,
  40.164 +                                                             time_t start_time);
  40.165 +GMythProgramInfo*   gmyth_scheduler_get_recorded_on_time    (GMythScheduler* scheduler,
  40.166 +                                                             guint channel_id);
  40.167 +GMythProgramInfo*   gmyth_scheduler_get_recorded            (GMythScheduler * scheduler,
  40.168 +                                                             GString * channel,
  40.169 +                                                             GTimeVal * starttime);
  40.170 +ScheduleInfo*       gmyth_scheduler_add_schedule_program    (GMythScheduler * scheduler,
  40.171 +                                                             GMythProgramInfo *program,
  40.172 +                                                             GMythScheduleType type);
  40.173 +gint                gmyth_scheduler_add_schedule            (GMythScheduler * scheduler,
  40.174 +                                                             ScheduleInfo * schedule_info);
  40.175 +gboolean            gmyth_scheduler_add_schedule_full       (GMythScheduler * scheduler,
  40.176 +                                                             ScheduleInfo * schedule_info,
  40.177 +                                                             GMythScheduleType type);
  40.178 +gboolean            gmyth_scheduler_add_exception           (GMythScheduler *scheduler,
  40.179 +                                                             gint schedule_id,
  40.180 +                                                             ScheduleInfo *exception_info);
  40.181 +gboolean            gmyth_scheduler_delete_schedule         (GMythScheduler * scheduler,
  40.182 +                                                             gint record_id);
  40.183 +gint                gmyth_scheduler_delete_recorded         (GMythScheduler * scheduler,
  40.184 +                                                             gint record_id);
  40.185 +gboolean            gmyth_scheduler_stop_recording          (GMythScheduler * scheduler,
  40.186 +                                                             gint channel_id);
  40.187 +void                gmyth_scheduler_recorded_info_get_preview(RecordedInfo * info,
  40.188 +                                                             GByteArray * data);
  40.189 +
  40.190 +
  40.191 +void                gmyth_recorded_info_free                (RecordedInfo * info);
  40.192 +void                gmyth_schedule_info_free                (ScheduleInfo * info);
  40.193 +void                gmyth_recorded_info_list_free           (GList * list);
  40.194 +void                gmyth_schedule_info_list_free           (GList * list);
  40.195 +
  40.196 +G_END_DECLS
  40.197 +#endif                          /* __GMYTH_SCHEDULER_H__ */
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/gmyth/gmyth/gmyth_socket.c	Mon Feb 25 17:51:43 2008 +0000
    41.3 @@ -0,0 +1,1295 @@
    41.4 +/**
    41.5 + * GMyth Library
    41.6 + *
    41.7 + * @file gmyth/gmyth_socket.c
    41.8 + * 
    41.9 + * @brief <p> MythTV socket implementation, according to the MythTV Project
   41.10 + * (www.mythtv.org). 
   41.11 + * 
   41.12 + * This component provides basic socket functionalities to interact with
   41.13 + * the Mythtv backend.
   41.14 + * <p>
   41.15 + *
   41.16 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   41.17 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br> 
   41.18 + *
   41.19 + * 
   41.20 + * This program is free software; you can redistribute it and/or modify
   41.21 + * it under the terms of the GNU Lesser General Public License as published by
   41.22 + * the Free Software Foundation; either version 2 of the License, or
   41.23 + * (at your option) any later version.
   41.24 + *
   41.25 + * This program is distributed in the hope that it will be useful,
   41.26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   41.27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   41.28 + * GNU General Public License for more details.
   41.29 + *
   41.30 + * You should have received a copy of the GNU Lesser General Public License
   41.31 + * along with this program; if not, write to the Free Software
   41.32 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   41.33 + */
   41.34 +
   41.35 +#ifdef HAVE_CONFIG_H
   41.36 +#include "config.h"
   41.37 +#endif
   41.38 +
   41.39 +#include "gmyth_socket.h"
   41.40 +
   41.41 +#include <glib.h>
   41.42 +#include <glib/gprintf.h>
   41.43 +
   41.44 +#include <arpa/inet.h>
   41.45 +#include <sys/types.h>
   41.46 +#include <sys/socket.h>
   41.47 +#include <sys/param.h>
   41.48 +#include <netdb.h>
   41.49 +#include <net/if.h>
   41.50 +#include <errno.h>
   41.51 +#include <assert.h>
   41.52 +#include <stdlib.h>
   41.53 +
   41.54 +#include <unistd.h>
   41.55 +#include <netinet/in.h>
   41.56 +#include <fcntl.h>
   41.57 +#include <signal.h>
   41.58 +
   41.59 +#include <sys/ioctl.h>
   41.60 +
   41.61 +#include "gmyth_stringlist.h"
   41.62 +#include "gmyth_uri.h"
   41.63 +#include "gmyth_debug.h"
   41.64 +
   41.65 +#define BUFLEN 				   	512
   41.66 +#define MYTH_SEPARATOR 			    	"[]:[]"
   41.67 +#define MYTH_PROTOCOL_FIELD_SIZE		8
   41.68 +
   41.69 +/*
   41.70 + * max number of iterations 
   41.71 + */
   41.72 +#define MYTHTV_MAX_VERSION_CHECKS		40
   41.73 +
   41.74 +// FIXME: put this in the right place
   41.75 +#define  MYTHTV_VERSION_DEFAULT			31
   41.76 +
   41.77 +/*
   41.78 + * static GStaticMutex mutex = G_STATIC_MUTEX_INIT; 
   41.79 + */
   41.80 +
   41.81 +/*
   41.82 + * static GStaticRWLock rwlock = G_STATIC_RW_LOCK_INIT;
   41.83 + */
   41.84 +
   41.85 +static gchar   *local_hostname = NULL;
   41.86 +
   41.87 +static void     gmyth_socket_class_init(GMythSocketClass * klass);
   41.88 +static void     gmyth_socket_init(GMythSocket * object);
   41.89 +
   41.90 +static void     gmyth_socket_dispose(GObject * object);
   41.91 +static void     gmyth_socket_finalize(GObject * object);
   41.92 +
   41.93 +G_DEFINE_TYPE(GMythSocket, gmyth_socket, G_TYPE_OBJECT)
   41.94 +    static void     gmyth_socket_class_init(GMythSocketClass * klass)
   41.95 +{
   41.96 +    GObjectClass   *gobject_class;
   41.97 +
   41.98 +    gobject_class = (GObjectClass *) klass;
   41.99 +
  41.100 +    gobject_class->dispose = gmyth_socket_dispose;
  41.101 +    gobject_class->finalize = gmyth_socket_finalize;
  41.102 +}
  41.103 +
  41.104 +static void
  41.105 +gmyth_socket_init(GMythSocket * gmyth_socket)
  41.106 +{
  41.107 +
  41.108 +    /*
  41.109 +     * gmyth_socket->local_hostname = NULL; 
  41.110 +     */
  41.111 +
  41.112 +}
  41.113 +
  41.114 +/** Gets the some important address translation info, from the client socket
  41.115 + * that will open a connection.
  41.116 + * 
  41.117 + * @return gint that represents the error number from getaddrinfo(). 
  41.118 + */
  41.119 +static          gint
  41.120 +gmyth_socket_toaddrinfo(const gchar * addr, gint port,
  41.121 +                        struct addrinfo **addrInfo)
  41.122 +{
  41.123 +    struct addrinfo hints;
  41.124 +    gchar          *portStr = NULL;
  41.125 +    gint            errorn = EADDRNOTAVAIL;
  41.126 +
  41.127 +    g_return_val_if_fail(addr != NULL, -1);
  41.128 +
  41.129 +    memset(&hints, 0, sizeof(struct addrinfo));
  41.130 +    hints.ai_family = AF_INET;
  41.131 +    hints.ai_socktype = SOCK_STREAM;
  41.132 +    /*
  41.133 +     * hints.ai_flags = AI_NUMERICHOST; 
  41.134 +     */
  41.135 +
  41.136 +    if (port != -1)
  41.137 +        portStr = g_strdup_printf("%d", port);
  41.138 +    else
  41.139 +        portStr = NULL;
  41.140 +
  41.141 +    gmyth_debug("Getting name resolution for: %s, %d\n", addr, port);
  41.142 +
  41.143 +    if ((errorn = getaddrinfo(addr, portStr, &hints, addrInfo)) != 0) {
  41.144 +        gmyth_debug("[%s] Socket ERROR: %s\n", __FUNCTION__,
  41.145 +                    gai_strerror(errorn));
  41.146 +    }
  41.147 +
  41.148 +    g_free(portStr);
  41.149 +
  41.150 +    return errorn;
  41.151 +}
  41.152 +
  41.153 +/*
  41.154 + * static gint gmyth_socket_find_match_address_uri( GMythURI* uri, gchar
  41.155 + * *address ) { if ( g_ascii_strcasecmp( gmyth_uri_get_host( uri ),
  41.156 + * address ) == 0 ) { //gmyth_debug( "Found URI: %s !!!\n",
  41.157 + * rui_uri_getvalue(uri) ); return 0; } else { return -1; } } 
  41.158 + */
  41.159 +
  41.160 +const gchar    *PATH_PROC_NET_DEV = "/proc/net/dev";
  41.161 +
  41.162 +/** Gets the list of all local network interfaces (using the /proc/net/dev directory).
  41.163 + * 
  41.164 + * @param current_connections	A list with all the network interfaces are valid, 
  41.165 + * 		to be applied just like a filter.
  41.166 + * @return List with all the local net interfaces. 
  41.167 + */
  41.168 +GList          *
  41.169 +gmyth_socket_get_local_addrs(GList * current_connections)
  41.170 +{
  41.171 +
  41.172 +    GList          *local_addrs = NULL;
  41.173 +    FILE           *fd;
  41.174 +    gint            s;
  41.175 +    gchar           buffer[256 + 1];
  41.176 +    gchar           ifaddr[20 + 1];
  41.177 +    gchar          *ifname;
  41.178 +    gchar          *sep;
  41.179 +
  41.180 +    s = socket(AF_INET, SOCK_DGRAM, 0);
  41.181 +    if (s < 0)
  41.182 +        return 0;
  41.183 +    fd = fopen(PATH_PROC_NET_DEV, "r");
  41.184 +    fgets(buffer, sizeof(buffer) - 1, fd);
  41.185 +    fgets(buffer, sizeof(buffer) - 1, fd);
  41.186 +    while (!feof(fd)) {
  41.187 +        ifname = buffer;
  41.188 +
  41.189 +        if (fgets(buffer, sizeof(buffer) - 1, fd) == NULL)
  41.190 +            break;
  41.191 +        sep = strrchr(buffer, ':');
  41.192 +        if (sep)
  41.193 +            *sep = 0;
  41.194 +        while (*ifname == ' ')
  41.195 +            ifname++;
  41.196 +        struct ifreq    req;
  41.197 +
  41.198 +        strcpy(req.ifr_name, ifname);
  41.199 +        if (ioctl(s, SIOCGIFFLAGS, &req) < 0)
  41.200 +            continue;
  41.201 +        if (!(req.ifr_flags & IFF_UP))
  41.202 +            continue;
  41.203 +        if (req.ifr_flags & IFF_LOOPBACK)
  41.204 +            continue;
  41.205 +        if (ioctl(s, SIOCGIFADDR, &req) < 0)
  41.206 +            continue;
  41.207 +        g_strlcpy(ifaddr,
  41.208 +                  inet_ntoa(((struct sockaddr_in *) &req.ifr_addr)->
  41.209 +                            sin_addr), sizeof(struct ifaddr) - 1);
  41.210 +        local_addrs = g_list_append(local_addrs, g_strdup(ifaddr));
  41.211 +
  41.212 +        gmyth_debug
  41.213 +            ("( from the /proc/net/dev) Interface name: %s, address: %s\n",
  41.214 +             ifname, ifaddr);
  41.215 +    }
  41.216 +    fclose(fd);
  41.217 +    close(s);
  41.218 +    return local_addrs;
  41.219 +}
  41.220 +
  41.221 +/**
  41.222 + * Get only the local addresses from the primary interface
  41.223 + */
  41.224 +gchar          *
  41.225 +gmyth_socket_get_primary_addr(void)
  41.226 +{
  41.227 +    gchar          *if_eth0 = g_new0(gchar, sizeof(struct ifaddr) - 1);
  41.228 +    GList          *if_tmp = NULL;
  41.229 +
  41.230 +    GList          *interfs = gmyth_socket_get_local_addrs(NULL);
  41.231 +
  41.232 +    if (interfs != NULL && (g_list_length(interfs) > 0)) {
  41.233 +        // get the first occurrence (primary interface) 
  41.234 +        if_tmp = g_list_first(interfs);
  41.235 +
  41.236 +        if (if_tmp != NULL)
  41.237 +            g_strlcpy(if_eth0, (gchar *) if_tmp->data,
  41.238 +                      sizeof(struct ifaddr) - 1);
  41.239 +
  41.240 +    }
  41.241 +
  41.242 +    if (interfs != NULL)
  41.243 +        g_list_free(interfs);
  41.244 +
  41.245 +    return if_eth0;
  41.246 +}
  41.247 +
  41.248 +/** This function retrieves the local hostname of the 
  41.249 + * client machine.
  41.250 + *
  41.251 + * @return GString* get local hostname.
  41.252 + */
  41.253 +GString        *
  41.254 +gmyth_socket_get_local_hostname(void)
  41.255 +{
  41.256 +    char            hname[50];
  41.257 +    gint            res = gethostname(hname, 50);
  41.258 +
  41.259 +    if (res == -1) {
  41.260 +        gmyth_debug("Error while getting hostname");
  41.261 +        return g_string_new("default");
  41.262 +    }
  41.263 +
  41.264 +    return g_string_new(hname);
  41.265 +
  41.266 +#if 0
  41.267 +    GString        *str = NULL;
  41.268 +
  41.269 +    if (local_hostname != NULL && strlen(local_hostname) > 0)
  41.270 +        return g_string_new(local_hostname);
  41.271 +
  41.272 +    gchar          *localaddr = NULL;
  41.273 +    gboolean        found_addr = FALSE;
  41.274 +    struct addrinfo *addr_info_data = NULL,
  41.275 +        *addr_info0 = NULL;
  41.276 +    struct sockaddr_in *sa = NULL;
  41.277 +    gchar           localhostname[MAXHOSTNAMELEN];
  41.278 +
  41.279 +
  41.280 +    if (gethostname(localhostname, MAXHOSTNAMELEN) != 0) {
  41.281 +        gmyth_debug("Error on gethostname");
  41.282 +    }
  41.283 +    localhostname[MAXHOSTNAMELEN - 1] = 0;
  41.284 +
  41.285 +    gint            err =
  41.286 +        gmyth_socket_toaddrinfo(localhostname, -1, &addr_info_data);
  41.287 +
  41.288 +    if (err == EADDRNOTAVAIL) {
  41.289 +        gmyth_debug("[%s] Address (%s) not available. (reason = %d)\n",
  41.290 +                    __FUNCTION__, localhostname, err);
  41.291 +        return str;
  41.292 +    }
  41.293 +
  41.294 +    g_mutex_lock(gmyth_socket->mutex);
  41.295 +
  41.296 +    addr_info0 = addr_info_data;
  41.297 +
  41.298 +    while (addr_info0 != NULL && addr_info0->ai_addr != NULL &&
  41.299 +           (sa = (struct sockaddr_in *) addr_info0->ai_addr) != NULL
  41.300 +           && !found_addr) {
  41.301 +        localaddr = inet_ntoa(sa->sin_addr);
  41.302 +
  41.303 +        if (localaddr != NULL && (g_strrstr(localaddr, "127") == NULL)) {
  41.304 +            str = g_string_new(localaddr);
  41.305 +            found_addr = TRUE;
  41.306 +            g_free(localaddr);
  41.307 +            break;
  41.308 +        }
  41.309 +        /*
  41.310 +         * if (localaddr != NULL) { g_free (localaddr); localaddr = NULL;
  41.311 +         * } 
  41.312 +         */
  41.313 +
  41.314 +        addr_info0 = addr_info0->ai_next;
  41.315 +    };
  41.316 +
  41.317 +    freeaddrinfo(addr_info_data);
  41.318 +    addr_info_data = NULL;
  41.319 +
  41.320 +    if (found_addr == FALSE) {
  41.321 +        gchar          *prim_addr = gmyth_socket_get_primary_addr();
  41.322 +
  41.323 +        if (prim_addr != NULL) {
  41.324 +            gmyth_debug
  41.325 +                ("[%s] Could not determine the local alphanumerical hostname. Setting to %s\n",
  41.326 +                 __FUNCTION__, prim_addr);
  41.327 +
  41.328 +            str = g_string_new(prim_addr);
  41.329 +            g_free(prim_addr);
  41.330 +        } else {
  41.331 +            str = g_string_new(localhostname);
  41.332 +        }
  41.333 +    }
  41.334 +
  41.335 +    g_mutex_unlock(gmyth_socket->mutex);
  41.336 +
  41.337 +    if (str != NULL && str->str != NULL)
  41.338 +        local_hostname = g_strdup(str->str);
  41.339 +
  41.340 +    return str;
  41.341 +#endif
  41.342 +}
  41.343 +
  41.344 +static void
  41.345 +gmyth_socket_dispose(GObject * object)
  41.346 +{
  41.347 +    GMythSocket    *gmyth_socket = GMYTH_SOCKET(object);
  41.348 +
  41.349 +    /*
  41.350 +     * disconnect socket 
  41.351 +     */
  41.352 +    gmyth_socket_close_connection(gmyth_socket);
  41.353 +
  41.354 +    g_free(gmyth_socket->hostname);
  41.355 +
  41.356 +    g_free(local_hostname);
  41.357 +
  41.358 +    local_hostname = NULL;
  41.359 +
  41.360 +    if (gmyth_socket->mutex != NULL) {
  41.361 +        g_mutex_free(gmyth_socket->mutex);
  41.362 +        gmyth_socket->mutex = NULL;
  41.363 +    }
  41.364 +
  41.365 +    G_OBJECT_CLASS(gmyth_socket_parent_class)->dispose(object);
  41.366 +}
  41.367 +
  41.368 +static void
  41.369 +gmyth_socket_finalize(GObject * object)
  41.370 +{
  41.371 +    g_signal_handlers_destroy(object);
  41.372 +
  41.373 +    G_OBJECT_CLASS(gmyth_socket_parent_class)->finalize(object);
  41.374 +}
  41.375 +
  41.376 +/** Creates a new instance of GMythSocket.
  41.377 + * 
  41.378 + * @return a new instance of GMythSocket.
  41.379 + */
  41.380 +GMythSocket    *
  41.381 +gmyth_socket_new()
  41.382 +{
  41.383 +    GMythSocket    *gmyth_socket =
  41.384 +        GMYTH_SOCKET(g_object_new(GMYTH_SOCKET_TYPE, NULL));
  41.385 +
  41.386 +    gmyth_socket->mythtv_version = MYTHTV_VERSION_DEFAULT;
  41.387 +
  41.388 +    gmyth_socket->mutex = g_mutex_new();
  41.389 +
  41.390 +    return gmyth_socket;
  41.391 +}
  41.392 +
  41.393 +/** Try to open an asynchronous connection to the MythTV backend.
  41.394 + * 
  41.395 + * @param fd 		Socket descriptor.
  41.396 + * @param remote 	Remote address.
  41.397 + * @param len 		Newly created socket length field.
  41.398 + * @param timeout	Timeval argument with the time interval to timeout before closing.
  41.399 + * @param err		Error message number.
  41.400 + * @return Any numerical value below 0, if an error had been found.
  41.401 + */
  41.402 +static          gint
  41.403 +gmyth_socket_try_connect(gint fd, struct sockaddr *remote, gint len,
  41.404 +                         struct timeval *timeout, gint * err)
  41.405 +{
  41.406 +    /*
  41.407 +     * g_return_val_if_fail( timeout != NULL, 0 ); 
  41.408 +     */
  41.409 +    gint            saveflags,
  41.410 +                    ret,
  41.411 +                    back_err;
  41.412 +
  41.413 +    fd_set          fd_w;
  41.414 +
  41.415 +    saveflags = fcntl(fd, F_GETFL, 0);
  41.416 +    if (saveflags < 0) {
  41.417 +        gmyth_debug("[%s] Problems when getting socket flags on fcntl.\n",
  41.418 +                    __FUNCTION__);
  41.419 +        *err = errno;
  41.420 +        return -1;
  41.421 +    }
  41.422 +
  41.423 +    /*
  41.424 +     * Set non blocking 
  41.425 +     */
  41.426 +    if (fcntl(fd, F_SETFL, saveflags | O_NONBLOCK) < 0) {
  41.427 +        gmyth_debug
  41.428 +            ("[%s] Problems when setting non-blocking using fcntl.\n",
  41.429 +             __FUNCTION__);
  41.430 +        *err = errno;
  41.431 +        return -1;
  41.432 +    }
  41.433 +
  41.434 +    /*
  41.435 +     * This will return immediately 
  41.436 +     */
  41.437 +    *err = connect(fd, remote, len);
  41.438 +    back_err = errno;
  41.439 +
  41.440 +    /*
  41.441 +     * restore flags 
  41.442 +     */
  41.443 +    if (fcntl(fd, F_SETFL, saveflags) < 0) {
  41.444 +        gmyth_debug
  41.445 +            ("[%s] Problems when trying to restore flags with fcntl.\n",
  41.446 +             __FUNCTION__);
  41.447 +        *err = errno;
  41.448 +        return -1;
  41.449 +    }
  41.450 +
  41.451 +    /*
  41.452 +     * return unless the connection was successful or the connect is still 
  41.453 +     * in progress. 
  41.454 +     */
  41.455 +    if (*err < 0 && back_err != EINPROGRESS) {
  41.456 +        gmyth_debug
  41.457 +            ("[%s] Connection unsucessfully (it is not in progress).\n",
  41.458 +             __FUNCTION__);
  41.459 +        *err = errno;
  41.460 +        return -1;
  41.461 +    }
  41.462 +
  41.463 +    FD_ZERO(&fd_w);
  41.464 +    FD_SET(fd, &fd_w);
  41.465 +
  41.466 +    *err = select(FD_SETSIZE, NULL, &fd_w, NULL, timeout);
  41.467 +    if (*err < 0) {
  41.468 +        gmyth_debug("[%s] Connection unsucessfull (timed out).\n",
  41.469 +                    __FUNCTION__);
  41.470 +        *err = errno;
  41.471 +        return -1;
  41.472 +    }
  41.473 +
  41.474 +    /*
  41.475 +     * 0 means it timeout out & no fds changed 
  41.476 +     */
  41.477 +    if (*err == 0) {
  41.478 +        gmyth_debug
  41.479 +            ("[%s] Connection unsucessfull [%d] - 0 means it timeout out & no fds changed\n",
  41.480 +             __FUNCTION__, *err);
  41.481 +        close(fd);
  41.482 +        *err = ETIMEDOUT;
  41.483 +        return -1;
  41.484 +    }
  41.485 +
  41.486 +    /*
  41.487 +     * Get the return code from the connect 
  41.488 +     */
  41.489 +    len = sizeof(ret);
  41.490 +    *err = getsockopt(fd, SOL_SOCKET, SO_ERROR, &ret, (socklen_t *) & len);
  41.491 +
  41.492 +    if (*err < 0) {
  41.493 +        gmyth_debug("[%s] Connection unsucessfull.\n", __FUNCTION__);
  41.494 +        *err = errno;
  41.495 +        return -1;
  41.496 +    }
  41.497 +
  41.498 +    /*
  41.499 +     * ret=0 means success, otherwise it contains the errno 
  41.500 +     */
  41.501 +    if (ret) {
  41.502 +        gmyth_debug
  41.503 +            ("[%s] Connection unsucessfull - Couldn't connect to remote host!!!\n",
  41.504 +             __FUNCTION__);
  41.505 +        *err = ret;
  41.506 +        return -1;
  41.507 +    }
  41.508 +
  41.509 +    *err = 0;
  41.510 +    return 0;
  41.511 +}
  41.512 +
  41.513 +/** Connects to the backend.
  41.514 + * 
  41.515 + * @param gmyth_socket The GMythSocket instance.
  41.516 + * @param hostname The backend hostname or IP address.
  41.517 + * @param port The backend port.
  41.518 + * @return TRUE if success, FALSE if error.
  41.519 + */
  41.520 +
  41.521 +
  41.522 +gboolean
  41.523 +gmyth_socket_connect(GMythSocket * gmyth_socket,
  41.524 +                     const gchar * hostname, gint port)
  41.525 +{
  41.526 +    return gmyth_socket_connect_with_timeout(gmyth_socket, hostname, port,
  41.527 +                                             30);
  41.528 +}
  41.529 +
  41.530 +gboolean
  41.531 +gmyth_socket_connect_with_timeout(GMythSocket * gmyth_socket,
  41.532 +                                  const gchar * hostname, gint port,
  41.533 +                                  guint timeout)
  41.534 +{
  41.535 +    struct addrinfo *addr_info_data = NULL,
  41.536 +        *addr_info0 = NULL;
  41.537 +    struct linger   ling;
  41.538 +    gchar          *tmp_str;
  41.539 +    gint            ret_code = 0;   /* -1 */
  41.540 +
  41.541 +    /*
  41.542 +     * FIXME: add as function parameter 
  41.543 +     */
  41.544 +    gint            err;
  41.545 +    gint            errno;
  41.546 +    gboolean        ret = TRUE;
  41.547 +
  41.548 +    gmyth_debug("CONNECTING %s:%d", hostname, port);
  41.549 +
  41.550 +    if (hostname == NULL)
  41.551 +        gmyth_debug("Invalid hostname parameter!\n");
  41.552 +
  41.553 +    /*
  41.554 +     * store hostname and port number 
  41.555 +     */
  41.556 +    gmyth_debug("CONNECTING %s:%d", hostname, port);
  41.557 +
  41.558 +    errno = gmyth_socket_toaddrinfo(hostname, port, &addr_info_data);
  41.559 +
  41.560 +    g_return_val_if_fail(addr_info_data != NULL
  41.561 +                         && hostname != NULL, FALSE);
  41.562 +
  41.563 +    /*
  41.564 +     * hack to avoid deleting the hostname when gmyth_socket->hostname ==
  41.565 +     * hostname 
  41.566 +     */
  41.567 +    tmp_str = gmyth_socket->hostname;
  41.568 +
  41.569 +    gmyth_socket->hostname = g_strdup(hostname);
  41.570 +    gmyth_socket->port = port;
  41.571 +
  41.572 +    g_free(tmp_str);
  41.573 +
  41.574 +    for (addr_info0 = addr_info_data; addr_info0;
  41.575 +         addr_info0 = addr_info_data->ai_next) {
  41.576 +        /*
  41.577 +         * init socket descriptor 
  41.578 +         */
  41.579 +
  41.580 +        g_debug ("FAMILY: %d, TYPE: %d, PROTOCOL: %d", 
  41.581 +                 addr_info0->ai_family,
  41.582 +                 addr_info0->ai_socktype,
  41.583 +                 addr_info0->ai_protocol);
  41.584 +        gmyth_socket->sd =
  41.585 +            socket(addr_info0->ai_family, addr_info0->ai_socktype,
  41.586 +                   addr_info0->ai_protocol);
  41.587 +
  41.588 +        if (gmyth_socket->sd < 0)
  41.589 +            continue;
  41.590 +
  41.591 +        struct timeval *timeout_val = g_new0(struct timeval, 1);
  41.592 +
  41.593 +        if (timeout != 0) {
  41.594 +            timeout_val->tv_sec = timeout;
  41.595 +            timeout_val->tv_usec = 0;
  41.596 +        } else {
  41.597 +            timeout_val->tv_sec = 5;
  41.598 +            timeout_val->tv_usec = 100;
  41.599 +        }
  41.600 +
  41.601 +        if (gmyth_socket_try_connect
  41.602 +            (gmyth_socket->sd, (struct sockaddr *) addr_info0->ai_addr,
  41.603 +             addr_info0->ai_addrlen, timeout_val, &ret_code) < 0) {
  41.604 +            gmyth_debug("[%s] Error connecting to backend!\n",
  41.605 +                        __FUNCTION__);
  41.606 +            if (ret_code == ETIMEDOUT)
  41.607 +                gmyth_debug("[%s]\tBackend host unreachable!\n",
  41.608 +                            __FUNCTION__);
  41.609 +
  41.610 +            close(gmyth_socket->sd);
  41.611 +            gmyth_socket->sd = -1;
  41.612 +            gmyth_debug("ERROR: %s\n", gai_strerror(ret_code));
  41.613 +            g_free(timeout_val);
  41.614 +            continue;
  41.615 +        }
  41.616 +
  41.617 +        g_free(timeout_val);
  41.618 +
  41.619 +        /*
  41.620 +         * only will be reached if none of the error above occurred 
  41.621 +         */
  41.622 +        break;
  41.623 +    }
  41.624 +
  41.625 +    freeaddrinfo(addr_info_data);
  41.626 +    addr_info_data = NULL;
  41.627 +
  41.628 +    if (gmyth_socket->sd_io_ch != NULL) {
  41.629 +        g_io_channel_unref(gmyth_socket->sd_io_ch);
  41.630 +        gmyth_socket->sd_io_ch = NULL;
  41.631 +    }
  41.632 +
  41.633 +
  41.634 +    memset(&ling, 0, sizeof(struct linger));
  41.635 +    ling.l_onoff = TRUE;
  41.636 +    ling.l_linger = 1;
  41.637 +
  41.638 +    err =
  41.639 +        setsockopt(gmyth_socket->sd, SOL_SOCKET, SO_LINGER, &ling,
  41.640 +                   sizeof(struct linger));
  41.641 +
  41.642 +    if (err < 0) {
  41.643 +        gmyth_debug("[%s] Setting connection unsucessfull.\n",
  41.644 +                    __FUNCTION__);
  41.645 +        err = errno;
  41.646 +        ret = FALSE;
  41.647 +        goto cleanup;
  41.648 +    }
  41.649 +
  41.650 +    gmyth_socket->sd_io_ch = g_io_channel_unix_new(gmyth_socket->sd);
  41.651 +
  41.652 +    g_io_channel_set_close_on_unref(gmyth_socket->sd_io_ch, TRUE);
  41.653 +    // g_io_channel_set_encoding (gmyth_socket->sd_io_ch, NULL, NULL );
  41.654 +
  41.655 +    GIOFlags        flags = g_io_channel_get_flags(gmyth_socket->sd_io_ch);
  41.656 +
  41.657 +    /*
  41.658 +     * unset the nonblock flag 
  41.659 +     */
  41.660 +    flags &= ~G_IO_FLAG_NONBLOCK;
  41.661 +    /*
  41.662 +     * unset the nonblocking stuff for some time, because GNUTLS doesn't
  41.663 +     * like that 
  41.664 +     */
  41.665 +    g_io_channel_set_flags(gmyth_socket->sd_io_ch, flags, NULL);
  41.666 +
  41.667 +    ret = (ret_code == 0) ? TRUE : FALSE;
  41.668 +
  41.669 +  cleanup:
  41.670 +    if (!ret)
  41.671 +        gmyth_debug("GMythSocket error - return code error!");
  41.672 +
  41.673 +    return ret;
  41.674 +}
  41.675 +
  41.676 +/** Gets the GIOChannel associated to the given GMythSocket.
  41.677 + * 
  41.678 + * @param gmyth_socket The GMythSocket instance.
  41.679 + */
  41.680 +GIOChannel     *
  41.681 +gmyth_socket_get_io_channel(GMythSocket * gmyth_socket)
  41.682 +{
  41.683 +    g_return_val_if_fail(gmyth_socket != NULL, NULL);
  41.684 +
  41.685 +    return gmyth_socket->sd_io_ch;
  41.686 +}
  41.687 +
  41.688 +/** Verifies if the socket is able to read.
  41.689 + * 
  41.690 + * @param gmyth_socket The GMythSocket instance.
  41.691 + * @return TRUE if the socket is able to read, FALSE if not.
  41.692 + */
  41.693 +gboolean
  41.694 +gmyth_socket_is_able_to_read(GMythSocket * gmyth_socket)
  41.695 +{
  41.696 +    gboolean        ret = TRUE;
  41.697 +
  41.698 +    /*
  41.699 +     * verify if the input (read) buffer is ready to receive data 
  41.700 +     */
  41.701 +    GIOCondition    io_cond =
  41.702 +        g_io_channel_get_buffer_condition(gmyth_socket->sd_io_ch);
  41.703 +
  41.704 +    if ((io_cond & G_IO_IN) == 0) {
  41.705 +        gmyth_debug("[%s] IO channel is not able to send data!\n",
  41.706 +                    __FUNCTION__);
  41.707 +        ret = FALSE;
  41.708 +    }
  41.709 +
  41.710 +    return ret;
  41.711 +
  41.712 +}
  41.713 +
  41.714 +/** Verifies if the socket is able to write.
  41.715 + * 
  41.716 + * @param gmyth_socket The GMythSocket instance.
  41.717 + * @return TRUE if the socket is able to write, FALSE if not.
  41.718 + */
  41.719 +gboolean
  41.720 +gmyth_socket_is_able_to_write(GMythSocket * gmyth_socket)
  41.721 +{
  41.722 +    gboolean        ret = TRUE;
  41.723 +
  41.724 +    /*
  41.725 +     * verify if the input (read) buffer is ready to receive data 
  41.726 +     */
  41.727 +    GIOCondition    io_cond =
  41.728 +        g_io_channel_get_buffer_condition(gmyth_socket->sd_io_ch);
  41.729 +
  41.730 +    if (((io_cond & G_IO_OUT) == 0) || ((io_cond & G_IO_HUP) == 0)) {
  41.731 +        gmyth_debug("[%s] IO channel is not able to send data!\n",
  41.732 +                    __FUNCTION__);
  41.733 +        ret = FALSE;
  41.734 +    }
  41.735 +
  41.736 +    return ret;
  41.737 +
  41.738 +}
  41.739 +
  41.740 +/** Sends a command to the backend.
  41.741 + * 
  41.742 + * @param gmyth_socket the GMythSocket instance.
  41.743 + * @param command The string command to be sent.
  41.744 + */
  41.745 +gboolean
  41.746 +gmyth_socket_send_command(GMythSocket * gmyth_socket, GString * command)
  41.747 +{
  41.748 +    gboolean        ret = TRUE;
  41.749 +
  41.750 +    GIOStatus       io_status = G_IO_STATUS_NORMAL;
  41.751 +
  41.752 +    // GIOCondition io_cond;
  41.753 +    GError         *error = NULL;
  41.754 +
  41.755 +    gchar          *buffer = NULL;
  41.756 +
  41.757 +    gsize           bytes_written = 0;
  41.758 +
  41.759 +    g_return_val_if_fail(gmyth_socket->sd_io_ch != NULL, FALSE);
  41.760 +
  41.761 +    if (command == NULL || (command->len <= 0) || command->str == NULL) {
  41.762 +        gmyth_debug("[%s] Invalid NULL command parameter!\n",
  41.763 +                    __FUNCTION__);
  41.764 +        ret = FALSE;
  41.765 +        goto done;
  41.766 +    }
  41.767 +
  41.768 +    g_mutex_lock(gmyth_socket->mutex);
  41.769 +    gmyth_debug("Sending command to backend: %s\n", command->str);
  41.770 +
  41.771 +    buffer = g_strnfill(BUFLEN, ' ');
  41.772 +    g_snprintf(buffer, MYTH_PROTOCOL_FIELD_SIZE + 1, "%-8d", command->len);
  41.773 +
  41.774 +    command = g_string_prepend(command, buffer);
  41.775 +
  41.776 +    /*
  41.777 +     * write bytes to socket 
  41.778 +     */
  41.779 +    io_status =
  41.780 +        g_io_channel_write_chars(gmyth_socket->sd_io_ch, command->str,
  41.781 +                                 command->len, &bytes_written, &error);
  41.782 +
  41.783 +
  41.784 +    if ((io_status == G_IO_STATUS_ERROR) || (bytes_written <= 0)) {
  41.785 +        gmyth_debug("[%s] Error while writing to socket", __FUNCTION__);
  41.786 +        ret = FALSE;
  41.787 +    } else if (bytes_written < command->len) {
  41.788 +        gmyth_debug("[%s] Not all data was written socket", __FUNCTION__);
  41.789 +        ret = FALSE;
  41.790 +    }
  41.791 +
  41.792 +    io_status = g_io_channel_flush(gmyth_socket->sd_io_ch, &error);
  41.793 +
  41.794 +    if ((bytes_written != command->len)
  41.795 +        || (io_status == G_IO_STATUS_ERROR)) {
  41.796 +        gmyth_debug
  41.797 +            ("[%s] Some problem occurred when sending data to the socket\n",
  41.798 +             __FUNCTION__);
  41.799 +
  41.800 +        ret = TRUE;
  41.801 +    }
  41.802 +
  41.803 +    g_mutex_unlock(gmyth_socket->mutex);
  41.804 +  done:
  41.805 +    if (error != NULL) {
  41.806 +        gmyth_debug
  41.807 +            ("[%s] Error found reading data from IO channel: (%d, %s)\n",
  41.808 +             __FUNCTION__, error->code, error->message);
  41.809 +        ret = FALSE;
  41.810 +        g_error_free(error);
  41.811 +    }
  41.812 +
  41.813 +    if (buffer != NULL)
  41.814 +        g_free(buffer);
  41.815 +
  41.816 +    return ret;
  41.817 +}
  41.818 +
  41.819 +/** Starts Mythtv protocol level connection. Checks Mythtv protocol version
  41.820 + * supported by the backend and send the "ANN" command.
  41.821 + * 
  41.822 + * @param gmyth_socket the GMythSocket instance.
  41.823 + * @param hostname_backend The backend hostname or IP address.
  41.824 + * @param port The backend port to connect.
  41.825 + * @param blocking_client A flag to choose between blocking and non-blocking
  41.826 + * @param with_events	Sets the connection flag to receive events.
  41.827 + * 										backend connection. 
  41.828 + */
  41.829 +static          gboolean
  41.830 +gmyth_socket_connect_to_backend_and_events(GMythSocket * gmyth_socket,
  41.831 +                                           const gchar * hostname_backend,
  41.832 +                                           gint port,
  41.833 +                                           gboolean blocking_client,
  41.834 +                                           gboolean with_events)
  41.835 +{
  41.836 +    if (!gmyth_socket_connect(gmyth_socket, hostname_backend, port)) {
  41.837 +        gmyth_debug("[%s] Could not open socket to backend machine [%s]\n",
  41.838 +                    __FUNCTION__, hostname_backend);
  41.839 +        return FALSE;
  41.840 +    }
  41.841 +
  41.842 +    if (gmyth_socket_check_protocol_version(gmyth_socket)) {
  41.843 +        GString        *result;
  41.844 +        GString        *base_str = g_string_new("");
  41.845 +        GString        *hostname = NULL;
  41.846 +
  41.847 +        hostname = gmyth_socket_get_local_hostname();
  41.848 +        if (hostname == NULL) {
  41.849 +            gmyth_debug
  41.850 +                ("Hostname not available, setting to n800frontend\n");
  41.851 +            hostname = g_string_new("n800frontend");
  41.852 +        }
  41.853 +
  41.854 +        g_string_printf(base_str, "ANN %s %s %u",
  41.855 +                        (blocking_client ? "Playback" : "Monitor"),
  41.856 +                        hostname->str, with_events);
  41.857 +
  41.858 +        gmyth_socket_send_command(gmyth_socket, base_str);
  41.859 +        result = gmyth_socket_receive_response(gmyth_socket);
  41.860 +
  41.861 +        if (result != NULL) {
  41.862 +            gmyth_debug("Response received from backend: %s", result->str);
  41.863 +            g_string_free(result, TRUE);
  41.864 +        }
  41.865 +
  41.866 +        g_string_free(hostname, TRUE);
  41.867 +        g_string_free(base_str, TRUE);
  41.868 +
  41.869 +        return TRUE;
  41.870 +    } else {
  41.871 +        gmyth_debug("[%s] GMythSocket could not connect to the backend",
  41.872 +                    __FUNCTION__);
  41.873 +        return FALSE;
  41.874 +    }
  41.875 +}
  41.876 +
  41.877 +/** Starts Mythtv protocol level connection. Checks Mythtv protocol version
  41.878 + * supported by the backend and send the "ANN" command.
  41.879 + * 
  41.880 + * @param gmyth_socket the GMythSocket instance.
  41.881 + * @param hostname_backend The backend hostname or IP address.
  41.882 + * @param port The backend port to connect.
  41.883 + * @param blocking_client A flag to choose between blocking and non-blocking 
  41.884 + */
  41.885 +gboolean
  41.886 +gmyth_socket_connect_to_backend(GMythSocket * gmyth_socket,
  41.887 +                                const gchar * hostname_backend, gint port,
  41.888 +                                gboolean blocking_client)
  41.889 +{
  41.890 +    if (!gmyth_socket_connect_to_backend_and_events
  41.891 +        (gmyth_socket, hostname_backend, port, blocking_client, FALSE)) {
  41.892 +        gmyth_debug("Could not open socket to backend machine [%s]\n",
  41.893 +                    hostname_backend);
  41.894 +        return FALSE;
  41.895 +    }
  41.896 +
  41.897 +    return TRUE;
  41.898 +
  41.899 +}
  41.900 +
  41.901 +/** Starts Mythtv protocol level connection. Checks Mythtv protocol version
  41.902 + * supported by the backend and send the "ANN" command.
  41.903 + * 
  41.904 + * @param gmyth_socket the GMythSocket instance.
  41.905 + * @param hostname_backend The backend hostname or IP address.
  41.906 + * @param port The backend port to connect.
  41.907 + * @param blocking_client A flag to choose between blocking and non-blocking 
  41.908 + */
  41.909 +gboolean
  41.910 +gmyth_socket_connect_to_backend_events(GMythSocket * gmyth_socket,
  41.911 +                                       const gchar * hostname_backend,
  41.912 +                                       gint port, gboolean blocking_client)
  41.913 +{
  41.914 +    if (!gmyth_socket_connect_to_backend_and_events
  41.915 +        (gmyth_socket, hostname_backend, port, blocking_client, TRUE)) {
  41.916 +        gmyth_debug
  41.917 +            ("Could not open socket to backend machine in order to receive events [%s]\n",
  41.918 +             hostname_backend);
  41.919 +        return FALSE;
  41.920 +    }
  41.921 +
  41.922 +    return TRUE;
  41.923 +}
  41.924 +
  41.925 +/** Closes the socket connection to the backend.
  41.926 + * 
  41.927 + * @param gmyth_socket The GMythSocket instance.
  41.928 + */
  41.929 +void
  41.930 +gmyth_socket_close_connection(GMythSocket * gmyth_socket)
  41.931 +{
  41.932 +    /*
  41.933 +     * if ( gmyth_socket->sd != -1 ) { close (gmyth_socket->sd);
  41.934 +     * gmyth_socket->sd = -1; } 
  41.935 +     */
  41.936 +
  41.937 +    if (gmyth_socket->sd_io_ch != NULL) {
  41.938 +        g_io_channel_shutdown(gmyth_socket->sd_io_ch, TRUE, NULL);
  41.939 +        g_io_channel_unref(gmyth_socket->sd_io_ch);
  41.940 +        gmyth_socket->sd_io_ch = NULL;
  41.941 +        gmyth_socket->sd = -1;
  41.942 +    }
  41.943 +
  41.944 +}
  41.945 +
  41.946 +
  41.947 +/** Try the MythTV version numbers, and get the version returned by
  41.948 + * the possible REJECT message, in order to contruct a new
  41.949 + * MythTV version request.
  41.950 + * 
  41.951 + * @param gmyth_socket The GMythSocket instance.
  41.952 + * @param mythtv_version The Mythtv protocol version to be tested
  41.953 + * 
  41.954 + * @return The actual MythTV the client is connected to.
  41.955 + */
  41.956 +gint
  41.957 +gmyth_socket_check_protocol_version_number(GMythSocket * gmyth_socket,
  41.958 +                                           gint mythtv_version)
  41.959 +{
  41.960 +    GString        *response = NULL;
  41.961 +    GString        *payload = NULL;
  41.962 +    gboolean        res = TRUE;
  41.963 +    gint            mythtv_new_version = MYTHTV_CANNOT_NEGOTIATE_VERSION;
  41.964 +    guint           max_iterations = MYTHTV_MAX_VERSION_CHECKS;
  41.965 +
  41.966 +    assert(gmyth_socket);
  41.967 +
  41.968 +  try_new_version:
  41.969 +    payload = g_string_new("MYTH_PROTO_VERSION");
  41.970 +    g_string_append_printf(payload, " %d", mythtv_version);
  41.971 +
  41.972 +    gmyth_socket_send_command(gmyth_socket, payload);
  41.973 +    response = gmyth_socket_receive_response(gmyth_socket);
  41.974 +
  41.975 +    if (response == NULL) {
  41.976 +        gmyth_debug("[%s] Check protocol version error! Not answered!",
  41.977 +                    __FUNCTION__);
  41.978 +        res = FALSE;
  41.979 +        goto done;
  41.980 +    }
  41.981 +
  41.982 +    res = g_str_has_prefix(response->str, "ACCEPT");
  41.983 +    if (!res) {
  41.984 +        gmyth_debug("[%s] Protocol version request error: %s",
  41.985 +                    __FUNCTION__, response->str);
  41.986 +        /*
  41.987 +         * get the version number returned by the REJECT message 
  41.988 +         */
  41.989 +        if ((res = g_str_has_prefix(response->str, "REJECT")) == TRUE) {
  41.990 +            gchar          *new_version = NULL;
  41.991 +
  41.992 +            new_version = g_strrstr(response->str, "]");
  41.993 +            if (new_version != NULL) {
  41.994 +                ++new_version;  /* skip ']' character */
  41.995 +                if (new_version != NULL) {
  41.996 +                    gmyth_debug("[%s] got MythTV version = %s.\n",
  41.997 +                                __FUNCTION__, new_version);
  41.998 +                    mythtv_version =
  41.999 +                        (gint) g_ascii_strtoull(new_version, NULL, 10);
 41.1000 +                    /*
 41.1001 +                     * do reconnection to the socket (socket is closed if
 41.1002 +                     * the MythTV version was wrong) 
 41.1003 +                     */
 41.1004 +                    gmyth_socket_connect(gmyth_socket,
 41.1005 +                                         gmyth_socket->hostname,
 41.1006 +                                         gmyth_socket->port);
 41.1007 +                    new_version = NULL;
 41.1008 +                    if (--max_iterations > 0) {
 41.1009 +                        g_string_free(payload, TRUE);
 41.1010 +                        g_string_free(response, TRUE);
 41.1011 +                        goto try_new_version;
 41.1012 +                    } else
 41.1013 +                        goto done;
 41.1014 +                }
 41.1015 +            }
 41.1016 +        }
 41.1017 +    }
 41.1018 +
 41.1019 +    /*
 41.1020 +     * change the return value to a valid one 
 41.1021 +     */
 41.1022 +    if (res) {
 41.1023 +        mythtv_new_version = mythtv_version;
 41.1024 +        gmyth_socket->mythtv_version = mythtv_new_version;
 41.1025 +    }
 41.1026 +
 41.1027 +  done:
 41.1028 +    g_string_free(payload, TRUE);
 41.1029 +    g_string_free(response, TRUE);
 41.1030 +
 41.1031 +    return mythtv_new_version;
 41.1032 +}
 41.1033 +
 41.1034 +/** Verifies if the Mythtv backend supported the GMyth supported version.
 41.1035 + * 
 41.1036 + * @param gmyth_socket The GMythSocket instance.
 41.1037 + * @return TRUE if supports, FALSE if not.
 41.1038 + */
 41.1039 +gboolean
 41.1040 +gmyth_socket_check_protocol_version(GMythSocket * gmyth_socket)
 41.1041 +{
 41.1042 +    return ((gmyth_socket->mythtv_version =
 41.1043 +             gmyth_socket_check_protocol_version_number(gmyth_socket,
 41.1044 +                                                        MYTHTV_VERSION_DEFAULT))
 41.1045 +            != MYTHTV_CANNOT_NEGOTIATE_VERSION);
 41.1046 +}
 41.1047 +
 41.1048 +/** Returns the Mythtv backend supported version.
 41.1049 + * 
 41.1050 + * @param gmyth_socket The GMythSocket instance.
 41.1051 + * @return The actual MythTV version number.
 41.1052 + */
 41.1053 +gint
 41.1054 +gmyth_socket_get_protocol_version(GMythSocket * gmyth_socket)
 41.1055 +{
 41.1056 +    return gmyth_socket->mythtv_version;
 41.1057 +}
 41.1058 +
 41.1059 +/** Receives a backend answer after a gmyth_socket_send_command_call ().
 41.1060 + * 
 41.1061 + * @param gmyth_socket The GMythSocket instance.
 41.1062 + * @return The response received, or NULL if error or nothing was received.
 41.1063 + */
 41.1064 +GString        *
 41.1065 +gmyth_socket_receive_response(GMythSocket * gmyth_socket)
 41.1066 +{
 41.1067 +    GIOStatus       io_status = G_IO_STATUS_NORMAL;
 41.1068 +    GError         *error = NULL;
 41.1069 +    gchar          *buffer = NULL;
 41.1070 +
 41.1071 +    GString        *str = NULL;
 41.1072 +
 41.1073 +    gsize           bytes_read = 0;
 41.1074 +    gint            len = 0;
 41.1075 +
 41.1076 +    if (gmyth_socket == NULL)
 41.1077 +        return NULL;
 41.1078 +
 41.1079 +    GIOCondition    io_cond;
 41.1080 +
 41.1081 +    /*
 41.1082 +     * verify if the input (read) buffer is ready to receive data
 41.1083 +     */
 41.1084 +    g_mutex_lock(gmyth_socket->mutex);
 41.1085 +
 41.1086 +    buffer = g_strnfill(MYTH_PROTOCOL_FIELD_SIZE, ' ');
 41.1087 +    if (NULL == gmyth_socket->sd_io_ch) {
 41.1088 +        gmyth_socket_connect(gmyth_socket, gmyth_socket->hostname,
 41.1089 +                             gmyth_socket->port);
 41.1090 +    }
 41.1091 +
 41.1092 +    io_cond = g_io_channel_get_buffer_condition(gmyth_socket->sd_io_ch);
 41.1093 +    /*
 41.1094 +     * if ( NULL == gmyth_socket->sd_io_ch->read_buf || ( NULL ==
 41.1095 +     * gmyth_socket->sd_io_ch->read_buf->str ) ) gmyth_socket->sd_io_ch =
 41.1096 +     * g_io_channel_unix_new( gmyth_socket->sd );
 41.1097 +     */
 41.1098 +
 41.1099 +    if (gmyth_socket->sd_io_ch->is_readable /* && !( ( io_cond & G_IO_IN )
 41.1100 +                                             * == 0 ) */ )
 41.1101 +        io_status =
 41.1102 +            g_io_channel_read_chars(gmyth_socket->sd_io_ch, buffer,
 41.1103 +                                    MYTH_PROTOCOL_FIELD_SIZE, &bytes_read,
 41.1104 +                                    &error);
 41.1105 +    else
 41.1106 +        return g_string_new("");
 41.1107 +
 41.1108 +    /*
 41.1109 +     * verify if the input (read) buffer is ready to receive data 
 41.1110 +     */
 41.1111 +    io_cond = g_io_channel_get_buffer_condition(gmyth_socket->sd_io_ch);
 41.1112 +
 41.1113 +    // if ( ( io_cond & G_IO_IN ) == 0 ) 
 41.1114 +    // return NULL; 
 41.1115 +
 41.1116 +    gmyth_debug("[%s] Bytes read = %d\n", __FUNCTION__, bytes_read);
 41.1117 +
 41.1118 +    if ((io_status == G_IO_STATUS_ERROR) || (bytes_read <= 0)) {
 41.1119 +        gmyth_debug("[%s] Error in mythprotocol response from backend\n",
 41.1120 +                    __FUNCTION__);
 41.1121 +        str = NULL;
 41.1122 +        // return NULL;
 41.1123 +    } else if (buffer != NULL && strlen(buffer) > 0) {
 41.1124 +
 41.1125 +        // io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error
 41.1126 +        // );
 41.1127 +        /*
 41.1128 +         * verify if the input (read) buffer is ready to receive data 
 41.1129 +         */
 41.1130 +        // io_cond = g_io_channel_get_buffer_condition(
 41.1131 +        // gmyth_socket->sd_io_ch );
 41.1132 +
 41.1133 +        // if ( ( io_cond & G_IO_IN ) != 0 ) {
 41.1134 +        // gchar *buffer_aux = NULL;
 41.1135 +
 41.1136 +        /*
 41.1137 +         * removes trailing whitespace 
 41.1138 +         */
 41.1139 +        // buffer_aux = g_strstrip (buffer);
 41.1140 +        len = (gint) g_ascii_strtoull(g_strstrip(buffer), NULL, 10);
 41.1141 +
 41.1142 +        g_free(buffer);
 41.1143 +
 41.1144 +        /*
 41.1145 +         * if (buffer_aux != NULL) { g_free (buffer_aux); buffer_aux =
 41.1146 +         * NULL; } 
 41.1147 +         */
 41.1148 +
 41.1149 +        buffer = g_new0(gchar, len + 1);
 41.1150 +
 41.1151 +        bytes_read = 0;
 41.1152 +        if (!(gmyth_socket != NULL && gmyth_socket->sd_io_ch != NULL))
 41.1153 +            return NULL;
 41.1154 +
 41.1155 +        if (gmyth_socket->sd_io_ch->is_readable)
 41.1156 +            io_status =
 41.1157 +                g_io_channel_read_chars(gmyth_socket->sd_io_ch, buffer,
 41.1158 +                                        len, &bytes_read, &error);
 41.1159 +        else
 41.1160 +            return g_string_new("");
 41.1161 +
 41.1162 +        buffer[bytes_read] = '\0';
 41.1163 +        // }
 41.1164 +    }
 41.1165 +
 41.1166 +    g_mutex_unlock(gmyth_socket->mutex);
 41.1167 +    // g_static_rw_lock_reader_unlock (&rwlock);
 41.1168 +
 41.1169 +    gmyth_debug("Response received from backend: ----- {%s}\n", buffer);
 41.1170 +    if ((bytes_read != len) || (io_status == G_IO_STATUS_ERROR))
 41.1171 +        str = NULL;
 41.1172 +    else
 41.1173 +        str = g_string_new(buffer);
 41.1174 +
 41.1175 +    if (error != NULL) {
 41.1176 +        gmyth_debug
 41.1177 +            ("[%s] Error found receiving response from the IO channel: (%d, %s)\n",
 41.1178 +             __FUNCTION__, error->code, error->message);
 41.1179 +        str = NULL;
 41.1180 +        g_error_free(error);
 41.1181 +    }
 41.1182 +
 41.1183 +    g_free(buffer);
 41.1184 +    return str;
 41.1185 +}
 41.1186 +
 41.1187 +/** Format a Mythtv command from the str_list entries and send it to backend.
 41.1188 + * 
 41.1189 + * @param gmyth_socket The GMythSocket instance.
 41.1190 + * @param str_list The string list to form the command
 41.1191 + * @return TRUE if command was sent, FALSE if any error happens.
 41.1192 + */
 41.1193 +gboolean
 41.1194 +gmyth_socket_write_stringlist(GMythSocket * gmyth_socket,
 41.1195 +                              GMythStringList * str_list)
 41.1196 +{
 41.1197 +
 41.1198 +    GList          *tmp_list = NULL;
 41.1199 +    GPtrArray      *ptr_array = NULL;
 41.1200 +    gchar          *str_array = NULL;
 41.1201 +
 41.1202 +    g_mutex_lock(gmyth_socket->mutex);
 41.1203 +    // g_static_rw_lock_writer_lock (&rwlock);
 41.1204 +
 41.1205 +    ptr_array = g_ptr_array_sized_new(g_list_length(str_list->glist));
 41.1206 +
 41.1207 +    // FIXME: change this implementation!
 41.1208 +    tmp_list = str_list->glist;
 41.1209 +    for (; tmp_list; tmp_list = tmp_list->next) {
 41.1210 +        if (tmp_list->data != NULL) {
 41.1211 +            g_ptr_array_add(ptr_array, ((GString *) tmp_list->data)->str);
 41.1212 +        } else {
 41.1213 +            g_ptr_array_add(ptr_array, "");
 41.1214 +        }
 41.1215 +    }
 41.1216 +    g_ptr_array_add(ptr_array, NULL);   // g_str_joinv() needs a NULL
 41.1217 +    // terminated string
 41.1218 +
 41.1219 +    str_array = g_strjoinv(MYTH_SEPARATOR, (gchar **) (ptr_array->pdata));
 41.1220 +
 41.1221 +    g_mutex_unlock(gmyth_socket->mutex);
 41.1222 +    // g_static_rw_lock_writer_unlock (&rwlock);
 41.1223 +
 41.1224 +    gmyth_debug("[%s] Sending socket request: %s\n", __FUNCTION__,
 41.1225 +                str_array);
 41.1226 +
 41.1227 +    // Sends message to backend 
 41.1228 +    // TODO: implement looping to send remaining data, and add timeout
 41.1229 +    // testing! 
 41.1230 +    GString        *command = g_string_new(str_array);
 41.1231 +
 41.1232 +    gmyth_socket_send_command(gmyth_socket, command);
 41.1233 +
 41.1234 +    g_string_free(command, TRUE);
 41.1235 +
 41.1236 +    g_free(str_array);
 41.1237 +
 41.1238 +    /*
 41.1239 +     * ptr_array is pointing to data inside str_list->glist 
 41.1240 +     */
 41.1241 +    g_ptr_array_free(ptr_array, TRUE);
 41.1242 +
 41.1243 +    return TRUE;
 41.1244 +}
 41.1245 +
 41.1246 +/*
 41.1247 + * Receives a backend command response and split it into the given string
 41.1248 + * list. @param gmyth_socket The GMythSocket instance. @param str_list
 41.1249 + * the string list to be filled. @return The number of received strings. 
 41.1250 + */
 41.1251 +gint
 41.1252 +gmyth_socket_read_stringlist(GMythSocket * gmyth_socket,
 41.1253 +                             GMythStringList * str_list)
 41.1254 +{
 41.1255 +    GString        *response;
 41.1256 +    gint            i;
 41.1257 +
 41.1258 +    gmyth_string_list_clear_all(str_list);
 41.1259 +
 41.1260 +    response = gmyth_socket_receive_response(gmyth_socket);
 41.1261 +    if (response != NULL && response->str != NULL && response->len > 0) {
 41.1262 +        gchar         **str_array;
 41.1263 +
 41.1264 +        g_mutex_lock(gmyth_socket->mutex);
 41.1265 +
 41.1266 +        str_array = g_strsplit(response->str, MYTH_SEPARATOR, -1);
 41.1267 +
 41.1268 +        for (i = 0; i < g_strv_length(str_array); i++) {
 41.1269 +            // if ( str_array[i] != NULL && strlen( str_array[i] ) > 0 )
 41.1270 +            gmyth_string_list_append_char_array(str_list, str_array[i]);
 41.1271 +        }
 41.1272 +
 41.1273 +        g_mutex_unlock(gmyth_socket->mutex);
 41.1274 +        g_strfreev(str_array);
 41.1275 +    }
 41.1276 +
 41.1277 +    g_string_free(response, TRUE);
 41.1278 +
 41.1279 +    return gmyth_string_list_length(str_list);
 41.1280 +}
 41.1281 +
 41.1282 +/** Formats a Mythtv protocol command based on str_list and sends it to
 41.1283 + * the connected backend. The backend response is overwritten into str_list.
 41.1284 + *
 41.1285 + * @param gmyth_socket The GMythSocket instance.
 41.1286 + * @param str_list The string list to be sent, and on which the answer 
 41.1287 + * will be written.
 41.1288 + * @return TRUE if command was sent and an answer was received, FALSE if any
 41.1289 + * error happens.
 41.1290 + */
 41.1291 +gint
 41.1292 +gmyth_socket_sendreceive_stringlist(GMythSocket * gmyth_socket,
 41.1293 +                                    GMythStringList * str_list)
 41.1294 +{
 41.1295 +    gmyth_socket_write_stringlist(gmyth_socket, str_list);
 41.1296 +
 41.1297 +    return gmyth_socket_read_stringlist(gmyth_socket, str_list);
 41.1298 +}
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/gmyth/gmyth/gmyth_socket.h	Mon Feb 25 17:51:43 2008 +0000
    42.3 @@ -0,0 +1,147 @@
    42.4 +/**
    42.5 + * GMyth Library
    42.6 + *
    42.7 + * @file gmyth/gmyth_socket.h
    42.8 + * 
    42.9 + * @brief <p> MythTV socket implementation, according to the MythTV Project
   42.10 + * (www.mythtv.org). 
   42.11 + * 
   42.12 + * This component provides basic socket functionalities to interact with
   42.13 + * the Mythtv backend.
   42.14 + * <p>
   42.15 + *
   42.16 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   42.17 + * @author Rosfran Lins Borges <rosfran.borges@indt.org.br> 
   42.18 + *
   42.19 + * 
   42.20 + * This program is free software; you can redistribute it and/or modify
   42.21 + * it under the terms of the GNU Lesser General Public License as published by
   42.22 + * the Free Software Foundation; either version 2 of the License, or
   42.23 + * (at your option) any later version.
   42.24 + *
   42.25 + * This program is distributed in the hope that it will be useful,
   42.26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   42.27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   42.28 + * GNU General Public License for more details.
   42.29 + *
   42.30 + * You should have received a copy of the GNU Lesser General Public License
   42.31 + * along with this program; if not, write to the Free Software
   42.32 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   42.33 + */
   42.34 +
   42.35 +#ifndef __GMYTH_SOCKET_H__
   42.36 +#define __GMYTH_SOCKET_H__
   42.37 +
   42.38 +#include <glib-object.h>
   42.39 +
   42.40 +#include <string.h>
   42.41 +#include <netdb.h>
   42.42 +#include <sys/socket.h>
   42.43 +#include <unistd.h>
   42.44 +#include <glib.h>
   42.45 +
   42.46 +#include "gmyth_stringlist.h"
   42.47 +
   42.48 +G_BEGIN_DECLS
   42.49 +#define GMYTH_SOCKET_TYPE               (gmyth_socket_get_type ())
   42.50 +#define GMYTH_SOCKET(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SOCKET_TYPE, GMythSocket))
   42.51 +#define GMYTH_SOCKET_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE, GMythSocketClass))
   42.52 +#define IS_GMYTH_SOCKET(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_SOCKET_TYPE))
   42.53 +#define IS_GMYTH_SOCKET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE))
   42.54 +#define GMYTH_SOCKET_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SOCKET_TYPE, GMythSocketClass))
   42.55 +typedef struct _GMythSocket GMythSocket;
   42.56 +typedef struct _GMythSocketClass GMythSocketClass;
   42.57 +
   42.58 +struct _GMythSocketClass {
   42.59 +    GObjectClass    parent_class;
   42.60 +
   42.61 +    /*
   42.62 +     * callbacks 
   42.63 +     */
   42.64 +    /*
   42.65 +     * no one for now 
   42.66 +     */
   42.67 +};
   42.68 +
   42.69 +struct _GMythSocket {
   42.70 +    GObject         parent;
   42.71 +
   42.72 +    GMutex         *mutex;
   42.73 +
   42.74 +    /*
   42.75 +     * socket descriptor 
   42.76 +     */
   42.77 +    gint            sd;
   42.78 +    GIOChannel     *sd_io_ch;
   42.79 +
   42.80 +    gchar          *hostname;
   42.81 +    gint            port;
   42.82 +    gint            mythtv_version;
   42.83 +};
   42.84 +
   42.85 +/*
   42.86 + * used when no protocol version number was negotiated 
   42.87 + */
   42.88 +#define	MYTHTV_CANNOT_NEGOTIATE_VERSION		0
   42.89 +
   42.90 +GType           gmyth_socket_get_type(void);
   42.91 +
   42.92 +GMythSocket    *gmyth_socket_new();
   42.93 +
   42.94 +GIOChannel     *gmyth_socket_get_io_channel(GMythSocket * gmyth_socket);
   42.95 +
   42.96 +gboolean        gmyth_socket_is_able_to_read(GMythSocket * gmyth_socket);
   42.97 +gboolean        gmyth_socket_is_able_to_write(GMythSocket * gmyth_socket);
   42.98 +
   42.99 +gboolean        gmyth_socket_send_command(GMythSocket * gmyth_socket,
  42.100 +                                          GString * command);
  42.101 +GString        *gmyth_socket_receive_response(GMythSocket * gmyth_socket);
  42.102 +gint            gmyth_socket_sendreceive_stringlist(GMythSocket *
  42.103 +                                                    gmyth_socket,
  42.104 +                                                    GMythStringList *
  42.105 +                                                    str_list);
  42.106 +
  42.107 +gboolean        gmyth_socket_connect(GMythSocket * gmyth_socket,
  42.108 +                                     const gchar * hostname, gint port);
  42.109 +gboolean        gmyth_socket_connect_with_timeout(GMythSocket *
  42.110 +                                                  gmyth_socket,
  42.111 +                                                  const gchar * hostname,
  42.112 +                                                  gint port,
  42.113 +                                                  guint timeout);
  42.114 +
  42.115 +gboolean        gmyth_socket_connect_to_backend(GMythSocket * gmyth_socket,
  42.116 +                                                const gchar *
  42.117 +                                                hostname_backend,
  42.118 +                                                gint port,
  42.119 +                                                gboolean blocking_client);
  42.120 +
  42.121 +gboolean        gmyth_socket_connect_to_backend_events(GMythSocket *
  42.122 +                                                       gmyth_socket,
  42.123 +                                                       const gchar *
  42.124 +                                                       hostname_backend,
  42.125 +                                                       gint port,
  42.126 +                                                       gboolean
  42.127 +                                                       blocking_client);
  42.128 +
  42.129 +gchar          *gmyth_socket_get_primary_addr(void);
  42.130 +
  42.131 +GString        *gmyth_socket_get_local_hostname(void);
  42.132 +
  42.133 +void            gmyth_socket_close_connection(GMythSocket * gmyth_socket);
  42.134 +
  42.135 +gboolean        gmyth_socket_check_protocol_version(GMythSocket *
  42.136 +                                                    gmyth_socket);
  42.137 +gint            gmyth_socket_check_protocol_version_number(GMythSocket *
  42.138 +                                                           gmyth_socket,
  42.139 +                                                           gint
  42.140 +                                                           mythtv_version);
  42.141 +
  42.142 +gint            gmyth_socket_get_protocol_version(GMythSocket *
  42.143 +                                                  gmyth_socket);
  42.144 +
  42.145 +gboolean        gmyth_socket_write_stringlist(GMythSocket * gmyth_socket,
  42.146 +                                              GMythStringList * str_list);
  42.147 +gint            gmyth_socket_read_stringlist(GMythSocket * gmyth_socket,
  42.148 +                                             GMythStringList * str_list);
  42.149 +G_END_DECLS
  42.150 +#endif                          /* __GMYTH_SOCKET_H__ */
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/gmyth/gmyth/gmyth_stringlist.c	Mon Feb 25 17:51:43 2008 +0000
    43.3 @@ -0,0 +1,454 @@
    43.4 +/**
    43.5 + * GMyth Library
    43.6 + *
    43.7 + * @file gmyth/gmyth_stringlist.c
    43.8 + * 
    43.9 + * @brief <p> This component contains functions for dealing with the stringlist
   43.10 + * format of the mythprotocol.
   43.11 + * 
   43.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   43.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   43.14 + *
   43.15 + * 
   43.16 + * This program is free software; you can redistribute it and/or modify
   43.17 + * it under the terms of the GNU Lesser General Public License as published by
   43.18 + * the Free Software Foundation; either version 2 of the License, or
   43.19 + * (at your option) any later version.
   43.20 + *
   43.21 + * This program is distributed in the hope that it will be useful,
   43.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   43.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   43.24 + * GNU General Public License for more details.
   43.25 + *
   43.26 + * You should have received a copy of the GNU Lesser General Public License
   43.27 + * along with this program; if not, write to the Free Software
   43.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   43.29 + */
   43.30 +
   43.31 +#ifdef HAVE_CONFIG_H
   43.32 +#include "config.h"
   43.33 +#endif
   43.34 +
   43.35 +#include "gmyth_stringlist.h"
   43.36 +
   43.37 +#include "gmyth_debug.h"
   43.38 +
   43.39 +static void     gmyth_string_list_class_init(GMythStringListClass * klass);
   43.40 +static void     gmyth_string_list_init(GMythStringList * object);
   43.41 +
   43.42 +static void     gmyth_string_list_dispose(GObject * object);
   43.43 +static void     gmyth_string_list_finalize(GObject * object);
   43.44 +
   43.45 +G_DEFINE_TYPE(GMythStringList, gmyth_string_list, G_TYPE_OBJECT)
   43.46 +    static void     gmyth_string_list_class_init(GMythStringListClass *
   43.47 +                                                 klass)
   43.48 +{
   43.49 +    GObjectClass   *gobject_class;
   43.50 +
   43.51 +    gobject_class = (GObjectClass *) klass;
   43.52 +
   43.53 +    gobject_class->dispose = gmyth_string_list_dispose;
   43.54 +    gobject_class->finalize = gmyth_string_list_finalize;
   43.55 +}
   43.56 +
   43.57 +static void
   43.58 +gmyth_string_list_init(GMythStringList * gmyth_string_list)
   43.59 +{
   43.60 +    gmyth_string_list->glist = NULL;
   43.61 +}
   43.62 +
   43.63 +static void
   43.64 +gmyth_string_list_dispose(GObject * object)
   43.65 +{
   43.66 +    GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
   43.67 +
   43.68 +    gmyth_string_list_clear_all(gmyth_string_list);
   43.69 +
   43.70 +    G_OBJECT_CLASS(gmyth_string_list_parent_class)->dispose(object);
   43.71 +}
   43.72 +
   43.73 +static void
   43.74 +gmyth_string_list_finalize(GObject * object)
   43.75 +{
   43.76 +    // GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
   43.77 +
   43.78 +    g_signal_handlers_destroy(object);
   43.79 +
   43.80 +    G_OBJECT_CLASS(gmyth_string_list_parent_class)->finalize(object);
   43.81 +}
   43.82 +
   43.83 +/** Creates a new instance of GStringList.
   43.84 + * 
   43.85 + * @return a new instance of GStringList.
   43.86 + */
   43.87 +GMythStringList *
   43.88 +gmyth_string_list_new()
   43.89 +{
   43.90 +    GMythStringList *gmyth_string_list =
   43.91 +        GMYTH_STRING_LIST(g_object_new(GMYTH_STRING_LIST_TYPE, NULL));
   43.92 +
   43.93 +    return gmyth_string_list;
   43.94 +}
   43.95 +
   43.96 +/** Appends a guint64 to the string list.
   43.97 + * 
   43.98 + * @param strlist The GMythStringList instance.
   43.99 + * @param value The guint64 to be appended.
  43.100 + * 
  43.101 + * @return The appended guint64 converted to a GString object.
  43.102 + */
  43.103 +GString        *
  43.104 +gmyth_string_list_append_int(GMythStringList * strlist, const gint value)
  43.105 +{
  43.106 +    GString        *value_str = g_string_new("");
  43.107 +
  43.108 +    g_string_printf(value_str, "%d", value);
  43.109 +
  43.110 +    strlist->glist = g_list_append(strlist->glist, value_str);
  43.111 +
  43.112 +    return value_str;
  43.113 +}
  43.114 +
  43.115 +
  43.116 +/** Appends a gdouble to the string list.
  43.117 + *
  43.118 + * @param strlist The GMythStringList instance.
  43.119 + * @param value The gdouble to be appended.
  43.120 + *
  43.121 + * @return The appended gdouble converted to a GString object.
  43.122 + */
  43.123 +GString        *
  43.124 +gmyth_string_list_append_float(GMythStringList * strlist, const gdouble value)
  43.125 +{
  43.126 +    GString        *value_str = g_string_new("");
  43.127 +    g_string_printf(value_str, "%f", value);
  43.128 +    strlist->glist = g_list_append(strlist->glist, value_str);
  43.129 +    return value_str;
  43.130 +}
  43.131 +
  43.132 +
  43.133 +/** Appends a guint64 to the string list.
  43.134 + * 
  43.135 + * @param strlist The GMythStringList instance.
  43.136 + * @param value The guint64 to be appended.
  43.137 + * 
  43.138 + * @return The appended guint64 converted to a GString object.
  43.139 + */
  43.140 +GString        *
  43.141 +gmyth_string_list_append_uint64(GMythStringList * strlist,
  43.142 +                                const guint64 value)
  43.143 +{
  43.144 +    GString        *tmp_str1 = g_string_new("");
  43.145 +    GString        *tmp_str2 = g_string_new("");
  43.146 +
  43.147 +    gmyth_debug("value = %llu.\n", value);
  43.148 +
  43.149 +    gulong          l2 = ((guint64) value & 0xffffffff);
  43.150 +    gulong          l1 = ((guint64) value >> 32);
  43.151 +
  43.152 +    /*
  43.153 +     * high order part of guint64 value 
  43.154 +     */
  43.155 +    g_string_printf(tmp_str1, "%lu", l1);
  43.156 +
  43.157 +    gmyth_debug("[%s] uint64 (high) = %s\n", __FUNCTION__, tmp_str1->str);
  43.158 +
  43.159 +    strlist->glist = g_list_append(strlist->glist, tmp_str1);
  43.160 +
  43.161 +    /*
  43.162 +     * low order part of guint64 value 
  43.163 +     */
  43.164 +    g_string_printf(tmp_str2, "%lu", l2);
  43.165 +
  43.166 +    gmyth_debug("[%s] uint64 (low) = %s\n", __FUNCTION__, tmp_str2->str);
  43.167 +
  43.168 +    strlist->glist = g_list_append(strlist->glist, tmp_str2);
  43.169 +
  43.170 +    return tmp_str2;
  43.171 +}
  43.172 +
  43.173 +/** Appends a gint64 to the string list.
  43.174 + * 
  43.175 + * @param strlist The GMythStringList instance.
  43.176 + * @param value The gint64 to be appended.
  43.177 + * 
  43.178 + * @return The appended gint64 converted to a GString object.
  43.179 + */
  43.180 +GString        *
  43.181 +gmyth_string_list_append_int64(GMythStringList * strlist,
  43.182 +                               const gint64 value)
  43.183 +{
  43.184 +    GString        *tmp_str1 = g_string_new("");
  43.185 +    GString        *tmp_str2 = g_string_new("");
  43.186 +
  43.187 +    gmyth_debug("value = %lld.\n", value);
  43.188 +
  43.189 +    glong           l2 = ((gint64) value & 0xffffffff);
  43.190 +    glong           l1 = ((gint64) value >> 32);
  43.191 +
  43.192 +    /*
  43.193 +     * high order part of gint64 value 
  43.194 +     */
  43.195 +    g_string_printf(tmp_str1, "%ld", l1);
  43.196 +
  43.197 +    gmyth_debug("[%s] int64 (high) = %s\n", __FUNCTION__, tmp_str1->str);
  43.198 +
  43.199 +    strlist->glist = g_list_append(strlist->glist, tmp_str1);
  43.200 +
  43.201 +    /*
  43.202 +     * low order part of gint64 value 
  43.203 +     */
  43.204 +    g_string_printf(tmp_str2, "%ld", l2);
  43.205 +
  43.206 +    gmyth_debug("[%s] int64 (low) = %s\n", __FUNCTION__, tmp_str2->str);
  43.207 +
  43.208 +    strlist->glist = g_list_append(strlist->glist, tmp_str2);
  43.209 +
  43.210 +    return tmp_str2;
  43.211 +}
  43.212 +
  43.213 +/** Appends a char array to the string list.
  43.214 + * 
  43.215 + * @param strlist The GMythStringList instance.
  43.216 + * @param value The char array to be appended.
  43.217 + * 
  43.218 + * @return The appended char array converted to a GString object.
  43.219 + */
  43.220 +GString        *
  43.221 +gmyth_string_list_append_char_array(GMythStringList * strlist,
  43.222 +                                    const gchar * value)
  43.223 +{
  43.224 +    GString        *tmp_str = NULL;
  43.225 +
  43.226 +    g_return_val_if_fail(strlist != NULL, NULL);
  43.227 +
  43.228 +    tmp_str = g_string_new(value);
  43.229 +
  43.230 +    strlist->glist = g_list_append(strlist->glist, tmp_str);
  43.231 +
  43.232 +    return tmp_str;
  43.233 +}
  43.234 +
  43.235 +/** Appends a string to the string list.
  43.236 + * 
  43.237 + * @param strlist The GMythStringList instance.
  43.238 + * @param value The string to be appended.
  43.239 + * 
  43.240 + * @return The appended string itself. 
  43.241 + */
  43.242 +GString        *
  43.243 +gmyth_string_list_append_string(GMythStringList * strlist, GString * value)
  43.244 +{
  43.245 +    g_return_val_if_fail(strlist != NULL, NULL);
  43.246 +
  43.247 +    if (value != NULL) {
  43.248 +        strlist->glist =
  43.249 +            g_list_append(strlist->glist, g_string_new(value->str));
  43.250 +    } else {
  43.251 +        strlist->glist = g_list_append(strlist->glist, NULL);
  43.252 +    }
  43.253 +
  43.254 +    return value;
  43.255 +}
  43.256 +
  43.257 +/** Gets an integer value from the string list at the given position.
  43.258 + * 
  43.259 + * @param strlist The GMythStringList instance.
  43.260 + * @param index the integer position in the list, starting with zero.
  43.261 + * @return The integer value.
  43.262 + */
  43.263 +gint
  43.264 +gmyth_string_list_get_int(GMythStringList * strlist, const gint index)
  43.265 +{
  43.266 +    // TODO: Create static method check_index()
  43.267 +    GString        *tmp_str = NULL;
  43.268 +
  43.269 +    g_return_val_if_fail(strlist != NULL, 0);
  43.270 +
  43.271 +    tmp_str = (GString *) g_list_nth_data(strlist->glist, index);
  43.272 +
  43.273 +    if (NULL == tmp_str || NULL == tmp_str->str
  43.274 +        || strlen(tmp_str->str) <= 0)
  43.275 +        return 0;
  43.276 +
  43.277 +    return (gint) (             /* 0x00000000ffffffffL & (gint64) */
  43.278 +                      g_ascii_strtoull(tmp_str->str, NULL, 10));
  43.279 +}
  43.280 +
  43.281 +/** Gets a guint64 value from the string list at the given position.
  43.282 + * According to the Mythtv protocol, the 64 bits value is formed by
  43.283 + * two strings.
  43.284 + * 
  43.285 + * @param strlist The GMythStringList instance.
  43.286 + * @param index the index of the first string forming the 64 bits value. 
  43.287 + * Index starts with zero.
  43.288 + * @return The guint64 value.
  43.289 + */
  43.290 +guint64
  43.291 +gmyth_string_list_get_uint64(GMythStringList * strlist, const gint index)
  43.292 +{
  43.293 +    // TODO: Create static method check_index()
  43.294 +    guint64         ret_value = 0;
  43.295 +    guint64         l2 = 0;
  43.296 +
  43.297 +    g_return_val_if_fail(strlist != NULL, 0);
  43.298 +
  43.299 +    const GString  *tmp_str1 =
  43.300 +        (GString *) g_list_nth_data(strlist->glist, index);
  43.301 +    const GString  *tmp_str2 =
  43.302 +        (GString *) g_list_nth_data(strlist->glist, index + 1);
  43.303 +
  43.304 +    if (tmp_str1 != NULL)
  43.305 +        gmyth_debug("[%s] seek high bytes = %s\n", __FUNCTION__,
  43.306 +                    tmp_str1->str);
  43.307 +    if (tmp_str2 == NULL || strlen(tmp_str2->str) > 0) {
  43.308 +    } else {
  43.309 +        gmyth_debug("[%s] seek low bytes = %s\n", __FUNCTION__,
  43.310 +                    tmp_str2->str);
  43.311 +    }
  43.312 +
  43.313 +    guint64         l1 = ((guint64) g_ascii_strtoull(tmp_str1->str, NULL, 10)   /* & 
  43.314 +                                                                                 * 0xffffffff 
  43.315 +                                                                                 */
  43.316 +        );
  43.317 +
  43.318 +    if (tmp_str2 != NULL && tmp_str2->str != NULL
  43.319 +        && strlen(tmp_str2->str) > 0) {
  43.320 +        l2 = ((guint64) g_ascii_strtoull(tmp_str2->str, NULL, 10)
  43.321 +              /*
  43.322 +               * & 0xffffffff 
  43.323 +               */
  43.324 +            );
  43.325 +    } else {
  43.326 +        l2 = l1;
  43.327 +        l1 = 0;
  43.328 +    }
  43.329 +
  43.330 +    gmyth_debug("[%s]\t[l1 == %llu, l2 == %llu]\n", __FUNCTION__, l1, l2);
  43.331 +
  43.332 +    ret_value =
  43.333 +        ((guint64) (l2) /* & 0xffffffff */ ) | ((guint64) l1 << 32);
  43.334 +
  43.335 +    gmyth_debug("[%s] returning uint64 value = %llu\n", __FUNCTION__,
  43.336 +                ret_value);
  43.337 +
  43.338 +    return ret_value;
  43.339 +}
  43.340 +
  43.341 +/** Gets a gint64 value from the string list at the given position.
  43.342 + * According to the Mythtv protocol, the 64 bits value is formed by
  43.343 + * two strings.
  43.344 + * 
  43.345 + * @param strlist The GMythStringList instance.
  43.346 + * @param index the index of the first string forming the 64 bits value. 
  43.347 + * Index starts with zero.
  43.348 + * @return The gint64 value.
  43.349 + */
  43.350 +gint64
  43.351 +gmyth_string_list_get_int64(GMythStringList * strlist, const gint index)
  43.352 +{
  43.353 +    // TODO: Create static method check_index()
  43.354 +    gint64          ret_value = 0;
  43.355 +    gint64          l2 = 0;
  43.356 +
  43.357 +    g_return_val_if_fail(strlist != NULL, 0);
  43.358 +
  43.359 +    const GString  *tmp_str1 =
  43.360 +        (GString *) g_list_nth_data(strlist->glist, index);
  43.361 +    const GString  *tmp_str2 =
  43.362 +        (GString *) g_list_nth_data(strlist->glist, index + 1);
  43.363 +
  43.364 +    if (tmp_str1 != NULL)
  43.365 +        gmyth_debug("[%s] seek high bytes = %s\n", __FUNCTION__,
  43.366 +                    tmp_str1->str);
  43.367 +    if (tmp_str2 == NULL || strlen(tmp_str2->str) > 0) {
  43.368 +    } else {
  43.369 +        gmyth_debug("[%s] seek low bytes = %s\n", __FUNCTION__,
  43.370 +                    tmp_str2->str);
  43.371 +    }
  43.372 +
  43.373 +    gint64          l1 = ((guint64) g_ascii_strtoull(tmp_str1->str, NULL, 10)   /* & 
  43.374 +                                                                                 * 0xffffffff 
  43.375 +                                                                                 */
  43.376 +        );
  43.377 +
  43.378 +    if (tmp_str2 != NULL && tmp_str2->str != NULL
  43.379 +        && strlen(tmp_str2->str) > 0) {
  43.380 +        l2 = ((gint64) g_ascii_strtoull(tmp_str2->str, NULL, 10)
  43.381 +              /*
  43.382 +               * & 0xffffffff 
  43.383 +               */
  43.384 +            );
  43.385 +    } else {
  43.386 +        l2 = l1;
  43.387 +        l1 = 0;
  43.388 +    }
  43.389 +
  43.390 +    gmyth_debug("[%s]\t[l1 == %lld, l2 == %lld]\n", __FUNCTION__, l1, l2);
  43.391 +
  43.392 +    ret_value = ((gint64) (l2) /* & 0xffffffff */ ) | ((gint64) l1 << 32);
  43.393 +
  43.394 +    gmyth_debug("[%s] returning int64 value = %lld\n", __FUNCTION__,
  43.395 +                ret_value);
  43.396 +
  43.397 +    return ret_value;
  43.398 +}
  43.399 +
  43.400 +
  43.401 +/** Gets a string from the string list at the given position. The GString must be deallocated.
  43.402 + * 
  43.403 + * @param strlist The GMythStringList instance.
  43.404 + * @param index the string position in the list, starting with zero.
  43.405 + * @return A pointer to the string data.
  43.406 + */
  43.407 +GString        *
  43.408 +gmyth_string_list_get_string(GMythStringList * strlist, const gint index)
  43.409 +{
  43.410 +    GString        *ret;
  43.411 +
  43.412 +    if (!strlist || !(strlist->glist)) {
  43.413 +        gmyth_debug("%s received Null arguments", __FUNCTION__);
  43.414 +        return NULL;
  43.415 +    }
  43.416 +
  43.417 +    ret = (GString *) g_list_nth_data(strlist->glist, index);
  43.418 +
  43.419 +    return g_string_new(ret->str);
  43.420 +}
  43.421 +
  43.422 +
  43.423 +static void
  43.424 +gmyth_string_list_clear_element(GString * str_elem, void *data_aux)
  43.425 +{
  43.426 +    if (str_elem != NULL)
  43.427 +        g_string_free(str_elem, TRUE);
  43.428 +}
  43.429 +
  43.430 +/** Removes all strings from the string list.
  43.431 + * 
  43.432 + * @param strlist The GMythStringList instance.
  43.433 + */
  43.434 +void
  43.435 +gmyth_string_list_clear_all(GMythStringList * strlist)
  43.436 +{
  43.437 +    if (strlist != NULL && strlist->glist) {
  43.438 +        g_list_foreach(strlist->glist,
  43.439 +                       (GFunc) gmyth_string_list_clear_element, NULL);
  43.440 +        g_list_free(strlist->glist);
  43.441 +        strlist->glist = NULL;
  43.442 +    }
  43.443 +}
  43.444 +
  43.445 +/** Retrieves the number of elements in the string list.
  43.446 + * 
  43.447 + * @param strlist The GMythStringList instance.
  43.448 + * @return the string list length.
  43.449 + */
  43.450 +gint
  43.451 +gmyth_string_list_length(GMythStringList * strlist)
  43.452 +{
  43.453 +    if (!(strlist != NULL && strlist->glist != NULL))
  43.454 +        return 0;
  43.455 +
  43.456 +    return g_list_length(strlist->glist);
  43.457 +}
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/gmyth/gmyth/gmyth_stringlist.h	Mon Feb 25 17:51:43 2008 +0000
    44.3 @@ -0,0 +1,108 @@
    44.4 +/**
    44.5 + * GMyth Library
    44.6 + *
    44.7 + * @file gmyth/gmyth_stringlist.h
    44.8 + * 
    44.9 + * @brief <p> This component contains functions for dealing with the stringlist
   44.10 + * format of the mythprotocol.
   44.11 + * 
   44.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   44.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   44.14 + *
   44.15 + * 
   44.16 + * This program is free software; you can redistribute it and/or modify
   44.17 + * it under the terms of the GNU Lesser General Public License as published by
   44.18 + * the Free Software Foundation; either version 2 of the License, or
   44.19 + * (at your option) any later version.
   44.20 + *
   44.21 + * This program is distributed in the hope that it will be useful,
   44.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   44.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   44.24 + * GNU General Public License for more details.
   44.25 + *
   44.26 + * You should have received a copy of the GNU Lesser General Public License
   44.27 + * along with this program; if not, write to the Free Software
   44.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   44.29 + */
   44.30 +
   44.31 +#ifndef GMYTH_STRING_LIST_H_
   44.32 +#define GMYTH_STRING_LIST_H_
   44.33 +
   44.34 +#include <glib-object.h>
   44.35 +
   44.36 +#include <stdio.h>
   44.37 +#include <stdlib.h>
   44.38 +#include <string.h>
   44.39 +#include <netdb.h>
   44.40 +#include <sys/socket.h>
   44.41 +#include <unistd.h>
   44.42 +
   44.43 +G_BEGIN_DECLS
   44.44 +#define GMYTH_STRING_LIST_TYPE               (gmyth_string_list_get_type ())
   44.45 +#define GMYTH_STRING_LIST(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_STRING_LIST_TYPE, GMythStringList))
   44.46 +#define GMYTH_STRING_LIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
   44.47 +#define IS_GMYTH_STRING_LIST(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_STRING_LIST_TYPE))
   44.48 +#define IS_GMYTH_STRING_LIST_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE))
   44.49 +#define GMYTH_STRING_LIST_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
   44.50 +typedef struct _GMythStringList GMythStringList;
   44.51 +typedef struct _GMythStringListClass GMythStringListClass;
   44.52 +
   44.53 +struct _GMythStringListClass {
   44.54 +    GObjectClass    parent_class;
   44.55 +
   44.56 +    /*
   44.57 +     * callbacks 
   44.58 +     */
   44.59 +    /*
   44.60 +     * no one for now 
   44.61 +     */
   44.62 +};
   44.63 +
   44.64 +struct _GMythStringList {
   44.65 +    GObject         parent;
   44.66 +
   44.67 +    /*
   44.68 +     * string list 
   44.69 +     */
   44.70 +    GList          *glist;
   44.71 +};
   44.72 +
   44.73 +
   44.74 +GType           gmyth_string_list_get_type(void);
   44.75 +
   44.76 +GMythStringList *gmyth_string_list_new(void);
   44.77 +
   44.78 +void            gmyth_string_list_clear_all(GMythStringList * strlist);
   44.79 +int             gmyth_string_list_length(GMythStringList * strlist);
   44.80 +
   44.81 +GString        *gmyth_string_list_append_float(GMythStringList * strlist,
   44.82 +                                             const gdouble value);
   44.83 +
   44.84 +GString        *gmyth_string_list_append_int(GMythStringList * strlist,
   44.85 +                                             const gint value);
   44.86 +GString        *gmyth_string_list_append_uint64(GMythStringList * strlist,
   44.87 +                                                const guint64 value);
   44.88 +
   44.89 +GString        *gmyth_string_list_append_int64(GMythStringList * strlist,
   44.90 +                                               const gint64 value);
   44.91 +
   44.92 +GString        *gmyth_string_list_append_char_array(GMythStringList *
   44.93 +                                                    strlist,
   44.94 +                                                    const char *value);
   44.95 +GString        *gmyth_string_list_append_string(GMythStringList * strlist,
   44.96 +                                                GString * value);
   44.97 +
   44.98 +int             gmyth_string_list_get_int(GMythStringList * strlist,
   44.99 +                                          const gint index);
  44.100 +guint64         gmyth_string_list_get_uint64(GMythStringList * strlist,
  44.101 +                                             const gint index);
  44.102 +gint64          gmyth_string_list_get_int64(GMythStringList * strlist,
  44.103 +                                            const gint index);
  44.104 +GString        *gmyth_string_list_get_string(GMythStringList * strlist,
  44.105 +                                             const gint index);
  44.106 +
  44.107 +#define gmyth_string_list_get_char_array(strlist, index) \
  44.108 +	(gmyth_string_list_get_string(strlist, index))->str
  44.109 +
  44.110 +G_END_DECLS
  44.111 +#endif                          /* GMYTH_STRING_LIST_H_ */
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/gmyth/gmyth/gmyth_transcoder.c	Mon Feb 25 17:51:43 2008 +0000
    45.3 @@ -0,0 +1,272 @@
    45.4 +/**
    45.5 + * GMyth Library
    45.6 + * 
    45.7 + * @file gmyth/gmyth_transcoder.c
    45.8 + * 
    45.9 + * @brief <p> This file contains the transcoder class.
   45.10 + *
   45.11 + * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   45.12 + * @author Artur Duque de Souza <artur.souza@indt.org.br>
   45.13 + *
   45.14 + * 
   45.15 + * This program is free software; you can redistribute it and/or modify
   45.16 + * it under the terms of the GNU Lesser General Public License as published by
   45.17 + * the Free Software Foundation; either version 2 of the License, or
   45.18 + * (at your option) any later version.
   45.19 + *
   45.20 + * This program is distributed in the hope that it will be useful,
   45.21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   45.22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   45.23 + * GNU General Public License for more details.
   45.24 + *
   45.25 + * You should have received a copy of the GNU Lesser General Public License
   45.26 + * along with this program; if not, write to the Free Software
   45.27 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   45.28 + */
   45.29 +
   45.30 +
   45.31 +#ifdef HAVE_CONFIG_H
   45.32 +#include "config.h"
   45.33 +#endif
   45.34 +
   45.35 +#include <stdlib.h>
   45.36 +#include <string.h>
   45.37 +#include <assert.h>
   45.38 +
   45.39 +#include "gmyth_util.h"
   45.40 +#include "gmyth_debug.h"
   45.41 +
   45.42 +#include "gmyth_jobqueue.h"
   45.43 +#include "gmyth_transcoder.h"
   45.44 +
   45.45 +static void     gmyth_transcoder_class_init(GMythTranscoderClass * klass);
   45.46 +static void     gmyth_transcoder_init(GMythTranscoder * object);
   45.47 +
   45.48 +static void     gmyth_transcoder_dispose(GObject * object);
   45.49 +static void     gmyth_transcoder_finalize(GObject * object);
   45.50 +
   45.51 +G_DEFINE_TYPE(GMythTranscoder, gmyth_transcoder, G_TYPE_OBJECT)
   45.52 +    static void     gmyth_transcoder_class_init(GMythTranscoderClass *
   45.53 +                                                klass)
   45.54 +{
   45.55 +    GObjectClass   *gobject_class = G_OBJECT_CLASS(klass);
   45.56 +
   45.57 +    gobject_class->dispose = gmyth_transcoder_dispose;
   45.58 +    gobject_class->finalize = gmyth_transcoder_finalize;
   45.59 +}
   45.60 +
   45.61 +static void
   45.62 +gmyth_transcoder_init(GMythTranscoder * transcoder)
   45.63 +{
   45.64 +    transcoder->started = FALSE;
   45.65 +}
   45.66 +
   45.67 +static void
   45.68 +gmyth_transcoder_dispose(GObject * object)
   45.69 +{
   45.70 +    GMythTranscoder *transcoder = GMYTH_TRANSCODER(object);
   45.71 +
   45.72 +    g_free(transcoder->output_filename);
   45.73 +    g_free(transcoder->filename);
   45.74 +    g_free(transcoder->profile);
   45.75 +    g_free(transcoder->starttime);
   45.76 +
   45.77 +    if (transcoder->backend_info)
   45.78 +        g_object_unref(transcoder->backend_info);
   45.79 +
   45.80 +    G_OBJECT_CLASS(gmyth_transcoder_parent_class)->dispose(object);
   45.81 +}
   45.82 +
   45.83 +static void
   45.84 +gmyth_transcoder_finalize(GObject * object)
   45.85 +{
   45.86 +    g_signal_handlers_destroy(object);
   45.87 +    G_OBJECT_CLASS(gmyth_transcoder_parent_class)->finalize(object);
   45.88 +}
   45.89 +
   45.90 +/**
   45.91 + * Creates a new instance of GMythTranscoder.
   45.92 + * 
   45.93 + * @return a new instance of GMythTranscoder.
   45.94 + **/
   45.95 +GMythTranscoder *
   45.96 +gmyth_transcoder_new(GMythBackendInfo * backend_info)
   45.97 +{
   45.98 +    GMythTranscoder *transcoder = GMYTH_TRANSCODER
   45.99 +        (g_object_new(GMYTH_TRANSCODER_TYPE, NULL));
  45.100 +
  45.101 +    if (backend_info != NULL) {
  45.102 +        g_object_ref(backend_info);
  45.103 +        transcoder->backend_info = backend_info;
  45.104 +    }
  45.105 +
  45.106 +    return transcoder;
  45.107 +}
  45.108 +
  45.109 +/**
  45.110 + *
  45.111 + * gmyth_transcoder_date_change_format
  45.112 + * @brief converts a string like YYYY-MM-DDTHH:MM:SS into YYYYMMDDHHMMSS (vice versa)
  45.113 + * @param date_s gchar*
  45.114 + * @return gchar* with file or iso format
  45.115 + *
  45.116 + **/
  45.117 +static gchar   *
  45.118 +gmyth_transcoder_date_change_format(gchar * date_s, int format)
  45.119 +{
  45.120 +    if (date_s != NULL) {
  45.121 +        gint            length = strlen(date_s);
  45.122 +
  45.123 +        // create the right date format
  45.124 +        gchar          *src = (gchar *) g_malloc0(sizeof(gchar) * length);
  45.125 +
  45.126 +        strncpy(src, date_s, length);
  45.127 +
  45.128 +        gchar          *dst;
  45.129 +
  45.130 +        if (format == DATE_FILE) {
  45.131 +            dst = (gchar *) g_malloc0(sizeof(gchar) * 16);
  45.132 +            snprintf(dst, 16, "%.4s%.2s%.2s%.2s%.2s%.2s", src, src + 5,
  45.133 +                     src + 7, src + 9, src + 11, src + 13);
  45.134 +            dst[15] = '\0';
  45.135 +        } else if (format == DATE_ISO) {
  45.136 +            dst = (gchar *) g_malloc0(sizeof(gchar) * 20);
  45.137 +            snprintf(dst, 20, "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s", src,
  45.138 +                     src + 4, src + 6, src + 8, src + 10, src + 12);
  45.139 +            dst[19] = '\0';
  45.140 +        }
  45.141 +
  45.142 +        gchar          *ret = g_strdup(dst);
  45.143 +
  45.144 +        g_free(src);
  45.145 +        g_free(dst);
  45.146 +
  45.147 +        return ret;
  45.148 +    } else
  45.149 +        return NULL;
  45.150 +}
  45.151 +
  45.152 +/**
  45.153 + * gmyth_transcoder_set_output
  45.154 + * @brief set transcoder to use output
  45.155 + * @param value gboolean
  45.156 + * @param outfile filename of output
  45.157 + * @return void set's up the var to value
  45.158 + *
  45.159 + **/
  45.160 +void
  45.161 +gmyth_transcoder_set_output(GMythTranscoder * transcoder,
  45.162 +                            gboolean value, const gchar * outputfile)
  45.163 +{
  45.164 +    transcoder->output = value;
  45.165 +    transcoder->output_filename = g_strdup(outputfile);
  45.166 +}
  45.167 +
  45.168 +/**
  45.169 + * gmyth_transcoder_set_file
  45.170 + * @brief set the file to transcoder
  45.171 + * @param file filename
  45.172 + * @return void set's up the var to value
  45.173 + *
  45.174 + **/
  45.175 +void
  45.176 +gmyth_transcoder_set_filename(GMythTranscoder * transcoder,
  45.177 +                              const gchar * file)
  45.178 +{
  45.179 +    // fixme: if this method is called twice, memory will not be
  45.180 +    // dealocated
  45.181 +    // one transcoder can be used only for one file request?
  45.182 +    if (file != NULL) {
  45.183 +        gchar         **splited = g_strsplit(file, "_", 2);
  45.184 +
  45.185 +        // Get chanid
  45.186 +        sscanf(splited[0], "%d", &(transcoder->chanid));
  45.187 +
  45.188 +        // Get starttime
  45.189 +        gchar         **date = g_strsplit(splited[1], ".", 2);
  45.190 +
  45.191 +        transcoder->starttime =
  45.192 +            gmyth_transcoder_date_change_format(date[0], DATE_ISO);
  45.193 +
  45.194 +        transcoder->filename = g_strdup(file);
  45.195 +    }
  45.196 +}
  45.197 +
  45.198 +
  45.199 +/**
  45.200 + *
  45.201 + * gmyth_transcoder_set_profile
  45.202 + * @brief set transcoder's profile
  45.203 + * @param rec GMythTranscoder*
  45.204 + * @param value the value
  45.205 + * @return gint representing the result
  45.206 + *
  45.207 + **/
  45.208 +gint
  45.209 +gmyth_transcoder_set_profile(GMythTranscoder * trans, const gchar * value)
  45.210 +{
  45.211 +    g_return_val_if_fail(value != NULL, -1);
  45.212 +
  45.213 +    trans->profile = g_strndup(value, strlen(value));
  45.214 +
  45.215 +    return 0;
  45.216 +}
  45.217 +
  45.218 +gboolean
  45.219 +gmyth_transcoder_start(GMythTranscoder * trans)
  45.220 +{
  45.221 +    g_return_val_if_fail(trans != NULL, FALSE);
  45.222 +    g_return_val_if_fail(trans->backend_info != NULL, FALSE);
  45.223 +    g_return_val_if_fail(trans->filename != NULL, FALSE);
  45.224 +
  45.225 +    if (trans->started == FALSE) {  // not started yet
  45.226 +        if (!gmyth_util_file_exists(trans->backend_info, trans->filename)) {
  45.227 +            gmyth_debug("File %s does not exist", trans->filename);
  45.228 +        }
  45.229 +        trans->started = gmyth_jobqueue_add_job(trans, "JOB_TRANSCODE");
  45.230 +        if (trans->started == FALSE)
  45.231 +            gmyth_debug("Error while starting GMythTranscoder to file: %s",
  45.232 +                        trans->output_filename);
  45.233 +    } else {
  45.234 +        gmyth_debug("GMythTransfer already started!");
  45.235 +    }
  45.236 +
  45.237 +    return trans->started;
  45.238 +}
  45.239 +
  45.240 +gboolean
  45.241 +gmyth_transcoder_pause(GMythTranscoder * trans)
  45.242 +{
  45.243 +    g_return_val_if_fail(trans != NULL, FALSE);
  45.244 +    g_return_val_if_fail(trans->started == TRUE, FALSE);
  45.245 +
  45.246 +    return gmyth_jobqueue_change_cmd(trans, "PAUSE", "JOB_TRANSCODE");
  45.247 +}
  45.248 +
  45.249 +gboolean
  45.250 +gmyth_transcoder_resume(GMythTranscoder * trans)
  45.251 +{
  45.252 +    g_return_val_if_fail(trans != NULL, FALSE);
  45.253 +
  45.254 +    return gmyth_jobqueue_change_cmd(trans, "RESUME", "JOB_TRANSCODE");
  45.255 +}
  45.256 +
  45.257 +gboolean
  45.258 +gmyth_transcoder_cancel(GMythTranscoder * trans)
  45.259 +{
  45.260 +    g_return_val_if_fail(trans != NULL, FALSE);
  45.261 +    g_return_val_if_fail(trans->started == TRUE, FALSE);
  45.262 +
  45.263 +    trans->started = FALSE;
  45.264 +
  45.265 +    return gmyth_jobqueue_change_cmd(trans, "STOP", "JOB_TRANSCODE");
  45.266 +}
  45.267 +
  45.268 +// fixme: implement this method
  45.269 +gint
  45.270 +gmyth_transcoder_get_progress(GMythTranscoder * trans)
  45.271 +{
  45.272 +    static int      fixme = 0;
  45.273 +
  45.274 +    return (fixme++) % 101;
  45.275 +}
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/gmyth/gmyth/gmyth_transcoder.h	Mon Feb 25 17:51:43 2008 +0000
    46.3 @@ -0,0 +1,104 @@
    46.4 +/**
    46.5 + * GMyth Library
    46.6 + * 
    46.7 + * @file gmyth/gmyth_transcoder.h
    46.8 + * 
    46.9 + * @brief <p> This file contains the transcoder class.
   46.10 + *
   46.11 + * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   46.12 + * @author Artur Duque de Souza <artur.souza@indt.org.br>
   46.13 + * 
   46.14 + * This program is free software; you can redistribute it and/or modify
   46.15 + * it under the terms of the GNU Lesser General Public License as published by
   46.16 + * the Free Software Foundation; either version 2 of the License, or
   46.17 + * (at your option) any later version.
   46.18 + *
   46.19 + * This program is distributed in the hope that it will be useful,
   46.20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   46.21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   46.22 + * GNU General Public License for more details.
   46.23 + *
   46.24 + * You should have received a copy of the GNU Lesser General Public License
   46.25 + * along with this program; if not, write to the Free Software
   46.26 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   46.27 + */
   46.28 +
   46.29 +#ifndef _GMYTH_TRANSCODER_H
   46.30 +#define _GMYTH_TRANSCODER_H
   46.31 +
   46.32 +#include <glib.h>
   46.33 +#include <glib-object.h>
   46.34 +
   46.35 +#include "gmyth_stringlist.h"
   46.36 +#include "gmyth_backendinfo.h"
   46.37 +#include "gmyth_socket.h"
   46.38 +#include "gmyth_http.h"
   46.39 +#include "gmyth_recprofile.h"
   46.40 +
   46.41 +G_BEGIN_DECLS
   46.42 +#define GMYTH_TRANSCODER_TYPE               (gmyth_transcoder_get_type ())
   46.43 +#define GMYTH_TRANSCODER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TRANSCODER_TYPE, GMythTranscoder))
   46.44 +#define GMYTH_TRANSCODER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TRANSCODER_TYPE, GMythTranscoderClass))
   46.45 +#define IS_GMYTH_TRANSCODER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_TRANSCODER_TYPE))
   46.46 +#define IS_GMYTH_TRANSCODER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TRANSCODER_TYPE))
   46.47 +#define GMYTH_TRANSCODER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_TRANSCODER_TYPE, GMythTranscoderClass))
   46.48 +#define DATE_ISO 0
   46.49 +#define DATE_FILE 1
   46.50 +typedef struct _GMythTranscoder GMythTranscoder;
   46.51 +typedef struct _GMythTranscoderClass GMythTranscoderClass;
   46.52 +
   46.53 +struct _GMythTranscoderClass {
   46.54 +    GObjectClass    parent_class;
   46.55 +
   46.56 +    /*
   46.57 +     * callbacks 
   46.58 +     */
   46.59 +};
   46.60 +
   46.61 +/**
   46.62 + * The GMythTranscoder structure is a class to implement functions
   46.63 + * related to transcoding.
   46.64 + */
   46.65 +struct _GMythTranscoder {
   46.66 +    GObject         parent;
   46.67 +
   46.68 +    gboolean        cutlist;
   46.69 +    gboolean        output;
   46.70 +    gboolean        started;
   46.71 +
   46.72 +    /*
   46.73 +     * private begin 
   46.74 +     */
   46.75 +    gchar          *output_filename;
   46.76 +    gchar          *filename;
   46.77 +    gchar          *profile;
   46.78 +    /*
   46.79 +     * private end 
   46.80 +     */
   46.81 +
   46.82 +    gchar          *starttime;
   46.83 +
   46.84 +    gint            chanid;
   46.85 +
   46.86 +    GMythBackendInfo *backend_info;
   46.87 +};
   46.88 +
   46.89 +GType           gmyth_transcoder_type(void);
   46.90 +
   46.91 +GMythTranscoder *gmyth_transcoder_new(GMythBackendInfo * backend_info);
   46.92 +void            gmyth_transcoder_set_output(GMythTranscoder * transcode,
   46.93 +                                            gboolean value,
   46.94 +                                            const gchar * outputfile);
   46.95 +void            gmyth_transcoder_set_filename(GMythTranscoder * transcode,
   46.96 +                                              const gchar * file);
   46.97 +gint            gmyth_transcoder_set_profile(GMythTranscoder * trans,
   46.98 +                                             const gchar * value);
   46.99 +gboolean        gmyth_transcoder_start(GMythTranscoder * trans);
  46.100 +gboolean        gmyth_transcoder_pause(GMythTranscoder * trans);
  46.101 +gboolean        gmyth_transcoder_resume(GMythTranscoder * trans);
  46.102 +gboolean        gmyth_transcoder_cancel(GMythTranscoder * trans);
  46.103 +gint            gmyth_transcoder_get_progress(GMythTranscoder * trans);
  46.104 +
  46.105 +
  46.106 +G_END_DECLS
  46.107 +#endif /*_GMYTH_TRANSCODER_H*/
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/gmyth/gmyth/gmyth_tvchain.c	Mon Feb 25 17:51:43 2008 +0000
    47.3 @@ -0,0 +1,620 @@
    47.4 +/**
    47.5 + * GMyth Library
    47.6 + *
    47.7 + * @file gmyth/gmyth_tvchain.c
    47.8 + * 
    47.9 + * @brief <p> This component contains functions for creating and accessing
   47.10 + * the tvchain functions for live tv playback.
   47.11 + * 
   47.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   47.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   47.14 + *
   47.15 + * 
   47.16 + * This program is free software; you can redistribute it and/or modify
   47.17 + * it under the terms of the GNU Lesser General Public License as published by
   47.18 + * the Free Software Foundation; either version 2 of the License, or
   47.19 + * (at your option) any later version.
   47.20 + *
   47.21 + * This program is distributed in the hope that it will be useful,
   47.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   47.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   47.24 + * GNU General Public License for more details.
   47.25 + *
   47.26 + * You should have received a copy of the GNU Lesser General Public License
   47.27 + * along with this program; if not, write to the Free Software
   47.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   47.29 + */
   47.30 +
   47.31 +#ifdef HAVE_CONFIG_H
   47.32 +#include "config.h"
   47.33 +#endif
   47.34 +
   47.35 +#include "gmyth_tvchain.h"
   47.36 +
   47.37 +#include <glib.h>
   47.38 +#include <time.h>
   47.39 +#include <stdio.h>
   47.40 +#include <stdlib.h>
   47.41 +#include <assert.h>
   47.42 +
   47.43 +#include "gmyth_epg.h"
   47.44 +#include "gmyth_util.h"
   47.45 +#include "gmyth_query.h"
   47.46 +#include "gmyth_scheduler.h"
   47.47 +#include "gmyth_debug.h"
   47.48 +
   47.49 +static void     gmyth_tvchain_class_init(GMythTVChainClass * klass);
   47.50 +static void     gmyth_tvchain_init(GMythTVChain * object);
   47.51 +
   47.52 +static void     gmyth_tvchain_dispose(GObject * object);
   47.53 +static void     gmyth_tvchain_finalize(GObject * object);
   47.54 +
   47.55 +static void     free_tvchain_entry(gpointer data, gpointer user_data);
   47.56 +
   47.57 +G_DEFINE_TYPE(GMythTVChain, gmyth_tvchain, G_TYPE_OBJECT)
   47.58 +    static void     gmyth_tvchain_class_init(GMythTVChainClass * klass)
   47.59 +{
   47.60 +    GObjectClass   *gobject_class;
   47.61 +
   47.62 +    gobject_class = (GObjectClass *) klass;
   47.63 +
   47.64 +    gobject_class->dispose = gmyth_tvchain_dispose;
   47.65 +    gobject_class->finalize = gmyth_tvchain_finalize;
   47.66 +}
   47.67 +
   47.68 +static void
   47.69 +gmyth_tvchain_init(GMythTVChain * tvchain)
   47.70 +{
   47.71 +    tvchain->tvchain_id = NULL;
   47.72 +
   47.73 +    tvchain->cur_chanid = g_string_new("");
   47.74 +    tvchain->cur_startts = NULL;
   47.75 +
   47.76 +    tvchain->mutex = g_mutex_new();
   47.77 +}
   47.78 +
   47.79 +GMythTVChain   *
   47.80 +gmyth_tvchain_new()
   47.81 +{
   47.82 +    GMythTVChain   *tvchain =
   47.83 +        GMYTH_TVCHAIN(g_object_new(GMYTH_TVCHAIN_TYPE, NULL));
   47.84 +
   47.85 +    return tvchain;
   47.86 +}
   47.87 +
   47.88 +static void
   47.89 +gmyth_tvchain_dispose(GObject * object)
   47.90 +{
   47.91 +    GMythTVChain   *tvchain = GMYTH_TVCHAIN(object);
   47.92 +
   47.93 +    if (tvchain->tvchain_id != NULL) {
   47.94 +        g_string_free(tvchain->tvchain_id, TRUE);
   47.95 +        tvchain->tvchain_id = NULL;
   47.96 +    }
   47.97 +
   47.98 +    if (tvchain->mutex != NULL) {
   47.99 +        g_mutex_free(tvchain->mutex);
  47.100 +        tvchain->mutex = NULL;
  47.101 +    }
  47.102 +
  47.103 +    if (tvchain->tvchain_list != NULL) {
  47.104 +        g_list_foreach(tvchain->tvchain_list, free_tvchain_entry, NULL);
  47.105 +        g_list_free(tvchain->tvchain_list);
  47.106 +    }
  47.107 +
  47.108 +    if (tvchain->cur_chanid != NULL) {
  47.109 +        g_string_free(tvchain->cur_chanid, TRUE);
  47.110 +        tvchain->cur_chanid = NULL;
  47.111 +    }
  47.112 +
  47.113 +    if (tvchain->backend_info) {
  47.114 +        g_object_unref(tvchain->backend_info);
  47.115 +        tvchain->backend_info = NULL;
  47.116 +    }
  47.117 +
  47.118 +
  47.119 +    G_OBJECT_CLASS(gmyth_tvchain_parent_class)->dispose(object);
  47.120 +}
  47.121 +
  47.122 +static void
  47.123 +gmyth_tvchain_finalize(GObject * object)
  47.124 +{
  47.125 +    g_signal_handlers_destroy(object);
  47.126 +
  47.127 +    G_OBJECT_CLASS(gmyth_tvchain_parent_class)->finalize(object);
  47.128 +}
  47.129 +
  47.130 +/** Initializes the tvchain and generates the tvchain id.
  47.131 + * 
  47.132 + * @param tvchain The GMythTVChain instance.
  47.133 + * @param hostname The local hostname used to generate the tvchain id.
  47.134 + */
  47.135 +gboolean
  47.136 +gmyth_tvchain_initialize(GMythTVChain * tvchain,
  47.137 +                         GMythBackendInfo * backend_info)
  47.138 +{
  47.139 +    const char     *hostname;
  47.140 +
  47.141 +    assert(tvchain);
  47.142 +    g_return_val_if_fail(backend_info != NULL, FALSE);
  47.143 +
  47.144 +    g_object_ref(backend_info);
  47.145 +    tvchain->backend_info = backend_info;
  47.146 +
  47.147 +    hostname = gmyth_backend_info_get_hostname(backend_info);
  47.148 +
  47.149 +    if (tvchain->tvchain_id == NULL) {
  47.150 +        gchar          *isodate = NULL;
  47.151 +        GTimeVal       *cur_time = g_new0(GTimeVal, 1);
  47.152 +
  47.153 +        // struct tm* gmyth_util_time_val_to_date ( const GTimeVal* time )
  47.154 +
  47.155 +        g_get_current_time(cur_time);
  47.156 +        isodate =
  47.157 +            gmyth_util_time_to_isoformat_from_time_val_fmt
  47.158 +            ("%Y-%m-%dT%H:%M:%S", cur_time);
  47.159 +
  47.160 +        tvchain->tvchain_id =
  47.161 +            g_string_sized_new(7 + strlen(hostname) + strlen(isodate));
  47.162 +        g_string_printf(tvchain->tvchain_id, "live-%s-%s", hostname,
  47.163 +                        isodate);
  47.164 +
  47.165 +        gmyth_debug("[%s] tv_chain_id: %s", __FUNCTION__,
  47.166 +                    tvchain->tvchain_id->str);
  47.167 +
  47.168 +        g_free(isodate);
  47.169 +        g_free(cur_time);
  47.170 +    } else {
  47.171 +        gmyth_debug("[%s] TVchain already initialized", __FUNCTION__);
  47.172 +    }
  47.173 +
  47.174 +    return TRUE;
  47.175 +}
  47.176 +
  47.177 +/** Gets the tvchain id.
  47.178 + * 
  47.179 + * @param tvchain The GMythTVChain instance.
  47.180 + * @return The tvchain id.
  47.181 + */
  47.182 +GString        *
  47.183 +gmyth_tvchain_get_id(GMythTVChain * tvchain)
  47.184 +{
  47.185 +    g_return_val_if_fail(tvchain != NULL
  47.186 +                         && tvchain->tvchain_id != NULL, NULL);
  47.187 +
  47.188 +    return tvchain->tvchain_id;
  47.189 +}
  47.190 +
  47.191 +/** Reloads all tvchain entries in the database.
  47.192 + * 
  47.193 + * @param tvchain The GMythTVChain instance.
  47.194 + * @return  TRUE if success, or FALSE if error.
  47.195 + */
  47.196 +gboolean
  47.197 +gmyth_tvchain_reload_all(GMythTVChain * tvchain)
  47.198 +{
  47.199 +    MYSQL_ROW       msql_row;
  47.200 +    MYSQL_RES      *msql_res = NULL;
  47.201 +    GMythQuery     *gmyth_query = NULL;
  47.202 +    gboolean        ret = TRUE;
  47.203 +    GString        *stmt_str = NULL;
  47.204 +
  47.205 +    g_mutex_lock(tvchain->mutex);
  47.206 +
  47.207 +    /*
  47.208 +     * gets the initial size of the TVChain entries list 
  47.209 +     */
  47.210 +    guint           prev_size = g_list_length(tvchain->tvchain_list);
  47.211 +
  47.212 +    gmyth_debug("[%s] chainid: %s", __FUNCTION__,
  47.213 +                tvchain->tvchain_id->str);
  47.214 +
  47.215 +    if (tvchain != NULL && tvchain->tvchain_list != NULL) {
  47.216 +        g_list_free(tvchain->tvchain_list);
  47.217 +        tvchain->tvchain_list = NULL;
  47.218 +    }
  47.219 +
  47.220 +    /*
  47.221 +     * TODO: Reuse gmyth_query already connected from context 
  47.222 +     */
  47.223 +    gmyth_query = gmyth_query_new();
  47.224 +    if (!gmyth_query_connect(gmyth_query, tvchain->backend_info)) {
  47.225 +        gmyth_debug("[%s] Could not connect to db", __FUNCTION__);
  47.226 +        g_mutex_unlock(tvchain->mutex);
  47.227 +        ret = FALSE;
  47.228 +        goto done;
  47.229 +    }
  47.230 +
  47.231 +    stmt_str = g_string_new("");
  47.232 +    g_string_printf(stmt_str,
  47.233 +                    "SELECT chanid, starttime, endtime, discontinuity, "
  47.234 +                    "chainpos, hostprefix, cardtype, channame, input "
  47.235 +                    "FROM tvchain "
  47.236 +                    "WHERE chainid = \"%s\" ORDER BY chainpos;",
  47.237 +                    tvchain->tvchain_id->str);
  47.238 +
  47.239 +    msql_res = gmyth_query_process_statement(gmyth_query, stmt_str->str);
  47.240 +    if (msql_res != NULL) {
  47.241 +
  47.242 +        while ((msql_row = mysql_fetch_row(msql_res)) != NULL) {
  47.243 +            struct LiveTVChainEntry *entry =
  47.244 +                g_new0(struct LiveTVChainEntry, 1);
  47.245 +            entry->chanid = g_string_new(msql_row[0]);
  47.246 +            entry->starttime =
  47.247 +                gmyth_util_string_to_time_val((const gchar *) msql_row[1]);
  47.248 +            entry->endtime =
  47.249 +                gmyth_util_string_to_time_val((const gchar *) msql_row[2]);
  47.250 +            entry->discontinuity =
  47.251 +                g_ascii_strtoull(msql_row[3], NULL, 10) != 0;
  47.252 +            entry->hostprefix = g_string_new(msql_row[5]);
  47.253 +            entry->cardtype = g_string_new(msql_row[6]);
  47.254 +            entry->channum = g_string_new(msql_row[7]);
  47.255 +            entry->inputname = g_string_new(msql_row[8]);
  47.256 +
  47.257 +            // m_maxpos = query.value(4).toInt() + 1;
  47.258 +            gmyth_debug
  47.259 +                ("[%s] Reading TV chain entry (channel %s): [%s, %s, %s]\n",
  47.260 +                 __FUNCTION__, entry->channum->str, entry->chanid->str,
  47.261 +                 (gchar *) msql_row[1], (gchar *) msql_row[2]);
  47.262 +
  47.263 +            /*
  47.264 +             * add this to get the actual start timestamp of the last
  47.265 +             * recording 
  47.266 +             */
  47.267 +            if (tvchain->cur_startts < entry->starttime)
  47.268 +                tvchain->cur_startts = entry->starttime;
  47.269 +
  47.270 +            tvchain->tvchain_list =
  47.271 +                g_list_append(tvchain->tvchain_list, entry);
  47.272 +        }
  47.273 +    } else {
  47.274 +        gmyth_debug("gmyth_tvchain_reload_all query error!\n");
  47.275 +        g_mutex_unlock(tvchain->mutex);
  47.276 +
  47.277 +        ret = FALSE;
  47.278 +        goto done;
  47.279 +    }
  47.280 +
  47.281 +    g_mutex_unlock(tvchain->mutex);
  47.282 +
  47.283 +    tvchain->cur_pos =
  47.284 +        gmyth_tvchain_program_is_at(tvchain, tvchain->cur_chanid,
  47.285 +                                    tvchain->cur_startts);
  47.286 +    gmyth_debug("[%s] TVChain current position = %d.\n", __FUNCTION__,
  47.287 +                tvchain->cur_pos);
  47.288 +
  47.289 +    if (tvchain->cur_pos < 0)
  47.290 +        tvchain->cur_pos = 0;
  47.291 +
  47.292 +    // if (m_switchid >= 0)
  47.293 +    // m_switchid =
  47.294 +    // ProgramIsAt(m_switchentry.chanid,m_switchentry.starttime);
  47.295 +
  47.296 +    if (prev_size != g_list_length(tvchain->tvchain_list)) {
  47.297 +        gmyth_debug("[%s] Added new recording", __FUNCTION__);
  47.298 +    }
  47.299 +
  47.300 +  done:
  47.301 +    if (stmt_str != NULL)
  47.302 +        g_string_free(stmt_str, TRUE);
  47.303 +
  47.304 +    if (msql_res != NULL)
  47.305 +        mysql_free_result(msql_res);
  47.306 +
  47.307 +    if (gmyth_query != NULL)
  47.308 +        g_object_unref(gmyth_query);
  47.309 +
  47.310 +    return ret;
  47.311 +}
  47.312 +
  47.313 +/** 
  47.314 + * Get all the program info entries in the database.
  47.315 + * 
  47.316 + * @param tvchain The GMythTVChain instance.
  47.317 + * 
  47.318 + * @return  A program info listage.
  47.319 + */
  47.320 +GList          *
  47.321 +gmyth_tvchain_get_program_info_list(GMythTVChain * tvchain)
  47.322 +{
  47.323 +    GList          *prog_list = NULL;
  47.324 +    MYSQL_ROW       msql_row;
  47.325 +    MYSQL_RES      *msql_res = NULL;
  47.326 +    GMythQuery     *gmyth_query = NULL;
  47.327 +    GString        *stmt_str = NULL;
  47.328 +
  47.329 +    g_mutex_lock(tvchain->mutex);
  47.330 +
  47.331 +    gmyth_query = gmyth_query_new();
  47.332 +    if (!gmyth_query_connect(gmyth_query, tvchain->backend_info)) {
  47.333 +        gmyth_debug("Could not connect to db.");
  47.334 +        goto done;
  47.335 +    }
  47.336 +
  47.337 +    stmt_str = g_string_new("");
  47.338 +    g_string_printf(stmt_str,
  47.339 +                    "SELECT channum, icon " "FROM channel "
  47.340 +                    "ORDER BY channum;");
  47.341 +
  47.342 +    msql_res = gmyth_query_process_statement(gmyth_query, stmt_str->str);
  47.343 +    if (msql_res != NULL) {
  47.344 +
  47.345 +        while ((msql_row = mysql_fetch_row(msql_res)) != NULL) {
  47.346 +            GMythProgramInfo *entry = gmyth_program_info_new();
  47.347 +
  47.348 +            entry->channame = g_string_new(msql_row[0]);
  47.349 +            entry->chansign = g_string_new(msql_row[1]);
  47.350 +
  47.351 +            gmyth_debug
  47.352 +                ("Reading TV program info entry (channel %s): [%s - {%s, %s}]\n",
  47.353 +                 entry->channame->str, entry->chansign->str,
  47.354 +                 (gchar *) msql_row[0], (gchar *) msql_row[1]);
  47.355 +
  47.356 +            prog_list = g_list_append(prog_list, entry);
  47.357 +        }
  47.358 +    } else {
  47.359 +        gmyth_debug
  47.360 +            ("Query error when trying to get the channel list from database!\n");
  47.361 +        goto done;
  47.362 +    }
  47.363 +
  47.364 +  done:
  47.365 +    g_mutex_unlock(tvchain->mutex);
  47.366 +
  47.367 +    if (stmt_str != NULL)
  47.368 +        g_string_free(stmt_str, TRUE);
  47.369 +
  47.370 +    if (msql_res != NULL)
  47.371 +        mysql_free_result(msql_res);
  47.372 +
  47.373 +    if (gmyth_query != NULL)
  47.374 +        g_object_unref(gmyth_query);
  47.375 +
  47.376 +    return prog_list;
  47.377 +}
  47.378 +
  47.379 +/** 
  47.380 + * Get all the program info entries in the database, given a channel name.
  47.381 + * 
  47.382 + * @param tvchain The GMythTVChain instance.
  47.383 + * @param channel The channel name.
  47.384 + * 
  47.385 + * @return  A program info listage, based on a given channel name.
  47.386 + */
  47.387 +GList          *
  47.388 +gmyth_tvchain_get_program_info_from_channel(GMythTVChain * tvchain,
  47.389 +                                            const gchar * channel)
  47.390 +{
  47.391 +    GList          *prog_list = NULL;
  47.392 +    MYSQL_ROW       msql_row;
  47.393 +    MYSQL_RES      *msql_res = NULL;
  47.394 +    GMythQuery     *gmyth_query = NULL;
  47.395 +    GString        *stmt_str = NULL;
  47.396 +
  47.397 +    g_mutex_lock(tvchain->mutex);
  47.398 +
  47.399 +    gmyth_query = gmyth_query_new();
  47.400 +    if (!gmyth_query_connect(gmyth_query, tvchain->backend_info)) {
  47.401 +        gmyth_debug("Could not connect to db.");
  47.402 +        goto done;
  47.403 +    }
  47.404 +
  47.405 +    stmt_str = g_string_new("");
  47.406 +    g_string_printf(stmt_str,
  47.407 +                    "SELECT channum, icon "
  47.408 +                    "FROM channel "
  47.409 +                    "WHERE channum = \"%s\" ORDER BY channum;", channel);
  47.410 +
  47.411 +    msql_res = gmyth_query_process_statement(gmyth_query, stmt_str->str);
  47.412 +    if (msql_res != NULL) {
  47.413 +
  47.414 +        while ((msql_row = mysql_fetch_row(msql_res)) != NULL) {
  47.415 +            GMythProgramInfo *entry = gmyth_program_info_new();
  47.416 +
  47.417 +            entry->channame = g_string_new(msql_row[0]);
  47.418 +            entry->chansign = g_string_new(msql_row[1]);
  47.419 +
  47.420 +            gmyth_debug
  47.421 +                ("Reading TV program info entry (channel %s): [%s - {%s, %s}]\n",
  47.422 +                 entry->channame->str, entry->chansign->str,
  47.423 +                 (gchar *) msql_row[0], (gchar *) msql_row[1]);
  47.424 +
  47.425 +            prog_list = g_list_append(prog_list, entry);
  47.426 +        }
  47.427 +    } else {
  47.428 +        gmyth_debug
  47.429 +            ("Query error when trying to get the channel list from database!\n");
  47.430 +        goto done;
  47.431 +    }
  47.432 +
  47.433 +  done:
  47.434 +    g_mutex_unlock(tvchain->mutex);
  47.435 +
  47.436 +    if (stmt_str != NULL)
  47.437 +        g_string_free(stmt_str, TRUE);
  47.438 +
  47.439 +    if (msql_res != NULL)
  47.440 +        mysql_free_result(msql_res);
  47.441 +
  47.442 +    if (gmyth_query != NULL)
  47.443 +        g_object_unref(gmyth_query);
  47.444 +
  47.445 +    return prog_list;
  47.446 +}
  47.447 +
  47.448 +/** 
  47.449 + * Returns the internal index for the TV chain related to the given
  47.450 + * channel and start time.
  47.451 + * 
  47.452 + * @param tvchain The GMythTVChain instance.
  47.453 + * @param chanid The channel id.
  47.454 + * @param startts The program start time.
  47.455 + * 
  47.456 + * @return The position of the related program info in the TV chain.
  47.457 + */
  47.458 +gint
  47.459 +gmyth_tvchain_program_is_at(GMythTVChain * tvchain, GString * chanid,
  47.460 +                            GTimeVal * startts)
  47.461 +{
  47.462 +    gint            count = 0;
  47.463 +    struct LiveTVChainEntry *entry;
  47.464 +    GList          *tmp_list = tvchain->tvchain_list;
  47.465 +    guint           list_size = g_list_length(tvchain->tvchain_list);
  47.466 +
  47.467 +    g_mutex_lock(tvchain->mutex);
  47.468 +
  47.469 +    for (; tmp_list && (count < list_size);
  47.470 +         tmp_list = tvchain->tvchain_list->next, count++) {
  47.471 +        entry = (struct LiveTVChainEntry *) tmp_list->data;
  47.472 +        if (!g_strncasecmp(entry->chanid->str, chanid->str, chanid->len)
  47.473 +            && entry->starttime == startts) {
  47.474 +            g_mutex_unlock(tvchain->mutex);
  47.475 +            return count;
  47.476 +        }
  47.477 +    }
  47.478 +    g_mutex_unlock(tvchain->mutex);
  47.479 +
  47.480 +    return -1;
  47.481 +}
  47.482 +
  47.483 +/** Get the program info associated to the tvchain.
  47.484 + * 
  47.485 + * @param tvchain The GMythTVChain instance.
  47.486 + * @param index The tvchain index.
  47.487 + * 
  47.488 + * @return The program info structure.
  47.489 + */
  47.490 +GMythProgramInfo *
  47.491 +gmyth_tvchain_get_program_at(GMythTVChain * tvchain, gint index)
  47.492 +{
  47.493 +    struct LiveTVChainEntry *entry;
  47.494 +
  47.495 +    entry = gmyth_tvchain_get_entry_at(tvchain, index);
  47.496 +
  47.497 +    if (entry)
  47.498 +        return gmyth_tvchain_entry_to_program(tvchain, entry);
  47.499 +
  47.500 +    return NULL;
  47.501 +}
  47.502 +
  47.503 +/** Gets a LiveTVChainEntry associated to the tvchain by its index.
  47.504 + * 
  47.505 + * @param tvchain The GMythTVChain instance.
  47.506 + * @param index The tvchain entry index
  47.507 + * @return The LiveTVchainEntry structure.
  47.508 + */
  47.509 +struct LiveTVChainEntry *
  47.510 +gmyth_tvchain_get_entry_at(GMythTVChain * tvchain, gint index)
  47.511 +{
  47.512 +    struct LiveTVChainEntry *chain_entry = NULL;
  47.513 +
  47.514 +    g_return_val_if_fail(tvchain != NULL
  47.515 +                         && tvchain->tvchain_list != NULL, NULL);
  47.516 +
  47.517 +    g_mutex_lock(tvchain->mutex);
  47.518 +
  47.519 +    gint            size = g_list_length(tvchain->tvchain_list);
  47.520 +    gint            new_index = (index < 0
  47.521 +                                 || index >= size) ? size - 1 : index;
  47.522 +
  47.523 +    if (new_index >= 0)
  47.524 +        chain_entry =
  47.525 +            (struct LiveTVChainEntry *) g_list_nth_data(tvchain->
  47.526 +                                                        tvchain_list,
  47.527 +                                                        new_index);
  47.528 +
  47.529 +    g_mutex_unlock(tvchain->mutex);
  47.530 +
  47.531 +    if (chain_entry != NULL) {
  47.532 +        gmyth_debug("[%s] Got TV Chain entry at %d.\n", __FUNCTION__,
  47.533 +                    new_index);
  47.534 +
  47.535 +    } else {
  47.536 +        gmyth_debug("[%s] failed to get entry at index %d", __FUNCTION__,
  47.537 +                    index);
  47.538 +    }
  47.539 +
  47.540 +    return chain_entry;
  47.541 +}
  47.542 +
  47.543 +/** 
  47.544 + * Gets the program info from backend database associated to the tv chain entry.
  47.545 + * 
  47.546 + * @param tvchain The GMythTVChain instance.
  47.547 + * @param entry the LiveTVChainEntry to be converted.
  47.548 + * 
  47.549 + * @return The program info.
  47.550 + */
  47.551 +GMythProgramInfo *
  47.552 +gmyth_tvchain_entry_to_program(GMythTVChain * tvchain,
  47.553 +                               struct LiveTVChainEntry * entry)
  47.554 +{
  47.555 +    GMythProgramInfo *proginfo = NULL;
  47.556 +
  47.557 +    g_return_val_if_fail(tvchain != NULL, NULL);
  47.558 +
  47.559 +    if (!entry || !tvchain) {
  47.560 +        gmyth_debug
  47.561 +            ("gmyth_tvchain_entry_to_program() received NULL argument");
  47.562 +        return NULL;
  47.563 +    }
  47.564 +
  47.565 +    GMythScheduler *scheduler = gmyth_scheduler_new();
  47.566 +
  47.567 +    gmyth_scheduler_connect(scheduler, tvchain->backend_info);
  47.568 +    proginfo = gmyth_scheduler_get_recorded(scheduler,
  47.569 +                                            entry->chanid,
  47.570 +                                            entry->starttime);
  47.571 +    gmyth_scheduler_disconnect(scheduler);
  47.572 +
  47.573 +    if (proginfo) {
  47.574 +        proginfo->pathname =
  47.575 +            g_string_prepend(proginfo->pathname, entry->hostprefix->str);
  47.576 +    } else {
  47.577 +        gmyth_debug
  47.578 +            ("tvchain_entry_to_program( chan id = %s, starttime = %ld) failed!",
  47.579 +             entry->chanid->str, entry->starttime->tv_sec);
  47.580 +    }
  47.581 +
  47.582 +    return proginfo;
  47.583 +}
  47.584 +
  47.585 +static void
  47.586 +free_tvchain_entry(gpointer data, gpointer user_data)
  47.587 +{
  47.588 +    struct LiveTVChainEntry *entry;
  47.589 +
  47.590 +    g_return_if_fail(data != NULL);
  47.591 +
  47.592 +    entry = (struct LiveTVChainEntry *) data;
  47.593 +
  47.594 +    if (entry->chanid != NULL) {
  47.595 +        g_string_free(entry->chanid, TRUE);
  47.596 +    }
  47.597 +
  47.598 +    if (entry->starttime != NULL) {
  47.599 +        g_free(entry->starttime);
  47.600 +    }
  47.601 +
  47.602 +    if (entry->endtime != NULL) {
  47.603 +        g_free(entry->endtime);
  47.604 +    }
  47.605 +
  47.606 +    if (entry->hostprefix) {
  47.607 +        g_string_free(entry->hostprefix, TRUE);
  47.608 +    }
  47.609 +
  47.610 +    if (entry->cardtype) {
  47.611 +        g_string_free(entry->cardtype, TRUE);
  47.612 +    }
  47.613 +
  47.614 +    if (entry->channum) {
  47.615 +        g_string_free(entry->channum, TRUE);
  47.616 +    }
  47.617 +
  47.618 +    if (entry->inputname) {
  47.619 +        g_string_free(entry->inputname, TRUE);
  47.620 +    }
  47.621 +
  47.622 +    g_free(entry);
  47.623 +}
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/gmyth/gmyth/gmyth_tvchain.h	Mon Feb 25 17:51:43 2008 +0000
    48.3 @@ -0,0 +1,118 @@
    48.4 +/**
    48.5 + * GMyth Library
    48.6 + *
    48.7 + * @file gmyth/gmyth_tvchain.h
    48.8 + * 
    48.9 + * @brief <p> This component contains functions for creating and accessing
   48.10 + * the tvchain functions for live tv playback.
   48.11 + * 
   48.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   48.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   48.14 + *
   48.15 + * 
   48.16 + * This program is free software; you can redistribute it and/or modify
   48.17 + * it under the terms of the GNU Lesser General Public License as published by
   48.18 + * the Free Software Foundation; either version 2 of the License, or
   48.19 + * (at your option) any later version.
   48.20 + *
   48.21 + * This program is distributed in the hope that it will be useful,
   48.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   48.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   48.24 + * GNU General Public License for more details.
   48.25 + *
   48.26 + * You should have received a copy of the GNU Lesser General Public License
   48.27 + * along with this program; if not, write to the Free Software
   48.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   48.29 + */
   48.30 +
   48.31 +#ifndef LIVETVCHAIN_H_
   48.32 +#define LIVETVCHAIN_H_
   48.33 +
   48.34 +#include <glib-object.h>
   48.35 +#include <time.h>
   48.36 +
   48.37 +#include "gmyth_common.h"
   48.38 +#include "gmyth_backendinfo.h"
   48.39 +
   48.40 +G_BEGIN_DECLS
   48.41 +#define GMYTH_TVCHAIN_TYPE               (gmyth_tvchain_get_type ())
   48.42 +#define GMYTH_TVCHAIN(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChain))
   48.43 +#define GMYTH_TVCHAIN_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
   48.44 +#define IS_GMYTH_TVCHAIN(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_TVCHAIN_TYPE))
   48.45 +#define IS_GMYTH_TVCHAIN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE))
   48.46 +#define GMYTH_TVCHAIN_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
   48.47 +typedef struct _GMythTVChain GMythTVChain;
   48.48 +typedef struct _GMythTVChainClass GMythTVChainClass;
   48.49 +
   48.50 +
   48.51 +struct LiveTVChainEntry {
   48.52 +    GString        *chanid;
   48.53 +
   48.54 +    GTimeVal       *starttime;
   48.55 +    GTimeVal       *endtime;
   48.56 +
   48.57 +    gboolean        discontinuity;  // if true, can't play smooth from
   48.58 +    // last entry
   48.59 +    GString        *hostprefix;
   48.60 +    GString        *cardtype;
   48.61 +    GString        *channum;
   48.62 +    GString        *inputname;
   48.63 +};
   48.64 +
   48.65 +
   48.66 +struct _GMythTVChainClass {
   48.67 +    GObjectClass    parent_class;
   48.68 +
   48.69 +    /*
   48.70 +     * callbacks 
   48.71 +     */
   48.72 +    /*
   48.73 +     * no one for now 
   48.74 +     */
   48.75 +};
   48.76 +
   48.77 +struct _GMythTVChain {
   48.78 +    GObject         parent;
   48.79 +
   48.80 +    GString        *tvchain_id;
   48.81 +    GList          *tvchain_list;
   48.82 +
   48.83 +    GTimeVal       *cur_startts;
   48.84 +    GString        *cur_chanid;
   48.85 +    gint            cur_pos;
   48.86 +
   48.87 +    GMythBackendInfo *backend_info;
   48.88 +
   48.89 +    GMutex         *mutex;
   48.90 +};
   48.91 +
   48.92 +GType           gmyth_tvchain_get_type(void);
   48.93 +
   48.94 +GMythTVChain   *gmyth_tvchain_new();
   48.95 +
   48.96 +gboolean        gmyth_tvchain_initialize(GMythTVChain * tvchain,
   48.97 +                                         GMythBackendInfo * backend_info);
   48.98 +gboolean        gmyth_tvchain_reload_all(GMythTVChain * tvchain);
   48.99 +GString        *gmyth_tvchain_get_id(GMythTVChain * tvchain);
  48.100 +gint            gmyth_tvchain_program_is_at(GMythTVChain * tvchain,
  48.101 +                                            GString * chanid,
  48.102 +                                            GTimeVal * startts);
  48.103 +
  48.104 +struct LiveTVChainEntry *gmyth_tvchain_get_entry_at(GMythTVChain * tvchain,
  48.105 +                                                    gint index);
  48.106 +
  48.107 +GMythProgramInfo *gmyth_tvchain_entry_to_program(GMythTVChain * tvchain, struct LiveTVChainEntry
  48.108 +                                                 *entry);
  48.109 +GMythProgramInfo *gmyth_tvchain_get_program_at(GMythTVChain * tvchain,
  48.110 +                                               gint index);
  48.111 +
  48.112 +GList          *gmyth_tvchain_get_program_info_from_channel(GMythTVChain *
  48.113 +                                                            tvchain,
  48.114 +                                                            const gchar *
  48.115 +                                                            channel);
  48.116 +
  48.117 +GList          *gmyth_tvchain_get_program_info_list(GMythTVChain *
  48.118 +                                                    tvchain);
  48.119 +
  48.120 +G_END_DECLS
  48.121 +#endif                          /* LIVETVCHAIN_H_ */
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/gmyth/gmyth/gmyth_uri.c	Mon Feb 25 17:51:43 2008 +0000
    49.3 @@ -0,0 +1,604 @@
    49.4 +/** 
    49.5 + * GMyth Library
    49.6 + *
    49.7 + * @file gmyth/gmyth_uri.c
    49.8 + * 
    49.9 + * @brief <p> GMythURI utils
   49.10 + *  - Extracts and parses a URI char string, in according with the RFC 2396 
   49.11 + *    [http://www.ietf.org/rfc/rfc2396.txt]
   49.12 + * 
   49.13 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   49.14 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
   49.15 + *
   49.16 + * 
   49.17 + * This program is free software; you can redistribute it and/or modify
   49.18 + * it under the terms of the GNU Lesser General Public License as published by
   49.19 + * the Free Software Foundation; either version 2 of the License, or
   49.20 + * (at your option) any later version.
   49.21 + *
   49.22 + * This program is distributed in the hope that it will be useful,
   49.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   49.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   49.25 + * GNU General Public License for more details.
   49.26 + *
   49.27 + * You should have received a copy of the GNU Lesser General Public License
   49.28 + * along with this program; if not, write to the Free Software
   49.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   49.30 + */
   49.31 +
   49.32 +#ifdef HAVE_CONFIG_H
   49.33 +#include "config.h"
   49.34 +#endif
   49.35 +
   49.36 +#include "gmyth_uri.h"
   49.37 +#include "gmyth_socket.h"
   49.38 +
   49.39 +#include <glib.h>
   49.40 +#include <string.h>
   49.41 +#include <stdlib.h>
   49.42 +
   49.43 +#include "gmyth_debug.h"
   49.44 +
   49.45 +/****************************************
   49.46 +* Define
   49.47 +****************************************/
   49.48 +
   49.49 +#define GMYTH_URI_KNKOWN_PORT               (-1)
   49.50 +#define GMYTH_URI_DEFAULT_HTTP_PORT         80
   49.51 +#define GMYTH_URI_DEFAULT_FTP_PORT          21
   49.52 +#define GMYTH_URI_DEFAULT_MYTH_PORT         6543
   49.53 +#define GMYTH_URI_DEFAULT_PATH              "/"
   49.54 +#define GMYTH_URI_MAXLEN                    256
   49.55 +
   49.56 +#define GMYTH_URI_PROTOCOL_DELIM            "://"
   49.57 +#define GMYTH_URI_USER_DELIM                "@"
   49.58 +#define GMYTH_URI_COLON_DELIM               ":"
   49.59 +#define GMYTH_URI_SLASH_DELIM               "/"
   49.60 +#define GMYTH_URI_SBLACET_DELIM             "["
   49.61 +#define GMYTH_URI_EBLACET_DELIM             "]"
   49.62 +#define GMYTH_URI_SHARP_DELIM               "#"
   49.63 +#define GMYTH_URI_QUESTION_DELIM            "?"
   49.64 +#define GMYTH_URI_E_DELIM                   "&"
   49.65 +#define GMYTH_URI_ESCAPING_CHAR             "%"
   49.66 +
   49.67 +#define GMYTH_URI_PROTOCOL_MYTH             "myth"
   49.68 +#define GMYTH_URI_PROTOCOL_HTTP             "http"
   49.69 +#define GMYTH_URI_PROTOCOL_FTP              "ftp"
   49.70 +
   49.71 +
   49.72 +static void     gmyth_uri_class_init(GMythURIClass * klass);
   49.73 +static void     gmyth_uri_init(GMythURI * object);
   49.74 +
   49.75 +static void     gmyth_uri_dispose(GObject * object);
   49.76 +static void     gmyth_uri_finalize(GObject * object);
   49.77 +
   49.78 +static void     gmyth_uri_parser_setup_and_new(GMythURI * uri,
   49.79 +                                               const gchar * value);
   49.80 +static gchar   *gmyth_uri_print_field(const GString * field);
   49.81 +
   49.82 +G_DEFINE_TYPE(GMythURI, gmyth_uri, G_TYPE_OBJECT)
   49.83 +    static void     gmyth_uri_class_init(GMythURIClass * klass)
   49.84 +{
   49.85 +    GObjectClass   *gobject_class;
   49.86 +
   49.87 +    gobject_class = (GObjectClass *) klass;
   49.88 +
   49.89 +    gobject_class->dispose = gmyth_uri_dispose;
   49.90 +    gobject_class->finalize = gmyth_uri_finalize;
   49.91 +}
   49.92 +
   49.93 +static void
   49.94 +gmyth_uri_init(GMythURI * gmyth_uri)
   49.95 +{
   49.96 +}
   49.97 +
   49.98 +static void
   49.99 +gmyth_uri_dispose(GObject * object)
  49.100 +{
  49.101 +    GMythURI       *gmyth_uri = GMYTH_URI(object);
  49.102 +
  49.103 +    if (gmyth_uri->host != NULL) {
  49.104 +        g_string_free(gmyth_uri->host, TRUE);
  49.105 +        gmyth_uri->host = NULL;
  49.106 +    }
  49.107 +
  49.108 +    if (gmyth_uri->protocol != NULL) {
  49.109 +        g_string_free(gmyth_uri->protocol, TRUE);
  49.110 +        gmyth_uri->protocol = NULL;
  49.111 +    }
  49.112 +
  49.113 +    if (gmyth_uri->path != NULL) {
  49.114 +        g_string_free(gmyth_uri->path, TRUE);
  49.115 +        gmyth_uri->path = NULL;
  49.116 +    }
  49.117 +
  49.118 +    if (gmyth_uri->fragment != NULL) {
  49.119 +        g_string_free(gmyth_uri->fragment, TRUE);
  49.120 +        gmyth_uri->fragment = NULL;
  49.121 +    }
  49.122 +
  49.123 +    if (gmyth_uri->user != NULL) {
  49.124 +        g_string_free(gmyth_uri->user, TRUE);
  49.125 +        gmyth_uri->user = NULL;
  49.126 +    }
  49.127 +
  49.128 +    if (gmyth_uri->password != NULL) {
  49.129 +        g_string_free(gmyth_uri->password, TRUE);
  49.130 +        gmyth_uri->password = NULL;
  49.131 +    }
  49.132 +
  49.133 +    if (gmyth_uri->query != NULL) {
  49.134 +        g_string_free(gmyth_uri->query, TRUE);
  49.135 +        gmyth_uri->query = NULL;
  49.136 +    }
  49.137 +
  49.138 +    if (gmyth_uri->uri != NULL) {
  49.139 +        g_string_free(gmyth_uri->uri, TRUE);
  49.140 +        gmyth_uri->uri = NULL;
  49.141 +    }
  49.142 +
  49.143 +
  49.144 +    G_OBJECT_CLASS(gmyth_uri_parent_class)->dispose(object);
  49.145 +}
  49.146 +
  49.147 +static void
  49.148 +gmyth_uri_finalize(GObject * object)
  49.149 +{
  49.150 +    // GMythURI *gmyth_uri = GMYTH_URI(object);
  49.151 +
  49.152 +    g_signal_handlers_destroy(object);
  49.153 +
  49.154 +    G_OBJECT_CLASS(gmyth_uri_parent_class)->finalize(object);
  49.155 +}
  49.156 +
  49.157 +/** 
  49.158 + * Creates a new instance of GMythURI.
  49.159 + * 
  49.160 + * @return a new instance of GMythURI.
  49.161 + */
  49.162 +GMythURI       *
  49.163 +gmyth_uri_new(void)
  49.164 +{
  49.165 +    GMythURI       *gmyth_uri =
  49.166 +        GMYTH_URI(g_object_new(GMYTH_URI_TYPE, NULL));
  49.167 +
  49.168 +    return gmyth_uri;
  49.169 +}
  49.170 +
  49.171 +/** 
  49.172 + * Creates a new instance of GMythURI.
  49.173 + * 
  49.174 + * @param uri_str The URI string representing this URI instance.
  49.175 + * 
  49.176 + * @return a new instance of GMythURI.
  49.177 + */
  49.178 +GMythURI       *
  49.179 +gmyth_uri_new_with_value(const gchar * uri_str)
  49.180 +{
  49.181 +    GMythURI       *gmyth_uri =
  49.182 +        GMYTH_URI(g_object_new(GMYTH_URI_TYPE, NULL));
  49.183 +
  49.184 +    gmyth_uri_parser_setup_and_new(gmyth_uri, uri_str);
  49.185 +
  49.186 +    return gmyth_uri;
  49.187 +}
  49.188 +
  49.189 +/** 
  49.190 + * Gets the starting offset of a substring inside a given string.
  49.191 + * 
  49.192 + * @param haystack The given string to be searched for patterns.
  49.193 + * @param needle The substring that should be matched over the haystack.
  49.194 + * 
  49.195 + * @return The starting offset to the given substring, or <code>-1</code> if the
  49.196 + * 				 haystack function parameter doesn't contains the needle string argument.
  49.197 + */
  49.198 +static          gint
  49.199 +gmyth_strstr(const gchar * haystack, const gchar * needle)
  49.200 +{
  49.201 +
  49.202 +    gchar          *strPos;
  49.203 +
  49.204 +    if (haystack == NULL || needle == NULL)
  49.205 +        return -1;
  49.206 +    strPos = strstr(haystack, needle);
  49.207 +    if (strPos == NULL)
  49.208 +        return -1;
  49.209 +
  49.210 +    return (strPos - haystack);
  49.211 +
  49.212 +}
  49.213 +
  49.214 +/** 
  49.215 + * Checks if a URI is absolute.
  49.216 + * 
  49.217 + * @param uri The GMythURI instance.
  49.218 + * 
  49.219 + * @return <code>true</code>, if the URI is absolute.
  49.220 + */
  49.221 +static          gboolean
  49.222 +gmyth_uri_isabsolute(const GMythURI * uri)
  49.223 +{
  49.224 +    gboolean        ret = FALSE;
  49.225 +
  49.226 +    g_return_val_if_fail(uri != NULL && uri->uri != NULL
  49.227 +                         && uri->protocol != NULL, FALSE);
  49.228 +
  49.229 +    if (gmyth_strstr(uri->uri->str, GMYTH_URI_PROTOCOL_DELIM) == 0
  49.230 +        || strlen(uri->protocol->str) > 0)
  49.231 +        ret = TRUE;
  49.232 +
  49.233 +    return ret;
  49.234 +}
  49.235 +
  49.236 +/** 
  49.237 + * Searches for the first reverse character occurrence, from a given 
  49.238 + * list of characters, inside a given string.
  49.239 + * 
  49.240 + * @param str The given string to be searched for characters occurrence.
  49.241 + * @param chars The characters list. If this string returns 4 on strlen, there are
  49.242 + * 						  four possible characters to be matched.
  49.243 + * @param nchars The number of characters to be matched, which has at most 
  49.244 + * 							 strlen(chars).
  49.245 + * 
  49.246 + * @return The starting offset to the first character occurrence, 
  49.247 + *         or <code>-1</code> if the no character of the list could be found.
  49.248 + */
  49.249 +static          gint
  49.250 +gmyth_strrchr(const gchar * str, const gchar * chars, const gint nchars)
  49.251 +{
  49.252 +
  49.253 +    gint            strLen;
  49.254 +    gint            i,
  49.255 +                    j;
  49.256 +
  49.257 +    if (str == NULL || chars == NULL)
  49.258 +        return -1;
  49.259 +
  49.260 +    strLen = strlen(str);
  49.261 +    for (i = (strLen - 1); 0 <= i; i--) {
  49.262 +        for (j = 0; j < nchars; j++) {
  49.263 +            if (str[i] == chars[j])
  49.264 +                return i;
  49.265 +        }
  49.266 +    }
  49.267 +
  49.268 +    return -1;
  49.269 +
  49.270 +}
  49.271 +
  49.272 +static gchar   *
  49.273 +gmyth_uri_print_field(const GString * field)
  49.274 +{
  49.275 +    if (field != NULL && field->str != NULL && strlen(field->str) > 0)
  49.276 +        return field->str;
  49.277 +    else
  49.278 +        return "";
  49.279 +}
  49.280 +
  49.281 +static gint
  49.282 +gmyth_uri_get_default_port (GMythURI * uri)
  49.283 +{
  49.284 +    const gchar  *protocol = gmyth_uri_get_protocol(uri);
  49.285 +
  49.286 +    if (strcmp(protocol, GMYTH_URI_PROTOCOL_HTTP) == 0)
  49.287 +        return GMYTH_URI_DEFAULT_HTTP_PORT;
  49.288 +    if (strcmp(protocol, GMYTH_URI_PROTOCOL_FTP) == 0)
  49.289 +        return GMYTH_URI_DEFAULT_FTP_PORT;
  49.290 +    if (strcmp(protocol, GMYTH_URI_PROTOCOL_MYTH) == 0)
  49.291 +        return GMYTH_URI_DEFAULT_MYTH_PORT;
  49.292 +
  49.293 +    return GMYTH_URI_KNKOWN_PORT;
  49.294 +}
  49.295 +
  49.296 +/** 
  49.297 + * Parses a URI string into a GMythURI instance.
  49.298 + * 
  49.299 + * @param uri The GMythURI instance.
  49.300 + * @param value The URI string to be parsed.
  49.301 + *
  49.302 + */
  49.303 +static void
  49.304 +gmyth_uri_parser_setup_and_new(GMythURI * uri, const gchar * value)
  49.305 +{
  49.306 +
  49.307 +    gint            uriLen;
  49.308 +    gint            currIdx;
  49.309 +    gint            protoIdx;
  49.310 +    gint            atIdx;
  49.311 +    gint            colonIdx;
  49.312 +    gint            shashIdx;
  49.313 +    gint            eIdx;
  49.314 +    gchar          *host;
  49.315 +    gint            eblacketIdx;
  49.316 +    gint            hostLen;
  49.317 +    gint            sharpIdx;
  49.318 +
  49.319 +    /*
  49.320 +     * gint questionIdx; gint queryLen; 
  49.321 +     */
  49.322 +
  49.323 +    uriLen = strlen(value);
  49.324 +    uri->uri = g_string_new(value);
  49.325 +
  49.326 +    currIdx = 0;
  49.327 +
  49.328 +    /*** Protocol ****/
  49.329 +    protoIdx = gmyth_strstr(value, GMYTH_URI_PROTOCOL_DELIM);
  49.330 +    if (0 < protoIdx) {
  49.331 +        uri->protocol = g_string_new_len(value, protoIdx);
  49.332 +        currIdx += protoIdx + strlen(GMYTH_URI_PROTOCOL_DELIM);
  49.333 +    }
  49.334 +
  49.335 +    /*** User (Password) ****/
  49.336 +    atIdx = gmyth_strstr(value + currIdx, GMYTH_URI_USER_DELIM);
  49.337 +    if (0 < atIdx) {
  49.338 +        colonIdx = gmyth_strstr(value + currIdx, GMYTH_URI_COLON_DELIM);
  49.339 +
  49.340 +        if (0 < colonIdx && colonIdx < atIdx) {
  49.341 +            uri->user = g_string_new_len(value + currIdx, colonIdx);
  49.342 +            uri->password =
  49.343 +                g_string_new_len(value + currIdx + colonIdx + 1,
  49.344 +                                 atIdx - (colonIdx + 1));
  49.345 +        } else
  49.346 +            uri->user = g_string_new_len(value + currIdx, atIdx - currIdx);
  49.347 +        currIdx += atIdx + 1;
  49.348 +    }
  49.349 +
  49.350 +    /*** Host (Port) ****/
  49.351 +    shashIdx = gmyth_strstr(value + currIdx, GMYTH_URI_SLASH_DELIM);
  49.352 +    if (0 < shashIdx)
  49.353 +        uri->host = g_string_new_len(value + currIdx, shashIdx);
  49.354 +    else if (gmyth_uri_isabsolute(uri) == TRUE)
  49.355 +        uri->host =
  49.356 +            g_string_new_len(value + currIdx, strlen(value) - currIdx);
  49.357 +
  49.358 +    host = gmyth_uri_get_host(uri);
  49.359 +    colonIdx = gmyth_strrchr(host, GMYTH_URI_COLON_DELIM, 1);
  49.360 +    eblacketIdx = gmyth_strrchr(host, GMYTH_URI_EBLACET_DELIM, 1);
  49.361 +    if ((0 < colonIdx) && (eblacketIdx < colonIdx)) {
  49.362 +        GString        *portStr = NULL;
  49.363 +        GString        *hostStr = g_string_new(host != NULL ? host : "");
  49.364 +
  49.365 +        hostLen = hostStr->len;
  49.366 +        /**** host ****/
  49.367 +        uri->host = g_string_erase(uri->host, 0, hostLen);
  49.368 +        uri->host =
  49.369 +            g_string_insert_len(uri->host, 0, hostStr->str, colonIdx);
  49.370 +        if (0 < hostLen) {
  49.371 +            if (host[0] == '[' && host[hostLen - 1] == ']')
  49.372 +                uri->host =
  49.373 +                    g_string_new_len(hostStr->str + 1, colonIdx - 2);
  49.374 +        }
  49.375 +
  49.376 +        /**** port ****/
  49.377 +        portStr = g_string_new_len(hostStr->str + colonIdx + 1,
  49.378 +                                   hostLen - colonIdx - 1);
  49.379 +        uri->port = (gint) g_ascii_strtoull(portStr->str, NULL, 10);
  49.380 +        g_string_free(portStr, TRUE);
  49.381 +        g_string_free(hostStr, TRUE);
  49.382 +    } else {
  49.383 +        uri->port = gmyth_uri_get_default_port (uri);
  49.384 +    }
  49.385 +
  49.386 +    if (shashIdx > 0)
  49.387 +        currIdx += shashIdx;
  49.388 +
  49.389 +    /*
  49.390 +     * Handle relative URL 
  49.391 +     */
  49.392 +    if (gmyth_uri_isabsolute(uri) == FALSE) {
  49.393 +
  49.394 +        if (shashIdx != 0) {
  49.395 +            /*
  49.396 +             * Add slash delimiter at the beginning of the URL, if it
  49.397 +             * doesn't exist 
  49.398 +             */
  49.399 +            uri->path = g_string_new(GMYTH_URI_SLASH_DELIM);
  49.400 +        }
  49.401 +        uri->path = g_string_append(uri->path, value);
  49.402 +
  49.403 +    } else {
  49.404 +        /*
  49.405 +         * First set path simply to the rest of URI 
  49.406 +         */
  49.407 +        uri->path = g_string_new_len(value + currIdx, uriLen - currIdx);
  49.408 +    }
  49.409 +
  49.410 +    // gmyth_debug( "uri value: %s", value );
  49.411 +    uri->query =
  49.412 +        g_string_new(g_strstr_len
  49.413 +                     (value, strlen(value), GMYTH_URI_QUESTION_DELIM));
  49.414 +
  49.415 +    eIdx = gmyth_strstr(value + currIdx, GMYTH_URI_QUESTION_DELIM);
  49.416 +
  49.417 +    if (0 < eIdx) {
  49.418 +        uri->query =
  49.419 +            g_string_new(g_strstr_len
  49.420 +                         (value, strlen(value), GMYTH_URI_QUESTION_DELIM));
  49.421 +        gmyth_debug("query = %s", uri->query->str);
  49.422 +    }
  49.423 +
  49.424 +    /**** Path (Query/Fragment) ****/
  49.425 +    sharpIdx = gmyth_strstr(value + currIdx, GMYTH_URI_E_DELIM);
  49.426 +    if (0 < sharpIdx) {
  49.427 +        uri->path =
  49.428 +            g_string_append_len(uri->path, value + currIdx, sharpIdx);
  49.429 +        uri->fragment =
  49.430 +            g_string_new_len(value + currIdx + sharpIdx + 1,
  49.431 +                             uriLen - (currIdx + sharpIdx + 1));
  49.432 +    }
  49.433 +
  49.434 +    gmyth_debug
  49.435 +        ("[%s] GMythURI: host = %s, port = %d, path = %s, query = %s, fragment = %s, "
  49.436 +         "user = %s, password = %s.\n", __FUNCTION__,
  49.437 +         gmyth_uri_print_field(uri->host), uri->port,
  49.438 +         gmyth_uri_print_field(uri->path),
  49.439 +         gmyth_uri_print_field(uri->query),
  49.440 +         gmyth_uri_print_field(uri->fragment),
  49.441 +         gmyth_uri_print_field(uri->user),
  49.442 +         gmyth_uri_print_field(uri->password));
  49.443 +
  49.444 +}
  49.445 +
  49.446 +/** 
  49.447 + * Compares 2 URI instances, and checks them for equality.
  49.448 + * 
  49.449 + * @param uri The first GMythURI instance for comparison.
  49.450 + * @param uri The second GMythURI instance for comparison.
  49.451 + * 
  49.452 + * @return <code>true</code>, if these two URI instances are equals.
  49.453 + */
  49.454 +gboolean
  49.455 +gmyth_uri_is_equals(GMythURI * uri1, GMythURI * uri2)
  49.456 +{
  49.457 +    return (g_ascii_strcasecmp
  49.458 +            (gmyth_uri_get_host(uri1), gmyth_uri_get_host(uri2)) == 0
  49.459 +            && gmyth_uri_get_port(uri1) == gmyth_uri_get_port(uri2));
  49.460 +}
  49.461 +
  49.462 +/** 
  49.463 + * Checks if the URI instance represents a LiveTV recording.
  49.464 + * 
  49.465 + * @param uri The GMythURI instance.
  49.466 + * 
  49.467 + * @return <code>true</code>, if the URI points to LiveTV content.
  49.468 + */
  49.469 +gboolean
  49.470 +gmyth_uri_is_livetv(GMythURI * uri)
  49.471 +{
  49.472 +    gboolean        ret = TRUE;
  49.473 +
  49.474 +    g_return_val_if_fail(uri != NULL, FALSE);
  49.475 +    g_return_val_if_fail(uri->uri != NULL, FALSE);
  49.476 +    g_return_val_if_fail(uri->uri->str != NULL, FALSE);
  49.477 +
  49.478 +    if ((strstr(uri->uri->str, "channel=") == NULL) &&
  49.479 +        (strstr(uri->uri->str, "livetv") == NULL))
  49.480 +        ret = FALSE;
  49.481 +
  49.482 +    if (ret)
  49.483 +        gmyth_debug("This URI is a LiveTV recording...");
  49.484 +    else
  49.485 +        gmyth_debug("This URI is a stored remote recording.");
  49.486 +
  49.487 +    return ret;
  49.488 +
  49.489 +}
  49.490 +
  49.491 +/** 
  49.492 + * Gets the channel name fro a URI instance.
  49.493 + * 
  49.494 + * @param uri The GMythURI instance.
  49.495 + * 
  49.496 + * @return The channel name, got from the substring "?channel=[channel_name]"
  49.497 + * 				 of the URI string.
  49.498 + */
  49.499 +gchar          *
  49.500 +gmyth_uri_get_channel_name(GMythURI * uri)
  49.501 +{
  49.502 +    gchar          *channel = NULL;
  49.503 +
  49.504 +    g_return_val_if_fail(uri != NULL && uri->uri != NULL
  49.505 +                         && uri->uri->str != NULL, FALSE);
  49.506 +
  49.507 +    gchar          *channel_query = g_strstr_len(gmyth_uri_get_query(uri),
  49.508 +                                                 strlen(gmyth_uri_get_query
  49.509 +                                                        (uri)),
  49.510 +                                                 "channel");
  49.511 +
  49.512 +    if (channel_query != NULL) {
  49.513 +        gchar         **chan_key_value =
  49.514 +            g_strsplit(gmyth_uri_get_query(uri), "=", 2);
  49.515 +
  49.516 +        /*
  49.517 +         * gmyth_debug( "Channel tuple is [ %s, %s ]", chan_key_value[0],
  49.518 +         * chan_key_value[1] ); 
  49.519 +         */
  49.520 +
  49.521 +        if (chan_key_value[1] != NULL && strlen(chan_key_value[1]) > 0) {
  49.522 +            channel = g_strdup(chan_key_value[1]);
  49.523 +        }
  49.524 +
  49.525 +        if (chan_key_value != NULL)
  49.526 +            g_strfreev(chan_key_value);
  49.527 +    }
  49.528 +
  49.529 +    gmyth_debug("Got channel decimal value from the URI: %s", channel);
  49.530 +
  49.531 +    return channel;
  49.532 +
  49.533 +}
  49.534 +
  49.535 +/** 
  49.536 + * Gets the channel number from a URI instance.
  49.537 + * 
  49.538 + * @param uri The GMythURI instance.
  49.539 + * 
  49.540 + * @return The channel number, got from the substring "?channel=[channel_number]"
  49.541 + * 				 of the URI string, or <code>-1</code> it if couldn't be converted.
  49.542 + */
  49.543 +gint
  49.544 +gmyth_uri_get_channel_num(GMythURI * uri)
  49.545 +{
  49.546 +    gchar          *channel_name = gmyth_uri_get_channel_name(uri);
  49.547 +
  49.548 +    if (channel_name != NULL) {
  49.549 +        return g_ascii_strtoull(channel_name, NULL, 10);
  49.550 +    }
  49.551 +
  49.552 +    return -1;
  49.553 +
  49.554 +}
  49.555 +
  49.556 +/** 
  49.557 + * Checks if the URI instance represents a reference to a local file.
  49.558 + * 
  49.559 + * @param uri The GMythURI instance.
  49.560 + * 
  49.561 + * @return <code>true</code>, if the URI points to a local file.
  49.562 + */
  49.563 +gboolean
  49.564 +gmyth_uri_is_local_file(const GMythURI * uri)
  49.565 +{
  49.566 +    gboolean        ret = FALSE;
  49.567 +    gint            len = -1;
  49.568 +
  49.569 +    GString        *hostname = gmyth_socket_get_local_hostname();
  49.570 +
  49.571 +    g_return_val_if_fail(uri != NULL, FALSE);
  49.572 +
  49.573 +    len = strlen(gmyth_uri_get_host(uri));
  49.574 +
  49.575 +    // gmyth_debug("URI: host = %s, hostname = %s.", uri->host->str,
  49.576 +    // hostname != NULL ? hostname->str : "[no hostname]");
  49.577 +
  49.578 +    ret = (NULL != hostname && (g_ascii_strncasecmp(uri->host->str, (hostname)->str, len) == 0) /* || 
  49.579 +                                                                                                 * ( 
  49.580 +                                                                                                 * g_ascii_strncasecmp( 
  49.581 +                                                                                                 * gmyth_uri_get_host(uri), 
  49.582 +                                                                                                 * gmyth_socket_get_primary_addr(), 
  49.583 +                                                                                                 * len 
  49.584 +                                                                                                 * ) 
  49.585 +                                                                                                 * == 
  49.586 +                                                                                                 * 0 
  49.587 +                                                                                                 * ) 
  49.588 +                                                                                                 */
  49.589 +        );
  49.590 +
  49.591 +    if (ret)
  49.592 +        gmyth_debug("This URI is a local file...");
  49.593 +    else
  49.594 +        gmyth_debug("This URI is NOT a local file...");
  49.595 +
  49.596 +    return ret;
  49.597 +
  49.598 +}
  49.599 +
  49.600 +char           *
  49.601 +gmyth_uri_to_string(const GMythURI * uri)
  49.602 +{
  49.603 +    g_return_val_if_fail(uri != NULL, NULL);
  49.604 +    g_return_val_if_fail(uri->uri != NULL, NULL);
  49.605 +
  49.606 +    return g_strdup(uri->uri->str);
  49.607 +}
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/gmyth/gmyth/gmyth_uri.h	Mon Feb 25 17:51:43 2008 +0000
    50.3 @@ -0,0 +1,101 @@
    50.4 +/**
    50.5 + * GMyth Library
    50.6 + *
    50.7 + * @file gmyth/gmyth_uri.h
    50.8 + * 
    50.9 + * @brief <p> GMythURI utils
   50.10 + *  - Extracts and parses a URI char string, in according with the RFC 2396 
   50.11 + *    [http://www.ietf.org/rfc/rfc2396.txt]
   50.12 + * 
   50.13 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   50.14 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
   50.15 + *
   50.16 + * 
   50.17 + * This program is free software; you can redistribute it and/or modify
   50.18 + * it under the terms of the GNU Lesser General Public License as published by
   50.19 + * the Free Software Foundation; either version 2 of the License, or
   50.20 + * (at your option) any later version.
   50.21 + *
   50.22 + * This program is distributed in the hope that it will be useful,
   50.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   50.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   50.25 + * GNU General Public License for more details.
   50.26 + *
   50.27 + * You should have received a copy of the GNU Lesser General Public License
   50.28 + * along with this program; if not, write to the Free Software
   50.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   50.30 + */
   50.31 +
   50.32 +#ifndef _GMYTH_URI_H_
   50.33 +#define _GMYTH_URI_H_
   50.34 +
   50.35 +#include <glib.h>
   50.36 +#include <glib-object.h>
   50.37 +
   50.38 +#include <stdlib.h>
   50.39 +#include <stdio.h>
   50.40 +#include <string.h>
   50.41 +
   50.42 +G_BEGIN_DECLS
   50.43 +#define GMYTH_URI_TYPE               (gmyth_uri_get_type ())
   50.44 +#define GMYTH_URI(obj)          		 (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_URI_TYPE, GMythURI))
   50.45 +#define GMYTH_URI_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_URI_TYPE, GMythURIClass))
   50.46 +#define IS_GMYTH_URI(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_URI_TYPE))
   50.47 +#define IS_GMYTH_URI_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_URI_TYPE))
   50.48 +#define GMYTH_URI_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_URI_TYPE, GMythURIClass))
   50.49 +typedef struct _GMythURI GMythURI;
   50.50 +typedef struct _GMythURIClass GMythURIClass;
   50.51 +
   50.52 +
   50.53 +    /****************************************
   50.54 +	 * Data Type
   50.55 +	 ****************************************/
   50.56 +
   50.57 +struct _GMythURIClass {
   50.58 +    GObjectClass    parent_class;
   50.59 +
   50.60 +    /*
   50.61 +     * callbacks 
   50.62 +     */
   50.63 +    /*
   50.64 +     * no one for now 
   50.65 +     */
   50.66 +};
   50.67 +
   50.68 +struct _GMythURI {
   50.69 +
   50.70 +    GObject         parent;
   50.71 +
   50.72 +    GString        *uri;
   50.73 +    GString        *host;
   50.74 +    gint            port;
   50.75 +    GString        *protocol;
   50.76 +    GString        *path;
   50.77 +    GString        *fragment;
   50.78 +    GString        *user;
   50.79 +    GString        *password;
   50.80 +    GString        *query;
   50.81 +
   50.82 +};
   50.83 +
   50.84 +GType           gmyth_uri_get_type(void);
   50.85 +GMythURI       *gmyth_uri_new(void);
   50.86 +GMythURI       *gmyth_uri_new_with_value(const gchar * value);
   50.87 +gboolean        gmyth_uri_is_equals(GMythURI * uri1, GMythURI * uri2);
   50.88 +gboolean        gmyth_uri_is_livetv(GMythURI * uri);
   50.89 +gint            gmyth_uri_get_channel_num(GMythURI * uri);
   50.90 +gchar          *gmyth_uri_get_channel_name(GMythURI * uri);
   50.91 +char           *gmyth_uri_to_string(const GMythURI * uri);
   50.92 +gboolean        gmyth_uri_is_local_file(const GMythURI * uri);
   50.93 +
   50.94 +#define 	gmyth_uri_get_host(urip) 			( urip->host != NULL ? urip->host->str : "" )
   50.95 +#define 	gmyth_uri_get_port(urip) 			( urip->port )
   50.96 +#define 	gmyth_uri_get_protocol(urip) 	( urip->protocol != NULL ? urip->protocol->str : "" )
   50.97 +#define 	gmyth_uri_get_path(urip) 			( urip->path != NULL ? urip->path->str : "" )
   50.98 +#define 	gmyth_uri_get_user(urip) 			( urip->user != NULL ? urip->user->str : "" )
   50.99 +#define    	gmyth_uri_get_password(urip) 	( urip->password != NULL ? urip->password->str : "" )
  50.100 +#define 	gmyth_uri_get_fragment(urip) 	( urip->fragment != NULL ? urip->fragment->str : "" )
  50.101 +#define 	gmyth_uri_get_query(urip) 		( urip->query != NULL ? urip->query->str : "" )
  50.102 +
  50.103 +G_END_DECLS
  50.104 +#endif                          /* _GMYTH_URI_H_ */
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/gmyth/gmyth/gmyth_util.c	Mon Feb 25 17:51:43 2008 +0000
    51.3 @@ -0,0 +1,957 @@
    51.4 +/**
    51.5 + * GMyth Library
    51.6 + *
    51.7 + * @file gmyth/gmyth_util.c
    51.8 + * 
    51.9 + * @brief <p> This component provides utility functions 
   51.10 + * 	(dealing with dates, time, string formatting, etc.).
   51.11 + * 
   51.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   51.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   51.14 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
   51.15 + *
   51.16 + * 
   51.17 + * This program is free software; you can redistribute it and/or modify
   51.18 + * it under the terms of the GNU Lesser General Public License as published by
   51.19 + * the Free Software Foundation; either version 2 of the License, or
   51.20 + * (at your option) any later version.
   51.21 + *
   51.22 + * This program is distributed in the hope that it will be useful,
   51.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   51.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   51.25 + * GNU General Public License for more details.
   51.26 + *
   51.27 + * You should have received a copy of the GNU Lesser General Public License
   51.28 + * along with this program; if not, write to the Free Software
   51.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   51.30 + */
   51.31 +
   51.32 +#ifdef HAVE_CONFIG_H
   51.33 +#include "config.h"
   51.34 +#endif
   51.35 +
   51.36 +#define _XOPEN_SOURCE
   51.37 +#define _XOPEN_SOURCE_EXTENDED
   51.38 +#define __USE_MISC
   51.39 +
   51.40 +#include <glib.h>
   51.41 +#include <glib/gprintf.h>
   51.42 +#include <time.h>
   51.43 +#include <sys/time.h>
   51.44 +#include <sys/timex.h>
   51.45 +
   51.46 +#include "gmyth_socket.h"
   51.47 +#include "gmyth_recorder.h"
   51.48 +#include "gmyth_common.h"
   51.49 +#include "gmyth_debug.h"
   51.50 +
   51.51 +#include "gmyth_util.h"
   51.52 +
   51.53 +#if !GLIB_CHECK_VERSION (2, 10, 0)
   51.54 +gchar          *g_time_val_to_iso8601(GTimeVal * time_);
   51.55 +gboolean        g_time_val_from_iso8601(const gchar * iso_date,
   51.56 +                                        GTimeVal * time_);
   51.57 +void            g_date_set_time_val(GDate * date, GTimeVal * timeval);
   51.58 +
   51.59 +#endif
   51.60 +
   51.61 +/** Converts a time_t struct in a GString at ISO standard format 
   51.62 + * (e.g. 2006-07-20T09:56:41).
   51.63 + * 
   51.64 + * The returned GString memory should be deallocated from 
   51.65 + * the calling function.
   51.66 + *
   51.67 + * @param time_value the time value to be converted
   51.68 + * @return GString* the converted isoformat string 
   51.69 + */
   51.70 +GString        *
   51.71 +gmyth_util_time_to_isoformat(time_t time_value)
   51.72 +{
   51.73 +    struct tm       tm_time;
   51.74 +    GString        *result;
   51.75 +
   51.76 +    if (localtime_r(&time_value, &tm_time) == NULL) {
   51.77 +        gmyth_debug("gmyth_util_time_to_isoformat convertion error!\n");
   51.78 +        return NULL;
   51.79 +    }
   51.80 +
   51.81 +    result = g_string_sized_new(20);
   51.82 +    g_string_printf(result, "%04d-%02d-%02dT%02d:%02d:%02d",
   51.83 +                    tm_time.tm_year + 1900, tm_time.tm_mon + 1,
   51.84 +                    tm_time.tm_mday, tm_time.tm_hour, tm_time.tm_min,
   51.85 +                    tm_time.tm_sec);
   51.86 +
   51.87 +    gmyth_debug("Result (ISO 8601) = %s", result->str);
   51.88 +
   51.89 +    return result;
   51.90 +}
   51.91 +
   51.92 +/** Converts a time_t struct in a GString at ISO standard format 
   51.93 + * (e.g. 2006-07-20T09:56:41).
   51.94 + * 
   51.95 + * The returned GString memory should be deallocated from 
   51.96 + * the calling function.
   51.97 + *
   51.98 + * @param time_value the GTimeValue to be converted
   51.99 + * @return GString* the converted isoformat string 
  51.100 + */
  51.101 +gchar          *
  51.102 +gmyth_util_time_to_isoformat_from_time_val_fmt(const gchar * fmt_string,
  51.103 +                                               const GTimeVal * time_val)
  51.104 +{
  51.105 +    gchar          *result = NULL;
  51.106 +    struct tm      *tm_time = NULL;
  51.107 +    time_t          time;
  51.108 +
  51.109 +    gint            buffer_len = 0;
  51.110 +
  51.111 +    g_return_val_if_fail(fmt_string != NULL, NULL);
  51.112 +
  51.113 +    g_return_val_if_fail(time_val != NULL, NULL);
  51.114 +
  51.115 +    time = time_val->tv_sec;    // + (gint)( time_val->tv_usec /
  51.116 +    // G_USEC_PER_SEC );
  51.117 +
  51.118 +    tm_time = g_malloc0(sizeof(struct tm));
  51.119 +
  51.120 +    if (NULL == localtime_r(&time, tm_time)) {
  51.121 +        gmyth_debug("gmyth_util_time_to_isoformat convertion error!\n");
  51.122 +    } else {
  51.123 +        /*
  51.124 +         * we first check the return of strftime to allocate a buffer of
  51.125 +         * the correct size 
  51.126 +         */
  51.127 +        buffer_len = strftime(NULL, SSIZE_MAX, fmt_string, tm_time);
  51.128 +        if (buffer_len > 0) {
  51.129 +            result = g_malloc0(buffer_len + 1);
  51.130 +            if (result == NULL) {
  51.131 +                gmyth_debug
  51.132 +                    ("gmyth_util_time_to_isoformat convertion error!\n");
  51.133 +                return NULL;
  51.134 +            }
  51.135 +            strftime(result, buffer_len + 1, fmt_string, tm_time);
  51.136 +            gmyth_debug("Dateline (ISO result): %s", result);
  51.137 +        }
  51.138 +    }                           /* if */
  51.139 +
  51.140 +    gmyth_debug("Result (strftime) = %s", result);
  51.141 +
  51.142 +    // strptime( result, "%Y-%m-%dT%H:%M:%SZ", tm_time ); 
  51.143 +
  51.144 +    // strftime( result, strlen(result), fmt_string, tm_time );
  51.145 +
  51.146 +    g_free(tm_time);
  51.147 +
  51.148 +    gmyth_debug("Result (ISO 8601) = %s", result);
  51.149 +
  51.150 +    return result;
  51.151 +}
  51.152 +
  51.153 +/** Converts a time_t struct in a GString at ISO standard format 
  51.154 + * (e.g. 2006-07-20 09:56:41).
  51.155 + * 
  51.156 + * The returned GString memory should be deallocated from 
  51.157 + * the calling function.
  51.158 + *
  51.159 + * @param time_value the GTimeValue to be converted
  51.160 + * @return GString* the converted isoformat string 
  51.161 + */
  51.162 +gchar          *
  51.163 +gmyth_util_time_to_isoformat_from_time_val(const GTimeVal * time)
  51.164 +{
  51.165 +    gchar          *result =
  51.166 +        gmyth_util_time_to_isoformat_from_time_val_fmt("%Y-%m-%d %H:%M:%S",
  51.167 +                                                       time);
  51.168 +
  51.169 +    // result[10] = ' ';
  51.170 +    // result[ strlen(result) - 1] = '\0';
  51.171 +
  51.172 +    return result;
  51.173 +}
  51.174 +
  51.175 +/** Converts a time_t struct in a GString at ISO standard format 2 
  51.176 + * (e.g. 2006-07-20T09:56:41).
  51.177 + * 
  51.178 + * The returned GString memory should be deallocated from 
  51.179 + * the calling function.
  51.180 + *
  51.181 + * @param time_value the GTimeValue to be converted
  51.182 + * @return GString* the converted isoformat string 
  51.183 + */
  51.184 +gchar          *
  51.185 +gmyth_util_time_to_mythformat_from_time_val(const GTimeVal * time)
  51.186 +{
  51.187 +    gchar          *result =
  51.188 +        gmyth_util_time_to_isoformat_from_time_val_fmt("%Y-%m-%dT%H:%M:%S",
  51.189 +                                                       time);
  51.190 +
  51.191 +    return result;
  51.192 +}
  51.193 +
  51.194 +/** Converts a time_t struct in a GString at ISO standard format 
  51.195 + * (e.g. 2006-07-20T09:56:41).
  51.196 + * 
  51.197 + * The returned GString memory should be deallocated from 
  51.198 + * the calling function.
  51.199 + *
  51.200 + * @param time_value the GTimeValue to be converted
  51.201 + * @return GString* the converted isoformat string 
  51.202 + */
  51.203 +gchar          *
  51.204 +gmyth_util_time_to_string_only_date(const GTimeVal * time)
  51.205 +{
  51.206 +    gchar          *result =
  51.207 +        gmyth_util_time_to_isoformat_from_time_val_fmt("%Y-%m-%d", time);
  51.208 +    // result[10] = ' ';
  51.209 +    // result[ strlen(result) - 1] = '\0';
  51.210 +    return result;
  51.211 +}
  51.212 +
  51.213 +/** Converts a time_t struct in a GString at ISO standard format 
  51.214 + * (e.g. 2006-07-20T09:56:41).
  51.215 + * 
  51.216 + * The returned GString memory should be deallocated from 
  51.217 + * the calling function.
  51.218 + *
  51.219 + * @param time_value the GTimeValue to be converted
  51.220 + * @return GString* the converted isoformat string 
  51.221 + */
  51.222 +gchar          *
  51.223 +gmyth_util_time_to_string_only_time(const GTimeVal * time)
  51.224 +{
  51.225 +    gchar          *result =
  51.226 +        gmyth_util_time_to_isoformat_from_time_val_fmt("%H:%M:%S", time);
  51.227 +    // result[10] = ' ';
  51.228 +    // result[ strlen(result) - 1] = '\0';
  51.229 +    return result;
  51.230 +}
  51.231 +
  51.232 +/** Converts a time_t struct in a GString to the following 
  51.233 + * format (e.g. 2006-07-20 09:56:41).
  51.234 + * 
  51.235 + * The returned GString memory should be deallocated from 
  51.236 + * the calling function.
  51.237 + *
  51.238 + * @param time_value the time value to be converted
  51.239 + * @return GString* the converted string 
  51.240 + */
  51.241 +GString        *
  51.242 +gmyth_util_time_to_string(time_t time_value)
  51.243 +{
  51.244 +    GString        *result = gmyth_util_time_to_isoformat(time_value);
  51.245 +
  51.246 +    result->str[10] = ' ';
  51.247 +    result->str[strlen(result->str) - 1] = '\0';
  51.248 +
  51.249 +    return result;
  51.250 +}
  51.251 +
  51.252 +/** Converts a time_t struct in a GString to the following 
  51.253 + * format (e.g. 2006-07-20 09:56:41).
  51.254 + * 
  51.255 + * The returned GString memory should be deallocated from 
  51.256 + * the calling function.
  51.257 + *
  51.258 + * @param time_value the time value to be converted
  51.259 + * @return GString* the converted string 
  51.260 + */
  51.261 +gchar          *
  51.262 +gmyth_util_time_to_string_from_time_val(const GTimeVal * time_val)
  51.263 +{
  51.264 +    gchar          *result =
  51.265 +        gmyth_util_time_to_isoformat_from_time_val_fmt("%Y-%m-%d %H:%M:%S",
  51.266 +                                                       time_val);
  51.267 +
  51.268 +    // result[10] = ' ';
  51.269 +
  51.270 +    return result;
  51.271 +}
  51.272 +
  51.273 +/** Converts a GString in the following format 
  51.274 + * (e.g. 2006-07-20 09:56:41) to a time_t struct.
  51.275 + * 
  51.276 + * @param time_str the string to be converted
  51.277 + * @return time_t the time converted value
  51.278 + */
  51.279 +time_t
  51.280 +gmyth_util_string_to_time(GString * time_str)
  51.281 +{
  51.282 +    gint            year,
  51.283 +                    month,
  51.284 +                    day,
  51.285 +                    hour,
  51.286 +                    min,
  51.287 +                    sec;
  51.288 +
  51.289 +    gmyth_debug("[%s] time_str = %s. [%s]", __FUNCTION__,
  51.290 +                time_str !=
  51.291 +                NULL ? time_str->str : "[time string is NULL!]",
  51.292 +                time_str->str);
  51.293 +
  51.294 +    if (sscanf(time_str->str, "%04d-%02d-%02d %02d:%02d:%02d",
  51.295 +               &year, &month, &day, &hour, &min, &sec) < 3) {
  51.296 +        gmyth_debug("GMythUtil: isoformat_to_time converter error!\n");
  51.297 +        return 0;
  51.298 +    }
  51.299 +
  51.300 +    struct tm      *tm_time = g_malloc0(sizeof(struct tm));
  51.301 +
  51.302 +    tm_time->tm_year = year - 1900;
  51.303 +    tm_time->tm_mon = month - 1;
  51.304 +    tm_time->tm_mday = day;
  51.305 +    tm_time->tm_hour = hour;
  51.306 +    tm_time->tm_min = min;
  51.307 +    tm_time->tm_sec = sec;
  51.308 +
  51.309 +    return mktime(tm_time);
  51.310 +}
  51.311 +
  51.312 +/** Converts a GString in the following format 
  51.313 + * (e.g. 2006-07-20 09:56:41) to a time_t struct.
  51.314 + * 
  51.315 + * @param time_str the string to be converted
  51.316 + * @return time_t the time converted value
  51.317 + */
  51.318 +struct tm      *
  51.319 +gmyth_util_time_val_to_date(const GTimeVal * time)
  51.320 +{
  51.321 +    struct tm      *date = g_malloc0(sizeof(struct tm));
  51.322 +    time_t          time_micros = time->tv_sec; // + (gint)( time->tv_usec 
  51.323 +                                                // 
  51.324 +    // 
  51.325 +    // / G_USEC_PER_SEC );
  51.326 +
  51.327 +    if (NULL == date) {
  51.328 +        gmyth_debug
  51.329 +            ("GMythUtil: GDate *gmyth_util_time_val_to_date (GTimeVal* time) - converter error!\n");
  51.330 +        return NULL;
  51.331 +    }
  51.332 +
  51.333 +    if (NULL == localtime_r(&time_micros, date)) {
  51.334 +        gmyth_debug("gmyth_util_time_to_isoformat convertion error!\n");
  51.335 +        return NULL;
  51.336 +    }
  51.337 +
  51.338 +    gmyth_debug("Converted from GTimeVal == %s to GDate", asctime(date));
  51.339 +
  51.340 +    return date;
  51.341 +}
  51.342 +
  51.343 +/** Converts a GString in the following format 
  51.344 + * (e.g. 2006-07-20 09:56:41) to a time_t struct.
  51.345 + * 
  51.346 + * @param time_str the string to be converted
  51.347 + * @return time_t the time converted value
  51.348 + */
  51.349 +GTimeVal       *
  51.350 +gmyth_util_string_to_time_val_fmt(const gchar * fmt_string,
  51.351 +                                  const gchar * time_str)
  51.352 +{
  51.353 +    GTimeVal       *time = g_new0(GTimeVal, 1);
  51.354 +    struct tm      *tm_time = NULL;
  51.355 +    time_t          time_micros;
  51.356 +    gchar          *result;
  51.357 +
  51.358 +    gmyth_debug("[%s] time_str = %s. [%s]", time_str, time_str != NULL ?
  51.359 +                time_str : "[time string is NULL!]", time_str);
  51.360 +
  51.361 +    if (NULL == time_str) {
  51.362 +        gmyth_debug("GMythUtil: isoformat_to_time converter error!\n");
  51.363 +        return NULL;
  51.364 +    }
  51.365 +
  51.366 +    tm_time = g_malloc0(sizeof(struct tm));
  51.367 +
  51.368 +    /*
  51.369 +     * we first check the return of strftime to allocate a buffer of the
  51.370 +     * correct size 
  51.371 +     */
  51.372 +    result = strptime(time_str, "%Y-%m-%dT%H:%M:%S", tm_time);
  51.373 +    if (NULL == result) {
  51.374 +        /*
  51.375 +         * we first check the return of strftime to allocate a buffer of
  51.376 +         * the correct size 
  51.377 +         */
  51.378 +        result = strptime(time_str, "%Y-%m-%dT%H:%M:%SZ", tm_time);
  51.379 +        if (NULL == result) {
  51.380 +            /*
  51.381 +             * we first check the return of strftime to allocate a buffer
  51.382 +             * of the correct size 
  51.383 +             */
  51.384 +            result = strptime(time_str, "%Y-%m-%d %H:%M:%S", tm_time);
  51.385 +            if (NULL == result) {
  51.386 +                result = strptime(time_str, "%Y-%m-%dT%H:%M", tm_time);
  51.387 +                if (NULL == result) {
  51.388 +                    gmyth_debug("Dateline (ISO result): %s", result);
  51.389 +                    g_free(tm_time);
  51.390 +                    return NULL;
  51.391 +                    // goto done; 
  51.392 +                }
  51.393 +            }
  51.394 +        }
  51.395 +    }
  51.396 +
  51.397 +    time_micros = mktime(tm_time);
  51.398 +
  51.399 +    time->tv_sec = time_micros; // + (gint)( time_val->tv_usec /
  51.400 +    // G_USEC_PER_SEC );
  51.401 +
  51.402 +    gmyth_debug("After mktime call... = %s", asctime(tm_time));
  51.403 +
  51.404 +    g_free(tm_time);
  51.405 +
  51.406 +    return time;
  51.407 +}
  51.408 +
  51.409 +/** Converts a GString in the following format 
  51.410 + * (e.g. 2006-07-20 09:56:41) to a time_t struct.
  51.411 + * 
  51.412 + * @param time_str the string to be converted
  51.413 + * @return time_t the time converted value
  51.414 + */
  51.415 +GTimeVal       *
  51.416 +gmyth_util_string_to_time_val(const gchar * time_str)
  51.417 +{
  51.418 +    GTimeVal       *time =
  51.419 +        gmyth_util_string_to_time_val_fmt("%Y-%m-%d %H:%M:%S", time_str);
  51.420 +
  51.421 +    return time;
  51.422 +}
  51.423 +
  51.424 +/** 
  51.425 + * Checks if the given remote file exists.
  51.426 + * 
  51.427 + * @param backend_info The GMythBackendInfo instance.
  51.428 + * @param filename The file name of the remote file.
  51.429 + * 
  51.430 + * @return <code>true</code>, if the remote file exists.
  51.431 + */
  51.432 +gboolean
  51.433 +gmyth_util_file_exists(GMythBackendInfo * backend_info,
  51.434 +                       const gchar * filename)
  51.435 +{
  51.436 +    GMythSocket    *socket;
  51.437 +    gboolean        res = FALSE;
  51.438 +
  51.439 +    gmyth_debug("Check if file %s exists", filename);
  51.440 +
  51.441 +    g_return_val_if_fail(backend_info != NULL, FALSE);
  51.442 +    g_return_val_if_fail(filename != NULL, FALSE);
  51.443 +
  51.444 +    socket = gmyth_backend_info_get_connected_socket (backend_info);
  51.445 +    if (socket != NULL) {
  51.446 +        res = gmyth_util_file_exists_from_socket (socket, filename);
  51.447 +        g_object_unref(socket);
  51.448 +    }
  51.449 +    return res;
  51.450 +}
  51.451 +
  51.452 +gboolean
  51.453 +gmyth_util_file_exists_from_socket (GMythSocket *sock, 
  51.454 +                                    const gchar *filename)
  51.455 +{
  51.456 +    gboolean res = FALSE;
  51.457 +    gint length = 0;
  51.458 +    GMythStringList *slist;
  51.459 +    GMythProgramInfo *program = NULL;
  51.460 +
  51.461 +    program = gmyth_program_info_new();
  51.462 +    program->pathname = g_string_new(filename);
  51.463 +
  51.464 +    slist = gmyth_string_list_new();
  51.465 +    gmyth_string_list_append_char_array(slist, "QUERY_CHECKFILE");
  51.466 +    gmyth_program_info_to_string_list(program, slist);
  51.467 +
  51.468 +    length = gmyth_socket_sendreceive_stringlist (sock, slist);
  51.469 +    if (length > 0)
  51.470 +        res = (gmyth_string_list_get_int(slist, 0) == 1);
  51.471 +
  51.472 +    g_object_unref(program);
  51.473 +    g_object_unref(slist);
  51.474 +
  51.475 +    return res;
  51.476 +}
  51.477 + 
  51.478 +gboolean
  51.479 +gmyth_util_get_backend_details (GMythSocket *sock, GMythBackendDetails **details)
  51.480 +{
  51.481 +    gboolean res = FALSE;
  51.482 +    gint length = 0;
  51.483 +    GMythStringList *slist;
  51.484 +
  51.485 +    slist = gmyth_string_list_new();
  51.486 +    gmyth_string_list_append_char_array(slist, "QUERY_FREE_SPACE");
  51.487 +
  51.488 +    length = gmyth_socket_sendreceive_stringlist (sock, slist);
  51.489 +    if (length >= 8) {
  51.490 +        *details = g_new0 (GMythBackendDetails, 1);
  51.491 +        (*details)->total_space = gmyth_string_list_get_uint64 (slist, 4) * 1024;
  51.492 +        (*details)->used_space = gmyth_string_list_get_uint64 (slist, 6) * 1024;
  51.493 +        res = TRUE;
  51.494 +    }
  51.495 +
  51.496 +    g_object_unref(slist);
  51.497 +
  51.498 +    return res;
  51.499 +}
  51.500 +
  51.501 +void
  51.502 +gmyth_util_backend_details_free (GMythBackendDetails *details)
  51.503 +{
  51.504 +    g_free (details);
  51.505 +}
  51.506 +                     
  51.507 +
  51.508 +/** 
  51.509 + * Checks if the given remote file exists, and gets its remote directory.
  51.510 + * 
  51.511 + * @param backend_info The GMythBackendInfo instance.
  51.512 + * @param filename The file name of the remote file.
  51.513 + * @param current_dir String pointer to the directory where the remote file is stored.
  51.514 + * 
  51.515 + * @return <code>true</code>, if the remote file exists.
  51.516 + */
  51.517 +gboolean
  51.518 +gmyth_util_file_exists_and_get_remote_dir(GMythBackendInfo * backend_info,
  51.519 +                                          const gchar * filename,
  51.520 +                                          gchar ** current_dir)
  51.521 +{
  51.522 +    GMythSocket    *socket;
  51.523 +    gboolean        res;
  51.524 +
  51.525 +    *current_dir = NULL;
  51.526 +
  51.527 +    socket = gmyth_socket_new();
  51.528 +    res = gmyth_socket_connect_to_backend(socket, backend_info->hostname,
  51.529 +                                          backend_info->port, TRUE);
  51.530 +
  51.531 +    if (res == TRUE) {
  51.532 +        GMythStringList *slist;
  51.533 +        GMythProgramInfo *program = NULL;
  51.534 +
  51.535 +        program = gmyth_program_info_new();
  51.536 +        program->pathname = g_string_new(filename);
  51.537 +
  51.538 +        slist = gmyth_string_list_new();
  51.539 +        gmyth_string_list_append_char_array(slist, "QUERY_CHECKFILE");
  51.540 +
  51.541 +        gmyth_program_info_to_string_list(program, slist);
  51.542 +
  51.543 +        gmyth_socket_sendreceive_stringlist(socket, slist);
  51.544 +
  51.545 +        res = (gmyth_string_list_get_int(slist, 0) == 1);
  51.546 +
  51.547 +        if ((gmyth_string_list_length(slist) > 1) &&
  51.548 +            gmyth_string_list_get_char_array(slist, 1) != NULL)
  51.549 +            *current_dir =
  51.550 +                g_strdup(gmyth_string_list_get_char_array(slist, 1));
  51.551 +
  51.552 +        if (*current_dir != NULL)
  51.553 +            gmyth_debug("Current directory = %s.", (*current_dir != NULL)
  51.554 +                        ? *current_dir : "[directory not found]");
  51.555 +
  51.556 +        g_object_unref(program);
  51.557 +
  51.558 +        g_object_unref(slist);
  51.559 +
  51.560 +        gmyth_socket_close_connection(socket);
  51.561 +    }
  51.562 +    g_object_unref(socket);
  51.563 +    return res;
  51.564 +}
  51.565 +
  51.566 +/** 
  51.567 + * Creates a file name to a possible existing remote file,
  51.568 + * based on some fields of the LiveTV/recorded program info.
  51.569 + * 
  51.570 + * @param chan_id The channel ID number.
  51.571 + * @param start_time The start time of the recording.
  51.572 + * 
  51.573 + * @return The string representing the file name.
  51.574 + */
  51.575 +gchar          *
  51.576 +gmyth_util_create_filename(const gint chan_id, const GTimeVal * start_time)
  51.577 +{
  51.578 +    gchar          *basename = NULL;
  51.579 +
  51.580 +    g_return_val_if_fail(start_time != NULL, NULL);
  51.581 +
  51.582 +    gchar          *isodate =
  51.583 +        gmyth_util_time_to_isoformat_from_time_val_fmt("%Y%m%d%H%M%S",
  51.584 +                                                       start_time);
  51.585 +
  51.586 +    basename = g_strdup_printf("%d_%s", chan_id, isodate);
  51.587 +
  51.588 +    gmyth_debug("Basename (from chan_id and start_time): %s", basename);
  51.589 +
  51.590 +    if (isodate)
  51.591 +        g_free(isodate);
  51.592 +
  51.593 +    return basename;
  51.594 +}
  51.595 +
  51.596 +/** 
  51.597 + * Gets the channel list.
  51.598 + * 
  51.599 + * @param backend_info The GMythBackendInfo instance.
  51.600 + * 
  51.601 + * @return a pointer to a GList with all the channels.
  51.602 + */
  51.603 +GList          *
  51.604 +gmyth_util_get_channel_list(GMythBackendInfo * backend_info)
  51.605 +{
  51.606 +    GMythRecorder  *recorder;
  51.607 +    GList          *channel_list = NULL;
  51.608 +    gboolean        res = FALSE;
  51.609 +
  51.610 +    gmyth_debug("Gets channel list.");
  51.611 +
  51.612 +    g_return_val_if_fail(backend_info != NULL, FALSE);
  51.613 +
  51.614 +    recorder =
  51.615 +        gmyth_recorder_new(1,
  51.616 +                           g_string_new(gmyth_backend_info_get_hostname
  51.617 +                                        (backend_info)),
  51.618 +                           gmyth_backend_info_get_port(backend_info));
  51.619 +    res = gmyth_recorder_setup(recorder);
  51.620 +
  51.621 +    if (res == TRUE) {
  51.622 +        // GList* channel_list = gmyth_recorder_get_channel_list( recorder 
  51.623 +        // 
  51.624 +        // 
  51.625 +        // ); 
  51.626 +        gmyth_debug("Yeah, got channel list!!!");
  51.627 +        GList          *ch = NULL;
  51.628 +        GMythChannelInfo *channel_info = NULL;
  51.629 +
  51.630 +        for (ch = gmyth_recorder_get_channel_list(recorder); ch != NULL;) {
  51.631 +            channel_info = g_malloc0(sizeof(GMythChannelInfo));
  51.632 +            channel_info->channel_ID = 0;
  51.633 +            channel_info->channel_num =
  51.634 +                g_string_new(g_strdup((gchar *) ch->data));
  51.635 +            channel_info->channel_name = g_string_new("");
  51.636 +            gmyth_debug("Printing channel info... (%s)",
  51.637 +                        channel_info->channel_num->str);
  51.638 +            channel_list =
  51.639 +                g_list_append(channel_list,
  51.640 +                              g_memdup(channel_info,
  51.641 +                                       sizeof(GMythChannelInfo)));
  51.642 +
  51.643 +            ch = g_list_next(ch);
  51.644 +
  51.645 +            if (channel_info != NULL)
  51.646 +                g_free(channel_info);
  51.647 +        }
  51.648 +
  51.649 +    } /* if */
  51.650 +    else {
  51.651 +        gmyth_debug("No, couldn't get the channel list!!!");
  51.652 +    }
  51.653 +
  51.654 +    gmyth_debug("Got %d channels!!!", g_list_length(channel_list));
  51.655 +
  51.656 +
  51.657 +    g_object_unref(recorder);
  51.658 +
  51.659 +    return channel_list;
  51.660 +}
  51.661 +
  51.662 +/** 
  51.663 + * Gets all the recordings from remote encoder.
  51.664 + * 
  51.665 + * @param backend_info The GMythBackendInfo instance.
  51.666 + * 
  51.667 + * @return The program info's listage.
  51.668 + */
  51.669 +GSList         *
  51.670 +gmyth_util_get_all_recordings(GMythBackendInfo * backend_info)
  51.671 +{
  51.672 +    GSList         *program_list = NULL;
  51.673 +    GMythSocket    *socket;
  51.674 +    gboolean        res;
  51.675 +
  51.676 +    socket = gmyth_socket_new();
  51.677 +    res = gmyth_socket_connect_to_backend(socket, backend_info->hostname,
  51.678 +                                          backend_info->port, TRUE);
  51.679 +
  51.680 +    if (res == TRUE) {
  51.681 +        GMythStringList *slist = gmyth_string_list_new();
  51.682 +        guint           pos = 0;
  51.683 +
  51.684 +        gmyth_string_list_append_char_array(slist,
  51.685 +                                            "QUERY_RECORDINGS Play");
  51.686 +
  51.687 +        gmyth_socket_sendreceive_stringlist(socket, slist);
  51.688 +
  51.689 +        if (slist != NULL && (gmyth_string_list_length(slist) > 0)) {
  51.690 +            GMythProgramInfo *program = NULL;
  51.691 +
  51.692 +            gmyth_debug("OK! Got the program list [size=%d].",
  51.693 +                        gmyth_string_list_length(slist));
  51.694 +
  51.695 +            do {
  51.696 +                program =
  51.697 +                    gmyth_program_info_from_string_list_from_pos(slist,
  51.698 +                                                                 pos);
  51.699 +
  51.700 +                if (program != NULL) {
  51.701 +                    pos += 41;
  51.702 +
  51.703 +                    program_list = g_slist_append(program_list, program);
  51.704 +                } else
  51.705 +                    break;
  51.706 +
  51.707 +            }
  51.708 +            while (gmyth_string_list_length(slist) > pos);
  51.709 +
  51.710 +        }
  51.711 +        /*
  51.712 +         * if 
  51.713 +         */
  51.714 +        g_object_unref(slist);
  51.715 +
  51.716 +        gmyth_socket_close_connection(socket);
  51.717 +    }
  51.718 +    g_object_unref(socket);
  51.719 +
  51.720 +    return program_list;
  51.721 +}
  51.722 +
  51.723 +/** 
  51.724 + * Checks if the given remote file exists, and gets its remote directory.
  51.725 + * 
  51.726 + * @param backend_info The GMythBackendInfo instance.
  51.727 + * @param channel The channel name of the program info.
  51.728 + * 
  51.729 + * @return The requested program info.
  51.730 + */
  51.731 +GMythProgramInfo *
  51.732 +gmyth_util_get_recording_from_channel(GMythBackendInfo * backend_info,
  51.733 +                                      const gchar * channel)
  51.734 +{
  51.735 +    GSList         *program_list = NULL;
  51.736 +    GMythProgramInfo *program = NULL;
  51.737 +
  51.738 +    program_list = gmyth_util_get_all_recordings(backend_info);
  51.739 +
  51.740 +    if (program_list != NULL && g_slist_length(program_list) > 0) {
  51.741 +        GMythProgramInfo *program = NULL;
  51.742 +        guint           pos = 0;
  51.743 +
  51.744 +        gmyth_debug("OK! Got the program list [size=%d].",
  51.745 +                    g_slist_length(program_list));
  51.746 +
  51.747 +        while (pos < g_slist_length(program_list)) {
  51.748 +            program =
  51.749 +                (GMythProgramInfo *) g_slist_nth_data(program_list, pos);
  51.750 +
  51.751 +            if (program != NULL && program->channame != NULL &&
  51.752 +                g_ascii_strncasecmp(program->channame->str, channel,
  51.753 +                                    strlen(channel)) == 0) {
  51.754 +                break;
  51.755 +            }
  51.756 +
  51.757 +            ++pos;
  51.758 +
  51.759 +        }                       /* while */
  51.760 +
  51.761 +    }
  51.762 +    /*
  51.763 +     * if 
  51.764 +     */
  51.765 +    return program;
  51.766 +}
  51.767 +
  51.768 +#if !GLIB_CHECK_VERSION (2, 10, 0)
  51.769 +
  51.770 +/*
  51.771 + * Hacked from glib 2.10 <gtime.c> 
  51.772 + */
  51.773 +
  51.774 +static          time_t
  51.775 +mktime_utc(struct tm *tm)
  51.776 +{
  51.777 +    time_t          retval;
  51.778 +
  51.779 +#ifndef HAVE_TIMEGM
  51.780 +    static const gint days_before[] = {
  51.781 +        0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
  51.782 +    };
  51.783 +#endif
  51.784 +
  51.785 +#ifndef HAVE_TIMEGM
  51.786 +    if (tm->tm_mon < 0 || tm->tm_mon > 11)
  51.787 +        return (time_t) - 1;
  51.788 +
  51.789 +    retval = (tm->tm_year - 70) * 365;
  51.790 +    retval += (tm->tm_year - 68) / 4;
  51.791 +    retval += days_before[tm->tm_mon] + tm->tm_mday - 1;
  51.792 +
  51.793 +    if (tm->tm_year % 4 == 0 && tm->tm_mon < 2)
  51.794 +        retval -= 1;
  51.795 +
  51.796 +    retval =
  51.797 +        ((((retval * 24) + tm->tm_hour) * 60) + tm->tm_min) * 60 +
  51.798 +        tm->tm_sec;
  51.799 +#else
  51.800 +    retval = timegm(tm);
  51.801 +#endif                          /* !HAVE_TIMEGM */
  51.802 +
  51.803 +    return retval;
  51.804 +}
  51.805 +
  51.806 +gboolean
  51.807 +g_time_val_from_iso8601(const gchar * iso_date, GTimeVal * time_)
  51.808 +{
  51.809 +    struct tm       tm;
  51.810 +    long            val;
  51.811 +
  51.812 +    g_return_val_if_fail(iso_date != NULL, FALSE);
  51.813 +    g_return_val_if_fail(time_ != NULL, FALSE);
  51.814 +
  51.815 +    val = strtoul(iso_date, (char **) &iso_date, 10);
  51.816 +    if (*iso_date == '-') {
  51.817 +        /*
  51.818 +         * YYYY-MM-DD 
  51.819 +         */
  51.820 +        tm.tm_year = val - 1900;
  51.821 +        iso_date++;
  51.822 +        tm.tm_mon = strtoul(iso_date, (char **) &iso_date, 10) - 1;
  51.823 +
  51.824 +        if (*iso_date++ != '-')
  51.825 +            return FALSE;
  51.826 +
  51.827 +        tm.tm_mday = strtoul(iso_date, (char **) &iso_date, 10);
  51.828 +    } else {
  51.829 +        /*
  51.830 +         * YYYYMMDD 
  51.831 +         */
  51.832 +        tm.tm_mday = val % 100;
  51.833 +        tm.tm_mon = (val % 10000) / 100 - 1;
  51.834 +        tm.tm_year = val / 10000 - 1900;
  51.835 +    }
  51.836 +
  51.837 +    if (*iso_date++ != 'T')
  51.838 +        return FALSE;
  51.839 +
  51.840 +    val = strtoul(iso_date, (char **) &iso_date, 10);
  51.841 +    if (*iso_date == ':') {
  51.842 +        /*
  51.843 +         * hh:mm:ss 
  51.844 +         */
  51.845 +        tm.tm_hour = val;
  51.846 +        iso_date++;
  51.847 +        tm.tm_min = strtoul(iso_date, (char **) &iso_date, 10);
  51.848 +
  51.849 +        if (*iso_date++ != ':')
  51.850 +            return FALSE;
  51.851 +
  51.852 +        tm.tm_sec = strtoul(iso_date, (char **) &iso_date, 10);
  51.853 +    } else {
  51.854 +        /*
  51.855 +         * hhmmss 
  51.856 +         */
  51.857 +        tm.tm_sec = val % 100;
  51.858 +        tm.tm_min = (val % 10000) / 100;
  51.859 +        tm.tm_hour = val / 10000;
  51.860 +    }
  51.861 +
  51.862 +    time_->tv_sec = mktime_utc(&tm);
  51.863 +    time_->tv_usec = 1;
  51.864 +
  51.865 +    if (*iso_date == '.')
  51.866 +        time_->tv_usec = strtoul(iso_date + 1, (char **) &iso_date, 10);
  51.867 +
  51.868 +    if (*iso_date == '+' || *iso_date == '-') {
  51.869 +        gint            sign = (*iso_date == '+') ? -1 : 1;
  51.870 +
  51.871 +        val = 60 * strtoul(iso_date + 1, (char **) &iso_date, 10);
  51.872 +
  51.873 +        if (*iso_date == ':')
  51.874 +            val = 60 * val + strtoul(iso_date + 1, NULL, 10);
  51.875 +        else
  51.876 +            val = 60 * (val / 100) + (val % 100);
  51.877 +
  51.878 +        time_->tv_sec += (time_t) (val * sign);
  51.879 +    }
  51.880 +
  51.881 +    return TRUE;
  51.882 +}
  51.883 +
  51.884 +
  51.885 +gchar          *
  51.886 +g_time_val_to_iso8601(GTimeVal * time_)
  51.887 +{
  51.888 +    gchar          *retval;
  51.889 +
  51.890 +    g_return_val_if_fail(time_->tv_usec >= 0
  51.891 +                         && time_->tv_usec < G_USEC_PER_SEC, NULL);
  51.892 +
  51.893 +#define ISO_8601_LEN    21
  51.894 +#define ISO_8601_FORMAT "%Y-%m-%dT%H:%M:%SZ"
  51.895 +    retval = g_new0(gchar, ISO_8601_LEN + 1);
  51.896 +
  51.897 +    strftime(retval, ISO_8601_LEN, ISO_8601_FORMAT,
  51.898 +             gmtime(&(time_->tv_sec)));
  51.899 +
  51.900 +    return retval;
  51.901 +}
  51.902 +
  51.903 +
  51.904 +/*
  51.905 + * Hacked from glib 2.10 <gdate.c> 
  51.906 + */
  51.907 +
  51.908 +void
  51.909 +g_date_set_time_t(GDate * date, time_t timet)
  51.910 +{
  51.911 +    struct tm       tm;
  51.912 +
  51.913 +    g_return_if_fail(date != NULL);
  51.914 +
  51.915 +#ifdef HAVE_LOCALTIME_R
  51.916 +    localtime_r(&timet, &tm);
  51.917 +#else
  51.918 +    {
  51.919 +        struct tm      *ptm = localtime(&timet);
  51.920 +
  51.921 +        if (ptm == NULL) {
  51.922 +            /*
  51.923 +             * Happens at least in Microsoft's C library if you pass a
  51.924 +             * negative time_t. Use 2000-01-01 as default date. 
  51.925 +             */
  51.926 +#ifndef G_DISABLE_CHECKS
  51.927 +            g_return_if_fail_warning(G_LOG_DOMAIN, "g_date_set_time",
  51.928 +                                     "ptm != NULL");
  51.929 +#endif
  51.930 +
  51.931 +            tm.tm_mon = 0;
  51.932 +            tm.tm_mday = 1;
  51.933 +            tm.tm_year = 100;
  51.934 +        } else
  51.935 +            memcpy((void *) &tm, (void *) ptm, sizeof(struct tm));
  51.936 +    }
  51.937 +#endif
  51.938 +
  51.939 +    date->julian = FALSE;
  51.940 +
  51.941 +    date->month = tm.tm_mon + 1;
  51.942 +    date->day = tm.tm_mday;
  51.943 +    date->year = tm.tm_year + 1900;
  51.944 +
  51.945 +    g_return_if_fail(g_date_valid_dmy(date->day, date->month, date->year));
  51.946 +
  51.947 +    date->dmy = TRUE;
  51.948 +}
  51.949 +
  51.950 +
  51.951 +void
  51.952 +g_date_set_time_val(GDate * date, GTimeVal * timeval)
  51.953 +{
  51.954 +    g_date_set_time_t(date, (time_t) timeval->tv_sec);
  51.955 +}
  51.956 +
  51.957 +
  51.958 +
  51.959 +
  51.960 +#endif
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/gmyth/gmyth/gmyth_util.h	Mon Feb 25 17:51:43 2008 +0000
    52.3 @@ -0,0 +1,82 @@
    52.4 +/**
    52.5 + * GMyth Library
    52.6 + *
    52.7 + * @file gmyth/gmyth_util.h
    52.8 + * 
    52.9 + * @brief <p> This component provides utility functions 
   52.10 + * 	(dealing with dates, time, string formatting, etc.).
   52.11 + * 
   52.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   52.13 + * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   52.14 + * @author Rosfran Borges <rosfran.borges@indt.org.br>
   52.15 + *
   52.16 + * 
   52.17 + * This program is free software; you can redistribute it and/or modify
   52.18 + * it under the terms of the GNU Lesser General Public License as published by
   52.19 + * the Free Software Foundation; either version 2 of the License, or
   52.20 + * (at your option) any later version.
   52.21 + *
   52.22 + * This program is distributed in the hope that it will be useful,
   52.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   52.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   52.25 + * GNU General Public License for more details.
   52.26 + *
   52.27 + * You should have received a copy of the GNU Lesser General Public License
   52.28 + * along with this program; if not, write to the Free Software
   52.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   52.30 + */
   52.31 +
   52.32 +#ifndef GMYTH_UTIL_H_
   52.33 +#define GMYTH_UTIL_H_
   52.34 +
   52.35 +#include <time.h>
   52.36 +#include <glib.h>
   52.37 +
   52.38 +#include "gmyth_stringlist.h"
   52.39 +#include "gmyth_backendinfo.h"
   52.40 +#include "gmyth_programinfo.h"
   52.41 +
   52.42 +G_BEGIN_DECLS 
   52.43 +
   52.44 +typedef struct {
   52.45 +    guint64 total_space;
   52.46 +    guint64 used_space;
   52.47 +} GMythBackendDetails;
   52.48 +
   52.49 +
   52.50 +GString*        gmyth_util_time_to_isoformat                (time_t time_value);
   52.51 +GString*        gmyth_util_time_to_string                   (time_t time_value);
   52.52 +time_t          gmyth_util_string_to_time                   (GString *time_str);
   52.53 +gchar*          gmyth_util_time_to_isoformat_from_time_val_fmt
   52.54 +                                                            (const gchar *fmt_string,
   52.55 +                                                             const GTimeVal *time_val);
   52.56 +GTimeVal*       gmyth_util_string_to_time_val_fmt           (const gchar *fmt_string,
   52.57 +                                                             const gchar *time_str);
   52.58 +GTimeVal*       gmyth_util_string_to_time_val               (const gchar *time_str);
   52.59 +gchar*          gmyth_util_time_to_isoformat_from_time_val  (const GTimeVal *time);
   52.60 +gchar*          gmyth_util_time_to_mythformat_from_time_val (const GTimeVal *time);
   52.61 +gchar*          gmyth_util_time_to_string_only_date         (const GTimeVal *time);
   52.62 +gchar*          gmyth_util_time_to_string_only_time         (const GTimeVal *time);
   52.63 +gchar*          gmyth_util_time_to_string_from_time_val     (const GTimeVal *time_val);
   52.64 +struct tm*      gmyth_util_time_val_to_date                 (const GTimeVal * time);
   52.65 +
   52.66 +gboolean        gmyth_util_get_backend_details (GMythSocket *sock, GMythBackendDetails **details);
   52.67 +void            gmyth_util_backend_details_free (GMythBackendDetails *details);
   52.68 +
   52.69 +gboolean        gmyth_util_file_exists                      (GMythBackendInfo *backend_info,
   52.70 +                                                             const gchar * filename);
   52.71 +gboolean        gmyth_util_file_exists_from_socket          (GMythSocket *sock, 
   52.72 +                                                             const gchar *filename);
   52.73 +gboolean        gmyth_util_file_exists_and_get_remote_dir   (GMythBackendInfo *backend_info,
   52.74 +                                                             const gchar *filename,
   52.75 +                                                             gchar **current_dir);
   52.76 +gchar*          gmyth_util_create_filename                  (const gint chan_id,
   52.77 +                                                             const GTimeVal * start_time);
   52.78 +GList*          gmyth_util_get_channel_list                 (GMythBackendInfo *backend_info);
   52.79 +GSList*         gmyth_util_get_all_recordings               (GMythBackendInfo *backend_info);
   52.80 +GMythProgramInfo*
   52.81 +                gmyth_util_get_recording_from_channel       (GMythBackendInfo *backend_info,
   52.82 +                                                             const gchar *channel);
   52.83 +
   52.84 +G_END_DECLS
   52.85 +#endif                          /* GMYTH_UTIL_H_ */
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/gmyth/gmyth/gmyth_vlc.c	Mon Feb 25 17:51:43 2008 +0000
    53.3 @@ -0,0 +1,290 @@
    53.4 +/**
    53.5 + * GMyth Library
    53.6 + *
    53.7 + * @file gmyth/gmyth_vlc.c
    53.8 + *
    53.9 + * @brief <p> GMythVLC library provides functions that
   53.10 + * interact with a VLC server running telnet interface.
   53.11 + *
   53.12 + * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   53.13 + * @author Artur Duque de Souza <artur.souza@indt.org.br>
   53.14 + *
   53.15 + * 
   53.16 + * This program is free software; you can redistribute it and/or modify
   53.17 + * it under the terms of the GNU Lesser General Public License as published by
   53.18 + * the Free Software Foundation; either version 2 of the License, or
   53.19 + * (at your option) any later version.
   53.20 + *
   53.21 + * This program is distributed in the hope that it will be useful,
   53.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   53.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   53.24 + * GNU General Public License for more details.
   53.25 + *
   53.26 + * You should have received a copy of the GNU Lesser General Public License
   53.27 + * along with this program; if not, write to the Free Software
   53.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   53.29 + */
   53.30 +
   53.31 +#ifdef HAVE_CONFIG_H
   53.32 +#include "config.h"
   53.33 +#endif
   53.34 +
   53.35 +#include <assert.h>
   53.36 +
   53.37 +#include "gmyth_vlc.h"
   53.38 +#include "gmyth_debug.h"
   53.39 +#include "gmyth_socket.h"
   53.40 +
   53.41 +/*
   53.42 + * static functions 
   53.43 + */
   53.44 +static int      _socket_send(int socket, gchar * msg);
   53.45 +static int      _socket_recv(int socket, gchar * buf);
   53.46 +
   53.47 +/** Primitive function to send a message through the socket
   53.48 + *
   53.49 + * @param socket 
   53.50 + * @param msg the message itself
   53.51 + * @return 0 if success
   53.52 + */
   53.53 +static int
   53.54 +_socket_send(int socket, gchar * msg)
   53.55 +{
   53.56 +    size_t          size = strlen(msg) + 2; // (\n + \0)
   53.57 +    gchar          *final = (gchar *) g_malloc0(sizeof(gchar) * size);
   53.58 +
   53.59 +    g_snprintf(final, size, "%s\n", msg);
   53.60 +
   53.61 +    if (send(socket, final, strlen(final), 0) == -1)
   53.62 +        perror("GMyth_VLC: send error");
   53.63 +
   53.64 +    g_free(final);
   53.65 +    return 0;
   53.66 +}
   53.67 +
   53.68 +
   53.69 +/** Primitive function to receive a message through the socket
   53.70 + *
   53.71 + * @param socket 
   53.72 + * @param buf Buffer to put the message
   53.73 + * @return 0 if success
   53.74 + */
   53.75 +static int
   53.76 +_socket_recv(int socket, gchar * buf)
   53.77 +{
   53.78 +    int             numbytes = 0;
   53.79 +
   53.80 +    if ((numbytes = recv(socket, buf, BUFFER - 1, 0)) == -1) {
   53.81 +        perror("GMyth_VLC: recv error");
   53.82 +        return -1;
   53.83 +    }
   53.84 +
   53.85 +    buf[numbytes - 1] = '\0';
   53.86 +    return numbytes;
   53.87 +}
   53.88 +
   53.89 +
   53.90 +/** Function that adds options to the output media
   53.91 + *
   53.92 + * @param vlc structure with options for vlc
   53.93 + * @param output the number of the output media
   53.94 + * @param kind the type of option we'll change
   53.95 + * @param the params for the option
   53.96 + * @return 0 if success
   53.97 + */
   53.98 +int
   53.99 +gmyth_vlc_setup_output(GMythVlc * vlc, int output, gchar * kind,
  53.100 +                       gchar * opts)
  53.101 +{
  53.102 +    int             ret;
  53.103 +
  53.104 +    size_t          size = strlen(opts) + 25;
  53.105 +    gchar          *msg = g_malloc0(sizeof(gchar) * size);
  53.106 +
  53.107 +    g_snprintf(msg, size, "setup output%d %s %s", output, kind, opts);
  53.108 +
  53.109 +    ret = _socket_send(vlc->sockfd, msg);
  53.110 +
  53.111 +    g_free(msg);
  53.112 +    return ret;
  53.113 +}
  53.114 +
  53.115 +
  53.116 +/** Function to clean the playlist
  53.117 + *
  53.118 + * @param vlc structure with options for vlc
  53.119 + * @param output the number of the output media
  53.120 + * @param file the file we want to insert in the playlist
  53.121 + * @return 0 if success
  53.122 + */
  53.123 +int
  53.124 +gmyth_vlc_clean_playlist(GMythVlc * vlc)
  53.125 +{
  53.126 +    return _socket_send(vlc->sockfd, "del all");
  53.127 +}
  53.128 +
  53.129 +
  53.130 +/** Function to control the playlist
  53.131 + *
  53.132 + * @param vlc structure with options for vlc
  53.133 + * @param output the number of the output media
  53.134 + * @param command play, stop or pause(just for vod)
  53.135 + * @return 0 if success
  53.136 + */
  53.137 +int
  53.138 +gmyth_vlc_control_input(GMythVlc * vlc, int output, gchar * command)
  53.139 +{
  53.140 +    size_t          size = 25;
  53.141 +    gchar          *msg = g_malloc0(sizeof(gchar) * size);
  53.142 +
  53.143 +    g_snprintf(msg, size, "control output%d %s", output, command);
  53.144 +
  53.145 +    int             ret = _socket_send(vlc->sockfd, msg);
  53.146 +
  53.147 +    g_free(msg);
  53.148 +    return ret;
  53.149 +}
  53.150 +
  53.151 +
  53.152 +
  53.153 +/** Function to insert an item in the playlist
  53.154 + *
  53.155 + * @param vlc structure with options for vlc
  53.156 + * @param output the number of the output media
  53.157 + * @param file the file we want to insert in the playlist
  53.158 + * @return 0 if success
  53.159 + */
  53.160 +int
  53.161 +gmyth_vlc_create_input(GMythVlc * vlc, int output, gchar * file)
  53.162 +{
  53.163 +    return gmyth_vlc_setup_output(vlc, output, "input", file);
  53.164 +}
  53.165 +
  53.166 +
  53.167 +/** Function to create a channel in vlc
  53.168 + *
  53.169 + * @param vlc structure with options for vlc
  53.170 + * @param type the type of channel (broadcast, vod...)
  53.171 + * @param port
  53.172 + * @return 0 if success
  53.173 + */
  53.174 +int
  53.175 +gmyth_vlc_create_channel(GMythVlc * vlc, gchar * type, int port,
  53.176 +                         int vcodec)
  53.177 +{
  53.178 +    int             ret;
  53.179 +    size_t          size = 40;
  53.180 +    gchar          *msg = (gchar *) g_malloc0(sizeof(gchar) * size);
  53.181 +
  53.182 +    g_snprintf(msg, size, "new output%d %s enabled loop", vlc->n_outputs,
  53.183 +               type);
  53.184 +
  53.185 +    ret = _socket_send(vlc->sockfd, msg);
  53.186 +
  53.187 +    if (ret > -1) {
  53.188 +        gmyth_vlc_setup_output(vlc, vlc->n_outputs, "option",
  53.189 +                               "sout-keep=1");
  53.190 +
  53.191 +        g_free(msg);
  53.192 +        size = 256;
  53.193 +        msg = (gchar *) g_malloc0(sizeof(gchar) * size);
  53.194 +
  53.195 +        if (vcodec == MPEG1)
  53.196 +            // Best transcode option for N800 (MP1V)
  53.197 +            g_snprintf(msg, size, "#transcode{vcodec=mp1v,vb=384,"
  53.198 +                       "fps=25.0,scale=1,acodec=mpga,"
  53.199 +                       "ab=64,channels=1}:duplicate{dst="
  53.200 +                       "std{access=http,mux=mpeg1,dst=" ":%d}}", port);
  53.201 +        else
  53.202 +            // Best transcode option for N800 (THEORA)
  53.203 +            g_snprintf(msg, size, "#transcode{vcodec=theo,vb=384,"
  53.204 +                       "fps=25.0,scale=1,acodec=vorb,"
  53.205 +                       "ab=64,channels=1}:duplicate{dst="
  53.206 +                       "std{access=http,mux=ogg,dst=" ":%d}}", port);
  53.207 +
  53.208 +        ret = gmyth_vlc_setup_output(vlc, vlc->n_outputs, "output", msg);
  53.209 +
  53.210 +        vlc->n_outputs++;
  53.211 +    }
  53.212 +
  53.213 +    g_free(msg);
  53.214 +
  53.215 +    return ret;
  53.216 +}
  53.217 +
  53.218 +
  53.219 +/** Function to connect to vlc on the backend
  53.220 + *
  53.221 + * @param vlc structure with options for vlc
  53.222 + * @param backend_info infos about the backend
  53.223 + * @param passwd the password for telnet interface
  53.224 + * @return 0 if success
  53.225 + */
  53.226 +int
  53.227 +gmyth_vlc_connect(GMythVlc * vlc, GMythBackendInfo * backend_info,
  53.228 +                  gchar * passwd, int port)
  53.229 +{
  53.230 +    int             numbytes;
  53.231 +
  53.232 +    if ((vlc->he = gethostbyname(backend_info->hostname)) == NULL) {
  53.233 +        herror("GMyth_VLC: gethostbyname error");
  53.234 +        return -1;
  53.235 +    }
  53.236 +
  53.237 +    if ((vlc->sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
  53.238 +        perror("GMyth_VLC: socket error");
  53.239 +        return -1;
  53.240 +    }
  53.241 +    // Socket properties
  53.242 +    vlc->their_addr.sin_family = AF_INET;
  53.243 +    vlc->their_addr.sin_port = htons(port);
  53.244 +    vlc->their_addr.sin_addr = *((struct in_addr *) vlc->he->h_addr);
  53.245 +    memset(&(vlc->their_addr.sin_zero), '\0', 8);
  53.246 +
  53.247 +    if (connect(vlc->sockfd, (struct sockaddr *) &(vlc->their_addr),
  53.248 +                sizeof(struct sockaddr)) == -1) {
  53.249 +        perror("GMyth_VLC: connect error. Check VLC's telnet interface");
  53.250 +        return -1;
  53.251 +    }
  53.252 +    // Receive the Password's Prompt
  53.253 +    numbytes = _socket_recv(vlc->sockfd, vlc->buf);
  53.254 +
  53.255 +    // Send the Password. We don't have to
  53.256 +    // care about passwords being sent in plain text
  53.257 +    // because telnet protocol does it.
  53.258 +    _socket_send(vlc->sockfd, passwd);
  53.259 +
  53.260 +    // Receive the Welcome msg
  53.261 +    numbytes = _socket_recv(vlc->sockfd, vlc->buf);
  53.262 +    if (numbytes > -1)
  53.263 +        if (strncmp(vlc->buf, "\r\nWrong password.", 17) == 0) {
  53.264 +            perror("Gmyth_VLC: passwd error. Check your passwd");
  53.265 +            return -2;
  53.266 +        }
  53.267 +
  53.268 +
  53.269 +    return 0;
  53.270 +}
  53.271 +
  53.272 +
  53.273 +/** Function to disconnect from vlc
  53.274 + *
  53.275 + * @param vlc structure with options for vlc
  53.276 + * @param backend_info infos about the backend
  53.277 + * @return 0 if success
  53.278 + */
  53.279 +int
  53.280 +gmyth_vlc_disconnect(GMythVlc * vlc)
  53.281 +{
  53.282 +
  53.283 +    int             ret;
  53.284 +
  53.285 +    ret = gmyth_vlc_clean_playlist(vlc);
  53.286 +
  53.287 +    if (ret > -1) {
  53.288 +        vlc->n_outputs = 0;
  53.289 +        vlc->n_inputs = 0;
  53.290 +    }
  53.291 +
  53.292 +    return close(vlc->sockfd);
  53.293 +}
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/gmyth/gmyth/gmyth_vlc.h	Mon Feb 25 17:51:43 2008 +0000
    54.3 @@ -0,0 +1,96 @@
    54.4 +/**
    54.5 + * GMyth Library
    54.6 + *
    54.7 + * @file gmyth/gmyth_vlc.h
    54.8 + * 
    54.9 + * @brief <p> GMythVLC library provides functions that
   54.10 + * interact with a VLC server running telnet interface.
   54.11 + *
   54.12 + * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   54.13 + * @author Artur Duque de Souza <artur.souza@indt.org.br>
   54.14 + *
   54.15 + * 
   54.16 + * This program is free software; you can redistribute it and/or modify
   54.17 + * it under the terms of the GNU Lesser General Public License as published by
   54.18 + * the Free Software Foundation; either version 2 of the License, or
   54.19 + * (at your option) any later version.
   54.20 + *
   54.21 + * This program is distributed in the hope that it will be useful,
   54.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   54.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   54.24 + * GNU General Public License for more details.
   54.25 + *
   54.26 + * You should have received a copy of the GNU Lesser General Public License
   54.27 + * along with this program; if not, write to the Free Software
   54.28 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   54.29 + */
   54.30 +
   54.31 +#ifndef __GMYTH_VLC_H__
   54.32 +#define __GMYTH_VLC_H__
   54.33 +
   54.34 +#include <glib-object.h>
   54.35 +
   54.36 +#include <glib.h>
   54.37 +#include <stdio.h>
   54.38 +#include <stdlib.h>
   54.39 +#include <unistd.h>
   54.40 +#include <errno.h>
   54.41 +#include <string.h>
   54.42 +#include <netdb.h>
   54.43 +#include <sys/types.h>
   54.44 +#include <netinet/in.h>
   54.45 +#include <sys/socket.h>
   54.46 +
   54.47 +
   54.48 +#include "gmyth_backendinfo.h"
   54.49 +#include "gmyth_util.h"
   54.50 +
   54.51 +G_BEGIN_DECLS
   54.52 +#define VLC_TELNET_PORT 4212
   54.53 +#define BUFFER 512
   54.54 +#define MPEG1 0
   54.55 +#define THEORA 1
   54.56 +typedef struct _GMythVlc GMythVlc;
   54.57 +
   54.58 +struct _GMythVlc {
   54.59 +    int             sockfd;
   54.60 +
   54.61 +    // Number of outputs used
   54.62 +    int             n_outputs;
   54.63 +
   54.64 +    // Number of inputs
   54.65 +    int             n_inputs;
   54.66 +
   54.67 +    // Socket vars
   54.68 +    struct hostent *he;
   54.69 +    struct sockaddr_in their_addr;
   54.70 +
   54.71 +    char            buf[BUFFER];
   54.72 +};
   54.73 +
   54.74 +
   54.75 +
   54.76 +int             gmyth_vlc_setup_output(GMythVlc * vlc, int output,
   54.77 +                                       gchar * kind, gchar * opts);
   54.78 +
   54.79 +
   54.80 +int             gmyth_vlc_clean_playlist(GMythVlc * vlc);
   54.81 +
   54.82 +
   54.83 +int             gmyth_vlc_control_input(GMythVlc * vlc, int output,
   54.84 +                                        gchar * command);
   54.85 +
   54.86 +int             gmyth_vlc_create_input(GMythVlc * vlc, int output,
   54.87 +                                       gchar * file);
   54.88 +
   54.89 +int             gmyth_vlc_create_channel(GMythVlc * vlc, gchar * type,
   54.90 +                                         int port, int vcodec);
   54.91 +
   54.92 +int             gmyth_vlc_connect(GMythVlc * vlc,
   54.93 +                                  GMythBackendInfo * backend_info,
   54.94 +                                  gchar * passwd, int port);
   54.95 +
   54.96 +int             gmyth_vlc_disconnect(GMythVlc * vlc);
   54.97 +
   54.98 +G_END_DECLS
   54.99 +#endif                          /* __GMYTH_VLC_H__ */
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/gmyth/gmyth/gst-indent.sh	Mon Feb 25 17:51:43 2008 +0000
    55.3 @@ -0,0 +1,16 @@
    55.4 +#!/bin/sh
    55.5 +indent \
    55.6 +  --braces-on-if-line \
    55.7 +  --blank-lines-after-declarations \
    55.8 +  --case-brace-indentation0 \
    55.9 +  --case-indentation4 \
   55.10 +  --braces-after-struct-decl-line \
   55.11 +  --line-length80 \
   55.12 +  --no-tabs \
   55.13 +  --cuddle-else \
   55.14 +  --dont-line-up-parentheses \
   55.15 +  --continuation-indentation4 \
   55.16 +  --honour-newlines \
   55.17 +  --tab-size4 \
   55.18 +  --indent-level4 \
   55.19 +  $*
    56.1 --- a/gmyth/samples/Makefile.am	Mon Feb 25 17:45:36 2008 +0000
    56.2 +++ b/gmyth/samples/Makefile.am	Mon Feb 25 17:51:43 2008 +0000
    56.3 @@ -7,7 +7,7 @@
    56.4          gmyth_ls.c
    56.5  
    56.6  LDADD = \
    56.7 -        $(top_builddir)/src/libgmyth.la
    56.8 +        $(top_builddir)/gmyth/libgmyth.la
    56.9  
   56.10  AM_CFLAGS = -g
   56.11  
   56.12 @@ -16,6 +16,6 @@
   56.13  
   56.14  INCLUDES = \
   56.15          -I$(top_srcdir) \
   56.16 -        -I$(top_srcdir)/src \
   56.17 +        -I$(top_srcdir)/gmyth \
   56.18          $(GLIB_CFLAGS) \
   56.19          $(GOBJECT_CFLAGS)
    57.1 --- a/gmyth/src/Makefile.am	Mon Feb 25 17:45:36 2008 +0000
    57.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.3 @@ -1,98 +0,0 @@
    57.4 -lib_LTLIBRARIES = libgmyth.la
    57.5 -
    57.6 -INCLUDES = -I$(top_srcdir)/src -I$(top_builddir)/src @GLIB_CFLAGS@ @GOBJECT_CFLAGS@
    57.7 -
    57.8 -BUILT_SOURCES =					\
    57.9 -	gmyth_marshal.c				\
   57.10 -	gmyth_marshal.h
   57.11 -
   57.12 -libgmyth_la_SOURCES =			\
   57.13 -	gmyth_common.c				\
   57.14 -	gmyth_debug.c				\
   57.15 -	gmyth_epg.c 				\
   57.16 -	gmyth_recorder.c			\
   57.17 -	gmyth_remote_util.c			\
   57.18 -	gmyth_tvchain.c				\
   57.19 -	gmyth_scheduler.c 			\
   57.20 -	gmyth_util.c				\
   57.21 -	gmyth_query.c				\
   57.22 -	gmyth_socket.c				\
   57.23 -	gmyth_stringlist.c			\
   57.24 -	gmyth_monitor_handler.c		\
   57.25 -	gmyth_file_transfer.c		\
   57.26 -	gmyth_livetv.c				\
   57.27 -	gmyth_backendinfo.c			\
   57.28 -	gmyth_programinfo.c			\
   57.29 -	gmyth_uri.c					\
   57.30 -	gmyth_http.c				\
   57.31 -	gmyth_vlc.c					\
   57.32 -	gmyth_jobqueue.c			\
   57.33 -	gmyth_transcoder.c			\
   57.34 -	gmyth_recprofile.c			\
   57.35 -	gmyth_file.c				\
   57.36 -	gmyth_file_local.c			\
   57.37 -	$(BUILT_SOURCES)
   57.38 -
   57.39 -EXTRA_libgmyth_la_SOURCES = gmyth_marshal.list
   57.40 -
   57.41 -gmyth_marshal.h: gmyth_marshal.list
   57.42 -	glib-genmarshal --header --prefix=gmyth_marshal gmyth_marshal.list > gmyth_marshal.h.tmp
   57.43 -	mv gmyth_marshal.h.tmp gmyth_marshal.h
   57.44 -
   57.45 -gmyth_marshal.c: gmyth_marshal.list gmyth_marshal.h
   57.46 -	echo "#include \"glib-object.h\"" > gmyth_marshal.c.tmp
   57.47 -	echo "#include \"gmyth_marshal.h\"" >> gmyth_marshal.c.tmp
   57.48 -	glib-genmarshal --body --prefix=gmyth_marshal $(srcdir)/gmyth_marshal.list >> gmyth_marshal.c.tmp
   57.49 -	mv gmyth_marshal.c.tmp gmyth_marshal.c
   57.50 -
   57.51 -libgmyth_la_CFLAGS = 			\
   57.52 -	-DDATADIR=\"$(pkgdatadir)\"	\
   57.53 -	$(GLIB_CFLAGS) 				\
   57.54 -	$(GOBJECT_CFLAGS)			\
   57.55 -	$(GST_CFLAGS) 				\
   57.56 -	$(GSTBASE_CFLAGS)			\
   57.57 -	$(GSTPLUGINSBASE_CFLAGS)	\
   57.58 -	$(MYSQL_CFLAGS)				\
   57.59 -	$(LIBXML_CFLAGS)
   57.60 -
   57.61 -libgmyth_la_LDFLAGS =			\
   57.62 -	-export-dynamic				\
   57.63 -	$(GLIB_CFLAGS)				\
   57.64 -	$(GOBJECT_CFLAGS)			\
   57.65 -	$(MYSQL_LIBS)				\
   57.66 -	$(GST_LIBS)					\
   57.67 -	$(GSTBASE_LIBS)				\
   57.68 -	$(GSTPLUGINS_LIBS)			\
   57.69 -	$(LIBXML_LIBS)
   57.70 -
   57.71 -libgmyth_includedir =			\
   57.72 -	$(pkgincludedir)
   57.73 -
   57.74 -libgmyth_include_HEADERS =		\
   57.75 -	gmyth.h						\
   57.76 -	gmyth_common.h	 			\
   57.77 -	gmyth_debug.h				\
   57.78 -	gmyth_epg.h					\
   57.79 -	gmyth_recorder.h			\
   57.80 -	gmyth_scheduler.h			\
   57.81 -	gmyth_tvchain.h				\
   57.82 -	gmyth_util.h				\
   57.83 -	gmyth_query.h				\
   57.84 -	gmyth_socket.h				\
   57.85 -	gmyth_remote_util.h			\
   57.86 -	gmyth_stringlist.h			\
   57.87 -	gmyth_monitor_handler.h		\
   57.88 -	gmyth_file_transfer.h		\
   57.89 -	gmyth_livetv.h				\
   57.90 -	gmyth_backendinfo.h			\
   57.91 -	gmyth_programinfo.h			\
   57.92 -	gmyth_uri.h					\
   57.93 -	gmyth_http.h				\
   57.94 -	gmyth_vlc.h					\
   57.95 -	gmyth_jobqueue.h			\
   57.96 -	gmyth_transcoder.h			\
   57.97 -	gmyth_recprofile.h			\
   57.98 -	gmyth_file.h				\
   57.99 -	gmyth_file_local.h
  57.100 -
  57.101 -CLEANFILES = $(BUILT_SOURCES)
    58.1 --- a/gmyth/src/gmyth-indent.sh	Mon Feb 25 17:45:36 2008 +0000
    58.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.3 @@ -1,25 +0,0 @@
    58.4 -#!/bin/sh
    58.5 -indent \
    58.6 -	-gnu \
    58.7 -	-i4 \
    58.8 -	-l80 \
    58.9 -	-bfda \
   58.10 -	-nut \
   58.11 -	-pcs \
   58.12 -	-psl \
   58.13 -	-bli0 \
   58.14 -	-cs \
   58.15 -	-cli0 \
   58.16 -	-nbfda \
   58.17 -	-sai \
   58.18 -	-saw \
   58.19 -	-saf \
   58.20 -	-sbi4 \
   58.21 -	-npro \
   58.22 -	-nfca \
   58.23 -	-nsc \
   58.24 -	-ts4 \
   58.25 -	-prs \
   58.26 -	-bap \
   58.27 -	$*
   58.28 -
    59.1 --- a/gmyth/src/gmyth.h	Mon Feb 25 17:45:36 2008 +0000
    59.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.3 @@ -1,57 +0,0 @@
    59.4 -/**
    59.5 - * GMyth Library
    59.6 - *
    59.7 - * @file gmyth/gmyth.h
    59.8 - * 
    59.9 - *
   59.10 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   59.11 - * @author Renato Filho <renato.filho@indt.org.br>
   59.12 - *
   59.13 - *//*
   59.14 - * 
   59.15 - * This program is free software; you can redistribute it and/or modify
   59.16 - * it under the terms of the GNU Lesser General Public License as published by
   59.17 - * the Free Software Foundation; either version 2 of the License, or
   59.18 - * (at your option) any later version.
   59.19 - *
   59.20 - * This program is distributed in the hope that it will be useful,
   59.21 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   59.22 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   59.23 - * GNU General Public License for more details.
   59.24 - *
   59.25 - * You should have received a copy of the GNU Lesser General Public License
   59.26 - * along with this program; if not, write to the Free Software
   59.27 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   59.28 - */
   59.29 -
   59.30 -
   59.31 -
   59.32 -#ifndef _GMYTH_H_
   59.33 -#define _GMYTH_H_
   59.34 -
   59.35 -#include <gmyth/gmyth_backendinfo.h>
   59.36 -#include <gmyth/gmyth_common.h>
   59.37 -#include <gmyth/gmyth_debug.h>
   59.38 -#include <gmyth/gmyth_epg.h>
   59.39 -#include <gmyth/gmyth_file.h>
   59.40 -#include <gmyth/gmyth_file_local.h>
   59.41 -#include <gmyth/gmyth_file_transfer.h>
   59.42 -#include <gmyth/gmyth_livetv.h>
   59.43 -#include <gmyth/gmyth_monitor_handler.h>
   59.44 -#include <gmyth/gmyth_programinfo.h>
   59.45 -#include <gmyth/gmyth_query.h>
   59.46 -#include <gmyth/gmyth_recorder.h>
   59.47 -#include <gmyth/gmyth_remote_util.h>
   59.48 -#include <gmyth/gmyth_scheduler.h>
   59.49 -#include <gmyth/gmyth_socket.h>
   59.50 -#include <gmyth/gmyth_stringlist.h>
   59.51 -#include <gmyth/gmyth_tvchain.h>
   59.52 -#include <gmyth/gmyth_uri.h>
   59.53 -#include <gmyth/gmyth_util.h>
   59.54 -#include <gmyth/gmyth_http.h>
   59.55 -#include <gmyth/gmyth_vlc.h>
   59.56 -#include <gmyth/gmyth_jobqueue.h>
   59.57 -#include <gmyth/gmyth_transcoder.h>
   59.58 -#include <gmyth/gmyth_recprofile.h>
   59.59 -
   59.60 -#endif /* _GMYTH_H_ */
    60.1 --- a/gmyth/src/gmyth_backendinfo.c	Mon Feb 25 17:45:36 2008 +0000
    60.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.3 @@ -1,395 +0,0 @@
    60.4 -/**
    60.5 - * GMyth Library
    60.6 - *
    60.7 - * @file gmyth/gmyth_backend_info.c
    60.8 - * 
    60.9 - * @brief <p> This component represents all the MythTV backend server
   60.10 - * 						configuration information.
   60.11 - *
   60.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   60.13 - * @author Hallyson Melo <hallyson.melo@indt.org.br>
   60.14 - * @author Rosfran Borges <rosfran.borges@indt.org.br>
   60.15 - *
   60.16 - * 
   60.17 - * This program is free software; you can redistribute it and/or modify
   60.18 - * it under the terms of the GNU Lesser General Public License as published by
   60.19 - * the Free Software Foundation; either version 2 of the License, or
   60.20 - * (at your option) any later version.
   60.21 - *
   60.22 - * This program is distributed in the hope that it will be useful,
   60.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   60.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   60.25 - * GNU General Public License for more details.
   60.26 - *
   60.27 - * You should have received a copy of the GNU Lesser General Public License
   60.28 - * along with this program; if not, write to the Free Software
   60.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   60.30 - */
   60.31 -
   60.32 -#ifdef HAVE_CONFIG_H
   60.33 -#include "config.h"
   60.34 -#endif
   60.35 -
   60.36 -#include "gmyth_backendinfo.h"
   60.37 -#include "gmyth_uri.h"
   60.38 -#include "gmyth_debug.h"
   60.39 -
   60.40 -static void     gmyth_backend_info_class_init(GMythBackendInfoClass *
   60.41 -                                              klass);
   60.42 -static void     gmyth_backend_info_init(GMythBackendInfo * object);
   60.43 -
   60.44 -static void     gmyth_backend_info_dispose(GObject * object);
   60.45 -static void     gmyth_backend_info_finalize(GObject * object);
   60.46 -
   60.47 -G_DEFINE_TYPE(GMythBackendInfo, gmyth_backend_info, G_TYPE_OBJECT);
   60.48 -static void     gmyth_backend_info_class_init(GMythBackendInfoClass *
   60.49 -                                                  klass)
   60.50 -{
   60.51 -    GObjectClass   *gobject_class;
   60.52 -
   60.53 -    gobject_class = (GObjectClass *) klass;
   60.54 -
   60.55 -    gobject_class->dispose = gmyth_backend_info_dispose;
   60.56 -    gobject_class->finalize = gmyth_backend_info_finalize;
   60.57 -}
   60.58 -
   60.59 -static void
   60.60 -gmyth_backend_info_init(GMythBackendInfo * backend_info)
   60.61 -{
   60.62 -    backend_info->hostname = NULL;
   60.63 -    backend_info->port = -1;
   60.64 -    backend_info->username = NULL;
   60.65 -    backend_info->password = NULL;
   60.66 -    backend_info->db_name = NULL;
   60.67 -    backend_info->db_port = 0;
   60.68 -    backend_info->status_port = -1;
   60.69 -}
   60.70 -
   60.71 -static void
   60.72 -gmyth_backend_info_dispose(GObject * object)
   60.73 -{
   60.74 -    GMythBackendInfo *backend_info = GMYTH_BACKEND_INFO(object);
   60.75 -
   60.76 -    g_free(backend_info->hostname);
   60.77 -    g_free(backend_info->username);
   60.78 -    g_free(backend_info->password);
   60.79 -    g_free(backend_info->db_name);
   60.80 -
   60.81 -    if (backend_info->sock)
   60.82 -        g_object_unref (backend_info->sock);
   60.83 -
   60.84 -    backend_info->hostname = NULL;
   60.85 -    backend_info->port = -1;
   60.86 -    backend_info->username = NULL;
   60.87 -    backend_info->password = NULL;
   60.88 -    backend_info->db_name = NULL;
   60.89 -    backend_info->db_port = 0;
   60.90 -    backend_info->status_port = -1;
   60.91 -    backend_info->sock = NULL;
   60.92 -
   60.93 -    G_OBJECT_CLASS(gmyth_backend_info_parent_class)->dispose(object);
   60.94 -}
   60.95 -
   60.96 -static void
   60.97 -gmyth_backend_info_finalize(GObject * object)
   60.98 -{
   60.99 -    g_signal_handlers_destroy(object);
  60.100 -
  60.101 -    G_OBJECT_CLASS(gmyth_backend_info_parent_class)->finalize(object);
  60.102 -}
  60.103 -
  60.104 -/** 
  60.105 - * Creates a new instance of GMythBackendInfo.
  60.106 - * 
  60.107 - * @return a new instance of GMythBackendInfo.
  60.108 - */
  60.109 -GMythBackendInfo *
  60.110 -gmyth_backend_info_new()
  60.111 -{
  60.112 -    GMythBackendInfo *backend_info =
  60.113 -        GMYTH_BACKEND_INFO(g_object_new(GMYTH_BACKEND_INFO_TYPE, NULL));
  60.114 -
  60.115 -    return backend_info;
  60.116 -}
  60.117 -
  60.118 -/** 
  60.119 - * Creates a new instance of GMythBackendInfo, based on a given set of 
  60.120 - * configuration parameters.
  60.121 - * 
  60.122 - * @param hostname The hostname to the MythTV backend server.
  60.123 - * @param username The user name to the MythTV backend MySQL server.
  60.124 - * @param password The password to the user of the MythTV backend MySQL server.
  60.125 - * @param db_name The database name of the MythTV backend, stored on the MySQL server.
  60.126 - * @param port The port number of the MythTV backend server (commonly is 6543).
  60.127 - * 
  60.128 - * @return a new instance of GMythBackendInfo.
  60.129 - */
  60.130 -GMythBackendInfo *
  60.131 -gmyth_backend_info_new_full(const gchar * hostname, const gchar * username,
  60.132 -                            const gchar * password, const gchar * db_name,
  60.133 -                            gint port)
  60.134 -{
  60.135 -    GMythBackendInfo *backend_info =
  60.136 -        GMYTH_BACKEND_INFO(g_object_new(GMYTH_BACKEND_INFO_TYPE, NULL));
  60.137 -
  60.138 -    gmyth_backend_info_set_hostname(backend_info, hostname);
  60.139 -    gmyth_backend_info_set_username(backend_info, username);
  60.140 -    gmyth_backend_info_set_password(backend_info, password);
  60.141 -    gmyth_backend_info_set_db_name(backend_info, db_name);
  60.142 -    gmyth_backend_info_set_port(backend_info, port);
  60.143 -
  60.144 -    return backend_info;
  60.145 -}
  60.146 -
  60.147 -/** 
  60.148 - * Creates a new instance of GMythBackendInfo, based on the 
  60.149 - * MythTV's backend server URI string.
  60.150 - * 
  60.151 - * @param uri_str The URI string pointing to the MythTV backend server.
  60.152 - * 
  60.153 - * @return a new instance of GMythBackendInfo.
  60.154 - */
  60.155 -GMythBackendInfo *
  60.156 -gmyth_backend_info_new_with_uri(const gchar * uri_str)
  60.157 -{
  60.158 -    GMythBackendInfo *backend_info;
  60.159 -    GMythURI       *uri;
  60.160 -    gchar         **path_parts;
  60.161 -    gchar          *db;
  60.162 -
  60.163 -    backend_info = GMYTH_BACKEND_INFO(g_object_new(GMYTH_BACKEND_INFO_TYPE, NULL));
  60.164 -    uri = gmyth_uri_new_with_value (uri_str);
  60.165 -    path_parts = g_strsplit(gmyth_uri_get_path(uri), "&", -1);
  60.166 -    gmyth_backend_info_set_hostname(backend_info, gmyth_uri_get_host(uri));
  60.167 -    gmyth_backend_info_set_username(backend_info, gmyth_uri_get_user(uri));
  60.168 -    gmyth_backend_info_set_password(backend_info,
  60.169 -                                    gmyth_uri_get_password(uri));
  60.170 -
  60.171 -    /*
  60.172 -     * gets the path info to database name, from the URI, and removes the
  60.173 -     * trash chars 
  60.174 -     */
  60.175 -    if ((path_parts != NULL) && (strlen (path_parts[0]) > 0))
  60.176 -    {
  60.177 -        db =  path_parts[0]+2;
  60.178 -    }
  60.179 -    else
  60.180 -    {
  60.181 -        db = gmyth_uri_get_path(uri);
  60.182 -    }
  60.183 -
  60.184 -    gmyth_backend_info_set_db_name(backend_info, db);
  60.185 -
  60.186 -    gmyth_backend_info_set_port(backend_info, gmyth_uri_get_port(uri));
  60.187 -
  60.188 -    g_object_unref(uri);
  60.189 -    g_strfreev(path_parts);
  60.190 -
  60.191 -    return backend_info;
  60.192 -}
  60.193 -
  60.194 -void
  60.195 -gmyth_backend_info_set_hostname(GMythBackendInfo * backend_info,
  60.196 -                                const gchar * hostname)
  60.197 -{
  60.198 -    g_return_if_fail(backend_info != NULL);
  60.199 -
  60.200 -    if (NULL == hostname || strlen(hostname) <= 0) {
  60.201 -        gmyth_debug("Error trying to set a hostname equals to NULL.");
  60.202 -    } else {
  60.203 -        backend_info->hostname = g_strdup(hostname);
  60.204 -    }
  60.205 -}
  60.206 -
  60.207 -void
  60.208 -gmyth_backend_info_set_username(GMythBackendInfo * backend_info,
  60.209 -                                const gchar * username)
  60.210 -{
  60.211 -    g_return_if_fail(backend_info != NULL);
  60.212 -
  60.213 -    backend_info->username = g_strdup(username);
  60.214 -}
  60.215 -
  60.216 -void
  60.217 -gmyth_backend_info_set_password(GMythBackendInfo * backend_info,
  60.218 -                                const gchar * password)
  60.219 -{
  60.220 -    g_return_if_fail(backend_info != NULL);
  60.221 -
  60.222 -    backend_info->password = g_strdup(password);
  60.223 -}
  60.224 -
  60.225 -void
  60.226 -gmyth_backend_info_set_db_name(GMythBackendInfo * backend_info,
  60.227 -                               const gchar * db_name)
  60.228 -{
  60.229 -    g_return_if_fail(backend_info != NULL);
  60.230 -
  60.231 -    backend_info->db_name = g_strdup(db_name);
  60.232 -}
  60.233 -
  60.234 -void
  60.235 -gmyth_backend_info_set_db_port(GMythBackendInfo * backend_info, gint db_port)
  60.236 -{
  60.237 -    g_return_if_fail(backend_info != NULL);
  60.238 -
  60.239 -    if (db_port <= 0) {
  60.240 -        gmyth_debug("Error trying to set a port less than 0.");
  60.241 -    } else {
  60.242 -        backend_info->db_port = db_port;
  60.243 -    }
  60.244 -}
  60.245 -
  60.246 -void
  60.247 -gmyth_backend_info_set_port(GMythBackendInfo * backend_info, gint port)
  60.248 -{
  60.249 -    g_return_if_fail(backend_info != NULL);
  60.250 -
  60.251 -    if (port <= 0) {
  60.252 -        gmyth_debug("Error trying to set a port less than 0.");
  60.253 -    } else {
  60.254 -        backend_info->port = port;
  60.255 -    }
  60.256 -}
  60.257 -
  60.258 -void
  60.259 -gmyth_backend_info_set_status_port(GMythBackendInfo * backend_info,
  60.260 -                                   gint port)
  60.261 -{
  60.262 -    g_return_if_fail(backend_info != NULL);
  60.263 -
  60.264 -    if (port <= 0) {
  60.265 -        gmyth_debug
  60.266 -            ("Error trying to set the status port to less than zero.");
  60.267 -    } else {
  60.268 -        backend_info->status_port = port;
  60.269 -    }
  60.270 -}
  60.271 -
  60.272 -const gchar    *
  60.273 -gmyth_backend_info_get_hostname(GMythBackendInfo * backend_info)
  60.274 -{
  60.275 -    g_return_val_if_fail(backend_info != NULL, NULL);
  60.276 -
  60.277 -    return backend_info->hostname;
  60.278 -}
  60.279 -
  60.280 -const gchar    *
  60.281 -gmyth_backend_info_get_username(GMythBackendInfo * backend_info)
  60.282 -{
  60.283 -    g_return_val_if_fail(backend_info != NULL, NULL);
  60.284 -
  60.285 -    return backend_info->username;
  60.286 -}
  60.287 -
  60.288 -const gchar    *
  60.289 -gmyth_backend_info_get_password(GMythBackendInfo * backend_info)
  60.290 -{
  60.291 -    g_return_val_if_fail(backend_info != NULL, NULL);
  60.292 -
  60.293 -    return backend_info->password;
  60.294 -}
  60.295 -
  60.296 -const gchar    *
  60.297 -gmyth_backend_info_get_db_name(GMythBackendInfo * backend_info)
  60.298 -{
  60.299 -    g_return_val_if_fail(backend_info != NULL, NULL);
  60.300 -
  60.301 -    return backend_info->db_name;
  60.302 -}
  60.303 -
  60.304 -gint
  60.305 -gmyth_backend_info_get_idb_port(GMythBackendInfo * backend_info)
  60.306 -{
  60.307 -    g_return_val_if_fail(backend_info != NULL, -1);
  60.308 -
  60.309 -    return backend_info->db_port;
  60.310 -}
  60.311 -
  60.312 -
  60.313 -gint
  60.314 -gmyth_backend_info_get_port(GMythBackendInfo * backend_info)
  60.315 -{
  60.316 -    g_return_val_if_fail(backend_info != NULL, -1);
  60.317 -
  60.318 -    return backend_info->port;
  60.319 -}
  60.320 -
  60.321 -/** 
  60.322 - * Creates a new instance of GMythURI, based on the GMythBackendInfo instance to the 
  60.323 - * MythTV's backend server.
  60.324 - * 
  60.325 - * @param backend_info The GMythBackendInfo instance.
  60.326 - * 
  60.327 - * @return an instance of GMythURI, created from a GMythBackendInfo.
  60.328 - */
  60.329 -GMythURI       *
  60.330 -gmyth_backend_info_get_uri(GMythBackendInfo * backend_info)
  60.331 -{
  60.332 -    GMythURI       *uri = NULL;
  60.333 -    gchar          *uri_str = NULL;
  60.334 -    gchar          *user_info = NULL;
  60.335 -    gchar          *db_data = NULL;
  60.336 -
  60.337 -    if ((backend_info->username != NULL
  60.338 -         && strlen(backend_info->username) > 0))
  60.339 -        user_info =
  60.340 -            g_strdup_printf("%s:%s@", backend_info->username,
  60.341 -                            backend_info->password);
  60.342 -
  60.343 -    if (backend_info->db_name != NULL && strlen(backend_info->db_name) > 0) {
  60.344 -        if ((g_strrstr(backend_info->db_name, "_") != NULL))
  60.345 -            db_data = g_strdup(backend_info->db_name);
  60.346 -        else
  60.347 -            db_data = g_strdup_printf("?%s&", backend_info->db_name);
  60.348 -    }
  60.349 -    // else if ( ( ( g_strrstr( backend_info->path, "livetv" ) != NULL )
  60.350 -    // || 
  60.351 -    // ( g_strrstr( backend_info->path, "/?" ) != NULL ) )
  60.352 -
  60.353 -    uri_str = g_strdup_printf("myth://%s%s:%d/%s", user_info != NULL
  60.354 -                              && strlen(user_info) > 0 ? user_info : "",
  60.355 -                              backend_info->hostname, backend_info->port,
  60.356 -                              db_data != NULL
  60.357 -                              && strlen(db_data) > 0 ? db_data : "");
  60.358 -    uri = gmyth_uri_new_with_value(uri_str);
  60.359 -
  60.360 -    if (user_info != NULL)
  60.361 -        g_free(user_info);
  60.362 -
  60.363 -    if (db_data != NULL)
  60.364 -        g_free(db_data);
  60.365 -
  60.366 -    g_free(uri_str);
  60.367 -
  60.368 -    return uri;
  60.369 -}
  60.370 -
  60.371 -gboolean
  60.372 -gmyth_backend_info_is_local_file(GMythBackendInfo * backend_info)
  60.373 -{
  60.374 -    g_return_val_if_fail(backend_info != NULL, FALSE);
  60.375 -
  60.376 -    return
  60.377 -        gmyth_uri_is_local_file(gmyth_backend_info_get_uri(backend_info));
  60.378 -}
  60.379 -
  60.380 -GMythSocket*
  60.381 -gmyth_backend_info_get_connected_socket (GMythBackendInfo *backend_info)
  60.382 -{
  60.383 -    if (backend_info->sock == NULL) {
  60.384 -        gboolean res;
  60.385 -        backend_info->sock = gmyth_socket_new ();
  60.386 -        res =  gmyth_socket_connect_to_backend (backend_info->sock,
  60.387 -                                                backend_info->hostname,
  60.388 -                                                backend_info->port,
  60.389 -                                                TRUE);
  60.390 -        if (res == FALSE) {
  60.391 -            g_object_unref (backend_info->sock);
  60.392 -            backend_info->sock = NULL;
  60.393 -            return NULL;
  60.394 -        }
  60.395 -    }
  60.396 -
  60.397 -    return g_object_ref (backend_info->sock);
  60.398 -}
    61.1 --- a/gmyth/src/gmyth_backendinfo.h	Mon Feb 25 17:45:36 2008 +0000
    61.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.3 @@ -1,121 +0,0 @@
    61.4 -/**
    61.5 - * GMyth Library
    61.6 - *
    61.7 - * @file gmyth/gmyth_backend_info.h
    61.8 - * 
    61.9 - * @brief <p> This component represents all the MythTV backend server
   61.10 - * 						configuration information.
   61.11 - *
   61.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   61.13 - * @author Hallyson Melo <hallyson.melo@indt.org.br>
   61.14 - * @author Rosfran Borges <rosfran.borges@indt.org.br>
   61.15 - *
   61.16 -* 
   61.17 -* This program is free software; you can redistribute it and/or modify
   61.18 -* it under the terms of the GNU Lesser General Public License as published by
   61.19 -* the Free Software Foundation; either version 2 of the License, or
   61.20 -* (at your option) any later version.
   61.21 -*
   61.22 -* This program is distributed in the hope that it will be useful,
   61.23 -	* but WITHOUT ANY WARRANTY; without even the implied warranty of
   61.24 -	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   61.25 -	* GNU General Public License for more details.
   61.26 -	*
   61.27 -	* You should have received a copy of the GNU Lesser General Public License
   61.28 -	* along with this program; if not, write to the Free Software
   61.29 -	* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   61.30 -	*/
   61.31 -
   61.32 -#ifndef __GMYTH_BACKEND_INFO_H__
   61.33 -#define __GMYTH_BACKEND_INFO_H__
   61.34 -
   61.35 -#include <glib-object.h>
   61.36 -
   61.37 -#include "gmyth_uri.h"
   61.38 -#include "gmyth_socket.h"
   61.39 -
   61.40 -G_BEGIN_DECLS
   61.41 -#define GMYTH_BACKEND_INFO_TYPE \
   61.42 -    (gmyth_backend_info_get_type ())
   61.43 -#define GMYTH_BACKEND_INFO(obj) \
   61.44 -    (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_BACKEND_INFO_TYPE, GMythBackendInfo))
   61.45 -#define GMYTH_BACKEND_INFO_CLASS(klass) \
   61.46 -    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_BACKEND_INFO_TYPE, GMythBackendInfoClass))
   61.47 -#define IS_GMYTH_BACKEND_INFO(obj) \
   61.48 -    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_BACKEND_INFO_TYPE))
   61.49 -#define IS_GMYTH_BACKEND_INFO_CLASS(klass) \
   61.50 -    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_BACKEND_INFO_TYPE))
   61.51 -#define GMYTH_BACKEND_INFO_GET_CLASS(obj) \
   61.52 -    (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_BACKEND_INFO_TYPE, GMythBackendInfoClass))
   61.53 -
   61.54 -typedef struct _GMythBackendInfo GMythBackendInfo;
   61.55 -typedef struct _GMythBackendInfoClass GMythBackendInfoClass;
   61.56 -
   61.57 -struct _GMythBackendInfoClass {
   61.58 -    GObjectClass    parent_class;
   61.59 -
   61.60 -    /*
   61.61 -     * callbacks 
   61.62 -     */
   61.63 -    /*
   61.64 -     * no one for now 
   61.65 -     */
   61.66 -};
   61.67 -
   61.68 -struct _GMythBackendInfo {
   61.69 -    GObject parent;
   61.70 -    /** The backend hostname or ip address. */
   61.71 -    gchar  *hostname;
   61.72 -    /** The backend port. */
   61.73 -    gint  port;
   61.74 -    /** The username to connect to the mysql server. */
   61.75 -    gchar *username;
   61.76 -    /** The password to connect to the mysql server. */
   61.77 -    gchar *password;
   61.78 -    /** The mythtv's mysql database name. */
   61.79 -    gchar *db_name;
   61.80 -    /** The mysql database port */
   61.81 -    gint  db_port;
   61.82 -    /** The backend status port for http connection */
   61.83 -    gint  status_port;
   61.84 -
   61.85 -    /* Private */
   61.86 -    GMythSocket *sock;
   61.87 -};
   61.88 -
   61.89 -
   61.90 -GType               gmyth_backend_info_get_type         (void) G_GNUC_CONST;
   61.91 -GMythBackendInfo*   gmyth_backend_info_new              (void);
   61.92 -GMythBackendInfo*   gmyth_backend_info_new_full         (const gchar        *hostname,
   61.93 -                                                         const gchar        *username,
   61.94 -                                                         const gchar        *password,
   61.95 -                                                         const gchar        *db_name,
   61.96 -                                                         gint               port);
   61.97 -GMythBackendInfo*   gmyth_backend_info_new_with_uri     (const gchar        *uri_str);
   61.98 -void                gmyth_backend_info_set_hostname     (GMythBackendInfo   *backend_info,
   61.99 -                                                         const gchar        *hostname);
  61.100 -void                gmyth_backend_info_set_username     (GMythBackendInfo   *backend_info,
  61.101 -                                                         const gchar        *username);
  61.102 -void                gmyth_backend_info_set_password     (GMythBackendInfo   *backend_info,
  61.103 -                                                         const gchar        *password);
  61.104 -void                gmyth_backend_info_set_db_name      (GMythBackendInfo   *backend_info,
  61.105 -                                                         const gchar        *db_name);
  61.106 -void                gmyth_backend_info_set_db_port      (GMythBackendInfo   *backend_info,
  61.107 -                                                         gint               db_port);
  61.108 -void                gmyth_backend_info_set_port         (GMythBackendInfo   *backend_info,
  61.109 -                                                         gint               port);
  61.110 -void                gmyth_backend_info_set_status_port  (GMythBackendInfo   *backend_info,
  61.111 -                                                         gint               port);
  61.112 -const gchar*        gmyth_backend_info_get_hostname     (GMythBackendInfo   *backend_info);
  61.113 -const gchar*        gmyth_backend_info_get_username     (GMythBackendInfo   *backend_info);
  61.114 -const gchar*        gmyth_backend_info_get_password     (GMythBackendInfo   *backend_info);
  61.115 -const gchar*        gmyth_backend_info_get_db_name      (GMythBackendInfo   *backend_info);
  61.116 -gint                gmyth_backend_info_get_db_port         (GMythBackendInfo   *backend_info);
  61.117 -gint                gmyth_backend_info_get_port         (GMythBackendInfo   *backend_info);
  61.118 -GMythURI*           gmyth_backend_info_get_uri          (GMythBackendInfo   *backend_info);
  61.119 -gboolean            gmyth_backend_info_is_local_file    (GMythBackendInfo   *backend_info);
  61.120 -GMythSocket*        gmyth_backend_info_get_connected_socket
  61.121 -                                                        (GMythBackendInfo   *backend_info);
  61.122 -
  61.123 -G_END_DECLS
  61.124 -#endif                          /* __GMYTH_BACKEND_INFO_H__ */
    62.1 --- a/gmyth/src/gmyth_common.c	Mon Feb 25 17:45:36 2008 +0000
    62.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.3 @@ -1,154 +0,0 @@
    62.4 -/**
    62.5 - * GMyth Library
    62.6 - *
    62.7 - * @file gmyth/gmyth_common.c
    62.8 - * 
    62.9 - * @brief <p> This file contains basic common functions for the gmyth library.
   62.10 - *
   62.11 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   62.12 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   62.13 - * @author Rosfran Borges <rosfran.borges@indt.org.br>
   62.14 - *
   62.15 - * 
   62.16 - * This program is free software; you can redistribute it and/or modify
   62.17 - * it under the terms of the GNU Lesser General Public License as published by
   62.18 - * the Free Software Foundation; either version 2 of the License, or
   62.19 - * (at your option) any later version.
   62.20 - *
   62.21 - * This program is distributed in the hope that it will be useful,
   62.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   62.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   62.24 - * GNU General Public License for more details.
   62.25 - *
   62.26 - * You should have received a copy of the GNU Lesser General Public License
   62.27 - * along with this program; if not, write to the Free Software
   62.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   62.29 - */
   62.30 -
   62.31 -#ifdef HAVE_CONFIG_H
   62.32 -#include "config.h"
   62.33 -#endif
   62.34 -
   62.35 -#include "gmyth_common.h"
   62.36 -#include "gmyth_debug.h"
   62.37 -#include "gmyth_util.h"
   62.38 -
   62.39 -static void     free_channel_data(gpointer data, gpointer user_data);
   62.40 -static void     free_program_data(gpointer data, gpointer user_data);
   62.41 -
   62.42 -/** 
   62.43 -* Frees the memory allocated to the GMythChannelInfo objects inside list.
   62.44 -* The list memory is also released by g_list_free(). If LIST is NULL it
   62.45 -* simply returns.
   62.46 -* 
   62.47 -* @param list the GList containing a list of GMythChannelInfo to free.
   62.48 -*/
   62.49 -void
   62.50 -gmyth_free_channel_list(GList * list)
   62.51 -{
   62.52 -    g_return_if_fail(list != NULL);
   62.53 -
   62.54 -    g_list_foreach(list, free_channel_data, NULL);
   62.55 -    g_list_free(list);
   62.56 -}
   62.57 -
   62.58 -/** 
   62.59 - * Frees the memory allocated to the GMythProgramInfo objects inside list.
   62.60 - * The list memory is also released by g_list_free(). If list is NULL it
   62.61 - * simply returns.
   62.62 - * 
   62.63 - * @param list the GList containing a list of GMythProgramInfo to free.
   62.64 - */
   62.65 -void
   62.66 -gmyth_free_program_list(GList * list)
   62.67 -{
   62.68 -    g_return_if_fail(list != NULL);
   62.69 -
   62.70 -    g_list_foreach(list, free_program_data, NULL);
   62.71 -    g_list_free(list);
   62.72 -}
   62.73 -
   62.74 -void
   62.75 -gmyth_channel_info_free(GMythChannelInfo * channel)
   62.76 -{
   62.77 -    g_return_if_fail(channel != NULL);
   62.78 -
   62.79 -    if (channel->channel_num)
   62.80 -        g_string_free(channel->channel_num, TRUE);
   62.81 -
   62.82 -    if (channel->channel_name)
   62.83 -        g_string_free(channel->channel_name, TRUE);
   62.84 -
   62.85 -    if (channel->channel_icon)
   62.86 -        g_string_free(channel->channel_icon, TRUE);
   62.87 -
   62.88 -    g_free(channel);
   62.89 -}
   62.90 -
   62.91 -/**
   62.92 - * Prints the channel info to the standard output. The gmyth debug must be enabled.
   62.93 - * @param channel_info the GMythChannelInfo instance
   62.94 - */
   62.95 -void
   62.96 -gmyth_channel_info_print(GMythChannelInfo * channel_info)
   62.97 -{
   62.98 -#ifdef GMYTH_USE_DEBUG
   62.99 -    if (channel_info != NULL) {
  62.100 -        g_return_if_fail(channel_info->channel_name != NULL);
  62.101 -        g_return_if_fail(channel_info->channel_num != NULL);
  62.102 -
  62.103 -        gmyth_debug("ChannelInfo (Name, Num, ID) = (%s, %s, %d)",
  62.104 -                    channel_info->channel_name->str,
  62.105 -                    channel_info->channel_num->str,
  62.106 -                    channel_info->channel_ID);
  62.107 -
  62.108 -    }
  62.109 -#endif
  62.110 -}
  62.111 -
  62.112 -/**
  62.113 - * Prints the program info to the standard output. The gmyth debug must be enabled.
  62.114 - * @param channel_info the GMythProgramInfo instance
  62.115 - */
  62.116 -void
  62.117 -gmyth_program_info_print(GMythProgramInfo * program_info)
  62.118 -{
  62.119 -#ifdef GMYTH_USE_DEBUG
  62.120 -    g_return_if_fail(program_info);
  62.121 -
  62.122 -    gmyth_debug("ProgramInfo\n\tTitle = %s\n\t"
  62.123 -                "Description = %s\n\t"
  62.124 -                "Start time= %s\t"
  62.125 -                "End time = %s\n"
  62.126 -                "Path name = %s\n"
  62.127 -                "File size = %lld\n",
  62.128 -                program_info->title ? program_info->title->str : "NULL",
  62.129 -                program_info->description ? program_info->description->
  62.130 -                str : "NULL",
  62.131 -                gmyth_util_time_to_string_from_time_val(program_info->
  62.132 -                                                        startts),
  62.133 -                gmyth_util_time_to_string_from_time_val(program_info->
  62.134 -                                                        endts),
  62.135 -                program_info->pathname ? program_info->pathname->
  62.136 -                str : "NULL", program_info->filesize);
  62.137 -#endif
  62.138 -}
  62.139 -
  62.140 -static void
  62.141 -free_channel_data(gpointer data, gpointer user_data)
  62.142 -{
  62.143 -    /*
  62.144 -     * Frees the GMythChannelInfo structure 
  62.145 -     */
  62.146 -    GMythChannelInfo *channel = (GMythChannelInfo *) data;
  62.147 -
  62.148 -    gmyth_channel_info_free(channel);
  62.149 -}
  62.150 -
  62.151 -static void
  62.152 -free_program_data(gpointer data, gpointer user_data)
  62.153 -{
  62.154 -    g_return_if_fail(data != NULL);
  62.155 -
  62.156 -    g_object_unref((GMythProgramInfo *) data);
  62.157 -}
    63.1 --- a/gmyth/src/gmyth_common.h	Mon Feb 25 17:45:36 2008 +0000
    63.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.3 @@ -1,62 +0,0 @@
    63.4 -/**
    63.5 - * GMyth Library
    63.6 - * 
    63.7 - * @file gmyth/gmyth_common.h
    63.8 - * 
    63.9 - * @brief <p> This file contains basic common functions for the gmyth library.
   63.10 - *
   63.11 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   63.12 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   63.13 - * @author Rosfran Borges <rosfran.borges@indt.org.br>
   63.14 - *
   63.15 - * 
   63.16 - * This program is free software; you can redistribute it and/or modify
   63.17 - * it under the terms of the GNU Lesser General Public License as published by
   63.18 - * the Free Software Foundation; either version 2 of the License, or
   63.19 - * (at your option) any later version.
   63.20 - *
   63.21 - * This program is distributed in the hope that it will be useful,
   63.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   63.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   63.24 - * GNU General Public License for more details.
   63.25 - *
   63.26 - * You should have received a copy of the GNU Lesser General Public License
   63.27 - * along with this program; if not, write to the Free Software
   63.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   63.29 - */
   63.30 -
   63.31 -#ifndef GMYTH_COMMON_H_
   63.32 -#define GMYTH_COMMON_H_
   63.33 -
   63.34 -#include <glib.h>
   63.35 -#include <time.h>
   63.36 -
   63.37 -#include "gmyth_programinfo.h"
   63.38 -
   63.39 -G_BEGIN_DECLS
   63.40 -    /**
   63.41 -    * The GMythChannelInfo structure represents the channel information
   63.42 -    * stored in the backend database.
   63.43 -    */
   63.44 -    typedef struct {
   63.45 -    /** The channel ID in backend database */
   63.46 -    gint            channel_ID;
   63.47 -
   63.48 -    /** The channel number */
   63.49 -    GString        *channel_num;
   63.50 -
   63.51 -    /** The channel name in backend database */
   63.52 -    GString        *channel_name;
   63.53 -
   63.54 -    /** The channel icon path in the backend database */
   63.55 -    GString        *channel_icon;
   63.56 -} GMythChannelInfo;
   63.57 -
   63.58 -void            gmyth_free_channel_list     (GList *list);
   63.59 -void            gmyth_free_program_list     (GList *list);
   63.60 -void            gmyth_channel_info_free     (GMythChannelInfo *channel_info);
   63.61 -void            gmyth_channel_info_print    (GMythChannelInfo *channel_info);
   63.62 -void            gmyth_program_info_print    (GMythProgramInfo *program_info);
   63.63 -
   63.64 -G_END_DECLS
   63.65 -#endif                          /* GMYTH_COMMON_H_ */
    64.1 --- a/gmyth/src/gmyth_debug.c	Mon Feb 25 17:45:36 2008 +0000
    64.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.3 @@ -1,54 +0,0 @@
    64.4 -/**
    64.5 - * GMyth Library
    64.6 - *
    64.7 - * @file gmyth/gmyth_debug.c
    64.8 - * 
    64.9 - *
   64.10 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   64.11 - * @author Renato Filho <renato.filho@indt.org.br>
   64.12 - *
   64.13 - * 
   64.14 - * This program is free software; you can redistribute it and/or modify
   64.15 - * it under the terms of the GNU Lesser General Public License as published by
   64.16 - * the Free Software Foundation; either version 2 of the License, or
   64.17 - * (at your option) any later version.
   64.18 - *
   64.19 - * This program is distributed in the hope that it will be useful,
   64.20 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   64.21 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   64.22 - * GNU General Public License for more details.
   64.23 - *
   64.24 - * You should have received a copy of the GNU Lesser General Public License
   64.25 - * along with this program; if not, write to the Free Software
   64.26 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   64.27 - */
   64.28 -
   64.29 -#ifdef HAVE_CONFIG_H
   64.30 -#include "config.h"
   64.31 -#endif
   64.32 -
   64.33 -#include "gmyth_debug.h"
   64.34 -
   64.35 -void
   64.36 -gmyth_debug_real(const char *func,
   64.37 -                 const char *file, const int line, gboolean newline,
   64.38 -                 const char *format, ...)
   64.39 -{
   64.40 -    va_list         args;
   64.41 -    char            buffer[1025];
   64.42 -    char            str_time[255];
   64.43 -    time_t          the_time;
   64.44 -
   64.45 -    va_start(args, format);
   64.46 -
   64.47 -    g_vsnprintf(buffer, 1024, format, args);
   64.48 -
   64.49 -    va_end(args);
   64.50 -
   64.51 -    time(&the_time);
   64.52 -    strftime(str_time, 254, "%H:%M:%S", localtime(&the_time));
   64.53 -
   64.54 -    g_printerr(newline ? "(%s) [%p] [%s] %s:%d: %s\n" :
   64.55 -               "(%s) [%p] [%s] %s:%d: %s", str_time, g_thread_self(), func,
   64.56 -               file, line, buffer);
   64.57 -}
    65.1 --- a/gmyth/src/gmyth_debug.h	Mon Feb 25 17:45:36 2008 +0000
    65.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.3 @@ -1,46 +0,0 @@
    65.4 -/**
    65.5 - * GMyth Library
    65.6 - *
    65.7 - * @file gmyth/gmyth_debug.h
    65.8 - * 
    65.9 - *
   65.10 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   65.11 - * @author Renato Filho <renato.filho@indt.org.br>
   65.12 - *
   65.13 -* 
   65.14 -* This program is free software; you can redistribute it and/or modify
   65.15 -* it under the terms of the GNU Lesser General Public License as published by
   65.16 -* the Free Software Foundation; either version 2 of the License, or
   65.17 -* (at your option) any later version.
   65.18 -*
   65.19 -* This program is distributed in the hope that it will be useful,
   65.20 -	* but WITHOUT ANY WARRANTY; without even the implied warranty of
   65.21 -	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   65.22 -	* GNU General Public License for more details.
   65.23 -	*
   65.24 -	* You should have received a copy of the GNU Lesser General Public License
   65.25 -	* along with this program; if not, write to the Free Software
   65.26 -	* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   65.27 -	*/
   65.28 -
   65.29 -#ifndef __GMYTH_DEBUG_H__
   65.30 -#define __GMYTH_DEBUG_H__
   65.31 -
   65.32 -#include <stdarg.h>
   65.33 -#include <glib.h>
   65.34 -#include <time.h>
   65.35 -
   65.36 -G_BEGIN_DECLS
   65.37 -#ifdef GMYTH_USE_DEBUG
   65.38 -#define gmyth_debug(...) gmyth_debug_real (__FUNCTION__, __FILE__, __LINE__, TRUE, __VA_ARGS__)
   65.39 -#else
   65.40 -#define gmyth_debug(...)
   65.41 -#endif
   65.42 -    void
   65.43 -gmyth_debug_real(const char *func,
   65.44 -                 const char *file, int line, gboolean newline,
   65.45 -                 const char *format, ...)
   65.46 -G_GNUC_PRINTF(5, 6);
   65.47 -
   65.48 -G_END_DECLS
   65.49 -#endif
    66.1 --- a/gmyth/src/gmyth_epg.c	Mon Feb 25 17:45:36 2008 +0000
    66.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.3 @@ -1,446 +0,0 @@
    66.4 -/**
    66.5 - * GMyth Library
    66.6 - *
    66.7 - * @file gmyth/gmyth_epg.c
    66.8 - * 
    66.9 - * @brief <p> GMythEPG class provides access to the program and channel data
   66.10 - * from the Electronic Program Guide (EPG) of the Mythtv backend.
   66.11 - *
   66.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   66.13 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   66.14 - * 
   66.15 - * This program is free software; you can redistribute it and/or modify
   66.16 - * it under the terms of the GNU Lesser General Public License as published by
   66.17 - * the Free Software Foundation; either version 2 of the License, or
   66.18 - * (at your option) any later version.
   66.19 - *
   66.20 - * This program is distributed in the hope that it will be useful,
   66.21 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   66.22 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   66.23 - * GNU General Public License for more details.
   66.24 - *
   66.25 - * You should have received a copy of the GNU Lesser General Public License
   66.26 - * along with this program; if not, write to the Free Software
   66.27 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   66.28 - */
   66.29 -
   66.30 -#ifdef HAVE_CONFIG_H
   66.31 -#include "config.h"
   66.32 -#endif
   66.33 -
   66.34 -#include <mysql/mysql.h>
   66.35 -#include <stdlib.h>
   66.36 -#include <string.h>
   66.37 -#include <assert.h>
   66.38 -
   66.39 -#include "gmyth_epg.h"
   66.40 -#include "gmyth_programinfo.h"
   66.41 -#include "gmyth_util.h"
   66.42 -#include "gmyth_file_transfer.h"
   66.43 -#include "gmyth_debug.h"
   66.44 -
   66.45 -#define CONNECT_TIMEOUT 6
   66.46 -
   66.47 -static void     gmyth_epg_class_init(GMythEPGClass * klass);
   66.48 -static void     gmyth_epg_init(GMythEPG * object);
   66.49 -
   66.50 -static void     gmyth_epg_dispose(GObject * object);
   66.51 -static void     gmyth_epg_finalize(GObject * object);
   66.52 -
   66.53 -G_DEFINE_TYPE(GMythEPG, gmyth_epg, G_TYPE_OBJECT)
   66.54 -    static void     gmyth_epg_class_init(GMythEPGClass * klass)
   66.55 -{
   66.56 -    GObjectClass   *gobject_class = G_OBJECT_CLASS(klass);
   66.57 -
   66.58 -    gobject_class->dispose = gmyth_epg_dispose;
   66.59 -    gobject_class->finalize = gmyth_epg_finalize;
   66.60 -}
   66.61 -
   66.62 -static void
   66.63 -gmyth_epg_init(GMythEPG * gmyth_epg)
   66.64 -{
   66.65 -
   66.66 -}
   66.67 -
   66.68 -static void
   66.69 -gmyth_epg_dispose(GObject * object)
   66.70 -{
   66.71 -    GMythEPG       *gmyth_epg = GMYTH_EPG(object);
   66.72 -
   66.73 -    if (gmyth_epg->sqlquery != NULL) {
   66.74 -        g_object_unref(gmyth_epg->sqlquery);
   66.75 -        gmyth_epg->sqlquery = NULL;
   66.76 -    }
   66.77 -
   66.78 -    G_OBJECT_CLASS(gmyth_epg_parent_class)->dispose(object);
   66.79 -}
   66.80 -
   66.81 -static void
   66.82 -gmyth_epg_finalize(GObject * object)
   66.83 -{
   66.84 -    g_signal_handlers_destroy(object);
   66.85 -
   66.86 -    G_OBJECT_CLASS(gmyth_epg_parent_class)->finalize(object);
   66.87 -}
   66.88 -
   66.89 -/**
   66.90 - * Creates a new instance of GMythEPG.
   66.91 - * 
   66.92 - * @return a new instance of GMythEPG.
   66.93 - */
   66.94 -GMythEPG       *
   66.95 -gmyth_epg_new(void)
   66.96 -{
   66.97 -    GMythEPG       *epg = GMYTH_EPG(g_object_new(GMYTH_EPG_TYPE, NULL));
   66.98 -
   66.99 -    return epg;
  66.100 -}
  66.101 -
  66.102 -/** Connects to the Mysql database in the backend. The backend address
  66.103 - * is loaded from the GMythSettings instance.
  66.104 - *
  66.105 - * @param gmyth_epg the GMythEPG instance to be connected.
  66.106 - * @return true if connection was success, false if failed.
  66.107 - */
  66.108 -gboolean
  66.109 -gmyth_epg_connect(GMythEPG * gmyth_epg, GMythBackendInfo * backend_info)
  66.110 -{
  66.111 -    g_return_val_if_fail(gmyth_epg != NULL, FALSE);
  66.112 -
  66.113 -    if (gmyth_epg->sqlquery == NULL) {
  66.114 -        gmyth_debug("[%s] Creating gmyth_query", __FUNCTION__);
  66.115 -        gmyth_epg->sqlquery = gmyth_query_new();
  66.116 -    }
  66.117 -
  66.118 -    if (!gmyth_query_connect_with_timeout(gmyth_epg->sqlquery,
  66.119 -                                          backend_info, CONNECT_TIMEOUT)) {
  66.120 -        gmyth_debug("[%s] Error while connecting to db", __FUNCTION__);
  66.121 -        return FALSE;
  66.122 -    }
  66.123 -
  66.124 -    gmyth_epg->backend_info = backend_info;
  66.125 -    g_object_ref(backend_info);
  66.126 -
  66.127 -    return TRUE;
  66.128 -}
  66.129 -
  66.130 -/** Disconnects from the Mysql database in the backend.
  66.131 - *
  66.132 - * @param gmyth_epg the GMythEPG instance to be disconnected
  66.133 - * @return true if disconnection was success, false if failed.
  66.134 - */
  66.135 -gboolean
  66.136 -gmyth_epg_disconnect(GMythEPG * gmyth_epg)
  66.137 -{
  66.138 -    g_return_val_if_fail(gmyth_epg != NULL, FALSE);
  66.139 -
  66.140 -    if (gmyth_epg->sqlquery != NULL) {
  66.141 -        gmyth_query_disconnect(gmyth_epg->sqlquery);
  66.142 -        g_object_unref(gmyth_epg->sqlquery);
  66.143 -        gmyth_epg->sqlquery = NULL;
  66.144 -    }
  66.145 -
  66.146 -    if (gmyth_epg->backend_info != NULL) {
  66.147 -        g_object_unref(gmyth_epg->backend_info);
  66.148 -        gmyth_epg->backend_info = NULL;
  66.149 -    }
  66.150 -
  66.151 -    return TRUE;
  66.152 -}
  66.153 -
  66.154 -/** Retrieves the available list of channels from the backend Mysql database.
  66.155 - * 
  66.156 - * @param gmyth_epg the GMythEPG instance.
  66.157 - * @param glist_ptr the GSList pointer to be filled with the loaded list address.
  66.158 - * @return The amount of channels retrieved from database,  or -1 if error.
  66.159 - */
  66.160 -gint
  66.161 -gmyth_epg_get_channel_list(GMythEPG * gmyth_epg, GList ** glist_ptr)
  66.162 -{
  66.163 -    MYSQL_RES      *msql_res;
  66.164 -
  66.165 -    g_return_val_if_fail(gmyth_epg != NULL, -1);
  66.166 -
  66.167 -    msql_res = gmyth_query_process_statement(gmyth_epg->sqlquery,
  66.168 -                                             "SELECT chanid, channum, name, icon FROM channel;");
  66.169 -
  66.170 -    (*glist_ptr) = NULL;
  66.171 -
  66.172 -    if (msql_res == NULL) {
  66.173 -        gmyth_debug("[%s] msql query returned NULL MYSQL_RES",
  66.174 -                    __FUNCTION__);
  66.175 -        return -1;
  66.176 -    } else {
  66.177 -        MYSQL_ROW       row;
  66.178 -        GMythChannelInfo *channel_info;
  66.179 -
  66.180 -        while ((row = mysql_fetch_row(msql_res)) != NULL) {
  66.181 -
  66.182 -            channel_info = g_new0(GMythChannelInfo, 1);
  66.183 -            channel_info->channel_ID =
  66.184 -                (gint) g_ascii_strtoull(row[0], NULL, 10);
  66.185 -            channel_info->channel_num = g_string_new(row[1]);
  66.186 -            channel_info->channel_name = g_string_new(row[2]);
  66.187 -            channel_info->channel_icon = g_string_new(row[3]);
  66.188 -#ifdef GMYTH_USE_DEBUG
  66.189 -            gmyth_channel_info_print(channel_info);
  66.190 -#endif
  66.191 -            (*glist_ptr) = g_list_append((*glist_ptr), channel_info);
  66.192 -        }
  66.193 -    }
  66.194 -    mysql_free_result(msql_res);
  66.195 -
  66.196 -    return (!(*glist_ptr)) ? 0 : g_list_length(*glist_ptr);
  66.197 -}
  66.198 -
  66.199 -GMythChannelInfo *
  66.200 -gmyth_epg_get_channel_info(GMythEPG * gmyth_epg, gint channel_id)
  66.201 -{
  66.202 -    GMythChannelInfo *channel_info = NULL;
  66.203 -    MYSQL_RES      *msql_res;
  66.204 -    gchar          *query_str;
  66.205 -
  66.206 -    g_return_val_if_fail(gmyth_epg != NULL, NULL);
  66.207 -
  66.208 -    query_str =
  66.209 -        g_strdup_printf
  66.210 -        ("SELECT channum, name, icon FROM channel WHERE chanid=%d;",
  66.211 -         channel_id);
  66.212 -    msql_res =
  66.213 -        gmyth_query_process_statement(gmyth_epg->sqlquery, query_str);
  66.214 -
  66.215 -    if (msql_res == NULL) {
  66.216 -        gmyth_debug("[%s] msql query returned NULL MYSQL_RES",
  66.217 -                    __FUNCTION__);
  66.218 -        return NULL;
  66.219 -    } else {
  66.220 -        MYSQL_ROW       row;
  66.221 -
  66.222 -        if ((row = mysql_fetch_row(msql_res)) != NULL) {
  66.223 -
  66.224 -            channel_info = g_new0(GMythChannelInfo, 1);
  66.225 -            channel_info->channel_ID = channel_id;
  66.226 -            channel_info->channel_num = g_string_new(row[0]);
  66.227 -            channel_info->channel_name = g_string_new(row[1]);
  66.228 -            channel_info->channel_icon = g_string_new(row[2]);
  66.229 -#ifdef GMYTH_USE_DEBUG
  66.230 -            gmyth_channel_info_print(channel_info);
  66.231 -#endif
  66.232 -        }
  66.233 -    }
  66.234 -    mysql_free_result(msql_res);
  66.235 -
  66.236 -    return channel_info;
  66.237 -}
  66.238 -
  66.239 -/** 
  66.240 - * Retrieves the available list of channels from the backend Mysql database.
  66.241 - * 
  66.242 - * @param gmyth_epg the GMythEPG instance.
  66.243 - * @param proglist the GSList pointer to be filled with the loaded list.
  66.244 - * @param chan_num the channel num on which to search for program.
  66.245 - * @param starttime the start time to search for programs.
  66.246 - * @param endtime the end time to search for programs.
  66.247 - * @return The amount of channels retrieved from database, or -1 if error.
  66.248 - */
  66.249 -gint
  66.250 -gmyth_epg_get_program_list(GMythEPG * gmyth_epg, GList ** proglist,
  66.251 -                           const gint chan_num, GTimeVal * starttime,
  66.252 -                           GTimeVal * endtime)
  66.253 -{
  66.254 -
  66.255 -    gchar          *startts =
  66.256 -        gmyth_util_time_to_string_from_time_val(starttime);
  66.257 -    gchar          *endts =
  66.258 -        gmyth_util_time_to_string_from_time_val(endtime);
  66.259 -    MYSQL_ROW       row;
  66.260 -    GString        *querystr;
  66.261 -
  66.262 -    assert(gmyth_epg);
  66.263 -
  66.264 -    querystr =
  66.265 -        g_string_new
  66.266 -        ("SELECT DISTINCT program.chanid, program.starttime, program.endtime, "
  66.267 -         "    program.title, program.subtitle, program.description, "
  66.268 -         "    program.category, channel.channum, channel.callsign, "
  66.269 -         "    channel.name, program.previouslyshown, channel.commfree, "
  66.270 -         "    channel.outputfilters, program.seriesid, program.programid, "
  66.271 -         "    program.airdate, program.stars, program.originalairdate, "
  66.272 -         "    program.category_type, record.recordid, "
  66.273 -         "    oldrecstatus.rectype, oldrecstatus.recstatus, "
  66.274 -         "    oldrecstatus.findid "
  66.275 -         "FROM program "
  66.276 -         "LEFT JOIN channel ON program.chanid = channel.chanid "
  66.277 -         "LEFT JOIN record ON "
  66.278 -         "    program.chanid = record.chanid AND "
  66.279 -         "    DATE (program.starttime) = record.startdate AND "
  66.280 -         "    TIME (program.starttime) = record.starttime AND "
  66.281 -         "    DATE (program.endtime) = record.enddate AND "
  66.282 -         "    TIME (program.endtime) = record.endtime "
  66.283 -         "LEFT JOIN oldrecorded AS oldrecstatus ON "
  66.284 -         "    program.title = oldrecstatus.title AND "
  66.285 -         "    channel.callsign = oldrecstatus.station AND "
  66.286 -         "    program.starttime = oldrecstatus.starttime ");
  66.287 -
  66.288 -    g_string_append_printf(querystr,
  66.289 -                           "WHERE program.chanid = %d "
  66.290 -                           "  AND program.endtime >= '%s' "
  66.291 -                           "  AND program.starttime <= '%s' "
  66.292 -                           "  AND program.manualid = 0 ", chan_num,
  66.293 -                           startts, endts);
  66.294 -
  66.295 -    if (!g_strrstr(querystr->str, " GROUP BY "))
  66.296 -        querystr = g_string_append(querystr,
  66.297 -                                   " GROUP BY program.starttime, channel.channum, "
  66.298 -                                   "  channel.callsign, program.title ");
  66.299 -
  66.300 -    if (!g_strrstr(querystr->str, " LIMIT "))
  66.301 -        querystr = g_string_append(querystr, " LIMIT 1000 ");
  66.302 -
  66.303 -    MYSQL_RES      *res_set =
  66.304 -        gmyth_query_process_statement(gmyth_epg->sqlquery, querystr->str);
  66.305 -
  66.306 -    if (res_set == NULL) {
  66.307 -        gmyth_debug("[%s] msql query returned NULL MYSQL_RES",
  66.308 -                    __FUNCTION__);
  66.309 -        return -1;
  66.310 -    }
  66.311 -
  66.312 -    *proglist = NULL;
  66.313 -    while ((row = mysql_fetch_row(res_set)) != NULL) {
  66.314 -
  66.315 -        GMythProgramInfo *p = gmyth_program_info_new();
  66.316 -
  66.317 -        p->channel_id = (int) g_ascii_strtoull (row[0], NULL, 10);
  66.318 -
  66.319 -        p->startts = gmyth_util_string_to_time_val(row[1]);
  66.320 -        p->endts = gmyth_util_string_to_time_val(row[2]);
  66.321 -
  66.322 -        p->recstartts = g_new0(GTimeVal, 1);
  66.323 -        p->recstartts->tv_sec = p->startts->tv_sec;
  66.324 -        p->recstartts->tv_usec = p->startts->tv_usec;
  66.325 -
  66.326 -        p->recendts = g_new0(GTimeVal, 1);
  66.327 -        p->recendts->tv_sec = p->endts->tv_sec;
  66.328 -        p->recendts->tv_usec = p->endts->tv_usec;
  66.329 -
  66.330 -        p->lastmodified = g_new0(GTimeVal, 1);
  66.331 -        p->lastmodified->tv_sec = p->startts->tv_sec;
  66.332 -        p->lastmodified->tv_usec = p->startts->tv_usec;
  66.333 -
  66.334 -
  66.335 -        p->title = g_string_new(row[3]);
  66.336 -        p->subtitle = g_string_new(row[4]);
  66.337 -        p->description = g_string_new(row[5]);
  66.338 -        p->category = g_string_new(row[6]);
  66.339 -        p->chanstr = g_string_new(row[7]);
  66.340 -        p->chansign = g_string_new(row[8]);
  66.341 -        p->channame = g_string_new(row[9]);
  66.342 -        p->repeat = g_ascii_strtoull(row[10], NULL, 10);
  66.343 -        p->chancommfree = g_ascii_strtoull(row[11], NULL, 10);
  66.344 -        p->chanOutputFilters = g_string_new(row[12]);
  66.345 -        p->seriesid = g_string_new(row[13]);
  66.346 -        p->program_id = g_string_new(row[14]);
  66.347 -        p->year = g_string_new(row[15]);
  66.348 -        p->stars = g_ascii_strtod(row[16], NULL);
  66.349 -
  66.350 -        if (!row[17] || !strcmp(row[17], "")) {
  66.351 -            p->originalAirDate = 0;
  66.352 -            p->hasAirDate = FALSE;
  66.353 -        } else {
  66.354 -            p->originalAirDate = gmyth_util_string_to_time_val(row[17]);
  66.355 -            p->hasAirDate = TRUE;
  66.356 -        }
  66.357 -
  66.358 -        p->catType = g_string_new(row[18]);
  66.359 -        if (row[19] != NULL)
  66.360 -            p->recordid =  g_ascii_strtoull(row[19], NULL, 10);
  66.361 -
  66.362 -        *proglist = g_list_append(*proglist, p);
  66.363 -
  66.364 -#ifdef GMYTH_USE_DEBUG
  66.365 -        gmyth_program_info_print(p);
  66.366 -#endif
  66.367 -    }
  66.368 -
  66.369 -    /*
  66.370 -     * deallocate 
  66.371 -     */
  66.372 -    mysql_free_result(res_set);
  66.373 -    g_string_free(querystr, TRUE);
  66.374 -
  66.375 -    return g_list_length (*proglist);
  66.376 -}
  66.377 -
  66.378 -gboolean
  66.379 -gmyth_epg_channel_has_icon(GMythEPG * gmyth_epg,
  66.380 -                           GMythChannelInfo * channel_info)
  66.381 -{
  66.382 -    gboolean        res = FALSE;
  66.383 -
  66.384 -    g_return_val_if_fail(gmyth_epg != NULL, FALSE);
  66.385 -    g_return_val_if_fail(channel_info != NULL, FALSE);
  66.386 -
  66.387 -    if (channel_info->channel_icon != NULL) {
  66.388 -        res = gmyth_util_file_exists(gmyth_epg->backend_info,
  66.389 -                                     channel_info->channel_icon->str);
  66.390 -    }
  66.391 -
  66.392 -    return res;
  66.393 -
  66.394 -}
  66.395 -
  66.396 -/**
  66.397 - * 
  66.398 - * @param data the data pointer to be filled with icon binary data. It must be freed by the calling function.
  66.399 - * @return TRUE if success, FALSE if any error happens.
  66.400 - */
  66.401 -gboolean
  66.402 -gmyth_epg_channel_get_icon(GMythEPG * gmyth_epg,
  66.403 -                           GMythChannelInfo * channel_info, guint8 ** data,
  66.404 -                           guint * length)
  66.405 -{
  66.406 -    gboolean res = FALSE;
  66.407 -
  66.408 -    g_return_val_if_fail(gmyth_epg != NULL, FALSE);
  66.409 -    g_return_val_if_fail(channel_info != NULL, FALSE);
  66.410 -
  66.411 -    if (gmyth_epg_channel_has_icon(gmyth_epg, channel_info)) {
  66.412 -        GMythFileTransfer *transfer =
  66.413 -            gmyth_file_transfer_new(gmyth_epg->backend_info);
  66.414 -
  66.415 -        GMythFileReadResult gmyth_res;
  66.416 -        GByteArray *icon_data;
  66.417 -        guint64 icon_length = 0;
  66.418 -
  66.419 -        res = gmyth_file_transfer_open(transfer,
  66.420 -                                       channel_info->channel_icon->str);
  66.421 -        if (!res) {
  66.422 -            gmyth_debug("Channel icon could not be opened");
  66.423 -            return FALSE;
  66.424 -        }
  66.425 -
  66.426 -        icon_length = gmyth_file_transfer_get_filesize(transfer);
  66.427 -        if (icon_length <= 0) {
  66.428 -            gmyth_debug("Channel icon file size is zero or negative");
  66.429 -            return FALSE;
  66.430 -        }
  66.431 -
  66.432 -        icon_data = g_byte_array_new();
  66.433 -        gmyth_res = gmyth_file_transfer_read(transfer,
  66.434 -                                             icon_data,
  66.435 -                                             icon_length, FALSE);
  66.436 -        if (gmyth_res == GMYTH_FILE_READ_EOF) {
  66.437 -            *length = icon_length;
  66.438 -            *data = icon_data->data;
  66.439 -            g_byte_array_free(icon_data, FALSE);
  66.440 -            res = TRUE;
  66.441 -        } else {
  66.442 -            *length = 0;
  66.443 -            *data = NULL;
  66.444 -            g_byte_array_free(icon_data, TRUE);
  66.445 -        }
  66.446 -    }
  66.447 -
  66.448 -    return res;
  66.449 -}
    67.1 --- a/gmyth/src/gmyth_epg.h	Mon Feb 25 17:45:36 2008 +0000
    67.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.3 @@ -1,85 +0,0 @@
    67.4 -/**
    67.5 - * GMyth Library
    67.6 - *
    67.7 - * @file gmyth/gmyth_epg.h
    67.8 - * 
    67.9 - * @brief <p> GMythEPG class provides access to the program and channel data
   67.10 - * from the Electronic Program Guide (EPG) of the Mythtv backend.
   67.11 - *
   67.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   67.13 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   67.14 - * 
   67.15 - * This program is free software; you can redistribute it and/or modify
   67.16 - * it under the terms of the GNU Lesser General Public License as published by
   67.17 - * the Free Software Foundation; either version 2 of the License, or
   67.18 - * (at your option) any later version.
   67.19 - *
   67.20 - * This program is distributed in the hope that it will be useful,
   67.21 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   67.22 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   67.23 - * GNU General Public License for more details.
   67.24 - *
   67.25 - * You should have received a copy of the GNU Lesser General Public License
   67.26 - * along with this program; if not, write to the Free Software
   67.27 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   67.28 - */
   67.29 -
   67.30 -#ifndef GMYTH_EPG_H_
   67.31 -#define GMYTH_EPG_H_
   67.32 -
   67.33 -#include <glib-object.h>
   67.34 -
   67.35 -#include "gmyth_query.h"
   67.36 -#include "gmyth_common.h"
   67.37 -
   67.38 -G_BEGIN_DECLS
   67.39 -#define GMYTH_EPG_TYPE               (gmyth_epg_get_type ())
   67.40 -#define GMYTH_EPG(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_EPG_TYPE, GMythEPG))
   67.41 -#define GMYTH_EPG_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE, GMythEPGClass))
   67.42 -#define IS_GMYTH_EPG(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_EPG_TYPE))
   67.43 -#define IS_GMYTH_EPG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_EPG_TYPE))
   67.44 -#define GMYTH_EPG_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_EPG_TYPE, GMythEPGClass))
   67.45 -typedef struct _GMythEPG GMythEPG;
   67.46 -typedef struct _GMythEPGClass GMythEPGClass;
   67.47 -
   67.48 -struct _GMythEPGClass {
   67.49 -    GObjectClass    parent_class;
   67.50 -
   67.51 -    /*
   67.52 -     * callbacks 
   67.53 -     */
   67.54 -    /*
   67.55 -     * no one for now 
   67.56 -     */
   67.57 -};
   67.58 -
   67.59 -struct _GMythEPG {
   67.60 -    GObject         parent;
   67.61 -
   67.62 -    GMythQuery     *sqlquery;
   67.63 -    GMythBackendInfo *backend_info;
   67.64 -};
   67.65 -
   67.66 -GType           gmyth_epg_get_type              (void) G_GNUC_CONST;;
   67.67 -GMythEPG*       gmyth_epg_new                   (void);
   67.68 -gboolean        gmyth_epg_connect               (GMythEPG           *gmyth_epg,
   67.69 -                                                 GMythBackendInfo   *backend_info);
   67.70 -gboolean        gmyth_epg_disconnect            (GMythEPG           *gmyth_epg);
   67.71 -gint            gmyth_epg_get_channel_list      (GMythEPG           *gmyth_epg,
   67.72 -                                                 GList              **glist_ptr);
   67.73 -gint            gmyth_epg_get_program_list      (GMythEPG           *gmyth_epg,
   67.74 -                                                 GList              **proglist,
   67.75 -                                                 gint               chanNum,
   67.76 -                                                 GTimeVal           *starttime,
   67.77 -                                                 GTimeVal           *endtime);
   67.78 -GMythChannelInfo*gmyth_epg_get_channel_info     (GMythEPG           *gmyth_epg,
   67.79 -                                                 gint               channel_id);
   67.80 -gboolean        gmyth_epg_channel_has_icon      (GMythEPG           *gmyth_epg,
   67.81 -                                                 GMythChannelInfo   *channel);
   67.82 -gboolean        gmyth_epg_channel_get_icon      (GMythEPG           *gmyth_epg,
   67.83 -                                                 GMythChannelInfo   *channel,
   67.84 -                                                 guint8             **data, 
   67.85 -                                                 guint              *length);
   67.86 -
   67.87 -G_END_DECLS
   67.88 -#endif                          /* GMYTH_EPG_H_ */
    68.1 --- a/gmyth/src/gmyth_file.c	Mon Feb 25 17:45:36 2008 +0000
    68.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.3 @@ -1,515 +0,0 @@
    68.4 -/**
    68.5 - * GMyth Library
    68.6 - *
    68.7 - * @file gmyth/gmyth_file.c
    68.8 - * 
    68.9 - * @brief <p> GMythFile deals with the file streaming media remote/local
   68.10 - * transfering to the MythTV frontend.
   68.11 - *
   68.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   68.13 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   68.14 - *
   68.15 - * 
   68.16 - * This program is free software; you can redistribute it and/or modify
   68.17 - * it under the terms of the GNU Lesser General Public License as published by
   68.18 - * the Free Software Foundation; either version 2 of the License, or
   68.19 - * (at your option) any later version.
   68.20 - *
   68.21 - * This program is distributed in the hope that it will be useful,
   68.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   68.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   68.24 - * GNU General Public License for more details.
   68.25 - *
   68.26 - * You should have received a copy of the GNU Lesser General Public License
   68.27 - * along with this program; if not, write to the Free Software
   68.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   68.29 - */
   68.30 -
   68.31 -#ifdef HAVE_CONFIG_H
   68.32 -#include "config.h"
   68.33 -#endif
   68.34 -
   68.35 -#include "gmyth_file.h"
   68.36 -#include "gmyth_recorder.h"
   68.37 -#include "gmyth_util.h"
   68.38 -#include "gmyth_socket.h"
   68.39 -#include "gmyth_stringlist.h"
   68.40 -#include "gmyth_debug.h"
   68.41 -#include "gmyth_uri.h"
   68.42 -#include "gmyth_marshal.h"
   68.43 -
   68.44 -#include <unistd.h>
   68.45 -#include <glib.h>
   68.46 -
   68.47 -#include <arpa/inet.h>
   68.48 -#include <sys/types.h>
   68.49 -#include <sys/socket.h>
   68.50 -#include <netdb.h>
   68.51 -#include <errno.h>
   68.52 -#include <stdlib.h>
   68.53 -#include <assert.h>
   68.54 -
   68.55 -#define GMYTH_FILE_GET_PRIVATE(obj) \
   68.56 -	(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_FILE_TYPE, GMythFilePrivate))
   68.57 -
   68.58 -struct _GMythFilePrivate {
   68.59 -    gboolean        disposed;
   68.60 -    gint64          offset;
   68.61 -    guint64         filesize;
   68.62 -
   68.63 -    GMythBackendInfo *backend_info;
   68.64 -
   68.65 -    /*
   68.66 -     * Myth URI structure 
   68.67 -     */
   68.68 -    gchar          *filename;
   68.69 -
   68.70 -    gint            file_id;
   68.71 -};
   68.72 -
   68.73 -enum {
   68.74 -    PROP_GMYTH_FILE_DUMMY,
   68.75 -    PROP_GMYTH_FILE_FILENAME,
   68.76 -    PROP_GMYTH_FILE_OFFSET,
   68.77 -    PROP_GMYTH_FILE_FILESIZE,
   68.78 -    PROP_GMYTH_FILE_BACKEND_INFO,
   68.79 -    PROP_GMYTH_FILE_FILEID
   68.80 -};
   68.81 -
   68.82 -static void     gmyth_file_set_property(GObject * object, guint prop_id,
   68.83 -                                        const GValue * value,
   68.84 -                                        GParamSpec * pspec);
   68.85 -static void     gmyth_file_get_property(GObject * object, guint prop_id,
   68.86 -                                        GValue * value,
   68.87 -                                        GParamSpec * pspec);
   68.88 -
   68.89 -static void     gmyth_file_class_init(GMythFileClass * klass);
   68.90 -static void     gmyth_file_init(GMythFile * object);
   68.91 -static void     gmyth_file_dispose(GObject * object);
   68.92 -static void     gmyth_file_finalize(GObject * object);
   68.93 -
   68.94 -G_DEFINE_TYPE(GMythFile, gmyth_file, G_TYPE_OBJECT)
   68.95 -    static void     gmyth_file_class_init(GMythFileClass * klass)
   68.96 -{
   68.97 -    GObjectClass   *gobject_class;
   68.98 -    GMythFileClass *gtransfer_class;
   68.99 -
  68.100 -    gobject_class = (GObjectClass *) klass;
  68.101 -    gtransfer_class = (GMythFileClass *) gobject_class;
  68.102 -
  68.103 -    gobject_class->dispose = gmyth_file_dispose;
  68.104 -    gobject_class->finalize = gmyth_file_finalize;
  68.105 -
  68.106 -    gobject_class->set_property = gmyth_file_set_property;
  68.107 -    gobject_class->get_property = gmyth_file_get_property;
  68.108 -
  68.109 -    g_object_class_install_property
  68.110 -        (gobject_class, PROP_GMYTH_FILE_FILENAME,
  68.111 -         g_param_spec_string("filename", "filename",
  68.112 -                             "The file name.",
  68.113 -                             "",
  68.114 -                             G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
  68.115 -                             G_PARAM_STATIC_BLURB | G_PARAM_READABLE |
  68.116 -                             G_PARAM_WRITABLE));
  68.117 -
  68.118 -    g_object_class_install_property
  68.119 -        (gobject_class, PROP_GMYTH_FILE_OFFSET,
  68.120 -         g_param_spec_int64("file-offset", "file-offset",
  68.121 -                            "The offset (position) of this file", 0,
  68.122 -                            G_MAXINT64, 0,
  68.123 -                            G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
  68.124 -                            G_PARAM_STATIC_BLURB | G_PARAM_READABLE |
  68.125 -                            G_PARAM_WRITABLE));
  68.126 -
  68.127 -    g_object_class_install_property
  68.128 -        (gobject_class, PROP_GMYTH_FILE_FILESIZE,
  68.129 -         g_param_spec_uint64("file-size", "file-size",
  68.130 -                             "The file size in bytes",
  68.131 -                             0, G_MAXUINT64, 0,
  68.132 -                             G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
  68.133 -                             G_PARAM_STATIC_BLURB | G_PARAM_READABLE |
  68.134 -                             G_PARAM_WRITABLE));
  68.135 -
  68.136 -    g_object_class_install_property
  68.137 -        (gobject_class, PROP_GMYTH_FILE_BACKEND_INFO,
  68.138 -         g_param_spec_object("backend-info", "backend-info",
  68.139 -                             "The Backend Information about the remote server",
  68.140 -                             G_TYPE_OBJECT,
  68.141 -                             G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
  68.142 -                             G_PARAM_STATIC_BLURB | G_PARAM_READABLE |
  68.143 -                             G_PARAM_WRITABLE));
  68.144 -
  68.145 -    g_object_class_install_property
  68.146 -        (gobject_class, PROP_GMYTH_FILE_FILEID,
  68.147 -         g_param_spec_int("file-id", "file-id",
  68.148 -                          "The file ID", 0, G_MAXINT, 0,
  68.149 -                          G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
  68.150 -                          G_PARAM_STATIC_BLURB | G_PARAM_READABLE |
  68.151 -                          G_PARAM_WRITABLE));
  68.152 -
  68.153 -    g_type_class_add_private(gobject_class, sizeof(GMythFilePrivate));
  68.154 -
  68.155 -}
  68.156 -
  68.157 -static void
  68.158 -gmyth_file_init(GMythFile * file)
  68.159 -{
  68.160 -    g_return_if_fail(file != NULL);
  68.161 -
  68.162 -    file->priv = GMYTH_FILE_GET_PRIVATE(file);
  68.163 -}
  68.164 -
  68.165 -static void
  68.166 -gmyth_file_dispose(GObject * object)
  68.167 -{
  68.168 -    GMythFilePrivate *priv;
  68.169 -    GMythFile      *file = GMYTH_FILE(object);
  68.170 -
  68.171 -    g_return_if_fail(file != NULL);
  68.172 -
  68.173 -    priv = GMYTH_FILE_GET_PRIVATE(file);
  68.174 -
  68.175 -    if (priv->disposed) {
  68.176 -        /*
  68.177 -         * If dispose did already run, return. 
  68.178 -         */
  68.179 -        return;
  68.180 -    }
  68.181 -
  68.182 -    /*
  68.183 -     * Make sure dispose does not run twice. 
  68.184 -     */
  68.185 -    priv->disposed = TRUE;
  68.186 -
  68.187 -    if (priv->backend_info != NULL) {
  68.188 -        g_object_unref(priv->backend_info);
  68.189 -        priv->backend_info = NULL;
  68.190 -    }
  68.191 -
  68.192 -    if (priv->filename != NULL) {
  68.193 -        g_free(priv->filename);
  68.194 -        priv->filename = NULL;
  68.195 -    }
  68.196 -
  68.197 -    G_OBJECT_CLASS(gmyth_file_parent_class)->dispose(object);
  68.198 -}
  68.199 -
  68.200 -static void
  68.201 -gmyth_file_finalize(GObject * object)
  68.202 -{
  68.203 -    g_signal_handlers_destroy(object);
  68.204 -
  68.205 -    G_OBJECT_CLASS(gmyth_file_parent_class)->finalize(object);
  68.206 -}
  68.207 -
  68.208 -/** 
  68.209 - * Creates a new instance of GMythFile.
  68.210 - * 
  68.211 - * @param backend_info The BackendInfo instance, with all the MythTV network 
  68.212 - * 										 configuration data.
  68.213 - * 
  68.214 - * @return a new instance of the File Transfer. 
  68.215 - */
  68.216 -GMythFile      *
  68.217 -gmyth_file_new(GMythBackendInfo * backend_info)
  68.218 -{
  68.219 -    GMythFile      *file = NULL;
  68.220 -
  68.221 -    g_return_val_if_fail(backend_info != NULL, NULL);
  68.222 -
  68.223 -    GParameter     *__params = g_new0(GParameter, 1);
  68.224 -    GParameter     *__params_it = __params;
  68.225 -
  68.226 -    (__params_it->name =
  68.227 -     "backend-info", g_value_init(&__params_it->value, G_TYPE_OBJECT),
  68.228 -     g_value_set_object(&__params_it->value, backend_info), __params_it++);
  68.229 -    file =
  68.230 -        g_object_newv(GMYTH_FILE_TYPE, __params_it - __params, __params);
  68.231 -
  68.232 -    return file;
  68.233 -}
  68.234 -
  68.235 -gchar          *
  68.236 -gmyth_file_get_file_name(GMythFile * file)
  68.237 -{
  68.238 -    GMythFilePrivate *priv = GMYTH_FILE_GET_PRIVATE(file);
  68.239 -
  68.240 -    g_return_val_if_fail(file != NULL, NULL);
  68.241 -
  68.242 -    return priv->filename;
  68.243 -}
  68.244 -
  68.245 -void
  68.246 -gmyth_file_set_file_name(GMythFile * file, const gchar * filename)
  68.247 -{
  68.248 -    g_return_if_fail(file != NULL);
  68.249 -    g_return_if_fail(filename != NULL);
  68.250 -
  68.251 -    gchar          *__temp2 = NULL;
  68.252 -    const gchar    *__temp1 = NULL;
  68.253 -
  68.254 -    file->priv->filename = (__temp2 =
  68.255 -                            (__temp1 =
  68.256 -                             filename,
  68.257 -                             (__temp1 == NULL ? NULL : g_strdup(__temp1))),
  68.258 -                            (file->priv->filename ==
  68.259 -                             NULL ? NULL : (file->priv->filename =
  68.260 -                                            (g_free(file->priv->filename),
  68.261 -                                             NULL))), __temp2);
  68.262 -}
  68.263 -
  68.264 -/** 
  68.265 - * Creates a new instance of GMythFile.
  68.266 - * 
  68.267 - * @param uri_str The URI poiting to the MythTV backend server.
  68.268 - * 
  68.269 - * @return a new instance of the File Transfer. 
  68.270 - */
  68.271 -GMythFile      *
  68.272 -gmyth_file_new_with_uri(const gchar * uri_str)
  68.273 -{
  68.274 -    GMythFile      *file = GMYTH_FILE(g_object_new(GMYTH_FILE_TYPE, NULL));
  68.275 -    GMythFilePrivate *priv = GMYTH_FILE_GET_PRIVATE(file);
  68.276 -
  68.277 -    priv->backend_info = gmyth_backend_info_new_with_uri(uri_str);
  68.278 -    return file;
  68.279 -}
  68.280 -
  68.281 -/** 
  68.282 - * Open a File Transfer connection in order to get a remote file.
  68.283 - * 
  68.284 - * @param file The actual File Transfer instance. 
  68.285 - * @param filename The file name of the remote file to be transfered to the client.
  68.286 - * 
  68.287 - * @return <code>true</code>, if the connection opening had been done successfully. 
  68.288 - */
  68.289 -gboolean
  68.290 -gmyth_file_setup(GMythFile * file, const gchar * filename)
  68.291 -{
  68.292 -    gboolean        ret = TRUE;
  68.293 -    GMythFilePrivate *priv;
  68.294 -
  68.295 -    g_return_val_if_fail(file != NULL, FALSE);
  68.296 -    g_return_val_if_fail(filename != NULL && strlen(filename) > 0, FALSE);
  68.297 -
  68.298 -    priv = GMYTH_FILE_GET_PRIVATE(file);
  68.299 -
  68.300 -    if (priv->filename != NULL) {
  68.301 -        gmyth_file_close(file);
  68.302 -    }
  68.303 -
  68.304 -    priv->filename = g_strdup(filename);
  68.305 -
  68.306 -    return ret;
  68.307 -}
  68.308 -
  68.309 -/** 
  68.310 - * Closes a remote File Transfer connection.
  68.311 - * 
  68.312 - * @param file The actual File Transfer instance. 
  68.313 - */
  68.314 -void
  68.315 -gmyth_file_close(GMythFile * file)
  68.316 -{
  68.317 -    GMythFilePrivate *priv;
  68.318 -
  68.319 -    priv = GMYTH_FILE_GET_PRIVATE(file);
  68.320 -
  68.321 -    if (priv->filename) {
  68.322 -        g_free(priv->filename);
  68.323 -        priv->filename = NULL;
  68.324 -    }
  68.325 -
  68.326 -}
  68.327 -
  68.328 -/** 
  68.329 - * Gets the actual file size of the binary content.
  68.330 - * 
  68.331 - * @param file The actual File Transfer instance.
  68.332 - * 
  68.333 - * @return The actual file size in bytes. 
  68.334 - */
  68.335 -guint64
  68.336 -gmyth_file_get_filesize(GMythFile * file)
  68.337 -{
  68.338 -    GMythFilePrivate *priv;
  68.339 -
  68.340 -    g_return_val_if_fail(file != NULL, 0);
  68.341 -
  68.342 -    priv = GMYTH_FILE_GET_PRIVATE(file);
  68.343 -    return priv->filesize;
  68.344 -}
  68.345 -
  68.346 -/** 
  68.347 - * Sets the actual file size.
  68.348 - * 
  68.349 - * @param file The actual File Transfer instance.
  68.350 - * @param filesize The actual File Transfer size, in bytes.
  68.351 - */
  68.352 -void
  68.353 -gmyth_file_set_filesize(GMythFile * file, guint64 filesize)
  68.354 -{
  68.355 -    GMythFilePrivate *priv;
  68.356 -
  68.357 -    priv = GMYTH_FILE_GET_PRIVATE(file);
  68.358 -
  68.359 -    priv->filesize = filesize;
  68.360 -}
  68.361 -
  68.362 -/** 
  68.363 - * Gets the actual offset of the binary content.
  68.364 - * 
  68.365 - * @param file The actual File Transfer instance.
  68.366 - * 
  68.367 - * @return The actual file offset in bytes. 
  68.368 - */
  68.369 -gint64
  68.370 -gmyth_file_get_offset(GMythFile * file)
  68.371 -{
  68.372 -    g_return_val_if_fail(file != NULL, 0);
  68.373 -
  68.374 -    return file->priv->offset;
  68.375 -}
  68.376 -
  68.377 -/**
  68.378 - * Sets the actual file offset.
  68.379 - * 
  68.380 - * @param file The actual File instance.
  68.381 - * @param filesize The actual File offset, in bytes.
  68.382 - */
  68.383 -void
  68.384 -gmyth_file_set_offset(GMythFile * file, gint64 offset)
  68.385 -{
  68.386 -    GMythFilePrivate *priv;
  68.387 -
  68.388 -    priv = GMYTH_FILE_GET_PRIVATE(file);
  68.389 -
  68.390 -    priv->offset = offset;
  68.391 -}
  68.392 -
  68.393 -gchar          *
  68.394 -gmyth_file_get_uri(GMythFile * file)
  68.395 -{
  68.396 -    GMythFilePrivate *priv = GMYTH_FILE_GET_PRIVATE(file);
  68.397 -    gchar          *uri = NULL;
  68.398 -
  68.399 -    g_return_val_if_fail(file != NULL, NULL);
  68.400 -
  68.401 -    if (g_strstr_len(priv->filename, strlen(priv->filename), "://") !=
  68.402 -        NULL)
  68.403 -        uri = g_strdup(priv->filename);
  68.404 -    else
  68.405 -        uri =
  68.406 -            g_strdup_printf("myth://%s:%d/%s",
  68.407 -                            gmyth_backend_info_get_hostname(priv->
  68.408 -                                                            backend_info),
  68.409 -                            gmyth_backend_info_get_port(priv->
  68.410 -                                                        backend_info),
  68.411 -                            priv->filename);
  68.412 -
  68.413 -    return uri;
  68.414 -}
  68.415 -
  68.416 -static void
  68.417 -gmyth_file_set_property(GObject * object, guint prop_id,
  68.418 -                        const GValue * value, GParamSpec * pspec)
  68.419 -{
  68.420 -    GMythFilePrivate *priv = GMYTH_FILE_GET_PRIVATE(GMYTH_FILE(object));
  68.421 -
  68.422 -    switch (prop_id) {
  68.423 -    case PROP_GMYTH_FILE_FILENAME:
  68.424 -        {
  68.425 -            if (!g_value_get_string(value)) {
  68.426 -                break;
  68.427 -            }
  68.428 -
  68.429 -            if (priv->filename != NULL) {
  68.430 -                g_free(priv->filename);
  68.431 -                priv->filename = NULL;
  68.432 -            }
  68.433 -
  68.434 -            priv->filename = g_value_dup_string(value);
  68.435 -            gmyth_debug("Changed the filename to [%s]!", priv->filename);
  68.436 -            break;
  68.437 -        }
  68.438 -    case PROP_GMYTH_FILE_OFFSET:
  68.439 -        {
  68.440 -            priv->offset = g_value_get_int64(value);
  68.441 -            break;
  68.442 -        }
  68.443 -    case PROP_GMYTH_FILE_FILESIZE:
  68.444 -        {
  68.445 -            priv->filesize = g_value_get_uint64(value);
  68.446 -            break;
  68.447 -        }
  68.448 -    case PROP_GMYTH_FILE_BACKEND_INFO:
  68.449 -        {
  68.450 -            if (!g_value_get_object(value)) {
  68.451 -                break;
  68.452 -            }
  68.453 -
  68.454 -            if (priv->backend_info != NULL) {
  68.455 -                g_object_unref(priv->backend_info);
  68.456 -                priv->backend_info = NULL;
  68.457 -            }
  68.458 -
  68.459 -            priv->backend_info = g_value_get_object(value);
  68.460 -            gmyth_debug("Changed the backend info to [%s]!",
  68.461 -                        gmyth_backend_info_get_hostname(priv->
  68.462 -                                                        backend_info));
  68.463 -            break;
  68.464 -        }
  68.465 -    case PROP_GMYTH_FILE_FILEID:
  68.466 -        {
  68.467 -            priv->file_id = g_value_get_int(value);
  68.468 -            break;
  68.469 -        }
  68.470 -
  68.471 -    default:
  68.472 -        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
  68.473 -        break;
  68.474 -    }
  68.475 -
  68.476 -}
  68.477 -
  68.478 -static void
  68.479 -gmyth_file_get_property(GObject * object, guint prop_id,
  68.480 -                        GValue * value, GParamSpec * pspec)
  68.481 -{
  68.482 -    GMythFilePrivate *priv = GMYTH_FILE_GET_PRIVATE(GMYTH_FILE(object));
  68.483 -
  68.484 -    switch (prop_id) {
  68.485 -    case PROP_GMYTH_FILE_FILENAME:
  68.486 -        {
  68.487 -            gmyth_debug("Got the filename to [%s]!", priv->filename);
  68.488 -            g_value_set_string(value, priv->filename);
  68.489 -            break;
  68.490 -        }
  68.491 -    case PROP_GMYTH_FILE_OFFSET:
  68.492 -        {
  68.493 -            g_value_set_int64(value, priv->offset);
  68.494 -            break;
  68.495 -        }
  68.496 -    case PROP_GMYTH_FILE_FILESIZE:
  68.497 -        {
  68.498 -            g_value_set_uint64(value, priv->filesize);
  68.499 -            break;
  68.500 -        }
  68.501 -    case PROP_GMYTH_FILE_BACKEND_INFO:
  68.502 -        {
  68.503 -            g_value_set_object(value, priv->backend_info);
  68.504 -            break;
  68.505 -        }
  68.506 -    case PROP_GMYTH_FILE_FILEID:
  68.507 -        {
  68.508 -            g_value_set_int(value, priv->file_id);
  68.509 -            break;
  68.510 -        }
  68.511 -    default:
  68.512 -        {
  68.513 -            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
  68.514 -            break;
  68.515 -        }
  68.516 -    }
  68.517 -
  68.518 -}
    69.1 --- a/gmyth/src/gmyth_file.h	Mon Feb 25 17:45:36 2008 +0000
    69.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.3 @@ -1,90 +0,0 @@
    69.4 -/**
    69.5 - * GMyth Library
    69.6 - *
    69.7 - * @file gmyth/gmyth_file.h
    69.8 - * 
    69.9 - * @brief <p> GMythFile is the parent GMObject that deals with the file streaming 
   69.10 - * media remote/local transfering to the MythTV frontend.
   69.11 - *
   69.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   69.13 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   69.14 - *
   69.15 - * 
   69.16 - * This program is free software; you can redistribute it and/or modify
   69.17 - * it under the terms of the GNU Lesser General Public License as published by
   69.18 - * the Free Software Foundation; either version 2 of the License, or
   69.19 - * (at your option) any later version.
   69.20 - *
   69.21 - * This program is distributed in the hope that it will be useful,
   69.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   69.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   69.24 - * GNU General Public License for more details.
   69.25 - *
   69.26 - * You should have received a copy of the GNU Lesser General Public License
   69.27 - * along with this program; if not, write to the Free Software
   69.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   69.29 - */
   69.30 -
   69.31 -#ifndef __GMYTH_FILE_H__
   69.32 -#define __GMYTH_FILE_H__
   69.33 -
   69.34 -#include <glib-object.h>
   69.35 -#include <glib.h>
   69.36 -
   69.37 -#include "gmyth_uri.h"
   69.38 -#include "gmyth_backendinfo.h"
   69.39 -
   69.40 -#include <stdio.h>
   69.41 -#include <stdlib.h>
   69.42 -#include <string.h>
   69.43 -#include <netdb.h>
   69.44 -#include <sys/socket.h>
   69.45 -#include <unistd.h>
   69.46 -
   69.47 -G_BEGIN_DECLS
   69.48 -#define GMYTH_FILE_TYPE               (gmyth_file_get_type ())
   69.49 -#define GMYTH_FILE(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_FILE_TYPE, GMythFile))
   69.50 -#define GMYTH_FILE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TYPE, GMythFileClass))
   69.51 -#define IS_GMYTH_FILE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_FILE_TYPE))
   69.52 -#define IS_GMYTH_FILE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TYPE))
   69.53 -#define GMYTH_FILE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_FILE_TYPE, GMythFileClass))
   69.54 -
   69.55 -typedef enum {
   69.56 -    GMYTH_FILE_READ_OK = 0,
   69.57 -    GMYTH_FILE_READ_NEXT_PROG_CHAIN = 1,
   69.58 -    GMYTH_FILE_READ_ERROR = 2,
   69.59 -    GMYTH_FILE_READ_EOF = 3
   69.60 -} GMythFileReadResult;
   69.61 -
   69.62 -typedef struct _GMythFile GMythFile;
   69.63 -typedef struct _GMythFileClass GMythFileClass;
   69.64 -typedef struct _GMythFilePrivate GMythFilePrivate;
   69.65 -
   69.66 -struct _GMythFile {
   69.67 -    GObject         parent;
   69.68 -    GMythFilePrivate *priv;
   69.69 -};
   69.70 -
   69.71 -struct _GMythFileClass {
   69.72 -    GObjectClass    parent_class;
   69.73 -};
   69.74 -
   69.75 -GType           gmyth_file_get_type                 (void);
   69.76 -GMythFile      *gmyth_file_new                      (GMythBackendInfo   *backend_info);
   69.77 -gchar          *gmyth_file_get_file_name            (GMythFile          *file);
   69.78 -void            gmyth_file_set_file_name            (GMythFile          *file,
   69.79 -                                                     const gchar        *filename);
   69.80 -gboolean        gmyth_file_setup                    (GMythFile          *file, 
   69.81 -                                                     const gchar        *filename);
   69.82 -void            gmyth_file_close                    (GMythFile          *file);
   69.83 -gboolean        gmyth_file_is_open                  (GMythFile          *file);
   69.84 -guint64         gmyth_file_get_filesize             (GMythFile          *file);
   69.85 -void            gmyth_file_set_filesize             (GMythFile          *file,
   69.86 -                                                     guint64            filesize);
   69.87 -gint64          gmyth_file_get_offset               (GMythFile          *file);
   69.88 -void            gmyth_file_set_offset               (GMythFile          *file, 
   69.89 -                                                     gint64             offset);
   69.90 -gchar          *gmyth_file_get_uri                  (GMythFile          *file);
   69.91 -
   69.92 -G_END_DECLS
   69.93 -#endif                          /* __GMYTH_FILE_H__ */
    70.1 --- a/gmyth/src/gmyth_file_local.c	Mon Feb 25 17:45:36 2008 +0000
    70.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.3 @@ -1,464 +0,0 @@
    70.4 -/**
    70.5 - * GMyth Library
    70.6 - *
    70.7 - * @file_local gmyth/gmyth_file_local.c
    70.8 - * 
    70.9 - * @brief <p> GMythFileLocal deals with the file_local streaming media remote/local
   70.10 - * transfering to the MythTV frontend.
   70.11 - *
   70.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   70.13 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   70.14 - *
   70.15 - * 
   70.16 - * This program is free software; you can redistribute it and/or modify
   70.17 - * it under the terms of the GNU Lesser General Public License as published by
   70.18 - * the Free Software Foundation; either version 2 of the License, or
   70.19 - * (at your option) any later version.
   70.20 - *
   70.21 - * This program is distributed in the hope that it will be useful,
   70.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   70.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   70.24 - * GNU General Public License for more details.
   70.25 - *
   70.26 - * You should have received a copy of the GNU Lesser General Public License
   70.27 - * along with this program; if not, write to the Free Software
   70.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   70.29 - */
   70.30 -
   70.31 -#ifdef HAVE_CONFIG_H
   70.32 -#include "config.h"
   70.33 -#endif
   70.34 -
   70.35 -#include "gmyth_file_local.h"
   70.36 -#include "gmyth_recorder.h"
   70.37 -#include "gmyth_util.h"
   70.38 -#include "gmyth_socket.h"
   70.39 -#include "gmyth_stringlist.h"
   70.40 -#include "gmyth_debug.h"
   70.41 -#include "gmyth_uri.h"
   70.42 -#include "gmyth_marshal.h"
   70.43 -
   70.44 -#include <unistd.h>
   70.45 -#include <glib.h>
   70.46 -
   70.47 -#include <arpa/inet.h>
   70.48 -#include <sys/types.h>
   70.49 -#include <sys/socket.h>
   70.50 -#include <netdb.h>
   70.51 -#include <errno.h>
   70.52 -#include <stdlib.h>
   70.53 -#include <assert.h>
   70.54 -
   70.55 -#define GMYTH_FILE_LOCAL_GET_PRIVATE(obj) \
   70.56 -	(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_FILE_LOCAL_TYPE, GMythFileLocalPrivate))
   70.57 -
   70.58 -struct _GMythFileLocalPrivate {
   70.59 -
   70.60 -    gboolean        disposed;
   70.61 -
   70.62 -    GMutex         *mutex;
   70.63 -
   70.64 -    gint            fd;
   70.65 -
   70.66 -    GIOChannel     *file_io;
   70.67 -
   70.68 -};
   70.69 -
   70.70 -static void     gmyth_file_local_class_init(GMythFileLocalClass * klass);
   70.71 -static void     gmyth_file_local_init(GMythFileLocal * object);
   70.72 -static void     gmyth_file_local_dispose(GObject * object);
   70.73 -static void     gmyth_file_local_finalize(GObject * object);
   70.74 -
   70.75 -static gboolean _control_acquire_context(GMythFileLocal * file_local,
   70.76 -                                         gboolean do_wait);
   70.77 -
   70.78 -static gboolean _control_release_context(GMythFileLocal * file_local);
   70.79 -
   70.80 -G_DEFINE_TYPE(GMythFileLocal, gmyth_file_local, GMYTH_FILE_TYPE)
   70.81 -    static void     gmyth_file_local_class_init(GMythFileLocalClass *
   70.82 -                                                klass)
   70.83 -{
   70.84 -    GObjectClass   *gobject_class;
   70.85 -    GMythFileLocalClass *gtransfer_class;
   70.86 -
   70.87 -    gobject_class = (GObjectClass *) klass;
   70.88 -    gtransfer_class = (GMythFileLocalClass *) gobject_class;
   70.89 -
   70.90 -    gobject_class->dispose = gmyth_file_local_dispose;
   70.91 -    gobject_class->finalize = gmyth_file_local_finalize;
   70.92 -
   70.93 -    g_type_class_add_private(gobject_class, sizeof(GMythFileLocalPrivate));
   70.94 -
   70.95 -}
   70.96 -
   70.97 -static void
   70.98 -gmyth_file_local_init(GMythFileLocal * file_local)
   70.99 -{
  70.100 -    GMythFileLocalPrivate *priv;
  70.101 -
  70.102 -    g_return_if_fail(file_local != NULL);
  70.103 -
  70.104 -    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  70.105 -
  70.106 -    priv->mutex = g_mutex_new();
  70.107 -}
  70.108 -
  70.109 -static void
  70.110 -gmyth_file_local_dispose(GObject * object)
  70.111 -{
  70.112 -    GMythFileLocalPrivate *priv;
  70.113 -    GMythFileLocal *file_local = GMYTH_FILE_LOCAL(object);
  70.114 -
  70.115 -    g_return_if_fail(file_local != NULL);
  70.116 -
  70.117 -    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  70.118 -
  70.119 -    if (priv->disposed) {
  70.120 -        /*
  70.121 -         * If dispose did already run, return. 
  70.122 -         */
  70.123 -        return;
  70.124 -    }
  70.125 -
  70.126 -    /*
  70.127 -     * Make sure dispose does not run twice. 
  70.128 -     */
  70.129 -    priv->disposed = TRUE;
  70.130 -
  70.131 -    if (priv->mutex != NULL) {
  70.132 -        g_mutex_free(priv->mutex);
  70.133 -        priv->mutex = NULL;
  70.134 -    }
  70.135 -
  70.136 -    if (priv->file_io != NULL) {
  70.137 -        g_io_channel_unref(priv->file_io);
  70.138 -        priv->file_io = NULL;
  70.139 -    }
  70.140 -
  70.141 -    G_OBJECT_CLASS(gmyth_file_local_parent_class)->dispose(object);
  70.142 -}
  70.143 -
  70.144 -static void
  70.145 -gmyth_file_local_finalize(GObject * object)
  70.146 -{
  70.147 -    g_signal_handlers_destroy(object);
  70.148 -
  70.149 -    G_OBJECT_CLASS(gmyth_file_local_parent_class)->finalize(object);
  70.150 -}
  70.151 -
  70.152 -/** 
  70.153 - * Creates a new instance of GMythFileLocal.
  70.154 - * 
  70.155 - * @param backend_info The BackendInfo instance, with all the MythTV network 
  70.156 - * 										 configuration data.
  70.157 - * 
  70.158 - * @return a new instance of the File Transfer. 
  70.159 - */
  70.160 -GMythFileLocal *
  70.161 -gmyth_file_local_new(GMythBackendInfo * backend_info)
  70.162 -{
  70.163 -    GMythFileLocal *file_local =
  70.164 -        GMYTH_FILE_LOCAL(g_object_new(GMYTH_FILE_LOCAL_TYPE, NULL));
  70.165 -
  70.166 -    g_object_set(GMYTH_FILE(file_local), "backend-info", &backend_info,
  70.167 -                 NULL);
  70.168 -
  70.169 -    return file_local;
  70.170 -}
  70.171 -
  70.172 -/** 
  70.173 - * Creates a new instance of GMythFileLocal.
  70.174 - * 
  70.175 - * @param uri_str The URI poiting to the MythTV backend server.
  70.176 - * 
  70.177 - * @return a new instance of the File Transfer.
  70.178 - */
  70.179 -GMythFileLocal *
  70.180 -gmyth_file_local_new_with_uri(const gchar * uri_str)
  70.181 -{
  70.182 -    GMythFileLocal *file_local =
  70.183 -        GMYTH_FILE_LOCAL(g_object_new(GMYTH_FILE_LOCAL_TYPE, NULL));
  70.184 -    GMythURI       *uri = gmyth_uri_new_with_value(uri_str);
  70.185 -
  70.186 -    gmyth_debug("GMythURI path segment = %s", gmyth_uri_get_path(uri));
  70.187 -
  70.188 -    g_object_set(GMYTH_FILE(file_local),
  70.189 -                 "backend-info", gmyth_backend_info_new_with_uri(uri_str),
  70.190 -                 "filename", g_strdup(gmyth_uri_get_path(uri)), NULL);
  70.191 -
  70.192 -    g_object_unref(uri);
  70.193 -
  70.194 -    return file_local;
  70.195 -}
  70.196 -
  70.197 -gchar          *
  70.198 -gmyth_file_local_get_file_name(GMythFileLocal * file_local)
  70.199 -{
  70.200 -    return gmyth_file_get_file_name(GMYTH_FILE(file_local));
  70.201 -}
  70.202 -
  70.203 -void
  70.204 -gmyth_file_local_set_file_name(GMythFileLocal * file_local,
  70.205 -                               const gchar * filename)
  70.206 -{
  70.207 -    gmyth_file_set_file_name(GMYTH_FILE(file_local), filename);
  70.208 -}
  70.209 -
  70.210 -/** 
  70.211 - * Open a File in order to get a local file.
  70.212 - * 
  70.213 - * @param file_local The actual File Transfer instance. 
  70.214 - * 
  70.215 - * @return <code>true</code>, if the connection opening had been done successfully. 
  70.216 - */
  70.217 -gboolean
  70.218 -gmyth_file_local_open(GMythFileLocal * file_local)
  70.219 -{
  70.220 -    gboolean        ret = TRUE;
  70.221 -    GMythFileLocalPrivate *priv;
  70.222 -    gchar          *file_name_uri = NULL;
  70.223 -
  70.224 -    g_return_val_if_fail(file_local != NULL, FALSE);
  70.225 -
  70.226 -    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  70.227 -    file_name_uri = gmyth_file_local_get_file_name(file_local);
  70.228 -
  70.229 -    if (file_name_uri != NULL) {
  70.230 -        priv->file_io =
  70.231 -            g_io_channel_new_file(g_strdup(file_name_uri), "r+", NULL);
  70.232 -        g_free(file_name_uri);
  70.233 -    }
  70.234 -
  70.235 -    if (priv->file_io < 0)
  70.236 -        ret = FALSE;
  70.237 -
  70.238 -    return ret;
  70.239 -}
  70.240 -
  70.241 -/** 
  70.242 - * Closes a remote File Transfer connection.
  70.243 - * 
  70.244 - * @param file_local The actual File Transfer instance. 
  70.245 - */
  70.246 -void
  70.247 -gmyth_file_local_close(GMythFileLocal * file_local)
  70.248 -{
  70.249 -    g_return_if_fail(file_local != NULL);
  70.250 -}
  70.251 -
  70.252 -/** 
  70.253 - * Acquire access to a local file read/write pointer.
  70.254 - * 
  70.255 - * @param transfer The actual File Local instance.
  70.256 - * @param do_wait Waits or not on a GCond, when trying to read from the remote socket.
  70.257 - * 
  70.258 - * @return <code>true</code>, if the acquire had been got. 
  70.259 - */
  70.260 -static          gboolean
  70.261 -_control_acquire_context(GMythFileLocal * file_local, gboolean do_wait)
  70.262 -{
  70.263 -    gboolean        ret = TRUE;
  70.264 -    GMythFileLocalPrivate *priv;
  70.265 -
  70.266 -    g_return_val_if_fail(file_local != NULL, FALSE);
  70.267 -    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  70.268 -
  70.269 -    g_mutex_lock(priv->mutex);
  70.270 -    return ret;
  70.271 -}
  70.272 -
  70.273 -/** 
  70.274 - * Release access to a local file read/write pointer.
  70.275 - * 
  70.276 - * @param transfer The actual File Transfer instance.
  70.277 - * 
  70.278 - * @return <code>true</code>, if the local file read/write permissions had been releaseds. 
  70.279 - */
  70.280 -static          gboolean
  70.281 -_control_release_context(GMythFileLocal * file_local)
  70.282 -{
  70.283 -    gboolean        ret = TRUE;
  70.284 -    GMythFileLocalPrivate *priv;
  70.285 -
  70.286 -    g_return_val_if_fail(file_local != NULL, FALSE);
  70.287 -    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  70.288 -
  70.289 -    g_mutex_unlock(priv->mutex);
  70.290 -
  70.291 -    return ret;
  70.292 -}
  70.293 -
  70.294 -/** 
  70.295 - * Reads a block from a remote file.
  70.296 - * 
  70.297 - * @param transfer The actual File Transfer instance.
  70.298 - * @param data A GByteArray instance, where all the binary data representing 
  70.299 - *                       the remote file will be stored.
  70.300 - * @param size The block size, in bytes, to be requested from a remote file.
  70.301 - * @param read_unlimited Tells the backend to read indefinitely (LiveTV), or only 
  70.302 - *                                           gets the actual size
  70.303 - * 
  70.304 - * @return The actual block size (in bytes) returned by REQUEST_BLOCK message,
  70.305 - *              or the error code. 
  70.306 - */
  70.307 -GMythFileReadResult
  70.308 -gmyth_file_local_read(GMythFileLocal * file_local, GByteArray * data,
  70.309 -                      gint size, gboolean read_unlimited)
  70.310 -{
  70.311 -    gsize           bytes_read = 0;
  70.312 -    gint64          total_read = 0;
  70.313 -    GMythFileReadResult retval = GMYTH_FILE_READ_OK;
  70.314 -    GMythFileLocalPrivate *priv;
  70.315 -
  70.316 -    GError         *error = NULL;
  70.317 -
  70.318 -    GIOCondition    io_cond;
  70.319 -    GIOStatus       io_status = G_IO_STATUS_NORMAL;
  70.320 -
  70.321 -    g_return_val_if_fail(file_local != NULL, FALSE);
  70.322 -    g_return_val_if_fail(data != NULL, GMYTH_FILE_READ_ERROR);
  70.323 -
  70.324 -    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  70.325 -
  70.326 -    io_status = g_io_channel_set_encoding(priv->file_io, NULL, &error);
  70.327 -    if (io_status == G_IO_STATUS_NORMAL)
  70.328 -        gmyth_debug("Setting encoding to binary file data stream.\n");
  70.329 -
  70.330 -    io_cond = g_io_channel_get_buffer_condition(priv->file_io);
  70.331 -
  70.332 -    _control_acquire_context(file_local, TRUE);
  70.333 -
  70.334 -    if (size > 0) {
  70.335 -        gchar          *data_buffer = g_new0(gchar, size);
  70.336 -
  70.337 -        io_status = g_io_channel_read_chars(priv->file_io,
  70.338 -                                            data_buffer, (gsize) size,
  70.339 -                                            &bytes_read, &error);
  70.340 -
  70.341 -        if (io_status != G_IO_STATUS_NORMAL) {
  70.342 -            gmyth_debug("Error on io_channel");
  70.343 -            g_free(data_buffer);
  70.344 -            retval = GMYTH_FILE_READ_ERROR;
  70.345 -            goto error;
  70.346 -        }
  70.347 -
  70.348 -        /*
  70.349 -         * append new data to the increasing byte array 
  70.350 -         */
  70.351 -        data =
  70.352 -            g_byte_array_append(data, (const guint8 *) data_buffer,
  70.353 -                                bytes_read);
  70.354 -        total_read += bytes_read;
  70.355 -
  70.356 -        if (!read_unlimited
  70.357 -            && (gmyth_file_local_get_filesize(file_local) > 0)
  70.358 -            && (gmyth_file_local_get_offset(file_local) ==
  70.359 -                gmyth_file_local_get_filesize(file_local))) {
  70.360 -            retval = GMYTH_FILE_READ_EOF;
  70.361 -            goto error;
  70.362 -        }
  70.363 -
  70.364 -        g_free(data_buffer);
  70.365 -    } else {
  70.366 -        retval = GMYTH_FILE_READ_ERROR;
  70.367 -    }
  70.368 -
  70.369 -  error:
  70.370 -    _control_release_context(file_local);
  70.371 -
  70.372 -    if (error != NULL) {
  70.373 -        gmyth_debug("Cleaning-up ERROR: [msg = %s, code = %d]\n",
  70.374 -                    error->message, error->code);
  70.375 -        g_error_free(error);
  70.376 -    }
  70.377 -
  70.378 -    if (total_read > 0)
  70.379 -        gmyth_file_local_set_offset(file_local,
  70.380 -                                    (gmyth_file_local_get_offset
  70.381 -                                     (file_local) + total_read));
  70.382 -
  70.383 -    return retval;
  70.384 -}
  70.385 -
  70.386 -gint64
  70.387 -gmyth_file_local_seek(GMythFileLocal * file_local, gint64 pos,
  70.388 -                      GSeekType whence)
  70.389 -{
  70.390 -    GMythFileLocalPrivate *priv;
  70.391 -
  70.392 -    GError         *error;
  70.393 -
  70.394 -    GIOStatus       io_status = G_IO_STATUS_NORMAL;
  70.395 -
  70.396 -    g_return_val_if_fail(file_local != NULL, -1);
  70.397 -
  70.398 -    priv = GMYTH_FILE_LOCAL_GET_PRIVATE(file_local);
  70.399 -
  70.400 -    io_status =
  70.401 -        g_io_channel_seek_position(priv->file_io, pos, whence, &error);
  70.402 -
  70.403 -    if (io_status == G_IO_STATUS_ERROR)
  70.404 -        pos = -1;
  70.405 -
  70.406 -    return pos;
  70.407 -
  70.408 -}
  70.409 -
  70.410 -/** 
  70.411 - * Gets the actual file_local size of the binary content.
  70.412 - * 
  70.413 - * @param file_local The actual File Transfer instance.
  70.414 - * 
  70.415 - * @return The actual file_local size in bytes. 
  70.416 - */
  70.417 -guint64
  70.418 -gmyth_file_local_get_filesize(GMythFileLocal * file_local)
  70.419 -{
  70.420 -    g_return_val_if_fail(file_local != NULL, 0);
  70.421 -
  70.422 -    return gmyth_file_get_filesize(GMYTH_FILE(file_local));
  70.423 -}
  70.424 -
  70.425 -/** 
  70.426 - * Sets the actual file_local size.
  70.427 - * 
  70.428 - * @param file_local The actual File Transfer instance.
  70.429 - * @param filesize The actual File Transfer size, in bytes.
  70.430 - */
  70.431 -void
  70.432 -gmyth_file_local_set_filesize(GMythFileLocal * file_local,
  70.433 -                              guint64 filesize)
  70.434 -{
  70.435 -    g_return_if_fail(file_local != NULL);
  70.436 -
  70.437 -    gmyth_file_set_filesize(GMYTH_FILE(file_local), filesize);
  70.438 -}
  70.439 -
  70.440 -/** 
  70.441 - * Gets the actual file offset of the binary content.
  70.442 - * 
  70.443 - * @param file_local The actual File Transfer instance.
  70.444 - * 
  70.445 - * @return The actual file offset in bytes.
  70.446 - */
  70.447 -gint64
  70.448 -gmyth_file_local_get_offset(GMythFileLocal * file_local)
  70.449 -{
  70.450 -    g_return_val_if_fail(file_local != NULL, 0);
  70.451 -
  70.452 -    return gmyth_file_get_offset(GMYTH_FILE(file_local));
  70.453 -}
  70.454 -
  70.455 -/** 
  70.456 - * Sets the actual file offset.
  70.457 - * 
  70.458 - * @param file_local The actual File Local instance.
  70.459 - * @param offset The actual File Local offset, in bytes.
  70.460 - */
  70.461 -void
  70.462 -gmyth_file_local_set_offset(GMythFileLocal * file_local, gint64 offset)
  70.463 -{
  70.464 -    g_return_if_fail(file_local != NULL);
  70.465 -
  70.466 -    gmyth_file_set_offset(GMYTH_FILE(file_local), offset);
  70.467 -}
    71.1 --- a/gmyth/src/gmyth_file_local.h	Mon Feb 25 17:45:36 2008 +0000
    71.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.3 @@ -1,93 +0,0 @@
    71.4 -/**
    71.5 - * GMyth Library
    71.6 - *
    71.7 - * @file gmyth/gmyth_file_local_local.h
    71.8 - * 
    71.9 - * @brief <p> GMythFileLocal is the parent GMythFile that deals with the file streaming 
   71.10 - * media local transfering from the MythTV backend.
   71.11 - *
   71.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   71.13 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   71.14 - *
   71.15 - * 
   71.16 - * This program is free software; you can redistribute it and/or modify
   71.17 - * it under the terms of the GNU Lesser General Public License as published by
   71.18 - * the Free Software Foundation; either version 2 of the License, or
   71.19 - * (at your option) any later version.
   71.20 - *
   71.21 - * This program is distributed in the hope that it will be useful,
   71.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   71.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   71.24 - * GNU General Public License for more details.
   71.25 - *
   71.26 - * You should have received a copy of the GNU Lesser General Public License
   71.27 - * along with this program; if not, write to the Free Software
   71.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   71.29 - */
   71.30 -
   71.31 -#ifndef __GMYTH_FILE_LOCAL_H__
   71.32 -#define __GMYTH_FILE_LOCAL_H__
   71.33 -
   71.34 -#include <glib-object.h>
   71.35 -#include <glib.h>
   71.36 -
   71.37 -#include "gmyth_file.h"
   71.38 -#include "gmyth_uri.h"
   71.39 -#include "gmyth_backendinfo.h"
   71.40 -
   71.41 -#include <stdio.h>
   71.42 -#include <stdlib.h>
   71.43 -#include <string.h>
   71.44 -#include <netdb.h>
   71.45 -#include <sys/socket.h>
   71.46 -#include <unistd.h>
   71.47 -
   71.48 -G_BEGIN_DECLS
   71.49 -#define GMYTH_FILE_LOCAL_TYPE               (gmyth_file_local_get_type ())
   71.50 -#define GMYTH_FILE_LOCAL(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_FILE_LOCAL_TYPE, GMythFileLocal))
   71.51 -#define GMYTH_FILE_LOCAL_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_LOCAL_TYPE, GMythFileLocalClass))
   71.52 -#define IS_GMYTH_FILE_LOCAL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_FILE_LOCAL_TYPE))
   71.53 -#define IS_GMYTH_FILE_LOCAL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_LOCAL_TYPE))
   71.54 -#define GMYTH_FILE_LOCAL_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_FILE_LOCAL_TYPE, GMythFileLocalClass))
   71.55 -typedef struct _GMythFileLocal GMythFileLocal;
   71.56 -typedef struct _GMythFileLocalClass GMythFileLocalClass;
   71.57 -typedef struct _GMythFileLocalPrivate GMythFileLocalPrivate;
   71.58 -
   71.59 -struct _GMythFileLocal {
   71.60 -    GMythFile       parent;
   71.61 -};
   71.62 -
   71.63 -struct _GMythFileLocalClass {
   71.64 -    GMythFileClass  parent_class;
   71.65 -};
   71.66 -
   71.67 -
   71.68 -GType           gmyth_file_local_get_type(void);
   71.69 -GMythFileLocal *gmyth_file_local_new(GMythBackendInfo * backend_info);
   71.70 -GMythFileLocal *gmyth_file_local_new_with_uri(const gchar * uri);
   71.71 -gchar          *gmyth_file_local_get_file_name(GMythFileLocal *
   71.72 -                                               file_local);
   71.73 -void            gmyth_file_local_set_file_name(GMythFileLocal * file_local,
   71.74 -                                               const gchar * filename);
   71.75 -gboolean        gmyth_file_local_open(GMythFileLocal * file_local);
   71.76 -void            gmyth_file_local_close(GMythFileLocal * file_local);
   71.77 -gboolean        gmyth_file_local_is_open(GMythFileLocal * file_local);
   71.78 -
   71.79 -GMythFileReadResult
   71.80 -gmyth_file_local_read(GMythFileLocal * file_local,
   71.81 -                      GByteArray * data, gint size,
   71.82 -                      gboolean read_unlimited);
   71.83 -
   71.84 -gint64          gmyth_file_local_seek(GMythFileLocal * file_local,
   71.85 -                                      gint64 pos, GSeekType whence);
   71.86 -
   71.87 -guint64         gmyth_file_local_get_filesize(GMythFileLocal * file_local);
   71.88 -void            gmyth_file_local_set_filesize(GMythFileLocal * file,
   71.89 -                                              guint64 filesize);
   71.90 -
   71.91 -gint64          gmyth_file_local_get_offset(GMythFileLocal * file_local);
   71.92 -void            gmyth_file_local_set_offset(GMythFileLocal * file_local,
   71.93 -                                            gint64 offset);
   71.94 -
   71.95 -G_END_DECLS
   71.96 -#endif                          /* __GMYTH_FILE_LOCAL_H__ */
    72.1 --- a/gmyth/src/gmyth_file_transfer.c	Mon Feb 25 17:45:36 2008 +0000
    72.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.3 @@ -1,1014 +0,0 @@
    72.4 -/**
    72.5 - * GMyth Library
    72.6 - *
    72.7 - * @file gmyth/gmyth_file_transfer.c
    72.8 - * 
    72.9 - * @brief <p> GMythFileTransfer deals with the file streaming media remote/local
   72.10 - * transfering to the MythTV frontend.
   72.11 - *
   72.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   72.13 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   72.14 - *
   72.15 - * 
   72.16 - * This program is free software; you can redistribute it and/or modify
   72.17 - * it under the terms of the GNU Lesser General Public License as published by
   72.18 - * the Free Software Foundation; either version 2 of the License, or
   72.19 - * (at your option) any later version.
   72.20 - *
   72.21 - * This program is distributed in the hope that it will be useful,
   72.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   72.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   72.24 - * GNU General Public License for more details.
   72.25 - *
   72.26 - * You should have received a copy of the GNU Lesser General Public License
   72.27 - * along with this program; if not, write to the Free Software
   72.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   72.29 - *
   72.30 - * GStreamer MythTV plug-in properties:
   72.31 - * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv]
   72.32 - * - path (qurl - remote file to be opened)
   72.33 - * - port number *   
   72.34 - */
   72.35 -
   72.36 -#ifdef HAVE_CONFIG_H
   72.37 -#include "config.h"
   72.38 -#endif
   72.39 -
   72.40 -#include "gmyth_file_transfer.h"
   72.41 -#include "gmyth_recorder.h"
   72.42 -#include "gmyth_util.h"
   72.43 -#include "gmyth_socket.h"
   72.44 -#include "gmyth_stringlist.h"
   72.45 -#include "gmyth_debug.h"
   72.46 -#include "gmyth_uri.h"
   72.47 -#include "gmyth_marshal.h"
   72.48 -
   72.49 -#include <unistd.h>
   72.50 -#include <glib.h>
   72.51 -
   72.52 -#include <arpa/inet.h>
   72.53 -#include <sys/types.h>
   72.54 -#include <sys/socket.h>
   72.55 -#include <netdb.h>
   72.56 -#include <errno.h>
   72.57 -#include <stdlib.h>
   72.58 -#include <assert.h>
   72.59 -
   72.60 -#define GMYTHTV_QUERY_HEADER		"QUERY_FILETRANSFER "
   72.61 -
   72.62 -
   72.63 -#define GMYTH_FILE_TRANSFER_GET_PRIVATE(obj) \
   72.64 -	(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferPrivate))
   72.65 -
   72.66 -enum myth_sock_types {
   72.67 -    GMYTH_PLAYBACK_TYPE = 0,
   72.68 -    GMYTH_MONITOR_TYPE,
   72.69 -    GMYTH_FILETRANSFER_TYPE,
   72.70 -    GMYTH_RINGBUFFER_TYPE
   72.71 -};
   72.72 -
   72.73 -struct _GMythFileTransferPrivate {
   72.74 -    GMythRecorder  *recorder;
   72.75 -
   72.76 -    gboolean        do_next_program_chain;
   72.77 -    gboolean        disposed;
   72.78 -    gboolean        livetv_wait;
   72.79 -
   72.80 -    /*
   72.81 -     * MythTV version number 
   72.82 -     */
   72.83 -    gint            mythtv_version;
   72.84 -
   72.85 -    /*
   72.86 -     * socket descriptors 
   72.87 -     */
   72.88 -    GMythSocket    *control_sock;
   72.89 -    GMythSocket    *sock;
   72.90 -    GMutex         *mutex;
   72.91 -    gint            file_id;
   72.92 -};
   72.93 -
   72.94 -static void     gmyth_file_transfer_class_init(GMythFileTransferClass *
   72.95 -                                               klass);
   72.96 -static void     gmyth_file_transfer_init(GMythFileTransfer * object);
   72.97 -static void     gmyth_file_transfer_dispose(GObject * object);
   72.98 -static void     gmyth_file_transfer_finalize(GObject * object);
   72.99 -static void     _file_transfer_program_info_changed(GMythFileTransfer *
  72.100 -                                                    transfer,
  72.101 -                                                    gint msg_code,
  72.102 -                                                    gpointer
  72.103 -                                                    livetv_recorder);
  72.104 -static gboolean _connect_to_backend(GMythFileTransfer * transfer);
  72.105 -static gboolean _control_acquire_context(GMythFileTransfer * transfer,
  72.106 -                                         gboolean do_wait);
  72.107 -static gboolean _control_release_context(GMythFileTransfer * transfer);
  72.108 -
  72.109 -G_DEFINE_TYPE(GMythFileTransfer, gmyth_file_transfer, GMYTH_FILE_TYPE)
  72.110 -    static void     gmyth_file_transfer_class_init(GMythFileTransferClass *
  72.111 -                                                   klass)
  72.112 -{
  72.113 -    GObjectClass   *gobject_class;
  72.114 -    GMythFileTransferClass *gtransfer_class;
  72.115 -
  72.116 -    gobject_class = (GObjectClass *) klass;
  72.117 -    gtransfer_class = (GMythFileTransferClass *) gobject_class;
  72.118 -
  72.119 -    gobject_class->dispose = gmyth_file_transfer_dispose;
  72.120 -    gobject_class->finalize = gmyth_file_transfer_finalize;
  72.121 -
  72.122 -    g_type_class_add_private(gobject_class,
  72.123 -                             sizeof(GMythFileTransferPrivate));
  72.124 -
  72.125 -    gtransfer_class->program_info_changed_handler =
  72.126 -        _file_transfer_program_info_changed;
  72.127 -
  72.128 -    gtransfer_class->program_info_changed_handler_signal_id =
  72.129 -        g_signal_new("program-info-changed",
  72.130 -                     G_TYPE_FROM_CLASS(gtransfer_class),
  72.131 -                     G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
  72.132 -                     G_SIGNAL_NO_HOOKS, 0, NULL, NULL,
  72.133 -                     gmyth_marshal_VOID__INT_POINTER, G_TYPE_NONE, 2,
  72.134 -                     G_TYPE_INT, G_TYPE_POINTER);
  72.135 -
  72.136 -}
  72.137 -
  72.138 -static void
  72.139 -gmyth_file_transfer_init(GMythFileTransfer * transfer)
  72.140 -{
  72.141 -    g_return_if_fail(transfer != NULL);
  72.142 -
  72.143 -    transfer->priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  72.144 -    transfer->priv->mutex = g_mutex_new();
  72.145 -
  72.146 -    g_signal_connect(G_OBJECT(transfer), "program-info-changed",
  72.147 -                     (GCallback) (GMYTH_FILE_TRANSFER_GET_CLASS
  72.148 -                         (transfer)->program_info_changed_handler),
  72.149 -                         NULL);
  72.150 -}
  72.151 -
  72.152 -static void
  72.153 -gmyth_file_transfer_dispose(GObject * object)
  72.154 -{
  72.155 -    GMythFileTransferPrivate *priv;
  72.156 -    GMythFileTransfer *transfer = GMYTH_FILE_TRANSFER(object);
  72.157 -
  72.158 -    g_return_if_fail(transfer != NULL);
  72.159 -
  72.160 -    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  72.161 -
  72.162 -    if (priv->disposed) {
  72.163 -        /*
  72.164 -         * If dispose did already run, return. 
  72.165 -         */
  72.166 -        return;
  72.167 -    }
  72.168 -
  72.169 -    /*
  72.170 -     * Make sure dispose does not run twice. 
  72.171 -     */
  72.172 -    priv->disposed = TRUE;
  72.173 -
  72.174 -    if (priv->mutex != NULL) {
  72.175 -        g_mutex_free(priv->mutex);
  72.176 -        priv->mutex = NULL;
  72.177 -    }
  72.178 -
  72.179 -    if (priv->control_sock != NULL) {
  72.180 -        g_object_unref(priv->control_sock);
  72.181 -        priv->control_sock = NULL;
  72.182 -    }
  72.183 -
  72.184 -    if (priv->sock != NULL) {
  72.185 -        g_object_unref(priv->sock);
  72.186 -        priv->sock = NULL;
  72.187 -    }
  72.188 -
  72.189 -    if (priv->recorder != NULL) {
  72.190 -        g_object_unref(priv->recorder);
  72.191 -        priv->recorder = NULL;
  72.192 -    }
  72.193 -
  72.194 -    G_OBJECT_CLASS(gmyth_file_transfer_parent_class)->dispose(object);
  72.195 -}
  72.196 -
  72.197 -static void
  72.198 -gmyth_file_transfer_finalize(GObject * object)
  72.199 -{
  72.200 -    g_signal_handlers_destroy(object);
  72.201 -
  72.202 -    G_OBJECT_CLASS(gmyth_file_transfer_parent_class)->finalize(object);
  72.203 -}
  72.204 -
  72.205 -/** 
  72.206 - * Creates a new instance of GMythFileTransfer.
  72.207 - * 
  72.208 - * @param backend_info The BackendInfo instance, with all the MythTV network 
  72.209 - * 										 configuration data.
  72.210 - * 
  72.211 - * @return a new instance of the File Transfer. 
  72.212 - */
  72.213 -GMythFileTransfer *
  72.214 -gmyth_file_transfer_new(GMythBackendInfo * backend_info)
  72.215 -{
  72.216 -    GMythFileTransfer *transfer = g_object_new(GMYTH_FILE_TRANSFER_TYPE,
  72.217 -                                               "backend-info",
  72.218 -                                               backend_info,
  72.219 -                                               NULL);
  72.220 -
  72.221 -    // GValue val = {0,}; 
  72.222 -    // backend_info = g_object_ref( backend_info );
  72.223 -    gmyth_debug("Creating FileTransfer BackendInfo hostname = %s",
  72.224 -                gmyth_backend_info_get_hostname(backend_info));
  72.225 -    // GMythBackendInfo *backend_info = gmyth_backend_info_new_with_uri
  72.226 -    // (uri_str);
  72.227 -    // g_value_init (&val, G_TYPE_OBJECT);
  72.228 -    // g_value_set_object (&val, backend_info); 
  72.229 -    // g_object_set (G_OBJECT (transfer), "backend-info", &val, NULL);
  72.230 -
  72.231 -    return transfer;
  72.232 -}
  72.233 -
  72.234 -gchar          *
  72.235 -gmyth_file_transfer_get_file_name(GMythFileTransfer * transfer)
  72.236 -{
  72.237 -    gchar          *filename;
  72.238 -
  72.239 -    g_object_get(G_OBJECT(transfer), "filename", &filename, NULL);
  72.240 -
  72.241 -    return filename;
  72.242 -}
  72.243 -
  72.244 -/** 
  72.245 - * Creates a new instance of GMythFileTransfer.
  72.246 - * 
  72.247 - * @param uri_str The URI poiting to the MythTV backend server.
  72.248 - * 
  72.249 - * @return a new instance of the File Transfer. 
  72.250 - */
  72.251 -GMythFileTransfer *
  72.252 -gmyth_file_transfer_new_with_uri(const gchar * uri_str)
  72.253 -{
  72.254 -    GMythFileTransfer *transfer =
  72.255 -        GMYTH_FILE_TRANSFER(g_object_new(GMYTH_FILE_TRANSFER_TYPE, NULL));
  72.256 -    gmyth_debug("URI str = %s", uri_str);
  72.257 -    // GMythBackendInfo *backend_info = gmyth_backend_info_new_with_uri
  72.258 -    // (uri_str);
  72.259 -    GValue          val = { 0, };
  72.260 -    g_value_init(&val, G_TYPE_OBJECT);
  72.261 -    g_value_set_object(&val, gmyth_backend_info_new_with_uri(uri_str));
  72.262 -    g_object_set(G_OBJECT(transfer), "backend-info", &val, NULL);
  72.263 -
  72.264 -    return transfer;
  72.265 -}
  72.266 -
  72.267 -/** 
  72.268 - * Open a File Transfer connection in order to get a remote file.
  72.269 - * 
  72.270 - * @param transfer The actual File Transfer instance. 
  72.271 - * @param filename The file name of the remote file to be transferred to the client.
  72.272 - * 
  72.273 - * @return <code>true</code>, if the connection opening had been done successfully. 
  72.274 - */
  72.275 -gboolean
  72.276 -gmyth_file_transfer_open(GMythFileTransfer * transfer,
  72.277 -                         const gchar * filename)
  72.278 -{
  72.279 -    gboolean        ret = TRUE;
  72.280 -    GMythFileTransferPrivate *priv;
  72.281 -
  72.282 -    g_return_val_if_fail(transfer != NULL, FALSE);
  72.283 -    g_return_val_if_fail(filename != NULL && strlen(filename) > 0, FALSE);
  72.284 -
  72.285 -    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  72.286 -
  72.287 -    gmyth_debug("Opening the FileTransfer... (%s)", filename);
  72.288 -
  72.289 -    g_object_set(GMYTH_FILE(transfer), "filename", filename, NULL);
  72.290 -
  72.291 -    /*
  72.292 -     * configure the control socket 
  72.293 -     */
  72.294 -    if (TRUE /* priv->control_sock == NULL */ ) {
  72.295 -        if (!_connect_to_backend(transfer)) {
  72.296 -            gmyth_debug("Connection to backend failed (Control Socket).");
  72.297 -            ret = FALSE;
  72.298 -        }
  72.299 -
  72.300 -        if (priv->do_next_program_chain) {
  72.301 -            priv->do_next_program_chain = FALSE;    // fixme
  72.302 -            gmyth_debug
  72.303 -                ("New file available before the current file was opened");
  72.304 -            GMythProgramInfo *prog_info =
  72.305 -                gmyth_recorder_get_current_program_info(priv->recorder);
  72.306 -
  72.307 -            if (prog_info != NULL && prog_info->pathname != NULL
  72.308 -                && strlen(prog_info->pathname->str) > 0
  72.309 -                && g_ascii_strcasecmp(prog_info->pathname->str,
  72.310 -                                      gmyth_file_get_file_name(GMYTH_FILE
  72.311 -                                                               (transfer)))
  72.312 -                != 0)
  72.313 -                ret =
  72.314 -                    gmyth_file_transfer_open(transfer,
  72.315 -                                             g_strrstr(prog_info->
  72.316 -                                                       pathname->str,
  72.317 -                                                       "/"));
  72.318 -
  72.319 -            if (prog_info != NULL)
  72.320 -                g_object_unref(prog_info);
  72.321 -
  72.322 -            if (!ret)
  72.323 -                gmyth_debug("Cannot change to the next program info!");
  72.324 -            else
  72.325 -                gmyth_debug("OK!!! MOVED to the next program info [%s]!",
  72.326 -                            gmyth_file_get_file_name(GMYTH_FILE
  72.327 -                                                     (transfer)));
  72.328 -
  72.329 -        } else {
  72.330 -            gmyth_debug
  72.331 -                ("None new file found. We continue with the same file opened before");
  72.332 -        }
  72.333 -
  72.334 -    } else {
  72.335 -        gmyth_debug("Remote transfer control socket already created.");
  72.336 -    }
  72.337 -
  72.338 -    gmyth_debug("Got file with size = %lld.\n",
  72.339 -                gmyth_file_get_filesize(GMYTH_FILE(transfer)));
  72.340 -
  72.341 -    return ret;
  72.342 -}
  72.343 -
  72.344 -/** 
  72.345 - * Connect a File Transfer binary client socket to a remote file.
  72.346 - * 
  72.347 - * @param transfer The actual File Transfer instance. 
  72.348 - * 
  72.349 - * @return <code>true</code>, if the connection had been configured successfully. 
  72.350 - */
  72.351 -static          gboolean
  72.352 -_connect_to_backend(GMythFileTransfer * transfer)
  72.353 -{
  72.354 -    GString        *base_str = NULL;
  72.355 -    GString        *hostname = NULL;
  72.356 -    GMythStringList *strlist = NULL;
  72.357 -    gboolean        ret = TRUE;
  72.358 -    GMythFileTransferPrivate *priv;
  72.359 -    GMythBackendInfo *backend_info;
  72.360 -
  72.361 -    g_return_val_if_fail(transfer != NULL, FALSE);
  72.362 -
  72.363 -    g_object_get(GMYTH_FILE(transfer), "backend-info", &backend_info,
  72.364 -                 NULL);
  72.365 -
  72.366 -    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  72.367 -    _control_acquire_context(transfer, TRUE);
  72.368 -
  72.369 -    /*
  72.370 -     * Creates the control socket 
  72.371 -     */
  72.372 -
  72.373 -    if (priv->control_sock != NULL) {
  72.374 -        g_object_unref(priv->control_sock);
  72.375 -        priv->control_sock = NULL;
  72.376 -    }
  72.377 -
  72.378 -    base_str = g_string_new("");
  72.379 -
  72.380 -    priv->control_sock = gmyth_socket_new();
  72.381 -    // Connects the socket, send Mythtv ANN command and verify Mythtv
  72.382 -    // protocol version 
  72.383 -    if (!gmyth_socket_connect_to_backend(priv->control_sock,
  72.384 -                                         backend_info->hostname,
  72.385 -                                         backend_info->port, TRUE)) {
  72.386 -
  72.387 -        _control_release_context(transfer);
  72.388 -        g_object_unref(priv->control_sock);
  72.389 -        priv->control_sock = NULL;
  72.390 -        return FALSE;
  72.391 -    }
  72.392 -
  72.393 -    /*
  72.394 -     * Creates the data socket 
  72.395 -     */
  72.396 -    if (priv->sock != NULL) {
  72.397 -        g_object_unref(priv->sock);
  72.398 -        priv->sock = NULL;
  72.399 -    }
  72.400 -
  72.401 -    priv->sock = gmyth_socket_new();
  72.402 -    gmyth_socket_connect(priv->sock, backend_info->hostname,
  72.403 -                         backend_info->port);
  72.404 -    gmyth_debug("Connecting file transfer... (%s, %d)",
  72.405 -                backend_info->hostname, backend_info->port);
  72.406 -
  72.407 -    strlist = gmyth_string_list_new();
  72.408 -    hostname = gmyth_socket_get_local_hostname();
  72.409 -    gmyth_debug("[%s] MythTV version (from backend) = %d.\n", __FUNCTION__,
  72.410 -                priv->control_sock->mythtv_version);
  72.411 -    if (priv->control_sock->mythtv_version > 26)
  72.412 -        g_string_printf(base_str, "ANN FileTransfer %s 1 -1",
  72.413 -                        hostname->str);
  72.414 -    else
  72.415 -        g_string_printf(base_str, "ANN FileTransfer %s", hostname->str);
  72.416 -
  72.417 -    gmyth_string_list_append_string(strlist, base_str);
  72.418 -    gmyth_string_list_append_char_array(strlist,
  72.419 -                                        gmyth_file_get_file_name(GMYTH_FILE
  72.420 -                                                                 (transfer)));
  72.421 -
  72.422 -    gmyth_socket_write_stringlist(priv->sock, strlist);
  72.423 -
  72.424 -    /*
  72.425 -     * MONITOR Handler - DVB TV Chain update messages!!! 
  72.426 -     */
  72.427 -
  72.428 -    gmyth_socket_read_stringlist(priv->sock, strlist);
  72.429 -
  72.430 -    /*
  72.431 -     * file identification used in future file transfer requests to
  72.432 -     * backend 
  72.433 -     */
  72.434 -    priv->file_id = gmyth_string_list_get_int(strlist, 1);
  72.435 -
  72.436 -    /*
  72.437 -     * Myth URI stream file size - decoded using two 8-bytes sequences (64 
  72.438 -     * bits/long long types) 
  72.439 -     */
  72.440 -    gmyth_file_set_filesize(GMYTH_FILE(transfer),
  72.441 -                            gmyth_string_list_get_int64(strlist, 2));
  72.442 -
  72.443 -    gmyth_debug("***** Received: recordernum = %d, filesize = %"
  72.444 -                G_GUINT64_FORMAT "\n", priv->file_id,
  72.445 -                gmyth_file_get_filesize(GMYTH_FILE(transfer)));
  72.446 -
  72.447 -    if (gmyth_file_get_filesize(GMYTH_FILE(transfer)) < 0) {
  72.448 -        gmyth_debug
  72.449 -            ("Got filesize equals to %llu is lesser than 0 [invalid stream file]\n",
  72.450 -             gmyth_file_get_filesize(GMYTH_FILE(transfer)));
  72.451 -        g_object_unref(priv->sock);
  72.452 -        priv->sock = NULL;
  72.453 -        ret = FALSE;
  72.454 -    }
  72.455 -
  72.456 -    _control_release_context(transfer);
  72.457 -
  72.458 -    if (strlist != NULL)
  72.459 -        g_object_unref(strlist);
  72.460 -
  72.461 -    if (base_str != NULL)
  72.462 -        g_string_free(base_str, TRUE);
  72.463 -
  72.464 -    if (hostname != NULL)
  72.465 -        g_string_free(hostname, TRUE);
  72.466 -
  72.467 -    return ret;
  72.468 -}
  72.469 -
  72.470 -/** 
  72.471 - * Receives a GObject signal coming from a LiveTV instance, all the time a 
  72.472 - * program info changes.
  72.473 - * 
  72.474 - * @param transfer The actual File Transfer instance. 
  72.475 - * @param msg_code The MythTV backend message status code.
  72.476 - * @param live_tv A pointer to the LiveTV instance. * 
  72.477 - */
  72.478 -void
  72.479 -gmyth_file_transfer_emit_program_info_changed_signal(GMythFileTransfer *
  72.480 -                                                     transfer,
  72.481 -                                                     gint msg_code,
  72.482 -                                                     gpointer
  72.483 -                                                     live_tv_recorder)
  72.484 -{
  72.485 -    gmyth_debug("Calling signal handler... [FILE_TRANSFER]");
  72.486 -
  72.487 -    g_signal_emit(transfer, GMYTH_FILE_TRANSFER_GET_CLASS(transfer)->program_info_changed_handler_signal_id, 0, /* details 
  72.488 -                                                                                                                 */
  72.489 -                  msg_code, live_tv_recorder);
  72.490 -
  72.491 -}
  72.492 -
  72.493 -/** 
  72.494 - * Checks if the actual File Transfer connection is open.
  72.495 - * 
  72.496 - * @param transfer The actual File Transfer instance. 
  72.497 - * 
  72.498 - * @return <code>true</code>, if the File Transfer connection is opened. 
  72.499 - */
  72.500 -gboolean
  72.501 -gmyth_file_transfer_is_open(GMythFileTransfer * transfer)
  72.502 -{
  72.503 -    GMythStringList *strlist;
  72.504 -    GMythFileTransferPrivate *priv;
  72.505 -    GString        *query;
  72.506 -
  72.507 -    g_return_val_if_fail(transfer != NULL, FALSE);
  72.508 -
  72.509 -    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  72.510 -    g_return_val_if_fail(priv->control_sock != NULL, FALSE);
  72.511 -    g_return_val_if_fail(priv->sock != NULL, FALSE);
  72.512 -
  72.513 -    _control_acquire_context(transfer, TRUE);
  72.514 -
  72.515 -    strlist = gmyth_string_list_new();
  72.516 -    query = g_string_new(GMYTHTV_QUERY_HEADER);
  72.517 -    g_string_append_printf(query, "%d", priv->file_id);
  72.518 -
  72.519 -    gmyth_string_list_append_string(strlist, query);
  72.520 -    gmyth_string_list_append_char_array(strlist, "IS_OPEN");
  72.521 -
  72.522 -    gmyth_socket_write_stringlist(priv->control_sock, strlist);
  72.523 -    gmyth_socket_read_stringlist(priv->control_sock, strlist);
  72.524 -
  72.525 -    _control_release_context(transfer);
  72.526 -
  72.527 -    g_string_free(query, TRUE);
  72.528 -    g_object_unref(strlist);
  72.529 -
  72.530 -    return (strlist != NULL && gmyth_string_list_get_int(strlist, 0) == 1);
  72.531 -}
  72.532 -
  72.533 -/** 
  72.534 - * Closes a remote File Transfer connection.
  72.535 - * 
  72.536 - * @param transfer The actual File Transfer instance. 
  72.537 - */
  72.538 -void
  72.539 -gmyth_file_transfer_close(GMythFileTransfer * transfer)
  72.540 -{
  72.541 -    GMythStringList *strlist;
  72.542 -    GMythFileTransferPrivate *priv;
  72.543 -    GString        *query;
  72.544 -
  72.545 -    g_return_if_fail(transfer != NULL);
  72.546 -
  72.547 -    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  72.548 -
  72.549 -    if (priv->control_sock == NULL)
  72.550 -        return;
  72.551 -
  72.552 -    _control_acquire_context(transfer, TRUE);
  72.553 -
  72.554 -    strlist = gmyth_string_list_new();
  72.555 -    query = g_string_new(GMYTHTV_QUERY_HEADER);
  72.556 -    g_string_append_printf(query, "%d", priv->file_id);
  72.557 -
  72.558 -    gmyth_string_list_append_string(strlist, query);
  72.559 -    gmyth_string_list_append_char_array(strlist, "DONE");
  72.560 -
  72.561 -    if (gmyth_socket_sendreceive_stringlist(priv->control_sock, strlist) <=
  72.562 -        0) {
  72.563 -        // fixme: time out???
  72.564 -        gmyth_debug("Remote file timeout.\n");
  72.565 -    }
  72.566 -
  72.567 -    g_string_free(query, TRUE);
  72.568 -    g_object_unref(strlist);
  72.569 -
  72.570 -    if (priv->sock) {
  72.571 -        g_object_unref(priv->sock);
  72.572 -        priv->sock = NULL;
  72.573 -    }
  72.574 -
  72.575 -    if (priv->control_sock) {
  72.576 -        g_object_unref(priv->control_sock);
  72.577 -        priv->control_sock = NULL;
  72.578 -    }
  72.579 -
  72.580 -    _control_release_context(transfer);
  72.581 -}
  72.582 -
  72.583 -/** 
  72.584 - * Do a seek operation (moves the read/write file pointer) on a remote file.
  72.585 - * 
  72.586 - * @param transfer The actual File Transfer instance. 
  72.587 - * @param pos The position to be moved in the remote file.
  72.588 - * @param whence Tells to what direction seek movement should be done.
  72.589 - * 
  72.590 - * @return The actual position on the remote file (after seek has been done). 
  72.591 - */
  72.592 -gint64
  72.593 -gmyth_file_transfer_seek(GMythFileTransfer * transfer, guint64 pos,
  72.594 -                         gint whence)
  72.595 -{
  72.596 -    GMythStringList *strlist = gmyth_string_list_new();
  72.597 -    GMythFileTransferPrivate *priv;
  72.598 -    GString        *query;
  72.599 -
  72.600 -    g_return_val_if_fail(transfer != NULL, FALSE);
  72.601 -    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  72.602 -
  72.603 -    g_return_val_if_fail(priv->sock != NULL, -1);
  72.604 -    g_return_val_if_fail(priv->control_sock != NULL, -1);
  72.605 -
  72.606 -    strlist = gmyth_string_list_new();
  72.607 -    query = g_string_new(GMYTHTV_QUERY_HEADER);
  72.608 -    g_string_append_printf(query, "%d", priv->file_id);
  72.609 -
  72.610 -    /*
  72.611 -     * myth_control_acquire_context( transfer, TRUE ); 
  72.612 -     */
  72.613 -
  72.614 -    gmyth_string_list_append_string(strlist, query);
  72.615 -    gmyth_string_list_append_char_array(strlist, "SEEK");
  72.616 -    gmyth_string_list_append_uint64(strlist, pos);
  72.617 -
  72.618 -    gmyth_string_list_append_int(strlist, whence);
  72.619 -
  72.620 -    if (pos > 0)
  72.621 -        gmyth_string_list_append_uint64(strlist, pos);
  72.622 -    else
  72.623 -        gmyth_string_list_append_uint64(strlist,
  72.624 -                                        gmyth_file_get_offset(GMYTH_FILE
  72.625 -                                                              (transfer)));
  72.626 -
  72.627 -    gmyth_socket_sendreceive_stringlist(priv->control_sock, strlist);
  72.628 -
  72.629 -    gint64          retval = gmyth_string_list_get_int64(strlist, 0);
  72.630 -
  72.631 -    gmyth_file_set_offset(GMYTH_FILE(transfer), retval);
  72.632 -    gmyth_debug("Got reading position pointer from the streaming = %lld\n",
  72.633 -                retval);
  72.634 -
  72.635 -    g_object_unref(strlist);
  72.636 -    g_string_free(query, TRUE);
  72.637 -
  72.638 -    /*
  72.639 -     * myth_control_release_context( transfer ); 
  72.640 -     */
  72.641 -
  72.642 -    return retval;
  72.643 -}
  72.644 -
  72.645 -/** 
  72.646 - * Acquire access to a remote file socket read/write pointer.
  72.647 - * 
  72.648 - * @param transfer The actual File Transfer instance.
  72.649 - * @param do_wait Waits or not on a GCond, when trying to read from the remote socket.
  72.650 - * 
  72.651 - * @return <code>true</code>, if the acquire had been got. 
  72.652 - */
  72.653 -static          gboolean
  72.654 -_control_acquire_context(GMythFileTransfer * transfer, gboolean do_wait)
  72.655 -{
  72.656 -    gboolean        ret = TRUE;
  72.657 -    GMythFileTransferPrivate *priv;
  72.658 -
  72.659 -    g_return_val_if_fail(transfer != NULL, FALSE);
  72.660 -    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  72.661 -
  72.662 -    g_mutex_lock(priv->mutex);
  72.663 -    return ret;
  72.664 -}
  72.665 -
  72.666 -/** 
  72.667 - * Release access to a remote file socket read/write pointer.
  72.668 - * 
  72.669 - * @param transfer The actual File Transfer instance.
  72.670 - * 
  72.671 - * @return <code>true</code>, if the socket read/write permissions had been releaseds. 
  72.672 - */
  72.673 -static          gboolean
  72.674 -_control_release_context(GMythFileTransfer * transfer)
  72.675 -{
  72.676 -    gboolean        ret = TRUE;
  72.677 -    GMythFileTransferPrivate *priv;
  72.678 -
  72.679 -    g_return_val_if_fail(transfer != NULL, FALSE);
  72.680 -    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  72.681 -
  72.682 -    g_mutex_unlock(priv->mutex);
  72.683 -
  72.684 -    return ret;
  72.685 -}
  72.686 -
  72.687 -/** 
  72.688 - * Reads a block from a remote file.
  72.689 - * 
  72.690 - * @param transfer The actual File Transfer instance.
  72.691 - * @param data A GByteArray instance, where all the binary data representing 
  72.692 - * 						 the remote file will be stored.
  72.693 - * @param size The block size, in bytes, to be requested from a remote file.
  72.694 - * @param read_unlimited Tells the backend to read indefinitely (LiveTV), or only 
  72.695 - * 			 gets the actual size
  72.696 - * 
  72.697 - * @return The actual block size (in bytes) returned by REQUEST_BLOCK message,
  72.698 - * 				or the error code. 
  72.699 - */
  72.700 -GMythFileReadResult
  72.701 -gmyth_file_transfer_read(GMythFileTransfer * transfer, GByteArray * data,
  72.702 -                         gint size, gboolean read_unlimited)
  72.703 -{
  72.704 -    gint            bytes_sent = 0;
  72.705 -    gsize           bytes_read = 0;
  72.706 -    gint64          total_read = 0;
  72.707 -    GMythFileReadResult retval = GMYTH_FILE_READ_OK;
  72.708 -    GMythFileTransferPrivate *priv;
  72.709 -
  72.710 -    GError         *error = NULL;
  72.711 -
  72.712 -    GIOChannel     *io_channel;
  72.713 -    GIOChannel     *io_channel_control;
  72.714 -
  72.715 -    GIOCondition    io_cond;
  72.716 -    GIOCondition    io_cond_control;
  72.717 -    GIOStatus       io_status = G_IO_STATUS_NORMAL;
  72.718 -    GIOStatus       io_status_control = G_IO_STATUS_NORMAL;
  72.719 -
  72.720 -    GMythStringList *strlist;
  72.721 -    GMythStringList *ret_strlist = NULL;
  72.722 -    gboolean        ret = TRUE;
  72.723 -    GString        *query;
  72.724 -
  72.725 -    g_return_val_if_fail(transfer != NULL, FALSE);
  72.726 -    g_return_val_if_fail(data != NULL, GMYTH_FILE_READ_ERROR);
  72.727 -
  72.728 -    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  72.729 -
  72.730 -    strlist = gmyth_string_list_new();
  72.731 -
  72.732 -    io_channel = priv->sock->sd_io_ch;
  72.733 -    io_channel_control = priv->control_sock->sd_io_ch;
  72.734 -
  72.735 -    io_status = g_io_channel_set_encoding(io_channel, NULL, &error);
  72.736 -    if (io_status == G_IO_STATUS_NORMAL)
  72.737 -        gmyth_debug("[%s] Setting encoding to binary data socket).\n",
  72.738 -                    __FUNCTION__);
  72.739 -
  72.740 -    io_cond = g_io_channel_get_buffer_condition(io_channel);
  72.741 -
  72.742 -    io_cond_control = g_io_channel_get_buffer_condition(io_channel);
  72.743 -    if (priv->sock == NULL || (io_status == G_IO_STATUS_ERROR)) {
  72.744 -        g_printerr
  72.745 -            ("gmyth_file_transfer_read(): Called with no raw socket.\n");
  72.746 -        return GMYTH_FILE_READ_ERROR;
  72.747 -    }
  72.748 -
  72.749 -    if (priv->control_sock == NULL
  72.750 -        || (io_status_control == G_IO_STATUS_ERROR)) {
  72.751 -        g_printerr
  72.752 -            ("gmyth_file_transfer_read(): Called with no control socket.\n");
  72.753 -        return GMYTH_FILE_READ_ERROR;
  72.754 -    }
  72.755 -
  72.756 -    query = g_string_new(GMYTHTV_QUERY_HEADER);
  72.757 -    g_string_append_printf(query, "%d", priv->file_id);
  72.758 -    gmyth_debug("[%s] Transfer_query = %s\n", __FUNCTION__, query->str);
  72.759 -
  72.760 -    _control_acquire_context(transfer, TRUE);
  72.761 -    // Do Read
  72.762 -    gmyth_string_list_append_char_array(strlist, query->str);
  72.763 -    gmyth_string_list_append_char_array(strlist, "REQUEST_BLOCK");
  72.764 -    gmyth_string_list_append_int(strlist, size - total_read);
  72.765 -
  72.766 -    guint           iter_count = 3;
  72.767 -
  72.768 -    do {
  72.769 -        bytes_sent = 0;
  72.770 -
  72.771 -        // Request the block to the backend
  72.772 -        gmyth_socket_write_stringlist(priv->control_sock, strlist);
  72.773 -
  72.774 -        if (ret_strlist != NULL)
  72.775 -            g_object_unref(ret_strlist);
  72.776 -
  72.777 -        ret_strlist = gmyth_string_list_new();
  72.778 -        // Receives the backand answer 
  72.779 -        gmyth_socket_read_stringlist(priv->control_sock, ret_strlist);
  72.780 -
  72.781 -        if (ret_strlist != NULL
  72.782 -            && gmyth_string_list_length(ret_strlist) > 0) {
  72.783 -            bytes_sent = gmyth_string_list_get_int(ret_strlist, 0); // -1
  72.784 -            // on
  72.785 -            // backend 
  72.786 -            // error
  72.787 -            gmyth_debug("[%s] got SENT buffer message = %d\n",
  72.788 -                        __FUNCTION__, bytes_sent);
  72.789 -        }
  72.790 -
  72.791 -        if (read_unlimited && (bytes_sent == 0)) {
  72.792 -            g_usleep(300);
  72.793 -        }
  72.794 -
  72.795 -        --iter_count;
  72.796 -
  72.797 -    }
  72.798 -    while (read_unlimited && (bytes_sent == 0) && iter_count > 0);
  72.799 -
  72.800 -    if (bytes_sent > 0) {
  72.801 -        gchar          *data_buffer = g_new0(gchar, bytes_sent);
  72.802 -
  72.803 -        io_status = g_io_channel_read_chars(io_channel,
  72.804 -                                            data_buffer,
  72.805 -                                            (gsize) bytes_sent,
  72.806 -                                            &bytes_read, &error);
  72.807 -
  72.808 -        if (io_status != G_IO_STATUS_NORMAL) {
  72.809 -            gmyth_debug("Error on io_channel");
  72.810 -            g_free(data_buffer);
  72.811 -            g_object_unref(strlist);
  72.812 -            retval = GMYTH_FILE_READ_ERROR;
  72.813 -            goto error;
  72.814 -        }
  72.815 -
  72.816 -        /*
  72.817 -         * append new data to the increasing byte array 
  72.818 -         */
  72.819 -        data =
  72.820 -            g_byte_array_append(data, (const guint8 *) data_buffer,
  72.821 -                                bytes_read);
  72.822 -        gmyth_file_set_offset(GMYTH_FILE(transfer),
  72.823 -                              gmyth_file_get_offset(GMYTH_FILE(transfer)) +
  72.824 -                              bytes_read);
  72.825 -
  72.826 -        if (!read_unlimited
  72.827 -            && (gmyth_file_get_filesize(GMYTH_FILE(transfer)) > 0)
  72.828 -            && (gmyth_file_get_offset(GMYTH_FILE(transfer)) ==
  72.829 -                gmyth_file_get_filesize(GMYTH_FILE(transfer)))) {
  72.830 -            retval = GMYTH_FILE_READ_EOF;
  72.831 -            goto error;
  72.832 -        }
  72.833 -
  72.834 -        g_free(data_buffer);
  72.835 -    } else {
  72.836 -        retval = GMYTH_FILE_READ_ERROR;
  72.837 -    }
  72.838 -
  72.839 -    if (strlist != NULL) {
  72.840 -        g_object_unref(strlist);
  72.841 -        strlist = NULL;
  72.842 -    }
  72.843 -
  72.844 -    if (ret_strlist != NULL) {
  72.845 -        g_object_unref(ret_strlist);
  72.846 -        ret_strlist = NULL;
  72.847 -    }
  72.848 -
  72.849 -    if (read_unlimited && (bytes_sent == 0)) {
  72.850 -        gmyth_debug("Trying to move to the next program chain...");
  72.851 -        if (priv->recorder != NULL && priv->do_next_program_chain) {
  72.852 -            priv->do_next_program_chain = FALSE;
  72.853 -            retval = GMYTH_FILE_READ_NEXT_PROG_CHAIN;
  72.854 -            GMythProgramInfo *prog_info =
  72.855 -                gmyth_recorder_get_current_program_info(priv->recorder);
  72.856 -
  72.857 -            gmyth_debug
  72.858 -                ("Comparing if the current prog. info = %s [strlen == %d] is equals to "
  72.859 -                 " %s [strlen == %d]...", prog_info->pathname->str,
  72.860 -                 strlen(prog_info->pathname->str),
  72.861 -                 gmyth_file_get_file_name(GMYTH_FILE(transfer)),
  72.862 -                 strlen(gmyth_file_get_file_name(GMYTH_FILE(transfer))));
  72.863 -
  72.864 -            if (prog_info != NULL && prog_info->pathname != NULL
  72.865 -                && strlen(prog_info->pathname->str) > 0
  72.866 -                && (NULL ==
  72.867 -                    g_strstr_len(prog_info->pathname->str,
  72.868 -                                 strlen(prog_info->pathname->str),
  72.869 -                                 gmyth_file_get_file_name(GMYTH_FILE
  72.870 -                                                          (transfer))))) {
  72.871 -                /*
  72.872 -                 * releasing context got at this function starting... 
  72.873 -                 */
  72.874 -                _control_release_context(transfer);
  72.875 -                ret =
  72.876 -                    gmyth_file_transfer_open(transfer,
  72.877 -                                             g_strrstr(prog_info->
  72.878 -                                                       pathname->str,
  72.879 -                                                       "/"));
  72.880 -                _control_acquire_context(transfer, TRUE);
  72.881 -                /*
  72.882 -                 * acquiring context released at this function stopping... 
  72.883 -                 */
  72.884 -
  72.885 -                if (prog_info != NULL)
  72.886 -                    g_object_unref(prog_info);
  72.887 -
  72.888 -                if (!ret)
  72.889 -                    gmyth_debug("Cannot change to the next program info!");
  72.890 -                else
  72.891 -                    gmyth_debug
  72.892 -                        ("OK!!! MOVED to the next program info [%s]!",
  72.893 -                         gmyth_file_get_file_name(GMYTH_FILE(transfer)));
  72.894 -            }
  72.895 -
  72.896 -        }
  72.897 -
  72.898 -    }
  72.899 -    /*
  72.900 -     * if 
  72.901 -     */
  72.902 -  error:
  72.903 -
  72.904 -    _control_release_context(transfer);
  72.905 -    g_string_free(query, TRUE);
  72.906 -
  72.907 -    if (error != NULL) {
  72.908 -        gmyth_debug("Cleaning-up ERROR: %s [msg = %s, code = %d]\n",
  72.909 -                    __FUNCTION__, error->message, error->code);
  72.910 -        g_error_free(error);
  72.911 -    }
  72.912 -
  72.913 -    if (total_read > 0)
  72.914 -        gmyth_file_set_offset(GMYTH_FILE(transfer),
  72.915 -                              gmyth_file_get_offset(GMYTH_FILE
  72.916 -                                                    (transfer)) +
  72.917 -                              total_read);
  72.918 -
  72.919 -    return retval;
  72.920 -}
  72.921 -
  72.922 -static void
  72.923 -_file_transfer_program_info_changed(GMythFileTransfer * transfer,
  72.924 -                                    gint msg_code,
  72.925 -                                    gpointer livetv_recorder)
  72.926 -{
  72.927 -    GMythRecorder  *recorder;
  72.928 -    GMythFileTransferPrivate *priv;
  72.929 -
  72.930 -    g_return_if_fail(transfer != NULL);
  72.931 -
  72.932 -    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  72.933 -
  72.934 -    recorder = GMYTH_RECORDER(livetv_recorder);
  72.935 -    gmyth_debug
  72.936 -        ("Program info changed! ( file transfer orig. = %p, ptr. = [%s] )",
  72.937 -         transfer, livetv_recorder != NULL ? "[NOT NULL]" : "[NULL]");
  72.938 -
  72.939 -    if (NULL != recorder) {
  72.940 -        gmyth_debug
  72.941 -            ("YES, the requested program info movement on the LiveTV transfer is authentical!");
  72.942 -    }
  72.943 -
  72.944 -    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  72.945 -    g_object_ref(recorder);
  72.946 -    priv->recorder = recorder;
  72.947 -    priv->do_next_program_chain = TRUE;
  72.948 -}
  72.949 -
  72.950 -/** 
  72.951 - * Sets the timeout flag of a file being transfered.
  72.952 - * 
  72.953 - * @param transfer The actual File Transfer instance.
  72.954 - * @param fast If this is <code>true</code>, sets the remote timeout to be as fast
  72.955 - * 						as possible.
  72.956 - * 
  72.957 - * @return <code>true</code>, if the acquire had been got. 
  72.958 - */
  72.959 -gboolean
  72.960 -gmyth_file_transfer_settimeout(GMythFileTransfer * transfer, gboolean fast)
  72.961 -{
  72.962 -    GMythFileTransferPrivate *priv;
  72.963 -    GMythStringList *strlist = NULL;
  72.964 -
  72.965 -    g_return_val_if_fail(transfer != NULL, FALSE);
  72.966 -
  72.967 -    priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer);
  72.968 -
  72.969 -    g_return_val_if_fail(priv->sock != NULL, FALSE);
  72.970 -    g_return_val_if_fail(priv->control_sock != NULL, FALSE);
  72.971 -
  72.972 -    _control_acquire_context(transfer, TRUE);
  72.973 -
  72.974 -    strlist = gmyth_string_list_new();
  72.975 -    gmyth_string_list_append_char_array(strlist, GMYTHTV_QUERY_HEADER);
  72.976 -    gmyth_string_list_append_char_array(strlist, "SET_TIMEOUT");
  72.977 -    gmyth_string_list_append_int(strlist, fast);
  72.978 -
  72.979 -    gint            strlist_len =
  72.980 -        gmyth_socket_sendreceive_stringlist(priv->control_sock,
  72.981 -                                            strlist);
  72.982 -
  72.983 -    if (strlist_len > 0)
  72.984 -        gmyth_debug("Yes, timeout was changed: %s.",
  72.985 -                    gmyth_string_list_get_char_array(strlist, 0));
  72.986 -    else
  72.987 -        gmyth_debug("Timeout cannot be changed!");
  72.988 -
  72.989 -    _control_release_context(transfer);
  72.990 -
  72.991 -    gmyth_debug("%s setting timeout flag of this file transfer = %s\n",
  72.992 -                strlist_len > 0 ? "Yes," : "NOT",
  72.993 -                fast ? "FAST" : "NOT FAST");
  72.994 -
  72.995 -    g_object_unref(strlist);
  72.996 -
  72.997 -    return TRUE;
  72.998 -}
  72.999 -
 72.1000 -/** 
 72.1001 - * Gets the actual file size of the binary content.
 72.1002 - * 
 72.1003 - * @param transfer The actual File Transfer instance.
 72.1004 - * 
 72.1005 - * @return The actual file size in bytes. 
 72.1006 - */
 72.1007 -guint64
 72.1008 -gmyth_file_transfer_get_filesize(GMythFileTransfer * transfer)
 72.1009 -{
 72.1010 -    guint64         filesize;
 72.1011 -
 72.1012 -    g_return_val_if_fail(transfer != NULL, 0);
 72.1013 -
 72.1014 -    g_object_get(GMYTH_FILE(transfer), "file-size", &filesize, NULL);
 72.1015 -
 72.1016 -    return filesize;
 72.1017 -}
    73.1 --- a/gmyth/src/gmyth_file_transfer.h	Mon Feb 25 17:45:36 2008 +0000
    73.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.3 @@ -1,111 +0,0 @@
    73.4 -/**
    73.5 - * GMyth Library
    73.6 - *
    73.7 - * @file gmyth/gmyth_file_transfer.h
    73.8 - * 
    73.9 - * @brief <p> GMythFileTransfer deals with the file streaming media remote/local
   73.10 - * transfering to the MythTV frontend.
   73.11 - *
   73.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   73.13 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   73.14 - *
   73.15 - * 
   73.16 - * This program is free software; you can redistribute it and/or modify
   73.17 - * it under the terms of the GNU Lesser General Public License as published by
   73.18 - * the Free Software Foundation; either version 2 of the License, or
   73.19 - * (at your option) any later version.
   73.20 - *
   73.21 - * This program is distributed in the hope that it will be useful,
   73.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   73.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   73.24 - * GNU General Public License for more details.
   73.25 - *
   73.26 - * You should have received a copy of the GNU Lesser General Public License
   73.27 - * along with this program; if not, write to the Free Software
   73.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   73.29 - */
   73.30 -
   73.31 -#ifndef __GMYTH_FILE_TRANSFER_H__
   73.32 -#define __GMYTH_FILE_TRANSFER_H__
   73.33 -
   73.34 -#include <glib-object.h>
   73.35 -#include <glib.h>
   73.36 -
   73.37 -#include "gmyth_file.h"
   73.38 -#include "gmyth_socket.h"
   73.39 -#include "gmyth_uri.h"
   73.40 -#include "gmyth_backendinfo.h"
   73.41 -
   73.42 -#include <stdio.h>
   73.43 -#include <stdlib.h>
   73.44 -#include <string.h>
   73.45 -#include <netdb.h>
   73.46 -#include <sys/socket.h>
   73.47 -#include <unistd.h>
   73.48 -
   73.49 -G_BEGIN_DECLS
   73.50 -#define GMYTH_FILE_TRANSFER_TYPE               (gmyth_file_transfer_get_type ())
   73.51 -#define GMYTH_FILE_TRANSFER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransfer))
   73.52 -#define GMYTH_FILE_TRANSFER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferClass))
   73.53 -#define IS_GMYTH_FILE_TRANSFER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_FILE_TRANSFER_TYPE))
   73.54 -#define IS_GMYTH_FILE_TRANSFER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TRANSFER_TYPE))
   73.55 -#define GMYTH_FILE_TRANSFER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferClass))
   73.56 -typedef struct _GMythFileTransfer GMythFileTransfer;
   73.57 -typedef struct _GMythFileTransferClass GMythFileTransferClass;
   73.58 -typedef struct _GMythFileTransferPrivate GMythFileTransferPrivate;
   73.59 -
   73.60 -struct _GMythFileTransfer {
   73.61 -    GMythFile       parent;
   73.62 -    GMythFileTransferPrivate *priv;
   73.63 -};
   73.64 -
   73.65 -struct _GMythFileTransferClass {
   73.66 -    GMythFileClass  parent_class;
   73.67 -
   73.68 -    /*
   73.69 -     * callbacks 
   73.70 -     */
   73.71 -    guint           program_info_changed_handler_signal_id;
   73.72 -
   73.73 -    /*
   73.74 -     * signal default handlers 
   73.75 -     */
   73.76 -    void            (*program_info_changed_handler) (GMythFileTransfer *
   73.77 -                                                     transfer,
   73.78 -                                                     gint msg_code,
   73.79 -                                                     gpointer
   73.80 -                                                     livetv_recorder);
   73.81 -};
   73.82 -
   73.83 -
   73.84 -GType           gmyth_file_transfer_get_type(void);
   73.85 -GMythFileTransfer *gmyth_file_transfer_new(GMythBackendInfo *
   73.86 -                                           backend_info);
   73.87 -gchar          *gmyth_file_transfer_get_file_name(GMythFileTransfer *
   73.88 -                                                  transfer);
   73.89 -gboolean        gmyth_file_transfer_open(GMythFileTransfer * transfer,
   73.90 -                                         const gchar * filename);
   73.91 -void            gmyth_file_transfer_close(GMythFileTransfer * transfer);
   73.92 -gboolean        gmyth_file_transfer_is_open(GMythFileTransfer * transfer);
   73.93 -
   73.94 -GMythFileReadResult
   73.95 -gmyth_file_transfer_read(GMythFileTransfer * transfer,
   73.96 -                         GByteArray * data, gint size,
   73.97 -                         gboolean read_unlimited);
   73.98 -gint64          gmyth_file_transfer_seek(GMythFileTransfer * transfer,
   73.99 -                                         guint64 pos, gint whence);
  73.100 -gboolean        gmyth_file_transfer_settimeout(GMythFileTransfer *
  73.101 -                                               transfer, gboolean fast);
  73.102 -guint64         gmyth_file_transfer_get_filesize(GMythFileTransfer *
  73.103 -                                                 transfer);
  73.104 -
  73.105 -void
  73.106 -                gmyth_file_transfer_emit_program_info_changed_signal(GMythFileTransfer *
  73.107 -                                                                     transfer,
  73.108 -                                                                     gint
  73.109 -                                                                     msg_code,
  73.110 -                                                                     gpointer
  73.111 -                                                                     live_tv_recorder);
  73.112 -
  73.113 -G_END_DECLS
  73.114 -#endif                          /* __GMYTH_FILE_TRANSFER_H__ */
    74.1 --- a/gmyth/src/gmyth_http.c	Mon Feb 25 17:45:36 2008 +0000
    74.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.3 @@ -1,1037 +0,0 @@
    74.4 -/**
    74.5 - * GMyth Library
    74.6 - *
    74.7 - * @file gmyth/gmyth_http.c
    74.8 - * 
    74.9 - * @brief <p> GMythHttp library provides a wrapper to access
   74.10 - * data from the database using http+xml
   74.11 - *
   74.12 - * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   74.13 - * @author Artur Duque de Souza <artur.souza@indt.org.br>
   74.14 - *
   74.15 - * 
   74.16 - * This program is free software; you can redistribute it and/or modify
   74.17 - * it under the terms of the GNU Lesser General Public License as published by
   74.18 - * the Free Software Foundation; either version 2 of the License, or
   74.19 - * (at your option) any later version.
   74.20 - *
   74.21 - * This program is distributed in the hope that it will be useful,
   74.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   74.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   74.24 - * GNU General Public License for more details.
   74.25 - *
   74.26 - * You should have received a copy of the GNU Lesser General Public License
   74.27 - * along with this program; if not, write to the Free Software
   74.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   74.29 - */
   74.30 -
   74.31 -#ifdef HAVE_CONFIG_H
   74.32 -#include "config.h"
   74.33 -#endif
   74.34 -
   74.35 -#include <assert.h>
   74.36 -#include <libxml/parser.h>
   74.37 -#include <libxml/tree.h>
   74.38 -#include <libxml/xpath.h>
   74.39 -#include <libxml/uri.h>
   74.40 -
   74.41 -#include "gmyth_http.h"
   74.42 -#include "gmyth_debug.h"
   74.43 -#include "gmyth_socket.h"
   74.44 -
   74.45 -xmlXPathObjectPtr
   74.46 -getnodeset(xmlDocPtr doc, xmlChar * xpath)
   74.47 -{
   74.48 -
   74.49 -    xmlXPathContextPtr context;
   74.50 -    xmlXPathObjectPtr result;
   74.51 -
   74.52 -    context = xmlXPathNewContext(doc);
   74.53 -    result = xmlXPathEvalExpression(xpath, context);
   74.54 -
   74.55 -    if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {
   74.56 -        g_fprintf(stderr, "Error: No result at XPath\n");
   74.57 -        return NULL;
   74.58 -    }
   74.59 -
   74.60 -    xmlXPathFreeContext(context);
   74.61 -    return result;
   74.62 -}
   74.63 -
   74.64 -
   74.65 -xmlDocPtr
   74.66 -XMLParse(const char *content, int length)
   74.67 -{
   74.68 -    xmlDocPtr       doc;        /* the resulting document tree */
   74.69 -
   74.70 -    doc = xmlReadMemory(content, length, NULL, NULL, 0);
   74.71 -    if (doc == NULL) {
   74.72 -        g_fprintf(stderr, "Error: Failed to parse XML document\n");
   74.73 -        return NULL;
   74.74 -    }
   74.75 -
   74.76 -    return doc;
   74.77 -}
   74.78 -
   74.79 -xmlXPathObjectPtr
   74.80 -getXPath(xmlChar * xpath, xmlDocPtr doc)
   74.81 -{
   74.82 -    xmlXPathObjectPtr result;
   74.83 -
   74.84 -    result = getnodeset(doc, xpath);
   74.85 -    return result;
   74.86 -}
   74.87 -
   74.88 -
   74.89 -/** Retrieves the Progam List from the Channel
   74.90 - *
   74.91 - * @param nodeTab A pointer to a node inside the XML
   74.92 - * @return A GSList containing a list of all the programs
   74.93 - */
   74.94 -GSList         *
   74.95 -get_Program_List(xmlNodePtr node)
   74.96 -{
   74.97 -    GSList         *program_list = NULL;
   74.98 -
   74.99 -    while (node != NULL) {
  74.100 -        if (g_ascii_strcasecmp((char *) node->name, "text") != 0) {
  74.101 -            GMythProgram   *program = (GMythProgram *)
  74.102 -                g_malloc(sizeof(struct _GMythProgram));
  74.103 -
  74.104 -            program->title = g_strdup((char *)
  74.105 -                                      xmlGetProp(node,
  74.106 -                                                 (xmlChar *) "title"));
  74.107 -
  74.108 -            program->subtitle = g_strdup((char *)
  74.109 -                                         xmlGetProp(node, (xmlChar *)
  74.110 -                                                    "subtitle"));
  74.111 -
  74.112 -            program->catType = g_strdup((char *)
  74.113 -                                        xmlGetProp(node, (xmlChar *)
  74.114 -                                                   "catType"));
  74.115 -
  74.116 -            program->category = g_strdup((char *)
  74.117 -                                         xmlGetProp(node, (xmlChar *)
  74.118 -                                                    "category"));
  74.119 -
  74.120 -            sscanf((char *) xmlGetProp(node, (xmlChar *) "repeat"),
  74.121 -                   "%d", &(program->repeat));
  74.122 -
  74.123 -            program->startTime = gmyth_util_string_to_time_val
  74.124 -                ((char *) xmlGetProp(node, (xmlChar *) "startTime"));
  74.125 -
  74.126 -            program->endTime = gmyth_util_string_to_time_val
  74.127 -                ((char *) xmlGetProp(node, (xmlChar *) "endTime"));
  74.128 -
  74.129 -            program_list = g_slist_append(program_list, program);
  74.130 -        }
  74.131 -
  74.132 -        node = node->next;
  74.133 -    }
  74.134 -
  74.135 -    return program_list;
  74.136 -}
  74.137 -
  74.138 -/** Retrieves the Channel List from the ProgramGuide
  74.139 - *
  74.140 - * @param node A pointer to a node inside the XML
  74.141 - * @param epg The struct where is the current epg
  74.142 - * @return The epg from "param" updated
  74.143 - */
  74.144 -void
  74.145 -get_Channel_List(xmlNodePtr node, GMythEpg * epg)
  74.146 -{
  74.147 -    epg->channelList = NULL;
  74.148 -
  74.149 -    while (node != NULL) {
  74.150 -
  74.151 -        if (g_ascii_strcasecmp((char *) node->name, "text") != 0) {
  74.152 -            GMythChannel   *channel = (GMythChannel *) g_malloc
  74.153 -                (sizeof(struct _GMythChannel));
  74.154 -
  74.155 -            channel->channelName = g_strdup((char *)
  74.156 -                                            xmlGetProp(node, (xmlChar *)
  74.157 -                                                       "channelName"));
  74.158 -
  74.159 -            channel->chanNum = g_strdup((char *)
  74.160 -                                        xmlGetProp(node, (xmlChar *)
  74.161 -                                                   "chanNum"));
  74.162 -
  74.163 -            sscanf((char *) xmlGetProp(node, (xmlChar *) "chanId"),
  74.164 -                   "%d", &(channel->chanId));
  74.165 -
  74.166 -            sscanf((char *) xmlGetProp(node, (xmlChar *) "callSign"),
  74.167 -                   "%d", &(channel->callSign));
  74.168 -
  74.169 -            channel->programList = get_Program_List(node->children);
  74.170 -
  74.171 -            epg->channelList = g_slist_append(epg->channelList, channel);
  74.172 -
  74.173 -        }
  74.174 -
  74.175 -        node = node->next;
  74.176 -    }
  74.177 -}
  74.178 -
  74.179 -/** Retrieves the properties from the ProgramGuide
  74.180 - *
  74.181 - * @param nodeTab A pointer to a node inside the XML
  74.182 - * @param epg The struct where is the current epg
  74.183 - * @return The epg from "param" updated
  74.184 - */
  74.185 -void
  74.186 -get_ProgramGuide_Properties(xmlNodePtr nodeTab, GMythEpg * epg)
  74.187 -{
  74.188 -
  74.189 -    xmlNode        *ptr = nodeTab->children->next->children;
  74.190 -
  74.191 -    epg->startTime = gmyth_util_string_to_time_val((char *) ptr->content);
  74.192 -
  74.193 -    ptr = ptr->parent->next->next->children;
  74.194 -    epg->endTime = gmyth_util_string_to_time_val((char *) ptr->content);
  74.195 -
  74.196 -    ptr = ptr->parent->next->next->children;
  74.197 -    sscanf((char *) ptr->content, "%d", &(epg->startChanId));
  74.198 -
  74.199 -    ptr = ptr->parent->next->next->children;
  74.200 -    sscanf((char *) ptr->content, "%d", &(epg->endChanId));
  74.201 -
  74.202 -    ptr = ptr->parent->next->next->children;
  74.203 -    sscanf((char *) ptr->content, "%d", &(epg->numOfChannels));
  74.204 -
  74.205 -    ptr = ptr->parent->next->next->children;
  74.206 -    sscanf((char *) ptr->content, "%d", &(epg->details));
  74.207 -
  74.208 -    ptr = ptr->parent->next->next->children;
  74.209 -    sscanf((char *) ptr->content, "%d", &(epg->totalCount));
  74.210 -
  74.211 -    ptr = ptr->parent->next->next->children;
  74.212 -    epg->asOf = gmyth_util_string_to_time_val((char *) ptr->content);
  74.213 -
  74.214 -    ptr = ptr->parent->next->next->children;
  74.215 -    epg->version = g_strdup((char *) ptr->content);
  74.216 -
  74.217 -    ptr = ptr->parent->next->next->children;
  74.218 -    sscanf((char *) ptr->content, "%d", &(epg->protoVer));
  74.219 -
  74.220 -    ptr = ptr->parent->next->next->children;
  74.221 -    // go to Channel section and retrieve Channels and Programs
  74.222 -    if (epg->numOfChannels > 0)
  74.223 -        get_Channel_List(ptr, epg);
  74.224 -    else
  74.225 -        epg->channelList = NULL;
  74.226 -}
  74.227 -
  74.228 -/** Aux function to retrieve the Eletronic Program Guide
  74.229 - *
  74.230 - * @param doc An XML document (xmlDocPtr)
  74.231 - * @return The epg
  74.232 - */
  74.233 -void
  74.234 -getEpg(xmlDocPtr doc, GMythEpg * epg)
  74.235 -{
  74.236 -    xmlXPathObjectPtr result;
  74.237 -    xmlNodeSetPtr   nodeset;
  74.238 -    xmlChar        *keyword;
  74.239 -
  74.240 -    int             i;
  74.241 -
  74.242 -    result = getXPath((xmlChar *) "/*", doc);
  74.243 -
  74.244 -    if (result) {
  74.245 -        nodeset = result->nodesetval;
  74.246 -        for (i = 0; i < nodeset->nodeNr; i++) {
  74.247 -            keyword = (xmlChar *) nodeset->nodeTab[i]->name;
  74.248 -            if (g_ascii_strcasecmp
  74.249 -                ((char *) keyword, "GetProgramGuideResponse") == 0) {
  74.250 -                get_ProgramGuide_Properties(nodeset->nodeTab[i], epg);
  74.251 -                break;
  74.252 -            }
  74.253 -        }
  74.254 -        xmlXPathFreeObject(result);
  74.255 -    }
  74.256 -
  74.257 -}
  74.258 -
  74.259 -
  74.260 -
  74.261 -/** Retrieves the Eletronic Program Guide from the backend
  74.262 - *
  74.263 - * @param doc An XML document (xmlDocPtr)
  74.264 - * @return The epg
  74.265 - */
  74.266 -GMythEpg
  74.267 -gmyth_http_retrieve_epg(GMythBackendInfo * backend_info,
  74.268 -                        GTimeVal * StartTime, GTimeVal * EndTime,
  74.269 -                        gint StartChanId, gint NumOfChannels,
  74.270 -                        gchar * Details)
  74.271 -{
  74.272 -    GMythEpg        epg;
  74.273 -    MemoryStruct    chunk;
  74.274 -
  74.275 -    chunk.memory = NULL;        /* we expect realloc(NULL, size) to work */
  74.276 -    chunk.size = 0;             /* no data at this point */
  74.277 -
  74.278 -    gchar          *starttime;
  74.279 -
  74.280 -    starttime = (gchar *) xmlURIEscapeStr((const xmlChar *)
  74.281 -                                          gmyth_util_time_to_mythformat_from_time_val
  74.282 -                                          (StartTime), NULL);
  74.283 -
  74.284 -    gchar          *endtime;
  74.285 -
  74.286 -    endtime = (gchar *) xmlURIEscapeStr((const xmlChar *)
  74.287 -                                        gmyth_util_time_to_mythformat_from_time_val
  74.288 -                                        (EndTime), NULL);
  74.289 -
  74.290 -    GString        *command = g_string_new("");
  74.291 -
  74.292 -    g_string_printf(command,
  74.293 -                    "GetProgramGuide?StartTime=%s&EndTime=%s&StartChanId=%d"
  74.294 -                    "&NumOfChannels=%d&Details=%s", starttime, endtime,
  74.295 -                    StartChanId, NumOfChannels, Details);
  74.296 -    gmyth_debug("HTTP Request command = %s\n", command->str);
  74.297 -
  74.298 -    chunk = gmyth_http_request(backend_info, command);
  74.299 -    if (chunk.memory != NULL) {
  74.300 -        xmlDocPtr       doc = XMLParse(chunk.memory, strlen(chunk.memory));
  74.301 -
  74.302 -        getEpg(doc, &epg);
  74.303 -        free(chunk.memory);
  74.304 -    }
  74.305 -
  74.306 -    return epg;
  74.307 -}
  74.308 -
  74.309 -
  74.310 -GMythRecorded_Recording
  74.311 -retrieve_recorded_recording(xmlNodePtr node)
  74.312 -{
  74.313 -    GMythRecorded_Recording recording;
  74.314 -
  74.315 -    if (g_ascii_strcasecmp((char *) node->name, "text") != 0) {
  74.316 -
  74.317 -        sscanf((char *) xmlGetProp(node, (xmlChar *) "dupInType"),
  74.318 -               "%d", &(recording.dupInType));
  74.319 -
  74.320 -        sscanf((char *) xmlGetProp(node, (xmlChar *) "dupMethod"),
  74.321 -               "%d", &(recording.dupMethod));
  74.322 -
  74.323 -        sscanf((char *) xmlGetProp(node, (xmlChar *) "recStatus"),
  74.324 -               "%d", &(recording.recStatus));
  74.325 -
  74.326 -        sscanf((char *) xmlGetProp(node, (xmlChar *) "encoderId"),
  74.327 -               "%d", &(recording.encoderId));
  74.328 -
  74.329 -        sscanf((char *) xmlGetProp(node, (xmlChar *) "recordId"),
  74.330 -               "%d", &(recording.recordId));
  74.331 -
  74.332 -        sscanf((char *) xmlGetProp(node, (xmlChar *) "recType"),
  74.333 -               "%d", &(recording.recType));
  74.334 -
  74.335 -        recording.playGroup = g_strdup((char *)
  74.336 -                                       xmlGetProp(node, (xmlChar *)
  74.337 -                                                  "playGroup"));
  74.338 -
  74.339 -        recording.recGroup = g_strdup((char *)
  74.340 -                                      xmlGetProp(node,
  74.341 -                                                 (xmlChar *) "recGroup"));
  74.342 -
  74.343 -        recording.recProfile = g_strdup((char *)
  74.344 -                                        xmlGetProp(node, (xmlChar *)
  74.345 -                                                   "recProfile"));
  74.346 -
  74.347 -        sscanf((char *) xmlGetProp(node, (xmlChar *) "recPriority"),
  74.348 -               "%d", &(recording.recPriority));
  74.349 -
  74.350 -        recording.recStartTs = gmyth_util_string_to_time_val
  74.351 -            ((char *) xmlGetProp(node, (xmlChar *) "recStartTs"));
  74.352 -
  74.353 -        recording.recEndTs = gmyth_util_string_to_time_val
  74.354 -            ((char *) xmlGetProp(node, (xmlChar *) "recEndTs"));
  74.355 -    }
  74.356 -
  74.357 -    return recording;
  74.358 -}
  74.359 -
  74.360 -
  74.361 -GMythRecorded_Channel
  74.362 -retrieve_recorded_channel(xmlNodePtr node)
  74.363 -{
  74.364 -    GMythRecorded_Channel channel;
  74.365 -
  74.366 -    if (g_ascii_strcasecmp((char *) node->name, "text") != 0) {
  74.367 -
  74.368 -        channel.chanFilters = g_strdup((char *)
  74.369 -                                       xmlGetProp(node, (xmlChar *)
  74.370 -                                                  "chanFilters"));
  74.371 -
  74.372 -        channel.channelName = g_strdup((char *)
  74.373 -                                       xmlGetProp(node, (xmlChar *)
  74.374 -                                                  "channelName"));
  74.375 -
  74.376 -        sscanf((char *) xmlGetProp(node, (xmlChar *) "chanNum"),
  74.377 -               "%d", &(channel.chanNum));
  74.378 -
  74.379 -        sscanf((char *) xmlGetProp(node, (xmlChar *) "sourceId"),
  74.380 -               "%d", &(channel.sourceId));
  74.381 -
  74.382 -        sscanf((char *) xmlGetProp(node, (xmlChar *) "commFree"),
  74.383 -               "%d", &(channel.commFree));
  74.384 -
  74.385 -        sscanf((char *) xmlGetProp(node, (xmlChar *) "inputId"),
  74.386 -               "%d", &(channel.inputId));
  74.387 -
  74.388 -        sscanf((char *) xmlGetProp(node, (xmlChar *) "chanId"),
  74.389 -               "%d", &(channel.chanId));
  74.390 -
  74.391 -        sscanf((char *) xmlGetProp(node, (xmlChar *) "callSign"),
  74.392 -               "%d", &(channel.callSign));
  74.393 -    }
  74.394 -
  74.395 -    return channel;
  74.396 -}
  74.397 -
  74.398 -
  74.399 -
  74.400 -/** Retrieves all the programs from Recorded XML
  74.401 - *
  74.402 - * @param nodeTab A pointer to a node inside the XML
  74.403 - * @param recorded The struct where is the current epg
  74.404 - * @return list with all the recorded programs
  74.405 - */
  74.406 -GSList         *
  74.407 -get_Recorded_Programs(xmlNodePtr node)
  74.408 -{
  74.409 -    GSList         *programList = NULL;
  74.410 -
  74.411 -    while (node != NULL) {
  74.412 -
  74.413 -        if (g_ascii_strcasecmp((char *) node->name, "text") != 0) {
  74.414 -
  74.415 -            GMythRecorded_Program *program = (GMythRecorded_Program *)
  74.416 -                g_malloc(sizeof(struct _GMythRecorded_Program));
  74.417 -
  74.418 -            sscanf((char *)
  74.419 -                   xmlGetProp(node, (xmlChar *) "programFlags"), "%d",
  74.420 -                   &(program->programFlags));
  74.421 -
  74.422 -            program->title = g_strdup((char *)
  74.423 -                                      xmlGetProp(node,
  74.424 -                                                 (xmlChar *) "title"));
  74.425 -
  74.426 -            sscanf((char *) xmlGetProp(node, (xmlChar *) "programId"),
  74.427 -                   "%d", &(program->programId));
  74.428 -
  74.429 -            program->catType = g_strdup((char *)
  74.430 -                                        xmlGetProp(node, (xmlChar *)
  74.431 -                                                   "catType"));
  74.432 -
  74.433 -            program->category = g_strdup((char *)
  74.434 -                                         xmlGetProp(node, (xmlChar *)
  74.435 -                                                    "category"));
  74.436 -
  74.437 -            sscanf((char *) xmlGetProp(node, (xmlChar *) "seriesId"),
  74.438 -                   "%d", &(program->seriesId));
  74.439 -
  74.440 -
  74.441 -            program->startTime = gmyth_util_string_to_time_val
  74.442 -                ((char *) xmlGetProp(node, (xmlChar *) "startTime"));
  74.443 -
  74.444 -            program->endTime = gmyth_util_string_to_time_val
  74.445 -                ((char *) xmlGetProp(node, (xmlChar *) "endTime"));
  74.446 -
  74.447 -            program->lastModified = gmyth_util_string_to_time_val((char *)
  74.448 -                                                                  xmlGetProp
  74.449 -                                                                  (node,
  74.450 -                                                                   (xmlChar
  74.451 -                                                                    *)
  74.452 -                                                                   "lastModified"));
  74.453 -
  74.454 -            /*
  74.455 -             * TODO: FIX ME at gmyth_util program->asOf =
  74.456 -             * gmyth_util_string_to_time_val\ ((char *)xmlGetProp(node,
  74.457 -             * (xmlChar *)"airdate")); 
  74.458 -             */
  74.459 -
  74.460 -            program->subTitle = g_strdup((char *)
  74.461 -                                         xmlGetProp(node, (xmlChar *)
  74.462 -                                                    "subTitle"));
  74.463 -
  74.464 -            sscanf((char *) xmlGetProp(node, (xmlChar *) "stars"),
  74.465 -                   "%d", &(program->stars));
  74.466 -
  74.467 -            sscanf((char *) xmlGetProp(node, (xmlChar *) "repeat"),
  74.468 -                   "%d", &(program->repeat));
  74.469 -
  74.470 -            sscanf((char *) xmlGetProp(node, (xmlChar *) "fileSize"),
  74.471 -                   "%d", &(program->repeat));
  74.472 -
  74.473 -            program->hostname = g_strdup((char *)
  74.474 -                                         xmlGetProp(node, (xmlChar *)
  74.475 -                                                    "hostname"));
  74.476 -
  74.477 -            program->channel = retrieve_recorded_channel(node->children);
  74.478 -
  74.479 -            // Skip the \n
  74.480 -            program->recording =
  74.481 -                retrieve_recorded_recording(node->children->next->next);
  74.482 -
  74.483 -            // add to the list
  74.484 -            programList = g_slist_append(programList, program);
  74.485 -        }
  74.486 -
  74.487 -        node = node->next;
  74.488 -    }
  74.489 -
  74.490 -    return programList;
  74.491 -}
  74.492 -
  74.493 -/** Retrieves the properties from Recorded XML
  74.494 - *
  74.495 - * @param nodeTab A pointer to a node inside the XML
  74.496 - * @param recorded The struct where is the current epg
  74.497 - * @return "recorded" from "param" updated
  74.498 - */
  74.499 -void
  74.500 -get_Recorded_Properties(xmlNodePtr nodeTab, GMythRecorded * recorded)
  74.501 -{
  74.502 -    xmlNode        *ptr = nodeTab->children->next->children;
  74.503 -
  74.504 -    sscanf((char *) ptr->content, "%d", &(recorded->totalCount));
  74.505 -
  74.506 -
  74.507 -    ptr = ptr->parent->next->next->children;
  74.508 -    recorded->asOf = gmyth_util_string_to_time_val((char *) ptr->content);
  74.509 -
  74.510 -    ptr = ptr->parent->next->next->children;
  74.511 -    recorded->version = g_strdup((char *) ptr->content);
  74.512 -
  74.513 -    ptr = ptr->parent->next->next->children;
  74.514 -    sscanf((char *) ptr->content, "%d", &(recorded->protoVer));
  74.515 -
  74.516 -    ptr = ptr->parent->next->next->children;
  74.517 -    if (recorded->totalCount > 0)
  74.518 -        recorded->programList = get_Recorded_Programs(ptr->children);
  74.519 -
  74.520 -}
  74.521 -
  74.522 -
  74.523 -/** Aux function to retrieve Recorded programs
  74.524 - *
  74.525 - * @param doc An XML document (xmlDocPtr)
  74.526 - * @return The recorded var updated
  74.527 - */
  74.528 -void
  74.529 -getRecorded(xmlDocPtr doc, GMythRecorded * recorded)
  74.530 -{
  74.531 -    xmlXPathObjectPtr result;
  74.532 -    xmlNodeSetPtr   nodeset;
  74.533 -    xmlChar        *keyword;
  74.534 -
  74.535 -    int             i;
  74.536 -
  74.537 -    result = getXPath((xmlChar *) "/*", doc);
  74.538 -
  74.539 -    if (result) {
  74.540 -        nodeset = result->nodesetval;
  74.541 -        for (i = 0; i < nodeset->nodeNr; i++) {
  74.542 -            keyword = (xmlChar *) nodeset->nodeTab[i]->name;
  74.543 -            if (g_ascii_strcasecmp
  74.544 -                ((char *) keyword, "GetRecordedResponse") == 0) {
  74.545 -                get_Recorded_Properties(nodeset->nodeTab[i], recorded);
  74.546 -                break;
  74.547 -            }
  74.548 -        }
  74.549 -        xmlXPathFreeObject(result);
  74.550 -    }
  74.551 -
  74.552 -}
  74.553 -
  74.554 -
  74.555 -/** Function to retrieve the files that are recorded
  74.556 - *
  74.557 - */
  74.558 -GMythRecorded
  74.559 -gmyth_http_retrieve_recorded(GMythBackendInfo * backend_info)
  74.560 -{
  74.561 -    GMythRecorded   recorded;
  74.562 -    MemoryStruct    chunk;
  74.563 -
  74.564 -    chunk.memory = NULL;
  74.565 -    chunk.size = 0;
  74.566 -
  74.567 -    GString        *command = g_string_new("");
  74.568 -
  74.569 -    g_string_printf(command, "GetRecorded");
  74.570 -
  74.571 -    chunk = gmyth_http_request(backend_info, command);
  74.572 -    if (chunk.memory != NULL) {
  74.573 -        xmlDocPtr       doc = XMLParse(chunk.memory, strlen(chunk.memory));
  74.574 -
  74.575 -        getRecorded(doc, &recorded);
  74.576 -        free(chunk.memory);
  74.577 -    }
  74.578 -
  74.579 -    return recorded;
  74.580 -}
  74.581 -
  74.582 -
  74.583 -
  74.584 -/** Function to retrieve jobqueue status
  74.585 - *
  74.586 - */
  74.587 -gint
  74.588 -gmyth_http_retrieve_job_status(GMythBackendInfo * backend_info,
  74.589 -                               gint chanid, GTimeVal * start)
  74.590 -{
  74.591 -    gint            status = 0;
  74.592 -    gint            count = 0;
  74.593 -    gint            temp_chanid = 0;
  74.594 -    GTimeVal       *temp_start = NULL;
  74.595 -    int             i;
  74.596 -
  74.597 -    xmlXPathObjectPtr result;
  74.598 -    xmlNodeSetPtr   nodeset;
  74.599 -    xmlNodePtr      node;
  74.600 -    MemoryStruct    chunk;
  74.601 -
  74.602 -    chunk.memory = NULL;
  74.603 -    chunk.size = 0;
  74.604 -
  74.605 -    GString        *command = g_string_new("");
  74.606 -
  74.607 -    g_string_printf(command, "GetStatus");
  74.608 -
  74.609 -    chunk = gmyth_http_request(backend_info, command);
  74.610 -
  74.611 -    if (chunk.memory != NULL) {
  74.612 -        xmlDocPtr       doc = XMLParse(chunk.memory, strlen(chunk.memory));
  74.613 -
  74.614 -        result = getXPath((xmlChar *) "/Status/JobQueue", doc);
  74.615 -        if (result) {
  74.616 -            nodeset = result->nodesetval;
  74.617 -            node = nodeset->nodeTab[0];
  74.618 -            sscanf((char *) xmlGetProp(node, (xmlChar *) "count"),
  74.619 -                   "%d", &count);
  74.620 -
  74.621 -            if (count > 0) {
  74.622 -
  74.623 -                // Get the first child
  74.624 -                node = node->children->next;
  74.625 -
  74.626 -                for (i = 0; i < count; i++) {
  74.627 -
  74.628 -                    sscanf((char *)
  74.629 -                           xmlGetProp(node, (xmlChar *) "chanId"), "%d",
  74.630 -                           &temp_chanid);
  74.631 -
  74.632 -                    if (chanid == temp_chanid) {
  74.633 -                        temp_start = gmyth_util_string_to_time_val((char *)
  74.634 -                                                                   xmlGetProp
  74.635 -                                                                   (node,
  74.636 -                                                                    (xmlChar
  74.637 -                                                                     *)
  74.638 -                                                                    "startTime"));
  74.639 -
  74.640 -                        if ((temp_start->tv_sec == start->tv_sec) &&
  74.641 -                            (temp_start->tv_usec == start->tv_usec))
  74.642 -                            sscanf((char *)
  74.643 -                                   xmlGetProp(node,
  74.644 -                                              (xmlChar *) "status"),
  74.645 -                                   "%d", &status);
  74.646 -                    }
  74.647 -                    // Escape "text" node
  74.648 -                    node = node->next->next;
  74.649 -                }
  74.650 -            }
  74.651 -
  74.652 -        }
  74.653 -
  74.654 -        xmlXPathFreeObject(result);
  74.655 -        free(chunk.memory);
  74.656 -
  74.657 -    }
  74.658 -
  74.659 -    return status;
  74.660 -}
  74.661 -
  74.662 -
  74.663 -
  74.664 -/** Function to retrieve settings on the backend
  74.665 - *
  74.666 - * @param backend_info infos about the backend
  74.667 - * @param key the key you want to retrieve
  74.668 - * @param hostname the hostname that the key is set up
  74.669 - * @return the value of the key
  74.670 - */
  74.671 -gchar          *
  74.672 -gmyth_http_retrieve_setting(GMythBackendInfo * backend_info,
  74.673 -                            gchar * key, gchar * hostname)
  74.674 -{
  74.675 -    xmlXPathObjectPtr result;
  74.676 -    xmlNodeSetPtr   nodeset;
  74.677 -    xmlChar        *keyword;
  74.678 -    MemoryStruct    chunk;
  74.679 -    gchar          *value = NULL;
  74.680 -
  74.681 -    chunk.memory = NULL;
  74.682 -    chunk.size = 0;
  74.683 -
  74.684 -    GString        *command = g_string_new("");
  74.685 -
  74.686 -    g_string_printf(command, "GetSetting?Key=%s&HostName=%s&Default=NULL",
  74.687 -                    key, hostname);
  74.688 -
  74.689 -    chunk = gmyth_http_request(backend_info, command);
  74.690 -
  74.691 -    if (chunk.memory != NULL) {
  74.692 -        xmlDocPtr       doc = XMLParse(chunk.memory, strlen(chunk.memory));
  74.693 -
  74.694 -        result = getXPath((xmlChar *) "/GetSettingResponse/Values/*", doc);
  74.695 -
  74.696 -        if (result) {
  74.697 -            nodeset = result->nodesetval;
  74.698 -            keyword = (xmlChar *) nodeset->nodeTab[0]->name;
  74.699 -            if (g_ascii_strcasecmp((char *) keyword, "Value") == 0) {
  74.700 -                // Here we have the value
  74.701 -                value = (gchar *) nodeset->nodeTab[0]->children->content;
  74.702 -            }
  74.703 -            xmlXPathFreeObject(result);
  74.704 -        }
  74.705 -
  74.706 -        free(chunk.memory);
  74.707 -    }
  74.708 -
  74.709 -    return value;
  74.710 -}
  74.711 -
  74.712 -/** Common steps for rec_profile's functions
  74.713 - *
  74.714 - * @param backend_info infos about the backend
  74.715 - * @param id the profile's id that you want to delete
  74.716 - * @return 0 if OK
  74.717 - */
  74.718 -gint
  74.719 -rec_profile_common(GMythBackendInfo * backend_info, GString * command)
  74.720 -{
  74.721 -    xmlXPathObjectPtr result;
  74.722 -    xmlNodeSetPtr   nodeset;
  74.723 -    xmlChar        *keyword;
  74.724 -    MemoryStruct    chunk;
  74.725 -
  74.726 -    chunk.memory = NULL;
  74.727 -    chunk.size = 0;
  74.728 -
  74.729 -    int             ret = -1;
  74.730 -
  74.731 -    chunk = gmyth_http_request(backend_info, command);
  74.732 -
  74.733 -    if (chunk.memory != NULL) {
  74.734 -        xmlDocPtr       doc = XMLParse(chunk.memory, strlen(chunk.memory));
  74.735 -
  74.736 -        result = getXPath((xmlChar *) "/*", doc);
  74.737 -
  74.738 -        if (result) {
  74.739 -            nodeset = result->nodesetval;
  74.740 -            keyword = (xmlChar *) nodeset->nodeTab[0]->name;
  74.741 -
  74.742 -            if (g_ascii_strcasecmp((char *) keyword, "Success") == 0)
  74.743 -                ret = 0;
  74.744 -
  74.745 -            xmlXPathFreeObject(result);
  74.746 -        }
  74.747 -
  74.748 -        free(chunk.memory);
  74.749 -    }
  74.750 -
  74.751 -    return ret;
  74.752 -}
  74.753 -
  74.754 -
  74.755 -/** Function to delete recording profiles
  74.756 - *
  74.757 - * @param backend_info infos about the backend
  74.758 - * @param id the profile's id that you want to delete
  74.759 - * @return 0 if OK
  74.760 - */
  74.761 -gint
  74.762 -gmyth_http_del_rec_profile(GMythBackendInfo * backend_info, gint id)
  74.763 -{
  74.764 -
  74.765 -    GString        *command = g_string_new("");
  74.766 -
  74.767 -    g_string_printf(command, "delRecProfiles?id=%d", id);
  74.768 -
  74.769 -
  74.770 -    return rec_profile_common(backend_info, command);
  74.771 -}
  74.772 -
  74.773 -/** Function to create recording profiles
  74.774 - *
  74.775 - * @param backend_info infos about the backend
  74.776 - * @param profilename the name of profile you want to use
  74.777 - * @param groupname the name of groupname you want to use
  74.778 - * @param vcodec the name of the video codec you want to use
  74.779 - * @param acodec the name of the audo codec you want to use
  74.780 - * @return 0 if OK
  74.781 - */
  74.782 -gint
  74.783 -gmyth_http_create_rec_profile(GMythBackendInfo * backend_info,
  74.784 -                              GMythRecProfile * profile)
  74.785 -{
  74.786 -
  74.787 -    if (profile->name != NULL && profile->group != NULL &&
  74.788 -        profile->vcodec && profile->acodec && profile->options != NULL) {
  74.789 -        GString        *command = g_string_new("");
  74.790 -
  74.791 -        g_string_printf(command, "createRecProfiles?profilename=%s&"
  74.792 -                        "groupname=%s&vcodec=%s&acodec=%s&"
  74.793 -                        "transcodelossless=%d&transcoderesize=%d&"
  74.794 -                        "width=%d&height=%d&rtjpegquality=%d&"
  74.795 -                        "rtjpeglumafilter=%d&rtjpegchromafilter=%d&"
  74.796 -                        "mpeg4bitrate=%d&mpeg4maxquality=%d&"
  74.797 -                        "mpeg4minquality=%d&mpeg4qualdiff=%d&"
  74.798 -                        "mpeg4scalebitrate=%d&mpeg4optionvhq=%d&"
  74.799 -                        "mpeg4option4mv=%d&mpeg4optionidct=%d&"
  74.800 -                        "mpeg4optionime=%d&hardwaremjpegquality=%d&"
  74.801 -                        "hardwaremjpeghdecimation=%d&hardwaremjpegvdecimation=%d&"
  74.802 -                        "mpeg2streamtype=%s&mpeg2aspectratio=%s&"
  74.803 -                        "mpeg2bitrate=%d&mpeg2maxbitrate=%d&"
  74.804 -                        "samplerate=%d&mp3quality=%d&"
  74.805 -                        "volume=%d&mpeg2audtype=%s&"
  74.806 -                        "mpeg2audbitratel1=%d&mpeg2audbitratel2=%d&"
  74.807 -                        "mpeg2audvolume=%d",
  74.808 -                        profile->name, profile->group,
  74.809 -                        profile->vcodec, profile->acodec,
  74.810 -                        profile->options->transcodelossless,
  74.811 -                        profile->options->transcoderesize,
  74.812 -                        profile->options->width,
  74.813 -                        profile->options->height,
  74.814 -                        profile->options->rtjpegquality,
  74.815 -                        profile->options->rtjpeglumafilter,
  74.816 -                        profile->options->rtjpegchromafilter,
  74.817 -                        profile->options->mpeg4bitrate,
  74.818 -                        profile->options->mpeg4maxquality,
  74.819 -                        profile->options->mpeg4minquality,
  74.820 -                        profile->options->mpeg4qualdiff,
  74.821 -                        profile->options->mpeg4scalebitrate,
  74.822 -                        profile->options->mpeg4optionvhq,
  74.823 -                        profile->options->mpeg4option4mv,
  74.824 -                        profile->options->mpeg4optionidct,
  74.825 -                        profile->options->mpeg4optionime,
  74.826 -                        profile->options->hardwaremjpegquality,
  74.827 -                        profile->options->hardwaremjpeghdecimation,
  74.828 -                        profile->options->hardwaremjpegvdecimation,
  74.829 -                        profile->options->mpeg2streamtype,
  74.830 -                        profile->options->mpeg2aspectratio,
  74.831 -                        profile->options->mpeg2bitrate,
  74.832 -                        profile->options->mpeg2maxbitrate,
  74.833 -                        profile->options->samplerate,
  74.834 -                        profile->options->mp3quality,
  74.835 -                        profile->options->volume,
  74.836 -                        profile->options->mpeg2audtype,
  74.837 -                        profile->options->mpeg2audbitratel1,
  74.838 -                        profile->options->mpeg2audbitratel2,
  74.839 -                        profile->options->mpeg2audvolume);
  74.840 -
  74.841 -
  74.842 -        return rec_profile_common(backend_info, command);
  74.843 -    } else
  74.844 -        return -1;
  74.845 -}
  74.846 -
  74.847 -/** Function to retrieve recording profiles
  74.848 - *
  74.849 - * @param backend_info infos about the backend
  74.850 - * @param groupname the name of group you want to retrieve
  74.851 - * @return the list of profiles
  74.852 - */
  74.853 -GSList         *
  74.854 -gmyth_http_retrieve_rec_profiles(GMythBackendInfo * backend_info,
  74.855 -                                 gchar * groupname)
  74.856 -{
  74.857 -    xmlXPathObjectPtr result;
  74.858 -    xmlNodeSetPtr   nodeset;
  74.859 -    xmlChar        *keyword;
  74.860 -    MemoryStruct    chunk;
  74.861 -    GSList         *profiles = NULL;
  74.862 -
  74.863 -    chunk.memory = NULL;
  74.864 -    chunk.size = 0;
  74.865 -
  74.866 -    GString        *command = g_string_new("");
  74.867 -
  74.868 -    g_string_printf(command, "GetRecProfiles?groupname=%s", groupname);
  74.869 -
  74.870 -    chunk = gmyth_http_request(backend_info, command);
  74.871 -
  74.872 -    if (chunk.memory != NULL) {
  74.873 -        xmlDocPtr       doc = XMLParse(chunk.memory, strlen(chunk.memory));
  74.874 -
  74.875 -        result = getXPath((xmlChar *) "/*", doc);
  74.876 -
  74.877 -        if (result) {
  74.878 -            nodeset = result->nodesetval;
  74.879 -            keyword = (xmlChar *) nodeset->nodeTab[0]->name;
  74.880 -
  74.881 -            if (g_ascii_strcasecmp((char *) keyword, "Profiles") == 0) {
  74.882 -                xmlNodePtr      node = nodeset->nodeTab[0]->children->next;
  74.883 -                GMythRecProfile *profile;
  74.884 -
  74.885 -                while (node != NULL) {
  74.886 -                    if (g_ascii_strcasecmp((char *) node->name, "text") !=
  74.887 -                        0) {
  74.888 -                        profile = gmyth_recprofile_new();
  74.889 -
  74.890 -                        sscanf((char *) xmlGetProp(node, (xmlChar *)
  74.891 -                                                   "id"), "%d",
  74.892 -                               &(profile->id));
  74.893 -
  74.894 -                        profile->name = g_strdup((char *)
  74.895 -                                                 xmlGetProp(node,
  74.896 -                                                            (xmlChar *)
  74.897 -                                                            "name"));
  74.898 -
  74.899 -                        profile->vcodec = g_strdup((char *)
  74.900 -                                                   xmlGetProp(node,
  74.901 -                                                              (xmlChar *)
  74.902 -                                                              "vcodec"));
  74.903 -
  74.904 -                        profile->acodec = g_strdup((char *)
  74.905 -                                                   xmlGetProp(node,
  74.906 -                                                              (xmlChar *)
  74.907 -                                                              "acodec"));
  74.908 -
  74.909 -                        profile->group = g_strdup(groupname);
  74.910 -
  74.911 -                        profiles = g_slist_append(profiles, profile);
  74.912 -                    }
  74.913 -                    node = node->next;
  74.914 -                }
  74.915 -
  74.916 -            }
  74.917 -            xmlXPathFreeObject(result);
  74.918 -        }
  74.919 -
  74.920 -        free(chunk.memory);
  74.921 -    }
  74.922 -
  74.923 -    return profiles;
  74.924 -}
  74.925 -
  74.926 -
  74.927 -
  74.928 -/*
  74.929 - * Aux functions got from libcurl 
  74.930 - */
  74.931 -void           *
  74.932 -myrealloc(void *ptr, size_t size)
  74.933 -{
  74.934 -    /*
  74.935 -     * There might be a realloc() out there that doesn't like reallocing
  74.936 -     * NULL pointers, so we take care of it here 
  74.937 -     */
  74.938 -    if (ptr)
  74.939 -        return realloc(ptr, size);
  74.940 -    else
  74.941 -        return malloc(size);
  74.942 -}
  74.943 -
  74.944 -size_t
  74.945 -WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
  74.946 -{
  74.947 -    size_t          realsize = size * nmemb;
  74.948 -    MemoryStruct   *mem = (struct _MemoryStruct *) data;
  74.949 -
  74.950 -    mem->memory =
  74.951 -        (char *) myrealloc(mem->memory, mem->size + realsize + 1);
  74.952 -    if (mem->memory) {
  74.953 -        memcpy(&(mem->memory[mem->size]), ptr, realsize);
  74.954 -        mem->size += realsize;
  74.955 -        mem->memory[mem->size] = 0;
  74.956 -    }
  74.957 -
  74.958 -    return realsize;
  74.959 -}
  74.960 -
  74.961 -
  74.962 -/** Send HTTP Command and receives the result of it
  74.963 - *
  74.964 - * @return A string with the response from the server
  74.965 - *          NULL if there is no response.
  74.966 - */
  74.967 -MemoryStruct
  74.968 -gmyth_http_request(GMythBackendInfo * backend_info, GString * command)
  74.969 -{
  74.970 -    LIBXML_TEST_VERSION
  74.971 -        size_t size =
  74.972 -        strlen(backend_info->hostname) + strlen(command->str) + 20;
  74.973 -
  74.974 -    gchar          *URL = (gchar *) g_malloc(sizeof(gchar) * size);
  74.975 -    gchar          *mid = (gchar *) g_malloc(sizeof(gchar) * 6);
  74.976 -
  74.977 -    mid = "";
  74.978 -
  74.979 -    if (g_ascii_strcasecmp(command->str, "GetStatus") &&
  74.980 -        g_ascii_strcasecmp(command->str, "GetStatusHTML")) {
  74.981 -        mid = "Myth/";
  74.982 -    }
  74.983 -
  74.984 -    g_snprintf(URL, size, "http://%s:%d/%s%s",
  74.985 -               backend_info->hostname, backend_info->status_port, mid,
  74.986 -               command->str);
  74.987 -
  74.988 -    CURL           *curl_handle;
  74.989 -
  74.990 -    MemoryStruct    chunk;
  74.991 -
  74.992 -    chunk.memory = NULL;        /* we expect realloc(NULL, size) to work */
  74.993 -    chunk.size = 0;             /* no data at this point */
  74.994 -
  74.995 -    curl_global_init(CURL_GLOBAL_ALL);
  74.996 -
  74.997 -    /*
  74.998 -     * init the curl session 
  74.999 -     */
 74.1000 -    curl_handle = curl_easy_init();
 74.1001 -
 74.1002 -    /*
 74.1003 -     * specify URL to get 
 74.1004 -     */
 74.1005 -    curl_easy_setopt(curl_handle, CURLOPT_URL, URL);
 74.1006 -
 74.1007 -    /*
 74.1008 -     * send all data to this function 
 74.1009 -     */
 74.1010 -    curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION,
 74.1011 -                     WriteMemoryCallback);
 74.1012 -
 74.1013 -    /*
 74.1014 -     * we pass our 'chunk' struct to the callback function 
 74.1015 -     */
 74.1016 -    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &chunk);
 74.1017 -
 74.1018 -    /*
 74.1019 -     * some servers don't like requests that are made without a user-agent
 74.1020 -     * field, so we provide one 
 74.1021 -     */
 74.1022 -    curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
 74.1023 -
 74.1024 -    /*
 74.1025 -     * set timeout 
 74.1026 -     */
 74.1027 -    curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, 20);
 74.1028 -
 74.1029 -    /*
 74.1030 -     * get it! 
 74.1031 -     */
 74.1032 -    curl_easy_perform(curl_handle);
 74.1033 -
 74.1034 -    /*
 74.1035 -     * cleanup curl stuff 
 74.1036 -     */
 74.1037 -    curl_easy_cleanup(curl_handle);
 74.1038 -
 74.1039 -    return chunk;
 74.1040 -}
    75.1 --- a/gmyth/src/gmyth_http.h	Mon Feb 25 17:45:36 2008 +0000
    75.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.3 @@ -1,204 +0,0 @@
    75.4 -/**
    75.5 - * GMyth Library
    75.6 - *
    75.7 - * @file gmyth/gmyth_http.h
    75.8 - * 
    75.9 - * @brief <p> GMythHttp library provides a wrapper to access
   75.10 - * data from the database using http+xml
   75.11 - *
   75.12 - * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   75.13 - * @author Artur Duque de Souza <artur.souza@indt.org.br>
   75.14 - *
   75.15 - *
   75.16 - * This program is free software; you can redistribute it and/or modify
   75.17 - * it under the terms of the GNU Lesser General Public License as published by
   75.18 - * the Free Software Foundation; either version 2 of the License, or
   75.19 - * (at your option) any later version.
   75.20 - *
   75.21 - * This program is distributed in the hope that it will be useful,
   75.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   75.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   75.24 - * GNU General Public License for more details.
   75.25 - *
   75.26 - * You should have received a copy of the GNU Lesser General Public License
   75.27 - * along with this program; if not, write to the Free Software
   75.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   75.29 - */
   75.30 -
   75.31 -#ifndef __GMYTH_HTTP_H__
   75.32 -#define __GMYTH_HTTP_H__
   75.33 -
   75.34 -#include <glib-object.h>
   75.35 -
   75.36 -#include <stdio.h>
   75.37 -#include <stdlib.h>
   75.38 -#include <string.h>
   75.39 -#include <stdarg.h>
   75.40 -#include <glib.h>
   75.41 -#include <glib/gprintf.h>
   75.42 -
   75.43 -#include "gmyth_backendinfo.h"
   75.44 -#include "gmyth_util.h"
   75.45 -#include "gmyth_recprofile.h"
   75.46 -
   75.47 -#include <curl/curl.h>
   75.48 -#include <curl/types.h>
   75.49 -#include <curl/easy.h>
   75.50 -
   75.51 -G_BEGIN_DECLS
   75.52 -#define MYTH_PORT_STATUS 6544
   75.53 -#define JOB_UNKNOWN   0x0000
   75.54 -#define JOB_QUEUED    0x0001
   75.55 -#define JOB_PENDING   0x0002
   75.56 -#define JOB_STARTING  0x0003
   75.57 -#define JOB_RUNNING   0x0004
   75.58 -#define JOB_STOPPING  0x0005
   75.59 -#define JOB_PAUSED    0x0006
   75.60 -#define JOB_RETRY     0x0007
   75.61 -#define JOB_ERRORING  0x0008
   75.62 -#define JOB_ABORTING  0x0009
   75.63 -    // JOB_DONE is a mask to indicate the job is done
   75.64 -    // whatever the status is
   75.65 -#define JOB_DONE      0x0100
   75.66 -#define JOB_FINISHED  0x0110
   75.67 -#define JOB_ABORTED   0x0120
   75.68 -#define JOB_ERRORED   0x0130
   75.69 -#define JOB_CANCELLED 0x0140
   75.70 -typedef struct _GMythRecorded_Recording GMythRecorded_Recording;
   75.71 -typedef struct _GMythRecorded_Channel GMythRecorded_Channel;
   75.72 -typedef struct _GMythRecorded_Program GMythRecorded_Program;
   75.73 -typedef struct _GMythRecorded GMythRecorded;
   75.74 -typedef struct _GMythProgram GMythProgram;
   75.75 -typedef struct _GMythChannel GMythChannel;
   75.76 -typedef struct _GMythEpg GMythEpg;
   75.77 -typedef struct _MemoryStruct MemoryStruct;
   75.78 -
   75.79 -struct _MemoryStruct {
   75.80 -    char           *memory;
   75.81 -    size_t          size;
   75.82 -};
   75.83 -
   75.84 -struct _GMythProgram {
   75.85 -    gchar          *title;
   75.86 -    gchar          *subtitle;
   75.87 -    gchar          *catType;
   75.88 -    gchar          *category;
   75.89 -    gint            repeat;
   75.90 -    GTimeVal       *startTime;
   75.91 -    GTimeVal       *endTime;
   75.92 -};
   75.93 -
   75.94 -struct _GMythChannel {
   75.95 -    gchar          *channelName;
   75.96 -    gchar          *chanNum;
   75.97 -    gint            chanId;
   75.98 -    gint            callSign;
   75.99 -    GSList         *programList;
  75.100 -};
  75.101 -
  75.102 -struct _GMythEpg {
  75.103 -    gint            startChanId;
  75.104 -    gint            endChanId;
  75.105 -    gchar          *version;
  75.106 -    gint            protoVer;
  75.107 -    gint            totalCount;
  75.108 -    gint            numOfChannels;
  75.109 -    GTimeVal       *asOf;
  75.110 -    GTimeVal       *startTime;
  75.111 -    GTimeVal       *endTime;
  75.112 -    gint            details;
  75.113 -    GSList         *channelList;
  75.114 -};
  75.115 -
  75.116 -
  75.117 -struct _GMythRecorded_Recording {
  75.118 -    gint            dupInType;
  75.119 -    gint            dupMethod;
  75.120 -    gchar          *playGroup;
  75.121 -    gchar          *recGroup;
  75.122 -    gchar          *recProfile;
  75.123 -    gint            recPriority;
  75.124 -    gint            recStatus;
  75.125 -    gint            encoderId;
  75.126 -    gint            recordId;
  75.127 -    gint            recType;
  75.128 -    GTimeVal       *recStartTs;
  75.129 -    GTimeVal       *recEndTs;
  75.130 -};
  75.131 -
  75.132 -
  75.133 -struct _GMythRecorded_Channel {
  75.134 -    gchar          *chanFilters;
  75.135 -    gchar          *channelName;
  75.136 -    gint            chanNum;
  75.137 -    gint            sourceId;
  75.138 -    gint            commFree;
  75.139 -    gint            inputId;
  75.140 -    gint            chanId;
  75.141 -    gint            callSign;
  75.142 -};
  75.143 -
  75.144 -
  75.145 -struct _GMythRecorded_Program {
  75.146 -    gint            programFlags;
  75.147 -    gchar          *title;
  75.148 -    gint            programId;
  75.149 -    gchar          *catType;
  75.150 -    gchar          *category;
  75.151 -    gint            seriesId;
  75.152 -    GTimeVal       *startTime;
  75.153 -    GTimeVal       *endTime;
  75.154 -    GTimeVal       *airdate;    // ?
  75.155 -    GTimeVal       *lastModified;
  75.156 -    gchar          *subTitle;
  75.157 -    gint            stars;
  75.158 -    gint            repeat;
  75.159 -    gint            fileSize;
  75.160 -    gchar          *hostname;
  75.161 -    GMythRecorded_Channel channel;
  75.162 -    GMythRecorded_Recording recording;
  75.163 -};
  75.164 -
  75.165 -struct _GMythRecorded {
  75.166 -    gchar          *version;
  75.167 -    gint            protoVer;
  75.168 -    gint            totalCount;
  75.169 -    GTimeVal       *asOf;
  75.170 -    GSList         *programList;
  75.171 -};
  75.172 -
  75.173 -
  75.174 -gint            gmyth_http_retrieve_job_status(GMythBackendInfo *
  75.175 -                                               backend_info, gint chanid,
  75.176 -                                               GTimeVal * start);
  75.177 -
  75.178 -gchar          *gmyth_http_retrieve_setting(GMythBackendInfo *
  75.179 -                                            backend_info, gchar * key,
  75.180 -                                            gchar * hostname);
  75.181 -
  75.182 -GMythEpg        gmyth_http_retrieve_epg(GMythBackendInfo * backend_info,
  75.183 -                                        GTimeVal * StartTime,
  75.184 -                                        GTimeVal * EndTime,
  75.185 -                                        gint StartChanId,
  75.186 -                                        gint NumOfChannels,
  75.187 -                                        gchar * Details);
  75.188 -
  75.189 -GMythRecorded   gmyth_http_retrieve_recorded(GMythBackendInfo *
  75.190 -                                             backend_info);
  75.191 -
  75.192 -GSList         *gmyth_http_retrieve_rec_profiles(GMythBackendInfo *
  75.193 -                                                 backend_info,
  75.194 -                                                 gchar * groupname);
  75.195 -
  75.196 -gint            gmyth_http_create_rec_profile(GMythBackendInfo *
  75.197 -                                              backend_info,
  75.198 -                                              GMythRecProfile * profile);
  75.199 -
  75.200 -gint            gmyth_http_del_rec_profile(GMythBackendInfo * backend_info,
  75.201 -                                           gint id);
  75.202 -
  75.203 -MemoryStruct    gmyth_http_request(GMythBackendInfo * backend_info,
  75.204 -                                   GString * command);
  75.205 -
  75.206 -G_END_DECLS
  75.207 -#endif                          /* __GMYTH_HTTP_H__ */
    76.1 --- a/gmyth/src/gmyth_jobqueue.c	Mon Feb 25 17:45:36 2008 +0000
    76.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.3 @@ -1,200 +0,0 @@
    76.4 -/**
    76.5 - * GMyth Library
    76.6 - *
    76.7 - * @file gmyth/gmyth_jobqueue.c
    76.8 - * 
    76.9 - * @brief <p> Library to use JobQueue from mythbackend
   76.10 - *
   76.11 - * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   76.12 - * @author Artur Duque de Souza <artur.souza@indt.org.br>
   76.13 - *
   76.14 - * 
   76.15 - * This program is free software; you can redistribute it and/or modify
   76.16 - * it under the terms of the GNU Lesser General Public License as published by
   76.17 - * the Free Software Foundation; either version 2 of the License, or
   76.18 - * (at your option) any later version.
   76.19 - *
   76.20 - * This program is distributed in the hope that it will be useful,
   76.21 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   76.22 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   76.23 - * GNU General Public License for more details.
   76.24 - *
   76.25 - * You should have received a copy of the GNU Lesser General Public License
   76.26 - * along with this program; if not, write to the Free Software
   76.27 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   76.28 - */
   76.29 -
   76.30 -#ifdef HAVE_CONFIG_H
   76.31 -#include "config.h"
   76.32 -#endif
   76.33 -
   76.34 -#include "gmyth_jobqueue.h"
   76.35 -#include "gmyth_http.h"
   76.36 -#include "gmyth_debug.h"
   76.37 -#include "gmyth_socket.h"
   76.38 -
   76.39 -/** Function to connect
   76.40 - *
   76.41 - * @param backend_info the backendinfo
   76.42 - * @return gboolean - result of connection
   76.43 - *
   76.44 - */
   76.45 -static GMythSocket *
   76.46 -backend_connect(GMythBackendInfo * backend_info)
   76.47 -{
   76.48 -    GMythSocket    *socket = gmyth_socket_new();
   76.49 -
   76.50 -    if (gmyth_socket_connect_to_backend(socket,
   76.51 -                                        gmyth_backend_info_get_hostname
   76.52 -                                        (backend_info),
   76.53 -                                        gmyth_backend_info_get_port
   76.54 -                                        (backend_info), TRUE) == TRUE) {
   76.55 -        gmyth_debug("Backend socket connection success");
   76.56 -        return socket;
   76.57 -    } else {
   76.58 -        gmyth_debug("Connection failed");
   76.59 -        return NULL;
   76.60 -    }
   76.61 -}
   76.62 -
   76.63 -
   76.64 -/** Function to send a command to the backend
   76.65 - *
   76.66 - * @param socket pointer to a socket
   76.67 - * @param action the action itself
   76.68 - * @param job the action itself
   76.69 - * @param chanid the action itself
   76.70 - * @param starttime the action itself
   76.71 - * @param options the action itself
   76.72 - * @return the value returned by the backend
   76.73 - *
   76.74 - */
   76.75 -static gchar   *
   76.76 -send_command(GMythSocket * socket, gchar * action,
   76.77 -             gchar * job, gint chanid, gchar * starttime, gchar * options)
   76.78 -{
   76.79 -    GString        *command = g_string_new("");
   76.80 -    GString        *ret_str;
   76.81 -    gchar          *ret;
   76.82 -
   76.83 -    GMythStringList *retlist = gmyth_string_list_new();
   76.84 -
   76.85 -    g_string_printf(command, "JOBQUEUE %s %s %d %s %s", action, job,
   76.86 -                    chanid, starttime, options);
   76.87 -
   76.88 -    gmyth_string_list_append_string(retlist, command);
   76.89 -    gmyth_socket_write_stringlist(socket, retlist);
   76.90 -
   76.91 -    // receive answer
   76.92 -    gmyth_socket_read_stringlist(socket, retlist);
   76.93 -    ret_str = gmyth_string_list_get_string(retlist, 0);
   76.94 -
   76.95 -    // ret = ret_str->str;
   76.96 -    ret = g_string_free(ret_str, FALSE);
   76.97 -    g_string_free(command, TRUE);
   76.98 -
   76.99 -    gmyth_string_list_clear_all(retlist);
  76.100 -    g_object_unref(retlist);
  76.101 -
  76.102 -    return ret;
  76.103 -}
  76.104 -
  76.105 -
  76.106 -/** Function to analyze the response from the backend
  76.107 - *
  76.108 - * @param ret the msg returned by the backend
  76.109 - * @param value the expected value
  76.110 - * @return 0 if success and -1 if error
  76.111 - *
  76.112 - */
  76.113 -static          gboolean
  76.114 -test_result(gchar * ret, gchar * value)
  76.115 -{
  76.116 -    if (g_ascii_strcasecmp(ret, value) == 0) {
  76.117 -        return TRUE;
  76.118 -    } else {
  76.119 -        gmyth_debug("JobQueue Error: %s", ret);
  76.120 -        return FALSE;
  76.121 -    }
  76.122 -}
  76.123 -
  76.124 -/** Function to add a job inside JOBQUEUE
  76.125 - *
  76.126 - * @param transcode object holding all the info about the transcoding
  76.127 - * @param job the job you want to add the action
  76.128 - * @return TRUE if the job was added, FALSE if not
  76.129 - *
  76.130 - */
  76.131 -gboolean
  76.132 -gmyth_jobqueue_add_job(GMythTranscoder * transcode, gchar * job)
  76.133 -{
  76.134 -    GMythSocket    *socket = backend_connect(transcode->backend_info);
  76.135 -    gboolean        res = FALSE;
  76.136 -
  76.137 -    if (socket != NULL) {
  76.138 -        GString        *options = g_string_new("");
  76.139 -        gchar          *ret = NULL;
  76.140 -
  76.141 -        if (g_ascii_strcasecmp(job, "JOB_TRANSCODE") == 0) {
  76.142 -            if (transcode->cutlist)
  76.143 -                g_string_append(options, " JOB_USE_CUTLIST");
  76.144 -
  76.145 -            if (transcode->output)
  76.146 -                g_string_append_printf(options, " JOB_OUTPUT %s",
  76.147 -                                       transcode->output_filename);
  76.148 -
  76.149 -            if (transcode->profile != NULL)
  76.150 -                g_string_append_printf(options, " %s", transcode->profile);
  76.151 -        }
  76.152 -        ret = send_command(socket, "ADD", job, transcode->chanid,
  76.153 -                           transcode->starttime, options->str);
  76.154 -        res = test_result(ret, "JOBQUEUE_OK");
  76.155 -        gmyth_socket_close_connection(socket);
  76.156 -
  76.157 -        g_object_unref(socket);
  76.158 -
  76.159 -        g_string_free(options, TRUE);
  76.160 -
  76.161 -        if (ret)
  76.162 -            g_free(ret);
  76.163 -
  76.164 -    } else {
  76.165 -        gmyth_debug("JobQueue Connection Failed");
  76.166 -    }
  76.167 -
  76.168 -    return res;
  76.169 -}
  76.170 -
  76.171 -/** Function to change a job cmd inside JOBQUEUE
  76.172 - *
  76.173 - * @param transcode object holding all the info about the transcoding
  76.174 - * @param action the action (ADD)
  76.175 - * @param job the job you want to add the action
  76.176 - * @return the value of the key
  76.177 - *
  76.178 - */
  76.179 -gboolean
  76.180 -gmyth_jobqueue_change_cmd(GMythTranscoder * transcode, gchar * action,
  76.181 -                          gchar * job)
  76.182 -{
  76.183 -    GMythSocket    *socket = backend_connect(transcode->backend_info);
  76.184 -    gboolean        res = FALSE;
  76.185 -
  76.186 -    if (socket != NULL) {
  76.187 -        gchar          *ret = send_command(socket, action, job,
  76.188 -                                           transcode->chanid,
  76.189 -                                           transcode->starttime, "");
  76.190 -
  76.191 -        res = test_result(ret, "JOBQUEUE_CHANGED_CMD_OK");
  76.192 -
  76.193 -        gmyth_socket_close_connection(socket);
  76.194 -        g_object_unref(socket);
  76.195 -
  76.196 -        g_free(ret);
  76.197 -
  76.198 -    } else {
  76.199 -        gmyth_debug("JobQueue Connection Failed");
  76.200 -    }
  76.201 -
  76.202 -    return res;
  76.203 -}
    77.1 --- a/gmyth/src/gmyth_jobqueue.h	Mon Feb 25 17:45:36 2008 +0000
    77.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.3 @@ -1,52 +0,0 @@
    77.4 -/**
    77.5 - * GMyth Library
    77.6 - *
    77.7 - * @file gmyth/gmyth_jobqueue.h
    77.8 - *
    77.9 - * @brief <p> Library to use JobQueue from mythbackend
   77.10 - *
   77.11 - * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   77.12 - * @author Artur Duque de Souza <artur.souza@indt.org.br>
   77.13 - *
   77.14 - *
   77.15 - * This program is free software; you can redistribute it and/or modify
   77.16 - * it under the terms of the GNU Lesser General Public License as published by
   77.17 - * the Free Software Foundation; either version 2 of the License, or
   77.18 - * (at your option) any later version.
   77.19 - *
   77.20 - * This program is distributed in the hope that it will be useful,
   77.21 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   77.22 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   77.23 - * GNU General Public License for more details.
   77.24 - *
   77.25 - * You should have received a copy of the GNU Lesser General Public License
   77.26 - * along with this program; if not, write to the Free Software
   77.27 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   77.28 - */
   77.29 -
   77.30 -#ifndef __GMYTH_JOBQUEUE_H__
   77.31 -#define __GMYTH_JOBQUEUE_H__
   77.32 -
   77.33 -#include <glib-object.h>
   77.34 -
   77.35 -#include <stdio.h>
   77.36 -#include <stdlib.h>
   77.37 -#include <string.h>
   77.38 -#include <stdarg.h>
   77.39 -#include <glib.h>
   77.40 -#include <glib/gprintf.h>
   77.41 -
   77.42 -#include "gmyth_stringlist.h"
   77.43 -#include "gmyth_backendinfo.h"
   77.44 -#include "gmyth_transcoder.h"
   77.45 -#include "gmyth_socket.h"
   77.46 -#include "gmyth_util.h"
   77.47 -
   77.48 -G_BEGIN_DECLS
   77.49 -    gboolean gmyth_jobqueue_add_job(GMythTranscoder * transcoder,
   77.50 -                                    gchar * job);
   77.51 -gboolean        gmyth_jobqueue_change_cmd(GMythTranscoder * transcoder,
   77.52 -                                          gchar * action, gchar * job);
   77.53 -
   77.54 -G_END_DECLS
   77.55 -#endif                          /* __GMYTH_JOBQUEUE_H__ */
    78.1 --- a/gmyth/src/gmyth_livetv.c	Mon Feb 25 17:45:36 2008 +0000
    78.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.3 @@ -1,980 +0,0 @@
    78.4 -/**
    78.5 - * GMyth Library
    78.6 - *
    78.7 - * @file gmyth/gmyth_livetv.c
    78.8 - * 
    78.9 - * @brief <p> GMythLiveTV starts a remote TV session with the MythTV backend.
   78.10 - *
   78.11 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   78.12 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   78.13 - *
   78.14 - * 
   78.15 - * This program is free software; you can redistribute it and/or modify
   78.16 - * it under the terms of the GNU Lesser General Public License as published by
   78.17 - * the Free Software Foundation; either version 2 of the License, or
   78.18 - * (at your option) any later version.
   78.19 - *
   78.20 - * This program is distributed in the hope that it will be useful,
   78.21 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   78.22 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   78.23 - * GNU General Public License for more details.
   78.24 - *
   78.25 - * You should have received a copy of the GNU Lesser General Public License
   78.26 - * along with this program; if not, write to the Free Software
   78.27 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   78.28 - */
   78.29 -
   78.30 -#ifdef HAVE_CONFIG_H
   78.31 -#include "config.h"
   78.32 -#endif
   78.33 -
   78.34 -#include "gmyth_livetv.h"
   78.35 -#include "gmyth_remote_util.h"
   78.36 -#include "gmyth_tvchain.h"
   78.37 -#include "gmyth_socket.h"
   78.38 -#include "gmyth_backendinfo.h"
   78.39 -#include "gmyth_debug.h"
   78.40 -
   78.41 -#include "gmyth_file.h"
   78.42 -#include "gmyth_file_transfer.h"
   78.43 -#include "gmyth_file_local.h"
   78.44 -#include "gmyth_monitor_handler.h"
   78.45 -
   78.46 -#include "gmyth_common.h"
   78.47 -#include "gmyth_util.h"
   78.48 -
   78.49 -static void     gmyth_livetv_class_init(GMythLiveTVClass * klass);
   78.50 -static void     gmyth_livetv_init(GMythLiveTV * object);
   78.51 -
   78.52 -static void     gmyth_livetv_dispose(GObject * object);
   78.53 -static void     gmyth_livetv_finalize(GObject * object);
   78.54 -
   78.55 -static gint     tvchain_curr_index = -1;
   78.56 -
   78.57 -/*
   78.58 - * static GStaticMutex lock = G_STATIC_MUTEX_INIT;
   78.59 - */
   78.60 -
   78.61 -#define GMYTHTV_TRANSFER_MAX_WAITS	    100
   78.62 -
   78.63 -G_DEFINE_TYPE(GMythLiveTV, gmyth_livetv, G_TYPE_OBJECT)
   78.64 -    static void     gmyth_livetv_class_init(GMythLiveTVClass * klass)
   78.65 -{
   78.66 -    GObjectClass   *gobject_class;
   78.67 -
   78.68 -    gobject_class = (GObjectClass *) klass;
   78.69 -
   78.70 -    gobject_class->dispose = gmyth_livetv_dispose;
   78.71 -    gobject_class->finalize = gmyth_livetv_finalize;
   78.72 -}
   78.73 -
   78.74 -static void
   78.75 -gmyth_livetv_init(GMythLiveTV * livetv)
   78.76 -{
   78.77 -    livetv->monitor = NULL;
   78.78 -    livetv->backend_info = NULL;
   78.79 -    livetv->local_hostname = NULL;
   78.80 -    livetv->file = NULL;
   78.81 -    livetv->setup_done = FALSE;
   78.82 -
   78.83 -    livetv->socket = NULL;
   78.84 -    livetv->recorder = NULL;
   78.85 -    livetv->tvchain = NULL;
   78.86 -    livetv->proginfo = NULL;
   78.87 -    livetv->uri = NULL;
   78.88 -
   78.89 -    livetv->mutex = g_mutex_new();
   78.90 -}
   78.91 -
   78.92 -static void
   78.93 -gmyth_livetv_dispose(GObject * object)
   78.94 -{
   78.95 -    GMythLiveTV    *livetv = GMYTH_LIVETV(object);
   78.96 -
   78.97 -
   78.98 -    if (livetv->disposed) {
   78.99 -        /*
  78.100 -         * If dispose did already run, return. 
  78.101 -         */
  78.102 -        return;
  78.103 -    }
  78.104 -
  78.105 -    /*
  78.106 -     * Make sure dispose does not run twice. 
  78.107 -     */
  78.108 -    livetv->disposed = TRUE;
  78.109 -
  78.110 -    if (livetv->monitor != NULL) {
  78.111 -        g_object_unref(livetv->monitor);
  78.112 -        livetv->monitor = NULL;
  78.113 -    }
  78.114 -
  78.115 -
  78.116 -    if (livetv->file != NULL) {
  78.117 -        g_object_unref(livetv->file);
  78.118 -        livetv->file = NULL;
  78.119 -    }
  78.120 -
  78.121 -    if (livetv->recorder != NULL) {
  78.122 -        // gmyth_recorder_close(livetv->recorder);
  78.123 -        g_object_unref(livetv->recorder);
  78.124 -        livetv->recorder = NULL;
  78.125 -    }
  78.126 -
  78.127 -    if (livetv->socket != NULL) {
  78.128 -        g_object_unref(livetv->socket);
  78.129 -        livetv->socket = NULL;
  78.130 -    }
  78.131 -
  78.132 -    if (livetv->tvchain != NULL) {
  78.133 -        g_object_unref(livetv->tvchain);
  78.134 -        livetv->tvchain = NULL;
  78.135 -    }
  78.136 -
  78.137 -    if (livetv->proginfo != NULL) {
  78.138 -        g_object_unref(livetv->proginfo);
  78.139 -        livetv->proginfo = NULL;
  78.140 -    }
  78.141 -
  78.142 -    if (livetv->backend_info != NULL) {
  78.143 -        g_object_unref(livetv->backend_info);
  78.144 -        livetv->backend_info = NULL;
  78.145 -    }
  78.146 -
  78.147 -    if (livetv->uri != NULL) {
  78.148 -        g_object_unref(livetv->uri);
  78.149 -        livetv->uri = NULL;
  78.150 -    }
  78.151 -
  78.152 -    if (livetv->mutex != NULL) {
  78.153 -        g_mutex_free(livetv->mutex);
  78.154 -        livetv->mutex = NULL;
  78.155 -    }
  78.156 -
  78.157 -    if (livetv->local_hostname != NULL) {
  78.158 -        g_string_free(livetv->local_hostname, TRUE);
  78.159 -        livetv->local_hostname = NULL;
  78.160 -    }
  78.161 -
  78.162 -    G_OBJECT_CLASS(gmyth_livetv_parent_class)->dispose(object);
  78.163 -}
  78.164 -
  78.165 -static void
  78.166 -gmyth_livetv_finalize(GObject * object)
  78.167 -{
  78.168 -    g_signal_handlers_destroy(object);
  78.169 -
  78.170 -    G_OBJECT_CLASS(gmyth_livetv_parent_class)->finalize(object);
  78.171 -}
  78.172 -
  78.173 -/**
  78.174 - * Creates a new GMythLiveTV instance
  78.175 - * 
  78.176 - * @return a newly allocated GMythLiveTV instance
  78.177 - */
  78.178 -GMythLiveTV    *
  78.179 -gmyth_livetv_new(GMythBackendInfo * backend_info)
  78.180 -{
  78.181 -    GMythLiveTV    *livetv =
  78.182 -        GMYTH_LIVETV(g_object_new(GMYTH_LIVETV_TYPE, NULL));
  78.183 -
  78.184 -    livetv->backend_info = backend_info;
  78.185 -    g_object_ref(livetv->backend_info);
  78.186 -
  78.187 -    return livetv;
  78.188 -}
  78.189 -
  78.190 -/**
  78.191 - * The GObject signal handler function, from which all status messages 
  78.192 - * from the Monitor Handler will be advertized, all time it receives
  78.193 - * LiveTV status messages from the MythTV backend
  78.194 - * 
  78.195 - * @param monitor a GMythMonitorHandler instance
  78.196 - * @param msg_code the MythTV's server numeric status code
  78.197 - * @param message the message's string description
  78.198 - * @param user_data pointer to the GMythLiveTV instance
  78.199 - */
  78.200 -static void
  78.201 -gmyth_livetv_monitor_signal_handler(GMythMonitorHandler * monitor,
  78.202 -                                    gint msg_code, gchar * message,
  78.203 -                                    gpointer user_data)
  78.204 -{
  78.205 -    GMythLiveTV    *live_tv = GMYTH_LIVETV(user_data);
  78.206 -
  78.207 -    gmyth_debug
  78.208 -        ("LIVETV Signal handler ( msg = %s, code = %d, live_tv param = %s, user_data = %s )\n",
  78.209 -         message, msg_code, live_tv != NULL ? "" : "NULL",
  78.210 -         user_data != NULL ? "" : "NULL");
  78.211 -
  78.212 -    if (NULL == live_tv || !IS_GMYTH_FILE_TRANSFER(live_tv->file)) {
  78.213 -        gmyth_debug("LiveTV_obj is equals to NULL!!!");
  78.214 -        return;
  78.215 -    }
  78.216 -
  78.217 -    switch (msg_code) {
  78.218 -
  78.219 -    case GMYTH_BACKEND_PROGRAM_INFO_CHANGED:
  78.220 -        {
  78.221 -            gmyth_debug
  78.222 -                ("LIVETV Program Changed request received [ msg = %s ]. Watching if the new "
  78.223 -                 "TV Chain ID is the same as the old one...\n", message);
  78.224 -            if (g_ascii_strcasecmp
  78.225 -                (message,
  78.226 -                 (gmyth_tvchain_get_id(live_tv->tvchain))->str) != 0) {
  78.227 -                gmyth_debug
  78.228 -                    ("OK!!! MOVED to the next program chain [actual == %s]!",
  78.229 -                     (gmyth_tvchain_get_id(live_tv->tvchain))->str);
  78.230 -                /*
  78.231 -                 * advertises the FileTransfer about the program info
  78.232 -                 * changed 
  78.233 -                 */
  78.234 -                if (live_tv->file != NULL) {
  78.235 -                    gmyth_debug
  78.236 -                        ("Emitting signal to the FileTransfer... [ \"program-info-changed \" ]");
  78.237 -
  78.238 -                    gmyth_file_transfer_emit_program_info_changed_signal
  78.239 -                        (GMYTH_FILE_TRANSFER(live_tv->file), msg_code,
  78.240 -                         (gpointer) (live_tv->recorder));
  78.241 -
  78.242 -                    /*
  78.243 -                     * gmyth_livetv_monitor_handler_stop( live_tv ); 
  78.244 -                     */
  78.245 -                } else
  78.246 -                    gmyth_debug
  78.247 -                        ("LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");
  78.248 -            }
  78.249 -            break;
  78.250 -        }
  78.251 -    case GMYTH_BACKEND_DONE_RECORDING:
  78.252 -        {
  78.253 -            gmyth_debug
  78.254 -                ("LIVETV Program Changed request received [ msg = %s ]. Watching if the new "
  78.255 -                 "TV Chain ID is the same as the old one...\n", message);
  78.256 -            if (g_ascii_strcasecmp
  78.257 -                (message,
  78.258 -                 (gmyth_tvchain_get_id(live_tv->tvchain))->str) != 0) {
  78.259 -                gmyth_debug
  78.260 -                    ("OK!!! MOVED to the next program chain [actual == %s]!",
  78.261 -                     (gmyth_tvchain_get_id(live_tv->tvchain))->str);
  78.262 -                /*
  78.263 -                 * advertises the FileTransfer about the program info
  78.264 -                 * changed 
  78.265 -                 */
  78.266 -                if (live_tv->file != NULL) {
  78.267 -                    gmyth_debug
  78.268 -                        ("Emitting signal to the FileTransfer... [ \"backend-done-recording\" ]");
  78.269 -
  78.270 -                    gmyth_file_transfer_emit_program_info_changed_signal
  78.271 -                        (GMYTH_FILE_TRANSFER(live_tv->file), msg_code,
  78.272 -                         (gpointer) (live_tv->recorder));
  78.273 -
  78.274 -                } else
  78.275 -                    gmyth_debug
  78.276 -                        ("LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");
  78.277 -            }
  78.278 -            break;
  78.279 -        }
  78.280 -    case GMYTH_BACKEND_STOP_LIVETV:
  78.281 -        {
  78.282 -            gmyth_debug
  78.283 -                ("LIVETV Stop LiveTV request received [ msg = %s ]. Going out the "
  78.284 -                 "LiveTV...\n", message);
  78.285 -            /*
  78.286 -             * stops the LiveTV 
  78.287 -             */
  78.288 -            if (live_tv != NULL) {
  78.289 -                gmyth_debug("Going out the LiveTV... [ \"quit-livetv\" ]");
  78.290 -
  78.291 -                g_object_unref(live_tv);
  78.292 -            } else
  78.293 -                gmyth_debug
  78.294 -                    ("LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n");
  78.295 -
  78.296 -            break;
  78.297 -        }
  78.298 -    default:
  78.299 -        break;
  78.300 -    }                           /* switch (Monitor Handler messages) */
  78.301 -
  78.302 -}
  78.303 -
  78.304 -/**
  78.305 - * Starts the Monitor Handler to this GMythLiveTV session, in order
  78.306 - * to receive the status messages from the MythTV's backend server 
  78.307 - * 
  78.308 - * @param live_tv the GMythLiveTV instance
  78.309 - * 
  78.310 - * @return <code>true</code> if the Monitor Handler start-up process
  78.311 - * 	   had been concluded succcesfully 
  78.312 - */
  78.313 -gboolean
  78.314 -gmyth_livetv_monitor_handler_start(GMythLiveTV * livetv)
  78.315 -{
  78.316 -    gboolean        res = TRUE;
  78.317 -
  78.318 -    if (livetv->monitor != NULL) {
  78.319 -        g_object_unref(livetv->monitor);
  78.320 -        livetv->monitor = NULL;
  78.321 -    }
  78.322 -
  78.323 -    livetv->monitor = gmyth_monitor_handler_new();
  78.324 -    res =
  78.325 -        gmyth_monitor_handler_open(livetv->monitor,
  78.326 -                                   livetv->backend_info->hostname,
  78.327 -                                   livetv->backend_info->port);
  78.328 -
  78.329 -    if (res == TRUE) {
  78.330 -        gmyth_debug
  78.331 -            ("Connect MythTV Monitor event socket! Trying to start the message handler...");
  78.332 -
  78.333 -        res = gmyth_monitor_handler_start(livetv->monitor);
  78.334 -
  78.335 -        if (res) {
  78.336 -            gmyth_debug
  78.337 -                ("MythTV Monitor event socket connected and listening!");
  78.338 -            g_signal_connect(G_OBJECT(livetv->monitor),
  78.339 -                             "backend-events-handler", (GCallback)
  78.340 -                             gmyth_livetv_monitor_signal_handler, livetv);
  78.341 -        } else {
  78.342 -            gmyth_debug
  78.343 -                ("Problems when trying to start MythTV Monitor event socket!");
  78.344 -            goto error;
  78.345 -        }
  78.346 -    }
  78.347 -
  78.348 -  error:
  78.349 -    return res;
  78.350 -
  78.351 -}
  78.352 -
  78.353 -/**
  78.354 - * Stops the Monitor Handler to this GMythLiveTV session, in order
  78.355 - * to stop receiving the status messages from the MythTV's backend server 
  78.356 - * 
  78.357 - * @param live_tv the GMythLiveTV instance
  78.358 - * 
  78.359 - * @return <code>true</code> if the Monitor Handler shutdown process
  78.360 - * 	   had been concluded succcesfully 
  78.361 - */
  78.362 -void
  78.363 -gmyth_livetv_monitor_handler_stop(GMythLiveTV * livetv)
  78.364 -{
  78.365 -
  78.366 -    if (livetv->monitor != NULL) {
  78.367 -        g_object_unref(livetv->monitor);
  78.368 -        livetv->monitor = NULL;
  78.369 -    }
  78.370 -
  78.371 -}
  78.372 -
  78.373 -#if 0
  78.374 -static gchar   *
  78.375 -gmyth_livetv_create_remote_url(GMythLiveTV * livetv)
  78.376 -{
  78.377 -    gchar          *uri = g_strdup("");
  78.378 -
  78.379 -    gmyth_backend_info_get_remote_h
  78.380 -        // gmyth_backend(livetv->backend_info)
  78.381 -        return uri;
  78.382 -}
  78.383 -#endif
  78.384 -
  78.385 -/**
  78.386 - * Configures the GMythLiveTV session, sends SPAWN_LIVETV message, 
  78.387 - * sets the channel name, and gets the first program info about the
  78.388 - * actual recording 
  78.389 - * 
  78.390 - * @param live_tv the GMythLiveTV instance
  78.391 - * @param channel the channel name (the chan_name field, from the tvchain table)
  78.392 - * @param backend_info the GMythBackendInfo describing the remote server
  78.393 - * 
  78.394 - * @return <code>true</code> if the LiveTV's recorder instance configuration 
  78.395 - * 				had been concluded succcesfully 
  78.396 - */
  78.397 -static gboolean
  78.398 -gmyth_livetv_setup_recorder_channel_name(GMythLiveTV * livetv,
  78.399 -                                         gchar * channel)
  78.400 -{
  78.401 -    gboolean        res = TRUE;
  78.402 -
  78.403 -    g_return_val_if_fail(livetv != NULL, FALSE);
  78.404 -
  78.405 -    g_mutex_lock(livetv->mutex);
  78.406 -
  78.407 -    if (livetv->socket == NULL) {
  78.408 -        livetv->socket = gmyth_socket_new();
  78.409 -        /*
  78.410 -         * FIME: Implement this at gmyth_socket 
  78.411 -         */
  78.412 -        res =
  78.413 -            gmyth_socket_connect_to_backend(livetv->socket,
  78.414 -                                            livetv->backend_info->hostname,
  78.415 -                                            livetv->backend_info->port,
  78.416 -                                            TRUE);
  78.417 -        if (!res) {
  78.418 -            gmyth_debug("[%s] LiveTV can not connect to backend",
  78.419 -                        __FUNCTION__);
  78.420 -            res = FALSE;
  78.421 -            goto error;
  78.422 -        }
  78.423 -    }
  78.424 -
  78.425 -    livetv->is_livetv = TRUE;
  78.426 -
  78.427 -    livetv->local_hostname = gmyth_socket_get_local_hostname();
  78.428 -
  78.429 -    if (livetv->local_hostname == NULL) {
  78.430 -        g_warning("livetv could not retrieve the local hostname");
  78.431 -        res = FALSE;
  78.432 -        goto error;
  78.433 -    } else {
  78.434 -        gmyth_debug("Local hostname: %s", livetv->local_hostname->str);
  78.435 -    }
  78.436 -
  78.437 -    if (livetv->recorder != NULL) {
  78.438 -        g_object_unref(livetv->recorder);
  78.439 -        livetv->recorder = NULL;
  78.440 -    }
  78.441 -
  78.442 -    if (gmyth_remote_util_get_free_recorder_count(livetv->socket) <= 0) {
  78.443 -        gmyth_debug("No free remote encoder available.");
  78.444 -        res = FALSE;
  78.445 -        goto error;
  78.446 -    }
  78.447 -
  78.448 -    /*
  78.449 -     * Gets the recorder num 
  78.450 -     */
  78.451 -    livetv->recorder =
  78.452 -        remote_request_next_free_recorder(livetv->socket, -1);
  78.453 -    gmyth_socket_close_connection(livetv->socket);
  78.454 -
  78.455 -    if (NULL == livetv->recorder) {
  78.456 -        gmyth_debug("[%s] None remote encoder available", __FUNCTION__);
  78.457 -        res = FALSE;
  78.458 -        goto error;
  78.459 -    }
  78.460 -
  78.461 -    /*
  78.462 -     * Init remote encoder. Opens its control socket. 
  78.463 -     */
  78.464 -    res = gmyth_recorder_setup(livetv->recorder);
  78.465 -    if (!res) {
  78.466 -        gmyth_debug("[%s] Fail while setting remote encoder\n",
  78.467 -                    __FUNCTION__);
  78.468 -        res = FALSE;
  78.469 -        goto error;
  78.470 -    }
  78.471 -
  78.472 -    /*
  78.473 -     * Creates livetv chain handler 
  78.474 -     */
  78.475 -    livetv->tvchain = gmyth_tvchain_new();
  78.476 -    gmyth_tvchain_initialize(livetv->tvchain, livetv->backend_info);
  78.477 -
  78.478 -    if (livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL) {
  78.479 -        res = FALSE;
  78.480 -        goto error;
  78.481 -    }
  78.482 -    // Spawn live tv. Uses the socket to send mythprotocol data to start
  78.483 -    // livetv in the backend (remotelly)
  78.484 -    res = gmyth_recorder_spawntv(livetv->recorder,
  78.485 -                                 gmyth_tvchain_get_id(livetv->tvchain));
  78.486 -    if (!res) {
  78.487 -        gmyth_debug("[%s] Fail while spawn tv\n", __FUNCTION__);
  78.488 -        res = FALSE;
  78.489 -        goto error;
  78.490 -    }
  78.491 -
  78.492 -    if (res == TRUE) {
  78.493 -        /*
  78.494 -         * loop finished, set the max tries variable to zero again... 
  78.495 -         */
  78.496 -        gint            wait_to_transfer = 0;
  78.497 -
  78.498 -        while (wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS &&
  78.499 -               (gmyth_recorder_is_recording(livetv->recorder) == FALSE))
  78.500 -            g_usleep(300);
  78.501 -
  78.502 -        if (channel != NULL) {
  78.503 -            /*
  78.504 -             * Pauses remote encoder. 
  78.505 -             */
  78.506 -            res = gmyth_recorder_pause_recording(livetv->recorder);
  78.507 -            if (!res) {
  78.508 -                gmyth_debug("[%s] Fail while pausing remote encoder\n",
  78.509 -                            __FUNCTION__);
  78.510 -                res = FALSE;
  78.511 -                goto error;
  78.512 -            }
  78.513 -
  78.514 -            if (gmyth_recorder_check_channel_name
  78.515 -                (livetv->recorder, channel)) {
  78.516 -                if (gmyth_recorder_set_channel_name
  78.517 -                    (livetv->recorder, channel)) {
  78.518 -                    gmyth_debug("Channel changed!!! [%s].\n", channel);
  78.519 -                }
  78.520 -            }
  78.521 -
  78.522 -        }
  78.523 -        /*
  78.524 -         * if - changes the channel number 
  78.525 -         */
  78.526 -        /*
  78.527 -         * sleep (5); 
  78.528 -         */
  78.529 -        /*
  78.530 -         * FIXME: this is evil (tpm) 
  78.531 -         */
  78.532 -    }
  78.533 -
  78.534 -    /*
  78.535 -     * DEBUG message 
  78.536 -     */
  78.537 -    GMythProgramInfo *prog_info =
  78.538 -        gmyth_recorder_get_current_program_info(livetv->recorder);
  78.539 -
  78.540 -    if (NULL == prog_info) {
  78.541 -        gmyth_debug("ProgramInfo is equals to NULL!!!");
  78.542 -
  78.543 -        gint            i;
  78.544 -        gchar          *channame = NULL;
  78.545 -
  78.546 -        gmyth_debug("Problem getting current proginfo!\n");
  78.547 -
  78.548 -        /*
  78.549 -         * mythbackend must not be tuned in to a channel, so keep
  78.550 -         * changing channels until we find a valid one, or until
  78.551 -         * we decide to give up.
  78.552 -         */
  78.553 -        for (i = 1; i < 1000; i++) {
  78.554 -            if (channame != NULL)
  78.555 -                g_free(channame);
  78.556 -            channame = g_strdup_printf("%d", i);
  78.557 -            if (gmyth_recorder_set_channel_name(livetv->recorder, channame)
  78.558 -                < 0) {
  78.559 -                continue;
  78.560 -            }
  78.561 -            prog_info =
  78.562 -                gmyth_recorder_get_next_program_info(livetv->recorder,
  78.563 -                                                     BROWSE_DIRECTION_UP);
  78.564 -            gmyth_program_info_print(prog_info);
  78.565 -            if (prog_info != NULL)
  78.566 -                break;
  78.567 -        }
  78.568 -
  78.569 -    }
  78.570 -
  78.571 -    /*
  78.572 -     * if - Program Info 
  78.573 -     */
  78.574 -    /*
  78.575 -     * prints program info data text 
  78.576 -     */
  78.577 -    gmyth_debug("New ProgramInfo...\n");
  78.578 -    gmyth_program_info_print(prog_info);
  78.579 -
  78.580 -    /*
  78.581 -     * check if the program chain could be obtained from the MythTV
  78.582 -     * protocol message 
  78.583 -     */
  78.584 -    if (prog_info != NULL) {
  78.585 -        gmyth_backend_info_set_username(livetv->tvchain->backend_info,
  78.586 -                                        "mythtv");
  78.587 -        gmyth_backend_info_set_password(livetv->tvchain->backend_info,
  78.588 -                                        "mythtv");
  78.589 -        gmyth_backend_info_set_db_name(livetv->tvchain->backend_info,
  78.590 -                                       "mythconverg");
  78.591 -        GList          *prog_list =
  78.592 -            gmyth_tvchain_get_program_info_from_channel(livetv->tvchain,
  78.593 -                                                        channel);
  78.594 -        GMythProgramInfo *ch_prog = NULL;
  78.595 -
  78.596 -        if (prog_list != NULL && g_list_length(prog_list) > 0) {
  78.597 -            ch_prog = (GMythProgramInfo *) g_list_nth_data(prog_list, 0);
  78.598 -            gmyth_debug
  78.599 -                ("Channel program info (from a list with size = %d)!",
  78.600 -                 g_list_length(prog_list));
  78.601 -            gmyth_program_info_print(ch_prog);
  78.602 -        }
  78.603 -
  78.604 -        gmyth_debug("Program Info: %s\n",
  78.605 -                    gmyth_program_info_to_string(prog_info));
  78.606 -        livetv->proginfo = prog_info;
  78.607 -        /*
  78.608 -         * testing change channel 
  78.609 -         */
  78.610 -        // gmyth_recorder_spawntv_no_tvchain( livetv->recorder );
  78.611 -    } else {
  78.612 -
  78.613 -        /*
  78.614 -         * check for the program info in the TV program chain could be
  78.615 -         * obtained from the MythTV MySQL database 
  78.616 -         */
  78.617 -
  78.618 -        /*
  78.619 -         * Reload all TV chain from Mysql database. 
  78.620 -         */
  78.621 -        gmyth_tvchain_reload_all(livetv->tvchain);
  78.622 -
  78.623 -        if (livetv->tvchain == NULL) {
  78.624 -            res = FALSE;
  78.625 -            goto error;
  78.626 -        }
  78.627 -
  78.628 -        /*
  78.629 -         * Get program info from database using chanid and starttime 
  78.630 -         */
  78.631 -        livetv->proginfo =
  78.632 -            gmyth_tvchain_get_program_at(livetv->tvchain,
  78.633 -                                         tvchain_curr_index++);
  78.634 -        if (livetv->proginfo == NULL) {
  78.635 -            gmyth_debug("LiveTV not successfully started.\n");
  78.636 -            res = FALSE;
  78.637 -            goto error;
  78.638 -        } else {
  78.639 -            res = TRUE;
  78.640 -            gmyth_debug
  78.641 -                ("GMythLiveTV: All requests to backend to start TV were OK. [%s]\n",
  78.642 -                 livetv->proginfo->pathname->str);
  78.643 -        }
  78.644 -
  78.645 -    }
  78.646 -
  78.647 -    livetv->uri =
  78.648 -        (GMythURI *) gmyth_backend_info_get_uri(livetv->backend_info);
  78.649 -
  78.650 -    g_mutex_unlock(livetv->mutex);
  78.651 -
  78.652 -    if (!gmyth_livetv_monitor_handler_start(livetv)) {
  78.653 -        res = FALSE;
  78.654 -        gmyth_debug("LiveTV MONITOR handler error on setup!");
  78.655 -        goto error;
  78.656 -    }
  78.657 -
  78.658 -    livetv->setup_done = TRUE;
  78.659 -
  78.660 -    return res;
  78.661 -
  78.662 -  error:
  78.663 -    g_mutex_unlock(livetv->mutex);
  78.664 -
  78.665 -    gmyth_debug("[%s] ERROR running LiveTV setup.\n", __FUNCTION__);
  78.666 -
  78.667 -    res = FALSE;
  78.668 -
  78.669 -    if (livetv->local_hostname != NULL) {
  78.670 -        g_string_free(livetv->local_hostname, TRUE);
  78.671 -        livetv->local_hostname = NULL;
  78.672 -    }
  78.673 -
  78.674 -    gmyth_debug("[%s] ERROR running LiveTV setup.\n", __FUNCTION__);
  78.675 -
  78.676 -    if (livetv->recorder != NULL) {
  78.677 -        g_object_unref(livetv->recorder);
  78.678 -        livetv->recorder = NULL;
  78.679 -    }
  78.680 -
  78.681 -    gmyth_debug("[%s] ERROR running LiveTV setup.\n", __FUNCTION__);
  78.682 -
  78.683 -    if (livetv->tvchain != NULL) {
  78.684 -        g_object_unref(livetv->tvchain);
  78.685 -        livetv->tvchain = NULL;
  78.686 -    }
  78.687 -
  78.688 -    gmyth_debug("[%s] ERROR running LiveTV setup.\n", __FUNCTION__);
  78.689 -
  78.690 -    if (livetv->proginfo != NULL) {
  78.691 -        g_object_unref(livetv->proginfo);
  78.692 -        livetv->proginfo = NULL;
  78.693 -    }
  78.694 -
  78.695 -    gmyth_debug("[%s] ERROR running LiveTV setup.\n", __FUNCTION__);
  78.696 -
  78.697 -    if (livetv->monitor != NULL) {
  78.698 -        g_object_unref(livetv->monitor);
  78.699 -        livetv->monitor = NULL;
  78.700 -    }
  78.701 -
  78.702 -
  78.703 -    gmyth_debug("[%s] ERROR running LiveTV setup.\n", __FUNCTION__);
  78.704 -
  78.705 -    return res;
  78.706 -
  78.707 -}
  78.708 -
  78.709 -/**
  78.710 - * Setup the GMythLiveTV session, sends SPAWN_LIVETV message, 
  78.711 - * sets the channel name, and gets the first program info about the
  78.712 - * actual recording 
  78.713 - * 
  78.714 - * @param live_tv the GMythLiveTV instance
  78.715 - * @param channel the channel name, in numerical format
  78.716 - * @param backend_info the GMythBackendInfo describing the remote server
  78.717 - * 
  78.718 - * @return <code>true</code> if the LiveTV's recorder instance configuration 
  78.719 - * 				had been concluded succcesfully 
  78.720 - */
  78.721 -static          gboolean
  78.722 -gmyth_livetv_setup_recorder(GMythLiveTV * livetv, gint channel)
  78.723 -{
  78.724 -    return gmyth_livetv_setup_recorder_channel_name(livetv,
  78.725 -                                                    (channel !=
  78.726 -                                                     -1) ?
  78.727 -                                                    g_strdup_printf("%d",
  78.728 -                                                                    channel)
  78.729 -                                                    : NULL);
  78.730 -}
  78.731 -
  78.732 -/**
  78.733 - * Setup the GMythLiveTV session, sends SPAWN_LIVETV message, 
  78.734 - * sets the channel name (numerical format), and gets the first program info about the
  78.735 - * actual recording 
  78.736 - * 
  78.737 - * @param live_tv the GMythLiveTV instance
  78.738 - * @param channel the channel name, in numerical format
  78.739 - * @param backend_info the GMythBackendInfo describing the remote server
  78.740 - * 
  78.741 - * @return <code>true</code> if the LiveTV's recorder instance configuration 
  78.742 - * 				had been concluded succcesfully 
  78.743 - */
  78.744 -gboolean
  78.745 -gmyth_livetv_channel_setup(GMythLiveTV * livetv, gint channel)
  78.746 -{
  78.747 -    return gmyth_livetv_setup_recorder(livetv, channel);
  78.748 -}
  78.749 -
  78.750 -/**
  78.751 - * Setup the GMythLiveTV session, sends SPAWN_LIVETV message, 
  78.752 - * sets the channel name (string format), and gets the first program info about the
  78.753 - * actual recording 
  78.754 - * 
  78.755 - * @param live_tv the GMythLiveTV instance
  78.756 - * @param channel the channel name, in numerical format
  78.757 - * @param backend_info the GMythBackendInfo describing the remote server
  78.758 - * 
  78.759 - * @return <code>true</code> if the LiveTV's recorder instance configuration 
  78.760 - * 				had been concluded succcesfully 
  78.761 - */
  78.762 -gboolean
  78.763 -gmyth_livetv_channel_name_setup(GMythLiveTV * livetv, gchar * channel)
  78.764 -{
  78.765 -    return gmyth_livetv_setup_recorder_channel_name(livetv, channel);
  78.766 -}
  78.767 -
  78.768 -/**
  78.769 - * Setup the GMythLiveTV session, sends SPAWN_LIVETV message, 
  78.770 - * and gets the first program info about the actual recording
  78.771 - * (doesn't changes the channel). 
  78.772 - * 
  78.773 - * @param live_tv the GMythLiveTV instance
  78.774 - * @param backend_info the GMythBackendInfo describing the remote server
  78.775 - * 
  78.776 - * @return <code>true</code> if the LiveTV's recorder instance configuration 
  78.777 - * 				had been concluded succcesfully 
  78.778 - */
  78.779 -gboolean
  78.780 -gmyth_livetv_setup(GMythLiveTV * livetv)
  78.781 -{
  78.782 -    return gmyth_livetv_setup_recorder(livetv, -1);
  78.783 -}
  78.784 -
  78.785 -/**
  78.786 - * Gets the next program info from this GMythLiveTV session.
  78.787 - * 
  78.788 - * @param live_tv the GMythLiveTV instance
  78.789 - * 
  78.790 - * @return <code>true</code> if the next program info could be got 
  78.791 - */
  78.792 -gboolean
  78.793 -gmyth_livetv_next_program_chain(GMythLiveTV * livetv)
  78.794 -{
  78.795 -    gboolean        res = TRUE;
  78.796 -    GMythProgramInfo *prog_info = NULL;
  78.797 -
  78.798 -    if (!livetv->setup_done) {
  78.799 -        gmyth_debug("Call the setup function first!");
  78.800 -        goto error;
  78.801 -    }
  78.802 -
  78.803 -    gmyth_debug("Current ProgramInfo...\n");
  78.804 -    prog_info = gmyth_recorder_get_current_program_info(livetv->recorder);
  78.805 -
  78.806 -    if (prog_info != NULL) {
  78.807 -        livetv->proginfo = prog_info;
  78.808 -    } else {
  78.809 -        gmyth_debug
  78.810 -            ("ProgramInfo equals to NULL!!! Getting the next program info...");
  78.811 -        prog_info =
  78.812 -            gmyth_recorder_get_next_program_info(livetv->recorder,
  78.813 -                                                 BROWSE_DIRECTION_RIGHT);
  78.814 -        livetv->proginfo = prog_info;
  78.815 -    }
  78.816 -    /*
  78.817 -     * prints program info data text 
  78.818 -     */
  78.819 -    gmyth_program_info_print(prog_info);
  78.820 -
  78.821 -    if (prog_info != NULL) {
  78.822 -        res = TRUE;
  78.823 -        livetv->proginfo = prog_info;
  78.824 -        gmyth_debug
  78.825 -            ("GMythLiveTV: All requests to backend to start TV were OK, program info changed.");
  78.826 -    } else {
  78.827 -        gmyth_debug
  78.828 -            ("[%s] LiveTV not successfully started on the next program chain.\n",
  78.829 -             __FUNCTION__);
  78.830 -        goto error;
  78.831 -    }
  78.832 -
  78.833 -    livetv->setup_done = TRUE;
  78.834 -
  78.835 -    return res;
  78.836 -
  78.837 -  error:
  78.838 -    gmyth_debug("ERROR running LiveTV setup.\n");
  78.839 -
  78.840 -    res = FALSE;
  78.841 -
  78.842 -    g_string_free(livetv->local_hostname, TRUE);
  78.843 -
  78.844 -    if (livetv->recorder != NULL) {
  78.845 -        g_object_unref(livetv->recorder);
  78.846 -        livetv->recorder = NULL;
  78.847 -    }
  78.848 -
  78.849 -    if (livetv->tvchain != NULL) {
  78.850 -        g_object_unref(livetv->tvchain);
  78.851 -        livetv->tvchain = NULL;
  78.852 -    }
  78.853 -
  78.854 -    if (livetv->proginfo != NULL) {
  78.855 -        g_object_unref(livetv->proginfo);
  78.856 -        livetv->proginfo = NULL;
  78.857 -    }
  78.858 -
  78.859 -    return res;
  78.860 -}
  78.861 -
  78.862 -/**
  78.863 - * Creates a File Transfer session, using all configuration information
  78.864 - * got from the actual program info.
  78.865 - * 
  78.866 - * @param live_tv the GMythLiveTV instance
  78.867 - * 
  78.868 - * @return the actual GMythFileTransfer instance, generated using the
  78.869 - * 		data got from the actual program info.
  78.870 - */
  78.871 -GMythFile*
  78.872 -gmyth_livetv_create_file_transfer(GMythLiveTV * livetv)
  78.873 -{
  78.874 -    // GMythURI* uri = NULL;
  78.875 -
  78.876 -    if (NULL == livetv)
  78.877 -        return NULL;
  78.878 -
  78.879 -    if (!livetv->setup_done) {
  78.880 -        gmyth_debug
  78.881 -            ("Error: You must do the LiveTV setup, just before generating the FileTransfer from LiveTV source!");
  78.882 -        return NULL;
  78.883 -    }
  78.884 -
  78.885 -    if (livetv->proginfo != NULL)
  78.886 -        gmyth_debug("URI path (from program info) = %s.\n",
  78.887 -                    livetv->proginfo->pathname->str);
  78.888 -    else
  78.889 -        gmyth_debug("URI path (from URI) = %s.\n", livetv->uri->uri->str);
  78.890 -
  78.891 -    g_mutex_lock(livetv->mutex);
  78.892 -
  78.893 -    if (livetv->file != NULL) {
  78.894 -        /*
  78.895 -         * gmyth_file_transfer_close( livetv->file ); 
  78.896 -         */
  78.897 -        g_object_unref(livetv->file);
  78.898 -        livetv->file = NULL;
  78.899 -    }
  78.900 -
  78.901 -    if (livetv->uri != NULL) {
  78.902 -        gmyth_debug
  78.903 -            ("URI is not NULL, creating from the ProgramInfo pathname... (%s)",
  78.904 -             livetv->proginfo->pathname->str);
  78.905 -        livetv->uri->path = g_string_erase(livetv->uri->path, 0, -1);
  78.906 -        livetv->uri->path =
  78.907 -            g_string_new(g_strrstr(livetv->proginfo->pathname->str, "/"));
  78.908 -    } else {
  78.909 -        gmyth_debug
  78.910 -            ("URI is NULL, creating from the ProgramInfo pathname... (%s)",
  78.911 -             livetv->proginfo->pathname->str);
  78.912 -        livetv->uri =
  78.913 -            gmyth_uri_new_with_value(livetv->proginfo->pathname->str);
  78.914 -    }
  78.915 -
  78.916 -    if (NULL == livetv->uri) {
  78.917 -        gmyth_debug("Couldn't parse the URI to start LiveTV! [ uri = %s ]",
  78.918 -                    livetv->proginfo->pathname->str);
  78.919 -        goto done;
  78.920 -    }
  78.921 -
  78.922 -    if (gmyth_uri_is_local_file(livetv->uri))
  78.923 -        livetv->file =
  78.924 -            GMYTH_FILE(gmyth_file_local_new(livetv->backend_info));
  78.925 -    else {
  78.926 -        livetv->file =
  78.927 -            GMYTH_FILE(gmyth_file_transfer_new(livetv->backend_info));
  78.928 -        /*
  78.929 -         * gmyth_file_transfer_settimeout(
  78.930 -         * GMYTH_FILE_TRANSFER(livetv->file), TRUE ); 
  78.931 -         */
  78.932 -    }
  78.933 -
  78.934 -    if (NULL == livetv->file) {
  78.935 -        gmyth_debug
  78.936 -            ("Error: couldn't create the FileTransfer from LiveTV source!");
  78.937 -        goto done;
  78.938 -    }
  78.939 -
  78.940 -    g_object_ref(livetv->file);
  78.941 -
  78.942 -done:
  78.943 -    g_mutex_unlock(livetv->mutex);
  78.944 -    return livetv->file;
  78.945 -}
  78.946 -
  78.947 -/**
  78.948 - * Stops this LiveTV session.
  78.949 - * 
  78.950 - * @param live_tv the GMythLiveTV instance
  78.951 - */
  78.952 -void
  78.953 -gmyth_livetv_stop_playing(GMythLiveTV * livetv)
  78.954 -{
  78.955 -    gmyth_debug("Stopping the LiveTV...\n");
  78.956 -
  78.957 -    if (livetv->is_livetv) {
  78.958 -        if (!gmyth_recorder_stop_livetv(livetv->recorder)) {
  78.959 -            gmyth_debug("[%s] Error while stoping remote encoder",
  78.960 -                        __FUNCTION__);
  78.961 -        }
  78.962 -
  78.963 -        if (!gmyth_recorder_finish_recording(livetv->recorder)) {
  78.964 -            gmyth_debug
  78.965 -                ("[%s] Error while finishing recording on remote encoder",
  78.966 -                 __FUNCTION__);
  78.967 -        }
  78.968 -    }
  78.969 -}
  78.970 -
  78.971 -gboolean
  78.972 -gmyth_livetv_is_playing(GMythLiveTV * livetv)
  78.973 -{
  78.974 -    return TRUE;
  78.975 -}
  78.976 -
  78.977 -void
  78.978 -gmyth_livetv_start_playing(GMythLiveTV * livetv)
  78.979 -{
  78.980 -
  78.981 -    // TODO
  78.982 -
  78.983 -}
    79.1 --- a/gmyth/src/gmyth_livetv.h	Mon Feb 25 17:45:36 2008 +0000
    79.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.3 @@ -1,103 +0,0 @@
    79.4 -/**
    79.5 - * GMyth Library
    79.6 - *
    79.7 - * @file gmyth/gmyth_livetv.h
    79.8 - * 
    79.9 - * @brief <p> GMythLiveTV starts a remote TV session with the MythTV backend.
   79.10 - *
   79.11 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   79.12 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   79.13 - *
   79.14 -* 
   79.15 -* This program is free software; you can redistribute it and/or modify
   79.16 -* it under the terms of the GNU Lesser General Public License as published by
   79.17 -* the Free Software Foundation; either version 2 of the License, or
   79.18 -* (at your option) any later version.
   79.19 -*
   79.20 -* This program is distributed in the hope that it will be useful,
   79.21 -	* but WITHOUT ANY WARRANTY; without even the implied warranty of
   79.22 -	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   79.23 -	* GNU General Public License for more details.
   79.24 -	*
   79.25 -	* You should have received a copy of the GNU Lesser General Public License
   79.26 -	* along with this program; if not, write to the Free Software
   79.27 -	* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   79.28 -	*/
   79.29 -
   79.30 -#ifndef GMYTH_LIVETV_H_
   79.31 -#define GMYTH_LIVETV_H_
   79.32 -
   79.33 -#include <glib.h>
   79.34 -#include <glib-object.h>
   79.35 -
   79.36 -#include "gmyth_recorder.h"
   79.37 -#include "gmyth_tvchain.h"
   79.38 -#include "gmyth_monitor_handler.h"
   79.39 -#include "gmyth_file.h"
   79.40 -#include "gmyth_programinfo.h"
   79.41 -#include "gmyth_backendinfo.h"
   79.42 -
   79.43 -G_BEGIN_DECLS
   79.44 -#define GMYTH_LIVETV_TYPE               (gmyth_livetv_get_type ())
   79.45 -#define GMYTH_LIVETV(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_LIVETV_TYPE, GMythLiveTV))
   79.46 -#define GMYTH_LIVETV_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_LIVETV_TYPE, GMythLiveTVClass))
   79.47 -#define IS_GMYTH_LIVETV(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_LIVETV_TYPE))
   79.48 -#define IS_GMYTH_LIVETV_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_LIVETV_TYPE))
   79.49 -#define GMYTH_LIVETV_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_LIVETV_TYPE, GMythLiveTVClass))
   79.50 -typedef struct _GMythLiveTV GMythLiveTV;
   79.51 -typedef struct _GMythLiveTVClass GMythLiveTVClass;
   79.52 -
   79.53 -struct _GMythLiveTVClass {
   79.54 -    GObjectClass    parent_class;
   79.55 -
   79.56 -    /*
   79.57 -     * callbacks 
   79.58 -     */
   79.59 -};
   79.60 -
   79.61 -struct _GMythLiveTV {
   79.62 -    GObject         parent;
   79.63 -
   79.64 -    GMythSocket    *socket;
   79.65 -
   79.66 -    GString        *local_hostname;
   79.67 -
   79.68 -    GMythBackendInfo *backend_info;
   79.69 -
   79.70 -    GMythRecorder  *recorder;
   79.71 -    GMythTVChain   *tvchain;
   79.72 -    GMythProgramInfo *proginfo;
   79.73 -
   79.74 -    GMythFile      *file;
   79.75 -
   79.76 -    GMythMonitorHandler *monitor;
   79.77 -    GMythURI       *uri;
   79.78 -
   79.79 -    gboolean        is_livetv;
   79.80 -    gboolean        setup_done;
   79.81 -
   79.82 -    GMutex         *mutex;
   79.83 -    gboolean        disposed;
   79.84 -};
   79.85 -
   79.86 -GType           gmyth_livetv_get_type(void);
   79.87 -
   79.88 -GMythLiveTV    *gmyth_livetv_new(GMythBackendInfo * backend_info);
   79.89 -
   79.90 -void            gmyth_livetv_start_playing(GMythLiveTV * livetv);
   79.91 -void            gmyth_livetv_stop_playing(GMythLiveTV * livetv);
   79.92 -
   79.93 -gboolean        gmyth_livetv_setup(GMythLiveTV * livetv);
   79.94 -gboolean        gmyth_livetv_channel_setup(GMythLiveTV * livetv,
   79.95 -                                           gint channel);
   79.96 -gboolean        gmyth_livetv_channel_name_setup(GMythLiveTV * livetv,
   79.97 -                                                gchar * channel);
   79.98 -gboolean        gmyth_livetv_next_program_chain(GMythLiveTV * livetv);
   79.99 -
  79.100 -GMythFile      *gmyth_livetv_create_file_transfer(GMythLiveTV * livetv);
  79.101 -
  79.102 -gboolean        gmyth_livetv_monitor_handler_start(GMythLiveTV * livetv);
  79.103 -void            gmyth_livetv_monitor_handler_stop(GMythLiveTV * livetv);
  79.104 -
  79.105 -G_END_DECLS
  79.106 -#endif                          /* GMYTH_LIVETV_H_ */
    80.1 --- a/gmyth/src/gmyth_marshal.list	Mon Feb 25 17:45:36 2008 +0000
    80.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.3 @@ -1,2 +0,0 @@
    80.4 -VOID:INT,STRING
    80.5 -VOID:INT,POINTER
    81.1 --- a/gmyth/src/gmyth_monitor_handler.c	Mon Feb 25 17:45:36 2008 +0000
    81.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.3 @@ -1,593 +0,0 @@
    81.4 -/**
    81.5 - * GMyth Library
    81.6 - *
    81.7 - * @file gmyth/gmyth_monitor_handler.c
    81.8 - * 
    81.9 - * @brief <p> GMythMonitorHandler deals with the streaming media events remote/local
   81.10 - * that are sent to the MythTV frontend.
   81.11 - *
   81.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   81.13 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   81.14 - *
   81.15 - * 
   81.16 - * This program is free software; you can redistribute it and/or modify
   81.17 - * it under the terms of the GNU Lesser General Public License as published by
   81.18 - * the Free Software Foundation; either version 2 of the License, or
   81.19 - * (at your option) any later version.
   81.20 - *
   81.21 - * This program is distributed in the hope that it will be useful,
   81.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   81.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   81.24 - * GNU General Public License for more details.
   81.25 - *
   81.26 - * You should have received a copy of the GNU Lesser General Public License
   81.27 - * along with this program; if not, write to the Free Software
   81.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   81.29 - *
   81.30 - * GStreamer MythTV plug-in properties:
   81.31 - * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv]
   81.32 - * - path (qurl - remote file to be opened)
   81.33 - * - port number *   
   81.34 - */
   81.35 -
   81.36 -#ifdef HAVE_CONFIG_H
   81.37 -#include "config.h"
   81.38 -#endif
   81.39 -
   81.40 -#include <unistd.h>
   81.41 -#include <glib.h>
   81.42 -#include <arpa/inet.h>
   81.43 -#include <sys/types.h>
   81.44 -#include <sys/socket.h>
   81.45 -#include <netdb.h>
   81.46 -#include <errno.h>
   81.47 -#include <stdlib.h>
   81.48 -#include <assert.h>
   81.49 -
   81.50 -#include "gmyth_marshal.h"
   81.51 -
   81.52 -#include "gmyth_monitor_handler.h"
   81.53 -#include "gmyth_debug.h"
   81.54 -
   81.55 -#define GMYTHTV_QUERY_HEADER		"QUERY_FILETRANSFER "
   81.56 -
   81.57 -#define GMYTHTV_VERSION							30
   81.58 -
   81.59 -#define GMYTHTV_TRANSFER_MAX_WAITS	700
   81.60 -
   81.61 -#define GMYTHTV_BUFFER_SIZE					8*1024
   81.62 -
   81.63 -#ifdef GMYTHTV_ENABLE_DEBUG
   81.64 -#define GMYTHTV_ENABLE_DEBUG				1
   81.65 -#else
   81.66 -#undef GMYTHTV_ENABLE_DEBUG
   81.67 -#endif
   81.68 -
   81.69 -/*
   81.70 - * this NDEBUG is to maintain compatibility with GMyth library 
   81.71 - */
   81.72 -#ifndef NDEBUG
   81.73 -#define GMYTHTV_ENABLE_DEBUG				1
   81.74 -#endif
   81.75 -
   81.76 -static gboolean gmyth_monitor_handler_listener  (GIOChannel *io_channel,
   81.77 -                                                 GIOCondition condition,
   81.78 -                                                 gpointer data);
   81.79 -
   81.80 -static void     gmyth_monitor_handler_default_listener(GMythMonitorHandler
   81.81 -                                                       * monitor,
   81.82 -                                                       gint msg_code,
   81.83 -                                                       gchar * message);
   81.84 -
   81.85 -static void     gmyth_monitor_handler_class_init(GMythMonitorHandlerClass *
   81.86 -                                                 klass);
   81.87 -static void     gmyth_monitor_handler_init(GMythMonitorHandler * object);
   81.88 -
   81.89 -static void     gmyth_monitor_handler_dispose(GObject * object);
   81.90 -static void     gmyth_monitor_handler_finalize(GObject * object);
   81.91 -
   81.92 -static gboolean gmyth_connect_to_backend_monitor(GMythMonitorHandler *
   81.93 -                                                 monitor);
   81.94 -
   81.95 -static gboolean gmyth_monitor_handler_setup(GMythMonitorHandler * monitor,
   81.96 -                                            GIOChannel * channel);
   81.97 -
   81.98 -void            gmyth_monitor_handler_close(GMythMonitorHandler * monitor);
   81.99 -
  81.100 -G_DEFINE_TYPE(GMythMonitorHandler, gmyth_monitor_handler, G_TYPE_OBJECT);
  81.101 -
  81.102 -static void
  81.103 -gmyth_monitor_handler_class_init(GMythMonitorHandlerClass * klass)
  81.104 -{
  81.105 -    GObjectClass   *gobject_class;
  81.106 -    GMythMonitorHandlerClass *gmonitor_class;
  81.107 -
  81.108 -    gobject_class = (GObjectClass *) klass;
  81.109 -    gmonitor_class = (GMythMonitorHandlerClass *) gobject_class;
  81.110 -
  81.111 -    gobject_class->dispose = gmyth_monitor_handler_dispose;
  81.112 -    gobject_class->finalize = gmyth_monitor_handler_finalize;
  81.113 -
  81.114 -    gmonitor_class->backend_events_handler_signal_id =
  81.115 -        g_signal_new("backend-events-handler",
  81.116 -                     G_TYPE_FROM_CLASS(gmonitor_class),
  81.117 -                     G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
  81.118 -                     G_SIGNAL_NO_HOOKS, 0, NULL, NULL,
  81.119 -                     gmyth_marshal_VOID__INT_STRING, G_TYPE_NONE, 2,
  81.120 -                     G_TYPE_INT, G_TYPE_STRING);
  81.121 -
  81.122 -    gmonitor_class->backend_events_handler =
  81.123 -        gmyth_monitor_handler_default_listener;
  81.124 -
  81.125 -}
  81.126 -
  81.127 -static void
  81.128 -gmyth_monitor_handler_init(GMythMonitorHandler * monitor)
  81.129 -{
  81.130 -    g_return_if_fail(monitor != NULL);
  81.131 -
  81.132 -    monitor->event_sock = NULL;
  81.133 -    monitor->hostname = NULL;
  81.134 -    monitor->port = 0;
  81.135 -    monitor->actual_index = 0;
  81.136 -    monitor->allow_msgs_listener = FALSE;
  81.137 -    /*
  81.138 -     * it is used for signalizing the event socket consumer thread 
  81.139 -     */
  81.140 -    monitor->mutex = g_mutex_new();
  81.141 -}
  81.142 -
  81.143 -static void
  81.144 -gmyth_monitor_handler_dispose(GObject * object)
  81.145 -{
  81.146 -    GMythMonitorHandler *monitor = GMYTH_MONITOR_HANDLER(object);
  81.147 -
  81.148 -    gmyth_monitor_handler_close(monitor);
  81.149 -
  81.150 -    monitor->allow_msgs_listener = FALSE;
  81.151 -
  81.152 -    if (monitor->io_source != 0) {
  81.153 -        g_source_remove (monitor->io_source);
  81.154 -        monitor->io_source = 0;
  81.155 -    }
  81.156 -
  81.157 -    /*
  81.158 -     * mutex to control access to the event socket consumer thread 
  81.159 -     */
  81.160 -    if (monitor->mutex != NULL) {
  81.161 -        // g_mutex_unlock( monitor->mutex );
  81.162 -        g_mutex_free(monitor->mutex);
  81.163 -        monitor->mutex = NULL;
  81.164 -    }
  81.165 -
  81.166 -    if (monitor->event_sock != NULL) {
  81.167 -        g_object_unref(monitor->event_sock);
  81.168 -        monitor->event_sock = NULL;
  81.169 -    }
  81.170 -
  81.171 -    if (monitor->hostname != NULL) {
  81.172 -        g_free(monitor->hostname);
  81.173 -        monitor->hostname = NULL;
  81.174 -    }
  81.175 -
  81.176 -
  81.177 -    if (monitor->backend_msgs != NULL) {
  81.178 -        g_hash_table_destroy(monitor->backend_msgs);
  81.179 -        monitor->backend_msgs = NULL;
  81.180 -    }
  81.181 -
  81.182 -    /*
  81.183 -     * if ( io_watcher_cond != NULL ) { g_cond_free( io_watcher_cond );
  81.184 -     * io_watcher_cond = NULL; } 
  81.185 -     */
  81.186 -
  81.187 -
  81.188 -    G_OBJECT_CLASS(gmyth_monitor_handler_parent_class)->dispose(object);
  81.189 -}
  81.190 -
  81.191 -static void
  81.192 -gmyth_monitor_handler_finalize(GObject * object)
  81.193 -{
  81.194 -    g_signal_handlers_destroy(object);
  81.195 -
  81.196 -    G_OBJECT_CLASS(gmyth_monitor_handler_parent_class)->finalize(object);
  81.197 -}
  81.198 -
  81.199 -/** 
  81.200 - * Creates a new instance of GMyth Monitor Handler.
  81.201 - * 
  81.202 - * @return a new instance of the Monitor Handler. 
  81.203 - */
  81.204 -GMythMonitorHandler *
  81.205 -gmyth_monitor_handler_new(void)
  81.206 -{
  81.207 -    GMythMonitorHandler *monitor =
  81.208 -        GMYTH_MONITOR_HANDLER(g_object_new
  81.209 -                              (GMYTH_MONITOR_HANDLER_TYPE, FALSE));
  81.210 -
  81.211 -    return monitor;
  81.212 -}
  81.213 -
  81.214 -/** 
  81.215 - * Acquire the mutex to have access to the IO Watcher listener.
  81.216 - * 
  81.217 - * @param monitor The GMythMonitorHandler instance.
  81.218 - * @param do_wait Tells the IO Watcher to wait on the GCond. (obsolete)
  81.219 - * 
  81.220 - * @return <code>true</code>, if the access to IO Watcher was acquired. 
  81.221 - */
  81.222 -static          gboolean
  81.223 -myth_control_acquire_context(GMythMonitorHandler * monitor,
  81.224 -                             gboolean do_wait)
  81.225 -{
  81.226 -
  81.227 -    gboolean        ret = TRUE;
  81.228 -
  81.229 -    g_mutex_lock(monitor->mutex);
  81.230 -
  81.231 -    return ret;
  81.232 -
  81.233 -}
  81.234 -
  81.235 -/** 
  81.236 - * Release the mutex to have access to the IO Watcher listener.
  81.237 - * 
  81.238 - * @param monitor The GMythMonitorHandler instance.
  81.239 - * 
  81.240 - * @return <code>true</code>, if the access to IO Watcher was released. 
  81.241 - */
  81.242 -static          gboolean
  81.243 -myth_control_release_context(GMythMonitorHandler * monitor)
  81.244 -{
  81.245 -
  81.246 -    gboolean        ret = TRUE;
  81.247 -
  81.248 -    g_mutex_unlock(monitor->mutex);
  81.249 -
  81.250 -    return ret;
  81.251 -}
  81.252 -
  81.253 -void
  81.254 -gmyth_monitor_handler_close(GMythMonitorHandler * monitor)
  81.255 -{
  81.256 -    monitor->allow_msgs_listener = FALSE;
  81.257 -
  81.258 -#if 0
  81.259 -    if (monitor->monitor_th != NULL) {
  81.260 -        g_thread_pool_free(monitor->monitor_th, TRUE, FALSE);
  81.261 -        // g_thread_exit( monitor->monitor_th );
  81.262 -        /*
  81.263 -         * if ( monitor->monitor_th != NULL ) g_object_unref(
  81.264 -         * monitor->monitor_th ); 
  81.265 -         */
  81.266 -        monitor->monitor_th = NULL;
  81.267 -    }
  81.268 -
  81.269 -    if (monitor->event_sock != NULL) {
  81.270 -        gmyth_socket_close_connection(monitor->event_sock);
  81.271 -    }
  81.272 -#endif
  81.273 -
  81.274 -}
  81.275 -
  81.276 -/** 
  81.277 - * Opens connection the the Monitor socket on MythTV backend server,
  81.278 - * where all status messages are notified to the client.
  81.279 - * 
  81.280 - * @param monitor The GMythMonitorHandler instance.
  81.281 - * @param hostname The remote host name of the MythTV backend server.
  81.282 - * @param port The remote port number of the MythTV backend server.
  81.283 - * 
  81.284 - * @return <code>true</code>, if the connection was successfully opened.
  81.285 - */
  81.286 -gboolean
  81.287 -gmyth_monitor_handler_open(GMythMonitorHandler * monitor,
  81.288 -                           const gchar * hostname, gint port)
  81.289 -{
  81.290 -    gboolean        ret = TRUE;
  81.291 -
  81.292 -    g_return_val_if_fail(hostname != NULL, FALSE);
  81.293 -
  81.294 -    if (monitor->hostname != NULL) {
  81.295 -        g_free(monitor->hostname);
  81.296 -        monitor->hostname = NULL;
  81.297 -    }
  81.298 -
  81.299 -    monitor->hostname = g_strdup(hostname);
  81.300 -    monitor->port = port;
  81.301 -
  81.302 -    gmyth_debug("Monitor event socket --- hostname: %s, port %d\n",
  81.303 -                monitor->hostname, monitor->port);
  81.304 -
  81.305 -    if (monitor->event_sock != NULL) {
  81.306 -        g_object_unref(monitor->event_sock);
  81.307 -        monitor->event_sock = NULL;
  81.308 -    }
  81.309 -
  81.310 -    /*
  81.311 -     * configure the event socket
  81.312 -     */
  81.313 -    if (!gmyth_connect_to_backend_monitor(monitor)) {
  81.314 -        gmyth_debug("Connection to backend failed (Event Socket)!");
  81.315 -        ret = FALSE;
  81.316 -    } else {
  81.317 -        gmyth_debug ("Remote monitor event socket had been succesfully create");
  81.318 -    }
  81.319 -
  81.320 -    return ret;
  81.321 -}
  81.322 -
  81.323 -/** 
  81.324 - * Reads the data got from the connection to the Monitor socket,
  81.325 - * and looks for some important status messages.
  81.326 - * 
  81.327 - * @param monitor The GMythMonitorHandler instance.
  81.328 - * @param strlist The GMythStringList instance got from the Monitor remote socket.
  81.329 - * @param back_msg_action A string pointer to the status message detailed description.
  81.330 - * 
  81.331 - * @return The backend status message code ID.
  81.332 - */
  81.333 -static          gint
  81.334 -gmyth_monitor_handler_is_backend_message(GMythMonitorHandler * monitor,
  81.335 -                                         GMythStringList * strlist,
  81.336 -                                         gchar ** back_msg_action)
  81.337 -{
  81.338 -    gint            msg_type = GMYTH_BACKEND_NO_MESSAGE;
  81.339 -    GString        *back_msg = NULL;
  81.340 -
  81.341 -    if (gmyth_string_list_length(strlist) > 0) {
  81.342 -
  81.343 -        back_msg = gmyth_string_list_get_string(strlist, 0);
  81.344 -        if (back_msg != NULL && back_msg->str != NULL &&
  81.345 -            strstr(back_msg->str, "BACKEND") != NULL) {
  81.346 -            gmyth_debug("MONITOR HANDLER - Received backend message = %s",
  81.347 -                        back_msg->str);
  81.348 -            *back_msg_action =
  81.349 -                gmyth_string_list_get_char_array(strlist, 1);
  81.350 -
  81.351 -            if (back_msg_action != NULL) {
  81.352 -
  81.353 -                if (g_strstr_len
  81.354 -                    (*back_msg_action, strlen(*back_msg_action),
  81.355 -                     "LIVETV_CHAIN")
  81.356 -                    || g_strstr_len(*back_msg_action,
  81.357 -                                    strlen(*back_msg_action),
  81.358 -                                    "RECORDING_LIST_CHANGE")
  81.359 -                    || g_strstr_len(*back_msg_action,
  81.360 -                                    strlen(*back_msg_action),
  81.361 -                                    "SCHEDULE_CHANGE")
  81.362 -                    || g_strstr_len(*back_msg_action,
  81.363 -                                    strlen(*back_msg_action),
  81.364 -                                    "LIVETV_WATCH")) {
  81.365 -                    gmyth_debug
  81.366 -                        ("MONITOR: message type == GMYTH_BACKEND_PROGRAM_INFO_CHANGED, msg = %s",
  81.367 -                         *back_msg_action);
  81.368 -                    msg_type = GMYTH_BACKEND_PROGRAM_INFO_CHANGED;
  81.369 -                } else if (g_strstr_len
  81.370 -                           (*back_msg_action, strlen(*back_msg_action),
  81.371 -                            "DONE_RECORDING")) {
  81.372 -                    gmyth_debug
  81.373 -                        ("MONITOR: message type == GMYTH_BACKEND_DONE_RECORDING, msg = %s",
  81.374 -                         *back_msg_action);
  81.375 -                    msg_type = GMYTH_BACKEND_DONE_RECORDING;
  81.376 -                } else if (g_strstr_len
  81.377 -                           (*back_msg_action, strlen(*back_msg_action),
  81.378 -                            "QUIT")) {
  81.379 -                    gmyth_debug
  81.380 -                        ("MONITOR: message type == GMYTH_BACKEND_STOP_LIVETV, msg = %s",
  81.381 -                         *back_msg_action);
  81.382 -                    msg_type = GMYTH_BACKEND_STOP_LIVETV;
  81.383 -                }
  81.384 -
  81.385 -                /*
  81.386 -                 * g_hash_table_insert ( monitor->backend_msgs,
  81.387 -                 * &(monitor->actual_index), *back_msg_action ); 
  81.388 -                 */
  81.389 -
  81.390 -            }
  81.391 -            /*
  81.392 -             * if 
  81.393 -             */
  81.394 -        }
  81.395 -        /*
  81.396 -         * if 
  81.397 -         */
  81.398 -        if (back_msg != NULL) {
  81.399 -            g_string_free(back_msg, TRUE);
  81.400 -            back_msg = NULL;
  81.401 -        }
  81.402 -
  81.403 -    }                           /* if - Does Monitor got any message from
  81.404 -                                 * * * backend? */
  81.405 -    else {
  81.406 -        *back_msg_action = g_strdup("");
  81.407 -    }
  81.408 -
  81.409 -    return msg_type;
  81.410 -
  81.411 -}
  81.412 -
  81.413 -static void
  81.414 -gmyth_monitor_handler_default_listener(GMythMonitorHandler * monitor,
  81.415 -                                       gint msg_code, gchar * message)
  81.416 -{
  81.417 -    // assert( message!= NULL ); 
  81.418 -    gmyth_debug("DEFAULT Signal handler ( msg = %s, code = %d )\n",
  81.419 -                message, msg_code);
  81.420 -}
  81.421 -
  81.422 -static void
  81.423 -gmyth_monitor_handler_print(GString * str, gpointer ptr)
  81.424 -{
  81.425 -    gmyth_debug("Backend message event: %s --- ", str->str);
  81.426 -}
  81.427 -
  81.428 -/** 
  81.429 - * Opens connection the the Monitor socket on MythTV backend server,
  81.430 - * where all status messages are notified to the client.
  81.431 - * 
  81.432 - * @param data Pointer to the GMythMonitorHandler.
  81.433 - * 
  81.434 - * @return Pointer to a gboolean <code>true</code> value, if the data was 
  81.435 - * 	successfully read.
  81.436 - */
  81.437 -static gboolean
  81.438 -gmyth_monitor_handler_listener (GIOChannel *io_channel,
  81.439 -                                GIOCondition io_cond,
  81.440 -                                gpointer data)
  81.441 -{
  81.442 -    GMythMonitorHandler *monitor;
  81.443 -    guint           recv = 0;
  81.444 -    gsize           len = 0;
  81.445 -    GMythStringList *strlist = NULL;
  81.446 -    gint bytes_sent = 0;
  81.447 -
  81.448 -    monitor = (GMythMonitorHandler *) data;
  81.449 -
  81.450 -    gmyth_debug("Entering MONITOR handler listener...");
  81.451 -
  81.452 -    myth_control_acquire_context(monitor, TRUE);
  81.453 -
  81.454 -    if (((io_cond & G_IO_HUP) != 0) ||
  81.455 -        ((io_cond & G_IO_ERR) != 0)) {
  81.456 -        goto clean_up;
  81.457 -    }
  81.458 -
  81.459 -
  81.460 -    gmyth_debug("Listening on Monitor socket...!\n");
  81.461 -    strlist = gmyth_string_list_new();
  81.462 -
  81.463 -    len = gmyth_socket_read_stringlist(monitor->event_sock, strlist);
  81.464 -    if ((len > 0) && strlist != NULL && gmyth_string_list_length(strlist) > 0) {
  81.465 -        gchar *back_msg_action;
  81.466 -        gint msg_type;
  81.467 -
  81.468 -        bytes_sent = gmyth_string_list_get_int(strlist, 0);
  81.469 -        // on  backend  error
  81.470 -        gmyth_debug ("received data buffer from IO event channel... %d strings gone!\n", len);
  81.471 -        recv += len;
  81.472 -
  81.473 -        /*
  81.474 -         * debug purpose: prints out all the string list
  81.475 -         * elements
  81.476 -         */
  81.477 -        g_list_foreach(strlist->glist,
  81.478 -                       (GFunc) gmyth_monitor_handler_print,
  81.479 -                       NULL);
  81.480 -
  81.481 -         back_msg_action = g_new0(gchar, 1);
  81.482 -         msg_type = gmyth_monitor_handler_is_backend_message(monitor,
  81.483 -            strlist,
  81.484 -            &back_msg_action);
  81.485 -
  81.486 -        if (msg_type != GMYTH_BACKEND_NO_MESSAGE) {
  81.487 -            g_signal_emit(monitor,
  81.488 -                          GMYTH_MONITOR_HANDLER_GET_CLASS(monitor)->backend_events_handler_signal_id,
  81.489 -                          0, msg_type, back_msg_action);
  81.490 -        }
  81.491 -
  81.492 -        if (back_msg_action != NULL)
  81.493 -            g_free(back_msg_action);
  81.494 -
  81.495 -        g_object_unref(strlist);
  81.496 -    }
  81.497 -
  81.498 -clean_up:
  81.499 -    myth_control_release_context(monitor);
  81.500 -    return TRUE;
  81.501 -}
  81.502 -
  81.503 -/**
  81.504 - * Opens connection events' socket the the Monitor socket on 
  81.505 - * MythTV backend server.
  81.506 - * 
  81.507 - * @param monitor The GMythMonitorHandler instance.
  81.508 - * 
  81.509 - * @return <code>true</code>, if the socket was successfully opened.
  81.510 - */
  81.511 -static gboolean
  81.512 -gmyth_connect_to_backend_monitor(GMythMonitorHandler * monitor)
  81.513 -{
  81.514 -    gboolean        ret = TRUE;
  81.515 -
  81.516 -    monitor->event_sock = gmyth_socket_new();
  81.517 -
  81.518 -    /*
  81.519 -     * Connects the socket, send Mythtv ANN Monitor and verify Mythtv
  81.520 -     * protocol version
  81.521 -     */
  81.522 -    if (!gmyth_socket_connect_to_backend_events(monitor->event_sock,
  81.523 -                                                monitor->hostname,
  81.524 -                                                monitor->port, FALSE)) {
  81.525 -        g_object_unref(monitor->event_sock);
  81.526 -        monitor->event_sock = NULL;
  81.527 -        ret = FALSE;
  81.528 -    }
  81.529 -
  81.530 -    return ret;
  81.531 -}
  81.532 -
  81.533 -/**
  81.534 - * Opens connection the the Monitor socket on MythTV backend server,
  81.535 - * where all status messages are notified to the client.
  81.536 - *
  81.537 - * @param monitor The GMythMonitorHandler instance.
  81.538 - * @param channel The GIOChannel instance to the Monitor socket.
  81.539 - *
  81.540 - * @return Pointer to the boolean value, and it is <code>true</code> only if the 
  81.541 - * GMythMonitorHandler could be configured.
  81.542 - */
  81.543 -static gboolean
  81.544 -gmyth_monitor_handler_setup(GMythMonitorHandler * monitor,
  81.545 -                            GIOChannel * channel)
  81.546 -{
  81.547 -    gboolean ret = TRUE;
  81.548 -
  81.549 -    if (channel != NULL) {
  81.550 -        monitor->allow_msgs_listener = TRUE;
  81.551 -        monitor->io_source = g_io_add_watch (channel, G_IO_IN | G_IO_ERR | G_IO_HUP,
  81.552 -                                             gmyth_monitor_handler_listener,
  81.553 -                                             monitor);
  81.554 -    } else {
  81.555 -        ret = FALSE;
  81.556 -    }
  81.557 -    return ret;
  81.558 -}
  81.559 -
  81.560 -/**
  81.561 - * Starts the MonitorHandler thread to the GIOWatcher.
  81.562 - *
  81.563 - * @param monitor The GMythMonitorHandler instance.
  81.564 - *
  81.565 - * @return <code>true</code>, if the MonitorHandler was started.
  81.566 - */
  81.567 -gboolean
  81.568 -gmyth_monitor_handler_start(GMythMonitorHandler * monitor)
  81.569 -{
  81.570 -    gboolean        ret = TRUE;
  81.571 -
  81.572 -    if (!(ret = g_thread_supported())) {
  81.573 -        gmyth_debug("Thread system wasn't initialized, starting NOW!!!");
  81.574 -        g_thread_init(NULL);
  81.575 -    }
  81.576 -
  81.577 -    ret =
  81.578 -        gmyth_monitor_handler_setup(monitor,
  81.579 -                                    monitor->event_sock->sd_io_ch);
  81.580 -    if (ret) {
  81.581 -        gmyth_debug
  81.582 -            ("\n[%s]\tOK! Starting listener on the MONITOR event socket...[thread location = %p]\n",
  81.583 -             __FUNCTION__, g_thread_self());
  81.584 -    } else {
  81.585 -        gmyth_debug
  81.586 -            ("\n[%s]\tERROR! Coudn't start listener on the MONITOR event socket...[thread location = %p]\n",
  81.587 -             __FUNCTION__, g_thread_self());
  81.588 -        ret = FALSE;
  81.589 -    }
  81.590 -
  81.591 -    gmyth_debug
  81.592 -        ("[%s] Watch listener function over the IO control channel? %s!!!\n",
  81.593 -         __FUNCTION__, (ret == TRUE ? "YES" : "NO"));
  81.594 -
  81.595 -    return ret;
  81.596 -}
    82.1 --- a/gmyth/src/gmyth_monitor_handler.h	Mon Feb 25 17:45:36 2008 +0000
    82.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.3 @@ -1,122 +0,0 @@
    82.4 -/**
    82.5 - * GMyth Library
    82.6 - *
    82.7 - * @file gmyth/gmyth_monitor_handler.h
    82.8 - * 
    82.9 - * @brief <p> GMythMonitorHandler deals with the streaming media events remote/local
   82.10 - * that are sent to the MythTV frontend.
   82.11 - *
   82.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   82.13 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
   82.14 - *
   82.15 - * 
   82.16 - * This program is free software; you can redistribute it and/or modify
   82.17 - * it under the terms of the GNU Lesser General Public License as published by
   82.18 - * the Free Software Foundation; either version 2 of the License, or
   82.19 - * (at your option) any later version.
   82.20 - *
   82.21 - * This program is distributed in the hope that it will be useful,
   82.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   82.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   82.24 - * GNU General Public License for more details.
   82.25 - *
   82.26 - * You should have received a copy of the GNU Lesser General Public License
   82.27 - * along with this program; if not, write to the Free Software
   82.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   82.29 - */
   82.30 -
   82.31 -#ifndef __GMYTH_MONITOR_HANDLER_H__
   82.32 -#define __GMYTH_MONITOR_HANDLER_H__
   82.33 -
   82.34 -#include <glib-object.h>
   82.35 -#include <glib.h>
   82.36 -#include <stdio.h>
   82.37 -#include <stdlib.h>
   82.38 -#include <string.h>
   82.39 -
   82.40 -#include <netdb.h>
   82.41 -#include <sys/socket.h>
   82.42 -#include <unistd.h>
   82.43 -
   82.44 -#include "gmyth_socket.h"
   82.45 -#include "gmyth_uri.h"
   82.46 -
   82.47 -G_BEGIN_DECLS
   82.48 -#define GMYTH_MONITOR_HANDLER_TYPE               (gmyth_monitor_handler_get_type ())
   82.49 -#define GMYTH_MONITOR_HANDLER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_MONITOR_HANDLER_TYPE, GMythMonitorHandler))
   82.50 -#define GMYTH_MONITOR_HANDLER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_MONITOR_HANDLER_TYPE, GMythMonitorHandlerClass))
   82.51 -#define IS_GMYTH_MONITOR_HANDLER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_MONITOR_HANDLER_TYPE))
   82.52 -#define IS_GMYTH_MONITOR_HANDLER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_MONITOR_HANDLER_TYPE))
   82.53 -#define GMYTH_MONITOR_HANDLER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_MONITOR_HANDLER_TYPE, GMythMonitorHandlerClass))
   82.54 -#define GMYTHTV_MONITOR_HANDLER_READ_ERROR	-314
   82.55 -    enum {
   82.56 -    GMYTH_BACKEND_NO_MESSAGE = 0,
   82.57 -    GMYTH_BACKEND_PROGRAM_INFO_CHANGED,
   82.58 -    GMYTH_BACKEND_DONE_RECORDING,
   82.59 -    GMYTH_BACKEND_STOP_LIVETV
   82.60 -};
   82.61 -
   82.62 -typedef struct _GMythMonitorHandler GMythMonitorHandler;
   82.63 -typedef struct _GMythMonitorHandlerClass GMythMonitorHandlerClass;
   82.64 -
   82.65 -struct _GMythMonitorHandlerClass {
   82.66 -    GObjectClass    parent_class;
   82.67 -
   82.68 -    /*
   82.69 -     * callbacks
   82.70 -     */
   82.71 -    guint           backend_events_handler_signal_id;
   82.72 -
   82.73 -    /*
   82.74 -     * signal default handlers
   82.75 -     */
   82.76 -    void            (*backend_events_handler) (GMythMonitorHandler *
   82.77 -                                               monitor, gint msg_code,
   82.78 -                                               gchar * message);
   82.79 -};
   82.80 -
   82.81 -struct _GMythMonitorHandler {
   82.82 -    GObject         parent;
   82.83 -
   82.84 -    /*
   82.85 -     * MythTV version number 
   82.86 -     */
   82.87 -    gint            mythtv_version;
   82.88 -
   82.89 -    /*
   82.90 -     * socket descriptors 
   82.91 -     */
   82.92 -    GMythSocket    *event_sock;
   82.93 -
   82.94 -    //gpointer(*gmyth_monitor_handler_listener) (gpointer data);
   82.95 -
   82.96 -    gchar          *hostname;
   82.97 -    gint            port;
   82.98 -
   82.99 -    gint64          actual_index;
  82.100 -
  82.101 -    gboolean        allow_msgs_listener;
  82.102 -
  82.103 -    /*
  82.104 -     * stores the messages coming from the backend 
  82.105 -     */
  82.106 -    GHashTable     *backend_msgs;
  82.107 -
  82.108 -    GMutex         *mutex;
  82.109 -    guint           io_source;
  82.110 -};
  82.111 -
  82.112 -GType           gmyth_monitor_handler_get_type(void);
  82.113 -
  82.114 -GMythMonitorHandler *gmyth_monitor_handler_new(void);
  82.115 -
  82.116 -gboolean        gmyth_monitor_handler_open(GMythMonitorHandler * monitor,
  82.117 -                                           const gchar * hostname,
  82.118 -                                           gint port);
  82.119 -
  82.120 -gboolean        gmyth_monitor_handler_start(GMythMonitorHandler * monitor);
  82.121 -
  82.122 -void            gmyth_monitor_handler_close(GMythMonitorHandler * monitor);
  82.123 -
  82.124 -G_END_DECLS
  82.125 -#endif                          /* __GMYTH_MONITOR_HANDLER_H__ */
    83.1 --- a/gmyth/src/gmyth_programinfo.c	Mon Feb 25 17:45:36 2008 +0000
    83.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.3 @@ -1,582 +0,0 @@
    83.4 -/**
    83.5 - * GMyth Library
    83.6 - *
    83.7 - * @file gmyth/gmyth_programinfo.c
    83.8 - * 
    83.9 - * @brief <p> GMythProgramInfo representing the program info, with the
   83.10 - * configuration data to the actual remote file in the TV chain.
   83.11 - *
   83.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   83.13 - * @author Rosfran Borges <rosfran.borges@indt.org.br>
   83.14 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   83.15 - *
   83.16 - * 
   83.17 - * This program is free software; you can redistribute it and/or modify
   83.18 - * it under the terms of the GNU Lesser General Public License as published by
   83.19 - * the Free Software Foundation; either version 2 of the License, or
   83.20 - * (at your option) any later version.
   83.21 - *
   83.22 - * This program is distributed in the hope that it will be useful,
   83.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   83.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   83.25 - * GNU General Public License for more details.
   83.26 - *
   83.27 - * You should have received a copy of the GNU Lesser General Public License
   83.28 - * along with this program; if not, write to the Free Software
   83.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   83.30 - *
   83.31 - */
   83.32 -
   83.33 -#ifdef HAVE_CONFIG_H
   83.34 -#include "config.h"
   83.35 -#endif
   83.36 -
   83.37 -#include <stdlib.h>
   83.38 -#include <string.h>
   83.39 -#include <assert.h>
   83.40 -
   83.41 -#include "gmyth_programinfo.h"
   83.42 -#include "gmyth_util.h"
   83.43 -#include "gmyth_debug.h"
   83.44 -
   83.45 -static void     gmyth_program_info_class_init(GMythProgramInfoClass *
   83.46 -                                              klass);
   83.47 -static void     gmyth_program_info_init(GMythProgramInfo * object);
   83.48 -
   83.49 -static void     gmyth_program_info_dispose(GObject * object);
   83.50 -static void     gmyth_program_info_finalize(GObject * object);
   83.51 -
   83.52 -G_DEFINE_TYPE(GMythProgramInfo, gmyth_program_info, G_TYPE_OBJECT)
   83.53 -    static const gchar *gmyth_program_info_non_null_value(const GString *
   83.54 -                                                          str);
   83.55 -
   83.56 -    static void     gmyth_program_info_class_init(GMythProgramInfoClass *
   83.57 -                                                  klass)
   83.58 -{
   83.59 -    GObjectClass   *gobject_class = G_OBJECT_CLASS(klass);
   83.60 -
   83.61 -    gobject_class->dispose = gmyth_program_info_dispose;
   83.62 -    gobject_class->finalize = gmyth_program_info_finalize;
   83.63 -}
   83.64 -
   83.65 -static void
   83.66 -gmyth_program_info_init(GMythProgramInfo * gmyth_program_info)
   83.67 -{
   83.68 -    gmyth_program_info->chancommfree = 0;
   83.69 -
   83.70 -    /** A flag informing if the program has video or not. */
   83.71 -    gmyth_program_info->isVideo = FALSE;
   83.72 -    gmyth_program_info->lenMins = 0;
   83.73 -
   83.74 -    gmyth_program_info->stars = 0.0f;
   83.75 -    gmyth_program_info->repeat = 0;
   83.76 -
   83.77 -    gmyth_program_info->hasAirDate = FALSE;
   83.78 -
   83.79 -    gmyth_program_info->spread = 0;
   83.80 -    gmyth_program_info->startCol = 0;
   83.81 -
   83.82 -    gmyth_program_info->recpriority2 = 0;
   83.83 -    gmyth_program_info->reactivate = 0;
   83.84 -
   83.85 -    gmyth_program_info->recordid = 0;
   83.86 -    gmyth_program_info->parentid = 0;
   83.87 -
   83.88 -    /** The backend video source id associated to this program.*/
   83.89 -    gmyth_program_info->sourceid = 0;
   83.90 -    /** the backend input id associated to this program.*/
   83.91 -    gmyth_program_info->inputid = 0;
   83.92 -    /** The backend card id associated to this program.*/
   83.93 -    gmyth_program_info->cardid = 0;
   83.94 -    gmyth_program_info->shareable = FALSE;
   83.95 -    gmyth_program_info->duplicate = FALSE;
   83.96 -
   83.97 -    gmyth_program_info->findid = 0;
   83.98 -
   83.99 -    gmyth_program_info->programflags = 0;
  83.100 -    gmyth_program_info->transcoder = 0;
  83.101 -
  83.102 -    gmyth_program_info->recpriority = 0;
  83.103 -
  83.104 -    /** The file size of the recorded program.*/
  83.105 -    gmyth_program_info->filesize = -1;
  83.106 -}
  83.107 -
  83.108 -static void
  83.109 -gmyth_program_info_dispose(GObject * object)
  83.110 -{
  83.111 -    GMythProgramInfo *gmyth_program_info = GMYTH_PROGRAM_INFO(object);
  83.112 -
  83.113 -    /** The program start time. */
  83.114 -    g_free(gmyth_program_info->startts);
  83.115 -
  83.116 -    /** The program end time. */
  83.117 -    g_free(gmyth_program_info->endts);
  83.118 -
  83.119 -    /** The recording schedule start time. */
  83.120 -    g_free(gmyth_program_info->recstartts);
  83.121 -
  83.122 -    /** The recording schedule end time */
  83.123 -    g_free(gmyth_program_info->recendts);
  83.124 -
  83.125 -    /** The program title. */
  83.126 -    if (gmyth_program_info->title != NULL) {
  83.127 -        g_string_free(gmyth_program_info->title, TRUE);
  83.128 -        gmyth_program_info->title = NULL;
  83.129 -    }
  83.130 -
  83.131 -    /** The program subtitle. */
  83.132 -    if (gmyth_program_info->subtitle != NULL) {
  83.133 -        g_string_free(gmyth_program_info->subtitle, TRUE);
  83.134 -        gmyth_program_info->subtitle = NULL;
  83.135 -    }
  83.136 -
  83.137 -    /** The program description. */
  83.138 -    if (gmyth_program_info->description != NULL) {
  83.139 -        g_string_free(gmyth_program_info->description, TRUE);
  83.140 -        gmyth_program_info->description = NULL;
  83.141 -    }
  83.142 -
  83.143 -    /** The program category. */
  83.144 -    if (gmyth_program_info->category != NULL) {
  83.145 -        g_string_free(gmyth_program_info->category, TRUE);
  83.146 -        gmyth_program_info->category = NULL;
  83.147 -    }
  83.148 -
  83.149 -    if (gmyth_program_info->chanstr != NULL) {
  83.150 -        g_string_free(gmyth_program_info->chanstr, TRUE);
  83.151 -        gmyth_program_info->chanstr = NULL;
  83.152 -    }
  83.153 -
  83.154 -    if (gmyth_program_info->chansign != NULL) {
  83.155 -        g_string_free(gmyth_program_info->chansign, TRUE);
  83.156 -        gmyth_program_info->chansign = NULL;
  83.157 -    }
  83.158 -
  83.159 -    /** The associated channel name. */
  83.160 -    if (gmyth_program_info->channame != NULL) {
  83.161 -        g_string_free(gmyth_program_info->channame, TRUE);
  83.162 -        gmyth_program_info->channame = NULL;
  83.163 -    }
  83.164 -
  83.165 -    if (gmyth_program_info->chanOutputFilters != NULL) {
  83.166 -        g_string_free(gmyth_program_info->chanOutputFilters, TRUE);
  83.167 -        gmyth_program_info->chanOutputFilters = NULL;
  83.168 -    }
  83.169 -
  83.170 -    if (gmyth_program_info->seriesid != NULL) {
  83.171 -        g_string_free(gmyth_program_info->seriesid, TRUE);
  83.172 -        gmyth_program_info->chanOutputFilters = NULL;
  83.173 -    }
  83.174 -
  83.175 -    /** The program unique id. */
  83.176 -    if (gmyth_program_info->program_id != NULL) {
  83.177 -        g_string_free (gmyth_program_info->program_id, TRUE);
  83.178 -        gmyth_program_info->program_id = NULL;
  83.179 -    }
  83.180 -
  83.181 -    if (gmyth_program_info->catType != NULL) {
  83.182 -        g_string_free(gmyth_program_info->catType, TRUE);
  83.183 -        gmyth_program_info->catType = NULL;
  83.184 -    }
  83.185 -
  83.186 -    if (gmyth_program_info->sortTitle != NULL) {
  83.187 -        g_string_free(gmyth_program_info->sortTitle, TRUE);
  83.188 -        gmyth_program_info->sortTitle = NULL;
  83.189 -    }
  83.190 -
  83.191 -    if (gmyth_program_info->year != NULL) {
  83.192 -        g_string_free(gmyth_program_info->year, TRUE);
  83.193 -        gmyth_program_info->year = NULL;
  83.194 -    }
  83.195 -
  83.196 -    g_free(gmyth_program_info->originalAirDate);
  83.197 -
  83.198 -    g_free(gmyth_program_info->lastmodified);
  83.199 -
  83.200 -    g_free(gmyth_program_info->lastInUseTime);
  83.201 -
  83.202 -    if (gmyth_program_info->schedulerid != NULL) {
  83.203 -        g_string_free(gmyth_program_info->schedulerid, TRUE);
  83.204 -        gmyth_program_info->schedulerid = NULL;
  83.205 -    }
  83.206 -
  83.207 -    if (gmyth_program_info->recgroup != NULL) {
  83.208 -        g_string_free(gmyth_program_info->recgroup, TRUE);
  83.209 -        gmyth_program_info->recgroup = NULL;
  83.210 -    }
  83.211 -
  83.212 -    if (gmyth_program_info->playgroup != NULL) {
  83.213 -        g_string_free(gmyth_program_info->playgroup, TRUE);
  83.214 -        gmyth_program_info->playgroup = NULL;
  83.215 -    }
  83.216 -
  83.217 -    /** The file name of the recorded program.*/
  83.218 -    if (gmyth_program_info->pathname != NULL) {
  83.219 -        g_string_free(gmyth_program_info->pathname, TRUE);
  83.220 -        gmyth_program_info->pathname = NULL;
  83.221 -    }
  83.222 -
  83.223 -    if (gmyth_program_info->hostname != NULL) {
  83.224 -        g_string_free(gmyth_program_info->hostname, TRUE);
  83.225 -        gmyth_program_info->hostname = NULL;
  83.226 -    }
  83.227 -
  83.228 -    G_OBJECT_CLASS(gmyth_program_info_parent_class)->dispose(object);
  83.229 -}
  83.230 -
  83.231 -static void
  83.232 -gmyth_program_info_finalize(GObject * object)
  83.233 -{
  83.234 -    g_signal_handlers_destroy(object);
  83.235 -
  83.236 -    G_OBJECT_CLASS(gmyth_program_info_parent_class)->finalize(object);
  83.237 -}
  83.238 -
  83.239 -/**
  83.240 - * Creates a new instance of GMythProgramInfo.
  83.241 - * 
  83.242 - * @return a new instance of GMythProgramInfo.
  83.243 - */
  83.244 -GMythProgramInfo *
  83.245 -gmyth_program_info_new(void)
  83.246 -{
  83.247 -    GMythProgramInfo *program_info =
  83.248 -        GMYTH_PROGRAM_INFO(g_object_new(GMYTH_PROGRAM_INFO_TYPE, NULL));
  83.249 -
  83.250 -    return program_info;
  83.251 -}
  83.252 -
  83.253 -/**
  83.254 - * Converts an instance of a GMythProgramInfo, to a GMythStringList.
  83.255 - * 
  83.256 - * @param prog A GMythProgramInfo instance.
  83.257 - * @param slist The GMythStringList to be passed to this function, in order to
  83.258 - * 							give the responsibility of the string list creation to the
  83.259 - * 						  API user.
  83.260 - * 
  83.261 - * @return a GMythStringList with the program info fields.
  83.262 - */
  83.263 -GMythStringList *
  83.264 -gmyth_program_info_to_string_list(GMythProgramInfo * prog,
  83.265 -                                  GMythStringList * slist)
  83.266 -{
  83.267 -    g_return_val_if_fail(prog != NULL, NULL);
  83.268 -    g_return_val_if_fail(slist != NULL, NULL);
  83.269 -
  83.270 -    gmyth_string_list_append_string(slist, prog->title);    /* 0 */
  83.271 -    gmyth_string_list_append_string(slist, prog->subtitle); /* 1 */
  83.272 -    gmyth_string_list_append_string(slist, prog->description);  /* 2 */
  83.273 -    gmyth_string_list_append_string(slist, prog->category); /* 3 */
  83.274 -    gmyth_string_list_append_int (slist, prog->channel_id);   /* 4 */
  83.275 -    gmyth_string_list_append_string(slist, prog->chanstr);  /* 5 */
  83.276 -    gmyth_string_list_append_string(slist, prog->chansign); /* 6 */
  83.277 -    gmyth_string_list_append_string(slist, prog->channame); /* 7 */
  83.278 -    gmyth_string_list_append_string(slist, prog->pathname); /* 8 */
  83.279 -    gmyth_string_list_append_int64(slist, 0);   /* 9 */
  83.280 -
  83.281 -    // fixme
  83.282 -    // gmyth_string_list_append_int64 (slist, 100/*prog->filesize*/); /* 9 
  83.283 -    // 
  83.284 -    // 
  83.285 -    // */
  83.286 -    // gmyth_string_list_append_int (slist, 0); /* 10 */
  83.287 -
  83.288 -    if (prog->startts)
  83.289 -        gmyth_string_list_append_int(slist, prog->startts->tv_sec); /* 11 */// DATETIME_TO_LIST(startts)
  83.290 -    else
  83.291 -        gmyth_string_list_append_int(slist, 0);
  83.292 -
  83.293 -    if (prog->endts)
  83.294 -        gmyth_string_list_append_int(slist, prog->endts->tv_sec);   /* 12 */// DATETIME_TO_LIST(endts)
  83.295 -    else
  83.296 -        gmyth_string_list_append_int(slist, 0);
  83.297 -
  83.298 -    gmyth_string_list_append_int(slist, prog->duplicate);   /* 13 */
  83.299 -    gmyth_string_list_append_int(slist, prog->shareable);   /* 14 */
  83.300 -    gmyth_string_list_append_int(slist, prog->findid);  /* 15 */
  83.301 -    gmyth_string_list_append_string(slist, prog->hostname); /* 16 */
  83.302 -    gmyth_string_list_append_int(slist, prog->sourceid);    /* 17 */
  83.303 -    gmyth_string_list_append_int(slist, prog->cardid);  /* 18 */
  83.304 -    gmyth_string_list_append_int(slist, prog->inputid); /* 19 */
  83.305 -    gmyth_string_list_append_int(slist, prog->recpriority); /* 20 */
  83.306 -    gmyth_string_list_append_int(slist, 0 /* prog->recstatus */ );  /* 21 */
  83.307 -    gmyth_string_list_append_int(slist, prog->recordid);    /* 22 */
  83.308 -    gmyth_string_list_append_int(slist, 0 /* prog->rectype */ );    /* 23 */
  83.309 -    gmyth_string_list_append_int(slist, 0 /* prog->dupin */ );  /* 24 */
  83.310 -    gmyth_string_list_append_int(slist, 0 /* prog->dupmethod */ );  /* 25 */
  83.311 -    gmyth_string_list_append_int(slist, prog->recstartts != NULL ? prog->recstartts->tv_sec : 0);   /* 26 
  83.312 -     */// DATETIME_TO_LIST(recstartts)
  83.313 -    gmyth_string_list_append_int(slist, prog->recendts != NULL ? prog->recendts->tv_sec : 0);   /* 27 
  83.314 -     */// DATETIME_TO_LIST(recendts)
  83.315 -    gmyth_string_list_append_int(slist, prog->repeat);  /* 28 */
  83.316 -    gmyth_string_list_append_int(slist, prog->programflags);    /* 29 */
  83.317 -    gmyth_string_list_append_char_array(slist, "Default");  /* 30 */// prog->(recgroup 
  83.318 -                                                            // 
  83.319 -    // 
  83.320 -    // != "") ?
  83.321 -    // recgroup :
  83.322 -    // "Default")
  83.323 -    gmyth_string_list_append_int(slist, prog->chancommfree);    /* 31 */
  83.324 -    gmyth_string_list_append_string(slist, prog->chanOutputFilters);    /* 32 
  83.325 -                                                                         */
  83.326 -    gmyth_string_list_append_string(slist, prog->seriesid); /* 33 */
  83.327 -    gmyth_string_list_append_string(slist, prog->program_id);    /* 34 */
  83.328 -    gmyth_string_list_append_char_array(slist, ""); /* 35 */
  83.329 -    gmyth_string_list_append_int(slist, prog->lastmodified != NULL ? prog->lastmodified->tv_sec : 0);   /* 36 
  83.330 -     */// DATETIME_TO_LIST(lastmodified)
  83.331 -    gmyth_string_list_append_int(slist, 0); /* 37 */// FLOAT_TO_LIST(stars)
  83.332 -    gmyth_string_list_append_int(slist, prog->originalAirDate != NULL ? prog->originalAirDate->tv_sec : 0); /* 38 
  83.333 -     */// DATETIME_TO_LIST(QDateTime(originalAirDate))
  83.334 -    gmyth_string_list_append_int(slist, prog->hasAirDate);  /* 39 */
  83.335 -    gmyth_string_list_append_char_array(slist, "Default");  /* 40 */// prog->(playgroup 
  83.336 -                                                            // 
  83.337 -    // 
  83.338 -    // != "") ?
  83.339 -    // playgroup : 
  83.340 -    // "Default")
  83.341 -    gmyth_string_list_append_int(slist, prog->recpriority2);    /* 41 */
  83.342 -
  83.343 -    return slist;
  83.344 -}
  83.345 -
  83.346 -/**
  83.347 - * Converts an instance of a GMythStringList, to a GMythProgramInfo.
  83.348 - * 
  83.349 - * @param slist The GMythStringList got from the MythTV backend server.
  83.350 - * @param pos   The position in the GMythStringList to start getting the fields.
  83.351 - * 
  83.352 - * @return a GMythProgramInfo representing the string list got from network.
  83.353 - */
  83.354 -GMythProgramInfo *
  83.355 -gmyth_program_info_from_string_list_from_pos(GMythStringList * slist,
  83.356 -                                             guint pos)
  83.357 -{
  83.358 -    GMythProgramInfo *prog = gmyth_program_info_new();
  83.359 -
  83.360 -    g_return_val_if_fail(slist != NULL &&
  83.361 -                         gmyth_string_list_get_string(slist, pos) != NULL,
  83.362 -                         NULL);
  83.363 -
  83.364 -    prog->title = gmyth_string_list_get_string(slist, pos);
  83.365 -    prog->subtitle = gmyth_string_list_get_string(slist, pos + 1);
  83.366 -    prog->description = gmyth_string_list_get_string(slist, pos + 2);
  83.367 -    prog->category = gmyth_string_list_get_string(slist, pos + 3);
  83.368 -    prog->channel_id = gmyth_string_list_get_int (slist, pos + 4);
  83.369 -    prog->channame = gmyth_string_list_get_string(slist, pos + 5);
  83.370 -    prog->chanstr = gmyth_string_list_get_string(slist, pos + 6);
  83.371 -    prog->chansign = gmyth_string_list_get_string(slist, pos + 7);
  83.372 -    prog->pathname = gmyth_string_list_get_string(slist, pos + 8);
  83.373 -
  83.374 -    prog->filesize = gmyth_string_list_get_int64(slist, pos + 9);
  83.375 -
  83.376 -    gmyth_debug("Prog info: [ %s, %s, %s, %s, %s, %s, %s, %s, %d ]\n",
  83.377 -                gmyth_program_info_non_null_value(prog->title),
  83.378 -                gmyth_program_info_non_null_value(prog->subtitle),
  83.379 -                gmyth_program_info_non_null_value(prog->description),
  83.380 -                gmyth_program_info_non_null_value(prog->category),
  83.381 -                gmyth_program_info_non_null_value(prog->channame),
  83.382 -                gmyth_program_info_non_null_value(prog->chanstr),
  83.383 -                gmyth_program_info_non_null_value(prog->chansign),
  83.384 -                gmyth_program_info_non_null_value(prog->pathname),
  83.385 -                gmyth_string_list_get_int(slist, pos + 11));
  83.386 -
  83.387 -    prog->startts = gmyth_util_string_to_time_val((gmyth_util_time_to_isoformat((time_t) gmyth_string_list_get_int(slist, pos + 11)))->str);    // DATETIME_TO_LIST(startts)
  83.388 -    prog->endts = gmyth_util_string_to_time_val((gmyth_util_time_to_isoformat((time_t) gmyth_string_list_get_int(slist, pos + 12)))->str);  // DATETIME_TO_LIST(endts)
  83.389 -    prog->duplicate = gmyth_string_list_get_int(slist, pos + 13);
  83.390 -    prog->shareable = gmyth_string_list_get_int(slist, pos + 14);
  83.391 -    prog->findid = gmyth_string_list_get_int(slist, pos + 15);
  83.392 -    prog->hostname = gmyth_string_list_get_string(slist, pos + 16);
  83.393 -    prog->sourceid = gmyth_string_list_get_int(slist, pos + 17);
  83.394 -    prog->cardid = gmyth_string_list_get_int(slist, pos + 18);
  83.395 -    prog->inputid = gmyth_string_list_get_int(slist, pos + 19);
  83.396 -    prog->recpriority = gmyth_string_list_get_int(slist, pos + 20);
  83.397 -    prog->reactivate = gmyth_string_list_get_int(slist, pos + 21);
  83.398 -    prog->recordid = gmyth_string_list_get_int(slist, pos + 22);
  83.399 -    gmyth_string_list_get_int(slist, pos + 23);
  83.400 -    gmyth_string_list_get_int(slist, pos + 24);
  83.401 -    gmyth_string_list_get_int(slist, pos + 25);
  83.402 -    prog->recstartts = gmyth_util_string_to_time_val((gmyth_util_time_to_isoformat((time_t) gmyth_string_list_get_int(slist, pos + 26)))->str); // DATETIME_TO_LIST(recstartts)
  83.403 -    prog->recendts = gmyth_util_string_to_time_val((gmyth_util_time_to_isoformat((time_t) gmyth_string_list_get_int(slist, pos + 27)))->str);   // DATETIME_TO_LIST(recendts)
  83.404 -    prog->repeat = gmyth_string_list_get_int(slist, pos + 28);
  83.405 -    prog->programflags = gmyth_string_list_get_int(slist, pos + 29);
  83.406 -    prog->recgroup = gmyth_string_list_get_string(slist, pos + 30); // prog->(recgroup 
  83.407 -                                                                    // 
  83.408 -    // 
  83.409 -    // !=
  83.410 -    // "") 
  83.411 -    // ?
  83.412 -    // recgroup 
  83.413 -    // :
  83.414 -    // "Default")
  83.415 -    prog->chancommfree = gmyth_string_list_get_int(slist, pos + 31);
  83.416 -    prog->chanOutputFilters =
  83.417 -        gmyth_string_list_get_string(slist, pos + 32);
  83.418 -    prog->seriesid = gmyth_string_list_get_string(slist, pos + 33);
  83.419 -    prog->program_id = gmyth_string_list_get_string(slist, pos + 34);
  83.420 -    gmyth_string_list_get_string(slist, pos + 35);
  83.421 -    prog->lastmodified = gmyth_util_string_to_time_val((gmyth_util_time_to_isoformat((time_t) gmyth_string_list_get_int(slist, pos + 36)))->str);   // DATETIME_TO_LIST(lastmodified)
  83.422 -    gmyth_string_list_get_int(slist, pos + 37); // FLOAT_TO_LIST(stars)
  83.423 -    prog->originalAirDate = gmyth_util_string_to_time_val((gmyth_util_time_to_isoformat((time_t) gmyth_string_list_get_int(slist, pos + 38)))->str);    // DATETIME_TO_LIST(QDateTime(originalAirDate))
  83.424 -    prog->hasAirDate = gmyth_string_list_get_int(slist, pos + 39);
  83.425 -    prog->playgroup = gmyth_string_list_get_string(slist, pos + 40);    // prog->(playgroup 
  83.426 -                                                                        // 
  83.427 -    // 
  83.428 -    // != 
  83.429 -    // "") 
  83.430 -    // ? 
  83.431 -    // playgroup 
  83.432 -    // : 
  83.433 -    // "Default")
  83.434 -    prog->recpriority2 = gmyth_string_list_get_int(slist, pos + 41);
  83.435 -
  83.436 -    return prog;
  83.437 -}
  83.438 -
  83.439 -/**
  83.440 - * Converts an instance of a GMythStringList, to a GMythProgramInfo.
  83.441 - * 
  83.442 - * @param slist The GMythStringList got from the MythTV backend server.
  83.443 - * 
  83.444 - * @return a GMythProgramInfo representing the string list got from network.
  83.445 - */
  83.446 -GMythProgramInfo *
  83.447 -gmyth_program_info_from_string_list(GMythStringList * slist)
  83.448 -{
  83.449 -    GMythProgramInfo *prog = NULL;
  83.450 -
  83.451 -    g_return_val_if_fail(slist != NULL, NULL);
  83.452 -
  83.453 -    prog = gmyth_program_info_from_string_list_from_pos(slist, 0);
  83.454 -
  83.455 -    return prog;
  83.456 -}
  83.457 -
  83.458 -/**
  83.459 - * Converts an instance of a GMythStringList, to a GMythProgramInfo ( NEXT_PROGRAM_INFO ).
  83.460 - * 
  83.461 - * @param slist The GMythStringList got from the MythTV backend server.
  83.462 - * 
  83.463 - * @return a GMythProgramInfo representing the string list got from network.
  83.464 - */
  83.465 -GMythProgramInfo *
  83.466 -gmyth_program_info_from_string_list_next_prog(GMythStringList * slist)
  83.467 -{
  83.468 -    GMythProgramInfo *prog = gmyth_program_info_new();
  83.469 -
  83.470 -    g_return_val_if_fail(slist != NULL, NULL);
  83.471 -
  83.472 -    /*
  83.473 -     * {Home Improvement[]:[]No, No, Godot[]:[] US sitcom about a
  83.474 -     * DIY-obsessed father of three. When Tim tries to sell off his extra 
  83.475 -     * ticket for an ice hockey game, he is arrested as a tout.[]:[]
  83.476 -     * Sitcom[]:[]2007-04-18T15:30:00[]:[]2007-04-18T16:00:00[]:[]ABC1[]:[]
  83.477 -     * /home/hmelo/.mythtv/channels/abc1.jpg[]:[]abc1[]:[]2000[]:[]25725844[]:[] 
  83.478 -     * } 
  83.479 -     */
  83.480 -
  83.481 -    prog->title = gmyth_string_list_get_string(slist, 0);
  83.482 -    prog->subtitle = gmyth_string_list_get_string(slist, 1);
  83.483 -    prog->description = gmyth_string_list_get_string(slist, 2);
  83.484 -    prog->category = gmyth_string_list_get_string(slist, 3);
  83.485 -    prog->startts = gmyth_util_string_to_time_val(gmyth_string_list_get_char_array(slist, 4));  // DATETIME_TO_LIST(startts)
  83.486 -    prog->endts = gmyth_util_string_to_time_val(gmyth_string_list_get_char_array(slist, 5));    // DATETIME_TO_LIST(endts)
  83.487 -    prog->channame = gmyth_string_list_get_string(slist, 6);
  83.488 -    prog->chansign = gmyth_string_list_get_string(slist, 7);
  83.489 -    prog->chanstr = gmyth_string_list_get_string(slist, 8);
  83.490 -    prog->channel_id = gmyth_string_list_get_int (slist, 9);
  83.491 -    prog->filesize = gmyth_string_list_get_int64(slist, 10);
  83.492 -
  83.493 -    gmyth_debug
  83.494 -        ("NEXT program info: [ %s, %s, %s, %s, %s, %s, %s, %s ]\n",
  83.495 -         gmyth_program_info_non_null_value(prog->title),
  83.496 -         gmyth_program_info_non_null_value(prog->subtitle),
  83.497 -         gmyth_program_info_non_null_value(prog->description),
  83.498 -         gmyth_program_info_non_null_value(prog->category),
  83.499 -         gmyth_program_info_non_null_value(prog->channame),
  83.500 -         gmyth_program_info_non_null_value(prog->chanstr),
  83.501 -         gmyth_program_info_non_null_value(prog->chansign),
  83.502 -         gmyth_program_info_non_null_value(prog->pathname));
  83.503 -
  83.504 -    return prog;
  83.505 -}
  83.506 -
  83.507 -static const gchar *
  83.508 -gmyth_program_info_non_null_value(const GString * str)
  83.509 -{
  83.510 -    return (str != NULL && str->str != NULL
  83.511 -            && strlen(str->str) > 0 ? str->str : " ");
  83.512 -}
  83.513 -
  83.514 -/**
  83.515 - * Prints out an instance of a GMythProgramInfo.
  83.516 - * 
  83.517 - * @param prog A GMythProgramInfo instance.
  83.518 - * 
  83.519 - * @return a string representing the program info.
  83.520 - */
  83.521 -const gchar    *
  83.522 -gmyth_program_info_to_string(const GMythProgramInfo * prog)
  83.523 -{
  83.524 -    return
  83.525 -        g_strdup_printf
  83.526 -        ("Title: %s, Subtitle: %s, Description: %s, Category: %s, Channel ID: %d, "
  83.527 -         "Channel Name: %s, Chan str: %s, Channel Sign: %s, Path Name: %s, File Size: %lld, \n"
  83.528 -         "Start TS: %s, End TS: %s, Duplicate: %d, Shareable: %d, Find ID: %d, Hostname: %s, "
  83.529 -         "Source ID: %d, Vard ID: %d, Input ID: %d, Rec Priority: %d, Reactivate: %d, \n"
  83.530 -         "Record ID: %d, Rec Start TS: %s, Rec End TS: %s, Repeat: %d, Program Flags: %d, "
  83.531 -         "Rec Group: %s, Channel Comm Free: %d, Channel Output Filters: %s, Series ID: %s, \n"
  83.532 -         "Program ID: %s, Last Modified Date: %s, Original Air Date: %s, Has Air Date: %d, "
  83.533 -         "Play Group: %s.\n",
  83.534 -         gmyth_program_info_non_null_value(prog->title),
  83.535 -         gmyth_program_info_non_null_value(prog->subtitle),
  83.536 -         gmyth_program_info_non_null_value(prog->description),
  83.537 -         gmyth_program_info_non_null_value(prog->category),
  83.538 -         prog->channel_id,
  83.539 -         gmyth_program_info_non_null_value(prog->channame),
  83.540 -         gmyth_program_info_non_null_value(prog->chanstr),
  83.541 -         gmyth_program_info_non_null_value(prog->chansign),
  83.542 -         gmyth_program_info_non_null_value(prog->pathname), prog->filesize,
  83.543 -         gmyth_util_time_to_string_from_time_val(prog->startts),
  83.544 -         gmyth_util_time_to_string_from_time_val(prog->endts),
  83.545 -         prog->duplicate, prog->shareable, prog->findid,
  83.546 -         gmyth_program_info_non_null_value(prog->hostname), prog->sourceid,
  83.547 -         prog->cardid, prog->inputid, prog->recpriority, prog->reactivate,
  83.548 -         prog->recordid,
  83.549 -         gmyth_util_time_to_string_from_time_val(prog->recstartts),
  83.550 -         gmyth_util_time_to_string_from_time_val(prog->recendts),
  83.551 -         prog->repeat, prog->programflags,
  83.552 -         gmyth_program_info_non_null_value(prog->recgroup),
  83.553 -         prog->chancommfree,
  83.554 -         gmyth_program_info_non_null_value(prog->chanOutputFilters),
  83.555 -         gmyth_program_info_non_null_value(prog->seriesid),
  83.556 -         gmyth_program_info_non_null_value(prog->program_id),
  83.557 -         gmyth_util_time_to_string_from_time_val(prog->lastmodified),
  83.558 -         gmyth_util_time_to_string_from_time_val(prog->originalAirDate),
  83.559 -         prog->hasAirDate,
  83.560 -         gmyth_program_info_non_null_value(prog->playgroup));
  83.561 -}
  83.562 -
  83.563 -/**
  83.564 - * Say if an instance of a GMythProgramInfo is equals to another one.
  83.565 - * 
  83.566 - * @param prog The first GMythProgramInfo instance.
  83.567 - * @param prog The second GMythProgramInfo instance.
  83.568 - * 
  83.569 - * @return <code>true</code>, if the program infos are equals.
  83.570 - */
  83.571 -gboolean
  83.572 -gmyth_program_info_is_equals(const GMythProgramInfo * prog1,
  83.573 -                             const GMythProgramInfo * prog2)
  83.574 -{
  83.575 -    if ((strcmp(gmyth_program_info_non_null_value(prog1->title),
  83.576 -                gmyth_program_info_non_null_value(prog2->title)) == 0)
  83.577 -        ||
  83.578 -        (strcmp
  83.579 -         (gmyth_program_info_non_null_value(prog1->pathname),
  83.580 -          gmyth_program_info_non_null_value(prog2->pathname)) == 0))
  83.581 -        return TRUE;
  83.582 -    else
  83.583 -        return FALSE;
  83.584 -
  83.585 -}
    84.1 --- a/gmyth/src/gmyth_programinfo.h	Mon Feb 25 17:45:36 2008 +0000
    84.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.3 @@ -1,180 +0,0 @@
    84.4 -/**
    84.5 - * GMyth Library
    84.6 - *
    84.7 - * @file gmyth/gmyth_programinfo.h
    84.8 - * 
    84.9 - * @brief <p> GMythProgramInfo representing the program info, with the
   84.10 - * configuration data to the actual remote file in the TV chain.
   84.11 - *
   84.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   84.13 - * @author Rosfran Borges <rosfran.borges@indt.org.br>
   84.14 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   84.15 - *
   84.16 - * 
   84.17 - * This program is free software; you can redistribute it and/or modify
   84.18 - * it under the terms of the GNU Lesser General Public License as published by
   84.19 - * the Free Software Foundation; either version 2 of the License, or
   84.20 - * (at your option) any later version.
   84.21 - *
   84.22 - * This program is distributed in the hope that it will be useful,
   84.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   84.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   84.25 - * GNU General Public License for more details.
   84.26 - *
   84.27 - * You should have received a copy of the GNU Lesser General Public License
   84.28 - * along with this program; if not, write to the Free Software
   84.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   84.30 - *
   84.31 - */
   84.32 -
   84.33 -#ifndef _GMYTH_PROGRAMINFO_H
   84.34 -#define _GMYTH_PROGRAMINFO_H
   84.35 -
   84.36 -#include <glib.h>
   84.37 -#include <glib-object.h>
   84.38 -
   84.39 -#include "gmyth_stringlist.h"
   84.40 -
   84.41 -G_BEGIN_DECLS
   84.42 -#define GMYTH_PROGRAM_INFO_TYPE               (gmyth_program_info_get_type ())
   84.43 -#define GMYTH_PROGRAM_INFO(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_PROGRAM_INFO_TYPE, GMythProgramInfo))
   84.44 -#define GMYTH_PROGRAM_INFO_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_PROGRAM_INFO_TYPE, GMythProgramInfoClass))
   84.45 -#define IS_GMYTH_PROGRAM_INFO(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_PROGRAM_INFO_TYPE))
   84.46 -#define IS_GMYTH_PROGRAM_INFO_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_PROGRAM_INFO_TYPE))
   84.47 -#define GMYTH_PROGRAM_INFO_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_PROGRAM_INFO_TYPE, GMythProgramInfoClass))
   84.48 -typedef struct _GMythProgramInfo GMythProgramInfo;
   84.49 -typedef struct _GMythProgramInfoClass GMythProgramInfoClass;
   84.50 -
   84.51 -struct _GMythProgramInfoClass {
   84.52 -    GObjectClass    parent_class;
   84.53 -
   84.54 -    /*
   84.55 -     * callbacks 
   84.56 -     */
   84.57 -};
   84.58 -
   84.59 -/**
   84.60 - * The GMythProgramInfo structure represents a program information
   84.61 - * stored in the database. It could be a program from the EPG data,
   84.62 - * a program scheduled to be recorded, or a program already recorded.
   84.63 - */
   84.64 -struct _GMythProgramInfo {
   84.65 -    GObject         parent;
   84.66 -
   84.67 -    /** The channel unique ID. */
   84.68 -    gint            channel_id;
   84.69 -    /** The program start time. */
   84.70 -    GTimeVal       *startts;
   84.71 -    /** The program end time. */
   84.72 -    GTimeVal       *endts;
   84.73 -    /** The recording schedule start time. */
   84.74 -    GTimeVal       *recstartts;
   84.75 -    /** The recording schedule end time */
   84.76 -    GTimeVal       *recendts;
   84.77 -
   84.78 -    /** The program title. */
   84.79 -    GString        *title;
   84.80 -    /** The program subtitle. */
   84.81 -    GString        *subtitle;
   84.82 -    /** The program description. */
   84.83 -    GString        *description;
   84.84 -    /** The program category. */
   84.85 -    GString        *category;
   84.86 -
   84.87 -    GString        *chanstr;
   84.88 -    GString        *chansign;
   84.89 -    /** The associated channel name. */
   84.90 -    GString        *channame;
   84.91 -    gint            chancommfree;
   84.92 -    GString        *chanOutputFilters;
   84.93 -
   84.94 -    GString        *seriesid;
   84.95 -    /** The program unique id. */
   84.96 -    GString        *program_id;
   84.97 -    GString        *catType;
   84.98 -
   84.99 -    GString        *sortTitle;
  84.100 -
  84.101 -    /** A flag informing if the program has video or not. */
  84.102 -    gboolean        isVideo;
  84.103 -    gint            lenMins;
  84.104 -
  84.105 -    GString        *year;
  84.106 -    gdouble         stars;
  84.107 -    gint            repeat;
  84.108 -
  84.109 -    GTimeVal       *originalAirDate;
  84.110 -    GTimeVal       *lastmodified;
  84.111 -    GTimeVal       *lastInUseTime;
  84.112 -
  84.113 -    gboolean        hasAirDate;
  84.114 -
  84.115 -    gint            spread;
  84.116 -    gint            startCol;
  84.117 -
  84.118 -    gint            recpriority2;
  84.119 -    gint            reactivate;
  84.120 -
  84.121 -    gint            recordid;
  84.122 -    gint            parentid;
  84.123 -
  84.124 -    /** The backend video source id associated to this program.*/
  84.125 -    gint            sourceid;
  84.126 -    /** the backend input id associated to this program.*/
  84.127 -    gint            inputid;
  84.128 -    /** The backend card id associated to this program.*/
  84.129 -    gint            cardid;
  84.130 -    gboolean        shareable;
  84.131 -    gboolean        duplicate;
  84.132 -
  84.133 -    GString        *schedulerid;
  84.134 -    gint            findid;
  84.135 -
  84.136 -    gint            programflags;
  84.137 -    gint            transcoder;
  84.138 -
  84.139 -    GString        *recgroup;
  84.140 -    GString        *playgroup;
  84.141 -    gint            rectype;
  84.142 -    gint            recstatus;
  84.143 -    gint            recpriority;
  84.144 -    gint            dupin;
  84.145 -    gint            dupmethod;
  84.146 -
  84.147 -    /** The file size of the recorded program.*/
  84.148 -    gint64          filesize;
  84.149 -
  84.150 -    /** The file name of the recorded program.*/
  84.151 -    GString        *pathname;
  84.152 -    GString        *hostname;
  84.153 -};
  84.154 -
  84.155 -GType           gmyth_program_info_get_type(void);
  84.156 -
  84.157 -GMythProgramInfo *gmyth_program_info_new(void);
  84.158 -
  84.159 -GMythStringList *gmyth_program_info_to_string_list(GMythProgramInfo * prog,
  84.160 -                                                   GMythStringList *
  84.161 -                                                   slist);
  84.162 -
  84.163 -GMythProgramInfo
  84.164 -    * gmyth_program_info_from_string_list_from_pos(GMythStringList * slist,
  84.165 -                                                   guint pos);
  84.166 -
  84.167 -GMythProgramInfo *gmyth_program_info_from_string_list(GMythStringList *
  84.168 -                                                      slist);
  84.169 -
  84.170 -GMythProgramInfo
  84.171 -    * gmyth_program_info_from_string_list_next_prog(GMythStringList *
  84.172 -                                                    slist);
  84.173 -
  84.174 -const gchar    *gmyth_program_info_to_string(const GMythProgramInfo *
  84.175 -                                             prog);
  84.176 -
  84.177 -gboolean        gmyth_program_info_is_equals(const GMythProgramInfo *
  84.178 -                                             prog1,
  84.179 -                                             const GMythProgramInfo *
  84.180 -                                             prog2);
  84.181 -
  84.182 -G_END_DECLS
  84.183 -#endif /*_GMYTH_PROGRAMINFO_H*/
    85.1 --- a/gmyth/src/gmyth_query.c	Mon Feb 25 17:45:36 2008 +0000
    85.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.3 @@ -1,280 +0,0 @@
    85.4 -/**
    85.5 - * GMyth Library
    85.6 - *
    85.7 - * @file gmyth/gmyth_query.c
    85.8 - * 
    85.9 - * @brief <p> GMythQuery class provides a wrapper for accessing
   85.10 - * the libmysqlclient funtions.
   85.11 - *
   85.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   85.13 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   85.14 - *
   85.15 - * 
   85.16 - * This program is free software; you can redistribute it and/or modify
   85.17 - * it under the terms of the GNU Lesser General Public License as published by
   85.18 - * the Free Software Foundation; either version 2 of the License, or
   85.19 - * (at your option) any later version.
   85.20 - *
   85.21 - * This program is distributed in the hope that it will be useful,
   85.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   85.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   85.24 - * GNU General Public License for more details.
   85.25 - *
   85.26 - * You should have received a copy of the GNU Lesser General Public License
   85.27 - * along with this program; if not, write to the Free Software
   85.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   85.29 - */
   85.30 -
   85.31 -#ifdef HAVE_CONFIG_H
   85.32 -#include "config.h"
   85.33 -#endif
   85.34 -
   85.35 -#include <stdlib.h>
   85.36 -#include <stdio.h>
   85.37 -#include <assert.h>
   85.38 -
   85.39 -#include "gmyth_query.h"
   85.40 -#include "gmyth_debug.h"
   85.41 -
   85.42 -static void     gmyth_query_class_init(GMythQueryClass * klass);
   85.43 -static void     gmyth_query_init(GMythQuery * object);
   85.44 -
   85.45 -static void     gmyth_query_dispose(GObject * object);
   85.46 -static void     gmyth_query_finalize(GObject * object);
   85.47 -
   85.48 -static void     gmyth_query_print_error(MYSQL * conn, char *message);
   85.49 -
   85.50 -G_DEFINE_TYPE(GMythQuery, gmyth_query, G_TYPE_OBJECT)
   85.51 -    static void     gmyth_query_class_init(GMythQueryClass * klass)
   85.52 -{
   85.53 -    GObjectClass   *gobject_class;
   85.54 -
   85.55 -    gobject_class = (GObjectClass *) klass;
   85.56 -
   85.57 -    gobject_class->dispose = gmyth_query_dispose;
   85.58 -    gobject_class->finalize = gmyth_query_finalize;
   85.59 -}
   85.60 -
   85.61 -static void
   85.62 -gmyth_query_init(GMythQuery * gmyth_query)
   85.63 -{
   85.64 -    gmyth_query->backend_info = NULL;
   85.65 -
   85.66 -    /*
   85.67 -     * initialize connection handler 
   85.68 -     */
   85.69 -    gmyth_query->conn = mysql_init(NULL);
   85.70 -
   85.71 -    if (!(gmyth_query->conn))
   85.72 -        g_warning("[%s] MSQL structure not initialized", __FUNCTION__);
   85.73 -}
   85.74 -
   85.75 -static void
   85.76 -gmyth_query_dispose(GObject * object)
   85.77 -{
   85.78 -    GMythQuery     *gmyth_query = GMYTH_QUERY(object);
   85.79 -
   85.80 -    if (gmyth_query->conn != NULL) {
   85.81 -        gmyth_query_disconnect(gmyth_query);
   85.82 -    }
   85.83 -
   85.84 -    if (gmyth_query->backend_info) {
   85.85 -        g_object_unref(gmyth_query->backend_info);
   85.86 -        gmyth_query->backend_info = NULL;
   85.87 -    }
   85.88 -
   85.89 -    G_OBJECT_CLASS(gmyth_query_parent_class)->dispose(object);
   85.90 -}
   85.91 -
   85.92 -static void
   85.93 -gmyth_query_finalize(GObject * object)
   85.94 -{
   85.95 -    g_signal_handlers_destroy(object);
   85.96 -
   85.97 -    G_OBJECT_CLASS(gmyth_query_parent_class)->finalize(object);
   85.98 -}
   85.99 -
  85.100 -/** Creates a new instance of GMythQuery.
  85.101 - *
  85.102 - * @return a new instance of GMythQuery.
  85.103 - */
  85.104 -GMythQuery     *
  85.105 -gmyth_query_new()
  85.106 -{
  85.107 -    GMythQuery     *sql_query =
  85.108 -        GMYTH_QUERY(g_object_new(GMYTH_QUERY_TYPE, NULL));
  85.109 -
  85.110 -    return sql_query;
  85.111 -}
  85.112 -
  85.113 -gboolean
  85.114 -gmyth_query_connect_with_timeout(GMythQuery * gmyth_query,
  85.115 -                                 GMythBackendInfo * backend_info,
  85.116 -                                 guint timeout)
  85.117 -{
  85.118 -    assert(gmyth_query);
  85.119 -
  85.120 -    if (gmyth_query->conn == NULL)
  85.121 -        gmyth_query->conn = mysql_init(NULL);
  85.122 -
  85.123 -    if (timeout != 0) {
  85.124 -      /*
  85.125 -       * sets connection timeout
  85.126 -       */
  85.127 -        mysql_options(gmyth_query->conn, MYSQL_OPT_CONNECT_TIMEOUT,
  85.128 -                      (gchar *) & timeout);
  85.129 -    }
  85.130 -
  85.131 -    return gmyth_query_connect(gmyth_query, backend_info);
  85.132 -}
  85.133 -
  85.134 -/** Connects to the Mysql database in the backend. The backend address
  85.135 - * is loaded from the GMythBackendInfo instance.
  85.136 - *
  85.137 - * @param gmyth_query the GMythEPG instance to be connected.
  85.138 - * @return true if connection was success, false if failed.
  85.139 - */
  85.140 -gboolean
  85.141 -gmyth_query_connect(GMythQuery * gmyth_query,
  85.142 -                    GMythBackendInfo * backend_info)
  85.143 -{
  85.144 -    assert(gmyth_query);
  85.145 -    g_return_val_if_fail(backend_info != NULL, FALSE);
  85.146 -    g_return_val_if_fail(backend_info->hostname != NULL, FALSE);
  85.147 -    g_return_val_if_fail(backend_info->username != NULL, FALSE);
  85.148 -    g_return_val_if_fail(backend_info->password != NULL, FALSE);
  85.149 -    g_return_val_if_fail(backend_info->db_name != NULL, FALSE);
  85.150 -
  85.151 -    if (gmyth_query->backend_info != NULL) {
  85.152 -        g_object_unref(gmyth_query->backend_info);
  85.153 -    }
  85.154 -    gmyth_query->backend_info = g_object_ref(backend_info);
  85.155 -
  85.156 -    if (gmyth_query->conn == NULL) {
  85.157 -        gmyth_query->conn = mysql_init(NULL);
  85.158 -    }
  85.159 -
  85.160 -    /*
  85.161 -     * connect to server
  85.162 -     */
  85.163 -    if (mysql_real_connect(gmyth_query->conn,
  85.164 -                           gmyth_query->backend_info->hostname,
  85.165 -                           gmyth_query->backend_info->username,
  85.166 -                           gmyth_query->backend_info->password,
  85.167 -                           gmyth_query->backend_info->db_name, 
  85.168 -                           gmyth_query->backend_info->db_port, 
  85.169 -                           NULL,
  85.170 -                           0) == NULL) {
  85.171 -        gmyth_query_print_error(gmyth_query->conn,
  85.172 -                                "mysql_real_connect() failed");
  85.173 -        return FALSE;
  85.174 -    }
  85.175 -
  85.176 -    gmyth_debug
  85.177 -        ("[%s] Connection to Mysql server succeeded! (host = %s, user = %s, "
  85.178 -         "password = %s, db name = %s)", __FUNCTION__,
  85.179 -         gmyth_query->backend_info->hostname,
  85.180 -         gmyth_query->backend_info->username,
  85.181 -         gmyth_query->backend_info->password,
  85.182 -         gmyth_query->backend_info->db_name);
  85.183 -
  85.184 -    return TRUE;
  85.185 -}
  85.186 -
  85.187 -/** Disconnects from the Mysql database in the backend.
  85.188 - * 
  85.189 - * @param gmyth_query the GMythQuery instance to be disconnected
  85.190 - * @return true if disconnection was success, false if failed.
  85.191 - */
  85.192 -gboolean
  85.193 -gmyth_query_disconnect(GMythQuery * gmyth_query)
  85.194 -{
  85.195 -    g_return_val_if_fail(gmyth_query != NULL, FALSE);
  85.196 -    g_return_val_if_fail(gmyth_query->conn != NULL, FALSE);
  85.197 -
  85.198 -    /*
  85.199 -     * TODO: Check how to return error 
  85.200 -     */
  85.201 -    gmyth_debug("[%s] Closing gmyth_query->conn", __FUNCTION__);
  85.202 -
  85.203 -    mysql_close(gmyth_query->conn);
  85.204 -    gmyth_query->conn = NULL;
  85.205 -
  85.206 -    return TRUE;
  85.207 -}
  85.208 -
  85.209 -static void
  85.210 -gmyth_query_print_error(MYSQL * conn, char *message)
  85.211 -{
  85.212 -    gmyth_debug("%s", message);
  85.213 -
  85.214 -    if (conn != NULL) {
  85.215 -#if MYSQL_VERSION_ID >= 40101
  85.216 -        gmyth_debug("Error %u (%s): %s\n",
  85.217 -                    mysql_errno(conn), mysql_sqlstate(conn),
  85.218 -                    mysql_error(conn));
  85.219 -#else
  85.220 -        gmyth_debug("Error %u: %s\n", mysql_errno(conn),
  85.221 -                    mysql_error(conn));
  85.222 -#endif
  85.223 -    }
  85.224 -}
  85.225 -
  85.226 -/** Sends the given query to the backend returning the query result as
  85.227 - * MYSQL_RES pointer.
  85.228 - * 
  85.229 - * FIXME: this function is returning NULL whether any error happens
  85.230 - * or no rows are returned (e.g. UPDATE or REPLACE).
  85.231 - * 
  85.232 - * @param gmyth_query the GMythQuery instance.
  85.233 - * @param stmt_str the query text.
  85.234 - * @return the MYSQL_RES result pointer or NULL if any error happens.
  85.235 - */
  85.236 -MYSQL_RES*
  85.237 -gmyth_query_process_statement(GMythQuery * gmyth_query, char *stmt_str)
  85.238 -{
  85.239 -    assert(gmyth_query);
  85.240 -
  85.241 -    gmyth_debug("[%s] Running mysql query %s", __FUNCTION__, stmt_str);
  85.242 -
  85.243 -    if (gmyth_query == NULL)
  85.244 -        return NULL;
  85.245 -
  85.246 -    //the statement failed
  85.247 -    if (mysql_query(gmyth_query->conn, stmt_str) != 0) {
  85.248 -        gmyth_query_print_error(gmyth_query->conn,
  85.249 -                                "Could not execute statement");
  85.250 -        return NULL;
  85.251 -    }
  85.252 -
  85.253 -    //the statement succeeded; determine whether it returned data
  85.254 -    return mysql_store_result(gmyth_query->conn);
  85.255 -}
  85.256 -
  85.257 -MYSQL_RES*
  85.258 -gmyth_query_process_statement_with_increment(GMythQuery * gmyth_query,
  85.259 -                                             char *stmt_str, gulong * id)
  85.260 -{
  85.261 -    assert(gmyth_query);
  85.262 -
  85.263 -    gmyth_debug("[%s] Running mysql query %s", __FUNCTION__, stmt_str);
  85.264 -
  85.265 -    if (gmyth_query == NULL)
  85.266 -        return NULL;
  85.267 -
  85.268 -    /*
  85.269 -     * the statement failed
  85.270 -     */
  85.271 -    if (mysql_query(gmyth_query->conn, stmt_str) != 0) {
  85.272 -        gmyth_query_print_error(gmyth_query->conn,
  85.273 -                                "Could not execute statement");
  85.274 -        return NULL;
  85.275 -    }
  85.276 -
  85.277 -    *id = (my_ulonglong) mysql_insert_id(gmyth_query->conn);
  85.278 -
  85.279 -    /*
  85.280 -     * the statement succeeded; determine whether it returned data 
  85.281 -     */
  85.282 -    return mysql_store_result(gmyth_query->conn);
  85.283 -}
    86.1 --- a/gmyth/src/gmyth_query.h	Mon Feb 25 17:45:36 2008 +0000
    86.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.3 @@ -1,93 +0,0 @@
    86.4 -/**
    86.5 - * GMyth Library
    86.6 - *
    86.7 - * @file gmyth/gmyth_query.h
    86.8 - * 
    86.9 - * @brief <p> GMythQuery class provides a wrapper for accessing
   86.10 - * the libmysqlclient funtions.
   86.11 - *
   86.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   86.13 - * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
   86.14 - *
   86.15 - * 
   86.16 - * This program is free software; you can redistribute it and/or modify
   86.17 - * it under the terms of the GNU Lesser General Public License as published by
   86.18 - * the Free Software Foundation; either version 2 of the License, or
   86.19 - * (at your option) any later version.
   86.20 - *
   86.21 - * This program is distributed in the hope that it will be useful,
   86.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   86.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   86.24 - * GNU General Public License for more details.
   86.25 - *
   86.26 - * You should have received a copy of the GNU Lesser General Public License
   86.27 - * along with this program; if not, write to the Free Software
   86.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   86.29 - */
   86.30 -
   86.31 -#ifndef __GMYTH_QUERY_H__
   86.32 -#define __GMYTH_QUERY_H__
   86.33 -
   86.34 -#include <glib-object.h>
   86.35 -
   86.36 -/*
   86.37 - * MYSQL includes 
   86.38 - */
   86.39 -#include <mysql/mysql.h>
   86.40 -
   86.41 -#include "gmyth_backendinfo.h"
   86.42 -
   86.43 -G_BEGIN_DECLS
   86.44 -#define GMYTH_QUERY_TYPE               (gmyth_query_get_type ())
   86.45 -#define GMYTH_QUERY(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE, GMythQuery))
   86.46 -#define GMYTH_QUERY_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE, GMythQueryClass))
   86.47 -#define IS_GMYTH_QUERY(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_QUERY_TYPE))
   86.48 -#define IS_GMYTH_QUERY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE))
   86.49 -#define GMYTH_QUERY_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_QUERY_TYPE, GMythQueryClass))
   86.50 -typedef struct _GMythQuery GMythQuery;
   86.51 -typedef struct _GMythQueryClass GMythQueryClass;
   86.52 -
   86.53 -struct _GMythQueryClass {
   86.54 -    GObjectClass    parent_class;
   86.55 -
   86.56 -    /*
   86.57 -     * callbacks 
   86.58 -     */
   86.59 -    /*
   86.60 -     * no one for now 
   86.61 -     */
   86.62 -};
   86.63 -
   86.64 -struct _GMythQuery {
   86.65 -    GObject         parent;
   86.66 -
   86.67 -    GMythBackendInfo *backend_info;
   86.68 -
   86.69 -    /*
   86.70 -     * pointer to connection handler 
   86.71 -     */
   86.72 -    MYSQL          *conn;
   86.73 -};
   86.74 -
   86.75 -
   86.76 -GType           gmyth_query_get_type(void);
   86.77 -
   86.78 -GMythQuery     *gmyth_query_new(void);
   86.79 -MYSQL_RES      *gmyth_query_process_statement(GMythQuery * gmyth_query,
   86.80 -                                              gchar * stmt_str);
   86.81 -MYSQL_RES      *gmyth_query_process_statement_with_increment(GMythQuery *
   86.82 -                                                             gmyth_query,
   86.83 -                                                             char
   86.84 -                                                             *stmt_str,
   86.85 -                                                             gulong * id);
   86.86 -
   86.87 -gboolean        gmyth_query_connect(GMythQuery * gmyth_query,
   86.88 -                                    GMythBackendInfo * backend_info);
   86.89 -gboolean        gmyth_query_connect_with_timeout(GMythQuery * gmyth_query,
   86.90 -                                                 GMythBackendInfo *
   86.91 -                                                 backend_info,
   86.92 -                                                 guint timeout);
   86.93 -gboolean        gmyth_query_disconnect(GMythQuery * gmyth_query);
   86.94 -
   86.95 -G_END_DECLS
   86.96 -#endif                          /* __GMYTH_QUERY_H__ */
    87.1 --- a/gmyth/src/gmyth_recorder.c	Mon Feb 25 17:45:36 2008 +0000
    87.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.3 @@ -1,1388 +0,0 @@
    87.4 -/**
    87.5 - * GMyth Library
    87.6 - *
    87.7 - * @file gmyth/gmyth_recorder.c
    87.8 - * 
    87.9 - * @brief <p> GMythRecorder defines functions for playing live tv.
   87.10 - *
   87.11 - * The remote encoder is used by gmyth_tvplayer to setup livetv. 
   87.12 - *
   87.13 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   87.14 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   87.15 - * @author Rosfran Borges <rosfran.borges@indt.org.br>
   87.16 - *
   87.17 - * 
   87.18 - * This program is free software; you can redistribute it and/or modify
   87.19 - * it under the terms of the GNU Lesser General Public License as published by
   87.20 - * the Free Software Foundation; either version 2 of the License, or
   87.21 - * (at your option) any later version.
   87.22 - *
   87.23 - * This program is distributed in the hope that it will be useful,
   87.24 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   87.25 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   87.26 - * GNU General Public License for more details.
   87.27 - *
   87.28 - * You should have received a copy of the GNU Lesser General Public License
   87.29 - * along with this program; if not, write to the Free Software
   87.30 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   87.31 - */
   87.32 -
   87.33 -#ifdef HAVE_CONFIG_H
   87.34 -#include "config.h"
   87.35 -#endif
   87.36 -
   87.37 -#include "gmyth_recorder.h"
   87.38 -
   87.39 -#include <assert.h>
   87.40 -
   87.41 -#include "gmyth_stringlist.h"
   87.42 -#include "gmyth_util.h"
   87.43 -#include "gmyth_common.h"
   87.44 -#include "gmyth_debug.h"
   87.45 -
   87.46 -#define	 GMYTHTV_RECORDER_HEADER			"QUERY_RECORDER"
   87.47 -
   87.48 -static void     gmyth_recorder_class_init(GMythRecorderClass * klass);
   87.49 -static void     gmyth_recorder_init(GMythRecorder * object);
   87.50 -
   87.51 -static void     gmyth_recorder_dispose(GObject * object);
   87.52 -static void     gmyth_recorder_finalize(GObject * object);
   87.53 -
   87.54 -G_DEFINE_TYPE(GMythRecorder, gmyth_recorder, G_TYPE_OBJECT)
   87.55 -    static void     gmyth_recorder_class_init(GMythRecorderClass * klass)
   87.56 -{
   87.57 -    GObjectClass   *gobject_class;
   87.58 -
   87.59 -    gobject_class = (GObjectClass *) klass;
   87.60 -
   87.61 -    gobject_class->dispose = gmyth_recorder_dispose;
   87.62 -    gobject_class->finalize = gmyth_recorder_finalize;
   87.63 -}
   87.64 -
   87.65 -static void
   87.66 -gmyth_recorder_init(GMythRecorder * gmyth_remote_encoder)
   87.67 -{
   87.68 -}
   87.69 -
   87.70 -static void
   87.71 -gmyth_recorder_dispose(GObject * object)
   87.72 -{
   87.73 -    GMythRecorder  *recorder = GMYTH_RECORDER(object);
   87.74 -
   87.75 -    gmyth_recorder_close(recorder);
   87.76 -
   87.77 -    if (recorder->mutex != NULL) {
   87.78 -        g_mutex_free(recorder->mutex);
   87.79 -        recorder->mutex = NULL;
   87.80 -    }
   87.81 -
   87.82 -    if (recorder->myth_socket != NULL) {
   87.83 -        g_object_unref(recorder->myth_socket);
   87.84 -        recorder->myth_socket = NULL;
   87.85 -    }
   87.86 -
   87.87 -    if (recorder->progs_info_list != NULL)
   87.88 -        gmyth_free_program_list(recorder->progs_info_list);
   87.89 -
   87.90 -    if (recorder->hostname != NULL)
   87.91 -        g_string_free(recorder->hostname, TRUE);
   87.92 -
   87.93 -    G_OBJECT_CLASS(gmyth_recorder_parent_class)->dispose(object);
   87.94 -}
   87.95 -
   87.96 -static void
   87.97 -gmyth_recorder_finalize(GObject * object)
   87.98 -{
   87.99 -    g_signal_handlers_destroy(object);
  87.100 -
  87.101 -    G_OBJECT_CLASS(gmyth_recorder_parent_class)->finalize(object);
  87.102 -}
  87.103 -
  87.104 -void
  87.105 -gmyth_recorder_close(GMythRecorder * recorder)
  87.106 -{
  87.107 -    if (recorder != NULL && recorder->recorder_num != -1) {
  87.108 -        g_mutex_lock(recorder->mutex);
  87.109 -
  87.110 -        gmyth_recorder_stop_playing(recorder);
  87.111 -        gmyth_recorder_stop_livetv(recorder);
  87.112 -        gmyth_recorder_finish_recording(recorder);
  87.113 -        gmyth_recorder_free_tuner(recorder);
  87.114 -
  87.115 -        g_mutex_unlock(recorder->mutex);
  87.116 -    }
  87.117 -}
  87.118 -
  87.119 -/** Creates a new instance of GMythRecorder.
  87.120 - * 
  87.121 - * @return a new instance of GMythRecorder.
  87.122 - */
  87.123 -GMythRecorder  *
  87.124 -gmyth_recorder_new(int num, GString * hostname, gshort port)
  87.125 -{
  87.126 -    GMythRecorder  *encoder =
  87.127 -        GMYTH_RECORDER(g_object_new(GMYTH_RECORDER_TYPE, FALSE));
  87.128 -
  87.129 -    encoder->recorder_num = num;
  87.130 -    encoder->hostname = g_string_new(hostname->str);
  87.131 -    encoder->port = port;
  87.132 -
  87.133 -    encoder->mutex = g_mutex_new();
  87.134 -
  87.135 -    encoder->progs_info_list = NULL;
  87.136 -
  87.137 -    return encoder;
  87.138 -}
  87.139 -
  87.140 -/** Configures the remote encoder instance connecting it to Mythtv backend.
  87.141 - * 
  87.142 - * @param recorder the GMythRecorder instance.
  87.143 - * 
  87.144 - * @return TRUE if successfull, FALSE if any error happens.
  87.145 - */
  87.146 -gboolean
  87.147 -gmyth_recorder_setup(GMythRecorder * recorder)
  87.148 -{
  87.149 -    assert(recorder);
  87.150 -    gmyth_debug("[%s] Creating socket and connecting to backend",
  87.151 -                __FUNCTION__);
  87.152 -
  87.153 -    if (recorder->myth_socket == NULL) {
  87.154 -        recorder->myth_socket = gmyth_socket_new();
  87.155 -
  87.156 -        if (!gmyth_socket_connect_to_backend(recorder->myth_socket,
  87.157 -                                             recorder->hostname->str,
  87.158 -                                             recorder->port, TRUE)) {
  87.159 -            gmyth_debug
  87.160 -                ("GMythRemoteEncoder: Connection to backend failed");
  87.161 -            return FALSE;
  87.162 -        }
  87.163 -    } else {
  87.164 -        gmyth_debug("Remote encoder socket already created\n");
  87.165 -    }
  87.166 -
  87.167 -    return TRUE;
  87.168 -}
  87.169 -
  87.170 -/** Sends the SPAWN_LIVETV command through Mythtv protocol. This command
  87.171 - * requests the backend to start capturing TV content.
  87.172 - * 
  87.173 - * @param recorder The GMythRecorder instance.
  87.174 - * @param tvchain_id The tvchain unique id.
  87.175 - * @return true if success, false if any error happens.
  87.176 - */
  87.177 -gboolean
  87.178 -gmyth_recorder_spawntv(GMythRecorder * recorder, GString * tvchain_id)
  87.179 -{
  87.180 -    GMythStringList *str_list;
  87.181 -    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  87.182 -    gboolean        ret = TRUE;
  87.183 -
  87.184 -    gmyth_debug("[%s] Spawntv with tvchain_id = %s", __FUNCTION__,
  87.185 -                tvchain_id->str);
  87.186 -
  87.187 -    str_list = gmyth_string_list_new();
  87.188 -
  87.189 -    g_mutex_lock(recorder->mutex);
  87.190 -
  87.191 -    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  87.192 -
  87.193 -    gmyth_string_list_append_string(str_list, tmp_str);
  87.194 -    g_string_free(tmp_str, TRUE);
  87.195 -
  87.196 -    gmyth_string_list_append_char_array(str_list, "SPAWN_LIVETV");
  87.197 -
  87.198 -    gmyth_string_list_append_string(str_list, tvchain_id);
  87.199 -    gmyth_string_list_append_int(str_list, 0);  // PIP = FALSE (0)
  87.200 -
  87.201 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  87.202 -
  87.203 -    tmp_str = gmyth_string_list_get_string(str_list, 0);
  87.204 -
  87.205 -    if (tmp_str == NULL) {
  87.206 -        gmyth_debug("[%s] Spawntv request returned %s", __FUNCTION__,
  87.207 -                    tmp_str->str);
  87.208 -        ret = FALSE;
  87.209 -        goto cleanup;
  87.210 -    }
  87.211 -
  87.212 -    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
  87.213 -        gmyth_debug("[%s] Spawntv request returned %s", __FUNCTION__,
  87.214 -                    tmp_str->str);
  87.215 -        ret = FALSE;
  87.216 -        goto cleanup;
  87.217 -    }
  87.218 -
  87.219 -  cleanup:
  87.220 -    g_mutex_unlock(recorder->mutex);
  87.221 -
  87.222 -    g_string_free(tmp_str, TRUE);
  87.223 -    g_object_unref(str_list);
  87.224 -
  87.225 -    return ret;
  87.226 -}
  87.227 -
  87.228 -/** 
  87.229 - * Sends the SPAWN_LIVETV command through Mythtv protocol. This command
  87.230 - * requests the backend to start capturing TV content, but it doesn't need
  87.231 - * the TV chain ID.
  87.232 - * 
  87.233 - * @param recorder The GMythRecorder instance.
  87.234 - * @return true if success, false if any error happens.
  87.235 - */
  87.236 -gboolean
  87.237 -gmyth_recorder_spawntv_no_tvchain(GMythRecorder * recorder)
  87.238 -{
  87.239 -    GMythStringList *str_list;
  87.240 -    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  87.241 -    gboolean        ret = TRUE;
  87.242 -
  87.243 -    gmyth_debug("[%s] Spawntv, no TV chain!", __FUNCTION__);
  87.244 -
  87.245 -    str_list = gmyth_string_list_new();
  87.246 -
  87.247 -    g_mutex_lock(recorder->mutex);
  87.248 -
  87.249 -    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  87.250 -
  87.251 -    gmyth_string_list_append_string(str_list, tmp_str);
  87.252 -    g_string_free(tmp_str, TRUE);
  87.253 -
  87.254 -    gmyth_string_list_append_char_array(str_list, "SPAWN_LIVETV");
  87.255 -
  87.256 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  87.257 -
  87.258 -    tmp_str = gmyth_string_list_get_string(str_list, 0);
  87.259 -
  87.260 -    if (tmp_str == NULL) {
  87.261 -        gmyth_debug("[%s] Spawntv request returned %s", __FUNCTION__,
  87.262 -                    tmp_str->str);
  87.263 -        ret = FALSE;
  87.264 -        goto cleanup;
  87.265 -    }
  87.266 -
  87.267 -    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
  87.268 -        gmyth_debug("[%s] Spawntv request returned %s", __FUNCTION__,
  87.269 -                    tmp_str->str);
  87.270 -        ret = FALSE;
  87.271 -        goto cleanup;
  87.272 -    }
  87.273 -
  87.274 -  cleanup:
  87.275 -    g_mutex_unlock(recorder->mutex);
  87.276 -
  87.277 -    g_string_free(tmp_str, TRUE);
  87.278 -    g_object_unref(str_list);
  87.279 -
  87.280 -    return ret;
  87.281 -}
  87.282 -
  87.283 -/** Sends the command STOP_LIVETV to Mythtv backend.
  87.284 - * 
  87.285 - * @param recorder the GMythRecorder instance.
  87.286 - * @return true if success, false if any error happens.
  87.287 - */
  87.288 -gboolean
  87.289 -gmyth_recorder_stop_livetv(GMythRecorder * recorder)
  87.290 -{
  87.291 -    GMythStringList *str_list;
  87.292 -    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  87.293 -    gboolean        ret = TRUE;
  87.294 -
  87.295 -    gmyth_debug("[%s]", __FUNCTION__);
  87.296 -
  87.297 -    str_list = gmyth_string_list_new();
  87.298 -
  87.299 -    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  87.300 -
  87.301 -    gmyth_string_list_append_string(str_list, tmp_str);
  87.302 -    g_string_free(tmp_str, TRUE);
  87.303 -
  87.304 -    gmyth_string_list_append_char_array(str_list, "STOP_LIVETV");
  87.305 -
  87.306 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  87.307 -
  87.308 -    tmp_str = gmyth_string_list_get_string(str_list, 0);
  87.309 -
  87.310 -    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
  87.311 -        gmyth_debug("[%s] Stop livetv request returned %s", __FUNCTION__,
  87.312 -                    tmp_str->str);
  87.313 -        ret = FALSE;
  87.314 -        goto cleanup;
  87.315 -    }
  87.316 -
  87.317 -  cleanup:
  87.318 -    g_string_free(tmp_str, TRUE);
  87.319 -    g_object_unref(str_list);
  87.320 -
  87.321 -    return ret;
  87.322 -}
  87.323 -
  87.324 -/** Sends the FRONTEND_READY command through Mythtv protocol. This command
  87.325 - * advertises the backend to start capturing TV content.
  87.326 - * 
  87.327 - * @param recorder The GMythRecorder instance.
  87.328 - * @return TRUE if success, FALSE if any error happens.
  87.329 - */
  87.330 -gboolean
  87.331 -gmyth_recorder_send_frontend_ready_command(GMythRecorder * recorder)
  87.332 -{
  87.333 -    GMythStringList *str_list;
  87.334 -    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  87.335 -    gboolean        ret = TRUE;
  87.336 -
  87.337 -    gmyth_debug("[%s] FRONTEND_READY with recorder id = %d", __FUNCTION__,
  87.338 -                recorder->recorder_num);
  87.339 -
  87.340 -    str_list = gmyth_string_list_new();
  87.341 -
  87.342 -    g_mutex_lock(recorder->mutex);
  87.343 -
  87.344 -    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  87.345 -
  87.346 -    gmyth_string_list_append_string(str_list, tmp_str);
  87.347 -    g_string_free(tmp_str, TRUE);
  87.348 -
  87.349 -    gmyth_string_list_append_char_array(str_list, "FRONTEND_READY");
  87.350 -
  87.351 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  87.352 -
  87.353 -    tmp_str = gmyth_string_list_get_string(str_list, 0);
  87.354 -
  87.355 -    if (tmp_str == NULL) {
  87.356 -        gmyth_debug
  87.357 -            ("[%s] FRONTEND_READY command request couldn't returns, reason: %s",
  87.358 -             __FUNCTION__, tmp_str->str);
  87.359 -        ret = FALSE;
  87.360 -        goto cleanup;
  87.361 -    }
  87.362 -
  87.363 -    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
  87.364 -        gmyth_debug("[%s] FRONTEND_READY request returned %s",
  87.365 -                    __FUNCTION__, tmp_str->str);
  87.366 -        ret = FALSE;
  87.367 -        goto cleanup;
  87.368 -    }
  87.369 -
  87.370 -  cleanup:
  87.371 -    g_mutex_unlock(recorder->mutex);
  87.372 -    g_string_free(tmp_str, TRUE);
  87.373 -    g_object_unref(str_list);
  87.374 -
  87.375 -    return ret;
  87.376 -}
  87.377 -
  87.378 -/** Send a CHECK_CHANNEL command request to the backend, in order to find if a 
  87.379 - * certain channel actually exists.
  87.380 - * 
  87.381 - * @param recorder The GMythRecorder instance.
  87.382 - * @param channel	 The new channel to be checked (string format).
  87.383 - * @return true if success, false if any error happens.
  87.384 - */
  87.385 -gboolean
  87.386 -gmyth_recorder_check_channel_name(GMythRecorder * recorder,
  87.387 -                                  gchar * channel)
  87.388 -{
  87.389 -    GMythStringList *str_list;
  87.390 -    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  87.391 -    gboolean        ret = TRUE;
  87.392 -
  87.393 -    gmyth_debug("[%s] CHECK_CHANNEL with channel = %s", __FUNCTION__,
  87.394 -                channel);
  87.395 -
  87.396 -    str_list = gmyth_string_list_new();
  87.397 -
  87.398 -    g_mutex_lock(recorder->mutex);
  87.399 -
  87.400 -    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  87.401 -
  87.402 -    gmyth_string_list_append_string(str_list, tmp_str);
  87.403 -    g_string_free(tmp_str, TRUE);
  87.404 -
  87.405 -    gmyth_string_list_append_char_array(str_list, "CHECK_CHANNEL");
  87.406 -
  87.407 -    gmyth_string_list_append_char_array(str_list, channel);
  87.408 -
  87.409 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  87.410 -
  87.411 -    tmp_str = gmyth_string_list_get_string(str_list, 0);
  87.412 -
  87.413 -    if (tmp_str == NULL) {
  87.414 -        gmyth_debug("[%s] CHECK_CHANNEL request returned %s", __FUNCTION__,
  87.415 -                    tmp_str->str);
  87.416 -        ret = FALSE;
  87.417 -        goto cleanup;
  87.418 -    }
  87.419 -
  87.420 -    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2) == 0
  87.421 -        || g_ascii_strncasecmp(tmp_str->str, "0", 1) == 0) {
  87.422 -        gmyth_debug("[%s] CHECK_CHANNEL request returned %s", __FUNCTION__,
  87.423 -                    tmp_str->str);
  87.424 -        ret = FALSE;
  87.425 -        goto cleanup;
  87.426 -    }
  87.427 -
  87.428 -  cleanup:
  87.429 -    g_mutex_unlock(recorder->mutex);
  87.430 -    g_string_free(tmp_str, TRUE);
  87.431 -    g_object_unref(str_list);
  87.432 -
  87.433 -    return ret;
  87.434 -}
  87.435 -
  87.436 -/** Send a CHECK_CHANNEL command request to the backend, in order to find if a 
  87.437 - * certain channel actually exists.
  87.438 - * 
  87.439 - * @param recorder The GMythRecorder instance.
  87.440 - * @param channel	 The new channel to be checked (decimal integer value).
  87.441 - * @return true if success, false if any error happens.
  87.442 - */
  87.443 -gboolean
  87.444 -gmyth_recorder_check_channel(GMythRecorder * recorder, gint channel)
  87.445 -{
  87.446 -    return gmyth_recorder_check_channel_name(recorder,
  87.447 -                                             g_strdup_printf("%d",
  87.448 -                                                             channel));
  87.449 -}
  87.450 -
  87.451 -/** Send a SET_CHANNEL command request to the backend, to start streaming on another 
  87.452 - * TV content channel.
  87.453 - * 
  87.454 - * @param recorder The GMythRecorder instance.
  87.455 - * @param channel	 The new channel to be loaded.
  87.456 - * @return true if success, false if any error happens.
  87.457 - */
  87.458 -gboolean
  87.459 -gmyth_recorder_set_channel(GMythRecorder * recorder, gint channel)
  87.460 -{
  87.461 -    GMythStringList *str_list;
  87.462 -    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  87.463 -    gboolean        ret = TRUE;
  87.464 -
  87.465 -    gmyth_debug("[%s] SET_CHANNEL with channel = %d", __FUNCTION__,
  87.466 -                channel);
  87.467 -
  87.468 -    str_list = gmyth_string_list_new();
  87.469 -
  87.470 -    g_mutex_lock(recorder->mutex);
  87.471 -
  87.472 -    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  87.473 -
  87.474 -    gmyth_string_list_append_string(str_list, tmp_str);
  87.475 -    g_string_free(tmp_str, TRUE);
  87.476 -
  87.477 -    gmyth_string_list_append_char_array(str_list, "SET_CHANNEL");
  87.478 -
  87.479 -    gmyth_string_list_append_int(str_list, channel);
  87.480 -
  87.481 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  87.482 -
  87.483 -    tmp_str = gmyth_string_list_get_string(str_list, 0);
  87.484 -
  87.485 -    if (tmp_str == NULL) {
  87.486 -        gmyth_debug("[%s] SET_CHANNEL request returned %s", __FUNCTION__,
  87.487 -                    tmp_str->str);
  87.488 -        ret = FALSE;
  87.489 -        goto cleanup;
  87.490 -    }
  87.491 -
  87.492 -    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
  87.493 -        gmyth_debug("[%s] SET_CHANNEL request returned %s", __FUNCTION__,
  87.494 -                    tmp_str->str);
  87.495 -        ret = FALSE;
  87.496 -        goto cleanup;
  87.497 -    }
  87.498 -
  87.499 -  cleanup:
  87.500 -    g_mutex_unlock(recorder->mutex);
  87.501 -    g_string_free(tmp_str, TRUE);
  87.502 -    g_object_unref(str_list);
  87.503 -
  87.504 -    return ret;
  87.505 -}
  87.506 -
  87.507 -/** Send a SET_CHANNEL command request to the backend, to start streaming on another 
  87.508 - * TV content channel.
  87.509 - * 
  87.510 - * @param recorder The GMythRecorder instance.
  87.511 - * @param channel	 The new channel to be loaded.
  87.512 - * @return true if success, false if any error happens.
  87.513 - */
  87.514 -gboolean
  87.515 -gmyth_recorder_set_channel_name(GMythRecorder * recorder,
  87.516 -                                const gchar * channel)
  87.517 -{
  87.518 -    GMythStringList *str_list;
  87.519 -    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  87.520 -    gboolean        ret = TRUE;
  87.521 -
  87.522 -    gmyth_debug("[%s] SET_CHANNEL with channel name = %s", __FUNCTION__,
  87.523 -                channel);
  87.524 -
  87.525 -    str_list = gmyth_string_list_new();
  87.526 -
  87.527 -    g_mutex_lock(recorder->mutex);
  87.528 -
  87.529 -    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  87.530 -
  87.531 -    gmyth_string_list_append_string(str_list, tmp_str);
  87.532 -    g_string_free(tmp_str, TRUE);
  87.533 -
  87.534 -    gmyth_string_list_append_char_array(str_list, "SET_CHANNEL");
  87.535 -    gmyth_string_list_append_char_array(str_list, channel);
  87.536 -
  87.537 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  87.538 -
  87.539 -    tmp_str = gmyth_string_list_get_string(str_list, 0);
  87.540 -
  87.541 -    if (tmp_str == NULL) {
  87.542 -        gmyth_debug("[%s] SET_CHANNEL name request returned NULL!",
  87.543 -                    __FUNCTION__);
  87.544 -        ret = FALSE;
  87.545 -        goto cleanup;
  87.546 -    }
  87.547 -
  87.548 -    if (tmp_str != NULL && g_ascii_strncasecmp(tmp_str->str, "ok", 2)
  87.549 -        /*
  87.550 -         * || g_ascii_strtoull( tmp_str->str, NULL, 10 ) == 0 
  87.551 -         */
  87.552 -        ) {
  87.553 -        g_warning("[%s] SET_CHANNEL name request returned not ok",
  87.554 -                  __FUNCTION__);
  87.555 -        ret = FALSE;
  87.556 -        goto cleanup;
  87.557 -    }
  87.558 -
  87.559 -  cleanup:
  87.560 -    g_mutex_unlock(recorder->mutex);
  87.561 -    g_string_free(tmp_str, TRUE);
  87.562 -    g_object_unref(str_list);
  87.563 -
  87.564 -    return ret;
  87.565 -}
  87.566 -
  87.567 -/**
  87.568 - * Changes the channel of the actual Recorder.
  87.569 - * 
  87.570 - * CHANNEL_DIRECTION_UP       - Go up one channel in the listing
  87.571 - *
  87.572 - * CHANNEL_DIRECTION_DOWN     - Go down one channel in the listing
  87.573 - *
  87.574 - * CHANNEL_DIRECTION_FAVORITE - Go to the next favorite channel
  87.575 - *
  87.576 - * CHANNEL_DIRECTION_SAME     - Stay
  87.577 - * 
  87.578 - * @param recorder 	 The GMythRecorder instance.
  87.579 - * @param direction	 The new channel direction where to move to.
  87.580 - * @return true if success, false if any error happens.
  87.581 - */
  87.582 -gboolean
  87.583 -gmyth_recorder_change_channel(GMythRecorder * recorder,
  87.584 -                              const GMythRecorderChannelChangeDirection
  87.585 -                              direction)
  87.586 -{
  87.587 -    GMythStringList *str_list;
  87.588 -    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  87.589 -    gboolean        ret = TRUE;
  87.590 -
  87.591 -    gmyth_debug("[%s] CHANGE_CHANNEL to the channel direction = %u",
  87.592 -                __FUNCTION__, direction);
  87.593 -
  87.594 -    str_list = gmyth_string_list_new();
  87.595 -
  87.596 -    g_mutex_lock(recorder->mutex);
  87.597 -
  87.598 -    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  87.599 -
  87.600 -    gmyth_string_list_append_string(str_list, tmp_str);
  87.601 -    g_string_free(tmp_str, TRUE);
  87.602 -
  87.603 -    gmyth_string_list_append_char_array(str_list, "CHANGE_CHANNEL");
  87.604 -    gmyth_string_list_append_int(str_list, direction);
  87.605 -
  87.606 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  87.607 -
  87.608 -    tmp_str = gmyth_string_list_get_string(str_list, 0);
  87.609 -
  87.610 -    if (tmp_str == NULL) {
  87.611 -        gmyth_debug("[%s] CHANGE_CHANNEL name request returned %s",
  87.612 -                    __FUNCTION__, tmp_str->str);
  87.613 -        ret = FALSE;
  87.614 -        goto cleanup;
  87.615 -    }
  87.616 -
  87.617 -    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)
  87.618 -        || g_ascii_strtoull(tmp_str->str, NULL, 10) == 0) {
  87.619 -        gmyth_debug("[%s] CHANGE_CHANNEL name request returned %s",
  87.620 -                    __FUNCTION__, tmp_str->str);
  87.621 -        ret = FALSE;
  87.622 -        goto cleanup;
  87.623 -    }
  87.624 -
  87.625 -  cleanup:
  87.626 -    g_mutex_unlock(recorder->mutex);
  87.627 -    g_string_free(tmp_str, TRUE);
  87.628 -    g_object_unref(str_list);
  87.629 -
  87.630 -    return ret;
  87.631 -}
  87.632 -
  87.633 -/** 
  87.634 - * Gets the channel's list from the MythTV backend server.
  87.635 - * 
  87.636 - * @param recorder The GMythRecorder instance.
  87.637 - * 
  87.638 - * @return a GList* instance with all the channel names.
  87.639 - */
  87.640 -GList          *
  87.641 -gmyth_recorder_get_channel_list(GMythRecorder * recorder)
  87.642 -{
  87.643 -
  87.644 -    GList          *channel_list = NULL;
  87.645 -    gchar          *channel = NULL;
  87.646 -    guint           i;
  87.647 -
  87.648 -    for (i = 0; i < 1000; i++) {
  87.649 -        channel = g_strdup_printf("%u", i);
  87.650 -
  87.651 -        if (gmyth_recorder_check_channel_name(recorder, channel)) {
  87.652 -            channel_list = g_list_append(channel_list, g_strdup(channel));
  87.653 -        }
  87.654 -
  87.655 -    }                           /* for - channel list */
  87.656 -
  87.657 -    g_free(channel);
  87.658 -
  87.659 -    return channel_list;
  87.660 -
  87.661 -}
  87.662 -
  87.663 -/** Send a PAUSE command request to the backend, to pause streaming on another 
  87.664 - * TV content channel.
  87.665 - * 
  87.666 - * @param recorder The GMythRecorder instance.
  87.667 - * @return true if success, false if any error happens.
  87.668 - */
  87.669 -gboolean
  87.670 -gmyth_recorder_pause_recording(GMythRecorder * recorder)
  87.671 -{
  87.672 -    GMythStringList *str_list;
  87.673 -    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  87.674 -    gboolean        ret = TRUE;
  87.675 -
  87.676 -    gmyth_debug("[%s] PAUSE", __FUNCTION__);
  87.677 -
  87.678 -    str_list = gmyth_string_list_new();
  87.679 -
  87.680 -    g_mutex_lock(recorder->mutex);
  87.681 -
  87.682 -    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  87.683 -
  87.684 -    gmyth_string_list_append_string(str_list, tmp_str);
  87.685 -    g_string_free(tmp_str, TRUE);
  87.686 -
  87.687 -    gmyth_string_list_append_char_array(str_list, "PAUSE");
  87.688 -
  87.689 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  87.690 -
  87.691 -    tmp_str = gmyth_string_list_get_string(str_list, 0);
  87.692 -
  87.693 -    if (tmp_str == NULL) {
  87.694 -        gmyth_debug("[%s] PAUSE name request returned %s", __FUNCTION__,
  87.695 -                    tmp_str->str);
  87.696 -        ret = FALSE;
  87.697 -        goto cleanup;
  87.698 -    }
  87.699 -
  87.700 -    if (g_ascii_strncasecmp(tmp_str->str, "ok", 2)) {
  87.701 -        gmyth_debug("[%s] PAUSE name request returned %s", __FUNCTION__,
  87.702 -                    tmp_str->str);
  87.703 -        ret = FALSE;
  87.704 -        goto cleanup;
  87.705 -    }
  87.706 -
  87.707 -  cleanup:
  87.708 -    g_mutex_unlock(recorder->mutex);
  87.709 -    g_string_free(tmp_str, TRUE);
  87.710 -    g_object_unref(str_list);
  87.711 -
  87.712 -    return ret;
  87.713 -}
  87.714 -
  87.715 -static          gboolean
  87.716 -gmyth_recorder_find_if_program_exists(GMythRecorder * recorder,
  87.717 -                                      GMythProgramInfo * prog)
  87.718 -{
  87.719 -    GList          *lst = NULL;
  87.720 -
  87.721 -    g_return_val_if_fail(recorder != NULL
  87.722 -                         && recorder->progs_info_list != NULL, FALSE);
  87.723 -
  87.724 -    for (lst = recorder->progs_info_list; lst != NULL;
  87.725 -         lst = g_list_next(lst)) {
  87.726 -        gmyth_debug("Got program info from list = [%s]",
  87.727 -                    gmyth_program_info_to_string((GMythProgramInfo *)
  87.728 -                                                 lst->data));
  87.729 -        if (gmyth_program_info_is_equals
  87.730 -            (prog, (GMythProgramInfo *) lst->data))
  87.731 -            return TRUE;
  87.732 -    }
  87.733 -
  87.734 -    return FALSE;
  87.735 -}
  87.736 -
  87.737 -/**
  87.738 - * Requests the actual program info from the MythTV backend server.
  87.739 - * 
  87.740 - * @param recorder The GMythRecorder instance.
  87.741 - * @return The actual program info.
  87.742 - */
  87.743 -GMythProgramInfo *
  87.744 -gmyth_recorder_get_current_program_info(GMythRecorder * recorder)
  87.745 -{
  87.746 -    GMythStringList *str_list = NULL;
  87.747 -    GMythProgramInfo *program_info = NULL;
  87.748 -    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  87.749 -
  87.750 -    str_list = gmyth_string_list_new();
  87.751 -
  87.752 -    g_mutex_lock(recorder->mutex);
  87.753 -
  87.754 -    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  87.755 -
  87.756 -    gmyth_string_list_append_string(str_list, tmp_str);
  87.757 -
  87.758 -    if (recorder->myth_socket->mythtv_version >= 26)
  87.759 -        gmyth_string_list_append_char_array(str_list,
  87.760 -                                            "GET_CURRENT_RECORDING");
  87.761 -    else
  87.762 -        gmyth_string_list_append_char_array(str_list, "GET_PROGRAM_INFO");
  87.763 -
  87.764 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
  87.765 -
  87.766 -    if (str_list == NULL) {
  87.767 -        gmyth_debug
  87.768 -            ("[%s] GET_PROGRAM_INFO request returned. Error getting program info, string list equals to NULL!",
  87.769 -             __FUNCTION__);
  87.770 -        goto cleanup;
  87.771 -    }
  87.772 -
  87.773 -    program_info = gmyth_program_info_from_string_list(str_list);
  87.774 -
  87.775 -    if (NULL == program_info || NULL == program_info->pathname
  87.776 -        || program_info->pathname->len <= 0) {
  87.777 -        gmyth_debug
  87.778 -            ("GET_PROGRAM_INFO request returned. Error getting program info, it is equals to NULL!!!");
  87.779 -
  87.780 -        if (program_info)
  87.781 -            g_object_unref(program_info);
  87.782 -
  87.783 -        program_info = NULL;
  87.784 -
  87.785 -        goto cleanup;
  87.786 -    }
  87.787 -
  87.788 -    if (!gmyth_recorder_find_if_program_exists(recorder, program_info))
  87.789 -        recorder->progs_info_list =
  87.790 -            g_list_append(recorder->progs_info_list,
  87.791 -                          g_object_ref(program_info));
  87.792 -  cleanup:
  87.793 -    g_mutex_unlock(recorder->mutex);
  87.794 -    g_string_free(tmp_str, TRUE);
  87.795 -    g_object_unref(str_list);
  87.796 -
  87.797 -    return program_info;
  87.798 -}
  87.799 -
  87.800 -/**
  87.801 - * Requests the actual program info from the MythTV backend server.
  87.802 - * 
  87.803 - * @param rec_id The GMythRecorder record number.
  87.804 - * @return The GMythRecorder instance.
  87.805 - */
  87.806 -GMythRecorder  *
  87.807 -gmyth_recorder_get_recorder_from_num(gint rec_id)
  87.808 -{
  87.809 -    GMythRecorder  *recorder = NULL;
  87.810 -    GMythStringList *str_list;
  87.811 -    GString        *tmp_str = g_string_new("GET_RECORDER_FROM_NUM");
  87.812 -    gint            command_size = 0;
  87.813 -
  87.814 -    gchar          *recorder_host = NULL;
  87.815 -    gint            recorder_port;
  87.816 -
  87.817 -    str_list = gmyth_string_list_new();
  87.818 -
  87.819 -    /*
  87.820 -     * g_string_append_printf ( tmp_str, " %d", recorder->recorder_num ); 
  87.821 -     */
  87.822 -
  87.823 -    g_mutex_lock(recorder->mutex);
  87.824 -
  87.825 -    gmyth_string_list_append_string(str_list, tmp_str);
  87.826 -
  87.827 -    gmyth_string_list_append_int(str_list, rec_id);
  87.828 -
  87.829 -    command_size =
  87.830 -        gmyth_socket_sendreceive_stringlist(recorder->myth_socket,
  87.831 -                                            str_list);
  87.832 -
  87.833 -    if (str_list == NULL) {
  87.834 -        gmyth_debug
  87.835 -            ("[%s] GET_RECORDER_FROM_NUM request returned. Error getting recorder number %d, it is equals to NULL!!!",
  87.836 -             __FUNCTION__, rec_id);
  87.837 -        return NULL;
  87.838 -    }
  87.839 -
  87.840 -    if (command_size > 0) {
  87.841 -        recorder_host = gmyth_string_list_get_char_array(str_list, 0);
  87.842 -        recorder_port = gmyth_string_list_get_int(str_list, 1);
  87.843 -
  87.844 -        if (g_strstr_len(recorder_host, strlen(recorder_host), "nohost")
  87.845 -            != NULL) {
  87.846 -            gmyth_debug
  87.847 -                ("No available recorder with the recorder ID number %d!",
  87.848 -                 rec_id);
  87.849 -        } else {
  87.850 -
  87.851 -            recorder = gmyth_recorder_new(rec_id,
  87.852 -                                          g_string_new(recorder_host),
  87.853 -                                          (gshort) recorder_port);
  87.854 -
  87.855 -            if (NULL == recorder) {
  87.856 -                gmyth_debug
  87.857 -                    ("[%s] GET_RECORDER_FROM_NUM request returned. Error getting recorder number %d, it is equals to NULL!!!",
  87.858 -                     __FUNCTION__, rec_id);
  87.859 -                g_object_unref(recorder);
  87.860 -                return NULL;
  87.861 -            }
  87.862 -
  87.863 -        }
  87.864 -
  87.865 -    } else {
  87.866 -        gmyth_debug
  87.867 -            ("Cannot find a valuable recorder with the recorder ID number %d, backend server error!",
  87.868 -             rec_id);
  87.869 -    }
  87.870 -
  87.871 -    g_mutex_unlock(recorder->mutex);
  87.872 -
  87.873 -    g_object_unref(str_list);
  87.874 -
  87.875 -    g_string_free(tmp_str, TRUE);
  87.876 -
  87.877 -    g_free(recorder_host);
  87.878 -
  87.879 -    return recorder;
  87.880 -
  87.881 -}
  87.882 -
  87.883 -/**
  87.884 - * Requests the actual program info from the MythTV backend server.
  87.885 - * 
  87.886 - * @param recorder The GMythRecorder instance.
  87.887 - * @param direction The direction to move based on the current channel (forward, backward,
  87.888 - *            up, down).
  87.889 - * 
  87.890 - * @return The GMythProgramInfo next program info instance.
  87.891 - */
  87.892 -GMythProgramInfo *
  87.893 -gmyth_recorder_get_next_program_info(GMythRecorder * recorder,
  87.894 -                                     const GMythRecorderBrowseDirection
  87.895 -                                     direction)
  87.896 -{
  87.897 -    GMythProgramInfo *actual_proginfo = NULL;
  87.898 -    GMythProgramInfo *program_info = NULL;
  87.899 -    GMythStringList *str_list;
  87.900 -    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
  87.901 -
  87.902 -    gchar          *date = NULL;
  87.903 -    struct tm      *tm = NULL;
  87.904 -    time_t          t;
  87.905 -
  87.906 -    actual_proginfo = gmyth_recorder_get_current_program_info(recorder);
  87.907 -
  87.908 -    str_list = gmyth_string_list_new();
  87.909 -
  87.910 -    g_mutex_lock(recorder->mutex);
  87.911 -
  87.912 -    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
  87.913 -
  87.914 -    t = time(NULL);
  87.915 -    tm = localtime(&t);
  87.916 -    date = g_strdup_printf("%.4d%.2d%.2d%.2d%.2d%.2d", tm->tm_year + 1900,
  87.917 -                           tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
  87.918 -                           tm->tm_min, tm->tm_sec);
  87.919 -
  87.920 -    gmyth_string_list_append_string(str_list, tmp_str);
  87.921 -    gmyth_string_list_append_char_array(str_list, "GET_NEXT_PROGRAM_INFO");
  87.922 -    gmyth_string_list_append_string(str_list, actual_proginfo->channame);
  87.923 -    gmyth_string_list_append_int(str_list, actual_proginfo->channel_id);
  87.924 -    gmyth_string_list_append_int(str_list, direction);
  87.925 -    gmyth_string_list_append_char_array(str_list, date);
  87.926 -
  87.927 -    if (gmyth_socket_sendreceive_stringlist
  87.928 -        (recorder->myth_socket, str_list)
  87.929 -        > 0) {
  87.930 -
  87.931 -        if (str_list == NULL) {
  87.932 -            gmyth_debug
  87.933 -                ("[%s] GET_NEXT_PROGRAM_INFO request returned. Error getting program info, it is equals to NULL!!!",
  87.934 -                 __FUNCTION__);
  87.935 -            goto done;
  87.936 -        }
  87.937 -        program_info =
  87.938 -            gmyth_program_info_from_string_list_next_prog(str_list);
  87.939 -
  87.940 -        if (NULL == program_info) {
  87.941 -            gmyth_debug
  87.942 -                ("[%s] GET_NEXT_PROGRAM_INFO request returned. Error getting next program info, it is equals to NULL!!!",
  87.943 -                 __FUNCTION__);
  87.944 -            g_object_unref(program_info);
  87.945 -            goto done;
  87.946 -        }
  87.947 -
  87.948 -        if (                    /* ( program_info->chanid != NULL &&
  87.949 -                                 * strlen( program_info->chanid->str ) > 0 
  87.950 -                                 * * * * * * ) && */
  87.951 -               (program_info->chansign != NULL
  87.952 -                && strlen(program_info->chansign->str) > 0)) {
  87.953 -            gmyth_debug("OK!!! Got the next program info... [%s].",
  87.954 -                        program_info->chansign->str);
  87.955 -        } else {
  87.956 -            gmyth_debug
  87.957 -                ("GET_NEXT_PROGRAM_INFO request returned. Error getting next program info, it is equals to NULL!!!");
  87.958 -            g_object_unref(program_info);
  87.959 -            program_info = NULL;
  87.960 -        }
  87.961 -
  87.962 -    }
  87.963 -    /*
  87.964 -     * if 
  87.965 -     */
  87.966 -  done:
  87.967 -
  87.968 -    g_mutex_unlock(recorder->mutex);
  87.969 -
  87.970 -    if (actual_proginfo != NULL)
  87.971 -        g_object_unref(actual_proginfo);
  87.972 -
  87.973 -    if (str_list != NULL)
  87.974 -        g_object_unref(str_list);
  87.975 -
  87.976 -    if (tmp_str != NULL)
  87.977 -        g_string_free(tmp_str, TRUE);
  87.978 -
  87.979 -    if (date != NULL)
  87.980 -        g_free(date);
  87.981 -    // if ( tm != NULL)
  87.982 -    // g_free (tm);
  87.983 -
  87.984 -    return program_info;
  87.985 -}
  87.986 -
  87.987 -/**
  87.988 - * Requests the program info from the MythTV backend server, based on its 
  87.989 - * channel name.
  87.990 - * 
  87.991 - * @param recorder The GMythRecorder instance.
  87.992 - * @return The GMythProgramInfo next program info instance.
  87.993 - */
  87.994 -GMythProgramInfo *
  87.995 -gmyth_recorder_get_program_info_from_channel_name(GMythRecorder * recorder,
  87.996 -                                                  const gchar * channel)
  87.997 -{
  87.998 -    // GMythProgramInfo* actual_proginfo= NULL;
  87.999 -    GMythProgramInfo *program_info = NULL;
 87.1000 -    GMythStringList *str_list;
 87.1001 -    GString        *tmp_str = g_string_new(GMYTHTV_RECORDER_HEADER);
 87.1002 -
 87.1003 -    /*
 87.1004 -     * gchar *date = NULL; struct tm *tm = NULL; time_t t;
 87.1005 -     * 
 87.1006 -     * actual_proginfo =
 87.1007 -     * gmyth_recorder_get_current_program_info(recorder); 
 87.1008 -     */
 87.1009 -
 87.1010 -    str_list = gmyth_string_list_new();
 87.1011 -
 87.1012 -    g_mutex_lock(recorder->mutex);
 87.1013 -
 87.1014 -    g_string_append_printf(tmp_str, " %d", recorder->recorder_num);
 87.1015 -
 87.1016 -    /*
 87.1017 -     * t = time(NULL); tm = localtime(&t); date =
 87.1018 -     * g_strdup_printf("%.4d%.2d%.2d%.2d%.2d%.2d", tm->tm_year + 1900,
 87.1019 -     * tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); 
 87.1020 -     */
 87.1021 -
 87.1022 -    gmyth_string_list_append_string(str_list, tmp_str);
 87.1023 -    gmyth_string_list_append_char_array(str_list, "GET_NEXT_PROGRAM_INFO");
 87.1024 -    gmyth_string_list_append_char_array(str_list, channel);
 87.1025 -    gmyth_string_list_append_char_array(str_list, "0");
 87.1026 -    gmyth_string_list_append_int(str_list, BROWSE_DIRECTION_UP);
 87.1027 -    gmyth_string_list_append_char_array(str_list, "0");
 87.1028 -
 87.1029 -    do {
 87.1030 -
 87.1031 -        if (str_list != NULL &&
 87.1032 -            gmyth_socket_sendreceive_stringlist(recorder->myth_socket,
 87.1033 -                                                str_list) > 0) {
 87.1034 -
 87.1035 -            if (str_list == NULL) {
 87.1036 -                gmyth_debug
 87.1037 -                    ("[%s] GET_NEXT_PROGRAM_INFO request returned. Error getting program info, it is equals to NULL!!!",
 87.1038 -                     __FUNCTION__);
 87.1039 -                goto done;
 87.1040 -            }
 87.1041 -            program_info =
 87.1042 -                gmyth_program_info_from_string_list_next_prog(str_list);
 87.1043 -
 87.1044 -            if (NULL == program_info) {
 87.1045 -                gmyth_debug
 87.1046 -                    ("[%s] GET_NEXT_PROGRAM_INFO request returned. Error getting next program info, it is equals to NULL!!!",
 87.1047 -                     __FUNCTION__);
 87.1048 -                g_object_unref(program_info);
 87.1049 -                goto done;
 87.1050 -            }
 87.1051 -
 87.1052 -            if (                /* ( program_info->chanid != NULL &&
 87.1053 -                                 * strlen( program_info->chanid->str ) > 0 
 87.1054 -                                 * * * * * * ) && */
 87.1055 -                   (program_info->chansign != NULL
 87.1056 -                    && strlen(program_info->chansign->str) > 0)) {
 87.1057 -                gmyth_debug("OK!!! Got the next program info... [%s].",
 87.1058 -                            program_info->chansign->str);
 87.1059 -            } else {
 87.1060 -                gmyth_debug
 87.1061 -                    ("GET_NEXT_PROGRAM_INFO request returned. Error getting "
 87.1062 -                     "next program info, it is equals to NULL!!!");
 87.1063 -                g_object_unref(program_info);
 87.1064 -                program_info = NULL;
 87.1065 -            }
 87.1066 -
 87.1067 -        }
 87.1068 -        /*
 87.1069 -         * if 
 87.1070 -         */
 87.1071 -    }
 87.1072 -    while (str_list != NULL);
 87.1073 -
 87.1074 -  done:
 87.1075 -
 87.1076 -    g_mutex_unlock(recorder->mutex);
 87.1077 -
 87.1078 -    if (str_list != NULL)
 87.1079 -        g_object_unref(str_list);
 87.1080 -
 87.1081 -    if (tmp_str != NULL)
 87.1082 -        g_string_free(tmp_str, TRUE);
 87.1083 -
 87.1084 -    return program_info;
 87.1085 -}
 87.1086 -
 87.1087 -/**
 87.1088 - * Requests the actual remote file position on a LiveTV instance.
 87.1089 - * 
 87.1090 - * @param recorder The GMythRecorder instance.
 87.1091 - * 
 87.1092 - * @return The position, in bytes, of the offset to the read header.
 87.1093 - */
 87.1094 -gint64
 87.1095 -gmyth_recorder_get_file_position(GMythRecorder * recorder)
 87.1096 -{
 87.1097 -    gint64          pos = 0;
 87.1098 -    GString        *query = g_string_new(GMYTHTV_RECORDER_HEADER);
 87.1099 -
 87.1100 -    GMythStringList *str_list = gmyth_string_list_new();
 87.1101 -
 87.1102 -    g_mutex_lock(recorder->mutex);
 87.1103 -
 87.1104 -    g_string_append_printf(query, " %d", recorder->recorder_num);
 87.1105 -
 87.1106 -    gmyth_string_list_append_string(str_list, query);
 87.1107 -    gmyth_string_list_append_char_array(str_list, "GET_FILE_POSITION");
 87.1108 -
 87.1109 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
 87.1110 -
 87.1111 -    if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
 87.1112 -        GString        *str = NULL;
 87.1113 -
 87.1114 -        if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL
 87.1115 -            && strstr(str->str, "bad") == NULL)
 87.1116 -            pos = gmyth_string_list_get_int64(str_list, 0);
 87.1117 -        g_string_free(str, TRUE);
 87.1118 -    }
 87.1119 -#ifndef GMYTHTV_ENABLE_DEBUG
 87.1120 -    gmyth_debug("[%s] Got file position = %lld\n", __FUNCTION__, pos);
 87.1121 -#endif
 87.1122 -
 87.1123 -    g_mutex_unlock(recorder->mutex);
 87.1124 -
 87.1125 -    if (str_list != NULL)
 87.1126 -        g_object_unref(str_list);
 87.1127 -
 87.1128 -    g_string_free(query, TRUE);
 87.1129 -
 87.1130 -    return pos;
 87.1131 -}
 87.1132 -
 87.1133 -/**
 87.1134 - * Asks MythTV backend server about if it started to record the remote file.
 87.1135 - * 
 87.1136 - * @param recorder The GMythRecorder instance.
 87.1137 - * 
 87.1138 - * @return <code>true</code>, if the actual remote file is bein recorded.
 87.1139 - */
 87.1140 -gboolean
 87.1141 -gmyth_recorder_is_recording(GMythRecorder * recorder)
 87.1142 -{
 87.1143 -    gboolean        ret = TRUE;
 87.1144 -
 87.1145 -    g_return_val_if_fail(recorder != NULL, FALSE);
 87.1146 -
 87.1147 -    GMythStringList *str_list = gmyth_string_list_new();
 87.1148 -    GString        *message = g_string_new("");
 87.1149 -
 87.1150 -    g_mutex_lock(recorder->mutex);
 87.1151 -
 87.1152 -    g_string_printf(message, "%s %d", GMYTHTV_RECORDER_HEADER,
 87.1153 -                    recorder->recorder_num);
 87.1154 -    gmyth_string_list_append_string(str_list, message);
 87.1155 -    gmyth_string_list_append_char_array(str_list, "IS_RECORDING");
 87.1156 -
 87.1157 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
 87.1158 -
 87.1159 -    if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
 87.1160 -        GString        *str = NULL;
 87.1161 -
 87.1162 -        if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL
 87.1163 -            && strcmp(str->str, "bad") != 0) {
 87.1164 -            gint            is_rec =
 87.1165 -                gmyth_string_list_get_int(str_list, 0);
 87.1166 -
 87.1167 -            if (is_rec != 0)
 87.1168 -                ret = TRUE;
 87.1169 -            else
 87.1170 -                ret = FALSE;
 87.1171 -        }
 87.1172 -        g_string_free(str, TRUE);
 87.1173 -    }
 87.1174 -
 87.1175 -    gmyth_debug("%s, stream is %s being recorded!\n", ret ? "YES" : "NO",
 87.1176 -                ret ? "" : "NOT");
 87.1177 -    // g_static_mutex_unlock (&mutex);
 87.1178 -
 87.1179 -    g_mutex_unlock(recorder->mutex);
 87.1180 -
 87.1181 -    if (str_list != NULL)
 87.1182 -        g_object_unref(str_list);
 87.1183 -
 87.1184 -    g_string_free(message, TRUE);
 87.1185 -
 87.1186 -    return ret;
 87.1187 -
 87.1188 -}
 87.1189 -
 87.1190 -/**
 87.1191 - * Finish remote file recording process.
 87.1192 - * 
 87.1193 - * @param recorder The GMythRecorder instance.
 87.1194 - * 
 87.1195 - * @return <code>true</code>, if the recording had been actually closed.
 87.1196 - */
 87.1197 -gboolean
 87.1198 -gmyth_recorder_finish_recording(GMythRecorder * recorder)
 87.1199 -{
 87.1200 -    gboolean        ret = TRUE;
 87.1201 -
 87.1202 -    g_return_val_if_fail(recorder != NULL, FALSE);
 87.1203 -
 87.1204 -    GMythStringList *str_list = gmyth_string_list_new();
 87.1205 -    GString        *message = g_string_new("");
 87.1206 -
 87.1207 -    g_string_printf(message, "%s %d", GMYTHTV_RECORDER_HEADER,
 87.1208 -                    recorder->recorder_num);
 87.1209 -    gmyth_string_list_append_string(str_list, message);
 87.1210 -    gmyth_string_list_append_char_array(str_list, "FINISH_RECORDING");
 87.1211 -
 87.1212 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
 87.1213 -
 87.1214 -    if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
 87.1215 -        GString        *str = NULL;
 87.1216 -
 87.1217 -        if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL &&
 87.1218 -            strcmp(str->str, "ok") != 0) {
 87.1219 -            gint            is_rec =
 87.1220 -                gmyth_string_list_get_int(str_list, 0);
 87.1221 -
 87.1222 -            if (is_rec != 0)
 87.1223 -                ret = TRUE;
 87.1224 -            else
 87.1225 -                ret = FALSE;
 87.1226 -        }
 87.1227 -        g_string_free(str, TRUE);
 87.1228 -    }
 87.1229 -
 87.1230 -    gmyth_debug("%s, stream is %s finished!\n", ret ? "YES" : "NO",
 87.1231 -                ret ? "" : "NOT");
 87.1232 -    // g_static_mutex_unlock (&mutex);
 87.1233 -
 87.1234 -    if (str_list != NULL)
 87.1235 -        g_object_unref(str_list);
 87.1236 -
 87.1237 -    g_string_free(message, TRUE);
 87.1238 -
 87.1239 -    return ret;
 87.1240 -}
 87.1241 -
 87.1242 -
 87.1243 -/**
 87.1244 - * Stops playing the remote file.
 87.1245 - * 
 87.1246 - * @param recorder The GMythRecorder instance.
 87.1247 - * 
 87.1248 - * @return <code>true</code>, if the recording had been actually stopped.
 87.1249 - */
 87.1250 -gboolean
 87.1251 -gmyth_recorder_stop_playing(GMythRecorder * recorder)
 87.1252 -{
 87.1253 -    gboolean        ret = TRUE;
 87.1254 -
 87.1255 -    g_return_val_if_fail(recorder != NULL, FALSE);
 87.1256 -
 87.1257 -    GMythStringList *str_list = gmyth_string_list_new();
 87.1258 -    GString        *message = g_string_new("");
 87.1259 -
 87.1260 -    g_string_printf(message, "%s %d", GMYTHTV_RECORDER_HEADER,
 87.1261 -                    recorder->recorder_num);
 87.1262 -    gmyth_string_list_append_string(str_list, message);
 87.1263 -    gmyth_string_list_append_char_array(str_list, "STOP_PLAYING");
 87.1264 -
 87.1265 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
 87.1266 -
 87.1267 -    if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
 87.1268 -        GString        *str = NULL;
 87.1269 -
 87.1270 -        if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL &&
 87.1271 -            strcmp(str->str, "ok") != 0) {
 87.1272 -            gint            is_rec =
 87.1273 -                gmyth_string_list_get_int(str_list, 0);
 87.1274 -
 87.1275 -            if (is_rec != 0)
 87.1276 -                ret = TRUE;
 87.1277 -            else
 87.1278 -                ret = FALSE;
 87.1279 -        }
 87.1280 -        g_string_free(str, TRUE);
 87.1281 -    }
 87.1282 -
 87.1283 -    gmyth_debug("%s, stream is %s stopped!\n", ret ? "YES" : "NO",
 87.1284 -                ret ? "" : "NOT");
 87.1285 -
 87.1286 -    if (str_list != NULL)
 87.1287 -        g_object_unref(str_list);
 87.1288 -
 87.1289 -    g_string_free(message, TRUE);
 87.1290 -
 87.1291 -    return ret;
 87.1292 -}
 87.1293 -
 87.1294 -/**
 87.1295 - * Free the tuner responsible for recording this channel.
 87.1296 - * 
 87.1297 - * @param recorder The GMythRecorder instance.
 87.1298 - * 
 87.1299 - * @return <code>true</code>, if the tuner had been freed.
 87.1300 - */
 87.1301 -gboolean
 87.1302 -gmyth_recorder_free_tuner(GMythRecorder * recorder)
 87.1303 -{
 87.1304 -    gboolean        ret = TRUE;
 87.1305 -
 87.1306 -    g_return_val_if_fail(recorder != NULL, FALSE);
 87.1307 -
 87.1308 -    GMythStringList *str_list = gmyth_string_list_new();
 87.1309 -    GString        *message = g_string_new("");
 87.1310 -
 87.1311 -    g_string_printf(message, "%s %d", "FREE_TUNER",
 87.1312 -                    recorder->recorder_num);
 87.1313 -    gmyth_string_list_append_string(str_list, message);
 87.1314 -
 87.1315 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
 87.1316 -
 87.1317 -    if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
 87.1318 -        GString        *str = NULL;
 87.1319 -
 87.1320 -        if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL &&
 87.1321 -            g_ascii_strncasecmp(str->str, "ok", 2) != 0) {
 87.1322 -            gint            is_rec =
 87.1323 -                gmyth_string_list_get_int(str_list, 0);
 87.1324 -
 87.1325 -            if (is_rec != 0)
 87.1326 -                ret = TRUE;
 87.1327 -            else
 87.1328 -                ret = FALSE;
 87.1329 -        }
 87.1330 -        g_string_free(str, TRUE);
 87.1331 -    }
 87.1332 -
 87.1333 -    gmyth_debug("%s, tuner is %s freed!\n", ret ? "YES" : "NO",
 87.1334 -                ret ? "" : "NOT");
 87.1335 -
 87.1336 -    if (str_list != NULL)
 87.1337 -        g_object_unref(str_list);
 87.1338 -
 87.1339 -    g_string_free(message, TRUE);
 87.1340 -
 87.1341 -    return ret;
 87.1342 -}
 87.1343 -
 87.1344 -/**
 87.1345 - * Asks the MythTV backend server about the frame rate 
 87.1346 - * of this LiveTV instance.
 87.1347 - * 
 87.1348 - * @param recorder The GMythRecorder instance.
 87.1349 - * 
 87.1350 - * @return The framerate (double value) of the current video.
 87.1351 - */
 87.1352 -gdouble
 87.1353 -gmyth_recorder_get_framerate(GMythRecorder * recorder)
 87.1354 -{
 87.1355 -    gdouble         fr = 0.0f;
 87.1356 -    GString        *query = g_string_new(GMYTHTV_RECORDER_HEADER);
 87.1357 -
 87.1358 -    GMythStringList *str_list = gmyth_string_list_new();
 87.1359 -
 87.1360 -    g_mutex_lock(recorder->mutex);
 87.1361 -
 87.1362 -    g_string_append_printf(query, " %d", recorder->recorder_num);
 87.1363 -
 87.1364 -    gmyth_string_list_append_string(str_list, query);
 87.1365 -    gmyth_string_list_append_char_array(str_list, "GET_FRAMERATE");
 87.1366 -
 87.1367 -    gmyth_socket_sendreceive_stringlist(recorder->myth_socket, str_list);
 87.1368 -
 87.1369 -    if (str_list != NULL && gmyth_string_list_length(str_list) > 0) {
 87.1370 -        GString        *str = NULL;
 87.1371 -
 87.1372 -        if ((str = gmyth_string_list_get_string(str_list, 0)) != NULL
 87.1373 -            && strstr(str->str, "bad") == NULL)
 87.1374 -            fr = g_ascii_strtod(str->str, NULL);
 87.1375 -
 87.1376 -        g_string_free(str, TRUE);
 87.1377 -    }
 87.1378 -#ifndef GMYTHTV_ENABLE_DEBUG
 87.1379 -    gmyth_debug("[%s] Got file position = %f\n", __FUNCTION__, fr);
 87.1380 -#endif
 87.1381 -
 87.1382 -    g_mutex_unlock(recorder->mutex);
 87.1383 -
 87.1384 -    if (str_list != NULL)
 87.1385 -        g_object_unref(str_list);
 87.1386 -
 87.1387 -    g_string_free(query, TRUE);
 87.1388 -
 87.1389 -    return fr;
 87.1390 -
 87.1391 -}
    88.1 --- a/gmyth/src/gmyth_recorder.h	Mon Feb 25 17:45:36 2008 +0000
    88.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.3 @@ -1,162 +0,0 @@
    88.4 -/**
    88.5 - * GMyth Library
    88.6 - *
    88.7 - * @file gmyth/gmyth_recorder.h
    88.8 - * 
    88.9 - * @brief <p> GMythRecorder defines functions for playing live tv.
   88.10 - *
   88.11 - * The remote encoder is used by gmyth_tvplayer to setup livetv. 
   88.12 - *
   88.13 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   88.14 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   88.15 - * @author Rosfran Borges <rosfran.borges@indt.org.br>
   88.16 - *
   88.17 - * 
   88.18 - * This program is free software; you can redistribute it and/or modify
   88.19 - * it under the terms of the GNU Lesser General Public License as published by
   88.20 - * the Free Software Foundation; either version 2 of the License, or
   88.21 - * (at your option) any later version.
   88.22 - *
   88.23 - * This program is distributed in the hope that it will be useful,
   88.24 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   88.25 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   88.26 - * GNU General Public License for more details.
   88.27 - *
   88.28 - * You should have received a copy of the GNU Lesser General Public License
   88.29 - * along with this program; if not, write to the Free Software
   88.30 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   88.31 - */
   88.32 -
   88.33 -#ifndef __GMYTH_RECORDER_H__
   88.34 -#define __GMYTH_RECORDER_H__
   88.35 -
   88.36 -#include <glib-object.h>
   88.37 -
   88.38 -#include "gmyth_socket.h"
   88.39 -#include "gmyth_programinfo.h"
   88.40 -
   88.41 -#include <stdio.h>
   88.42 -#include <stdlib.h>
   88.43 -#include <string.h>
   88.44 -#include <netdb.h>
   88.45 -#include <sys/socket.h>
   88.46 -#include <unistd.h>
   88.47 -
   88.48 -G_BEGIN_DECLS
   88.49 -#define GMYTH_RECORDER_TYPE               (gmyth_recorder_get_type ())
   88.50 -#define GMYTH_RECORDER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_RECORDER_TYPE, GMythRecorder))
   88.51 -#define GMYTH_RECORDER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_RECORDER_TYPE, GMythRecorderClass))
   88.52 -#define IS_GMYTH_RECORDER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_RECORDER_TYPE))
   88.53 -#define IS_GMYTH_RECORDER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_RECORDER_TYPE))
   88.54 -#define GMYTH_RECORDER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_RECORDER_TYPE, GMythRecorderClass))
   88.55 -typedef struct _GMythRecorder GMythRecorder;
   88.56 -typedef struct _GMythRecorderClass GMythRecorderClass;
   88.57 -
   88.58 -struct _GMythRecorderClass {
   88.59 -    GObjectClass    parent_class;
   88.60 -
   88.61 -    /*
   88.62 -     * callbacks 
   88.63 -     */
   88.64 -    /*
   88.65 -     * no one for now 
   88.66 -     */
   88.67 -};
   88.68 -
   88.69 -struct _GMythRecorder {
   88.70 -    GObject         parent;
   88.71 -
   88.72 -    /*
   88.73 -     * socket descriptor 
   88.74 -     */
   88.75 -    GMythSocket    *myth_socket;
   88.76 -
   88.77 -    gint            recorder_num;
   88.78 -    GString        *hostname;
   88.79 -    gint            port;
   88.80 -
   88.81 -    GList          *progs_info_list;
   88.82 -
   88.83 -    GMutex         *mutex;
   88.84 -};
   88.85 -
   88.86 -typedef enum _GMythRecorderChannelChangeDirection {
   88.87 -    CHANNEL_DIRECTION_UP = 0,
   88.88 -    CHANNEL_DIRECTION_DOWN,
   88.89 -    CHANNEL_DIRECTION_FAVORITE,
   88.90 -    CHANNEL_DIRECTION_SAME
   88.91 -} GMythRecorderChannelChangeDirection;
   88.92 -
   88.93 -typedef enum _GMythRecorderBrowseDirection {
   88.94 -    BROWSE_DIRECTION_SAME = 0,  /* Stay in the same place */
   88.95 -    BROWSE_DIRECTION_UP,        /* Move up one slot (down one channel) */
   88.96 -    BROWSE_DIRECTION_DOWN,      /* Move down one slot (up one channel) */
   88.97 -    BROWSE_DIRECTION_LEFT,      /* Move left one slot (down one time slot) 
   88.98 -                                 */
   88.99 -    BROWSE_DIRECTION_RIGHT,     /* Move right one slot (up one time slot) */
  88.100 -    BROWSE_DIRECTION_FAVORITE   /* Move to the next favorite slot */
  88.101 -} GMythRecorderBrowseDirection;
  88.102 -
  88.103 -GType           gmyth_recorder_get_type(void);
  88.104 -
  88.105 -GMythRecorder  *gmyth_recorder_new(int num, GString * hostname,
  88.106 -                                   gshort port);
  88.107 -
  88.108 -void            gmyth_recorder_close(GMythRecorder * recorder);
  88.109 -
  88.110 -gboolean        gmyth_recorder_setup(GMythRecorder * recorder);
  88.111 -gboolean        gmyth_recorder_spawntv(GMythRecorder * recorder,
  88.112 -                                       GString * tvchain_id);
  88.113 -
  88.114 -gboolean        gmyth_recorder_spawntv_no_tvchain(GMythRecorder *
  88.115 -                                                  recorder);
  88.116 -
  88.117 -gboolean        gmyth_recorder_stop_livetv(GMythRecorder * recorder);
  88.118 -
  88.119 -gboolean        gmyth_recorder_send_frontend_ready_command(GMythRecorder *
  88.120 -                                                           recorder);
  88.121 -
  88.122 -gboolean        gmyth_recorder_check_channel(GMythRecorder * recorder,
  88.123 -                                             gint channel);
  88.124 -
  88.125 -gboolean        gmyth_recorder_check_channel_name(GMythRecorder * recorder,
  88.126 -                                                  gchar * channel);
  88.127 -
  88.128 -gboolean        gmyth_recorder_set_channel(GMythRecorder * recorder,
  88.129 -                                           gint channel);
  88.130 -
  88.131 -gboolean        gmyth_recorder_set_channel_name(GMythRecorder * recorder,
  88.132 -                                                const gchar * channel);
  88.133 -
  88.134 -gboolean        gmyth_recorder_change_channel(GMythRecorder * recorder, const
  88.135 -                                              GMythRecorderChannelChangeDirection
  88.136 -                                              direction);
  88.137 -
  88.138 -GList          *gmyth_recorder_get_channel_list(GMythRecorder * recorder);
  88.139 -
  88.140 -gboolean        gmyth_recorder_pause_recording(GMythRecorder * recorder);
  88.141 -
  88.142 -GMythProgramInfo *gmyth_recorder_get_current_program_info(GMythRecorder *
  88.143 -                                                          recorder);
  88.144 -
  88.145 -GMythProgramInfo *gmyth_recorder_get_next_program_info(GMythRecorder *
  88.146 -                                                       recorder, const
  88.147 -                                                       GMythRecorderBrowseDirection
  88.148 -                                                       direction);
  88.149 -
  88.150 -GMythRecorder  *gmyth_recorder_get_recorder_from_num(gint rec_id);
  88.151 -
  88.152 -gint64          gmyth_recorder_get_file_position(GMythRecorder * recorder);
  88.153 -
  88.154 -gboolean        gmyth_recorder_is_recording(GMythRecorder * recorder);
  88.155 -
  88.156 -gboolean        gmyth_recorder_finish_recording(GMythRecorder * recorder);
  88.157 -
  88.158 -gboolean        gmyth_recorder_stop_playing(GMythRecorder * recorder);
  88.159 -
  88.160 -gboolean        gmyth_recorder_free_tuner(GMythRecorder * recorder);
  88.161 -
  88.162 -gdouble         gmyth_recorder_get_framerate(GMythRecorder * recorder);
  88.163 -
  88.164 -G_END_DECLS
  88.165 -#endif                          /* __GMYTH_REMOTE_ENCODER_H__ */
    89.1 --- a/gmyth/src/gmyth_recprofile.c	Mon Feb 25 17:45:36 2008 +0000
    89.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.3 @@ -1,264 +0,0 @@
    89.4 -/**
    89.5 - * GMyth Library
    89.6 - * 
    89.7 - * @file gmyth/gmyth_recprofile.c
    89.8 - * 
    89.9 - * @brief <p> This file contains the recprofile class.
   89.10 - *
   89.11 - * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   89.12 - * @author Artur Duque de Souza <artur.souza@indt.org.br>
   89.13 - *
   89.14 - * This program is free software; you can redistribute it and/or modify
   89.15 - * it under the terms of the GNU Lesser General Public License as published by
   89.16 - * the Free Software Foundation; either version 2 of the License, or
   89.17 - * (at your option) any later version.
   89.18 - *
   89.19 - * This program is distributed in the hope that it will be useful,
   89.20 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   89.21 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   89.22 - * GNU General Public License for more details.
   89.23 - *
   89.24 - * You should have received a copy of the GNU Lesser General Public License
   89.25 - * along with this program; if not, write to the Free Software
   89.26 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   89.27 - */
   89.28 -
   89.29 -
   89.30 -#ifdef HAVE_CONFIG_H
   89.31 -#include "config.h"
   89.32 -#endif
   89.33 -
   89.34 -#include <stdlib.h>
   89.35 -#include <string.h>
   89.36 -#include <assert.h>
   89.37 -
   89.38 -#include "gmyth_recprofile.h"
   89.39 -#include "gmyth_util.h"
   89.40 -#include "gmyth_debug.h"
   89.41 -#include "gmyth_http.h"
   89.42 -
   89.43 -static void     gmyth_recprofile_class_init(GMythRecProfileClass * klass);
   89.44 -static void     gmyth_recprofile_init(GMythRecProfile * object);
   89.45 -
   89.46 -static void     gmyth_recprofile_dispose(GObject * object);
   89.47 -static void     gmyth_recprofile_finalize(GObject * object);
   89.48 -
   89.49 -G_DEFINE_TYPE(GMythRecProfile, gmyth_recprofile, G_TYPE_OBJECT)
   89.50 -    static void     gmyth_recprofile_class_init(GMythRecProfileClass *
   89.51 -                                                klass)
   89.52 -{
   89.53 -    GObjectClass   *gobject_class = G_OBJECT_CLASS(klass);
   89.54 -
   89.55 -    gobject_class->dispose = gmyth_recprofile_dispose;
   89.56 -    gobject_class->finalize = gmyth_recprofile_finalize;
   89.57 -}
   89.58 -
   89.59 -static void
   89.60 -gmyth_recprofile_init(GMythRecProfile * recprofile)
   89.61 -{
   89.62 -}
   89.63 -
   89.64 -static void
   89.65 -gmyth_recprofile_dispose(GObject * object)
   89.66 -{
   89.67 -    GMythRecProfile *recprofile = GMYTH_RECPROFILE(object);
   89.68 -
   89.69 -    if (recprofile->name)
   89.70 -        g_free(recprofile->name);
   89.71 -
   89.72 -    if (recprofile->group)
   89.73 -        g_free(recprofile->group);
   89.74 -
   89.75 -    if (recprofile->vcodec)
   89.76 -        g_free(recprofile->vcodec);
   89.77 -
   89.78 -    if (recprofile->acodec)
   89.79 -        g_free(recprofile->acodec);
   89.80 -
   89.81 -    if (recprofile->options)
   89.82 -        g_free(recprofile->options);
   89.83 -
   89.84 -    G_OBJECT_CLASS(gmyth_recprofile_parent_class)->dispose(object);
   89.85 -}
   89.86 -
   89.87 -static void
   89.88 -gmyth_recprofile_finalize(GObject * object)
   89.89 -{
   89.90 -    g_signal_handlers_destroy(object);
   89.91 -    G_OBJECT_CLASS(gmyth_recprofile_parent_class)->finalize(object);
   89.92 -}
   89.93 -
   89.94 -/**
   89.95 - * Creates a new instance of GMythRecProfile.
   89.96 - * 
   89.97 - * @return a new instance of GMythRecProfile.
   89.98 - **/
   89.99 -GMythRecProfile *
  89.100 -gmyth_recprofile_new(void)
  89.101 -{
  89.102 -    GMythRecProfile *recprofile = GMYTH_RECPROFILE
  89.103 -        (g_object_new(GMYTH_RECPROFILE_TYPE, NULL));
  89.104 -
  89.105 -    recprofile->id = 0;
  89.106 -    recprofile->name = NULL;
  89.107 -    recprofile->group = NULL;
  89.108 -    recprofile->vcodec = NULL;
  89.109 -    recprofile->acodec = NULL;
  89.110 -    recprofile->options = NULL;
  89.111 -
  89.112 -    return recprofile;
  89.113 -}
  89.114 -
  89.115 -
  89.116 -/**
  89.117 - *
  89.118 - * gmyth_recprofile_get_profile_list
  89.119 - * @brief get profile list from the backend
  89.120 - * @param backend_info GMythBackendInfo*
  89.121 - * @return GSList
  89.122 - *
  89.123 - **/
  89.124 -GSList         *
  89.125 -gmyth_recprofile_get_profile_list(GMythBackendInfo * backend_info)
  89.126 -{
  89.127 -    return gmyth_http_retrieve_rec_profiles(backend_info, "Transcoders");
  89.128 -}
  89.129 -
  89.130 -/**
  89.131 - *
  89.132 - * gmyth_recprofile_create_profile
  89.133 - * @brief get profile list from the backend
  89.134 - * @param backend_info GMythBackendInfo*
  89.135 - * @param profile GMythRecProfile*
  89.136 - * @return gint representing the result
  89.137 - *
  89.138 - **/
  89.139 -gint
  89.140 -gmyth_recprofile_create_profile(GMythBackendInfo * backend_info,
  89.141 -                                GMythRecProfile * profile)
  89.142 -{
  89.143 -    return gmyth_http_create_rec_profile(backend_info, profile);
  89.144 -}
  89.145 -
  89.146 -/**
  89.147 - *
  89.148 - * gmyth_recprofile_del_profile
  89.149 - * @brief del profile from the backend
  89.150 - * @param backend_info GMythBackendInfo*
  89.151 - * @param id profile's id
  89.152 - * @return gint representing the result
  89.153 - *
  89.154 - **/
  89.155 -gint
  89.156 -gmyth_recprofile_del_profile_list(GMythBackendInfo * backend_info, gint id)
  89.157 -{
  89.158 -    return gmyth_http_del_rec_profile(backend_info, id);
  89.159 -}
  89.160 -
  89.161 -/**
  89.162 - *
  89.163 - * gmyth_recprofile_set_id
  89.164 - * @brief set recprofile's id
  89.165 - * @param rec GMythRecProfile*
  89.166 - * @param id profile's id
  89.167 - * @return gint representing the result
  89.168 - *
  89.169 - **/
  89.170 -gint
  89.171 -gmyth_recprofile_set_id(GMythRecProfile * rec, gint id)
  89.172 -{
  89.173 -    rec->id = id;
  89.174 -    return 0;
  89.175 -}
  89.176 -
  89.177 -/**
  89.178 - *
  89.179 - * gmyth_recprofile_set
  89.180 - * @brief set recprofile's property
  89.181 - * @param rec GMythRecProfile*
  89.182 - * @param member the member you want to modify
  89.183 - * @param value the value
  89.184 - * @return gint representing the result
  89.185 - *
  89.186 - **/
  89.187 -gint
  89.188 -gmyth_recprofile_set(GMythRecProfile * rec, gchar * member, gchar * value)
  89.189 -{
  89.190 -    int             ret = 0;
  89.191 -
  89.192 -    if (value != NULL) {
  89.193 -        if (g_ascii_strcasecmp(member, "name") == 0)
  89.194 -            rec->name = g_strndup(value, strlen(value));
  89.195 -        else if (g_ascii_strcasecmp(member, "group") == 0)
  89.196 -            rec->group = g_strndup(value, strlen(value));
  89.197 -        else if (g_ascii_strcasecmp(member, "vcodec") == 0)
  89.198 -            rec->vcodec = g_strndup(value, strlen(value));
  89.199 -        else if (g_ascii_strcasecmp(member, "acodec") == 0)
  89.200 -            rec->acodec = g_strndup(value, strlen(value));
  89.201 -        else
  89.202 -            ret = -1;
  89.203 -    } else
  89.204 -        ret = -1;
  89.205 -
  89.206 -    return ret;
  89.207 -}
  89.208 -
  89.209 -/**
  89.210 - *
  89.211 - * gmyth_recprofile_set_name
  89.212 - * @brief set recprofile's name
  89.213 - * @param rec GMythRecProfile*
  89.214 - * @param name profile's name
  89.215 - * @return gint representing the result
  89.216 - *
  89.217 - **/
  89.218 -gint
  89.219 -gmyth_recprofile_set_name(GMythRecProfile * rec, gchar * name)
  89.220 -{
  89.221 -    return gmyth_recprofile_set(rec, "name", name);
  89.222 -}
  89.223 -
  89.224 -/**
  89.225 - *
  89.226 - * gmyth_recprofile_set_group
  89.227 - * @brief set recprofile's group
  89.228 - * @param rec GMythRecProfile*
  89.229 - * @param group profile's group
  89.230 - * @return gint representing the result
  89.231 - *
  89.232 - **/
  89.233 -gint
  89.234 -gmyth_recprofile_set_group(GMythRecProfile * rec, gchar * group)
  89.235 -{
  89.236 -    return gmyth_recprofile_set(rec, "group", group);
  89.237 -}
  89.238 -
  89.239 -/**
  89.240 - *
  89.241 - * gmyth_recprofile_set_vcodec
  89.242 - * @brief set recprofile's vcodec
  89.243 - * @param rec GMythRecProfile*
  89.244 - * @param vcodec profile's vcodec
  89.245 - * @return gint representing the result
  89.246 - *
  89.247 - **/
  89.248 -gint
  89.249 -gmyth_recprofile_set_vcodec(GMythRecProfile * rec, gchar * vcodec)
  89.250 -{
  89.251 -    return gmyth_recprofile_set(rec, "vcodec", vcodec);
  89.252 -}
  89.253 -
  89.254 -/**
  89.255 - *
  89.256 - * gmyth_recprofile_set_acodec
  89.257 - * @brief set recprofile's acodec
  89.258 - * @param rec GMythRecProfile*
  89.259 - * @param acodec profile's acodec
  89.260 - * @return gint representing the result
  89.261 - *
  89.262 - **/
  89.263 -gint
  89.264 -gmyth_recprofile_set_acodec(GMythRecProfile * rec, gchar * acodec)
  89.265 -{
  89.266 -    return gmyth_recprofile_set(rec, "acodec", acodec);
  89.267 -}
    90.1 --- a/gmyth/src/gmyth_recprofile.h	Mon Feb 25 17:45:36 2008 +0000
    90.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.3 @@ -1,123 +0,0 @@
    90.4 -/**
    90.5 - * GMyth Library
    90.6 - * 
    90.7 - * @file gmyth/gmyth_recprofile.h
    90.8 - * 
    90.9 - * @brief <p> This file contains the recprofile class.
   90.10 - *
   90.11 - * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   90.12 - * @author Artur Duque de Souza <artur.souza@indt.org.br>
   90.13 - *
   90.14 - * 
   90.15 - * This program is free software; you can redistribute it and/or modify
   90.16 - * it under the terms of the GNU Lesser General Public License as published by
   90.17 - * the Free Software Foundation; either version 2 of the License, or
   90.18 - * (at your option) any later version.
   90.19 - *
   90.20 - * This program is distributed in the hope that it will be useful,
   90.21 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   90.22 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   90.23 - * GNU General Public License for more details.
   90.24 - *
   90.25 - * You should have received a copy of the GNU Lesser General Public License
   90.26 - * along with this program; if not, write to the Free Software
   90.27 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   90.28 - */
   90.29 -
   90.30 -#ifndef _GMYTH_RECPROFILE_H
   90.31 -#define _GMYTH_RECPROFILE_H
   90.32 -
   90.33 -#include <glib.h>
   90.34 -#include <glib-object.h>
   90.35 -
   90.36 -#include "gmyth_stringlist.h"
   90.37 -#include "gmyth_backendinfo.h"
   90.38 -#include "gmyth_socket.h"
   90.39 -
   90.40 -G_BEGIN_DECLS
   90.41 -#define GMYTH_RECPROFILE_TYPE               (gmyth_recprofile_get_type ())
   90.42 -#define GMYTH_RECPROFILE(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_RECPROFILE_TYPE, GMythRecProfile))
   90.43 -#define GMYTH_RECPROFILE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_RECPROFILE_TYPE, GMythRecProfileClass))
   90.44 -#define IS_GMYTH_RECPROFILE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_RECPROFILE_TYPE))
   90.45 -#define IS_GMYTH_RECPROFILE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_RECPROFILE_TYPE))
   90.46 -#define GMYTH_RECPROFILE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_RECPROFILE_TYPE, GMythRecProfileClass))
   90.47 -typedef struct _Options Options;
   90.48 -typedef struct _GMythRecProfile GMythRecProfile;
   90.49 -typedef struct _GMythRecProfileClass GMythRecProfileClass;
   90.50 -
   90.51 -struct _GMythRecProfileClass {
   90.52 -    GObjectClass    parent_class;
   90.53 -    gint            teste;
   90.54 -    /*
   90.55 -     * callbacks 
   90.56 -     */
   90.57 -};
   90.58 -
   90.59 -struct _GMythRecProfile {
   90.60 -    gint            id;
   90.61 -    gchar          *name;
   90.62 -    gchar          *group;
   90.63 -    gchar          *vcodec;
   90.64 -    gchar          *acodec;
   90.65 -    Options        *options;
   90.66 -};
   90.67 -
   90.68 -struct _Options {
   90.69 -    gint            transcodelossless;
   90.70 -    gint            transcoderesize;
   90.71 -    gint            width;
   90.72 -    gint            height;
   90.73 -    gint            rtjpegquality;
   90.74 -    gint            rtjpeglumafilter;
   90.75 -    gint            rtjpegchromafilter;
   90.76 -    gint            mpeg4bitrate;
   90.77 -    gint            mpeg4maxquality;
   90.78 -    gint            mpeg4minquality;
   90.79 -    gint            mpeg4qualdiff;
   90.80 -    gint            mpeg4scalebitrate;
   90.81 -    gint            mpeg4optionvhq;
   90.82 -    gint            mpeg4option4mv;
   90.83 -    gint            mpeg4optionidct;
   90.84 -    gint            mpeg4optionime;
   90.85 -    gint            hardwaremjpegquality;
   90.86 -    gint            hardwaremjpeghdecimation;
   90.87 -    gint            hardwaremjpegvdecimation;
   90.88 -    gchar          *mpeg2streamtype;
   90.89 -    gchar          *mpeg2aspectratio;
   90.90 -    gint            mpeg2bitrate;
   90.91 -    gint            mpeg2maxbitrate;
   90.92 -    gint            samplerate;
   90.93 -    gint            mp3quality;
   90.94 -    gint            volume;
   90.95 -    gchar          *mpeg2audtype;
   90.96 -    gint            mpeg2audbitratel1;
   90.97 -    gint            mpeg2audbitratel2;
   90.98 -    gint            mpeg2audvolume;
   90.99 -};
  90.100 -
  90.101 -GType           gmyth_recprofile_type(void);
  90.102 -
  90.103 -GMythRecProfile *gmyth_recprofile_new(void);
  90.104 -
  90.105 -GSList         *gmyth_recprofile_get_profile_list(GMythBackendInfo *
  90.106 -                                                  backend_info);
  90.107 -
  90.108 -gint            gmyth_recprofile_create_profile(GMythBackendInfo *
  90.109 -                                                backend_info,
  90.110 -                                                GMythRecProfile * profile);
  90.111 -
  90.112 -gint            gmyth_recprofile_del_profile_list(GMythBackendInfo *
  90.113 -                                                  backend_info, gint id);
  90.114 -
  90.115 -gint            gmyth_recprofile_set_acodec(GMythRecProfile * rec,
  90.116 -                                            gchar * acodec);
  90.117 -gint            gmyth_recprofile_set_vcodec(GMythRecProfile * rec,
  90.118 -                                            gchar * vcodec);
  90.119 -gint            gmyth_recprofile_set_group(GMythRecProfile * rec,
  90.120 -                                           gchar * group);
  90.121 -gint            gmyth_recprofile_set_name(GMythRecProfile * rec,
  90.122 -                                          gchar * name);
  90.123 -gint            gmyth_recprofile_set_id(GMythRecProfile * rec, gint id);
  90.124 -
  90.125 -G_END_DECLS
  90.126 -#endif /*_GMYTH_RECPROFILE_H*/
    91.1 --- a/gmyth/src/gmyth_remote_util.c	Mon Feb 25 17:45:36 2008 +0000
    91.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.3 @@ -1,126 +0,0 @@
    91.4 -/**
    91.5 - * GMyth Library
    91.6 - *
    91.7 - * @file gmyth/gmyth_remote_util.c
    91.8 - * 
    91.9 - * @brief <p> This component provides utility functions for accessing remote data.
   91.10 - *
   91.11 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   91.12 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   91.13 - * @author Rosfran Borges <rosfran.borges@indt.org.br>
   91.14 - *
   91.15 - * 
   91.16 - * This program is free software; you can redistribute it and/or modify
   91.17 - * it under the terms of the GNU Lesser General Public License as published by
   91.18 - * the Free Software Foundation; either version 2 of the License, or
   91.19 - * (at your option) any later version.
   91.20 - *
   91.21 - * This program is distributed in the hope that it will be useful,
   91.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   91.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   91.24 - * GNU General Public License for more details.
   91.25 - *
   91.26 - * You should have received a copy of the GNU Lesser General Public License
   91.27 - * along with this program; if not, write to the Free Software
   91.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   91.29 - */
   91.30 -
   91.31 -#ifdef HAVE_CONFIG_H
   91.32 -#include "config.h"
   91.33 -#endif
   91.34 -
   91.35 -#include "gmyth_remote_util.h"
   91.36 -
   91.37 -#include "gmyth_recorder.h"
   91.38 -#include "gmyth_stringlist.h"
   91.39 -#include "gmyth_debug.h"
   91.40 -
   91.41 -/** 
   91.42 - * Requests the Mythtv backend for a free remote recorder.
   91.43 - * 
   91.44 - * @param socket The socket instance where to send the command.
   91.45 - * @param curr The recorder index, or -1 to consider the first one.
   91.46 - * 
   91.47 - * @return the remote encoder instance available, or NULL if any error happens.
   91.48 - */
   91.49 -GMythRecorder  *
   91.50 -remote_request_next_free_recorder(GMythSocket * socket, gint curr)
   91.51 -{
   91.52 -    GMythRecorder  *recorder = NULL;
   91.53 -    GString        *hostname;
   91.54 -    gint            num,
   91.55 -                    port;
   91.56 -
   91.57 -    GMythStringList *strlist = gmyth_string_list_new();
   91.58 -
   91.59 -    gmyth_debug("[%s] Request next free recorder in the backend",
   91.60 -                __FUNCTION__);
   91.61 -
   91.62 -    gmyth_string_list_append_char_array(strlist, "GET_NEXT_FREE_RECORDER");
   91.63 -    gmyth_string_list_append_int(strlist, curr);
   91.64 -
   91.65 -    if (!gmyth_socket_sendreceive_stringlist(socket, strlist)) {
   91.66 -        g_warning("GET_NEXT_FREE_RECORDER request error!\n");
   91.67 -        return NULL;
   91.68 -    }
   91.69 -
   91.70 -    num = gmyth_string_list_get_int(strlist, 0);
   91.71 -    hostname = gmyth_string_list_get_string(strlist, 1);
   91.72 -    port = gmyth_string_list_get_int(strlist, 2);
   91.73 -
   91.74 -    if (num < 0 || port < 0)
   91.75 -        goto clean_up;
   91.76 -
   91.77 -    gmyth_debug
   91.78 -        ("[%s] Free recorder info received: num: %d, hostname: %s, port: %d",
   91.79 -         __FUNCTION__, num, hostname->str, port);
   91.80 -
   91.81 -    recorder = gmyth_recorder_new(num, hostname, port);
   91.82 -
   91.83 -  clean_up:
   91.84 -
   91.85 -    g_string_free(hostname, TRUE);
   91.86 -    g_object_unref(strlist);
   91.87 -
   91.88 -    return recorder;
   91.89 -}
   91.90 -
   91.91 -/** 
   91.92 - * Requests the Mythtv backend for the number of free remote recorders.
   91.93 - * 
   91.94 - * @param socket The socket instance where to send the command.
   91.95 - * 
   91.96 - * @return the number of remote encoders instance available, or 0 if no one is actually free..
   91.97 - */
   91.98 -gint
   91.99 -gmyth_remote_util_get_free_recorder_count(GMythSocket * socket)
  91.100 -{
  91.101 -    gint            num_recs = 0;
  91.102 -
  91.103 -    GMythStringList *strlist = gmyth_string_list_new();
  91.104 -
  91.105 -    gmyth_debug("[%s] Request next free recorder in the backend",
  91.106 -                __FUNCTION__);
  91.107 -
  91.108 -    gmyth_string_list_append_char_array(strlist,
  91.109 -                                        "GET_FREE_RECORDER_COUNT");
  91.110 -
  91.111 -    if (!gmyth_socket_sendreceive_stringlist(socket, strlist)) {
  91.112 -        gmyth_debug("GET_FREE_RECORDER_COUNT request error!");
  91.113 -        return 0;
  91.114 -    }
  91.115 -
  91.116 -    num_recs = gmyth_string_list_get_int(strlist, 0);
  91.117 -
  91.118 -    if (num_recs < 0)
  91.119 -        goto clean_up;
  91.120 -
  91.121 -    gmyth_debug("[%s] Free recorder info received: num recorders: %d",
  91.122 -                __FUNCTION__, num_recs);
  91.123 -
  91.124 -  clean_up:
  91.125 -
  91.126 -    g_object_unref(strlist);
  91.127 -
  91.128 -    return num_recs;
  91.129 -}
    92.1 --- a/gmyth/src/gmyth_remote_util.h	Mon Feb 25 17:45:36 2008 +0000
    92.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.3 @@ -1,41 +0,0 @@
    92.4 -/**
    92.5 - * GMyth Library
    92.6 - *
    92.7 - * @file gmyth/gmyth_remote_util.h
    92.8 - * 
    92.9 - * @brief <p> This component provides utility functions for accessing remote data.
   92.10 - *
   92.11 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   92.12 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   92.13 - *
   92.14 - * 
   92.15 - * This program is free software; you can redistribute it and/or modify
   92.16 - * it under the terms of the GNU Lesser General Public License as published by
   92.17 - * the Free Software Foundation; either version 2 of the License, or
   92.18 - * (at your option) any later version.
   92.19 - *
   92.20 - * This program is distributed in the hope that it will be useful,
   92.21 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   92.22 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   92.23 - * GNU General Public License for more details.
   92.24 - *
   92.25 - * You should have received a copy of the GNU Lesser General Public License
   92.26 - * along with this program; if not, write to the Free Software
   92.27 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   92.28 - */
   92.29 -
   92.30 -#ifndef __REMOTE_UTIL_H__
   92.31 -#define __REMOTE_UTIL_H__
   92.32 -
   92.33 -#include <glib.h>
   92.34 -#include "gmyth_recorder.h"
   92.35 -#include "gmyth_socket.h"
   92.36 -
   92.37 -G_BEGIN_DECLS
   92.38 -    GMythRecorder * remote_request_next_free_recorder(GMythSocket * socket,
   92.39 -                                                      gint curr);
   92.40 -gint            gmyth_remote_util_get_free_recorder_count(GMythSocket *
   92.41 -                                                          socket);
   92.42 -
   92.43 -G_END_DECLS
   92.44 -#endif
    93.1 --- a/gmyth/src/gmyth_scheduler.c	Mon Feb 25 17:45:36 2008 +0000
    93.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.3 @@ -1,1266 +0,0 @@
    93.4 -/**
    93.5 - * GMyth Library
    93.6 - *
    93.7 - * @file gmyth/gmyth_scheduler.c
    93.8 - *
    93.9 - * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
   93.10 - * and modifying the recorded content.
   93.11 - *
   93.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   93.13 - * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
   93.14 - *
   93.15 - *
   93.16 - * This program is free software; you can redistribute it and/or modify
   93.17 - * it under the terms of the GNU Lesser General Public License as published by
   93.18 - * the Free Software Foundation; either version 2 of the License, or
   93.19 - * (at your option) any later version.
   93.20 - *
   93.21 - * This program is distributed in the hope that it will be useful,
   93.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   93.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   93.24 - * GNU General Public License for more details.
   93.25 - *
   93.26 - * You should have received a copy of the GNU Lesser General Public License
   93.27 - * along with this program; if not, write to the Free Software
   93.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   93.29 - */
   93.30 -
   93.31 -#ifdef HAVE_CONFIG_H
   93.32 -#include "config.h"
   93.33 -#endif
   93.34 -
   93.35 -#include <assert.h>
   93.36 -
   93.37 -#include <glib.h>
   93.38 -#include <glib/gprintf.h>
   93.39 -
   93.40 -#include "gmyth_scheduler.h"
   93.41 -#include "gmyth_util.h"
   93.42 -#include "gmyth_query.h"
   93.43 -#include "gmyth_socket.h"
   93.44 -#include "gmyth_debug.h"
   93.45 -
   93.46 -static void     gmyth_scheduler_class_init(GMythSchedulerClass * klass);
   93.47 -static void     gmyth_scheduler_init(GMythScheduler * object);
   93.48 -
   93.49 -static void     gmyth_scheduler_dispose(GObject * object);
   93.50 -static void     gmyth_scheduler_finalize(GObject * object);
   93.51 -
   93.52 -static gboolean update_backend(GMythScheduler * scheduler, gint record_id);
   93.53 -
   93.54 -G_DEFINE_TYPE(GMythScheduler, gmyth_scheduler, G_TYPE_OBJECT)
   93.55 -    static void     gmyth_scheduler_class_init(GMythSchedulerClass * klass)
   93.56 -{
   93.57 -    GObjectClass   *gobject_class;
   93.58 -
   93.59 -    gobject_class = (GObjectClass *) klass;
   93.60 -
   93.61 -    gobject_class->dispose = gmyth_scheduler_dispose;
   93.62 -    gobject_class->finalize = gmyth_scheduler_finalize;
   93.63 -}
   93.64 -
   93.65 -static void
   93.66 -gmyth_scheduler_init(GMythScheduler * sched)
   93.67 -{
   93.68 -    sched->recordid = 0;
   93.69 -    sched->type = 0;
   93.70 -    sched->search = 0;
   93.71 -    sched->profile = g_string_new("");
   93.72 -
   93.73 -    sched->dupin = 0;
   93.74 -    sched->dupmethod = 0;
   93.75 -    sched->autoexpire = 0;
   93.76 -    sched->autotranscode = 0;
   93.77 -    sched->transcoder = 0;
   93.78 -
   93.79 -    sched->autocommflag = 0;
   93.80 -    sched->autouserjob1 = 0;
   93.81 -    sched->autouserjob2 = 0;
   93.82 -    sched->autouserjob3 = 0;
   93.83 -    sched->autouserjob4 = 0;
   93.84 -
   93.85 -    sched->startoffset = 0;
   93.86 -    sched->endoffset = 0;
   93.87 -    sched->maxepisodes = 0;
   93.88 -    sched->maxnewest = 0;
   93.89 -
   93.90 -    sched->recpriority = 0;
   93.91 -    sched->recgroup = g_string_new("");
   93.92 -    sched->playgroup = g_string_new("");
   93.93 -
   93.94 -    sched->prefinput = 0;
   93.95 -    sched->inactive = 0;
   93.96 -
   93.97 -    sched->search_type = g_string_new("");
   93.98 -    sched->search_what = g_string_new("");
   93.99 -
  93.100 -    sched->msqlquery = gmyth_query_new();
  93.101 -}
  93.102 -
  93.103 -static void
  93.104 -gmyth_scheduler_dispose(GObject * object)
  93.105 -{
  93.106 -    GMythScheduler *scheduler = GMYTH_SCHEDULER(object);
  93.107 -
  93.108 -    if (scheduler->backend_info) {
  93.109 -        g_object_unref(scheduler->backend_info);
  93.110 -        scheduler->backend_info = NULL;
  93.111 -    }
  93.112 -
  93.113 -    if (scheduler->msqlquery) {
  93.114 -        g_object_unref(scheduler->msqlquery);
  93.115 -        scheduler->msqlquery = NULL;
  93.116 -    }
  93.117 -
  93.118 -    g_string_free(scheduler->profile, TRUE);
  93.119 -    g_string_free(scheduler->recgroup, TRUE);
  93.120 -    g_string_free(scheduler->playgroup, TRUE);
  93.121 -    g_string_free(scheduler->search_type, TRUE);
  93.122 -    g_string_free(scheduler->search_what, TRUE);
  93.123 -
  93.124 -    G_OBJECT_CLASS(gmyth_scheduler_parent_class)->dispose(object);
  93.125 -}
  93.126 -
  93.127 -static void
  93.128 -gmyth_scheduler_finalize(GObject * object)
  93.129 -{
  93.130 -    g_signal_handlers_destroy(object);
  93.131 -
  93.132 -    G_OBJECT_CLASS(gmyth_scheduler_parent_class)->finalize(object);
  93.133 -}
  93.134 -
  93.135 -/** Creates a new instance of GMythScheduler.
  93.136 - * 
  93.137 - * @return a new instance of GMythScheduler.
  93.138 - */
  93.139 -GMythScheduler *
  93.140 -gmyth_scheduler_new()
  93.141 -{
  93.142 -    GMythScheduler *scheduler =
  93.143 -        GMYTH_SCHEDULER(g_object_new(GMYTH_SCHEDULER_TYPE, NULL));
  93.144 -
  93.145 -    return scheduler;
  93.146 -}
  93.147 -
  93.148 -gboolean
  93.149 -gmyth_scheduler_connect(GMythScheduler * scheduler,
  93.150 -                        GMythBackendInfo * backend_info)
  93.151 -{
  93.152 -    return gmyth_scheduler_connect_with_timeout(scheduler, backend_info,
  93.153 -                                                0);
  93.154 -}
  93.155 -
  93.156 -/** Connects to the Mysql database in the backend. The backend address
  93.157 - * is loaded from the GMythSettings instance.
  93.158 - *
  93.159 - * @param scheduler the GMythScheduler instance to be connected.
  93.160 - * @return true if connection was success, false if failed.
  93.161 - */
  93.162 -gboolean
  93.163 -gmyth_scheduler_connect_with_timeout(GMythScheduler * scheduler,
  93.164 -                                     GMythBackendInfo * backend_info,
  93.165 -                                     guint timeout)
  93.166 -{
  93.167 -    assert(scheduler);
  93.168 -    g_return_val_if_fail(backend_info != NULL, FALSE);
  93.169 -
  93.170 -    if (scheduler->backend_info)
  93.171 -        g_object_unref(scheduler->backend_info);
  93.172 -
  93.173 -    scheduler->backend_info = g_object_ref(backend_info);
  93.174 -
  93.175 -    if (scheduler->msqlquery == NULL) {
  93.176 -        g_warning("[%s] GMythScheduler db initializing", __FUNCTION__);
  93.177 -        scheduler->msqlquery = gmyth_query_new();
  93.178 -    }
  93.179 -
  93.180 -    if (!gmyth_query_connect_with_timeout(scheduler->msqlquery,
  93.181 -                                          scheduler->backend_info,
  93.182 -                                          timeout)) {
  93.183 -        g_warning("[%s] Error while connecting to db", __FUNCTION__);
  93.184 -        return FALSE;
  93.185 -    }
  93.186 -
  93.187 -    return TRUE;
  93.188 -}
  93.189 -
  93.190 -/** Disconnects from the Mysql database in the backend.
  93.191 - *
  93.192 - * @param scheduler the GMythScheduler instance to be disconnected
  93.193 - * @return true if disconnection was success, false if failed.
  93.194 - */
  93.195 -gboolean
  93.196 -gmyth_scheduler_disconnect(GMythScheduler * scheduler)
  93.197 -{
  93.198 -    assert(scheduler);
  93.199 -
  93.200 -    if (scheduler->msqlquery != NULL) {
  93.201 -        gmyth_query_disconnect(scheduler->msqlquery);
  93.202 -    }
  93.203 -
  93.204 -    return TRUE;
  93.205 -}
  93.206 -
  93.207 -/** Retrieves from the backend Mysql database the list of recording schedules.
  93.208 - * 
  93.209 - * @param scheduler The GMythScheduler instance.
  93.210 - * @param schedule_list the GList pointer to be filled with the loaded list of ScheduleInfo items.
  93.211 - * @return The amount of schedules retrieved from database, or -1 if error.
  93.212 - */
  93.213 -gint
  93.214 -gmyth_scheduler_get_schedule_list(GMythScheduler * scheduler,
  93.215 -                                  GList ** schedule_list)
  93.216 -{
  93.217 -    ScheduleInfo   *schedule;
  93.218 -    MYSQL_RES      *msql_res;
  93.219 -    GString        *query_str = g_string_new("");
  93.220 -    gchar          *date_time = NULL;
  93.221 -
  93.222 -    assert(scheduler);
  93.223 -
  93.224 -    g_string_printf(query_str,
  93.225 -                    "SELECT recordid,programid,chanid,starttime,startdate,"
  93.226 -                    "endtime,enddate,title,subtitle,description,category,type,parentid,seriesid FROM record;");
  93.227 -
  93.228 -    if (scheduler->msqlquery == NULL) {
  93.229 -        g_warning("[%s] Scheduler db connection not initialized",
  93.230 -                  __FUNCTION__);
  93.231 -        return -1;
  93.232 -    }
  93.233 -    msql_res =
  93.234 -        gmyth_query_process_statement(scheduler->msqlquery,
  93.235 -                                      query_str->str);
  93.236 -
  93.237 -    if (msql_res == NULL) {
  93.238 -        g_warning("DB retrieval of schedule list failed");
  93.239 -        return -1;
  93.240 -    } else {
  93.241 -        MYSQL_ROW       row;
  93.242 -
  93.243 -        *schedule_list = NULL;
  93.244 -
  93.245 -        while ((row = mysql_fetch_row(msql_res)) != NULL) {
  93.246 -            schedule = g_new0(ScheduleInfo, 1);
  93.247 -            gint type = 0;
  93.248 -
  93.249 -            schedule->schedule_id =
  93.250 -                (guint) g_ascii_strtoull(row[0], NULL, 10);
  93.251 -            schedule->program_id = g_string_new (row[1]);
  93.252 -            schedule->channel_id = (gint) g_ascii_strtoull (row[2], NULL, 10);
  93.253 -
  93.254 -            /*
  93.255 -             * generate a time_t from a time and a date db field 
  93.256 -             */
  93.257 -            date_time = g_strdup_printf("%sT%s", row[4], row[3]);
  93.258 -            schedule->start_time =
  93.259 -                gmyth_util_string_to_time_val(date_time);
  93.260 -            g_free(date_time);
  93.261 -
  93.262 -            /*
  93.263 -             * generate a time_t from a time and a date db field 
  93.264 -             */
  93.265 -            date_time = g_strdup_printf("%sT%s", row[6], row[5]);
  93.266 -            schedule->end_time = gmyth_util_string_to_time_val(date_time);
  93.267 -            g_free(date_time);
  93.268 -
  93.269 -            schedule->title = g_string_new(row[7]);
  93.270 -            schedule->subtitle = g_string_new(row[8]);
  93.271 -            schedule->description = g_string_new(row[9]);
  93.272 -            schedule->category = g_string_new(row[10]);
  93.273 -            type = g_ascii_strtoull (row[11], NULL, 10);
  93.274 -            if (type == 4) {
  93.275 -                schedule->type = GMYTH_SCHEDULE_ALL_OCCURRENCES;
  93.276 -            } else if (type == 1) {
  93.277 -                schedule->type = GMYTH_SCHEDULE_ONE_OCCURRENCE;
  93.278 -            } else if (type == 8) {
  93.279 -                schedule->type = GMYTH_SCHEDULE_EXCEPTION;
  93.280 -                schedule->parentid = (gint) g_ascii_strtoull (row[12], NULL, 10);
  93.281 -            }
  93.282 -
  93.283 -            schedule->seriesid = g_string_new (row[13]);
  93.284 -
  93.285 -            (*schedule_list) = g_list_append(*(schedule_list), schedule);
  93.286 -        }
  93.287 -    }
  93.288 -
  93.289 -    mysql_free_result(msql_res);
  93.290 -    g_string_free(query_str, TRUE);
  93.291 -
  93.292 -    return (*schedule_list == NULL) ? 0 : g_list_length(*schedule_list);
  93.293 -}
  93.294 -
  93.295 -/** Retrieves from the backend Mysql database the list of recorded programs.
  93.296 - * 
  93.297 - * @param scheduler The GMythScheduler instance.
  93.298 - * @param recorded_list the GList pointer to be filled with the loaded RecordInfo items.
  93.299 - * @return The amount of recorded retrieved from database, or -1 if error.
  93.300 - */
  93.301 -gint
  93.302 -gmyth_scheduler_get_recorded_list(GMythScheduler * scheduler,
  93.303 -                                  GList ** recorded_list)
  93.304 -{
  93.305 -    RecordedInfo   *record;
  93.306 -    MYSQL_RES      *msql_res;
  93.307 -    GString        *query_str = g_string_new("");
  93.308 -
  93.309 -    assert(scheduler);
  93.310 -
  93.311 -    g_string_printf(query_str,
  93.312 -                    "SELECT recordid,programid,chanid,starttime,progstart,"
  93.313 -                    "endtime,progend,title,subtitle,description,category,"
  93.314 -                    "filesize,basename,seriesid FROM recorded WHERE recgroup != 'LiveTV'");
  93.315 -
  93.316 -    if (scheduler->msqlquery == NULL) {
  93.317 -        g_warning("[%s] Scheduler db connection not initialized",
  93.318 -                  __FUNCTION__);
  93.319 -        return -1;
  93.320 -    }
  93.321 -
  93.322 -    msql_res =
  93.323 -        gmyth_query_process_statement(scheduler->msqlquery,
  93.324 -                                      query_str->str);
  93.325 -
  93.326 -    if (msql_res == NULL) {
  93.327 -        g_warning("DB retrieval of recording list failed");
  93.328 -        return -1;
  93.329 -    } else {
  93.330 -        MYSQL_ROW       row;
  93.331 -
  93.332 -        (*recorded_list) = NULL;
  93.333 -
  93.334 -        while ((row = mysql_fetch_row(msql_res)) != NULL) {
  93.335 -            record = g_new0(RecordedInfo, 1);
  93.336 -
  93.337 -            record->record_id = (guint) g_ascii_strtoull(row[0], NULL, 10);
  93.338 -            record->program_id = g_string_new (row[1]);
  93.339 -            record->channel_id = (gint) g_ascii_strtoull(row[2], NULL, 10);
  93.340 -            record->start_time = gmyth_util_string_to_time_val(row[3]);
  93.341 -            record->end_time = gmyth_util_string_to_time_val(row[5]);
  93.342 -
  93.343 -            record->title = g_string_new(row[7]);
  93.344 -            record->subtitle = g_string_new(row[8]);
  93.345 -            record->description = g_string_new(row[9]);
  93.346 -            record->category = g_string_new(row[10]);
  93.347 -            record->filesize = g_ascii_strtoull(row[11], NULL, 10);
  93.348 -            record->basename = g_string_new(row[12]);
  93.349 -            record->seriesid = g_string_new(row[13]);
  93.350 -
  93.351 -            (*recorded_list) = g_list_append((*recorded_list), record);
  93.352 -        }
  93.353 -    }
  93.354 -
  93.355 -    mysql_free_result(msql_res);
  93.356 -    g_string_free(query_str, TRUE);
  93.357 -
  93.358 -    return (*recorded_list == NULL) ? 0 : g_list_length(*recorded_list);
  93.359 -}
  93.360 -
  93.361 -RecordedInfo*
  93.362 -gmyth_scheduler_get_recorded_info (GMythScheduler *scheduler,
  93.363 -                                   const gchar* basename)
  93.364 -{
  93.365 -    RecordedInfo   *record = NULL;
  93.366 -    MYSQL_RES      *msql_res;
  93.367 -    GString        *query_str = g_string_new("");
  93.368 -
  93.369 -    assert(scheduler);
  93.370 -
  93.371 -    g_string_printf(query_str,
  93.372 -                    "SELECT recordid,programid,chanid,starttime,progstart,"
  93.373 -                    "endtime,progend,title,subtitle,description,category,"
  93.374 -                    "filesize,basename,seriesid FROM recorded "
  93.375 -                    "WHERE recgroup != 'LiveTV' AND basename = '%s'", basename);
  93.376 -
  93.377 -    if (scheduler->msqlquery == NULL) {
  93.378 -        g_warning("[%s] Scheduler db connection not initialized", 
  93.379 -                        __FUNCTION__);
  93.380 -        return NULL;
  93.381 -    }
  93.382 -
  93.383 -    msql_res =
  93.384 -        gmyth_query_process_statement(scheduler->msqlquery,
  93.385 -                                      query_str->str);
  93.386 -
  93.387 -    if (msql_res == NULL) {
  93.388 -        g_warning("DB retrieval of recording list failed");
  93.389 -        return NULL;
  93.390 -    } else {
  93.391 -        MYSQL_ROW       row;
  93.392 -        row = mysql_fetch_row(msql_res);
  93.393 -        if (row != NULL) {
  93.394 -            record = g_new0(RecordedInfo, 1);
  93.395 -            record->record_id = (guint) g_ascii_strtoull(row[0], NULL, 10);
  93.396 -            record->program_id = g_string_new (row[1]);
  93.397 -            record->channel_id = (gint) g_ascii_strtoull(row[2], NULL, 10);
  93.398 -            record->start_time = gmyth_util_string_to_time_val(row[3]);
  93.399 -            record->end_time = gmyth_util_string_to_time_val(row[5]);
  93.400 -            record->title = g_string_new(row[7]);
  93.401 -            record->subtitle = g_string_new(row[8]);
  93.402 -            record->description = g_string_new(row[9]);
  93.403 -            record->category = g_string_new(row[10]);
  93.404 -            record->filesize = g_ascii_strtoull(row[11], NULL, 10);
  93.405 -            record->basename = g_string_new(row[12]);
  93.406 -            record->seriesid = g_string_new(row[13]);
  93.407 -        }
  93.408 -    }
  93.409 -
  93.410 -    mysql_free_result(msql_res);
  93.411 -    g_string_free(query_str, TRUE);
  93.412 -
  93.413 -    return record;
  93.414 -}
  93.415 -
  93.416 -
  93.417 -static void
  93.418 -_set_value(GMythQuery * myth_query, char *field, gchar * value,
  93.419 -           gint rec_id)
  93.420 -{
  93.421 -    gchar          *query =
  93.422 -        g_strdup_printf
  93.423 -        ("UPDATE record SET recordid = %d, %s = \"%s\" WHERE recordid = %d;",
  93.424 -         rec_id, field, value, rec_id);
  93.425 -
  93.426 -    gmyth_query_process_statement(myth_query, query);
  93.427 -    g_free(query);
  93.428 -}
  93.429 -
  93.430 -static void
  93.431 -_set_int_value(GMythQuery * myth_query, char *field, gint value,
  93.432 -               gint rec_id)
  93.433 -{
  93.434 -    gchar *str_value = g_strdup_printf("%d", value);
  93.435 -
  93.436 -    _set_value(myth_query, field, str_value, rec_id);
  93.437 -    g_free(str_value);
  93.438 -}
  93.439 -
  93.440 -ScheduleInfo*
  93.441 -gmyth_scheduler_add_schedule_program (GMythScheduler * scheduler,
  93.442 -                                      GMythProgramInfo *program,
  93.443 -                                      GMythScheduleType type)
  93.444 -{
  93.445 -    ScheduleInfo *info;
  93.446 -
  93.447 -    info = g_new0 (ScheduleInfo, 1);
  93.448 -    info->program_id = g_string_new (program->program_id->str);
  93.449 -    info->channel_id = program->channel_id;
  93.450 -    info->start_time = g_new0 (GTimeVal, 1);
  93.451 -    *info->start_time = *program->startts;
  93.452 -    info->end_time = g_new0 (GTimeVal, 1);
  93.453 -    *info->end_time = *program->endts;
  93.454 -    info->seriesid = g_string_new (program->seriesid->str);
  93.455 -    info->title = g_string_new (program->title->str);
  93.456 -    info->subtitle = g_string_new (program->subtitle->str);
  93.457 -    info->description = g_string_new (program->description->str);
  93.458 -    info->category = g_string_new (program->category->str);
  93.459 -    info->type = type;
  93.460 -
  93.461 -    if (gmyth_scheduler_add_schedule_full (scheduler, info, type))
  93.462 -    {
  93.463 -        if (!program->recstartts)
  93.464 -            program->recstartts = g_new0 (GTimeVal, 1);
  93.465 -        *program->recstartts = *info->start_time;
  93.466 -
  93.467 -        if (!program->recendts)
  93.468 -            program->recendts = g_new0 (GTimeVal, 1);
  93.469 -        *program->recendts = *info->end_time;
  93.470 -
  93.471 -        program->recordid = info->schedule_id;
  93.472 -        return info;
  93.473 -    }
  93.474 -
  93.475 -    gmyth_schedule_info_free (info);
  93.476 -    return NULL;
  93.477 -}
  93.478 -
  93.479 -
  93.480 -gboolean
  93.481 -gmyth_scheduler_add_schedule_full (GMythScheduler * scheduler,
  93.482 -                             ScheduleInfo * schedule_info, GMythScheduleType type)
  93.483 -{
  93.484 -    MYSQL_RES      *msql_res;
  93.485 -    gchar          *query_str = "INSERT record (recordid) VALUE (0);";
  93.486 -    gchar          *station = NULL;
  93.487 -    gulong          rec_id;
  93.488 -
  93.489 -    g_return_val_if_fail (IS_GMYTH_SCHEDULER (scheduler), FALSE);
  93.490 -
  93.491 -    if (scheduler->msqlquery == NULL) {
  93.492 -        g_warning("[%s] Scheduler db connection not initialized",
  93.493 -                  __FUNCTION__);
  93.494 -        return FALSE;
  93.495 -    }
  93.496 -
  93.497 -    msql_res =
  93.498 -        gmyth_query_process_statement_with_increment(scheduler->msqlquery,
  93.499 -                                                     query_str, &rec_id);
  93.500 -    mysql_free_result(msql_res);
  93.501 -
  93.502 -    // Retrieves the station info
  93.503 -    query_str =
  93.504 -        g_strdup_printf
  93.505 -        ("SELECT callsign FROM channel WHERE chanid = %d;",
  93.506 -         schedule_info->channel_id);
  93.507 -    msql_res =
  93.508 -        gmyth_query_process_statement(scheduler->msqlquery, query_str);
  93.509 -    if (msql_res == NULL) {
  93.510 -        g_warning("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
  93.511 -        return FALSE;
  93.512 -    } else {
  93.513 -        MYSQL_ROW       row;
  93.514 -
  93.515 -        if ((row = mysql_fetch_row(msql_res)) != NULL) {
  93.516 -            station = g_strdup(row[0]);
  93.517 -        }
  93.518 -    }
  93.519 -    mysql_free_result(msql_res);
  93.520 -    g_free(query_str);
  93.521 -
  93.522 -    // _set_value (field, value, id);
  93.523 -    _set_int_value(scheduler->msqlquery, "chanid",
  93.524 -                   schedule_info->channel_id, rec_id);
  93.525 -    _set_value(scheduler->msqlquery, "station", station, rec_id);
  93.526 -    _set_value(scheduler->msqlquery, "title", schedule_info->title->str,
  93.527 -               rec_id);
  93.528 -    // / subtitle, description 
  93.529 -    _set_value(scheduler->msqlquery, "starttime",
  93.530 -               gmyth_util_time_to_string_only_time(schedule_info->
  93.531 -                                                   start_time), rec_id);
  93.532 -    _set_value(scheduler->msqlquery, "startdate",
  93.533 -               gmyth_util_time_to_string_only_date(schedule_info->
  93.534 -                                                   start_time), rec_id);
  93.535 -    _set_value(scheduler->msqlquery, "endtime",
  93.536 -               gmyth_util_time_to_string_only_time(schedule_info->
  93.537 -                                                   end_time), rec_id);
  93.538 -    _set_value(scheduler->msqlquery, "enddate",
  93.539 -               gmyth_util_time_to_string_only_date(schedule_info->
  93.540 -                                                   end_time), rec_id);
  93.541 -    // / category, series id, program id
  93.542 -    // _set_value (scheduler->msqlquery, "findday",
  93.543 -    // (gmyth_util_time_val_to_date( schedule_info->start_time
  93.544 -    // ))->tm_wday, rec_id);
  93.545 -    // _set_value (scheduler->msqlquery, "findtime",
  93.546 -    // gmyth_util_time_to_string_only_time( schedule_info->start_time),
  93.547 -    // rec_id);
  93.548 -    // _set_int_value (scheduler->msqlquery, "findid",
  93.549 -    // (gint)(schedule_info->start_time->tv_sec/60/60/24 + 719528),
  93.550 -    // rec_id);
  93.551 -
  93.552 -    if (schedule_info->seriesid)
  93.553 -       _set_value(scheduler->msqlquery, "seriesid",
  93.554 -                  schedule_info->seriesid->str, rec_id);
  93.555 - 
  93.556 -    _set_value(scheduler->msqlquery, "parentid", "0", rec_id);
  93.557 -    _set_value(scheduler->msqlquery, "search", "0", rec_id);
  93.558 -
  93.559 -    if (type == GMYTH_SCHEDULE_ALL_OCCURRENCES) {
  93.560 -        _set_int_value(scheduler->msqlquery, "type", 3, rec_id);
  93.561 -    } else if (type == GMYTH_SCHEDULE_ONE_OCCURRENCE) {
  93.562 -        _set_int_value(scheduler->msqlquery, "type", 1, rec_id);
  93.563 -    } else if (type == GMYTH_SCHEDULE_EXCEPTION) {
  93.564 -        _set_int_value(scheduler->msqlquery, "type", 8, rec_id);
  93.565 -        _set_int_value(scheduler->msqlquery, "parentid", schedule_info->parentid,
  93.566 -		       rec_id);
  93.567 -    }
  93.568 -
  93.569 -    _set_value(scheduler->msqlquery, "recpriority", "0", rec_id);
  93.570 -    _set_value(scheduler->msqlquery, "startoffset", "0", rec_id);
  93.571 -    _set_value(scheduler->msqlquery, "endoffset", "0", rec_id);
  93.572 -    _set_value(scheduler->msqlquery, "dupmethod", "6", rec_id); // ?
  93.573 -    _set_value(scheduler->msqlquery, "dupin", "15", rec_id);    // ?
  93.574 -
  93.575 -    _set_value(scheduler->msqlquery, "prefinput", "0", rec_id);
  93.576 -    _set_value(scheduler->msqlquery, "inactive", "0", rec_id);
  93.577 -    _set_value(scheduler->msqlquery, "profile", "Default", rec_id);
  93.578 -    _set_value(scheduler->msqlquery, "recgroup", "Default", rec_id);
  93.579 -    _set_value(scheduler->msqlquery, "storagegroup", "Default", rec_id);
  93.580 -    _set_value(scheduler->msqlquery, "playgroup", "Default", rec_id);
  93.581 -    _set_value(scheduler->msqlquery, "autoexpire", "1", rec_id);
  93.582 -    _set_value(scheduler->msqlquery, "maxepisodes", "0", rec_id);
  93.583 -    _set_value(scheduler->msqlquery, "maxnewest", "0", rec_id);
  93.584 -    _set_value(scheduler->msqlquery, "autocommflag", "1", rec_id);
  93.585 -    _set_value(scheduler->msqlquery, "autotranscode", "0", rec_id);
  93.586 -    _set_value(scheduler->msqlquery, "transcoder", "0", rec_id);
  93.587 -
  93.588 -    _set_value(scheduler->msqlquery, "autouserjob1", "0", rec_id);
  93.589 -    _set_value(scheduler->msqlquery, "autouserjob2", "0", rec_id);
  93.590 -    _set_value(scheduler->msqlquery, "autouserjob3", "0", rec_id);
  93.591 -    _set_value(scheduler->msqlquery, "autouserjob4", "0", rec_id);
  93.592 -
  93.593 -    schedule_info->schedule_id = rec_id;
  93.594 -
  93.595 -    /* Notify the backend of changes */
  93.596 -    return update_backend(scheduler, rec_id);
  93.597 -}
  93.598 -
  93.599 -/** Requests the Mysql database in the backend to add a new schedule.
  93.600 - * 
  93.601 - * @param scheduler the GMythScheduler instance.
  93.602 - * @param schedule_info the ScheduleInfo with recording schedule information
  93.603 - * to be added. record_id = -1 to add a new schedule, otherwise this
  93.604 - * function will update the schedule in the db
  93.605 - * @return gboolean returns FALSE if some error occurs, TRUE otherwise
  93.606 - */
  93.607 -gboolean
  93.608 -gmyth_scheduler_add_schedule (GMythScheduler * scheduler,
  93.609 -                             ScheduleInfo * schedule_info)
  93.610 -{
  93.611 -    return gmyth_scheduler_add_schedule_full (scheduler, schedule_info, 
  93.612 -                                              GMYTH_SCHEDULE_ONE_OCCURRENCE);
  93.613 -}
  93.614 -
  93.615 -/** Requests the Mysql database in the backend to remove an existing schedule.
  93.616 - * 
  93.617 - * @param scheduler the GMythScheduler instance.
  93.618 - * @param schedule_id The schedule's record id to be removed
  93.619 - * @return gboolean TRUE if success, FALSE if error
  93.620 - */
  93.621 -gboolean
  93.622 -gmyth_scheduler_delete_schedule(GMythScheduler * scheduler, gint schedule_id)
  93.623 -{
  93.624 -
  93.625 -    MYSQL_RES      *msql_res;
  93.626 -    GString        *query_str = NULL;
  93.627 -
  93.628 -    g_return_val_if_fail (scheduler != NULL, FALSE);
  93.629 -
  93.630 -
  93.631 -    if (scheduler->msqlquery == NULL) {
  93.632 -        g_warning("[%s] Scheduler db connection not initialized",
  93.633 -                  __FUNCTION__);
  93.634 -        return FALSE;
  93.635 -    }
  93.636 -
  93.637 -    query_str = g_string_new("");
  93.638 -    g_string_printf(query_str,
  93.639 -                    "DELETE FROM record WHERE recordid=%d", schedule_id);
  93.640 -
  93.641 -    msql_res =
  93.642 -        gmyth_query_process_statement(scheduler->msqlquery,
  93.643 -                                      query_str->str);
  93.644 -
  93.645 -
  93.646 -    mysql_free_result(msql_res);
  93.647 -    g_string_free(query_str, TRUE);
  93.648 -
  93.649 -    // Notify the backend of the changes
  93.650 -    return update_backend(scheduler, schedule_id);
  93.651 -}
  93.652 -
  93.653 -/*
  93.654 - * Add an exception program to be removed from the schedule list, when programs
  93.655 - * where scheduled with the GMYTH_SCHEDULE_ALL_OCCURRENCES option.
  93.656 - * @param scheduler the GMythScheduler instance.
  93.657 - * @param schedule_id the schedule id of the all occurrence schedule to be changed
  93.658 - * @param exception_info the ScheduleInfo to be removed from all schedule occurrences
  93.659 - * @return TRUE if success, FALSE if any error happens
  93.660 - */
  93.661 -gboolean
  93.662 -gmyth_scheduler_add_exception (GMythScheduler *scheduler, gint schedule_id,
  93.663 -			       ScheduleInfo *exception_info)
  93.664 -{
  93.665 -    gboolean res;
  93.666 -
  93.667 -    g_return_val_if_fail (scheduler != NULL, FALSE);
  93.668 -    g_return_val_if_fail (exception_info != NULL, FALSE);
  93.669 -
  93.670 -    exception_info->parentid = schedule_id;
  93.671 -    res = gmyth_scheduler_add_schedule_full (scheduler, exception_info, GMYTH_SCHEDULE_EXCEPTION);
  93.672 -
  93.673 -    return res;
  93.674 -}
  93.675 -
  93.676 -/** Requests the Mysql database in the backend to remove an existing recorded item.
  93.677 - * 
  93.678 - * @param scheduler the GMythScheduler instance.
  93.679 - * @param record_id The recorded item id to be removed
  93.680 - * @return gboolean TRUE if success, FALSE if error
  93.681 - */
  93.682 -gboolean
  93.683 -gmyth_scheduler_delete_recorded(GMythScheduler * scheduler, gint record_id)
  93.684 -{
  93.685 -
  93.686 -    MYSQL_RES      *msql_res;
  93.687 -
  93.688 -    GString        *query_str = g_string_new("");
  93.689 -
  93.690 -    assert(scheduler);
  93.691 -
  93.692 -    if (scheduler->msqlquery == NULL) {
  93.693 -        g_warning("[%s] Scheduler db connection not initialized",
  93.694 -                  __FUNCTION__);
  93.695 -        return FALSE;
  93.696 -    }
  93.697 -    // ========================================
  93.698 -    g_string_printf(query_str,
  93.699 -                    "DELETE FROM recorded WHERE recordid=%d", record_id);
  93.700 -
  93.701 -    // FIXME: Mythtv implementation runs also: DELETE FROM oldfind WHERE
  93.702 -    // recordid = x
  93.703 -
  93.704 -    msql_res =
  93.705 -        gmyth_query_process_statement(scheduler->msqlquery,
  93.706 -                                      query_str->str);
  93.707 -
  93.708 -    mysql_free_result(msql_res);
  93.709 -    g_string_free(query_str, TRUE);
  93.710 -
  93.711 -    // Notify the backend of the changes
  93.712 -    return update_backend(scheduler, record_id);
  93.713 -}
  93.714 -
  93.715 -
  93.716 -gboolean gmyth_scheduler_was_recorded_before(GMythScheduler* scheduler, gint channel_id,
  93.717 -                                             time_t start_time)
  93.718 -{
  93.719 -    MYSQL_RES      *msql_res;
  93.720 -    GString        *query_str = g_string_new("");
  93.721 -
  93.722 -    assert(scheduler);
  93.723 -    g_string_printf(query_str, "SELECT callsign FROM channel "
  93.724 -                    "WHERE chanid = \"%d\"", channel_id);
  93.725 -
  93.726 -    msql_res = gmyth_query_process_statement(scheduler->msqlquery, query_str->str);
  93.727 -
  93.728 -    if (msql_res) {
  93.729 -        MYSQL_ROW msql_row = mysql_fetch_row(msql_res);
  93.730 -        if (msql_row) {
  93.731 -            GString* callsign = g_string_new(msql_row[0]);
  93.732 -            GString* startts = gmyth_util_time_to_string(start_time);
  93.733 -            g_string_printf(query_str, "SELECT * FROM oldrecorded "
  93.734 -                            "WHERE station = \"%s\" AND starttime = \"%s\"",
  93.735 -                            callsign->str, startts->str);
  93.736 -            msql_res = gmyth_query_process_statement(scheduler->msqlquery, query_str->str);
  93.737 -            g_string_free(callsign, TRUE);
  93.738 -            g_string_free(startts, TRUE);
  93.739 -            g_string_free(query_str, TRUE);
  93.740 -            if (mysql_fetch_row(msql_res)) return TRUE;
  93.741 -        }
  93.742 -    }
  93.743 -    return FALSE;
  93.744 -}
  93.745 -
  93.746 -
  93.747 -gboolean gmyth_scheduler_reactivate_schedule(GMythScheduler* scheduler, gint channel_id,
  93.748 -                                             time_t start_time)
  93.749 -
  93.750 -{
  93.751 -    MYSQL_RES      *msql_res;
  93.752 -    GString        *query_str = g_string_new("");
  93.753 -
  93.754 -    assert(scheduler);
  93.755 -    g_string_printf(query_str, "SELECT callsign FROM channel "
  93.756 -                    "WHERE chanid = \"%d\"", channel_id);
  93.757 -
  93.758 -    msql_res = gmyth_query_process_statement(scheduler->msqlquery, query_str->str);
  93.759 -    if (msql_res) {
  93.760 -        MYSQL_ROW msql_row = mysql_fetch_row(msql_res);
  93.761 -        if (msql_row) {
  93.762 -            GString* callsign = g_string_new(msql_row[0]);
  93.763 -            GString* startts = gmyth_util_time_to_string(start_time);
  93.764 -            g_string_printf(query_str, "UPDATE oldrecorded SET reactivate = 1 "
  93.765 -                            "WHERE station = \"%s\" AND starttime = \"%s\"",
  93.766 -                            callsign->str, startts->str);
  93.767 -            gmyth_query_process_statement(scheduler->msqlquery, query_str->str);
  93.768 -            g_string_free(callsign, TRUE);
  93.769 -            g_string_free(startts, TRUE);
  93.770 -            g_string_free(query_str, TRUE);
  93.771 -            return TRUE;
  93.772 -        }
  93.773 -
  93.774 -    }
  93.775 -
  93.776 -    return FALSE;
  93.777 -}
  93.778 -
  93.779 -
  93.780 -/*
  93.781 - * This should only be used in special situations. We do not know the time that
  93.782 - * the recording was set. We just know that it is an "ongoing" record and then
  93.783 - * we have to use this to get it's info. It's always the oldest one -> first on list
  93.784 - *
  93.785 - */
  93.786 -GMythProgramInfo*
  93.787 -gmyth_scheduler_get_recorded_on_time(GMythScheduler* scheduler,
  93.788 -                                     guint channel_id)
  93.789 -{
  93.790 -    MYSQL_RES      *msql_res;
  93.791 -    GMythProgramInfo *proginfo = NULL;
  93.792 -    GString        *query_str = g_string_new("");
  93.793 -
  93.794 -    assert(scheduler);
  93.795 -
  93.796 -    g_string_printf(query_str,
  93.797 -                    "SELECT recorded.chanid,starttime,endtime,title,"
  93.798 -                    "subtitle,description,channel.channum,"
  93.799 -                    "channel.callsign,channel.name,channel.commfree,"
  93.800 -                    "channel.outputfilters,seriesid,programid,filesize,"
  93.801 -                    "lastmodified,stars,previouslyshown,originalairdate,"
  93.802 -                    "hostname,recordid,transcoder,playgroup,"
  93.803 -                    "recorded.recpriority,progstart,progend,basename,recgroup,"
  93.804 -                    "category,findid,duplicate "
  93.805 -                    "FROM recorded " "LEFT JOIN channel "
  93.806 -                    "ON recorded.chanid = channel.chanid "
  93.807 -                    "WHERE recorded.chanid = %d "
  93.808 -                    "ORDER BY starttime DESC", channel_id);
  93.809 -
  93.810 -    msql_res =
  93.811 -        gmyth_query_process_statement(scheduler->msqlquery, query_str->str);
  93.812 -
  93.813 -    if (msql_res) {
  93.814 -        MYSQL_ROW msql_row = mysql_fetch_row(msql_res);
  93.815 -
  93.816 -        if (msql_row) {
  93.817 -            proginfo = gmyth_program_info_new();
  93.818 -
  93.819 -            proginfo->channel_id = (gint) g_ascii_strtoull (msql_row[0], NULL, 10);
  93.820 -            proginfo->recstartts = gmyth_util_string_to_time_val(msql_row[1]);
  93.821 -            proginfo->recendts = gmyth_util_string_to_time_val(msql_row[2]);
  93.822 -
  93.823 -            proginfo->title = g_string_new(msql_row[3]);
  93.824 -            proginfo->subtitle = g_string_new(msql_row[4]);
  93.825 -            proginfo->description = g_string_new(msql_row[5]);
  93.826 -
  93.827 -            proginfo->chanstr = g_string_new(msql_row[6]);
  93.828 -            proginfo->chansign = g_string_new(msql_row[7]);
  93.829 -            proginfo->channame = g_string_new(msql_row[8]);
  93.830 -            proginfo->chancommfree = (gint) g_ascii_strtoull(msql_row[9], NULL, 10);
  93.831 -            proginfo->chanOutputFilters = g_string_new(msql_row[10]);
  93.832 -            proginfo->seriesid = g_string_new(msql_row[11]);
  93.833 -            proginfo->program_id = g_string_new(msql_row[12]);
  93.834 -            proginfo->filesize = g_ascii_strtoull(msql_row[13], NULL, 10);
  93.835 -
  93.836 -            proginfo->lastmodified = gmyth_util_string_to_time_val(msql_row[14]);
  93.837 -            proginfo->stars = g_ascii_strtod(msql_row[15], NULL);
  93.838 -            proginfo->repeat = (gint)g_ascii_strtoull(msql_row[16], NULL, 10);
  93.839 -
  93.840 -            if (msql_row[17] == NULL) {
  93.841 -                proginfo->originalAirDate = 0;
  93.842 -                proginfo->hasAirDate = FALSE;
  93.843 -            } else {
  93.844 -                proginfo->originalAirDate = gmyth_util_string_to_time_val(msql_row[17]);
  93.845 -                proginfo->hasAirDate = TRUE;
  93.846 -            }
  93.847 -
  93.848 -            proginfo->hostname = g_string_new(msql_row[18]);
  93.849 -            proginfo->recordid = (gint) g_ascii_strtoull(msql_row[19], NULL, 10);
  93.850 -            proginfo->transcoder = (gint) g_ascii_strtoull(msql_row[20], NULL, 10);
  93.851 -
  93.852 -            proginfo->playgroup = g_string_new(msql_row[21]);
  93.853 -            proginfo->recpriority = (gint) g_ascii_strtoull(msql_row[22], NULL, 10);
  93.854 -
  93.855 -            proginfo->startts = gmyth_util_string_to_time_val(msql_row[23]);
  93.856 -            proginfo->endts = gmyth_util_string_to_time_val(msql_row[24]);
  93.857 -            proginfo->pathname = g_string_new(g_strdup(msql_row[25]));
  93.858 -            proginfo->recgroup = g_string_new(msql_row[26]);
  93.859 -            proginfo->category = g_string_new(msql_row[27]);
  93.860 -            proginfo->findid = (gint) g_ascii_strtoull(msql_row[28], NULL, 10);
  93.861 -
  93.862 -            proginfo->recpriority2 = 0;
  93.863 -
  93.864 -            g_string_printf(query_str,
  93.865 -                            "SELECT dupmethod,dupin,parentid,type "
  93.866 -                            "FROM record WHERE recordid = \"%d\"", proginfo->recordid);
  93.867 -
  93.868 -            msql_res =
  93.869 -                gmyth_query_process_statement(scheduler->msqlquery,
  93.870 -                                              query_str->str);
  93.871 -
  93.872 -            if (msql_res) {
  93.873 -                MYSQL_ROW msql_row = mysql_fetch_row(msql_res);
  93.874 -
  93.875 -                if (msql_row) {
  93.876 -                    proginfo->dupmethod = (gint) g_ascii_strtoull(msql_row[0], NULL, 10);
  93.877 -                    proginfo->dupin = (gint) g_ascii_strtoull(msql_row[1], NULL, 10);
  93.878 -                    proginfo->parentid = (gint) g_ascii_strtoull(msql_row[2], NULL, 10);
  93.879 -                    proginfo->rectype = 0;
  93.880 -                }
  93.881 -            }
  93.882 -
  93.883 -
  93.884 -            g_string_printf(query_str,
  93.885 -                            "SELECT sourceid,cardid,cardinputid,shareable "
  93.886 -                            "FROM cardinput");
  93.887 -
  93.888 -            msql_res =
  93.889 -                gmyth_query_process_statement(scheduler->msqlquery,
  93.890 -                                              query_str->str);
  93.891 -
  93.892 -            if (msql_res) {
  93.893 -                MYSQL_ROW msql_row = mysql_fetch_row(msql_res);
  93.894 -
  93.895 -                if (msql_row) {
  93.896 -                    proginfo->sourceid = 0;
  93.897 -                    proginfo->cardid = 0;
  93.898 -                    proginfo->inputid = 0;
  93.899 -                    if (msql_row[3] != NULL && g_ascii_strcasecmp("Y", msql_row[3]) == 0)
  93.900 -                        proginfo->shareable = 1;
  93.901 -                    else
  93.902 -                        proginfo->shareable = 0;
  93.903 -                }
  93.904 -            }
  93.905 -
  93.906 -
  93.907 -
  93.908 -        }
  93.909 -    }
  93.910 -
  93.911 -    g_string_free(query_str, TRUE);
  93.912 -    return proginfo;
  93.913 -}
  93.914 -
  93.915 -/** Retrieves an existing recorded item information from database. The information
  93.916 - * is used to fill the returned GMythProgramInfo.
  93.917 - * 
  93.918 - * @param scheduler The GMythScheduler instance.
  93.919 - * @param channel The channel associated to the record
  93.920 - * @param starttime The record start time
  93.921 - * @return A GMythProgramInfo struct with the requested record item
  93.922 - * information, or NULL if error.
  93.923 - */
  93.924 -GMythProgramInfo *
  93.925 -gmyth_scheduler_get_recorded(GMythScheduler * scheduler,
  93.926 -                             GString * channel, GTimeVal * starttime)
  93.927 -{
  93.928 -    MYSQL_RES      *msql_res;
  93.929 -    GMythProgramInfo *proginfo = NULL;
  93.930 -    GString        *query_str = g_string_new("");
  93.931 -    gchar          *time_str =
  93.932 -        gmyth_util_time_to_string_from_time_val(starttime);
  93.933 -
  93.934 -    assert(scheduler);
  93.935 -
  93.936 -    gmyth_debug("[%s] channel: %s", __FUNCTION__, channel->str);
  93.937 -
  93.938 -    if (scheduler->msqlquery == NULL) {
  93.939 -        g_warning("[%s] Scheduler db connection not initialized",
  93.940 -                  __FUNCTION__);
  93.941 -        return NULL;
  93.942 -    }
  93.943 -
  93.944 -    g_string_printf(query_str,
  93.945 -                    "SELECT recorded.chanid,starttime,endtime,title, "
  93.946 -                    "subtitle,description,channel.channum, "
  93.947 -                    "channel.callsign,channel.name,channel.commfree, "
  93.948 -                    "channel.outputfilters,seriesid,programid,filesize, "
  93.949 -                    "lastmodified,stars,previouslyshown,originalairdate, "
  93.950 -                    "hostname,recordid,transcoder,playgroup, "
  93.951 -                    "recorded.recpriority,progstart,progend,basename,recgroup "
  93.952 -                    "FROM recorded " "LEFT JOIN channel "
  93.953 -                    "ON recorded.chanid = channel.chanid "
  93.954 -                    "WHERE recorded.chanid = \"%s\" "
  93.955 -                    "AND starttime = \"%s\" ;", channel->str, time_str);
  93.956 -
  93.957 -    msql_res =
  93.958 -        gmyth_query_process_statement(scheduler->msqlquery,
  93.959 -                                      query_str->str);
  93.960 -
  93.961 -    if (msql_res /* && query.size() > 0 */ ) {
  93.962 -        MYSQL_ROW       msql_row = mysql_fetch_row(msql_res);
  93.963 -
  93.964 -        if (msql_row) {
  93.965 -            proginfo = gmyth_program_info_new();
  93.966 -
  93.967 -            proginfo->channel_id = (gint) g_ascii_strtoull (msql_row[0], NULL, 10);
  93.968 -            proginfo->startts =
  93.969 -                gmyth_util_string_to_time_val(msql_row[23]);
  93.970 -            proginfo->endts = gmyth_util_string_to_time_val(msql_row[24]);
  93.971 -            proginfo->recstartts =
  93.972 -                gmyth_util_string_to_time_val(msql_row[1]);
  93.973 -            proginfo->recendts =
  93.974 -                gmyth_util_string_to_time_val(msql_row[2]);
  93.975 -            proginfo->title = g_string_new(msql_row[3]);
  93.976 -            proginfo->subtitle = g_string_new(msql_row[4]);
  93.977 -            proginfo->description = g_string_new(msql_row[5]);
  93.978 -
  93.979 -            proginfo->chanstr = g_string_new(msql_row[6]);
  93.980 -            proginfo->chansign = g_string_new(msql_row[7]);
  93.981 -            proginfo->channame = g_string_new(msql_row[0]);
  93.982 -            proginfo->chancommfree =
  93.983 -                (gint) g_ascii_strtoull(msql_row[9], NULL, 10);
  93.984 -            proginfo->chanOutputFilters = g_string_new(msql_row[10]);
  93.985 -            proginfo->seriesid = g_string_new(msql_row[11]);
  93.986 -            proginfo->program_id = g_string_new(msql_row[12]);
  93.987 -            proginfo->filesize = g_ascii_strtoull(msql_row[13], NULL, 10);
  93.988 -
  93.989 -            proginfo->lastmodified =
  93.990 -                gmyth_util_string_to_time_val(msql_row[14]);
  93.991 -            proginfo->stars = g_ascii_strtod(msql_row[15], NULL);
  93.992 -            proginfo->repeat =
  93.993 -                (gint) g_ascii_strtoull(msql_row[16], NULL, 10);
  93.994 -
  93.995 -            if (msql_row[17] == NULL) {
  93.996 -                proginfo->originalAirDate = 0;
  93.997 -                proginfo->hasAirDate = FALSE;
  93.998 -            } else {
  93.999 -                proginfo->originalAirDate =
 93.1000 -                    gmyth_util_string_to_time_val(msql_row[17]);
 93.1001 -                proginfo->hasAirDate = TRUE;
 93.1002 -            }
 93.1003 -
 93.1004 -            proginfo->hostname = g_string_new(msql_row[18]);
 93.1005 -            proginfo->recordid =
 93.1006 -                (gint) g_ascii_strtoull(msql_row[19], NULL, 10);
 93.1007 -            proginfo->transcoder =
 93.1008 -                (gint) g_ascii_strtoull(msql_row[20], NULL, 10);
 93.1009 -            // proginfo->spread = -1;
 93.1010 -            // proginfo->programflags = proginfo->getProgramFlags();
 93.1011 -
 93.1012 -            proginfo->recgroup = g_string_new(msql_row[26]);
 93.1013 -            proginfo->playgroup = g_string_new(msql_row[21]);
 93.1014 -            proginfo->recpriority =
 93.1015 -                (gint) g_ascii_strtoull(msql_row[22], NULL, 10);
 93.1016 -
 93.1017 -            proginfo->pathname = g_string_new(g_strdup(msql_row[25]));
 93.1018 -
 93.1019 -            gmyth_debug("One program info loaded from mysql database\n");
 93.1020 -        }
 93.1021 -    }
 93.1022 -
 93.1023 -    mysql_free_result(msql_res);
 93.1024 -    g_string_free(query_str, TRUE);
 93.1025 -    g_free(time_str);
 93.1026 -
 93.1027 -    return proginfo;
 93.1028 -}
 93.1029 -
 93.1030 -gboolean
 93.1031 -gmyth_scheduler_stop_recording (GMythScheduler * scheduler,
 93.1032 -                                gint channel_id)
 93.1033 -{
 93.1034 -    GMythProgramInfo *program;
 93.1035 -    GMythSocket    *socket;
 93.1036 -    gboolean        res = FALSE;
 93.1037 -    GMythStringList *slist;
 93.1038 -
 93.1039 -    socket = gmyth_backend_info_get_connected_socket (scheduler->backend_info);
 93.1040 -    program = gmyth_scheduler_get_recorded_on_time (scheduler, channel_id);
 93.1041 -
 93.1042 -    if (program) {
 93.1043 -        slist = gmyth_string_list_new();
 93.1044 -        gmyth_string_list_append_char_array(slist, "STOP_RECORDING");
 93.1045 -
 93.1046 -        gmyth_string_list_append_string(slist, program->title);        /* 0 */
 93.1047 -        gmyth_string_list_append_string(slist, program->subtitle);     /* 1 */
 93.1048 -        gmyth_string_list_append_string(slist, program->description);  /* 2 */
 93.1049 -        gmyth_string_list_append_string(slist, program->category);     /* 3 */
 93.1050 -        gmyth_string_list_append_int(slist, program->channel_id);   /* 4 */
 93.1051 -        gmyth_string_list_append_string(slist, program->chanstr);      /* 5 */
 93.1052 -        gmyth_string_list_append_string(slist, program->chansign);     /* 6 */
 93.1053 -        gmyth_string_list_append_string(slist, program->channame);     /* 7 */
 93.1054 -        gmyth_string_list_append_string(slist, program->pathname);     /* 8 */
 93.1055 -        gmyth_string_list_append_int64(slist, program->filesize);      /* 9 */
 93.1056 -
 93.1057 -        if (program->startts)
 93.1058 -            gmyth_string_list_append_int(slist, program->startts->tv_sec); /* 10 */
 93.1059 -        else
 93.1060 -            gmyth_string_list_append_int(slist, 0);
 93.1061 -
 93.1062 -        if (program->endts)
 93.1063 -            gmyth_string_list_append_int(slist, program->endts->tv_sec);   /* 11 */
 93.1064 -        else
 93.1065 -            gmyth_string_list_append_int(slist, 0);
 93.1066 -
 93.1067 -        gmyth_string_list_append_int(slist, program->duplicate);   /* 12 */
 93.1068 -        gmyth_string_list_append_int(slist, program->shareable);   /* 13 */
 93.1069 -        gmyth_string_list_append_int(slist, program->findid);      /* 14 */
 93.1070 -        gmyth_string_list_append_string(slist, program->hostname); /* 15 */
 93.1071 -        gmyth_string_list_append_int(slist, program->sourceid);    /* 16 */
 93.1072 -        gmyth_string_list_append_int(slist, program->cardid);      /* 17 */
 93.1073 -        gmyth_string_list_append_int(slist, program->inputid);     /* 18 */
 93.1074 -        gmyth_string_list_append_int(slist, program->recpriority); /* 19 */
 93.1075 -
 93.1076 -        // recstatus == recording
 93.1077 -        gmyth_string_list_append_int(slist, -3);                   /* 20 */
 93.1078 -
 93.1079 -        gmyth_string_list_append_int(slist, program->recordid);    /* 21 */
 93.1080 -        gmyth_string_list_append_int(slist, program->rectype);     /* 22 */
 93.1081 -        gmyth_string_list_append_int(slist, program->dupin);       /* 23 */
 93.1082 -        gmyth_string_list_append_int(slist, program->dupmethod);   /* 24 */
 93.1083 -
 93.1084 -
 93.1085 -        //fixme
 93.1086 -        program->recstartts->tv_sec -= (60*60);
 93.1087 -
 93.1088 -        gmyth_string_list_append_int(slist, 
 93.1089 -                                     program->recstartts != NULL ?
 93.1090 -                                     program->recstartts->tv_sec : 0);   /* 26 */
 93.1091 -
 93.1092 -        gmyth_string_list_append_int(slist, 
 93.1093 -                                     program->recendts != NULL ?
 93.1094 -                                     program->recendts->tv_sec : 0);    /* 27 */
 93.1095 -
 93.1096 -        gmyth_string_list_append_int(slist, program->repeat);       /* 28 */
 93.1097 -        gmyth_string_list_append_int(slist, program->programflags); /* 29 */
 93.1098 -
 93.1099 -        gmyth_string_list_append_char_array(slist, 
 93.1100 -                                            program->recgroup != NULL ?
 93.1101 -                                            program->recgroup->str : "Default");  /* 30 */
 93.1102 -
 93.1103 -        gmyth_string_list_append_int(slist, program->chancommfree);         /* 31 */
 93.1104 -        gmyth_string_list_append_string(slist, program->chanOutputFilters); /* 32 */
 93.1105 -        gmyth_string_list_append_string(slist, program->seriesid);          /* 33 */
 93.1106 -        gmyth_string_list_append_string(slist, program->program_id);     /* 34 */
 93.1107 -
 93.1108 -        gmyth_string_list_append_int(slist,
 93.1109 -                                     program->lastmodified != NULL ?
 93.1110 -                                     program->lastmodified->tv_sec : 0);   /* 35 */
 93.1111 -
 93.1112 -        gmyth_string_list_append_float(slist, program->stars); /* 36 */
 93.1113 -
 93.1114 -        gmyth_string_list_append_int(slist,
 93.1115 -                                     program->originalAirDate != NULL ?
 93.1116 -                                     program->originalAirDate->tv_sec : 0); /* 37 */
 93.1117 -
 93.1118 -        gmyth_string_list_append_int(slist, program->hasAirDate);  /* 38 */
 93.1119 -
 93.1120 -        gmyth_string_list_append_char_array(slist,
 93.1121 -                                            program->playgroup != NULL ?
 93.1122 -                                            program->playgroup->str : "Default");  /* 39 */
 93.1123 -
 93.1124 -        gmyth_string_list_append_int(slist, program->recpriority2); /* 40 */
 93.1125 -        gmyth_string_list_append_int(slist, program->recpriority2); /* 40 */
 93.1126 -
 93.1127 -        gmyth_socket_sendreceive_stringlist(socket, slist);
 93.1128 -        res = (gmyth_string_list_get_int(slist, 0) == 1);
 93.1129 -
 93.1130 -        g_object_unref (program);
 93.1131 -        g_object_unref (slist);
 93.1132 -    }
 93.1133 -
 93.1134 -    g_object_unref (socket);
 93.1135 -    return res;
 93.1136 -}
 93.1137 -
 93.1138 -
 93.1139 -/** Notifies the backend of an update in the db.
 93.1140 - * 
 93.1141 - * @param record_id the id of the modified recording.
 93.1142 - */
 93.1143 -// fixme: put void and discovery record_id inside
 93.1144 -static gboolean
 93.1145 -update_backend (GMythScheduler * scheduler, 
 93.1146 -                gint record_id)  
 93.1147 -{
 93.1148 -    GMythSocket    *socket;
 93.1149 -    GMythStringList *strlist = gmyth_string_list_new();
 93.1150 -    GString        *datastr = g_string_new("RESCHEDULE_RECORDINGS ");
 93.1151 -    gboolean        ret = FALSE;
 93.1152 -
 93.1153 -    g_string_append_printf(datastr, "%d", record_id);
 93.1154 -    gmyth_string_list_append_string(strlist, datastr);
 93.1155 -
 93.1156 -    socket = gmyth_backend_info_get_connected_socket (scheduler->backend_info);
 93.1157 -    if (socket != NULL) { 
 93.1158 -        ret = (gmyth_socket_sendreceive_stringlist(socket, strlist) > 0);
 93.1159 -        g_object_unref (socket);
 93.1160 -    } else {
 93.1161 -        g_warning("[%s] Connection to backend failed!", __FUNCTION__);
 93.1162 -    }
 93.1163 -
 93.1164 -    g_string_free(datastr, TRUE);
 93.1165 -    g_object_unref(strlist);
 93.1166 -    return ret;
 93.1167 -}
 93.1168 -
 93.1169 -void
 93.1170 -gmyth_scheduler_recorded_info_get_preview(RecordedInfo * info,
 93.1171 -                                          GByteArray * data)
 93.1172 -{
 93.1173 -}
 93.1174 -
 93.1175 -void
 93.1176 -gmyth_recorded_info_free(RecordedInfo * info)
 93.1177 -{
 93.1178 -    g_return_if_fail (info != NULL);
 93.1179 -
 93.1180 -    if (info->program_id)
 93.1181 -        g_string_free (info->program_id, TRUE);
 93.1182 -
 93.1183 -    if (info->title != NULL)
 93.1184 -        g_string_free(info->title, TRUE);
 93.1185 -
 93.1186 -    if (info->subtitle != NULL)
 93.1187 -        g_string_free(info->subtitle, TRUE);
 93.1188 -
 93.1189 -    if (info->description != NULL)
 93.1190 -        g_string_free(info->description, TRUE);
 93.1191 -
 93.1192 -    if (info->category != NULL)
 93.1193 -        g_string_free(info->category, TRUE);
 93.1194 -
 93.1195 -    if (info->basename != NULL)
 93.1196 -        g_string_free(info->basename, TRUE);
 93.1197 -
 93.1198 -    if (info != NULL)
 93.1199 -        g_free(info->start_time);
 93.1200 -
 93.1201 -    if (info != NULL)
 93.1202 -        g_free(info->end_time);
 93.1203 -
 93.1204 -    g_free(info);
 93.1205 -}
 93.1206 -
 93.1207 -static void
 93.1208 -free_recorded_info_item(gpointer data, gpointer user_data)
 93.1209 -{
 93.1210 -    RecordedInfo   *info = (RecordedInfo *) data;
 93.1211 -
 93.1212 -    gmyth_recorded_info_free(info);
 93.1213 -}
 93.1214 -
 93.1215 -void
 93.1216 -gmyth_recorded_info_list_free(GList * list)
 93.1217 -{
 93.1218 -    g_return_if_fail(list != NULL);
 93.1219 -
 93.1220 -    g_list_foreach(list, free_recorded_info_item, NULL);
 93.1221 -    g_list_free(list);
 93.1222 -}
 93.1223 -
 93.1224 -void
 93.1225 -gmyth_schedule_info_free(ScheduleInfo * info)
 93.1226 -{
 93.1227 -
 93.1228 -    g_return_if_fail(info != NULL);
 93.1229 -
 93.1230 -    if (info->program_id)
 93.1231 -        g_string_free (info->program_id, TRUE);
 93.1232 -
 93.1233 -    if (info->title != NULL)
 93.1234 -        g_string_free(info->title, TRUE);
 93.1235 -
 93.1236 -    if (info->subtitle != NULL)
 93.1237 -        g_string_free(info->subtitle, TRUE);
 93.1238 -
 93.1239 -    if (info->description != NULL)
 93.1240 -        g_string_free(info->description, TRUE);
 93.1241 -
 93.1242 -    if (info->category != NULL)
 93.1243 -        g_string_free(info->category, TRUE);
 93.1244 -
 93.1245 -    if (info != NULL)
 93.1246 -        g_free(info->start_time);
 93.1247 -
 93.1248 -    if (info != NULL)
 93.1249 -        g_free(info->end_time);
 93.1250 -
 93.1251 -    g_free(info);
 93.1252 -}
 93.1253 -
 93.1254 -static void
 93.1255 -free_schedule_info_item(gpointer data, gpointer user_data)
 93.1256 -{
 93.1257 -    ScheduleInfo   *info = (ScheduleInfo *) data;
 93.1258 -
 93.1259 -    gmyth_schedule_info_free(info);
 93.1260 -}
 93.1261 -
 93.1262 -void
 93.1263 -gmyth_schedule_info_list_free(GList * list)
 93.1264 -{
 93.1265 -    g_return_if_fail(list != NULL);
 93.1266 -
 93.1267 -    g_list_foreach(list, free_schedule_info_item, NULL);
 93.1268 -    g_list_free(list);
 93.1269 -}
    94.1 --- a/gmyth/src/gmyth_scheduler.h	Mon Feb 25 17:45:36 2008 +0000
    94.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.3 @@ -1,194 +0,0 @@
    94.4 -/**
    94.5 - * GMyth Library
    94.6 - *
    94.7 - * @file gmyth/gmyth_scheduler.h
    94.8 - *
    94.9 - * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
   94.10 - * and modifying the recorded content.
   94.11 - *
   94.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   94.13 - * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
   94.14 - *
   94.15 - *
   94.16 - * This program is free software; you can redistribute it and/or modify
   94.17 - * it under the terms of the GNU Lesser General Public License as published by
   94.18 - * the Free Software Foundation; either version 2 of the License, or
   94.19 - * (at your option) any later version.
   94.20 - *
   94.21 - * This program is distributed in the hope that it will be useful,
   94.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   94.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   94.24 - * GNU General Public License for more details.
   94.25 - *
   94.26 - * You should have received a copy of the GNU Lesser General Public License
   94.27 - * along with this program; if not, write to the Free Software
   94.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   94.29 - */
   94.30 -
   94.31 -#ifndef __GMYTH_SCHEDULER_H__
   94.32 -#define __GMYTH_SCHEDULER_H__
   94.33 -
   94.34 -#include <glib-object.h>
   94.35 -#include <time.h>
   94.36 -
   94.37 -#include "gmyth_common.h"
   94.38 -#include "gmyth_query.h"
   94.39 -#include "gmyth_backendinfo.h"
   94.40 -
   94.41 -G_BEGIN_DECLS
   94.42 -
   94.43 -typedef enum {
   94.44 -    GMYTH_SCHEDULE_ONE_OCCURRENCE,
   94.45 -    GMYTH_SCHEDULE_ALL_OCCURRENCES,
   94.46 -    GMYTH_SCHEDULE_EXCEPTION
   94.47 -} GMythScheduleType;
   94.48 -
   94.49 -
   94.50 -#define GMYTH_SCHEDULER_TYPE               (gmyth_scheduler_get_type ())
   94.51 -#define GMYTH_SCHEDULER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SCHEDULER_TYPE, GMythScheduler))
   94.52 -#define GMYTH_SCHEDULER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
   94.53 -#define IS_GMYTH_SCHEDULER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_SCHEDULER_TYPE))
   94.54 -#define IS_GMYTH_SCHEDULER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SCHEDULER_TYPE))
   94.55 -#define GMYTH_SCHEDULER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SCHEDULER_TYPE, GMythSchedulerClass))
   94.56 -
   94.57 -typedef struct _GMythScheduler GMythScheduler;
   94.58 -typedef struct _GMythSchedulerClass GMythSchedulerClass;
   94.59 -
   94.60 -struct _GMythSchedulerClass {
   94.61 -    GObjectClass    parent_class;
   94.62 -};
   94.63 -
   94.64 -struct _GMythScheduler {
   94.65 -    GObject         parent;
   94.66 -
   94.67 -    unsigned long   recordid;
   94.68 -    unsigned long   type;
   94.69 -    unsigned long   search;
   94.70 -    GString        *profile;
   94.71 -
   94.72 -    long            dupin;
   94.73 -    long            dupmethod;
   94.74 -    long            autoexpire;
   94.75 -    short int       autotranscode;
   94.76 -    long            transcoder;
   94.77 -
   94.78 -    short int       autocommflag;
   94.79 -    short int       autouserjob1;
   94.80 -    short int       autouserjob2;
   94.81 -    short int       autouserjob3;
   94.82 -    short int       autouserjob4;
   94.83 -
   94.84 -    long            startoffset;
   94.85 -    long            endoffset;
   94.86 -    long            maxepisodes;
   94.87 -    long            maxnewest;
   94.88 -
   94.89 -    long            recpriority;
   94.90 -    GString        *recgroup;
   94.91 -    GString        *playgroup;
   94.92 -
   94.93 -    long            prefinput;
   94.94 -    short int       inactive;
   94.95 -
   94.96 -    GString        *search_type;
   94.97 -    GString        *search_what;
   94.98 -
   94.99 -    GMythQuery     *msqlquery;
  94.100 -    GMythBackendInfo *backend_info;
  94.101 -};
  94.102 -
  94.103 -typedef struct {
  94.104 -    guint           schedule_id;
  94.105 -    gint            channel_id;
  94.106 -    GString        *program_id;
  94.107 -
  94.108 -    GTimeVal       *start_time;
  94.109 -    GTimeVal       *end_time;
  94.110 -
  94.111 -    GString        *seriesid;
  94.112 -    GString        *title;
  94.113 -    GString        *subtitle;
  94.114 -    GString        *description;
  94.115 -    GString        *category;
  94.116 -
  94.117 -    GMythScheduleType type;
  94.118 -
  94.119 -    gint parentid;
  94.120 -
  94.121 -} ScheduleInfo;
  94.122 -
  94.123 -typedef struct {
  94.124 -    guint           record_id;
  94.125 -    gint            channel_id;
  94.126 -    GString        *program_id;
  94.127 -
  94.128 -    GTimeVal       *start_time;
  94.129 -    GTimeVal       *end_time;
  94.130 -
  94.131 -    GString         *seriesid;
  94.132 -    GString        *title;
  94.133 -    GString        *subtitle;
  94.134 -    GString        *description;
  94.135 -    GString        *category;
  94.136 -
  94.137 -    GString        *basename;
  94.138 -
  94.139 -    guint64         filesize;
  94.140 -
  94.141 -} RecordedInfo;
  94.142 -
  94.143 -
  94.144 -GType               gmyth_scheduler_get_type                (void);
  94.145 -
  94.146 -GMythScheduler*     gmyth_scheduler_new                     (void);
  94.147 -gboolean            gmyth_scheduler_connect                 (GMythScheduler * scheduler,
  94.148 -                                                             GMythBackendInfo * backend_info);
  94.149 -gboolean            gmyth_scheduler_connect_with_timeout    (GMythScheduler * scheduler,
  94.150 -                                                             GMythBackendInfo * backend_info,
  94.151 -                                                             guint timeout);
  94.152 -gboolean            gmyth_scheduler_disconnect              (GMythScheduler * scheduler);
  94.153 -gint                gmyth_scheduler_get_schedule_list       (GMythScheduler * scheduler,
  94.154 -                                                             GList ** sched_list);
  94.155 -gint                gmyth_scheduler_get_recorded_list       (GMythScheduler * scheduler,
  94.156 -                                                             GList ** rec_list);
  94.157 -RecordedInfo*       gmyth_scheduler_get_recorded_info       (GMythScheduler *scheduler,
  94.158 -                                                             const char *basename);
  94.159 -gboolean            gmyth_scheduler_was_recorded_before     (GMythScheduler* scheduler,
  94.160 -                                                             gint channel_id,
  94.161 -                                                             time_t start_time);
  94.162 -gboolean            gmyth_scheduler_reactivate_schedule     (GMythScheduler* scheduler,
  94.163 -                                                             gint channel_id,
  94.164 -                                                             time_t start_time);
  94.165 -GMythProgramInfo*   gmyth_scheduler_get_recorded_on_time    (GMythScheduler* scheduler,
  94.166 -                                                             guint channel_id);
  94.167 -GMythProgramInfo*   gmyth_scheduler_get_recorded            (GMythScheduler * scheduler,
  94.168 -                                                             GString * channel,
  94.169 -                                                             GTimeVal * starttime);
  94.170 -ScheduleInfo*       gmyth_scheduler_add_schedule_program    (GMythScheduler * scheduler,
  94.171 -                                                             GMythProgramInfo *program,
  94.172 -                                                             GMythScheduleType type);
  94.173 -gint                gmyth_scheduler_add_schedule            (GMythScheduler * scheduler,
  94.174 -                                                             ScheduleInfo * schedule_info);
  94.175 -gboolean            gmyth_scheduler_add_schedule_full       (GMythScheduler * scheduler,
  94.176 -                                                             ScheduleInfo * schedule_info,
  94.177 -                                                             GMythScheduleType type);
  94.178 -gboolean            gmyth_scheduler_add_exception           (GMythScheduler *scheduler,
  94.179 -                                                             gint schedule_id,
  94.180 -                                                             ScheduleInfo *exception_info);
  94.181 -gboolean            gmyth_scheduler_delete_schedule         (GMythScheduler * scheduler,
  94.182 -                                                             gint record_id);
  94.183 -gint                gmyth_scheduler_delete_recorded         (GMythScheduler * scheduler,
  94.184 -                                                             gint record_id);
  94.185 -gboolean            gmyth_scheduler_stop_recording          (GMythScheduler * scheduler,
  94.186 -                                                             gint channel_id);
  94.187 -void                gmyth_scheduler_recorded_info_get_preview(RecordedInfo * info,
  94.188 -                                                             GByteArray * data);
  94.189 -
  94.190 -
  94.191 -void                gmyth_recorded_info_free                (RecordedInfo * info);
  94.192 -void                gmyth_schedule_info_free                (ScheduleInfo * info);
  94.193 -void                gmyth_recorded_info_list_free           (GList * list);
  94.194 -void                gmyth_schedule_info_list_free           (GList * list);
  94.195 -
  94.196 -G_END_DECLS
  94.197 -#endif                          /* __GMYTH_SCHEDULER_H__ */
    95.1 --- a/gmyth/src/gmyth_socket.c	Mon Feb 25 17:45:36 2008 +0000
    95.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.3 @@ -1,1295 +0,0 @@
    95.4 -/**
    95.5 - * GMyth Library
    95.6 - *
    95.7 - * @file gmyth/gmyth_socket.c
    95.8 - * 
    95.9 - * @brief <p> MythTV socket implementation, according to the MythTV Project
   95.10 - * (www.mythtv.org). 
   95.11 - * 
   95.12 - * This component provides basic socket functionalities to interact with
   95.13 - * the Mythtv backend.
   95.14 - * <p>
   95.15 - *
   95.16 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   95.17 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br> 
   95.18 - *
   95.19 - * 
   95.20 - * This program is free software; you can redistribute it and/or modify
   95.21 - * it under the terms of the GNU Lesser General Public License as published by
   95.22 - * the Free Software Foundation; either version 2 of the License, or
   95.23 - * (at your option) any later version.
   95.24 - *
   95.25 - * This program is distributed in the hope that it will be useful,
   95.26 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   95.27 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   95.28 - * GNU General Public License for more details.
   95.29 - *
   95.30 - * You should have received a copy of the GNU Lesser General Public License
   95.31 - * along with this program; if not, write to the Free Software
   95.32 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   95.33 - */
   95.34 -
   95.35 -#ifdef HAVE_CONFIG_H
   95.36 -#include "config.h"
   95.37 -#endif
   95.38 -
   95.39 -#include "gmyth_socket.h"
   95.40 -
   95.41 -#include <glib.h>
   95.42 -#include <glib/gprintf.h>
   95.43 -
   95.44 -#include <arpa/inet.h>
   95.45 -#include <sys/types.h>
   95.46 -#include <sys/socket.h>
   95.47 -#include <sys/param.h>
   95.48 -#include <netdb.h>
   95.49 -#include <net/if.h>
   95.50 -#include <errno.h>
   95.51 -#include <assert.h>
   95.52 -#include <stdlib.h>
   95.53 -
   95.54 -#include <unistd.h>
   95.55 -#include <netinet/in.h>
   95.56 -#include <fcntl.h>
   95.57 -#include <signal.h>
   95.58 -
   95.59 -#include <sys/ioctl.h>
   95.60 -
   95.61 -#include "gmyth_stringlist.h"
   95.62 -#include "gmyth_uri.h"
   95.63 -#include "gmyth_debug.h"
   95.64 -
   95.65 -#define BUFLEN 				   	512
   95.66 -#define MYTH_SEPARATOR 			    	"[]:[]"
   95.67 -#define MYTH_PROTOCOL_FIELD_SIZE		8
   95.68 -
   95.69 -/*
   95.70 - * max number of iterations 
   95.71 - */
   95.72 -#define MYTHTV_MAX_VERSION_CHECKS		40
   95.73 -
   95.74 -// FIXME: put this in the right place
   95.75 -#define  MYTHTV_VERSION_DEFAULT			31
   95.76 -
   95.77 -/*
   95.78 - * static GStaticMutex mutex = G_STATIC_MUTEX_INIT; 
   95.79 - */
   95.80 -
   95.81 -/*
   95.82 - * static GStaticRWLock rwlock = G_STATIC_RW_LOCK_INIT;
   95.83 - */
   95.84 -
   95.85 -static gchar   *local_hostname = NULL;
   95.86 -
   95.87 -static void     gmyth_socket_class_init(GMythSocketClass * klass);
   95.88 -static void     gmyth_socket_init(GMythSocket * object);
   95.89 -
   95.90 -static void     gmyth_socket_dispose(GObject * object);
   95.91 -static void     gmyth_socket_finalize(GObject * object);
   95.92 -
   95.93 -G_DEFINE_TYPE(GMythSocket, gmyth_socket, G_TYPE_OBJECT)
   95.94 -    static void     gmyth_socket_class_init(GMythSocketClass * klass)
   95.95 -{
   95.96 -    GObjectClass   *gobject_class;
   95.97 -
   95.98 -    gobject_class = (GObjectClass *) klass;
   95.99 -
  95.100 -    gobject_class->dispose = gmyth_socket_dispose;
  95.101 -    gobject_class->finalize = gmyth_socket_finalize;
  95.102 -}
  95.103 -
  95.104 -static void
  95.105 -gmyth_socket_init(GMythSocket * gmyth_socket)
  95.106 -{
  95.107 -
  95.108 -    /*
  95.109 -     * gmyth_socket->local_hostname = NULL; 
  95.110 -     */
  95.111 -
  95.112 -}
  95.113 -
  95.114 -/** Gets the some important address translation info, from the client socket
  95.115 - * that will open a connection.
  95.116 - * 
  95.117 - * @return gint that represents the error number from getaddrinfo(). 
  95.118 - */
  95.119 -static          gint
  95.120 -gmyth_socket_toaddrinfo(const gchar * addr, gint port,
  95.121 -                        struct addrinfo **addrInfo)
  95.122 -{
  95.123 -    struct addrinfo hints;
  95.124 -    gchar          *portStr = NULL;
  95.125 -    gint            errorn = EADDRNOTAVAIL;
  95.126 -
  95.127 -    g_return_val_if_fail(addr != NULL, -1);
  95.128 -
  95.129 -    memset(&hints, 0, sizeof(struct addrinfo));
  95.130 -    hints.ai_family = AF_INET;
  95.131 -    hints.ai_socktype = SOCK_STREAM;
  95.132 -    /*
  95.133 -     * hints.ai_flags = AI_NUMERICHOST; 
  95.134 -     */
  95.135 -
  95.136 -    if (port != -1)
  95.137 -        portStr = g_strdup_printf("%d", port);
  95.138 -    else
  95.139 -        portStr = NULL;
  95.140 -
  95.141 -    gmyth_debug("Getting name resolution for: %s, %d\n", addr, port);
  95.142 -
  95.143 -    if ((errorn = getaddrinfo(addr, portStr, &hints, addrInfo)) != 0) {
  95.144 -        gmyth_debug("[%s] Socket ERROR: %s\n", __FUNCTION__,
  95.145 -                    gai_strerror(errorn));
  95.146 -    }
  95.147 -
  95.148 -    g_free(portStr);
  95.149 -
  95.150 -    return errorn;
  95.151 -}
  95.152 -
  95.153 -/*
  95.154 - * static gint gmyth_socket_find_match_address_uri( GMythURI* uri, gchar
  95.155 - * *address ) { if ( g_ascii_strcasecmp( gmyth_uri_get_host( uri ),
  95.156 - * address ) == 0 ) { //gmyth_debug( "Found URI: %s !!!\n",
  95.157 - * rui_uri_getvalue(uri) ); return 0; } else { return -1; } } 
  95.158 - */
  95.159 -
  95.160 -const gchar    *PATH_PROC_NET_DEV = "/proc/net/dev";
  95.161 -
  95.162 -/** Gets the list of all local network interfaces (using the /proc/net/dev directory).
  95.163 - * 
  95.164 - * @param current_connections	A list with all the network interfaces are valid, 
  95.165 - * 		to be applied just like a filter.
  95.166 - * @return List with all the local net interfaces. 
  95.167 - */
  95.168 -GList          *
  95.169 -gmyth_socket_get_local_addrs(GList * current_connections)
  95.170 -{
  95.171 -
  95.172 -    GList          *local_addrs = NULL;
  95.173 -    FILE           *fd;
  95.174 -    gint            s;
  95.175 -    gchar           buffer[256 + 1];
  95.176 -    gchar           ifaddr[20 + 1];
  95.177 -    gchar          *ifname;
  95.178 -    gchar          *sep;
  95.179 -
  95.180 -    s = socket(AF_INET, SOCK_DGRAM, 0);
  95.181 -    if (s < 0)
  95.182 -        return 0;
  95.183 -    fd = fopen(PATH_PROC_NET_DEV, "r");
  95.184 -    fgets(buffer, sizeof(buffer) - 1, fd);
  95.185 -    fgets(buffer, sizeof(buffer) - 1, fd);
  95.186 -    while (!feof(fd)) {
  95.187 -        ifname = buffer;
  95.188 -
  95.189 -        if (fgets(buffer, sizeof(buffer) - 1, fd) == NULL)
  95.190 -            break;
  95.191 -        sep = strrchr(buffer, ':');
  95.192 -        if (sep)
  95.193 -            *sep = 0;
  95.194 -        while (*ifname == ' ')
  95.195 -            ifname++;
  95.196 -        struct ifreq    req;
  95.197 -
  95.198 -        strcpy(req.ifr_name, ifname);
  95.199 -        if (ioctl(s, SIOCGIFFLAGS, &req) < 0)
  95.200 -            continue;
  95.201 -        if (!(req.ifr_flags & IFF_UP))
  95.202 -            continue;
  95.203 -        if (req.ifr_flags & IFF_LOOPBACK)
  95.204 -            continue;
  95.205 -        if (ioctl(s, SIOCGIFADDR, &req) < 0)
  95.206 -            continue;
  95.207 -        g_strlcpy(ifaddr,
  95.208 -                  inet_ntoa(((struct sockaddr_in *) &req.ifr_addr)->
  95.209 -                            sin_addr), sizeof(struct ifaddr) - 1);
  95.210 -        local_addrs = g_list_append(local_addrs, g_strdup(ifaddr));
  95.211 -
  95.212 -        gmyth_debug
  95.213 -            ("( from the /proc/net/dev) Interface name: %s, address: %s\n",
  95.214 -             ifname, ifaddr);
  95.215 -    }
  95.216 -    fclose(fd);
  95.217 -    close(s);
  95.218 -    return local_addrs;
  95.219 -}
  95.220 -
  95.221 -/**
  95.222 - * Get only the local addresses from the primary interface
  95.223 - */
  95.224 -gchar          *
  95.225 -gmyth_socket_get_primary_addr(void)
  95.226 -{
  95.227 -    gchar          *if_eth0 = g_new0(gchar, sizeof(struct ifaddr) - 1);
  95.228 -    GList          *if_tmp = NULL;
  95.229 -
  95.230 -    GList          *interfs = gmyth_socket_get_local_addrs(NULL);
  95.231 -
  95.232 -    if (interfs != NULL && (g_list_length(interfs) > 0)) {
  95.233 -        // get the first occurrence (primary interface) 
  95.234 -        if_tmp = g_list_first(interfs);
  95.235 -
  95.236 -        if (if_tmp != NULL)
  95.237 -            g_strlcpy(if_eth0, (gchar *) if_tmp->data,
  95.238 -                      sizeof(struct ifaddr) - 1);
  95.239 -
  95.240 -    }
  95.241 -
  95.242 -    if (interfs != NULL)
  95.243 -        g_list_free(interfs);
  95.244 -
  95.245 -    return if_eth0;
  95.246 -}
  95.247 -
  95.248 -/** This function retrieves the local hostname of the 
  95.249 - * client machine.
  95.250 - *
  95.251 - * @return GString* get local hostname.
  95.252 - */
  95.253 -GString        *
  95.254 -gmyth_socket_get_local_hostname(void)
  95.255 -{
  95.256 -    char            hname[50];
  95.257 -    gint            res = gethostname(hname, 50);
  95.258 -
  95.259 -    if (res == -1) {
  95.260 -        gmyth_debug("Error while getting hostname");
  95.261 -        return g_string_new("default");
  95.262 -    }
  95.263 -
  95.264 -    return g_string_new(hname);
  95.265 -
  95.266 -#if 0
  95.267 -    GString        *str = NULL;
  95.268 -
  95.269 -    if (local_hostname != NULL && strlen(local_hostname) > 0)
  95.270 -        return g_string_new(local_hostname);
  95.271 -
  95.272 -    gchar          *localaddr = NULL;
  95.273 -    gboolean        found_addr = FALSE;
  95.274 -    struct addrinfo *addr_info_data = NULL,
  95.275 -        *addr_info0 = NULL;
  95.276 -    struct sockaddr_in *sa = NULL;
  95.277 -    gchar           localhostname[MAXHOSTNAMELEN];
  95.278 -
  95.279 -
  95.280 -    if (gethostname(localhostname, MAXHOSTNAMELEN) != 0) {
  95.281 -        gmyth_debug("Error on gethostname");
  95.282 -    }
  95.283 -    localhostname[MAXHOSTNAMELEN - 1] = 0;
  95.284 -
  95.285 -    gint            err =
  95.286 -        gmyth_socket_toaddrinfo(localhostname, -1, &addr_info_data);
  95.287 -
  95.288 -    if (err == EADDRNOTAVAIL) {
  95.289 -        gmyth_debug("[%s] Address (%s) not available. (reason = %d)\n",
  95.290 -                    __FUNCTION__, localhostname, err);
  95.291 -        return str;
  95.292 -    }
  95.293 -
  95.294 -    g_mutex_lock(gmyth_socket->mutex);
  95.295 -
  95.296 -    addr_info0 = addr_info_data;
  95.297 -
  95.298 -    while (addr_info0 != NULL && addr_info0->ai_addr != NULL &&
  95.299 -           (sa = (struct sockaddr_in *) addr_info0->ai_addr) != NULL
  95.300 -           && !found_addr) {
  95.301 -        localaddr = inet_ntoa(sa->sin_addr);
  95.302 -
  95.303 -        if (localaddr != NULL && (g_strrstr(localaddr, "127") == NULL)) {
  95.304 -            str = g_string_new(localaddr);
  95.305 -            found_addr = TRUE;
  95.306 -            g_free(localaddr);
  95.307 -            break;
  95.308 -        }
  95.309 -        /*
  95.310 -         * if (localaddr != NULL) { g_free (localaddr); localaddr = NULL;
  95.311 -         * } 
  95.312 -         */
  95.313 -
  95.314 -        addr_info0 = addr_info0->ai_next;
  95.315 -    };
  95.316 -
  95.317 -    freeaddrinfo(addr_info_data);
  95.318 -    addr_info_data = NULL;
  95.319 -
  95.320 -    if (found_addr == FALSE) {
  95.321 -        gchar          *prim_addr = gmyth_socket_get_primary_addr();
  95.322 -
  95.323 -        if (prim_addr != NULL) {
  95.324 -            gmyth_debug
  95.325 -                ("[%s] Could not determine the local alphanumerical hostname. Setting to %s\n",
  95.326 -                 __FUNCTION__, prim_addr);
  95.327 -
  95.328 -            str = g_string_new(prim_addr);
  95.329 -            g_free(prim_addr);
  95.330 -        } else {
  95.331 -            str = g_string_new(localhostname);
  95.332 -        }
  95.333 -    }
  95.334 -
  95.335 -    g_mutex_unlock(gmyth_socket->mutex);
  95.336 -
  95.337 -    if (str != NULL && str->str != NULL)
  95.338 -        local_hostname = g_strdup(str->str);
  95.339 -
  95.340 -    return str;
  95.341 -#endif
  95.342 -}
  95.343 -
  95.344 -static void
  95.345 -gmyth_socket_dispose(GObject * object)
  95.346 -{
  95.347 -    GMythSocket    *gmyth_socket = GMYTH_SOCKET(object);
  95.348 -
  95.349 -    /*
  95.350 -     * disconnect socket 
  95.351 -     */
  95.352 -    gmyth_socket_close_connection(gmyth_socket);
  95.353 -
  95.354 -    g_free(gmyth_socket->hostname);
  95.355 -
  95.356 -    g_free(local_hostname);
  95.357 -
  95.358 -    local_hostname = NULL;
  95.359 -
  95.360 -    if (gmyth_socket->mutex != NULL) {
  95.361 -        g_mutex_free(gmyth_socket->mutex);
  95.362 -        gmyth_socket->mutex = NULL;
  95.363 -    }
  95.364 -
  95.365 -    G_OBJECT_CLASS(gmyth_socket_parent_class)->dispose(object);
  95.366 -}
  95.367 -
  95.368 -static void
  95.369 -gmyth_socket_finalize(GObject * object)
  95.370 -{
  95.371 -    g_signal_handlers_destroy(object);
  95.372 -
  95.373 -    G_OBJECT_CLASS(gmyth_socket_parent_class)->finalize(object);
  95.374 -}
  95.375 -
  95.376 -/** Creates a new instance of GMythSocket.
  95.377 - * 
  95.378 - * @return a new instance of GMythSocket.
  95.379 - */
  95.380 -GMythSocket    *
  95.381 -gmyth_socket_new()
  95.382 -{
  95.383 -    GMythSocket    *gmyth_socket =
  95.384 -        GMYTH_SOCKET(g_object_new(GMYTH_SOCKET_TYPE, NULL));
  95.385 -
  95.386 -    gmyth_socket->mythtv_version = MYTHTV_VERSION_DEFAULT;
  95.387 -
  95.388 -    gmyth_socket->mutex = g_mutex_new();
  95.389 -
  95.390 -    return gmyth_socket;
  95.391 -}
  95.392 -
  95.393 -/** Try to open an asynchronous connection to the MythTV backend.
  95.394 - * 
  95.395 - * @param fd 		Socket descriptor.
  95.396 - * @param remote 	Remote address.
  95.397 - * @param len 		Newly created socket length field.
  95.398 - * @param timeout	Timeval argument with the time interval to timeout before closing.
  95.399 - * @param err		Error message number.
  95.400 - * @return Any numerical value below 0, if an error had been found.
  95.401 - */
  95.402 -static          gint
  95.403 -gmyth_socket_try_connect(gint fd, struct sockaddr *remote, gint len,
  95.404 -                         struct timeval *timeout, gint * err)
  95.405 -{
  95.406 -    /*
  95.407 -     * g_return_val_if_fail( timeout != NULL, 0 ); 
  95.408 -     */
  95.409 -    gint            saveflags,
  95.410 -                    ret,
  95.411 -                    back_err;
  95.412 -
  95.413 -    fd_set          fd_w;
  95.414 -
  95.415 -    saveflags = fcntl(fd, F_GETFL, 0);
  95.416 -    if (saveflags < 0) {
  95.417 -        gmyth_debug("[%s] Problems when getting socket flags on fcntl.\n",
  95.418 -                    __FUNCTION__);
  95.419 -        *err = errno;
  95.420 -        return -1;
  95.421 -    }
  95.422 -
  95.423 -    /*
  95.424 -     * Set non blocking 
  95.425 -     */
  95.426 -    if (fcntl(fd, F_SETFL, saveflags | O_NONBLOCK) < 0) {
  95.427 -        gmyth_debug
  95.428 -            ("[%s] Problems when setting non-blocking using fcntl.\n",
  95.429 -             __FUNCTION__);
  95.430 -        *err = errno;
  95.431 -        return -1;
  95.432 -    }
  95.433 -
  95.434 -    /*
  95.435 -     * This will return immediately 
  95.436 -     */
  95.437 -    *err = connect(fd, remote, len);
  95.438 -    back_err = errno;
  95.439 -
  95.440 -    /*
  95.441 -     * restore flags 
  95.442 -     */
  95.443 -    if (fcntl(fd, F_SETFL, saveflags) < 0) {
  95.444 -        gmyth_debug
  95.445 -            ("[%s] Problems when trying to restore flags with fcntl.\n",
  95.446 -             __FUNCTION__);
  95.447 -        *err = errno;
  95.448 -        return -1;
  95.449 -    }
  95.450 -
  95.451 -    /*
  95.452 -     * return unless the connection was successful or the connect is still 
  95.453 -     * in progress. 
  95.454 -     */
  95.455 -    if (*err < 0 && back_err != EINPROGRESS) {
  95.456 -        gmyth_debug
  95.457 -            ("[%s] Connection unsucessfully (it is not in progress).\n",
  95.458 -             __FUNCTION__);
  95.459 -        *err = errno;
  95.460 -        return -1;
  95.461 -    }
  95.462 -
  95.463 -    FD_ZERO(&fd_w);
  95.464 -    FD_SET(fd, &fd_w);
  95.465 -
  95.466 -    *err = select(FD_SETSIZE, NULL, &fd_w, NULL, timeout);
  95.467 -    if (*err < 0) {
  95.468 -        gmyth_debug("[%s] Connection unsucessfull (timed out).\n",
  95.469 -                    __FUNCTION__);
  95.470 -        *err = errno;
  95.471 -        return -1;
  95.472 -    }
  95.473 -
  95.474 -    /*
  95.475 -     * 0 means it timeout out & no fds changed 
  95.476 -     */
  95.477 -    if (*err == 0) {
  95.478 -        gmyth_debug
  95.479 -            ("[%s] Connection unsucessfull [%d] - 0 means it timeout out & no fds changed\n",
  95.480 -             __FUNCTION__, *err);
  95.481 -        close(fd);
  95.482 -        *err = ETIMEDOUT;
  95.483 -        return -1;
  95.484 -    }
  95.485 -
  95.486 -    /*
  95.487 -     * Get the return code from the connect 
  95.488 -     */
  95.489 -    len = sizeof(ret);
  95.490 -    *err = getsockopt(fd, SOL_SOCKET, SO_ERROR, &ret, (socklen_t *) & len);
  95.491 -
  95.492 -    if (*err < 0) {
  95.493 -        gmyth_debug("[%s] Connection unsucessfull.\n", __FUNCTION__);
  95.494 -        *err = errno;
  95.495 -        return -1;
  95.496 -    }
  95.497 -
  95.498 -    /*
  95.499 -     * ret=0 means success, otherwise it contains the errno 
  95.500 -     */
  95.501 -    if (ret) {
  95.502 -        gmyth_debug
  95.503 -            ("[%s] Connection unsucessfull - Couldn't connect to remote host!!!\n",
  95.504 -             __FUNCTION__);
  95.505 -        *err = ret;
  95.506 -        return -1;
  95.507 -    }
  95.508 -
  95.509 -    *err = 0;
  95.510 -    return 0;
  95.511 -}
  95.512 -
  95.513 -/** Connects to the backend.
  95.514 - * 
  95.515 - * @param gmyth_socket The GMythSocket instance.
  95.516 - * @param hostname The backend hostname or IP address.
  95.517 - * @param port The backend port.
  95.518 - * @return TRUE if success, FALSE if error.
  95.519 - */
  95.520 -
  95.521 -
  95.522 -gboolean
  95.523 -gmyth_socket_connect(GMythSocket * gmyth_socket,
  95.524 -                     const gchar * hostname, gint port)
  95.525 -{
  95.526 -    return gmyth_socket_connect_with_timeout(gmyth_socket, hostname, port,
  95.527 -                                             30);
  95.528 -}
  95.529 -
  95.530 -gboolean
  95.531 -gmyth_socket_connect_with_timeout(GMythSocket * gmyth_socket,
  95.532 -                                  const gchar * hostname, gint port,
  95.533 -                                  guint timeout)
  95.534 -{
  95.535 -    struct addrinfo *addr_info_data = NULL,
  95.536 -        *addr_info0 = NULL;
  95.537 -    struct linger   ling;
  95.538 -    gchar          *tmp_str;
  95.539 -    gint            ret_code = 0;   /* -1 */
  95.540 -
  95.541 -    /*
  95.542 -     * FIXME: add as function parameter 
  95.543 -     */
  95.544 -    gint            err;
  95.545 -    gint            errno;
  95.546 -    gboolean        ret = TRUE;
  95.547 -
  95.548 -    gmyth_debug("CONNECTING %s:%d", hostname, port);
  95.549 -
  95.550 -    if (hostname == NULL)
  95.551 -        gmyth_debug("Invalid hostname parameter!\n");
  95.552 -
  95.553 -    /*
  95.554 -     * store hostname and port number 
  95.555 -     */
  95.556 -    gmyth_debug("CONNECTING %s:%d", hostname, port);
  95.557 -
  95.558 -    errno = gmyth_socket_toaddrinfo(hostname, port, &addr_info_data);
  95.559 -
  95.560 -    g_return_val_if_fail(addr_info_data != NULL
  95.561 -                         && hostname != NULL, FALSE);
  95.562 -
  95.563 -    /*
  95.564 -     * hack to avoid deleting the hostname when gmyth_socket->hostname ==
  95.565 -     * hostname 
  95.566 -     */
  95.567 -    tmp_str = gmyth_socket->hostname;
  95.568 -
  95.569 -    gmyth_socket->hostname = g_strdup(hostname);
  95.570 -    gmyth_socket->port = port;
  95.571 -
  95.572 -    g_free(tmp_str);
  95.573 -
  95.574 -    for (addr_info0 = addr_info_data; addr_info0;
  95.575 -         addr_info0 = addr_info_data->ai_next) {
  95.576 -        /*
  95.577 -         * init socket descriptor 
  95.578 -         */
  95.579 -
  95.580 -        g_debug ("FAMILY: %d, TYPE: %d, PROTOCOL: %d", 
  95.581 -                 addr_info0->ai_family,
  95.582 -                 addr_info0->ai_socktype,
  95.583 -                 addr_info0->ai_protocol);
  95.584 -        gmyth_socket->sd =
  95.585 -            socket(addr_info0->ai_family, addr_info0->ai_socktype,
  95.586 -                   addr_info0->ai_protocol);
  95.587 -
  95.588 -        if (gmyth_socket->sd < 0)
  95.589 -            continue;
  95.590 -
  95.591 -        struct timeval *timeout_val = g_new0(struct timeval, 1);
  95.592 -
  95.593 -        if (timeout != 0) {
  95.594 -            timeout_val->tv_sec = timeout;
  95.595 -            timeout_val->tv_usec = 0;
  95.596 -        } else {
  95.597 -            timeout_val->tv_sec = 5;
  95.598 -            timeout_val->tv_usec = 100;
  95.599 -        }
  95.600 -
  95.601 -        if (gmyth_socket_try_connect
  95.602 -            (gmyth_socket->sd, (struct sockaddr *) addr_info0->ai_addr,
  95.603 -             addr_info0->ai_addrlen, timeout_val, &ret_code) < 0) {
  95.604 -            gmyth_debug("[%s] Error connecting to backend!\n",
  95.605 -                        __FUNCTION__);
  95.606 -            if (ret_code == ETIMEDOUT)
  95.607 -                gmyth_debug("[%s]\tBackend host unreachable!\n",
  95.608 -                            __FUNCTION__);
  95.609 -
  95.610 -            close(gmyth_socket->sd);
  95.611 -            gmyth_socket->sd = -1;
  95.612 -            gmyth_debug("ERROR: %s\n", gai_strerror(ret_code));
  95.613 -            g_free(timeout_val);
  95.614 -            continue;
  95.615 -        }
  95.616 -
  95.617 -        g_free(timeout_val);
  95.618 -
  95.619 -        /*
  95.620 -         * only will be reached if none of the error above occurred 
  95.621 -         */
  95.622 -        break;
  95.623 -    }
  95.624 -
  95.625 -    freeaddrinfo(addr_info_data);
  95.626 -    addr_info_data = NULL;
  95.627 -
  95.628 -    if (gmyth_socket->sd_io_ch != NULL) {
  95.629 -        g_io_channel_unref(gmyth_socket->sd_io_ch);
  95.630 -        gmyth_socket->sd_io_ch = NULL;
  95.631 -    }
  95.632 -
  95.633 -
  95.634 -    memset(&ling, 0, sizeof(struct linger));
  95.635 -    ling.l_onoff = TRUE;
  95.636 -    ling.l_linger = 1;
  95.637 -
  95.638 -    err =
  95.639 -        setsockopt(gmyth_socket->sd, SOL_SOCKET, SO_LINGER, &ling,
  95.640 -                   sizeof(struct linger));
  95.641 -
  95.642 -    if (err < 0) {
  95.643 -        gmyth_debug("[%s] Setting connection unsucessfull.\n",
  95.644 -                    __FUNCTION__);
  95.645 -        err = errno;
  95.646 -        ret = FALSE;
  95.647 -        goto cleanup;
  95.648 -    }
  95.649 -
  95.650 -    gmyth_socket->sd_io_ch = g_io_channel_unix_new(gmyth_socket->sd);
  95.651 -
  95.652 -    g_io_channel_set_close_on_unref(gmyth_socket->sd_io_ch, TRUE);
  95.653 -    // g_io_channel_set_encoding (gmyth_socket->sd_io_ch, NULL, NULL );
  95.654 -
  95.655 -    GIOFlags        flags = g_io_channel_get_flags(gmyth_socket->sd_io_ch);
  95.656 -
  95.657 -    /*
  95.658 -     * unset the nonblock flag 
  95.659 -     */
  95.660 -    flags &= ~G_IO_FLAG_NONBLOCK;
  95.661 -    /*
  95.662 -     * unset the nonblocking stuff for some time, because GNUTLS doesn't
  95.663 -     * like that 
  95.664 -     */
  95.665 -    g_io_channel_set_flags(gmyth_socket->sd_io_ch, flags, NULL);
  95.666 -
  95.667 -    ret = (ret_code == 0) ? TRUE : FALSE;
  95.668 -
  95.669 -  cleanup:
  95.670 -    if (!ret)
  95.671 -        gmyth_debug("GMythSocket error - return code error!");
  95.672 -
  95.673 -    return ret;
  95.674 -}
  95.675 -
  95.676 -/** Gets the GIOChannel associated to the given GMythSocket.
  95.677 - * 
  95.678 - * @param gmyth_socket The GMythSocket instance.
  95.679 - */
  95.680 -GIOChannel     *
  95.681 -gmyth_socket_get_io_channel(GMythSocket * gmyth_socket)
  95.682 -{
  95.683 -    g_return_val_if_fail(gmyth_socket != NULL, NULL);
  95.684 -
  95.685 -    return gmyth_socket->sd_io_ch;
  95.686 -}
  95.687 -
  95.688 -/** Verifies if the socket is able to read.
  95.689 - * 
  95.690 - * @param gmyth_socket The GMythSocket instance.
  95.691 - * @return TRUE if the socket is able to read, FALSE if not.
  95.692 - */
  95.693 -gboolean
  95.694 -gmyth_socket_is_able_to_read(GMythSocket * gmyth_socket)
  95.695 -{
  95.696 -    gboolean        ret = TRUE;
  95.697 -
  95.698 -    /*
  95.699 -     * verify if the input (read) buffer is ready to receive data 
  95.700 -     */
  95.701 -    GIOCondition    io_cond =
  95.702 -        g_io_channel_get_buffer_condition(gmyth_socket->sd_io_ch);
  95.703 -
  95.704 -    if ((io_cond & G_IO_IN) == 0) {
  95.705 -        gmyth_debug("[%s] IO channel is not able to send data!\n",
  95.706 -                    __FUNCTION__);
  95.707 -        ret = FALSE;
  95.708 -    }
  95.709 -
  95.710 -    return ret;
  95.711 -
  95.712 -}
  95.713 -
  95.714 -/** Verifies if the socket is able to write.
  95.715 - * 
  95.716 - * @param gmyth_socket The GMythSocket instance.
  95.717 - * @return TRUE if the socket is able to write, FALSE if not.
  95.718 - */
  95.719 -gboolean
  95.720 -gmyth_socket_is_able_to_write(GMythSocket * gmyth_socket)
  95.721 -{
  95.722 -    gboolean        ret = TRUE;
  95.723 -
  95.724 -    /*
  95.725 -     * verify if the input (read) buffer is ready to receive data 
  95.726 -     */
  95.727 -    GIOCondition    io_cond =
  95.728 -        g_io_channel_get_buffer_condition(gmyth_socket->sd_io_ch);
  95.729 -
  95.730 -    if (((io_cond & G_IO_OUT) == 0) || ((io_cond & G_IO_HUP) == 0)) {
  95.731 -        gmyth_debug("[%s] IO channel is not able to send data!\n",
  95.732 -                    __FUNCTION__);
  95.733 -        ret = FALSE;
  95.734 -    }
  95.735 -
  95.736 -    return ret;
  95.737 -
  95.738 -}
  95.739 -
  95.740 -/** Sends a command to the backend.
  95.741 - * 
  95.742 - * @param gmyth_socket the GMythSocket instance.
  95.743 - * @param command The string command to be sent.
  95.744 - */
  95.745 -gboolean
  95.746 -gmyth_socket_send_command(GMythSocket * gmyth_socket, GString * command)
  95.747 -{
  95.748 -    gboolean        ret = TRUE;
  95.749 -
  95.750 -    GIOStatus       io_status = G_IO_STATUS_NORMAL;
  95.751 -
  95.752 -    // GIOCondition io_cond;
  95.753 -    GError         *error = NULL;
  95.754 -
  95.755 -    gchar          *buffer = NULL;
  95.756 -
  95.757 -    gsize           bytes_written = 0;
  95.758 -
  95.759 -    g_return_val_if_fail(gmyth_socket->sd_io_ch != NULL, FALSE);
  95.760 -
  95.761 -    if (command == NULL || (command->len <= 0) || command->str == NULL) {
  95.762 -        gmyth_debug("[%s] Invalid NULL command parameter!\n",
  95.763 -                    __FUNCTION__);
  95.764 -        ret = FALSE;
  95.765 -        goto done;
  95.766 -    }
  95.767 -
  95.768 -    g_mutex_lock(gmyth_socket->mutex);
  95.769 -    gmyth_debug("Sending command to backend: %s\n", command->str);
  95.770 -
  95.771 -    buffer = g_strnfill(BUFLEN, ' ');
  95.772 -    g_snprintf(buffer, MYTH_PROTOCOL_FIELD_SIZE + 1, "%-8d", command->len);
  95.773 -
  95.774 -    command = g_string_prepend(command, buffer);
  95.775 -
  95.776 -    /*
  95.777 -     * write bytes to socket 
  95.778 -     */
  95.779 -    io_status =
  95.780 -        g_io_channel_write_chars(gmyth_socket->sd_io_ch, command->str,
  95.781 -                                 command->len, &bytes_written, &error);
  95.782 -
  95.783 -
  95.784 -    if ((io_status == G_IO_STATUS_ERROR) || (bytes_written <= 0)) {
  95.785 -        gmyth_debug("[%s] Error while writing to socket", __FUNCTION__);
  95.786 -        ret = FALSE;
  95.787 -    } else if (bytes_written < command->len) {
  95.788 -        gmyth_debug("[%s] Not all data was written socket", __FUNCTION__);
  95.789 -        ret = FALSE;
  95.790 -    }
  95.791 -
  95.792 -    io_status = g_io_channel_flush(gmyth_socket->sd_io_ch, &error);
  95.793 -
  95.794 -    if ((bytes_written != command->len)
  95.795 -        || (io_status == G_IO_STATUS_ERROR)) {
  95.796 -        gmyth_debug
  95.797 -            ("[%s] Some problem occurred when sending data to the socket\n",
  95.798 -             __FUNCTION__);
  95.799 -
  95.800 -        ret = TRUE;
  95.801 -    }
  95.802 -
  95.803 -    g_mutex_unlock(gmyth_socket->mutex);
  95.804 -  done:
  95.805 -    if (error != NULL) {
  95.806 -        gmyth_debug
  95.807 -            ("[%s] Error found reading data from IO channel: (%d, %s)\n",
  95.808 -             __FUNCTION__, error->code, error->message);
  95.809 -        ret = FALSE;
  95.810 -        g_error_free(error);
  95.811 -    }
  95.812 -
  95.813 -    if (buffer != NULL)
  95.814 -        g_free(buffer);
  95.815 -
  95.816 -    return ret;
  95.817 -}
  95.818 -
  95.819 -/** Starts Mythtv protocol level connection. Checks Mythtv protocol version
  95.820 - * supported by the backend and send the "ANN" command.
  95.821 - * 
  95.822 - * @param gmyth_socket the GMythSocket instance.
  95.823 - * @param hostname_backend The backend hostname or IP address.
  95.824 - * @param port The backend port to connect.
  95.825 - * @param blocking_client A flag to choose between blocking and non-blocking
  95.826 - * @param with_events	Sets the connection flag to receive events.
  95.827 - * 										backend connection. 
  95.828 - */
  95.829 -static          gboolean
  95.830 -gmyth_socket_connect_to_backend_and_events(GMythSocket * gmyth_socket,
  95.831 -                                           const gchar * hostname_backend,
  95.832 -                                           gint port,
  95.833 -                                           gboolean blocking_client,
  95.834 -                                           gboolean with_events)
  95.835 -{
  95.836 -    if (!gmyth_socket_connect(gmyth_socket, hostname_backend, port)) {
  95.837 -        gmyth_debug("[%s] Could not open socket to backend machine [%s]\n",
  95.838 -                    __FUNCTION__, hostname_backend);
  95.839 -        return FALSE;
  95.840 -    }
  95.841 -
  95.842 -    if (gmyth_socket_check_protocol_version(gmyth_socket)) {
  95.843 -        GString        *result;
  95.844 -        GString        *base_str = g_string_new("");
  95.845 -        GString        *hostname = NULL;
  95.846 -
  95.847 -        hostname = gmyth_socket_get_local_hostname();
  95.848 -        if (hostname == NULL) {
  95.849 -            gmyth_debug
  95.850 -                ("Hostname not available, setting to n800frontend\n");
  95.851 -            hostname = g_string_new("n800frontend");
  95.852 -        }
  95.853 -
  95.854 -        g_string_printf(base_str, "ANN %s %s %u",
  95.855 -                        (blocking_client ? "Playback" : "Monitor"),
  95.856 -                        hostname->str, with_events);
  95.857 -
  95.858 -        gmyth_socket_send_command(gmyth_socket, base_str);
  95.859 -        result = gmyth_socket_receive_response(gmyth_socket);
  95.860 -
  95.861 -        if (result != NULL) {
  95.862 -            gmyth_debug("Response received from backend: %s", result->str);
  95.863 -            g_string_free(result, TRUE);
  95.864 -        }
  95.865 -
  95.866 -        g_string_free(hostname, TRUE);
  95.867 -        g_string_free(base_str, TRUE);
  95.868 -
  95.869 -        return TRUE;
  95.870 -    } else {
  95.871 -        gmyth_debug("[%s] GMythSocket could not connect to the backend",
  95.872 -                    __FUNCTION__);
  95.873 -        return FALSE;
  95.874 -    }
  95.875 -}
  95.876 -
  95.877 -/** Starts Mythtv protocol level connection. Checks Mythtv protocol version
  95.878 - * supported by the backend and send the "ANN" command.
  95.879 - * 
  95.880 - * @param gmyth_socket the GMythSocket instance.
  95.881 - * @param hostname_backend The backend hostname or IP address.
  95.882 - * @param port The backend port to connect.
  95.883 - * @param blocking_client A flag to choose between blocking and non-blocking 
  95.884 - */
  95.885 -gboolean
  95.886 -gmyth_socket_connect_to_backend(GMythSocket * gmyth_socket,
  95.887 -                                const gchar * hostname_backend, gint port,
  95.888 -                                gboolean blocking_client)
  95.889 -{
  95.890 -    if (!gmyth_socket_connect_to_backend_and_events
  95.891 -        (gmyth_socket, hostname_backend, port, blocking_client, FALSE)) {
  95.892 -        gmyth_debug("Could not open socket to backend machine [%s]\n",
  95.893 -                    hostname_backend);
  95.894 -        return FALSE;
  95.895 -    }
  95.896 -
  95.897 -    return TRUE;
  95.898 -
  95.899 -}
  95.900 -
  95.901 -/** Starts Mythtv protocol level connection. Checks Mythtv protocol version
  95.902 - * supported by the backend and send the "ANN" command.
  95.903 - * 
  95.904 - * @param gmyth_socket the GMythSocket instance.
  95.905 - * @param hostname_backend The backend hostname or IP address.
  95.906 - * @param port The backend port to connect.
  95.907 - * @param blocking_client A flag to choose between blocking and non-blocking 
  95.908 - */
  95.909 -gboolean
  95.910 -gmyth_socket_connect_to_backend_events(GMythSocket * gmyth_socket,
  95.911 -                                       const gchar * hostname_backend,
  95.912 -                                       gint port, gboolean blocking_client)
  95.913 -{
  95.914 -    if (!gmyth_socket_connect_to_backend_and_events
  95.915 -        (gmyth_socket, hostname_backend, port, blocking_client, TRUE)) {
  95.916 -        gmyth_debug
  95.917 -            ("Could not open socket to backend machine in order to receive events [%s]\n",
  95.918 -             hostname_backend);
  95.919 -        return FALSE;
  95.920 -    }
  95.921 -
  95.922 -    return TRUE;
  95.923 -}
  95.924 -
  95.925 -/** Closes the socket connection to the backend.
  95.926 - * 
  95.927 - * @param gmyth_socket The GMythSocket instance.
  95.928 - */
  95.929 -void
  95.930 -gmyth_socket_close_connection(GMythSocket * gmyth_socket)
  95.931 -{
  95.932 -    /*
  95.933 -     * if ( gmyth_socket->sd != -1 ) { close (gmyth_socket->sd);
  95.934 -     * gmyth_socket->sd = -1; } 
  95.935 -     */
  95.936 -
  95.937 -    if (gmyth_socket->sd_io_ch != NULL) {
  95.938 -        g_io_channel_shutdown(gmyth_socket->sd_io_ch, TRUE, NULL);
  95.939 -        g_io_channel_unref(gmyth_socket->sd_io_ch);
  95.940 -        gmyth_socket->sd_io_ch = NULL;
  95.941 -        gmyth_socket->sd = -1;
  95.942 -    }
  95.943 -
  95.944 -}
  95.945 -
  95.946 -
  95.947 -/** Try the MythTV version numbers, and get the version returned by
  95.948 - * the possible REJECT message, in order to contruct a new
  95.949 - * MythTV version request.
  95.950 - * 
  95.951 - * @param gmyth_socket The GMythSocket instance.
  95.952 - * @param mythtv_version The Mythtv protocol version to be tested
  95.953 - * 
  95.954 - * @return The actual MythTV the client is connected to.
  95.955 - */
  95.956 -gint
  95.957 -gmyth_socket_check_protocol_version_number(GMythSocket * gmyth_socket,
  95.958 -                                           gint mythtv_version)
  95.959 -{
  95.960 -    GString        *response = NULL;
  95.961 -    GString        *payload = NULL;
  95.962 -    gboolean        res = TRUE;
  95.963 -    gint            mythtv_new_version = MYTHTV_CANNOT_NEGOTIATE_VERSION;
  95.964 -    guint           max_iterations = MYTHTV_MAX_VERSION_CHECKS;
  95.965 -
  95.966 -    assert(gmyth_socket);
  95.967 -
  95.968 -  try_new_version:
  95.969 -    payload = g_string_new("MYTH_PROTO_VERSION");
  95.970 -    g_string_append_printf(payload, " %d", mythtv_version);
  95.971 -
  95.972 -    gmyth_socket_send_command(gmyth_socket, payload);
  95.973 -    response = gmyth_socket_receive_response(gmyth_socket);
  95.974 -
  95.975 -    if (response == NULL) {
  95.976 -        gmyth_debug("[%s] Check protocol version error! Not answered!",
  95.977 -                    __FUNCTION__);
  95.978 -        res = FALSE;
  95.979 -        goto done;
  95.980 -    }
  95.981 -
  95.982 -    res = g_str_has_prefix(response->str, "ACCEPT");
  95.983 -    if (!res) {
  95.984 -        gmyth_debug("[%s] Protocol version request error: %s",
  95.985 -                    __FUNCTION__, response->str);
  95.986 -        /*
  95.987 -         * get the version number returned by the REJECT message 
  95.988 -         */
  95.989 -        if ((res = g_str_has_prefix(response->str, "REJECT")) == TRUE) {
  95.990 -            gchar          *new_version = NULL;
  95.991 -
  95.992 -            new_version = g_strrstr(response->str, "]");
  95.993 -            if (new_version != NULL) {
  95.994 -                ++new_version;  /* skip ']' character */
  95.995 -                if (new_version != NULL) {
  95.996 -                    gmyth_debug("[%s] got MythTV version = %s.\n",
  95.997 -                                __FUNCTION__, new_version);
  95.998 -                    mythtv_version =
  95.999 -                        (gint) g_ascii_strtoull(new_version, NULL, 10);
 95.1000 -                    /*
 95.1001 -                     * do reconnection to the socket (socket is closed if
 95.1002 -                     * the MythTV version was wrong) 
 95.1003 -                     */
 95.1004 -                    gmyth_socket_connect(gmyth_socket,
 95.1005 -                                         gmyth_socket->hostname,
 95.1006 -                                         gmyth_socket->port);
 95.1007 -                    new_version = NULL;
 95.1008 -                    if (--max_iterations > 0) {
 95.1009 -                        g_string_free(payload, TRUE);
 95.1010 -                        g_string_free(response, TRUE);
 95.1011 -                        goto try_new_version;
 95.1012 -                    } else
 95.1013 -                        goto done;
 95.1014 -                }
 95.1015 -            }
 95.1016 -        }
 95.1017 -    }
 95.1018 -
 95.1019 -    /*
 95.1020 -     * change the return value to a valid one 
 95.1021 -     */
 95.1022 -    if (res) {
 95.1023 -        mythtv_new_version = mythtv_version;
 95.1024 -        gmyth_socket->mythtv_version = mythtv_new_version;
 95.1025 -    }
 95.1026 -
 95.1027 -  done:
 95.1028 -    g_string_free(payload, TRUE);
 95.1029 -    g_string_free(response, TRUE);
 95.1030 -
 95.1031 -    return mythtv_new_version;
 95.1032 -}
 95.1033 -
 95.1034 -/** Verifies if the Mythtv backend supported the GMyth supported version.
 95.1035 - * 
 95.1036 - * @param gmyth_socket The GMythSocket instance.
 95.1037 - * @return TRUE if supports, FALSE if not.
 95.1038 - */
 95.1039 -gboolean
 95.1040 -gmyth_socket_check_protocol_version(GMythSocket * gmyth_socket)
 95.1041 -{
 95.1042 -    return ((gmyth_socket->mythtv_version =
 95.1043 -             gmyth_socket_check_protocol_version_number(gmyth_socket,
 95.1044 -                                                        MYTHTV_VERSION_DEFAULT))
 95.1045 -            != MYTHTV_CANNOT_NEGOTIATE_VERSION);
 95.1046 -}
 95.1047 -
 95.1048 -/** Returns the Mythtv backend supported version.
 95.1049 - * 
 95.1050 - * @param gmyth_socket The GMythSocket instance.
 95.1051 - * @return The actual MythTV version number.
 95.1052 - */
 95.1053 -gint
 95.1054 -gmyth_socket_get_protocol_version(GMythSocket * gmyth_socket)
 95.1055 -{
 95.1056 -    return gmyth_socket->mythtv_version;
 95.1057 -}
 95.1058 -
 95.1059 -/** Receives a backend answer after a gmyth_socket_send_command_call ().
 95.1060 - * 
 95.1061 - * @param gmyth_socket The GMythSocket instance.
 95.1062 - * @return The response received, or NULL if error or nothing was received.
 95.1063 - */
 95.1064 -GString        *
 95.1065 -gmyth_socket_receive_response(GMythSocket * gmyth_socket)
 95.1066 -{
 95.1067 -    GIOStatus       io_status = G_IO_STATUS_NORMAL;
 95.1068 -    GError         *error = NULL;
 95.1069 -    gchar          *buffer = NULL;
 95.1070 -
 95.1071 -    GString        *str = NULL;
 95.1072 -
 95.1073 -    gsize           bytes_read = 0;
 95.1074 -    gint            len = 0;
 95.1075 -
 95.1076 -    if (gmyth_socket == NULL)
 95.1077 -        return NULL;
 95.1078 -
 95.1079 -    GIOCondition    io_cond;
 95.1080 -
 95.1081 -    /*
 95.1082 -     * verify if the input (read) buffer is ready to receive data
 95.1083 -     */
 95.1084 -    g_mutex_lock(gmyth_socket->mutex);
 95.1085 -
 95.1086 -    buffer = g_strnfill(MYTH_PROTOCOL_FIELD_SIZE, ' ');
 95.1087 -    if (NULL == gmyth_socket->sd_io_ch) {
 95.1088 -        gmyth_socket_connect(gmyth_socket, gmyth_socket->hostname,
 95.1089 -                             gmyth_socket->port);
 95.1090 -    }
 95.1091 -
 95.1092 -    io_cond = g_io_channel_get_buffer_condition(gmyth_socket->sd_io_ch);
 95.1093 -    /*
 95.1094 -     * if ( NULL == gmyth_socket->sd_io_ch->read_buf || ( NULL ==
 95.1095 -     * gmyth_socket->sd_io_ch->read_buf->str ) ) gmyth_socket->sd_io_ch =
 95.1096 -     * g_io_channel_unix_new( gmyth_socket->sd );
 95.1097 -     */
 95.1098 -
 95.1099 -    if (gmyth_socket->sd_io_ch->is_readable /* && !( ( io_cond & G_IO_IN )
 95.1100 -                                             * == 0 ) */ )
 95.1101 -        io_status =
 95.1102 -            g_io_channel_read_chars(gmyth_socket->sd_io_ch, buffer,
 95.1103 -                                    MYTH_PROTOCOL_FIELD_SIZE, &bytes_read,
 95.1104 -                                    &error);
 95.1105 -    else
 95.1106 -        return g_string_new("");
 95.1107 -
 95.1108 -    /*
 95.1109 -     * verify if the input (read) buffer is ready to receive data 
 95.1110 -     */
 95.1111 -    io_cond = g_io_channel_get_buffer_condition(gmyth_socket->sd_io_ch);
 95.1112 -
 95.1113 -    // if ( ( io_cond & G_IO_IN ) == 0 ) 
 95.1114 -    // return NULL; 
 95.1115 -
 95.1116 -    gmyth_debug("[%s] Bytes read = %d\n", __FUNCTION__, bytes_read);
 95.1117 -
 95.1118 -    if ((io_status == G_IO_STATUS_ERROR) || (bytes_read <= 0)) {
 95.1119 -        gmyth_debug("[%s] Error in mythprotocol response from backend\n",
 95.1120 -                    __FUNCTION__);
 95.1121 -        str = NULL;
 95.1122 -        // return NULL;
 95.1123 -    } else if (buffer != NULL && strlen(buffer) > 0) {
 95.1124 -
 95.1125 -        // io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error
 95.1126 -        // );
 95.1127 -        /*
 95.1128 -         * verify if the input (read) buffer is ready to receive data 
 95.1129 -         */
 95.1130 -        // io_cond = g_io_channel_get_buffer_condition(
 95.1131 -        // gmyth_socket->sd_io_ch );
 95.1132 -
 95.1133 -        // if ( ( io_cond & G_IO_IN ) != 0 ) {
 95.1134 -        // gchar *buffer_aux = NULL;
 95.1135 -
 95.1136 -        /*
 95.1137 -         * removes trailing whitespace 
 95.1138 -         */
 95.1139 -        // buffer_aux = g_strstrip (buffer);
 95.1140 -        len = (gint) g_ascii_strtoull(g_strstrip(buffer), NULL, 10);
 95.1141 -
 95.1142 -        g_free(buffer);
 95.1143 -
 95.1144 -        /*
 95.1145 -         * if (buffer_aux != NULL) { g_free (buffer_aux); buffer_aux =
 95.1146 -         * NULL; } 
 95.1147 -         */
 95.1148 -
 95.1149 -        buffer = g_new0(gchar, len + 1);
 95.1150 -
 95.1151 -        bytes_read = 0;
 95.1152 -        if (!(gmyth_socket != NULL && gmyth_socket->sd_io_ch != NULL))
 95.1153 -            return NULL;
 95.1154 -
 95.1155 -        if (gmyth_socket->sd_io_ch->is_readable)
 95.1156 -            io_status =
 95.1157 -                g_io_channel_read_chars(gmyth_socket->sd_io_ch, buffer,
 95.1158 -                                        len, &bytes_read, &error);
 95.1159 -        else
 95.1160 -            return g_string_new("");
 95.1161 -
 95.1162 -        buffer[bytes_read] = '\0';
 95.1163 -        // }
 95.1164 -    }
 95.1165 -
 95.1166 -    g_mutex_unlock(gmyth_socket->mutex);
 95.1167 -    // g_static_rw_lock_reader_unlock (&rwlock);
 95.1168 -
 95.1169 -    gmyth_debug("Response received from backend: ----- {%s}\n", buffer);
 95.1170 -    if ((bytes_read != len) || (io_status == G_IO_STATUS_ERROR))
 95.1171 -        str = NULL;
 95.1172 -    else
 95.1173 -        str = g_string_new(buffer);
 95.1174 -
 95.1175 -    if (error != NULL) {
 95.1176 -        gmyth_debug
 95.1177 -            ("[%s] Error found receiving response from the IO channel: (%d, %s)\n",
 95.1178 -             __FUNCTION__, error->code, error->message);
 95.1179 -        str = NULL;
 95.1180 -        g_error_free(error);
 95.1181 -    }
 95.1182 -
 95.1183 -    g_free(buffer);
 95.1184 -    return str;
 95.1185 -}
 95.1186 -
 95.1187 -/** Format a Mythtv command from the str_list entries and send it to backend.
 95.1188 - * 
 95.1189 - * @param gmyth_socket The GMythSocket instance.
 95.1190 - * @param str_list The string list to form the command
 95.1191 - * @return TRUE if command was sent, FALSE if any error happens.
 95.1192 - */
 95.1193 -gboolean
 95.1194 -gmyth_socket_write_stringlist(GMythSocket * gmyth_socket,
 95.1195 -                              GMythStringList * str_list)
 95.1196 -{
 95.1197 -
 95.1198 -    GList          *tmp_list = NULL;
 95.1199 -    GPtrArray      *ptr_array = NULL;
 95.1200 -    gchar          *str_array = NULL;
 95.1201 -
 95.1202 -    g_mutex_lock(gmyth_socket->mutex);
 95.1203 -    // g_static_rw_lock_writer_lock (&rwlock);
 95.1204 -
 95.1205 -    ptr_array = g_ptr_array_sized_new(g_list_length(str_list->glist));
 95.1206 -
 95.1207 -    // FIXME: change this implementation!
 95.1208 -    tmp_list = str_list->glist;
 95.1209 -    for (; tmp_list; tmp_list = tmp_list->next) {
 95.1210 -        if (tmp_list->data != NULL) {
 95.1211 -            g_ptr_array_add(ptr_array, ((GString *) tmp_list->data)->str);
 95.1212 -        } else {
 95.1213 -            g_ptr_array_add(ptr_array, "");
 95.1214 -        }
 95.1215 -    }
 95.1216 -    g_ptr_array_add(ptr_array, NULL);   // g_str_joinv() needs a NULL
 95.1217 -    // terminated string
 95.1218 -
 95.1219 -    str_array = g_strjoinv(MYTH_SEPARATOR, (gchar **) (ptr_array->pdata));
 95.1220 -
 95.1221 -    g_mutex_unlock(gmyth_socket->mutex);
 95.1222 -    // g_static_rw_lock_writer_unlock (&rwlock);
 95.1223 -
 95.1224 -    gmyth_debug("[%s] Sending socket request: %s\n", __FUNCTION__,
 95.1225 -                str_array);
 95.1226 -
 95.1227 -    // Sends message to backend 
 95.1228 -    // TODO: implement looping to send remaining data, and add timeout
 95.1229 -    // testing! 
 95.1230 -    GString        *command = g_string_new(str_array);
 95.1231 -
 95.1232 -    gmyth_socket_send_command(gmyth_socket, command);
 95.1233 -
 95.1234 -    g_string_free(command, TRUE);
 95.1235 -
 95.1236 -    g_free(str_array);
 95.1237 -
 95.1238 -    /*
 95.1239 -     * ptr_array is pointing to data inside str_list->glist 
 95.1240 -     */
 95.1241 -    g_ptr_array_free(ptr_array, TRUE);
 95.1242 -
 95.1243 -    return TRUE;
 95.1244 -}
 95.1245 -
 95.1246 -/*
 95.1247 - * Receives a backend command response and split it into the given string
 95.1248 - * list. @param gmyth_socket The GMythSocket instance. @param str_list
 95.1249 - * the string list to be filled. @return The number of received strings. 
 95.1250 - */
 95.1251 -gint
 95.1252 -gmyth_socket_read_stringlist(GMythSocket * gmyth_socket,
 95.1253 -                             GMythStringList * str_list)
 95.1254 -{
 95.1255 -    GString        *response;
 95.1256 -    gint            i;
 95.1257 -
 95.1258 -    gmyth_string_list_clear_all(str_list);
 95.1259 -
 95.1260 -    response = gmyth_socket_receive_response(gmyth_socket);
 95.1261 -    if (response != NULL && response->str != NULL && response->len > 0) {
 95.1262 -        gchar         **str_array;
 95.1263 -
 95.1264 -        g_mutex_lock(gmyth_socket->mutex);
 95.1265 -
 95.1266 -        str_array = g_strsplit(response->str, MYTH_SEPARATOR, -1);
 95.1267 -
 95.1268 -        for (i = 0; i < g_strv_length(str_array); i++) {
 95.1269 -            // if ( str_array[i] != NULL && strlen( str_array[i] ) > 0 )
 95.1270 -            gmyth_string_list_append_char_array(str_list, str_array[i]);
 95.1271 -        }
 95.1272 -
 95.1273 -        g_mutex_unlock(gmyth_socket->mutex);
 95.1274 -        g_strfreev(str_array);
 95.1275 -    }
 95.1276 -
 95.1277 -    g_string_free(response, TRUE);
 95.1278 -
 95.1279 -    return gmyth_string_list_length(str_list);
 95.1280 -}
 95.1281 -
 95.1282 -/** Formats a Mythtv protocol command based on str_list and sends it to
 95.1283 - * the connected backend. The backend response is overwritten into str_list.
 95.1284 - *
 95.1285 - * @param gmyth_socket The GMythSocket instance.
 95.1286 - * @param str_list The string list to be sent, and on which the answer 
 95.1287 - * will be written.
 95.1288 - * @return TRUE if command was sent and an answer was received, FALSE if any
 95.1289 - * error happens.
 95.1290 - */
 95.1291 -gint
 95.1292 -gmyth_socket_sendreceive_stringlist(GMythSocket * gmyth_socket,
 95.1293 -                                    GMythStringList * str_list)
 95.1294 -{
 95.1295 -    gmyth_socket_write_stringlist(gmyth_socket, str_list);
 95.1296 -
 95.1297 -    return gmyth_socket_read_stringlist(gmyth_socket, str_list);
 95.1298 -}
    96.1 --- a/gmyth/src/gmyth_socket.h	Mon Feb 25 17:45:36 2008 +0000
    96.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.3 @@ -1,147 +0,0 @@
    96.4 -/**
    96.5 - * GMyth Library
    96.6 - *
    96.7 - * @file gmyth/gmyth_socket.h
    96.8 - * 
    96.9 - * @brief <p> MythTV socket implementation, according to the MythTV Project
   96.10 - * (www.mythtv.org). 
   96.11 - * 
   96.12 - * This component provides basic socket functionalities to interact with
   96.13 - * the Mythtv backend.
   96.14 - * <p>
   96.15 - *
   96.16 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   96.17 - * @author Rosfran Lins Borges <rosfran.borges@indt.org.br> 
   96.18 - *
   96.19 - * 
   96.20 - * This program is free software; you can redistribute it and/or modify
   96.21 - * it under the terms of the GNU Lesser General Public License as published by
   96.22 - * the Free Software Foundation; either version 2 of the License, or
   96.23 - * (at your option) any later version.
   96.24 - *
   96.25 - * This program is distributed in the hope that it will be useful,
   96.26 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   96.27 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   96.28 - * GNU General Public License for more details.
   96.29 - *
   96.30 - * You should have received a copy of the GNU Lesser General Public License
   96.31 - * along with this program; if not, write to the Free Software
   96.32 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   96.33 - */
   96.34 -
   96.35 -#ifndef __GMYTH_SOCKET_H__
   96.36 -#define __GMYTH_SOCKET_H__
   96.37 -
   96.38 -#include <glib-object.h>
   96.39 -
   96.40 -#include <string.h>
   96.41 -#include <netdb.h>
   96.42 -#include <sys/socket.h>
   96.43 -#include <unistd.h>
   96.44 -#include <glib.h>
   96.45 -
   96.46 -#include "gmyth_stringlist.h"
   96.47 -
   96.48 -G_BEGIN_DECLS
   96.49 -#define GMYTH_SOCKET_TYPE               (gmyth_socket_get_type ())
   96.50 -#define GMYTH_SOCKET(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_SOCKET_TYPE, GMythSocket))
   96.51 -#define GMYTH_SOCKET_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE, GMythSocketClass))
   96.52 -#define IS_GMYTH_SOCKET(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_SOCKET_TYPE))
   96.53 -#define IS_GMYTH_SOCKET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_SOCKET_TYPE))
   96.54 -#define GMYTH_SOCKET_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_SOCKET_TYPE, GMythSocketClass))
   96.55 -typedef struct _GMythSocket GMythSocket;
   96.56 -typedef struct _GMythSocketClass GMythSocketClass;
   96.57 -
   96.58 -struct _GMythSocketClass {
   96.59 -    GObjectClass    parent_class;
   96.60 -
   96.61 -    /*
   96.62 -     * callbacks 
   96.63 -     */
   96.64 -    /*
   96.65 -     * no one for now 
   96.66 -     */
   96.67 -};
   96.68 -
   96.69 -struct _GMythSocket {
   96.70 -    GObject         parent;
   96.71 -
   96.72 -    GMutex         *mutex;
   96.73 -
   96.74 -    /*
   96.75 -     * socket descriptor 
   96.76 -     */
   96.77 -    gint            sd;
   96.78 -    GIOChannel     *sd_io_ch;
   96.79 -
   96.80 -    gchar          *hostname;
   96.81 -    gint            port;
   96.82 -    gint            mythtv_version;
   96.83 -};
   96.84 -
   96.85 -/*
   96.86 - * used when no protocol version number was negotiated 
   96.87 - */
   96.88 -#define	MYTHTV_CANNOT_NEGOTIATE_VERSION		0
   96.89 -
   96.90 -GType           gmyth_socket_get_type(void);
   96.91 -
   96.92 -GMythSocket    *gmyth_socket_new();
   96.93 -
   96.94 -GIOChannel     *gmyth_socket_get_io_channel(GMythSocket * gmyth_socket);
   96.95 -
   96.96 -gboolean        gmyth_socket_is_able_to_read(GMythSocket * gmyth_socket);
   96.97 -gboolean        gmyth_socket_is_able_to_write(GMythSocket * gmyth_socket);
   96.98 -
   96.99 -gboolean        gmyth_socket_send_command(GMythSocket * gmyth_socket,
  96.100 -                                          GString * command);
  96.101 -GString        *gmyth_socket_receive_response(GMythSocket * gmyth_socket);
  96.102 -gint            gmyth_socket_sendreceive_stringlist(GMythSocket *
  96.103 -                                                    gmyth_socket,
  96.104 -                                                    GMythStringList *
  96.105 -                                                    str_list);
  96.106 -
  96.107 -gboolean        gmyth_socket_connect(GMythSocket * gmyth_socket,
  96.108 -                                     const gchar * hostname, gint port);
  96.109 -gboolean        gmyth_socket_connect_with_timeout(GMythSocket *
  96.110 -                                                  gmyth_socket,
  96.111 -                                                  const gchar * hostname,
  96.112 -                                                  gint port,
  96.113 -                                                  guint timeout);
  96.114 -
  96.115 -gboolean        gmyth_socket_connect_to_backend(GMythSocket * gmyth_socket,
  96.116 -                                                const gchar *
  96.117 -                                                hostname_backend,
  96.118 -                                                gint port,
  96.119 -                                                gboolean blocking_client);
  96.120 -
  96.121 -gboolean        gmyth_socket_connect_to_backend_events(GMythSocket *
  96.122 -                                                       gmyth_socket,
  96.123 -                                                       const gchar *
  96.124 -                                                       hostname_backend,
  96.125 -                                                       gint port,
  96.126 -                                                       gboolean
  96.127 -                                                       blocking_client);
  96.128 -
  96.129 -gchar          *gmyth_socket_get_primary_addr(void);
  96.130 -
  96.131 -GString        *gmyth_socket_get_local_hostname(void);
  96.132 -
  96.133 -void            gmyth_socket_close_connection(GMythSocket * gmyth_socket);
  96.134 -
  96.135 -gboolean        gmyth_socket_check_protocol_version(GMythSocket *
  96.136 -                                                    gmyth_socket);
  96.137 -gint            gmyth_socket_check_protocol_version_number(GMythSocket *
  96.138 -                                                           gmyth_socket,
  96.139 -                                                           gint
  96.140 -                                                           mythtv_version);
  96.141 -
  96.142 -gint            gmyth_socket_get_protocol_version(GMythSocket *
  96.143 -                                                  gmyth_socket);
  96.144 -
  96.145 -gboolean        gmyth_socket_write_stringlist(GMythSocket * gmyth_socket,
  96.146 -                                              GMythStringList * str_list);
  96.147 -gint            gmyth_socket_read_stringlist(GMythSocket * gmyth_socket,
  96.148 -                                             GMythStringList * str_list);
  96.149 -G_END_DECLS
  96.150 -#endif                          /* __GMYTH_SOCKET_H__ */
    97.1 --- a/gmyth/src/gmyth_stringlist.c	Mon Feb 25 17:45:36 2008 +0000
    97.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.3 @@ -1,454 +0,0 @@
    97.4 -/**
    97.5 - * GMyth Library
    97.6 - *
    97.7 - * @file gmyth/gmyth_stringlist.c
    97.8 - * 
    97.9 - * @brief <p> This component contains functions for dealing with the stringlist
   97.10 - * format of the mythprotocol.
   97.11 - * 
   97.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   97.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   97.14 - *
   97.15 - * 
   97.16 - * This program is free software; you can redistribute it and/or modify
   97.17 - * it under the terms of the GNU Lesser General Public License as published by
   97.18 - * the Free Software Foundation; either version 2 of the License, or
   97.19 - * (at your option) any later version.
   97.20 - *
   97.21 - * This program is distributed in the hope that it will be useful,
   97.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   97.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   97.24 - * GNU General Public License for more details.
   97.25 - *
   97.26 - * You should have received a copy of the GNU Lesser General Public License
   97.27 - * along with this program; if not, write to the Free Software
   97.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   97.29 - */
   97.30 -
   97.31 -#ifdef HAVE_CONFIG_H
   97.32 -#include "config.h"
   97.33 -#endif
   97.34 -
   97.35 -#include "gmyth_stringlist.h"
   97.36 -
   97.37 -#include "gmyth_debug.h"
   97.38 -
   97.39 -static void     gmyth_string_list_class_init(GMythStringListClass * klass);
   97.40 -static void     gmyth_string_list_init(GMythStringList * object);
   97.41 -
   97.42 -static void     gmyth_string_list_dispose(GObject * object);
   97.43 -static void     gmyth_string_list_finalize(GObject * object);
   97.44 -
   97.45 -G_DEFINE_TYPE(GMythStringList, gmyth_string_list, G_TYPE_OBJECT)
   97.46 -    static void     gmyth_string_list_class_init(GMythStringListClass *
   97.47 -                                                 klass)
   97.48 -{
   97.49 -    GObjectClass   *gobject_class;
   97.50 -
   97.51 -    gobject_class = (GObjectClass *) klass;
   97.52 -
   97.53 -    gobject_class->dispose = gmyth_string_list_dispose;
   97.54 -    gobject_class->finalize = gmyth_string_list_finalize;
   97.55 -}
   97.56 -
   97.57 -static void
   97.58 -gmyth_string_list_init(GMythStringList * gmyth_string_list)
   97.59 -{
   97.60 -    gmyth_string_list->glist = NULL;
   97.61 -}
   97.62 -
   97.63 -static void
   97.64 -gmyth_string_list_dispose(GObject * object)
   97.65 -{
   97.66 -    GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
   97.67 -
   97.68 -    gmyth_string_list_clear_all(gmyth_string_list);
   97.69 -
   97.70 -    G_OBJECT_CLASS(gmyth_string_list_parent_class)->dispose(object);
   97.71 -}
   97.72 -
   97.73 -static void
   97.74 -gmyth_string_list_finalize(GObject * object)
   97.75 -{
   97.76 -    // GMythStringList *gmyth_string_list = GMYTH_STRING_LIST(object);
   97.77 -
   97.78 -    g_signal_handlers_destroy(object);
   97.79 -
   97.80 -    G_OBJECT_CLASS(gmyth_string_list_parent_class)->finalize(object);
   97.81 -}
   97.82 -
   97.83 -/** Creates a new instance of GStringList.
   97.84 - * 
   97.85 - * @return a new instance of GStringList.
   97.86 - */
   97.87 -GMythStringList *
   97.88 -gmyth_string_list_new()
   97.89 -{
   97.90 -    GMythStringList *gmyth_string_list =
   97.91 -        GMYTH_STRING_LIST(g_object_new(GMYTH_STRING_LIST_TYPE, NULL));
   97.92 -
   97.93 -    return gmyth_string_list;
   97.94 -}
   97.95 -
   97.96 -/** Appends a guint64 to the string list.
   97.97 - * 
   97.98 - * @param strlist The GMythStringList instance.
   97.99 - * @param value The guint64 to be appended.
  97.100 - * 
  97.101 - * @return The appended guint64 converted to a GString object.
  97.102 - */
  97.103 -GString        *
  97.104 -gmyth_string_list_append_int(GMythStringList * strlist, const gint value)
  97.105 -{
  97.106 -    GString        *value_str = g_string_new("");
  97.107 -
  97.108 -    g_string_printf(value_str, "%d", value);
  97.109 -
  97.110 -    strlist->glist = g_list_append(strlist->glist, value_str);
  97.111 -
  97.112 -    return value_str;
  97.113 -}
  97.114 -
  97.115 -
  97.116 -/** Appends a gdouble to the string list.
  97.117 - *
  97.118 - * @param strlist The GMythStringList instance.
  97.119 - * @param value The gdouble to be appended.
  97.120 - *
  97.121 - * @return The appended gdouble converted to a GString object.
  97.122 - */
  97.123 -GString        *
  97.124 -gmyth_string_list_append_float(GMythStringList * strlist, const gdouble value)
  97.125 -{
  97.126 -    GString        *value_str = g_string_new("");
  97.127 -    g_string_printf(value_str, "%f", value);
  97.128 -    strlist->glist = g_list_append(strlist->glist, value_str);
  97.129 -    return value_str;
  97.130 -}
  97.131 -
  97.132 -
  97.133 -/** Appends a guint64 to the string list.
  97.134 - * 
  97.135 - * @param strlist The GMythStringList instance.
  97.136 - * @param value The guint64 to be appended.
  97.137 - * 
  97.138 - * @return The appended guint64 converted to a GString object.
  97.139 - */
  97.140 -GString        *
  97.141 -gmyth_string_list_append_uint64(GMythStringList * strlist,
  97.142 -                                const guint64 value)
  97.143 -{
  97.144 -    GString        *tmp_str1 = g_string_new("");
  97.145 -    GString        *tmp_str2 = g_string_new("");
  97.146 -
  97.147 -    gmyth_debug("value = %llu.\n", value);
  97.148 -
  97.149 -    gulong          l2 = ((guint64) value & 0xffffffff);
  97.150 -    gulong          l1 = ((guint64) value >> 32);
  97.151 -
  97.152 -    /*
  97.153 -     * high order part of guint64 value 
  97.154 -     */
  97.155 -    g_string_printf(tmp_str1, "%lu", l1);
  97.156 -
  97.157 -    gmyth_debug("[%s] uint64 (high) = %s\n", __FUNCTION__, tmp_str1->str);
  97.158 -
  97.159 -    strlist->glist = g_list_append(strlist->glist, tmp_str1);
  97.160 -
  97.161 -    /*
  97.162 -     * low order part of guint64 value 
  97.163 -     */
  97.164 -    g_string_printf(tmp_str2, "%lu", l2);
  97.165 -
  97.166 -    gmyth_debug("[%s] uint64 (low) = %s\n", __FUNCTION__, tmp_str2->str);
  97.167 -
  97.168 -    strlist->glist = g_list_append(strlist->glist, tmp_str2);
  97.169 -
  97.170 -    return tmp_str2;
  97.171 -}
  97.172 -
  97.173 -/** Appends a gint64 to the string list.
  97.174 - * 
  97.175 - * @param strlist The GMythStringList instance.
  97.176 - * @param value The gint64 to be appended.
  97.177 - * 
  97.178 - * @return The appended gint64 converted to a GString object.
  97.179 - */
  97.180 -GString        *
  97.181 -gmyth_string_list_append_int64(GMythStringList * strlist,
  97.182 -                               const gint64 value)
  97.183 -{
  97.184 -    GString        *tmp_str1 = g_string_new("");
  97.185 -    GString        *tmp_str2 = g_string_new("");
  97.186 -
  97.187 -    gmyth_debug("value = %lld.\n", value);
  97.188 -
  97.189 -    glong           l2 = ((gint64) value & 0xffffffff);
  97.190 -    glong           l1 = ((gint64) value >> 32);
  97.191 -
  97.192 -    /*
  97.193 -     * high order part of gint64 value 
  97.194 -     */
  97.195 -    g_string_printf(tmp_str1, "%ld", l1);
  97.196 -
  97.197 -    gmyth_debug("[%s] int64 (high) = %s\n", __FUNCTION__, tmp_str1->str);
  97.198 -
  97.199 -    strlist->glist = g_list_append(strlist->glist, tmp_str1);
  97.200 -
  97.201 -    /*
  97.202 -     * low order part of gint64 value 
  97.203 -     */
  97.204 -    g_string_printf(tmp_str2, "%ld", l2);
  97.205 -
  97.206 -    gmyth_debug("[%s] int64 (low) = %s\n", __FUNCTION__, tmp_str2->str);
  97.207 -
  97.208 -    strlist->glist = g_list_append(strlist->glist, tmp_str2);
  97.209 -
  97.210 -    return tmp_str2;
  97.211 -}
  97.212 -
  97.213 -/** Appends a char array to the string list.
  97.214 - * 
  97.215 - * @param strlist The GMythStringList instance.
  97.216 - * @param value The char array to be appended.
  97.217 - * 
  97.218 - * @return The appended char array converted to a GString object.
  97.219 - */
  97.220 -GString        *
  97.221 -gmyth_string_list_append_char_array(GMythStringList * strlist,
  97.222 -                                    const gchar * value)
  97.223 -{
  97.224 -    GString        *tmp_str = NULL;
  97.225 -
  97.226 -    g_return_val_if_fail(strlist != NULL, NULL);
  97.227 -
  97.228 -    tmp_str = g_string_new(value);
  97.229 -
  97.230 -    strlist->glist = g_list_append(strlist->glist, tmp_str);
  97.231 -
  97.232 -    return tmp_str;
  97.233 -}
  97.234 -
  97.235 -/** Appends a string to the string list.
  97.236 - * 
  97.237 - * @param strlist The GMythStringList instance.
  97.238 - * @param value The string to be appended.
  97.239 - * 
  97.240 - * @return The appended string itself. 
  97.241 - */
  97.242 -GString        *
  97.243 -gmyth_string_list_append_string(GMythStringList * strlist, GString * value)
  97.244 -{
  97.245 -    g_return_val_if_fail(strlist != NULL, NULL);
  97.246 -
  97.247 -    if (value != NULL) {
  97.248 -        strlist->glist =
  97.249 -            g_list_append(strlist->glist, g_string_new(value->str));
  97.250 -    } else {
  97.251 -        strlist->glist = g_list_append(strlist->glist, NULL);
  97.252 -    }
  97.253 -
  97.254 -    return value;
  97.255 -}
  97.256 -
  97.257 -/** Gets an integer value from the string list at the given position.
  97.258 - * 
  97.259 - * @param strlist The GMythStringList instance.
  97.260 - * @param index the integer position in the list, starting with zero.
  97.261 - * @return The integer value.
  97.262 - */
  97.263 -gint
  97.264 -gmyth_string_list_get_int(GMythStringList * strlist, const gint index)
  97.265 -{
  97.266 -    // TODO: Create static method check_index()
  97.267 -    GString        *tmp_str = NULL;
  97.268 -
  97.269 -    g_return_val_if_fail(strlist != NULL, 0);
  97.270 -
  97.271 -    tmp_str = (GString *) g_list_nth_data(strlist->glist, index);
  97.272 -
  97.273 -    if (NULL == tmp_str || NULL == tmp_str->str
  97.274 -        || strlen(tmp_str->str) <= 0)
  97.275 -        return 0;
  97.276 -
  97.277 -    return (gint) (             /* 0x00000000ffffffffL & (gint64) */
  97.278 -                      g_ascii_strtoull(tmp_str->str, NULL, 10));
  97.279 -}
  97.280 -
  97.281 -/** Gets a guint64 value from the string list at the given position.
  97.282 - * According to the Mythtv protocol, the 64 bits value is formed by
  97.283 - * two strings.
  97.284 - * 
  97.285 - * @param strlist The GMythStringList instance.
  97.286 - * @param index the index of the first string forming the 64 bits value. 
  97.287 - * Index starts with zero.
  97.288 - * @return The guint64 value.
  97.289 - */
  97.290 -guint64
  97.291 -gmyth_string_list_get_uint64(GMythStringList * strlist, const gint index)
  97.292 -{
  97.293 -    // TODO: Create static method check_index()
  97.294 -    guint64         ret_value = 0;
  97.295 -    guint64         l2 = 0;
  97.296 -
  97.297 -    g_return_val_if_fail(strlist != NULL, 0);
  97.298 -
  97.299 -    const GString  *tmp_str1 =
  97.300 -        (GString *) g_list_nth_data(strlist->glist, index);
  97.301 -    const GString  *tmp_str2 =
  97.302 -        (GString *) g_list_nth_data(strlist->glist, index + 1);
  97.303 -
  97.304 -    if (tmp_str1 != NULL)
  97.305 -        gmyth_debug("[%s] seek high bytes = %s\n", __FUNCTION__,
  97.306 -                    tmp_str1->str);
  97.307 -    if (tmp_str2 == NULL || strlen(tmp_str2->str) > 0) {
  97.308 -    } else {
  97.309 -        gmyth_debug("[%s] seek low bytes = %s\n", __FUNCTION__,
  97.310 -                    tmp_str2->str);
  97.311 -    }
  97.312 -
  97.313 -    guint64         l1 = ((guint64) g_ascii_strtoull(tmp_str1->str, NULL, 10)   /* & 
  97.314 -                                                                                 * 0xffffffff 
  97.315 -                                                                                 */
  97.316 -        );
  97.317 -
  97.318 -    if (tmp_str2 != NULL && tmp_str2->str != NULL
  97.319 -        && strlen(tmp_str2->str) > 0) {
  97.320 -        l2 = ((guint64) g_ascii_strtoull(tmp_str2->str, NULL, 10)
  97.321 -              /*
  97.322 -               * & 0xffffffff 
  97.323 -               */
  97.324 -            );
  97.325 -    } else {
  97.326 -        l2 = l1;
  97.327 -        l1 = 0;
  97.328 -    }
  97.329 -
  97.330 -    gmyth_debug("[%s]\t[l1 == %llu, l2 == %llu]\n", __FUNCTION__, l1, l2);
  97.331 -
  97.332 -    ret_value =
  97.333 -        ((guint64) (l2) /* & 0xffffffff */ ) | ((guint64) l1 << 32);
  97.334 -
  97.335 -    gmyth_debug("[%s] returning uint64 value = %llu\n", __FUNCTION__,
  97.336 -                ret_value);
  97.337 -
  97.338 -    return ret_value;
  97.339 -}
  97.340 -
  97.341 -/** Gets a gint64 value from the string list at the given position.
  97.342 - * According to the Mythtv protocol, the 64 bits value is formed by
  97.343 - * two strings.
  97.344 - * 
  97.345 - * @param strlist The GMythStringList instance.
  97.346 - * @param index the index of the first string forming the 64 bits value. 
  97.347 - * Index starts with zero.
  97.348 - * @return The gint64 value.
  97.349 - */
  97.350 -gint64
  97.351 -gmyth_string_list_get_int64(GMythStringList * strlist, const gint index)
  97.352 -{
  97.353 -    // TODO: Create static method check_index()
  97.354 -    gint64          ret_value = 0;
  97.355 -    gint64          l2 = 0;
  97.356 -
  97.357 -    g_return_val_if_fail(strlist != NULL, 0);
  97.358 -
  97.359 -    const GString  *tmp_str1 =
  97.360 -        (GString *) g_list_nth_data(strlist->glist, index);
  97.361 -    const GString  *tmp_str2 =
  97.362 -        (GString *) g_list_nth_data(strlist->glist, index + 1);
  97.363 -
  97.364 -    if (tmp_str1 != NULL)
  97.365 -        gmyth_debug("[%s] seek high bytes = %s\n", __FUNCTION__,
  97.366 -                    tmp_str1->str);
  97.367 -    if (tmp_str2 == NULL || strlen(tmp_str2->str) > 0) {
  97.368 -    } else {
  97.369 -        gmyth_debug("[%s] seek low bytes = %s\n", __FUNCTION__,
  97.370 -                    tmp_str2->str);
  97.371 -    }
  97.372 -
  97.373 -    gint64          l1 = ((guint64) g_ascii_strtoull(tmp_str1->str, NULL, 10)   /* & 
  97.374 -                                                                                 * 0xffffffff 
  97.375 -                                                                                 */
  97.376 -        );
  97.377 -
  97.378 -    if (tmp_str2 != NULL && tmp_str2->str != NULL
  97.379 -        && strlen(tmp_str2->str) > 0) {
  97.380 -        l2 = ((gint64) g_ascii_strtoull(tmp_str2->str, NULL, 10)
  97.381 -              /*
  97.382 -               * & 0xffffffff 
  97.383 -               */
  97.384 -            );
  97.385 -    } else {
  97.386 -        l2 = l1;
  97.387 -        l1 = 0;
  97.388 -    }
  97.389 -
  97.390 -    gmyth_debug("[%s]\t[l1 == %lld, l2 == %lld]\n", __FUNCTION__, l1, l2);
  97.391 -
  97.392 -    ret_value = ((gint64) (l2) /* & 0xffffffff */ ) | ((gint64) l1 << 32);
  97.393 -
  97.394 -    gmyth_debug("[%s] returning int64 value = %lld\n", __FUNCTION__,
  97.395 -                ret_value);
  97.396 -
  97.397 -    return ret_value;
  97.398 -}
  97.399 -
  97.400 -
  97.401 -/** Gets a string from the string list at the given position. The GString must be deallocated.
  97.402 - * 
  97.403 - * @param strlist The GMythStringList instance.
  97.404 - * @param index the string position in the list, starting with zero.
  97.405 - * @return A pointer to the string data.
  97.406 - */
  97.407 -GString        *
  97.408 -gmyth_string_list_get_string(GMythStringList * strlist, const gint index)
  97.409 -{
  97.410 -    GString        *ret;
  97.411 -
  97.412 -    if (!strlist || !(strlist->glist)) {
  97.413 -        gmyth_debug("%s received Null arguments", __FUNCTION__);
  97.414 -        return NULL;
  97.415 -    }
  97.416 -
  97.417 -    ret = (GString *) g_list_nth_data(strlist->glist, index);
  97.418 -
  97.419 -    return g_string_new(ret->str);
  97.420 -}
  97.421 -
  97.422 -
  97.423 -static void
  97.424 -gmyth_string_list_clear_element(GString * str_elem, void *data_aux)
  97.425 -{
  97.426 -    if (str_elem != NULL)
  97.427 -        g_string_free(str_elem, TRUE);
  97.428 -}
  97.429 -
  97.430 -/** Removes all strings from the string list.
  97.431 - * 
  97.432 - * @param strlist The GMythStringList instance.
  97.433 - */
  97.434 -void
  97.435 -gmyth_string_list_clear_all(GMythStringList * strlist)
  97.436 -{
  97.437 -    if (strlist != NULL && strlist->glist) {
  97.438 -        g_list_foreach(strlist->glist,
  97.439 -                       (GFunc) gmyth_string_list_clear_element, NULL);
  97.440 -        g_list_free(strlist->glist);
  97.441 -        strlist->glist = NULL;
  97.442 -    }
  97.443 -}
  97.444 -
  97.445 -/** Retrieves the number of elements in the string list.
  97.446 - * 
  97.447 - * @param strlist The GMythStringList instance.
  97.448 - * @return the string list length.
  97.449 - */
  97.450 -gint
  97.451 -gmyth_string_list_length(GMythStringList * strlist)
  97.452 -{
  97.453 -    if (!(strlist != NULL && strlist->glist != NULL))
  97.454 -        return 0;
  97.455 -
  97.456 -    return g_list_length(strlist->glist);
  97.457 -}
    98.1 --- a/gmyth/src/gmyth_stringlist.h	Mon Feb 25 17:45:36 2008 +0000
    98.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.3 @@ -1,108 +0,0 @@
    98.4 -/**
    98.5 - * GMyth Library
    98.6 - *
    98.7 - * @file gmyth/gmyth_stringlist.h
    98.8 - * 
    98.9 - * @brief <p> This component contains functions for dealing with the stringlist
   98.10 - * format of the mythprotocol.
   98.11 - * 
   98.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
   98.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
   98.14 - *
   98.15 - * 
   98.16 - * This program is free software; you can redistribute it and/or modify
   98.17 - * it under the terms of the GNU Lesser General Public License as published by
   98.18 - * the Free Software Foundation; either version 2 of the License, or
   98.19 - * (at your option) any later version.
   98.20 - *
   98.21 - * This program is distributed in the hope that it will be useful,
   98.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   98.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   98.24 - * GNU General Public License for more details.
   98.25 - *
   98.26 - * You should have received a copy of the GNU Lesser General Public License
   98.27 - * along with this program; if not, write to the Free Software
   98.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   98.29 - */
   98.30 -
   98.31 -#ifndef GMYTH_STRING_LIST_H_
   98.32 -#define GMYTH_STRING_LIST_H_
   98.33 -
   98.34 -#include <glib-object.h>
   98.35 -
   98.36 -#include <stdio.h>
   98.37 -#include <stdlib.h>
   98.38 -#include <string.h>
   98.39 -#include <netdb.h>
   98.40 -#include <sys/socket.h>
   98.41 -#include <unistd.h>
   98.42 -
   98.43 -G_BEGIN_DECLS
   98.44 -#define GMYTH_STRING_LIST_TYPE               (gmyth_string_list_get_type ())
   98.45 -#define GMYTH_STRING_LIST(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_STRING_LIST_TYPE, GMythStringList))
   98.46 -#define GMYTH_STRING_LIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
   98.47 -#define IS_GMYTH_STRING_LIST(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_STRING_LIST_TYPE))
   98.48 -#define IS_GMYTH_STRING_LIST_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_STRING_LIST_TYPE))
   98.49 -#define GMYTH_STRING_LIST_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_STRING_LIST_TYPE, GMythStringListClass))
   98.50 -typedef struct _GMythStringList GMythStringList;
   98.51 -typedef struct _GMythStringListClass GMythStringListClass;
   98.52 -
   98.53 -struct _GMythStringListClass {
   98.54 -    GObjectClass    parent_class;
   98.55 -
   98.56 -    /*
   98.57 -     * callbacks 
   98.58 -     */
   98.59 -    /*
   98.60 -     * no one for now 
   98.61 -     */
   98.62 -};
   98.63 -
   98.64 -struct _GMythStringList {
   98.65 -    GObject         parent;
   98.66 -
   98.67 -    /*
   98.68 -     * string list 
   98.69 -     */
   98.70 -    GList          *glist;
   98.71 -};
   98.72 -
   98.73 -
   98.74 -GType           gmyth_string_list_get_type(void);
   98.75 -
   98.76 -GMythStringList *gmyth_string_list_new(void);
   98.77 -
   98.78 -void            gmyth_string_list_clear_all(GMythStringList * strlist);
   98.79 -int             gmyth_string_list_length(GMythStringList * strlist);
   98.80 -
   98.81 -GString        *gmyth_string_list_append_float(GMythStringList * strlist,
   98.82 -                                             const gdouble value);
   98.83 -
   98.84 -GString        *gmyth_string_list_append_int(GMythStringList * strlist,
   98.85 -                                             const gint value);
   98.86 -GString        *gmyth_string_list_append_uint64(GMythStringList * strlist,
   98.87 -                                                const guint64 value);
   98.88 -
   98.89 -GString        *gmyth_string_list_append_int64(GMythStringList * strlist,
   98.90 -                                               const gint64 value);
   98.91 -
   98.92 -GString        *gmyth_string_list_append_char_array(GMythStringList *
   98.93 -                                                    strlist,
   98.94 -                                                    const char *value);
   98.95 -GString        *gmyth_string_list_append_string(GMythStringList * strlist,
   98.96 -                                                GString * value);
   98.97 -
   98.98 -int             gmyth_string_list_get_int(GMythStringList * strlist,
   98.99 -                                          const gint index);
  98.100 -guint64         gmyth_string_list_get_uint64(GMythStringList * strlist,
  98.101 -                                             const gint index);
  98.102 -gint64          gmyth_string_list_get_int64(GMythStringList * strlist,
  98.103 -                                            const gint index);
  98.104 -GString        *gmyth_string_list_get_string(GMythStringList * strlist,
  98.105 -                                             const gint index);
  98.106 -
  98.107 -#define gmyth_string_list_get_char_array(strlist, index) \
  98.108 -	(gmyth_string_list_get_string(strlist, index))->str
  98.109 -
  98.110 -G_END_DECLS
  98.111 -#endif                          /* GMYTH_STRING_LIST_H_ */
    99.1 --- a/gmyth/src/gmyth_transcoder.c	Mon Feb 25 17:45:36 2008 +0000
    99.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.3 @@ -1,272 +0,0 @@
    99.4 -/**
    99.5 - * GMyth Library
    99.6 - * 
    99.7 - * @file gmyth/gmyth_transcoder.c
    99.8 - * 
    99.9 - * @brief <p> This file contains the transcoder class.
   99.10 - *
   99.11 - * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
   99.12 - * @author Artur Duque de Souza <artur.souza@indt.org.br>
   99.13 - *
   99.14 - * 
   99.15 - * This program is free software; you can redistribute it and/or modify
   99.16 - * it under the terms of the GNU Lesser General Public License as published by
   99.17 - * the Free Software Foundation; either version 2 of the License, or
   99.18 - * (at your option) any later version.
   99.19 - *
   99.20 - * This program is distributed in the hope that it will be useful,
   99.21 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   99.22 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   99.23 - * GNU General Public License for more details.
   99.24 - *
   99.25 - * You should have received a copy of the GNU Lesser General Public License
   99.26 - * along with this program; if not, write to the Free Software
   99.27 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   99.28 - */
   99.29 -
   99.30 -
   99.31 -#ifdef HAVE_CONFIG_H
   99.32 -#include "config.h"
   99.33 -#endif
   99.34 -
   99.35 -#include <stdlib.h>
   99.36 -#include <string.h>
   99.37 -#include <assert.h>
   99.38 -
   99.39 -#include "gmyth_util.h"
   99.40 -#include "gmyth_debug.h"
   99.41 -
   99.42 -#include "gmyth_jobqueue.h"
   99.43 -#include "gmyth_transcoder.h"
   99.44 -
   99.45 -static void     gmyth_transcoder_class_init(GMythTranscoderClass * klass);
   99.46 -static void     gmyth_transcoder_init(GMythTranscoder * object);
   99.47 -
   99.48 -static void     gmyth_transcoder_dispose(GObject * object);
   99.49 -static void     gmyth_transcoder_finalize(GObject * object);
   99.50 -
   99.51 -G_DEFINE_TYPE(GMythTranscoder, gmyth_transcoder, G_TYPE_OBJECT)
   99.52 -    static void     gmyth_transcoder_class_init(GMythTranscoderClass *
   99.53 -                                                klass)
   99.54 -{
   99.55 -    GObjectClass   *gobject_class = G_OBJECT_CLASS(klass);
   99.56 -
   99.57 -    gobject_class->dispose = gmyth_transcoder_dispose;
   99.58 -    gobject_class->finalize = gmyth_transcoder_finalize;
   99.59 -}
   99.60 -
   99.61 -static void
   99.62 -gmyth_transcoder_init(GMythTranscoder * transcoder)
   99.63 -{
   99.64 -    transcoder->started = FALSE;
   99.65 -}
   99.66 -
   99.67 -static void
   99.68 -gmyth_transcoder_dispose(GObject * object)
   99.69 -{
   99.70 -    GMythTranscoder *transcoder = GMYTH_TRANSCODER(object);
   99.71 -
   99.72 -    g_free(transcoder->output_filename);
   99.73 -    g_free(transcoder->filename);
   99.74 -    g_free(transcoder->profile);
   99.75 -    g_free(transcoder->starttime);
   99.76 -
   99.77 -    if (transcoder->backend_info)
   99.78 -        g_object_unref(transcoder->backend_info);
   99.79 -
   99.80 -    G_OBJECT_CLASS(gmyth_transcoder_parent_class)->dispose(object);
   99.81 -}
   99.82 -
   99.83 -static void
   99.84 -gmyth_transcoder_finalize(GObject * object)
   99.85 -{
   99.86 -    g_signal_handlers_destroy(object);
   99.87 -    G_OBJECT_CLASS(gmyth_transcoder_parent_class)->finalize(object);
   99.88 -}
   99.89 -
   99.90 -/**
   99.91 - * Creates a new instance of GMythTranscoder.
   99.92 - * 
   99.93 - * @return a new instance of GMythTranscoder.
   99.94 - **/
   99.95 -GMythTranscoder *
   99.96 -gmyth_transcoder_new(GMythBackendInfo * backend_info)
   99.97 -{
   99.98 -    GMythTranscoder *transcoder = GMYTH_TRANSCODER
   99.99 -        (g_object_new(GMYTH_TRANSCODER_TYPE, NULL));
  99.100 -
  99.101 -    if (backend_info != NULL) {
  99.102 -        g_object_ref(backend_info);
  99.103 -        transcoder->backend_info = backend_info;
  99.104 -    }
  99.105 -
  99.106 -    return transcoder;
  99.107 -}
  99.108 -
  99.109 -/**
  99.110 - *
  99.111 - * gmyth_transcoder_date_change_format
  99.112 - * @brief converts a string like YYYY-MM-DDTHH:MM:SS into YYYYMMDDHHMMSS (vice versa)
  99.113 - * @param date_s gchar*
  99.114 - * @return gchar* with file or iso format
  99.115 - *
  99.116 - **/
  99.117 -static gchar   *
  99.118 -gmyth_transcoder_date_change_format(gchar * date_s, int format)
  99.119 -{
  99.120 -    if (date_s != NULL) {
  99.121 -        gint            length = strlen(date_s);
  99.122 -
  99.123 -        // create the right date format
  99.124 -        gchar          *src = (gchar *) g_malloc0(sizeof(gchar) * length);
  99.125 -
  99.126 -        strncpy(src, date_s, length);
  99.127 -
  99.128 -        gchar          *dst;
  99.129 -
  99.130 -        if (format == DATE_FILE) {
  99.131 -            dst = (gchar *) g_malloc0(sizeof(gchar) * 16);
  99.132 -            snprintf(dst, 16, "%.4s%.2s%.2s%.2s%.2s%.2s", src, src + 5,
  99.133 -                     src + 7, src + 9, src + 11, src + 13);
  99.134 -            dst[15] = '\0';
  99.135 -        } else if (format == DATE_ISO) {
  99.136 -            dst = (gchar *) g_malloc0(sizeof(gchar) * 20);
  99.137 -            snprintf(dst, 20, "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s", src,
  99.138 -                     src + 4, src + 6, src + 8, src + 10, src + 12);
  99.139 -            dst[19] = '\0';
  99.140 -        }
  99.141 -
  99.142 -        gchar          *ret = g_strdup(dst);
  99.143 -
  99.144 -        g_free(src);
  99.145 -        g_free(dst);
  99.146 -
  99.147 -        return ret;
  99.148 -    } else
  99.149 -        return NULL;
  99.150 -}
  99.151 -
  99.152 -/**
  99.153 - * gmyth_transcoder_set_output
  99.154 - * @brief set transcoder to use output
  99.155 - * @param value gboolean
  99.156 - * @param outfile filename of output
  99.157 - * @return void set's up the var to value
  99.158 - *
  99.159 - **/
  99.160 -void
  99.161 -gmyth_transcoder_set_output(GMythTranscoder * transcoder,
  99.162 -                            gboolean value, const gchar * outputfile)
  99.163 -{
  99.164 -    transcoder->output = value;
  99.165 -    transcoder->output_filename = g_strdup(outputfile);
  99.166 -}
  99.167 -
  99.168 -/**
  99.169 - * gmyth_transcoder_set_file
  99.170 - * @brief set the file to transcoder
  99.171 - * @param file filename
  99.172 - * @return void set's up the var to value
  99.173 - *
  99.174 - **/
  99.175 -void
  99.176 -gmyth_transcoder_set_filename(GMythTranscoder * transcoder,
  99.177 -                              const gchar * file)
  99.178 -{
  99.179 -    // fixme: if this method is called twice, memory will not be
  99.180 -    // dealocated
  99.181 -    // one transcoder can be used only for one file request?
  99.182 -    if (file != NULL) {
  99.183 -        gchar         **splited = g_strsplit(file, "_", 2);
  99.184 -
  99.185 -        // Get chanid
  99.186 -        sscanf(splited[0], "%d", &(transcoder->chanid));
  99.187 -
  99.188 -        // Get starttime
  99.189 -        gchar         **date = g_strsplit(splited[1], ".", 2);
  99.190 -
  99.191 -        transcoder->starttime =
  99.192 -            gmyth_transcoder_date_change_format(date[0], DATE_ISO);
  99.193 -
  99.194 -        transcoder->filename = g_strdup(file);
  99.195 -    }
  99.196 -}
  99.197 -
  99.198 -
  99.199 -/**
  99.200 - *
  99.201 - * gmyth_transcoder_set_profile
  99.202 - * @brief set transcoder's profile
  99.203 - * @param rec GMythTranscoder*
  99.204 - * @param value the value
  99.205 - * @return gint representing the result
  99.206 - *
  99.207 - **/
  99.208 -gint
  99.209 -gmyth_transcoder_set_profile(GMythTranscoder * trans, const gchar * value)
  99.210 -{
  99.211 -    g_return_val_if_fail(value != NULL, -1);
  99.212 -
  99.213 -    trans->profile = g_strndup(value, strlen(value));
  99.214 -
  99.215 -    return 0;
  99.216 -}
  99.217 -
  99.218 -gboolean
  99.219 -gmyth_transcoder_start(GMythTranscoder * trans)
  99.220 -{
  99.221 -    g_return_val_if_fail(trans != NULL, FALSE);
  99.222 -    g_return_val_if_fail(trans->backend_info != NULL, FALSE);
  99.223 -    g_return_val_if_fail(trans->filename != NULL, FALSE);
  99.224 -
  99.225 -    if (trans->started == FALSE) {  // not started yet
  99.226 -        if (!gmyth_util_file_exists(trans->backend_info, trans->filename)) {
  99.227 -            gmyth_debug("File %s does not exist", trans->filename);
  99.228 -        }
  99.229 -        trans->started = gmyth_jobqueue_add_job(trans, "JOB_TRANSCODE");
  99.230 -        if (trans->started == FALSE)
  99.231 -            gmyth_debug("Error while starting GMythTranscoder to file: %s",
  99.232 -                        trans->output_filename);
  99.233 -    } else {
  99.234 -        gmyth_debug("GMythTransfer already started!");
  99.235 -    }
  99.236 -
  99.237 -    return trans->started;
  99.238 -}
  99.239 -
  99.240 -gboolean
  99.241 -gmyth_transcoder_pause(GMythTranscoder * trans)
  99.242 -{
  99.243 -    g_return_val_if_fail(trans != NULL, FALSE);
  99.244 -    g_return_val_if_fail(trans->started == TRUE, FALSE);
  99.245 -
  99.246 -    return gmyth_jobqueue_change_cmd(trans, "PAUSE", "JOB_TRANSCODE");
  99.247 -}
  99.248 -
  99.249 -gboolean
  99.250 -gmyth_transcoder_resume(GMythTranscoder * trans)
  99.251 -{
  99.252 -    g_return_val_if_fail(trans != NULL, FALSE);
  99.253 -
  99.254 -    return gmyth_jobqueue_change_cmd(trans, "RESUME", "JOB_TRANSCODE");
  99.255 -}
  99.256 -
  99.257 -gboolean
  99.258 -gmyth_transcoder_cancel(GMythTranscoder * trans)
  99.259 -{
  99.260 -    g_return_val_if_fail(trans != NULL, FALSE);
  99.261 -    g_return_val_if_fail(trans->started == TRUE, FALSE);
  99.262 -
  99.263 -    trans->started = FALSE;
  99.264 -
  99.265 -    return gmyth_jobqueue_change_cmd(trans, "STOP", "JOB_TRANSCODE");
  99.266 -}
  99.267 -
  99.268 -// fixme: implement this method
  99.269 -gint
  99.270 -gmyth_transcoder_get_progress(GMythTranscoder * trans)
  99.271 -{
  99.272 -    static int      fixme = 0;
  99.273 -
  99.274 -    return (fixme++) % 101;
  99.275 -}
   100.1 --- a/gmyth/src/gmyth_transcoder.h	Mon Feb 25 17:45:36 2008 +0000
   100.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.3 @@ -1,104 +0,0 @@
   100.4 -/**
   100.5 - * GMyth Library
   100.6 - * 
   100.7 - * @file gmyth/gmyth_transcoder.h
   100.8 - * 
   100.9 - * @brief <p> This file contains the transcoder class.
  100.10 - *
  100.11 - * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
  100.12 - * @author Artur Duque de Souza <artur.souza@indt.org.br>
  100.13 - * 
  100.14 - * This program is free software; you can redistribute it and/or modify
  100.15 - * it under the terms of the GNU Lesser General Public License as published by
  100.16 - * the Free Software Foundation; either version 2 of the License, or
  100.17 - * (at your option) any later version.
  100.18 - *
  100.19 - * This program is distributed in the hope that it will be useful,
  100.20 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  100.21 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  100.22 - * GNU General Public License for more details.
  100.23 - *
  100.24 - * You should have received a copy of the GNU Lesser General Public License
  100.25 - * along with this program; if not, write to the Free Software
  100.26 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  100.27 - */
  100.28 -
  100.29 -#ifndef _GMYTH_TRANSCODER_H
  100.30 -#define _GMYTH_TRANSCODER_H
  100.31 -
  100.32 -#include <glib.h>
  100.33 -#include <glib-object.h>
  100.34 -
  100.35 -#include "gmyth_stringlist.h"
  100.36 -#include "gmyth_backendinfo.h"
  100.37 -#include "gmyth_socket.h"
  100.38 -#include "gmyth_http.h"
  100.39 -#include "gmyth_recprofile.h"
  100.40 -
  100.41 -G_BEGIN_DECLS
  100.42 -#define GMYTH_TRANSCODER_TYPE               (gmyth_transcoder_get_type ())
  100.43 -#define GMYTH_TRANSCODER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TRANSCODER_TYPE, GMythTranscoder))
  100.44 -#define GMYTH_TRANSCODER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TRANSCODER_TYPE, GMythTranscoderClass))
  100.45 -#define IS_GMYTH_TRANSCODER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_TRANSCODER_TYPE))
  100.46 -#define IS_GMYTH_TRANSCODER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TRANSCODER_TYPE))
  100.47 -#define GMYTH_TRANSCODER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_TRANSCODER_TYPE, GMythTranscoderClass))
  100.48 -#define DATE_ISO 0
  100.49 -#define DATE_FILE 1
  100.50 -typedef struct _GMythTranscoder GMythTranscoder;
  100.51 -typedef struct _GMythTranscoderClass GMythTranscoderClass;
  100.52 -
  100.53 -struct _GMythTranscoderClass {
  100.54 -    GObjectClass    parent_class;
  100.55 -
  100.56 -    /*
  100.57 -     * callbacks 
  100.58 -     */
  100.59 -};
  100.60 -
  100.61 -/**
  100.62 - * The GMythTranscoder structure is a class to implement functions
  100.63 - * related to transcoding.
  100.64 - */
  100.65 -struct _GMythTranscoder {
  100.66 -    GObject         parent;
  100.67 -
  100.68 -    gboolean        cutlist;
  100.69 -    gboolean        output;
  100.70 -    gboolean        started;
  100.71 -
  100.72 -    /*
  100.73 -     * private begin 
  100.74 -     */
  100.75 -    gchar          *output_filename;
  100.76 -    gchar          *filename;
  100.77 -    gchar          *profile;
  100.78 -    /*
  100.79 -     * private end 
  100.80 -     */
  100.81 -
  100.82 -    gchar          *starttime;
  100.83 -
  100.84 -    gint            chanid;
  100.85 -
  100.86 -    GMythBackendInfo *backend_info;
  100.87 -};
  100.88 -
  100.89 -GType           gmyth_transcoder_type(void);
  100.90 -
  100.91 -GMythTranscoder *gmyth_transcoder_new(GMythBackendInfo * backend_info);
  100.92 -void            gmyth_transcoder_set_output(GMythTranscoder * transcode,
  100.93 -                                            gboolean value,
  100.94 -                                            const gchar * outputfile);
  100.95 -void            gmyth_transcoder_set_filename(GMythTranscoder * transcode,
  100.96 -                                              const gchar * file);
  100.97 -gint            gmyth_transcoder_set_profile(GMythTranscoder * trans,
  100.98 -                                             const gchar * value);
  100.99 -gboolean        gmyth_transcoder_start(GMythTranscoder * trans);
 100.100 -gboolean        gmyth_transcoder_pause(GMythTranscoder * trans);
 100.101 -gboolean        gmyth_transcoder_resume(GMythTranscoder * trans);
 100.102 -gboolean        gmyth_transcoder_cancel(GMythTranscoder * trans);
 100.103 -gint            gmyth_transcoder_get_progress(GMythTranscoder * trans);
 100.104 -
 100.105 -
 100.106 -G_END_DECLS
 100.107 -#endif /*_GMYTH_TRANSCODER_H*/
   101.1 --- a/gmyth/src/gmyth_tvchain.c	Mon Feb 25 17:45:36 2008 +0000
   101.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.3 @@ -1,620 +0,0 @@
   101.4 -/**
   101.5 - * GMyth Library
   101.6 - *
   101.7 - * @file gmyth/gmyth_tvchain.c
   101.8 - * 
   101.9 - * @brief <p> This component contains functions for creating and accessing
  101.10 - * the tvchain functions for live tv playback.
  101.11 - * 
  101.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
  101.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
  101.14 - *
  101.15 - * 
  101.16 - * This program is free software; you can redistribute it and/or modify
  101.17 - * it under the terms of the GNU Lesser General Public License as published by
  101.18 - * the Free Software Foundation; either version 2 of the License, or
  101.19 - * (at your option) any later version.
  101.20 - *
  101.21 - * This program is distributed in the hope that it will be useful,
  101.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  101.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  101.24 - * GNU General Public License for more details.
  101.25 - *
  101.26 - * You should have received a copy of the GNU Lesser General Public License
  101.27 - * along with this program; if not, write to the Free Software
  101.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  101.29 - */
  101.30 -
  101.31 -#ifdef HAVE_CONFIG_H
  101.32 -#include "config.h"
  101.33 -#endif
  101.34 -
  101.35 -#include "gmyth_tvchain.h"
  101.36 -
  101.37 -#include <glib.h>
  101.38 -#include <time.h>
  101.39 -#include <stdio.h>
  101.40 -#include <stdlib.h>
  101.41 -#include <assert.h>
  101.42 -
  101.43 -#include "gmyth_epg.h"
  101.44 -#include "gmyth_util.h"
  101.45 -#include "gmyth_query.h"
  101.46 -#include "gmyth_scheduler.h"
  101.47 -#include "gmyth_debug.h"
  101.48 -
  101.49 -static void     gmyth_tvchain_class_init(GMythTVChainClass * klass);
  101.50 -static void     gmyth_tvchain_init(GMythTVChain * object);
  101.51 -
  101.52 -static void     gmyth_tvchain_dispose(GObject * object);
  101.53 -static void     gmyth_tvchain_finalize(GObject * object);
  101.54 -
  101.55 -static void     free_tvchain_entry(gpointer data, gpointer user_data);
  101.56 -
  101.57 -G_DEFINE_TYPE(GMythTVChain, gmyth_tvchain, G_TYPE_OBJECT)
  101.58 -    static void     gmyth_tvchain_class_init(GMythTVChainClass * klass)
  101.59 -{
  101.60 -    GObjectClass   *gobject_class;
  101.61 -
  101.62 -    gobject_class = (GObjectClass *) klass;
  101.63 -
  101.64 -    gobject_class->dispose = gmyth_tvchain_dispose;
  101.65 -    gobject_class->finalize = gmyth_tvchain_finalize;
  101.66 -}
  101.67 -
  101.68 -static void
  101.69 -gmyth_tvchain_init(GMythTVChain * tvchain)
  101.70 -{
  101.71 -    tvchain->tvchain_id = NULL;
  101.72 -
  101.73 -    tvchain->cur_chanid = g_string_new("");
  101.74 -    tvchain->cur_startts = NULL;
  101.75 -
  101.76 -    tvchain->mutex = g_mutex_new();
  101.77 -}
  101.78 -
  101.79 -GMythTVChain   *
  101.80 -gmyth_tvchain_new()
  101.81 -{
  101.82 -    GMythTVChain   *tvchain =
  101.83 -        GMYTH_TVCHAIN(g_object_new(GMYTH_TVCHAIN_TYPE, NULL));
  101.84 -
  101.85 -    return tvchain;
  101.86 -}
  101.87 -
  101.88 -static void
  101.89 -gmyth_tvchain_dispose(GObject * object)
  101.90 -{
  101.91 -    GMythTVChain   *tvchain = GMYTH_TVCHAIN(object);
  101.92 -
  101.93 -    if (tvchain->tvchain_id != NULL) {
  101.94 -        g_string_free(tvchain->tvchain_id, TRUE);
  101.95 -        tvchain->tvchain_id = NULL;
  101.96 -    }
  101.97 -
  101.98 -    if (tvchain->mutex != NULL) {
  101.99 -        g_mutex_free(tvchain->mutex);
 101.100 -        tvchain->mutex = NULL;
 101.101 -    }
 101.102 -
 101.103 -    if (tvchain->tvchain_list != NULL) {
 101.104 -        g_list_foreach(tvchain->tvchain_list, free_tvchain_entry, NULL);
 101.105 -        g_list_free(tvchain->tvchain_list);
 101.106 -    }
 101.107 -
 101.108 -    if (tvchain->cur_chanid != NULL) {
 101.109 -        g_string_free(tvchain->cur_chanid, TRUE);
 101.110 -        tvchain->cur_chanid = NULL;
 101.111 -    }
 101.112 -
 101.113 -    if (tvchain->backend_info) {
 101.114 -        g_object_unref(tvchain->backend_info);
 101.115 -        tvchain->backend_info = NULL;
 101.116 -    }
 101.117 -
 101.118 -
 101.119 -    G_OBJECT_CLASS(gmyth_tvchain_parent_class)->dispose(object);
 101.120 -}
 101.121 -
 101.122 -static void
 101.123 -gmyth_tvchain_finalize(GObject * object)
 101.124 -{
 101.125 -    g_signal_handlers_destroy(object);
 101.126 -
 101.127 -    G_OBJECT_CLASS(gmyth_tvchain_parent_class)->finalize(object);
 101.128 -}
 101.129 -
 101.130 -/** Initializes the tvchain and generates the tvchain id.
 101.131 - * 
 101.132 - * @param tvchain The GMythTVChain instance.
 101.133 - * @param hostname The local hostname used to generate the tvchain id.
 101.134 - */
 101.135 -gboolean
 101.136 -gmyth_tvchain_initialize(GMythTVChain * tvchain,
 101.137 -                         GMythBackendInfo * backend_info)
 101.138 -{
 101.139 -    const char     *hostname;
 101.140 -
 101.141 -    assert(tvchain);
 101.142 -    g_return_val_if_fail(backend_info != NULL, FALSE);
 101.143 -
 101.144 -    g_object_ref(backend_info);
 101.145 -    tvchain->backend_info = backend_info;
 101.146 -
 101.147 -    hostname = gmyth_backend_info_get_hostname(backend_info);
 101.148 -
 101.149 -    if (tvchain->tvchain_id == NULL) {
 101.150 -        gchar          *isodate = NULL;
 101.151 -        GTimeVal       *cur_time = g_new0(GTimeVal, 1);
 101.152 -
 101.153 -        // struct tm* gmyth_util_time_val_to_date ( const GTimeVal* time )
 101.154 -
 101.155 -        g_get_current_time(cur_time);
 101.156 -        isodate =
 101.157 -            gmyth_util_time_to_isoformat_from_time_val_fmt
 101.158 -            ("%Y-%m-%dT%H:%M:%S", cur_time);
 101.159 -
 101.160 -        tvchain->tvchain_id =
 101.161 -            g_string_sized_new(7 + strlen(hostname) + strlen(isodate));
 101.162 -        g_string_printf(tvchain->tvchain_id, "live-%s-%s", hostname,
 101.163 -                        isodate);
 101.164 -
 101.165 -        gmyth_debug("[%s] tv_chain_id: %s", __FUNCTION__,
 101.166 -                    tvchain->tvchain_id->str);
 101.167 -
 101.168 -        g_free(isodate);
 101.169 -        g_free(cur_time);
 101.170 -    } else {
 101.171 -        gmyth_debug("[%s] TVchain already initialized", __FUNCTION__);
 101.172 -    }
 101.173 -
 101.174 -    return TRUE;
 101.175 -}
 101.176 -
 101.177 -/** Gets the tvchain id.
 101.178 - * 
 101.179 - * @param tvchain The GMythTVChain instance.
 101.180 - * @return The tvchain id.
 101.181 - */
 101.182 -GString        *
 101.183 -gmyth_tvchain_get_id(GMythTVChain * tvchain)
 101.184 -{
 101.185 -    g_return_val_if_fail(tvchain != NULL
 101.186 -                         && tvchain->tvchain_id != NULL, NULL);
 101.187 -
 101.188 -    return tvchain->tvchain_id;
 101.189 -}
 101.190 -
 101.191 -/** Reloads all tvchain entries in the database.
 101.192 - * 
 101.193 - * @param tvchain The GMythTVChain instance.
 101.194 - * @return  TRUE if success, or FALSE if error.
 101.195 - */
 101.196 -gboolean
 101.197 -gmyth_tvchain_reload_all(GMythTVChain * tvchain)
 101.198 -{
 101.199 -    MYSQL_ROW       msql_row;
 101.200 -    MYSQL_RES      *msql_res = NULL;
 101.201 -    GMythQuery     *gmyth_query = NULL;
 101.202 -    gboolean        ret = TRUE;
 101.203 -    GString        *stmt_str = NULL;
 101.204 -
 101.205 -    g_mutex_lock(tvchain->mutex);
 101.206 -
 101.207 -    /*
 101.208 -     * gets the initial size of the TVChain entries list 
 101.209 -     */
 101.210 -    guint           prev_size = g_list_length(tvchain->tvchain_list);
 101.211 -
 101.212 -    gmyth_debug("[%s] chainid: %s", __FUNCTION__,
 101.213 -                tvchain->tvchain_id->str);
 101.214 -
 101.215 -    if (tvchain != NULL && tvchain->tvchain_list != NULL) {
 101.216 -        g_list_free(tvchain->tvchain_list);
 101.217 -        tvchain->tvchain_list = NULL;
 101.218 -    }
 101.219 -
 101.220 -    /*
 101.221 -     * TODO: Reuse gmyth_query already connected from context 
 101.222 -     */
 101.223 -    gmyth_query = gmyth_query_new();
 101.224 -    if (!gmyth_query_connect(gmyth_query, tvchain->backend_info)) {
 101.225 -        gmyth_debug("[%s] Could not connect to db", __FUNCTION__);
 101.226 -        g_mutex_unlock(tvchain->mutex);
 101.227 -        ret = FALSE;
 101.228 -        goto done;
 101.229 -    }
 101.230 -
 101.231 -    stmt_str = g_string_new("");
 101.232 -    g_string_printf(stmt_str,
 101.233 -                    "SELECT chanid, starttime, endtime, discontinuity, "
 101.234 -                    "chainpos, hostprefix, cardtype, channame, input "
 101.235 -                    "FROM tvchain "
 101.236 -                    "WHERE chainid = \"%s\" ORDER BY chainpos;",
 101.237 -                    tvchain->tvchain_id->str);
 101.238 -
 101.239 -    msql_res = gmyth_query_process_statement(gmyth_query, stmt_str->str);
 101.240 -    if (msql_res != NULL) {
 101.241 -
 101.242 -        while ((msql_row = mysql_fetch_row(msql_res)) != NULL) {
 101.243 -            struct LiveTVChainEntry *entry =
 101.244 -                g_new0(struct LiveTVChainEntry, 1);
 101.245 -            entry->chanid = g_string_new(msql_row[0]);
 101.246 -            entry->starttime =
 101.247 -                gmyth_util_string_to_time_val((const gchar *) msql_row[1]);
 101.248 -            entry->endtime =
 101.249 -                gmyth_util_string_to_time_val((const gchar *) msql_row[2]);
 101.250 -            entry->discontinuity =
 101.251 -                g_ascii_strtoull(msql_row[3], NULL, 10) != 0;
 101.252 -            entry->hostprefix = g_string_new(msql_row[5]);
 101.253 -            entry->cardtype = g_string_new(msql_row[6]);
 101.254 -            entry->channum = g_string_new(msql_row[7]);
 101.255 -            entry->inputname = g_string_new(msql_row[8]);
 101.256 -
 101.257 -            // m_maxpos = query.value(4).toInt() + 1;
 101.258 -            gmyth_debug
 101.259 -                ("[%s] Reading TV chain entry (channel %s): [%s, %s, %s]\n",
 101.260 -                 __FUNCTION__, entry->channum->str, entry->chanid->str,
 101.261 -                 (gchar *) msql_row[1], (gchar *) msql_row[2]);
 101.262 -
 101.263 -            /*
 101.264 -             * add this to get the actual start timestamp of the last
 101.265 -             * recording 
 101.266 -             */
 101.267 -            if (tvchain->cur_startts < entry->starttime)
 101.268 -                tvchain->cur_startts = entry->starttime;
 101.269 -
 101.270 -            tvchain->tvchain_list =
 101.271 -                g_list_append(tvchain->tvchain_list, entry);
 101.272 -        }
 101.273 -    } else {
 101.274 -        gmyth_debug("gmyth_tvchain_reload_all query error!\n");
 101.275 -        g_mutex_unlock(tvchain->mutex);
 101.276 -
 101.277 -        ret = FALSE;
 101.278 -        goto done;
 101.279 -    }
 101.280 -
 101.281 -    g_mutex_unlock(tvchain->mutex);
 101.282 -
 101.283 -    tvchain->cur_pos =
 101.284 -        gmyth_tvchain_program_is_at(tvchain, tvchain->cur_chanid,
 101.285 -                                    tvchain->cur_startts);
 101.286 -    gmyth_debug("[%s] TVChain current position = %d.\n", __FUNCTION__,
 101.287 -                tvchain->cur_pos);
 101.288 -
 101.289 -    if (tvchain->cur_pos < 0)
 101.290 -        tvchain->cur_pos = 0;
 101.291 -
 101.292 -    // if (m_switchid >= 0)
 101.293 -    // m_switchid =
 101.294 -    // ProgramIsAt(m_switchentry.chanid,m_switchentry.starttime);
 101.295 -
 101.296 -    if (prev_size != g_list_length(tvchain->tvchain_list)) {
 101.297 -        gmyth_debug("[%s] Added new recording", __FUNCTION__);
 101.298 -    }
 101.299 -
 101.300 -  done:
 101.301 -    if (stmt_str != NULL)
 101.302 -        g_string_free(stmt_str, TRUE);
 101.303 -
 101.304 -    if (msql_res != NULL)
 101.305 -        mysql_free_result(msql_res);
 101.306 -
 101.307 -    if (gmyth_query != NULL)
 101.308 -        g_object_unref(gmyth_query);
 101.309 -
 101.310 -    return ret;
 101.311 -}
 101.312 -
 101.313 -/** 
 101.314 - * Get all the program info entries in the database.
 101.315 - * 
 101.316 - * @param tvchain The GMythTVChain instance.
 101.317 - * 
 101.318 - * @return  A program info listage.
 101.319 - */
 101.320 -GList          *
 101.321 -gmyth_tvchain_get_program_info_list(GMythTVChain * tvchain)
 101.322 -{
 101.323 -    GList          *prog_list = NULL;
 101.324 -    MYSQL_ROW       msql_row;
 101.325 -    MYSQL_RES      *msql_res = NULL;
 101.326 -    GMythQuery     *gmyth_query = NULL;
 101.327 -    GString        *stmt_str = NULL;
 101.328 -
 101.329 -    g_mutex_lock(tvchain->mutex);
 101.330 -
 101.331 -    gmyth_query = gmyth_query_new();
 101.332 -    if (!gmyth_query_connect(gmyth_query, tvchain->backend_info)) {
 101.333 -        gmyth_debug("Could not connect to db.");
 101.334 -        goto done;
 101.335 -    }
 101.336 -
 101.337 -    stmt_str = g_string_new("");
 101.338 -    g_string_printf(stmt_str,
 101.339 -                    "SELECT channum, icon " "FROM channel "
 101.340 -                    "ORDER BY channum;");
 101.341 -
 101.342 -    msql_res = gmyth_query_process_statement(gmyth_query, stmt_str->str);
 101.343 -    if (msql_res != NULL) {
 101.344 -
 101.345 -        while ((msql_row = mysql_fetch_row(msql_res)) != NULL) {
 101.346 -            GMythProgramInfo *entry = gmyth_program_info_new();
 101.347 -
 101.348 -            entry->channame = g_string_new(msql_row[0]);
 101.349 -            entry->chansign = g_string_new(msql_row[1]);
 101.350 -
 101.351 -            gmyth_debug
 101.352 -                ("Reading TV program info entry (channel %s): [%s - {%s, %s}]\n",
 101.353 -                 entry->channame->str, entry->chansign->str,
 101.354 -                 (gchar *) msql_row[0], (gchar *) msql_row[1]);
 101.355 -
 101.356 -            prog_list = g_list_append(prog_list, entry);
 101.357 -        }
 101.358 -    } else {
 101.359 -        gmyth_debug
 101.360 -            ("Query error when trying to get the channel list from database!\n");
 101.361 -        goto done;
 101.362 -    }
 101.363 -
 101.364 -  done:
 101.365 -    g_mutex_unlock(tvchain->mutex);
 101.366 -
 101.367 -    if (stmt_str != NULL)
 101.368 -        g_string_free(stmt_str, TRUE);
 101.369 -
 101.370 -    if (msql_res != NULL)
 101.371 -        mysql_free_result(msql_res);
 101.372 -
 101.373 -    if (gmyth_query != NULL)
 101.374 -        g_object_unref(gmyth_query);
 101.375 -
 101.376 -    return prog_list;
 101.377 -}
 101.378 -
 101.379 -/** 
 101.380 - * Get all the program info entries in the database, given a channel name.
 101.381 - * 
 101.382 - * @param tvchain The GMythTVChain instance.
 101.383 - * @param channel The channel name.
 101.384 - * 
 101.385 - * @return  A program info listage, based on a given channel name.
 101.386 - */
 101.387 -GList          *
 101.388 -gmyth_tvchain_get_program_info_from_channel(GMythTVChain * tvchain,
 101.389 -                                            const gchar * channel)
 101.390 -{
 101.391 -    GList          *prog_list = NULL;
 101.392 -    MYSQL_ROW       msql_row;
 101.393 -    MYSQL_RES      *msql_res = NULL;
 101.394 -    GMythQuery     *gmyth_query = NULL;
 101.395 -    GString        *stmt_str = NULL;
 101.396 -
 101.397 -    g_mutex_lock(tvchain->mutex);
 101.398 -
 101.399 -    gmyth_query = gmyth_query_new();
 101.400 -    if (!gmyth_query_connect(gmyth_query, tvchain->backend_info)) {
 101.401 -        gmyth_debug("Could not connect to db.");
 101.402 -        goto done;
 101.403 -    }
 101.404 -
 101.405 -    stmt_str = g_string_new("");
 101.406 -    g_string_printf(stmt_str,
 101.407 -                    "SELECT channum, icon "
 101.408 -                    "FROM channel "
 101.409 -                    "WHERE channum = \"%s\" ORDER BY channum;", channel);
 101.410 -
 101.411 -    msql_res = gmyth_query_process_statement(gmyth_query, stmt_str->str);
 101.412 -    if (msql_res != NULL) {
 101.413 -
 101.414 -        while ((msql_row = mysql_fetch_row(msql_res)) != NULL) {
 101.415 -            GMythProgramInfo *entry = gmyth_program_info_new();
 101.416 -
 101.417 -            entry->channame = g_string_new(msql_row[0]);
 101.418 -            entry->chansign = g_string_new(msql_row[1]);
 101.419 -
 101.420 -            gmyth_debug
 101.421 -                ("Reading TV program info entry (channel %s): [%s - {%s, %s}]\n",
 101.422 -                 entry->channame->str, entry->chansign->str,
 101.423 -                 (gchar *) msql_row[0], (gchar *) msql_row[1]);
 101.424 -
 101.425 -            prog_list = g_list_append(prog_list, entry);
 101.426 -        }
 101.427 -    } else {
 101.428 -        gmyth_debug
 101.429 -            ("Query error when trying to get the channel list from database!\n");
 101.430 -        goto done;
 101.431 -    }
 101.432 -
 101.433 -  done:
 101.434 -    g_mutex_unlock(tvchain->mutex);
 101.435 -
 101.436 -    if (stmt_str != NULL)
 101.437 -        g_string_free(stmt_str, TRUE);
 101.438 -
 101.439 -    if (msql_res != NULL)
 101.440 -        mysql_free_result(msql_res);
 101.441 -
 101.442 -    if (gmyth_query != NULL)
 101.443 -        g_object_unref(gmyth_query);
 101.444 -
 101.445 -    return prog_list;
 101.446 -}
 101.447 -
 101.448 -/** 
 101.449 - * Returns the internal index for the TV chain related to the given
 101.450 - * channel and start time.
 101.451 - * 
 101.452 - * @param tvchain The GMythTVChain instance.
 101.453 - * @param chanid The channel id.
 101.454 - * @param startts The program start time.
 101.455 - * 
 101.456 - * @return The position of the related program info in the TV chain.
 101.457 - */
 101.458 -gint
 101.459 -gmyth_tvchain_program_is_at(GMythTVChain * tvchain, GString * chanid,
 101.460 -                            GTimeVal * startts)
 101.461 -{
 101.462 -    gint            count = 0;
 101.463 -    struct LiveTVChainEntry *entry;
 101.464 -    GList          *tmp_list = tvchain->tvchain_list;
 101.465 -    guint           list_size = g_list_length(tvchain->tvchain_list);
 101.466 -
 101.467 -    g_mutex_lock(tvchain->mutex);
 101.468 -
 101.469 -    for (; tmp_list && (count < list_size);
 101.470 -         tmp_list = tvchain->tvchain_list->next, count++) {
 101.471 -        entry = (struct LiveTVChainEntry *) tmp_list->data;
 101.472 -        if (!g_strncasecmp(entry->chanid->str, chanid->str, chanid->len)
 101.473 -            && entry->starttime == startts) {
 101.474 -            g_mutex_unlock(tvchain->mutex);
 101.475 -            return count;
 101.476 -        }
 101.477 -    }
 101.478 -    g_mutex_unlock(tvchain->mutex);
 101.479 -
 101.480 -    return -1;
 101.481 -}
 101.482 -
 101.483 -/** Get the program info associated to the tvchain.
 101.484 - * 
 101.485 - * @param tvchain The GMythTVChain instance.
 101.486 - * @param index The tvchain index.
 101.487 - * 
 101.488 - * @return The program info structure.
 101.489 - */
 101.490 -GMythProgramInfo *
 101.491 -gmyth_tvchain_get_program_at(GMythTVChain * tvchain, gint index)
 101.492 -{
 101.493 -    struct LiveTVChainEntry *entry;
 101.494 -
 101.495 -    entry = gmyth_tvchain_get_entry_at(tvchain, index);
 101.496 -
 101.497 -    if (entry)
 101.498 -        return gmyth_tvchain_entry_to_program(tvchain, entry);
 101.499 -
 101.500 -    return NULL;
 101.501 -}
 101.502 -
 101.503 -/** Gets a LiveTVChainEntry associated to the tvchain by its index.
 101.504 - * 
 101.505 - * @param tvchain The GMythTVChain instance.
 101.506 - * @param index The tvchain entry index
 101.507 - * @return The LiveTVchainEntry structure.
 101.508 - */
 101.509 -struct LiveTVChainEntry *
 101.510 -gmyth_tvchain_get_entry_at(GMythTVChain * tvchain, gint index)
 101.511 -{
 101.512 -    struct LiveTVChainEntry *chain_entry = NULL;
 101.513 -
 101.514 -    g_return_val_if_fail(tvchain != NULL
 101.515 -                         && tvchain->tvchain_list != NULL, NULL);
 101.516 -
 101.517 -    g_mutex_lock(tvchain->mutex);
 101.518 -
 101.519 -    gint            size = g_list_length(tvchain->tvchain_list);
 101.520 -    gint            new_index = (index < 0
 101.521 -                                 || index >= size) ? size - 1 : index;
 101.522 -
 101.523 -    if (new_index >= 0)
 101.524 -        chain_entry =
 101.525 -            (struct LiveTVChainEntry *) g_list_nth_data(tvchain->
 101.526 -                                                        tvchain_list,
 101.527 -                                                        new_index);
 101.528 -
 101.529 -    g_mutex_unlock(tvchain->mutex);
 101.530 -
 101.531 -    if (chain_entry != NULL) {
 101.532 -        gmyth_debug("[%s] Got TV Chain entry at %d.\n", __FUNCTION__,
 101.533 -                    new_index);
 101.534 -
 101.535 -    } else {
 101.536 -        gmyth_debug("[%s] failed to get entry at index %d", __FUNCTION__,
 101.537 -                    index);
 101.538 -    }
 101.539 -
 101.540 -    return chain_entry;
 101.541 -}
 101.542 -
 101.543 -/** 
 101.544 - * Gets the program info from backend database associated to the tv chain entry.
 101.545 - * 
 101.546 - * @param tvchain The GMythTVChain instance.
 101.547 - * @param entry the LiveTVChainEntry to be converted.
 101.548 - * 
 101.549 - * @return The program info.
 101.550 - */
 101.551 -GMythProgramInfo *
 101.552 -gmyth_tvchain_entry_to_program(GMythTVChain * tvchain,
 101.553 -                               struct LiveTVChainEntry * entry)
 101.554 -{
 101.555 -    GMythProgramInfo *proginfo = NULL;
 101.556 -
 101.557 -    g_return_val_if_fail(tvchain != NULL, NULL);
 101.558 -
 101.559 -    if (!entry || !tvchain) {
 101.560 -        gmyth_debug
 101.561 -            ("gmyth_tvchain_entry_to_program() received NULL argument");
 101.562 -        return NULL;
 101.563 -    }
 101.564 -
 101.565 -    GMythScheduler *scheduler = gmyth_scheduler_new();
 101.566 -
 101.567 -    gmyth_scheduler_connect(scheduler, tvchain->backend_info);
 101.568 -    proginfo = gmyth_scheduler_get_recorded(scheduler,
 101.569 -                                            entry->chanid,
 101.570 -                                            entry->starttime);
 101.571 -    gmyth_scheduler_disconnect(scheduler);
 101.572 -
 101.573 -    if (proginfo) {
 101.574 -        proginfo->pathname =
 101.575 -            g_string_prepend(proginfo->pathname, entry->hostprefix->str);
 101.576 -    } else {
 101.577 -        gmyth_debug
 101.578 -            ("tvchain_entry_to_program( chan id = %s, starttime = %ld) failed!",
 101.579 -             entry->chanid->str, entry->starttime->tv_sec);
 101.580 -    }
 101.581 -
 101.582 -    return proginfo;
 101.583 -}
 101.584 -
 101.585 -static void
 101.586 -free_tvchain_entry(gpointer data, gpointer user_data)
 101.587 -{
 101.588 -    struct LiveTVChainEntry *entry;
 101.589 -
 101.590 -    g_return_if_fail(data != NULL);
 101.591 -
 101.592 -    entry = (struct LiveTVChainEntry *) data;
 101.593 -
 101.594 -    if (entry->chanid != NULL) {
 101.595 -        g_string_free(entry->chanid, TRUE);
 101.596 -    }
 101.597 -
 101.598 -    if (entry->starttime != NULL) {
 101.599 -        g_free(entry->starttime);
 101.600 -    }
 101.601 -
 101.602 -    if (entry->endtime != NULL) {
 101.603 -        g_free(entry->endtime);
 101.604 -    }
 101.605 -
 101.606 -    if (entry->hostprefix) {
 101.607 -        g_string_free(entry->hostprefix, TRUE);
 101.608 -    }
 101.609 -
 101.610 -    if (entry->cardtype) {
 101.611 -        g_string_free(entry->cardtype, TRUE);
 101.612 -    }
 101.613 -
 101.614 -    if (entry->channum) {
 101.615 -        g_string_free(entry->channum, TRUE);
 101.616 -    }
 101.617 -
 101.618 -    if (entry->inputname) {
 101.619 -        g_string_free(entry->inputname, TRUE);
 101.620 -    }
 101.621 -
 101.622 -    g_free(entry);
 101.623 -}
   102.1 --- a/gmyth/src/gmyth_tvchain.h	Mon Feb 25 17:45:36 2008 +0000
   102.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.3 @@ -1,118 +0,0 @@
   102.4 -/**
   102.5 - * GMyth Library
   102.6 - *
   102.7 - * @file gmyth/gmyth_tvchain.h
   102.8 - * 
   102.9 - * @brief <p> This component contains functions for creating and accessing
  102.10 - * the tvchain functions for live tv playback.
  102.11 - * 
  102.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
  102.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
  102.14 - *
  102.15 - * 
  102.16 - * This program is free software; you can redistribute it and/or modify
  102.17 - * it under the terms of the GNU Lesser General Public License as published by
  102.18 - * the Free Software Foundation; either version 2 of the License, or
  102.19 - * (at your option) any later version.
  102.20 - *
  102.21 - * This program is distributed in the hope that it will be useful,
  102.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  102.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  102.24 - * GNU General Public License for more details.
  102.25 - *
  102.26 - * You should have received a copy of the GNU Lesser General Public License
  102.27 - * along with this program; if not, write to the Free Software
  102.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  102.29 - */
  102.30 -
  102.31 -#ifndef LIVETVCHAIN_H_
  102.32 -#define LIVETVCHAIN_H_
  102.33 -
  102.34 -#include <glib-object.h>
  102.35 -#include <time.h>
  102.36 -
  102.37 -#include "gmyth_common.h"
  102.38 -#include "gmyth_backendinfo.h"
  102.39 -
  102.40 -G_BEGIN_DECLS
  102.41 -#define GMYTH_TVCHAIN_TYPE               (gmyth_tvchain_get_type ())
  102.42 -#define GMYTH_TVCHAIN(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChain))
  102.43 -#define GMYTH_TVCHAIN_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
  102.44 -#define IS_GMYTH_TVCHAIN(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_TVCHAIN_TYPE))
  102.45 -#define IS_GMYTH_TVCHAIN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_TVCHAIN_TYPE))
  102.46 -#define GMYTH_TVCHAIN_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_TVCHAIN_TYPE, GMythTVChainClass))
  102.47 -typedef struct _GMythTVChain GMythTVChain;
  102.48 -typedef struct _GMythTVChainClass GMythTVChainClass;
  102.49 -
  102.50 -
  102.51 -struct LiveTVChainEntry {
  102.52 -    GString        *chanid;
  102.53 -
  102.54 -    GTimeVal       *starttime;
  102.55 -    GTimeVal       *endtime;
  102.56 -
  102.57 -    gboolean        discontinuity;  // if true, can't play smooth from
  102.58 -    // last entry
  102.59 -    GString        *hostprefix;
  102.60 -    GString        *cardtype;
  102.61 -    GString        *channum;
  102.62 -    GString        *inputname;
  102.63 -};
  102.64 -
  102.65 -
  102.66 -struct _GMythTVChainClass {
  102.67 -    GObjectClass    parent_class;
  102.68 -
  102.69 -    /*
  102.70 -     * callbacks 
  102.71 -     */
  102.72 -    /*
  102.73 -     * no one for now 
  102.74 -     */
  102.75 -};
  102.76 -
  102.77 -struct _GMythTVChain {
  102.78 -    GObject         parent;
  102.79 -
  102.80 -    GString        *tvchain_id;
  102.81 -    GList          *tvchain_list;
  102.82 -
  102.83 -    GTimeVal       *cur_startts;
  102.84 -    GString        *cur_chanid;
  102.85 -    gint            cur_pos;
  102.86 -
  102.87 -    GMythBackendInfo *backend_info;
  102.88 -
  102.89 -    GMutex         *mutex;
  102.90 -};
  102.91 -
  102.92 -GType           gmyth_tvchain_get_type(void);
  102.93 -
  102.94 -GMythTVChain   *gmyth_tvchain_new();
  102.95 -
  102.96 -gboolean        gmyth_tvchain_initialize(GMythTVChain * tvchain,
  102.97 -                                         GMythBackendInfo * backend_info);
  102.98 -gboolean        gmyth_tvchain_reload_all(GMythTVChain * tvchain);
  102.99 -GString        *gmyth_tvchain_get_id(GMythTVChain * tvchain);
 102.100 -gint            gmyth_tvchain_program_is_at(GMythTVChain * tvchain,
 102.101 -                                            GString * chanid,
 102.102 -                                            GTimeVal * startts);
 102.103 -
 102.104 -struct LiveTVChainEntry *gmyth_tvchain_get_entry_at(GMythTVChain * tvchain,
 102.105 -                                                    gint index);
 102.106 -
 102.107 -GMythProgramInfo *gmyth_tvchain_entry_to_program(GMythTVChain * tvchain, struct LiveTVChainEntry
 102.108 -                                                 *entry);
 102.109 -GMythProgramInfo *gmyth_tvchain_get_program_at(GMythTVChain * tvchain,
 102.110 -                                               gint index);
 102.111 -
 102.112 -GList          *gmyth_tvchain_get_program_info_from_channel(GMythTVChain *
 102.113 -                                                            tvchain,
 102.114 -                                                            const gchar *
 102.115 -                                                            channel);
 102.116 -
 102.117 -GList          *gmyth_tvchain_get_program_info_list(GMythTVChain *
 102.118 -                                                    tvchain);
 102.119 -
 102.120 -G_END_DECLS
 102.121 -#endif                          /* LIVETVCHAIN_H_ */
   103.1 --- a/gmyth/src/gmyth_uri.c	Mon Feb 25 17:45:36 2008 +0000
   103.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.3 @@ -1,604 +0,0 @@
   103.4 -/** 
   103.5 - * GMyth Library
   103.6 - *
   103.7 - * @file gmyth/gmyth_uri.c
   103.8 - * 
   103.9 - * @brief <p> GMythURI utils
  103.10 - *  - Extracts and parses a URI char string, in according with the RFC 2396 
  103.11 - *    [http://www.ietf.org/rfc/rfc2396.txt]
  103.12 - * 
  103.13 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
  103.14 - * @author Rosfran Borges <rosfran.borges@indt.org.br>
  103.15 - *
  103.16 - * 
  103.17 - * This program is free software; you can redistribute it and/or modify
  103.18 - * it under the terms of the GNU Lesser General Public License as published by
  103.19 - * the Free Software Foundation; either version 2 of the License, or
  103.20 - * (at your option) any later version.
  103.21 - *
  103.22 - * This program is distributed in the hope that it will be useful,
  103.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  103.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  103.25 - * GNU General Public License for more details.
  103.26 - *
  103.27 - * You should have received a copy of the GNU Lesser General Public License
  103.28 - * along with this program; if not, write to the Free Software
  103.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  103.30 - */
  103.31 -
  103.32 -#ifdef HAVE_CONFIG_H
  103.33 -#include "config.h"
  103.34 -#endif
  103.35 -
  103.36 -#include "gmyth_uri.h"
  103.37 -#include "gmyth_socket.h"
  103.38 -
  103.39 -#include <glib.h>
  103.40 -#include <string.h>
  103.41 -#include <stdlib.h>
  103.42 -
  103.43 -#include "gmyth_debug.h"
  103.44 -
  103.45 -/****************************************
  103.46 -* Define
  103.47 -****************************************/
  103.48 -
  103.49 -#define GMYTH_URI_KNKOWN_PORT               (-1)
  103.50 -#define GMYTH_URI_DEFAULT_HTTP_PORT         80
  103.51 -#define GMYTH_URI_DEFAULT_FTP_PORT          21
  103.52 -#define GMYTH_URI_DEFAULT_MYTH_PORT         6543
  103.53 -#define GMYTH_URI_DEFAULT_PATH              "/"
  103.54 -#define GMYTH_URI_MAXLEN                    256
  103.55 -
  103.56 -#define GMYTH_URI_PROTOCOL_DELIM            "://"
  103.57 -#define GMYTH_URI_USER_DELIM                "@"
  103.58 -#define GMYTH_URI_COLON_DELIM               ":"
  103.59 -#define GMYTH_URI_SLASH_DELIM               "/"
  103.60 -#define GMYTH_URI_SBLACET_DELIM             "["
  103.61 -#define GMYTH_URI_EBLACET_DELIM             "]"
  103.62 -#define GMYTH_URI_SHARP_DELIM               "#"
  103.63 -#define GMYTH_URI_QUESTION_DELIM            "?"
  103.64 -#define GMYTH_URI_E_DELIM                   "&"
  103.65 -#define GMYTH_URI_ESCAPING_CHAR             "%"
  103.66 -
  103.67 -#define GMYTH_URI_PROTOCOL_MYTH             "myth"
  103.68 -#define GMYTH_URI_PROTOCOL_HTTP             "http"
  103.69 -#define GMYTH_URI_PROTOCOL_FTP              "ftp"
  103.70 -
  103.71 -
  103.72 -static void     gmyth_uri_class_init(GMythURIClass * klass);
  103.73 -static void     gmyth_uri_init(GMythURI * object);
  103.74 -
  103.75 -static void     gmyth_uri_dispose(GObject * object);
  103.76 -static void     gmyth_uri_finalize(GObject * object);
  103.77 -
  103.78 -static void     gmyth_uri_parser_setup_and_new(GMythURI * uri,
  103.79 -                                               const gchar * value);
  103.80 -static gchar   *gmyth_uri_print_field(const GString * field);
  103.81 -
  103.82 -G_DEFINE_TYPE(GMythURI, gmyth_uri, G_TYPE_OBJECT)
  103.83 -    static void     gmyth_uri_class_init(GMythURIClass * klass)
  103.84 -{
  103.85 -    GObjectClass   *gobject_class;
  103.86 -
  103.87 -    gobject_class = (GObjectClass *) klass;
  103.88 -
  103.89 -    gobject_class->dispose = gmyth_uri_dispose;
  103.90 -    gobject_class->finalize = gmyth_uri_finalize;
  103.91 -}
  103.92 -
  103.93 -static void
  103.94 -gmyth_uri_init(GMythURI * gmyth_uri)
  103.95 -{
  103.96 -}
  103.97 -
  103.98 -static void
  103.99 -gmyth_uri_dispose(GObject * object)
 103.100 -{
 103.101 -    GMythURI       *gmyth_uri = GMYTH_URI(object);
 103.102 -
 103.103 -    if (gmyth_uri->host != NULL) {
 103.104 -        g_string_free(gmyth_uri->host, TRUE);
 103.105 -        gmyth_uri->host = NULL;
 103.106 -    }
 103.107 -
 103.108 -    if (gmyth_uri->protocol != NULL) {
 103.109 -        g_string_free(gmyth_uri->protocol, TRUE);
 103.110 -        gmyth_uri->protocol = NULL;
 103.111 -    }
 103.112 -
 103.113 -    if (gmyth_uri->path != NULL) {
 103.114 -        g_string_free(gmyth_uri->path, TRUE);
 103.115 -        gmyth_uri->path = NULL;
 103.116 -    }
 103.117 -
 103.118 -    if (gmyth_uri->fragment != NULL) {
 103.119 -        g_string_free(gmyth_uri->fragment, TRUE);
 103.120 -        gmyth_uri->fragment = NULL;
 103.121 -    }
 103.122 -
 103.123 -    if (gmyth_uri->user != NULL) {
 103.124 -        g_string_free(gmyth_uri->user, TRUE);
 103.125 -        gmyth_uri->user = NULL;
 103.126 -    }
 103.127 -
 103.128 -    if (gmyth_uri->password != NULL) {
 103.129 -        g_string_free(gmyth_uri->password, TRUE);
 103.130 -        gmyth_uri->password = NULL;
 103.131 -    }
 103.132 -
 103.133 -    if (gmyth_uri->query != NULL) {
 103.134 -        g_string_free(gmyth_uri->query, TRUE);
 103.135 -        gmyth_uri->query = NULL;
 103.136 -    }
 103.137 -
 103.138 -    if (gmyth_uri->uri != NULL) {
 103.139 -        g_string_free(gmyth_uri->uri, TRUE);
 103.140 -        gmyth_uri->uri = NULL;
 103.141 -    }
 103.142 -
 103.143 -
 103.144 -    G_OBJECT_CLASS(gmyth_uri_parent_class)->dispose(object);
 103.145 -}
 103.146 -
 103.147 -static void
 103.148 -gmyth_uri_finalize(GObject * object)
 103.149 -{
 103.150 -    // GMythURI *gmyth_uri = GMYTH_URI(object);
 103.151 -
 103.152 -    g_signal_handlers_destroy(object);
 103.153 -
 103.154 -    G_OBJECT_CLASS(gmyth_uri_parent_class)->finalize(object);
 103.155 -}
 103.156 -
 103.157 -/** 
 103.158 - * Creates a new instance of GMythURI.
 103.159 - * 
 103.160 - * @return a new instance of GMythURI.
 103.161 - */
 103.162 -GMythURI       *
 103.163 -gmyth_uri_new(void)
 103.164 -{
 103.165 -    GMythURI       *gmyth_uri =
 103.166 -        GMYTH_URI(g_object_new(GMYTH_URI_TYPE, NULL));
 103.167 -
 103.168 -    return gmyth_uri;
 103.169 -}
 103.170 -
 103.171 -/** 
 103.172 - * Creates a new instance of GMythURI.
 103.173 - * 
 103.174 - * @param uri_str The URI string representing this URI instance.
 103.175 - * 
 103.176 - * @return a new instance of GMythURI.
 103.177 - */
 103.178 -GMythURI       *
 103.179 -gmyth_uri_new_with_value(const gchar * uri_str)
 103.180 -{
 103.181 -    GMythURI       *gmyth_uri =
 103.182 -        GMYTH_URI(g_object_new(GMYTH_URI_TYPE, NULL));
 103.183 -
 103.184 -    gmyth_uri_parser_setup_and_new(gmyth_uri, uri_str);
 103.185 -
 103.186 -    return gmyth_uri;
 103.187 -}
 103.188 -
 103.189 -/** 
 103.190 - * Gets the starting offset of a substring inside a given string.
 103.191 - * 
 103.192 - * @param haystack The given string to be searched for patterns.
 103.193 - * @param needle The substring that should be matched over the haystack.
 103.194 - * 
 103.195 - * @return The starting offset to the given substring, or <code>-1</code> if the
 103.196 - * 				 haystack function parameter doesn't contains the needle string argument.
 103.197 - */
 103.198 -static          gint
 103.199 -gmyth_strstr(const gchar * haystack, const gchar * needle)
 103.200 -{
 103.201 -
 103.202 -    gchar          *strPos;
 103.203 -
 103.204 -    if (haystack == NULL || needle == NULL)
 103.205 -        return -1;
 103.206 -    strPos = strstr(haystack, needle);
 103.207 -    if (strPos == NULL)
 103.208 -        return -1;
 103.209 -
 103.210 -    return (strPos - haystack);
 103.211 -
 103.212 -}
 103.213 -
 103.214 -/** 
 103.215 - * Checks if a URI is absolute.
 103.216 - * 
 103.217 - * @param uri The GMythURI instance.
 103.218 - * 
 103.219 - * @return <code>true</code>, if the URI is absolute.
 103.220 - */
 103.221 -static          gboolean
 103.222 -gmyth_uri_isabsolute(const GMythURI * uri)
 103.223 -{
 103.224 -    gboolean        ret = FALSE;
 103.225 -
 103.226 -    g_return_val_if_fail(uri != NULL && uri->uri != NULL
 103.227 -                         && uri->protocol != NULL, FALSE);
 103.228 -
 103.229 -    if (gmyth_strstr(uri->uri->str, GMYTH_URI_PROTOCOL_DELIM) == 0
 103.230 -        || strlen(uri->protocol->str) > 0)
 103.231 -        ret = TRUE;
 103.232 -
 103.233 -    return ret;
 103.234 -}
 103.235 -
 103.236 -/** 
 103.237 - * Searches for the first reverse character occurrence, from a given 
 103.238 - * list of characters, inside a given string.
 103.239 - * 
 103.240 - * @param str The given string to be searched for characters occurrence.
 103.241 - * @param chars The characters list. If this string returns 4 on strlen, there are
 103.242 - * 						  four possible characters to be matched.
 103.243 - * @param nchars The number of characters to be matched, which has at most 
 103.244 - * 							 strlen(chars).
 103.245 - * 
 103.246 - * @return The starting offset to the first character occurrence, 
 103.247 - *         or <code>-1</code> if the no character of the list could be found.
 103.248 - */
 103.249 -static          gint
 103.250 -gmyth_strrchr(const gchar * str, const gchar * chars, const gint nchars)
 103.251 -{
 103.252 -
 103.253 -    gint            strLen;
 103.254 -    gint            i,
 103.255 -                    j;
 103.256 -
 103.257 -    if (str == NULL || chars == NULL)
 103.258 -        return -1;
 103.259 -
 103.260 -    strLen = strlen(str);
 103.261 -    for (i = (strLen - 1); 0 <= i; i--) {
 103.262 -        for (j = 0; j < nchars; j++) {
 103.263 -            if (str[i] == chars[j])
 103.264 -                return i;
 103.265 -        }
 103.266 -    }
 103.267 -
 103.268 -    return -1;
 103.269 -
 103.270 -}
 103.271 -
 103.272 -static gchar   *
 103.273 -gmyth_uri_print_field(const GString * field)
 103.274 -{
 103.275 -    if (field != NULL && field->str != NULL && strlen(field->str) > 0)
 103.276 -        return field->str;
 103.277 -    else
 103.278 -        return "";
 103.279 -}
 103.280 -
 103.281 -static gint
 103.282 -gmyth_uri_get_default_port (GMythURI * uri)
 103.283 -{
 103.284 -    const gchar  *protocol = gmyth_uri_get_protocol(uri);
 103.285 -
 103.286 -    if (strcmp(protocol, GMYTH_URI_PROTOCOL_HTTP) == 0)
 103.287 -        return GMYTH_URI_DEFAULT_HTTP_PORT;
 103.288 -    if (strcmp(protocol, GMYTH_URI_PROTOCOL_FTP) == 0)
 103.289 -        return GMYTH_URI_DEFAULT_FTP_PORT;
 103.290 -    if (strcmp(protocol, GMYTH_URI_PROTOCOL_MYTH) == 0)
 103.291 -        return GMYTH_URI_DEFAULT_MYTH_PORT;
 103.292 -
 103.293 -    return GMYTH_URI_KNKOWN_PORT;
 103.294 -}
 103.295 -
 103.296 -/** 
 103.297 - * Parses a URI string into a GMythURI instance.
 103.298 - * 
 103.299 - * @param uri The GMythURI instance.
 103.300 - * @param value The URI string to be parsed.
 103.301 - *
 103.302 - */
 103.303 -static void
 103.304 -gmyth_uri_parser_setup_and_new(GMythURI * uri, const gchar * value)
 103.305 -{
 103.306 -
 103.307 -    gint            uriLen;
 103.308 -    gint            currIdx;
 103.309 -    gint            protoIdx;
 103.310 -    gint            atIdx;
 103.311 -    gint            colonIdx;
 103.312 -    gint            shashIdx;
 103.313 -    gint            eIdx;
 103.314 -    gchar          *host;
 103.315 -    gint            eblacketIdx;
 103.316 -    gint            hostLen;
 103.317 -    gint            sharpIdx;
 103.318 -
 103.319 -    /*
 103.320 -     * gint questionIdx; gint queryLen; 
 103.321 -     */
 103.322 -
 103.323 -    uriLen = strlen(value);
 103.324 -    uri->uri = g_string_new(value);
 103.325 -
 103.326 -    currIdx = 0;
 103.327 -
 103.328 -    /*** Protocol ****/
 103.329 -    protoIdx = gmyth_strstr(value, GMYTH_URI_PROTOCOL_DELIM);
 103.330 -    if (0 < protoIdx) {
 103.331 -        uri->protocol = g_string_new_len(value, protoIdx);
 103.332 -        currIdx += protoIdx + strlen(GMYTH_URI_PROTOCOL_DELIM);
 103.333 -    }
 103.334 -
 103.335 -    /*** User (Password) ****/
 103.336 -    atIdx = gmyth_strstr(value + currIdx, GMYTH_URI_USER_DELIM);
 103.337 -    if (0 < atIdx) {
 103.338 -        colonIdx = gmyth_strstr(value + currIdx, GMYTH_URI_COLON_DELIM);
 103.339 -
 103.340 -        if (0 < colonIdx && colonIdx < atIdx) {
 103.341 -            uri->user = g_string_new_len(value + currIdx, colonIdx);
 103.342 -            uri->password =
 103.343 -                g_string_new_len(value + currIdx + colonIdx + 1,
 103.344 -                                 atIdx - (colonIdx + 1));
 103.345 -        } else
 103.346 -            uri->user = g_string_new_len(value + currIdx, atIdx - currIdx);
 103.347 -        currIdx += atIdx + 1;
 103.348 -    }
 103.349 -
 103.350 -    /*** Host (Port) ****/
 103.351 -    shashIdx = gmyth_strstr(value + currIdx, GMYTH_URI_SLASH_DELIM);
 103.352 -    if (0 < shashIdx)
 103.353 -        uri->host = g_string_new_len(value + currIdx, shashIdx);
 103.354 -    else if (gmyth_uri_isabsolute(uri) == TRUE)
 103.355 -        uri->host =
 103.356 -            g_string_new_len(value + currIdx, strlen(value) - currIdx);
 103.357 -
 103.358 -    host = gmyth_uri_get_host(uri);
 103.359 -    colonIdx = gmyth_strrchr(host, GMYTH_URI_COLON_DELIM, 1);
 103.360 -    eblacketIdx = gmyth_strrchr(host, GMYTH_URI_EBLACET_DELIM, 1);
 103.361 -    if ((0 < colonIdx) && (eblacketIdx < colonIdx)) {
 103.362 -        GString        *portStr = NULL;
 103.363 -        GString        *hostStr = g_string_new(host != NULL ? host : "");
 103.364 -
 103.365 -        hostLen = hostStr->len;
 103.366 -        /**** host ****/
 103.367 -        uri->host = g_string_erase(uri->host, 0, hostLen);
 103.368 -        uri->host =
 103.369 -            g_string_insert_len(uri->host, 0, hostStr->str, colonIdx);
 103.370 -        if (0 < hostLen) {
 103.371 -            if (host[0] == '[' && host[hostLen - 1] == ']')
 103.372 -                uri->host =
 103.373 -                    g_string_new_len(hostStr->str + 1, colonIdx - 2);
 103.374 -        }
 103.375 -
 103.376 -        /**** port ****/
 103.377 -        portStr = g_string_new_len(hostStr->str + colonIdx + 1,
 103.378 -                                   hostLen - colonIdx - 1);
 103.379 -        uri->port = (gint) g_ascii_strtoull(portStr->str, NULL, 10);
 103.380 -        g_string_free(portStr, TRUE);
 103.381 -        g_string_free(hostStr, TRUE);
 103.382 -    } else {
 103.383 -        uri->port = gmyth_uri_get_default_port (uri);
 103.384 -    }
 103.385 -
 103.386 -    if (shashIdx > 0)
 103.387 -        currIdx += shashIdx;
 103.388 -
 103.389 -    /*
 103.390 -     * Handle relative URL 
 103.391 -     */
 103.392 -    if (gmyth_uri_isabsolute(uri) == FALSE) {
 103.393 -
 103.394 -        if (shashIdx != 0) {
 103.395 -            /*
 103.396 -             * Add slash delimiter at the beginning of the URL, if it
 103.397 -             * doesn't exist 
 103.398 -             */
 103.399 -            uri->path = g_string_new(GMYTH_URI_SLASH_DELIM);
 103.400 -        }
 103.401 -        uri->path = g_string_append(uri->path, value);
 103.402 -
 103.403 -    } else {
 103.404 -        /*
 103.405 -         * First set path simply to the rest of URI 
 103.406 -         */
 103.407 -        uri->path = g_string_new_len(value + currIdx, uriLen - currIdx);
 103.408 -    }
 103.409 -
 103.410 -    // gmyth_debug( "uri value: %s", value );
 103.411 -    uri->query =
 103.412 -        g_string_new(g_strstr_len
 103.413 -                     (value, strlen(value), GMYTH_URI_QUESTION_DELIM));
 103.414 -
 103.415 -    eIdx = gmyth_strstr(value + currIdx, GMYTH_URI_QUESTION_DELIM);
 103.416 -
 103.417 -    if (0 < eIdx) {
 103.418 -        uri->query =
 103.419 -            g_string_new(g_strstr_len
 103.420 -                         (value, strlen(value), GMYTH_URI_QUESTION_DELIM));
 103.421 -        gmyth_debug("query = %s", uri->query->str);
 103.422 -    }
 103.423 -
 103.424 -    /**** Path (Query/Fragment) ****/
 103.425 -    sharpIdx = gmyth_strstr(value + currIdx, GMYTH_URI_E_DELIM);
 103.426 -    if (0 < sharpIdx) {
 103.427 -        uri->path =
 103.428 -            g_string_append_len(uri->path, value + currIdx, sharpIdx);
 103.429 -        uri->fragment =
 103.430 -            g_string_new_len(value + currIdx + sharpIdx + 1,
 103.431 -                             uriLen - (currIdx + sharpIdx + 1));
 103.432 -    }
 103.433 -
 103.434 -    gmyth_debug
 103.435 -        ("[%s] GMythURI: host = %s, port = %d, path = %s, query = %s, fragment = %s, "
 103.436 -         "user = %s, password = %s.\n", __FUNCTION__,
 103.437 -         gmyth_uri_print_field(uri->host), uri->port,
 103.438 -         gmyth_uri_print_field(uri->path),
 103.439 -         gmyth_uri_print_field(uri->query),
 103.440 -         gmyth_uri_print_field(uri->fragment),
 103.441 -         gmyth_uri_print_field(uri->user),
 103.442 -         gmyth_uri_print_field(uri->password));
 103.443 -
 103.444 -}
 103.445 -
 103.446 -/** 
 103.447 - * Compares 2 URI instances, and checks them for equality.
 103.448 - * 
 103.449 - * @param uri The first GMythURI instance for comparison.
 103.450 - * @param uri The second GMythURI instance for comparison.
 103.451 - * 
 103.452 - * @return <code>true</code>, if these two URI instances are equals.
 103.453 - */
 103.454 -gboolean
 103.455 -gmyth_uri_is_equals(GMythURI * uri1, GMythURI * uri2)
 103.456 -{
 103.457 -    return (g_ascii_strcasecmp
 103.458 -            (gmyth_uri_get_host(uri1), gmyth_uri_get_host(uri2)) == 0
 103.459 -            && gmyth_uri_get_port(uri1) == gmyth_uri_get_port(uri2));
 103.460 -}
 103.461 -
 103.462 -/** 
 103.463 - * Checks if the URI instance represents a LiveTV recording.
 103.464 - * 
 103.465 - * @param uri The GMythURI instance.
 103.466 - * 
 103.467 - * @return <code>true</code>, if the URI points to LiveTV content.
 103.468 - */
 103.469 -gboolean
 103.470 -gmyth_uri_is_livetv(GMythURI * uri)
 103.471 -{
 103.472 -    gboolean        ret = TRUE;
 103.473 -
 103.474 -    g_return_val_if_fail(uri != NULL, FALSE);
 103.475 -    g_return_val_if_fail(uri->uri != NULL, FALSE);
 103.476 -    g_return_val_if_fail(uri->uri->str != NULL, FALSE);
 103.477 -
 103.478 -    if ((strstr(uri->uri->str, "channel=") == NULL) &&
 103.479 -        (strstr(uri->uri->str, "livetv") == NULL))
 103.480 -        ret = FALSE;
 103.481 -
 103.482 -    if (ret)
 103.483 -        gmyth_debug("This URI is a LiveTV recording...");
 103.484 -    else
 103.485 -        gmyth_debug("This URI is a stored remote recording.");
 103.486 -
 103.487 -    return ret;
 103.488 -
 103.489 -}
 103.490 -
 103.491 -/** 
 103.492 - * Gets the channel name fro a URI instance.
 103.493 - * 
 103.494 - * @param uri The GMythURI instance.
 103.495 - * 
 103.496 - * @return The channel name, got from the substring "?channel=[channel_name]"
 103.497 - * 				 of the URI string.
 103.498 - */
 103.499 -gchar          *
 103.500 -gmyth_uri_get_channel_name(GMythURI * uri)
 103.501 -{
 103.502 -    gchar          *channel = NULL;
 103.503 -
 103.504 -    g_return_val_if_fail(uri != NULL && uri->uri != NULL
 103.505 -                         && uri->uri->str != NULL, FALSE);
 103.506 -
 103.507 -    gchar          *channel_query = g_strstr_len(gmyth_uri_get_query(uri),
 103.508 -                                                 strlen(gmyth_uri_get_query
 103.509 -                                                        (uri)),
 103.510 -                                                 "channel");
 103.511 -
 103.512 -    if (channel_query != NULL) {
 103.513 -        gchar         **chan_key_value =
 103.514 -            g_strsplit(gmyth_uri_get_query(uri), "=", 2);
 103.515 -
 103.516 -        /*
 103.517 -         * gmyth_debug( "Channel tuple is [ %s, %s ]", chan_key_value[0],
 103.518 -         * chan_key_value[1] ); 
 103.519 -         */
 103.520 -
 103.521 -        if (chan_key_value[1] != NULL && strlen(chan_key_value[1]) > 0) {
 103.522 -            channel = g_strdup(chan_key_value[1]);
 103.523 -        }
 103.524 -
 103.525 -        if (chan_key_value != NULL)
 103.526 -            g_strfreev(chan_key_value);
 103.527 -    }
 103.528 -
 103.529 -    gmyth_debug("Got channel decimal value from the URI: %s", channel);
 103.530 -
 103.531 -    return channel;
 103.532 -
 103.533 -}
 103.534 -
 103.535 -/** 
 103.536 - * Gets the channel number from a URI instance.
 103.537 - * 
 103.538 - * @param uri The GMythURI instance.
 103.539 - * 
 103.540 - * @return The channel number, got from the substring "?channel=[channel_number]"
 103.541 - * 				 of the URI string, or <code>-1</code> it if couldn't be converted.
 103.542 - */
 103.543 -gint
 103.544 -gmyth_uri_get_channel_num(GMythURI * uri)
 103.545 -{
 103.546 -    gchar          *channel_name = gmyth_uri_get_channel_name(uri);
 103.547 -
 103.548 -    if (channel_name != NULL) {
 103.549 -        return g_ascii_strtoull(channel_name, NULL, 10);
 103.550 -    }
 103.551 -
 103.552 -    return -1;
 103.553 -
 103.554 -}
 103.555 -
 103.556 -/** 
 103.557 - * Checks if the URI instance represents a reference to a local file.
 103.558 - * 
 103.559 - * @param uri The GMythURI instance.
 103.560 - * 
 103.561 - * @return <code>true</code>, if the URI points to a local file.
 103.562 - */
 103.563 -gboolean
 103.564 -gmyth_uri_is_local_file(const GMythURI * uri)
 103.565 -{
 103.566 -    gboolean        ret = FALSE;
 103.567 -    gint            len = -1;
 103.568 -
 103.569 -    GString        *hostname = gmyth_socket_get_local_hostname();
 103.570 -
 103.571 -    g_return_val_if_fail(uri != NULL, FALSE);
 103.572 -
 103.573 -    len = strlen(gmyth_uri_get_host(uri));
 103.574 -
 103.575 -    // gmyth_debug("URI: host = %s, hostname = %s.", uri->host->str,
 103.576 -    // hostname != NULL ? hostname->str : "[no hostname]");
 103.577 -
 103.578 -    ret = (NULL != hostname && (g_ascii_strncasecmp(uri->host->str, (hostname)->str, len) == 0) /* || 
 103.579 -                                                                                                 * ( 
 103.580 -                                                                                                 * g_ascii_strncasecmp( 
 103.581 -                                                                                                 * gmyth_uri_get_host(uri), 
 103.582 -                                                                                                 * gmyth_socket_get_primary_addr(), 
 103.583 -                                                                                                 * len 
 103.584 -                                                                                                 * ) 
 103.585 -                                                                                                 * == 
 103.586 -                                                                                                 * 0 
 103.587 -                                                                                                 * ) 
 103.588 -                                                                                                 */
 103.589 -        );
 103.590 -
 103.591 -    if (ret)
 103.592 -        gmyth_debug("This URI is a local file...");
 103.593 -    else
 103.594 -        gmyth_debug("This URI is NOT a local file...");
 103.595 -
 103.596 -    return ret;
 103.597 -
 103.598 -}
 103.599 -
 103.600 -char           *
 103.601 -gmyth_uri_to_string(const GMythURI * uri)
 103.602 -{
 103.603 -    g_return_val_if_fail(uri != NULL, NULL);
 103.604 -    g_return_val_if_fail(uri->uri != NULL, NULL);
 103.605 -
 103.606 -    return g_strdup(uri->uri->str);
 103.607 -}
   104.1 --- a/gmyth/src/gmyth_uri.h	Mon Feb 25 17:45:36 2008 +0000
   104.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   104.3 @@ -1,101 +0,0 @@
   104.4 -/**
   104.5 - * GMyth Library
   104.6 - *
   104.7 - * @file gmyth/gmyth_uri.h
   104.8 - * 
   104.9 - * @brief <p> GMythURI utils
  104.10 - *  - Extracts and parses a URI char string, in according with the RFC 2396 
  104.11 - *    [http://www.ietf.org/rfc/rfc2396.txt]
  104.12 - * 
  104.13 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
  104.14 - * @author Rosfran Borges <rosfran.borges@indt.org.br>
  104.15 - *
  104.16 - * 
  104.17 - * This program is free software; you can redistribute it and/or modify
  104.18 - * it under the terms of the GNU Lesser General Public License as published by
  104.19 - * the Free Software Foundation; either version 2 of the License, or
  104.20 - * (at your option) any later version.
  104.21 - *
  104.22 - * This program is distributed in the hope that it will be useful,
  104.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  104.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  104.25 - * GNU General Public License for more details.
  104.26 - *
  104.27 - * You should have received a copy of the GNU Lesser General Public License
  104.28 - * along with this program; if not, write to the Free Software
  104.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  104.30 - */
  104.31 -
  104.32 -#ifndef _GMYTH_URI_H_
  104.33 -#define _GMYTH_URI_H_
  104.34 -
  104.35 -#include <glib.h>
  104.36 -#include <glib-object.h>
  104.37 -
  104.38 -#include <stdlib.h>
  104.39 -#include <stdio.h>
  104.40 -#include <string.h>
  104.41 -
  104.42 -G_BEGIN_DECLS
  104.43 -#define GMYTH_URI_TYPE               (gmyth_uri_get_type ())
  104.44 -#define GMYTH_URI(obj)          		 (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_URI_TYPE, GMythURI))
  104.45 -#define GMYTH_URI_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_URI_TYPE, GMythURIClass))
  104.46 -#define IS_GMYTH_URI(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_URI_TYPE))
  104.47 -#define IS_GMYTH_URI_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_URI_TYPE))
  104.48 -#define GMYTH_URI_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_URI_TYPE, GMythURIClass))
  104.49 -typedef struct _GMythURI GMythURI;
  104.50 -typedef struct _GMythURIClass GMythURIClass;
  104.51 -
  104.52 -
  104.53 -    /****************************************
  104.54 -	 * Data Type
  104.55 -	 ****************************************/
  104.56 -
  104.57 -struct _GMythURIClass {
  104.58 -    GObjectClass    parent_class;
  104.59 -
  104.60 -    /*
  104.61 -     * callbacks 
  104.62 -     */
  104.63 -    /*
  104.64 -     * no one for now 
  104.65 -     */
  104.66 -};
  104.67 -
  104.68 -struct _GMythURI {
  104.69 -
  104.70 -    GObject         parent;
  104.71 -
  104.72 -    GString        *uri;
  104.73 -    GString        *host;
  104.74 -    gint            port;
  104.75 -    GString        *protocol;
  104.76 -    GString        *path;
  104.77 -    GString        *fragment;
  104.78 -    GString        *user;
  104.79 -    GString        *password;
  104.80 -    GString        *query;
  104.81 -
  104.82 -};
  104.83 -
  104.84 -GType           gmyth_uri_get_type(void);
  104.85 -GMythURI       *gmyth_uri_new(void);
  104.86 -GMythURI       *gmyth_uri_new_with_value(const gchar * value);
  104.87 -gboolean        gmyth_uri_is_equals(GMythURI * uri1, GMythURI * uri2);
  104.88 -gboolean        gmyth_uri_is_livetv(GMythURI * uri);
  104.89 -gint            gmyth_uri_get_channel_num(GMythURI * uri);
  104.90 -gchar          *gmyth_uri_get_channel_name(GMythURI * uri);
  104.91 -char           *gmyth_uri_to_string(const GMythURI * uri);
  104.92 -gboolean        gmyth_uri_is_local_file(const GMythURI * uri);
  104.93 -
  104.94 -#define 	gmyth_uri_get_host(urip) 			( urip->host != NULL ? urip->host->str : "" )
  104.95 -#define 	gmyth_uri_get_port(urip) 			( urip->port )
  104.96 -#define 	gmyth_uri_get_protocol(urip) 	( urip->protocol != NULL ? urip->protocol->str : "" )
  104.97 -#define 	gmyth_uri_get_path(urip) 			( urip->path != NULL ? urip->path->str : "" )
  104.98 -#define 	gmyth_uri_get_user(urip) 			( urip->user != NULL ? urip->user->str : "" )
  104.99 -#define    	gmyth_uri_get_password(urip) 	( urip->password != NULL ? urip->password->str : "" )
 104.100 -#define 	gmyth_uri_get_fragment(urip) 	( urip->fragment != NULL ? urip->fragment->str : "" )
 104.101 -#define 	gmyth_uri_get_query(urip) 		( urip->query != NULL ? urip->query->str : "" )
 104.102 -
 104.103 -G_END_DECLS
 104.104 -#endif                          /* _GMYTH_URI_H_ */
   105.1 --- a/gmyth/src/gmyth_util.c	Mon Feb 25 17:45:36 2008 +0000
   105.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.3 @@ -1,957 +0,0 @@
   105.4 -/**
   105.5 - * GMyth Library
   105.6 - *
   105.7 - * @file gmyth/gmyth_util.c
   105.8 - * 
   105.9 - * @brief <p> This component provides utility functions 
  105.10 - * 	(dealing with dates, time, string formatting, etc.).
  105.11 - * 
  105.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
  105.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
  105.14 - * @author Rosfran Borges <rosfran.borges@indt.org.br>
  105.15 - *
  105.16 - * 
  105.17 - * This program is free software; you can redistribute it and/or modify
  105.18 - * it under the terms of the GNU Lesser General Public License as published by
  105.19 - * the Free Software Foundation; either version 2 of the License, or
  105.20 - * (at your option) any later version.
  105.21 - *
  105.22 - * This program is distributed in the hope that it will be useful,
  105.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  105.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  105.25 - * GNU General Public License for more details.
  105.26 - *
  105.27 - * You should have received a copy of the GNU Lesser General Public License
  105.28 - * along with this program; if not, write to the Free Software
  105.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  105.30 - */
  105.31 -
  105.32 -#ifdef HAVE_CONFIG_H
  105.33 -#include "config.h"
  105.34 -#endif
  105.35 -
  105.36 -#define _XOPEN_SOURCE
  105.37 -#define _XOPEN_SOURCE_EXTENDED
  105.38 -#define __USE_MISC
  105.39 -
  105.40 -#include <glib.h>
  105.41 -#include <glib/gprintf.h>
  105.42 -#include <time.h>
  105.43 -#include <sys/time.h>
  105.44 -#include <sys/timex.h>
  105.45 -
  105.46 -#include "gmyth_socket.h"
  105.47 -#include "gmyth_recorder.h"
  105.48 -#include "gmyth_common.h"
  105.49 -#include "gmyth_debug.h"
  105.50 -
  105.51 -#include "gmyth_util.h"
  105.52 -
  105.53 -#if !GLIB_CHECK_VERSION (2, 10, 0)
  105.54 -gchar          *g_time_val_to_iso8601(GTimeVal * time_);
  105.55 -gboolean        g_time_val_from_iso8601(const gchar * iso_date,
  105.56 -                                        GTimeVal * time_);
  105.57 -void            g_date_set_time_val(GDate * date, GTimeVal * timeval);
  105.58 -
  105.59 -#endif
  105.60 -
  105.61 -/** Converts a time_t struct in a GString at ISO standard format 
  105.62 - * (e.g. 2006-07-20T09:56:41).
  105.63 - * 
  105.64 - * The returned GString memory should be deallocated from 
  105.65 - * the calling function.
  105.66 - *
  105.67 - * @param time_value the time value to be converted
  105.68 - * @return GString* the converted isoformat string 
  105.69 - */
  105.70 -GString        *
  105.71 -gmyth_util_time_to_isoformat(time_t time_value)
  105.72 -{
  105.73 -    struct tm       tm_time;
  105.74 -    GString        *result;
  105.75 -
  105.76 -    if (localtime_r(&time_value, &tm_time) == NULL) {
  105.77 -        gmyth_debug("gmyth_util_time_to_isoformat convertion error!\n");
  105.78 -        return NULL;
  105.79 -    }
  105.80 -
  105.81 -    result = g_string_sized_new(20);
  105.82 -    g_string_printf(result, "%04d-%02d-%02dT%02d:%02d:%02d",
  105.83 -                    tm_time.tm_year + 1900, tm_time.tm_mon + 1,
  105.84 -                    tm_time.tm_mday, tm_time.tm_hour, tm_time.tm_min,
  105.85 -                    tm_time.tm_sec);
  105.86 -
  105.87 -    gmyth_debug("Result (ISO 8601) = %s", result->str);
  105.88 -
  105.89 -    return result;
  105.90 -}
  105.91 -
  105.92 -/** Converts a time_t struct in a GString at ISO standard format 
  105.93 - * (e.g. 2006-07-20T09:56:41).
  105.94 - * 
  105.95 - * The returned GString memory should be deallocated from 
  105.96 - * the calling function.
  105.97 - *
  105.98 - * @param time_value the GTimeValue to be converted
  105.99 - * @return GString* the converted isoformat string 
 105.100 - */
 105.101 -gchar          *
 105.102 -gmyth_util_time_to_isoformat_from_time_val_fmt(const gchar * fmt_string,
 105.103 -                                               const GTimeVal * time_val)
 105.104 -{
 105.105 -    gchar          *result = NULL;
 105.106 -    struct tm      *tm_time = NULL;
 105.107 -    time_t          time;
 105.108 -
 105.109 -    gint            buffer_len = 0;
 105.110 -
 105.111 -    g_return_val_if_fail(fmt_string != NULL, NULL);
 105.112 -
 105.113 -    g_return_val_if_fail(time_val != NULL, NULL);
 105.114 -
 105.115 -    time = time_val->tv_sec;    // + (gint)( time_val->tv_usec /
 105.116 -    // G_USEC_PER_SEC );
 105.117 -
 105.118 -    tm_time = g_malloc0(sizeof(struct tm));
 105.119 -
 105.120 -    if (NULL == localtime_r(&time, tm_time)) {
 105.121 -        gmyth_debug("gmyth_util_time_to_isoformat convertion error!\n");
 105.122 -    } else {
 105.123 -        /*
 105.124 -         * we first check the return of strftime to allocate a buffer of
 105.125 -         * the correct size 
 105.126 -         */
 105.127 -        buffer_len = strftime(NULL, SSIZE_MAX, fmt_string, tm_time);
 105.128 -        if (buffer_len > 0) {
 105.129 -            result = g_malloc0(buffer_len + 1);
 105.130 -            if (result == NULL) {
 105.131 -                gmyth_debug
 105.132 -                    ("gmyth_util_time_to_isoformat convertion error!\n");
 105.133 -                return NULL;
 105.134 -            }
 105.135 -            strftime(result, buffer_len + 1, fmt_string, tm_time);
 105.136 -            gmyth_debug("Dateline (ISO result): %s", result);
 105.137 -        }
 105.138 -    }                           /* if */
 105.139 -
 105.140 -    gmyth_debug("Result (strftime) = %s", result);
 105.141 -
 105.142 -    // strptime( result, "%Y-%m-%dT%H:%M:%SZ", tm_time ); 
 105.143 -
 105.144 -    // strftime( result, strlen(result), fmt_string, tm_time );
 105.145 -
 105.146 -    g_free(tm_time);
 105.147 -
 105.148 -    gmyth_debug("Result (ISO 8601) = %s", result);
 105.149 -
 105.150 -    return result;
 105.151 -}
 105.152 -
 105.153 -/** Converts a time_t struct in a GString at ISO standard format 
 105.154 - * (e.g. 2006-07-20 09:56:41).
 105.155 - * 
 105.156 - * The returned GString memory should be deallocated from 
 105.157 - * the calling function.
 105.158 - *
 105.159 - * @param time_value the GTimeValue to be converted
 105.160 - * @return GString* the converted isoformat string 
 105.161 - */
 105.162 -gchar          *
 105.163 -gmyth_util_time_to_isoformat_from_time_val(const GTimeVal * time)
 105.164 -{
 105.165 -    gchar          *result =
 105.166 -        gmyth_util_time_to_isoformat_from_time_val_fmt("%Y-%m-%d %H:%M:%S",
 105.167 -                                                       time);
 105.168 -
 105.169 -    // result[10] = ' ';
 105.170 -    // result[ strlen(result) - 1] = '\0';
 105.171 -
 105.172 -    return result;
 105.173 -}
 105.174 -
 105.175 -/** Converts a time_t struct in a GString at ISO standard format 2 
 105.176 - * (e.g. 2006-07-20T09:56:41).
 105.177 - * 
 105.178 - * The returned GString memory should be deallocated from 
 105.179 - * the calling function.
 105.180 - *
 105.181 - * @param time_value the GTimeValue to be converted
 105.182 - * @return GString* the converted isoformat string 
 105.183 - */
 105.184 -gchar          *
 105.185 -gmyth_util_time_to_mythformat_from_time_val(const GTimeVal * time)
 105.186 -{
 105.187 -    gchar          *result =
 105.188 -        gmyth_util_time_to_isoformat_from_time_val_fmt("%Y-%m-%dT%H:%M:%S",
 105.189 -                                                       time);
 105.190 -
 105.191 -    return result;
 105.192 -}
 105.193 -
 105.194 -/** Converts a time_t struct in a GString at ISO standard format 
 105.195 - * (e.g. 2006-07-20T09:56:41).
 105.196 - * 
 105.197 - * The returned GString memory should be deallocated from 
 105.198 - * the calling function.
 105.199 - *
 105.200 - * @param time_value the GTimeValue to be converted
 105.201 - * @return GString* the converted isoformat string 
 105.202 - */
 105.203 -gchar          *
 105.204 -gmyth_util_time_to_string_only_date(const GTimeVal * time)
 105.205 -{
 105.206 -    gchar          *result =
 105.207 -        gmyth_util_time_to_isoformat_from_time_val_fmt("%Y-%m-%d", time);
 105.208 -    // result[10] = ' ';
 105.209 -    // result[ strlen(result) - 1] = '\0';
 105.210 -    return result;
 105.211 -}
 105.212 -
 105.213 -/** Converts a time_t struct in a GString at ISO standard format 
 105.214 - * (e.g. 2006-07-20T09:56:41).
 105.215 - * 
 105.216 - * The returned GString memory should be deallocated from 
 105.217 - * the calling function.
 105.218 - *
 105.219 - * @param time_value the GTimeValue to be converted
 105.220 - * @return GString* the converted isoformat string 
 105.221 - */
 105.222 -gchar          *
 105.223 -gmyth_util_time_to_string_only_time(const GTimeVal * time)
 105.224 -{
 105.225 -    gchar          *result =
 105.226 -        gmyth_util_time_to_isoformat_from_time_val_fmt("%H:%M:%S", time);
 105.227 -    // result[10] = ' ';
 105.228 -    // result[ strlen(result) - 1] = '\0';
 105.229 -    return result;
 105.230 -}
 105.231 -
 105.232 -/** Converts a time_t struct in a GString to the following 
 105.233 - * format (e.g. 2006-07-20 09:56:41).
 105.234 - * 
 105.235 - * The returned GString memory should be deallocated from 
 105.236 - * the calling function.
 105.237 - *
 105.238 - * @param time_value the time value to be converted
 105.239 - * @return GString* the converted string 
 105.240 - */
 105.241 -GString        *
 105.242 -gmyth_util_time_to_string(time_t time_value)
 105.243 -{
 105.244 -    GString        *result = gmyth_util_time_to_isoformat(time_value);
 105.245 -
 105.246 -    result->str[10] = ' ';
 105.247 -    result->str[strlen(result->str) - 1] = '\0';
 105.248 -
 105.249 -    return result;
 105.250 -}
 105.251 -
 105.252 -/** Converts a time_t struct in a GString to the following 
 105.253 - * format (e.g. 2006-07-20 09:56:41).
 105.254 - * 
 105.255 - * The returned GString memory should be deallocated from 
 105.256 - * the calling function.
 105.257 - *
 105.258 - * @param time_value the time value to be converted
 105.259 - * @return GString* the converted string 
 105.260 - */
 105.261 -gchar          *
 105.262 -gmyth_util_time_to_string_from_time_val(const GTimeVal * time_val)
 105.263 -{
 105.264 -    gchar          *result =
 105.265 -        gmyth_util_time_to_isoformat_from_time_val_fmt("%Y-%m-%d %H:%M:%S",
 105.266 -                                                       time_val);
 105.267 -
 105.268 -    // result[10] = ' ';
 105.269 -
 105.270 -    return result;
 105.271 -}
 105.272 -
 105.273 -/** Converts a GString in the following format 
 105.274 - * (e.g. 2006-07-20 09:56:41) to a time_t struct.
 105.275 - * 
 105.276 - * @param time_str the string to be converted
 105.277 - * @return time_t the time converted value
 105.278 - */
 105.279 -time_t
 105.280 -gmyth_util_string_to_time(GString * time_str)
 105.281 -{
 105.282 -    gint            year,
 105.283 -                    month,
 105.284 -                    day,
 105.285 -                    hour,
 105.286 -                    min,
 105.287 -                    sec;
 105.288 -
 105.289 -    gmyth_debug("[%s] time_str = %s. [%s]", __FUNCTION__,
 105.290 -                time_str !=
 105.291 -                NULL ? time_str->str : "[time string is NULL!]",
 105.292 -                time_str->str);
 105.293 -
 105.294 -    if (sscanf(time_str->str, "%04d-%02d-%02d %02d:%02d:%02d",
 105.295 -               &year, &month, &day, &hour, &min, &sec) < 3) {
 105.296 -        gmyth_debug("GMythUtil: isoformat_to_time converter error!\n");
 105.297 -        return 0;
 105.298 -    }
 105.299 -
 105.300 -    struct tm      *tm_time = g_malloc0(sizeof(struct tm));
 105.301 -
 105.302 -    tm_time->tm_year = year - 1900;
 105.303 -    tm_time->tm_mon = month - 1;
 105.304 -    tm_time->tm_mday = day;
 105.305 -    tm_time->tm_hour = hour;
 105.306 -    tm_time->tm_min = min;
 105.307 -    tm_time->tm_sec = sec;
 105.308 -
 105.309 -    return mktime(tm_time);
 105.310 -}
 105.311 -
 105.312 -/** Converts a GString in the following format 
 105.313 - * (e.g. 2006-07-20 09:56:41) to a time_t struct.
 105.314 - * 
 105.315 - * @param time_str the string to be converted
 105.316 - * @return time_t the time converted value
 105.317 - */
 105.318 -struct tm      *
 105.319 -gmyth_util_time_val_to_date(const GTimeVal * time)
 105.320 -{
 105.321 -    struct tm      *date = g_malloc0(sizeof(struct tm));
 105.322 -    time_t          time_micros = time->tv_sec; // + (gint)( time->tv_usec 
 105.323 -                                                // 
 105.324 -    // 
 105.325 -    // / G_USEC_PER_SEC );
 105.326 -
 105.327 -    if (NULL == date) {
 105.328 -        gmyth_debug
 105.329 -            ("GMythUtil: GDate *gmyth_util_time_val_to_date (GTimeVal* time) - converter error!\n");
 105.330 -        return NULL;
 105.331 -    }
 105.332 -
 105.333 -    if (NULL == localtime_r(&time_micros, date)) {
 105.334 -        gmyth_debug("gmyth_util_time_to_isoformat convertion error!\n");
 105.335 -        return NULL;
 105.336 -    }
 105.337 -
 105.338 -    gmyth_debug("Converted from GTimeVal == %s to GDate", asctime(date));
 105.339 -
 105.340 -    return date;
 105.341 -}
 105.342 -
 105.343 -/** Converts a GString in the following format 
 105.344 - * (e.g. 2006-07-20 09:56:41) to a time_t struct.
 105.345 - * 
 105.346 - * @param time_str the string to be converted
 105.347 - * @return time_t the time converted value
 105.348 - */
 105.349 -GTimeVal       *
 105.350 -gmyth_util_string_to_time_val_fmt(const gchar * fmt_string,
 105.351 -                                  const gchar * time_str)
 105.352 -{
 105.353 -    GTimeVal       *time = g_new0(GTimeVal, 1);
 105.354 -    struct tm      *tm_time = NULL;
 105.355 -    time_t          time_micros;
 105.356 -    gchar          *result;
 105.357 -
 105.358 -    gmyth_debug("[%s] time_str = %s. [%s]", time_str, time_str != NULL ?
 105.359 -                time_str : "[time string is NULL!]", time_str);
 105.360 -
 105.361 -    if (NULL == time_str) {
 105.362 -        gmyth_debug("GMythUtil: isoformat_to_time converter error!\n");
 105.363 -        return NULL;
 105.364 -    }
 105.365 -
 105.366 -    tm_time = g_malloc0(sizeof(struct tm));
 105.367 -
 105.368 -    /*
 105.369 -     * we first check the return of strftime to allocate a buffer of the
 105.370 -     * correct size 
 105.371 -     */
 105.372 -    result = strptime(time_str, "%Y-%m-%dT%H:%M:%S", tm_time);
 105.373 -    if (NULL == result) {
 105.374 -        /*
 105.375 -         * we first check the return of strftime to allocate a buffer of
 105.376 -         * the correct size 
 105.377 -         */
 105.378 -        result = strptime(time_str, "%Y-%m-%dT%H:%M:%SZ", tm_time);
 105.379 -        if (NULL == result) {
 105.380 -            /*
 105.381 -             * we first check the return of strftime to allocate a buffer
 105.382 -             * of the correct size 
 105.383 -             */
 105.384 -            result = strptime(time_str, "%Y-%m-%d %H:%M:%S", tm_time);
 105.385 -            if (NULL == result) {
 105.386 -                result = strptime(time_str, "%Y-%m-%dT%H:%M", tm_time);
 105.387 -                if (NULL == result) {
 105.388 -                    gmyth_debug("Dateline (ISO result): %s", result);
 105.389 -                    g_free(tm_time);
 105.390 -                    return NULL;
 105.391 -                    // goto done; 
 105.392 -                }
 105.393 -            }
 105.394 -        }
 105.395 -    }
 105.396 -
 105.397 -    time_micros = mktime(tm_time);
 105.398 -
 105.399 -    time->tv_sec = time_micros; // + (gint)( time_val->tv_usec /
 105.400 -    // G_USEC_PER_SEC );
 105.401 -
 105.402 -    gmyth_debug("After mktime call... = %s", asctime(tm_time));
 105.403 -
 105.404 -    g_free(tm_time);
 105.405 -
 105.406 -    return time;
 105.407 -}
 105.408 -
 105.409 -/** Converts a GString in the following format 
 105.410 - * (e.g. 2006-07-20 09:56:41) to a time_t struct.
 105.411 - * 
 105.412 - * @param time_str the string to be converted
 105.413 - * @return time_t the time converted value
 105.414 - */
 105.415 -GTimeVal       *
 105.416 -gmyth_util_string_to_time_val(const gchar * time_str)
 105.417 -{
 105.418 -    GTimeVal       *time =
 105.419 -        gmyth_util_string_to_time_val_fmt("%Y-%m-%d %H:%M:%S", time_str);
 105.420 -
 105.421 -    return time;
 105.422 -}
 105.423 -
 105.424 -/** 
 105.425 - * Checks if the given remote file exists.
 105.426 - * 
 105.427 - * @param backend_info The GMythBackendInfo instance.
 105.428 - * @param filename The file name of the remote file.
 105.429 - * 
 105.430 - * @return <code>true</code>, if the remote file exists.
 105.431 - */
 105.432 -gboolean
 105.433 -gmyth_util_file_exists(GMythBackendInfo * backend_info,
 105.434 -                       const gchar * filename)
 105.435 -{
 105.436 -    GMythSocket    *socket;
 105.437 -    gboolean        res = FALSE;
 105.438 -
 105.439 -    gmyth_debug("Check if file %s exists", filename);
 105.440 -
 105.441 -    g_return_val_if_fail(backend_info != NULL, FALSE);
 105.442 -    g_return_val_if_fail(filename != NULL, FALSE);
 105.443 -
 105.444 -    socket = gmyth_backend_info_get_connected_socket (backend_info);
 105.445 -    if (socket != NULL) {
 105.446 -        res = gmyth_util_file_exists_from_socket (socket, filename);
 105.447 -        g_object_unref(socket);
 105.448 -    }
 105.449 -    return res;
 105.450 -}
 105.451 -
 105.452 -gboolean
 105.453 -gmyth_util_file_exists_from_socket (GMythSocket *sock, 
 105.454 -                                    const gchar *filename)
 105.455 -{
 105.456 -    gboolean res = FALSE;
 105.457 -    gint length = 0;
 105.458 -    GMythStringList *slist;
 105.459 -    GMythProgramInfo *program = NULL;
 105.460 -
 105.461 -    program = gmyth_program_info_new();
 105.462 -    program->pathname = g_string_new(filename);
 105.463 -
 105.464 -    slist = gmyth_string_list_new();
 105.465 -    gmyth_string_list_append_char_array(slist, "QUERY_CHECKFILE");
 105.466 -    gmyth_program_info_to_string_list(program, slist);
 105.467 -
 105.468 -    length = gmyth_socket_sendreceive_stringlist (sock, slist);
 105.469 -    if (length > 0)
 105.470 -        res = (gmyth_string_list_get_int(slist, 0) == 1);
 105.471 -
 105.472 -    g_object_unref(program);
 105.473 -    g_object_unref(slist);
 105.474 -
 105.475 -    return res;
 105.476 -}
 105.477 - 
 105.478 -gboolean
 105.479 -gmyth_util_get_backend_details (GMythSocket *sock, GMythBackendDetails **details)
 105.480 -{
 105.481 -    gboolean res = FALSE;
 105.482 -    gint length = 0;
 105.483 -    GMythStringList *slist;
 105.484 -
 105.485 -    slist = gmyth_string_list_new();
 105.486 -    gmyth_string_list_append_char_array(slist, "QUERY_FREE_SPACE");
 105.487 -
 105.488 -    length = gmyth_socket_sendreceive_stringlist (sock, slist);
 105.489 -    if (length >= 8) {
 105.490 -        *details = g_new0 (GMythBackendDetails, 1);
 105.491 -        (*details)->total_space = gmyth_string_list_get_uint64 (slist, 4) * 1024;
 105.492 -        (*details)->used_space = gmyth_string_list_get_uint64 (slist, 6) * 1024;
 105.493 -        res = TRUE;
 105.494 -    }
 105.495 -
 105.496 -    g_object_unref(slist);
 105.497 -
 105.498 -    return res;
 105.499 -}
 105.500 -
 105.501 -void
 105.502 -gmyth_util_backend_details_free (GMythBackendDetails *details)
 105.503 -{
 105.504 -    g_free (details);
 105.505 -}
 105.506 -                     
 105.507 -
 105.508 -/** 
 105.509 - * Checks if the given remote file exists, and gets its remote directory.
 105.510 - * 
 105.511 - * @param backend_info The GMythBackendInfo instance.
 105.512 - * @param filename The file name of the remote file.
 105.513 - * @param current_dir String pointer to the directory where the remote file is stored.
 105.514 - * 
 105.515 - * @return <code>true</code>, if the remote file exists.
 105.516 - */
 105.517 -gboolean
 105.518 -gmyth_util_file_exists_and_get_remote_dir(GMythBackendInfo * backend_info,
 105.519 -                                          const gchar * filename,
 105.520 -                                          gchar ** current_dir)
 105.521 -{
 105.522 -    GMythSocket    *socket;
 105.523 -    gboolean        res;
 105.524 -
 105.525 -    *current_dir = NULL;
 105.526 -
 105.527 -    socket = gmyth_socket_new();
 105.528 -    res = gmyth_socket_connect_to_backend(socket, backend_info->hostname,
 105.529 -                                          backend_info->port, TRUE);
 105.530 -
 105.531 -    if (res == TRUE) {
 105.532 -        GMythStringList *slist;
 105.533 -        GMythProgramInfo *program = NULL;
 105.534 -
 105.535 -        program = gmyth_program_info_new();
 105.536 -        program->pathname = g_string_new(filename);
 105.537 -
 105.538 -        slist = gmyth_string_list_new();
 105.539 -        gmyth_string_list_append_char_array(slist, "QUERY_CHECKFILE");
 105.540 -
 105.541 -        gmyth_program_info_to_string_list(program, slist);
 105.542 -
 105.543 -        gmyth_socket_sendreceive_stringlist(socket, slist);
 105.544 -
 105.545 -        res = (gmyth_string_list_get_int(slist, 0) == 1);
 105.546 -
 105.547 -        if ((gmyth_string_list_length(slist) > 1) &&
 105.548 -            gmyth_string_list_get_char_array(slist, 1) != NULL)
 105.549 -            *current_dir =
 105.550 -                g_strdup(gmyth_string_list_get_char_array(slist, 1));
 105.551 -
 105.552 -        if (*current_dir != NULL)
 105.553 -            gmyth_debug("Current directory = %s.", (*current_dir != NULL)
 105.554 -                        ? *current_dir : "[directory not found]");
 105.555 -
 105.556 -        g_object_unref(program);
 105.557 -
 105.558 -        g_object_unref(slist);
 105.559 -
 105.560 -        gmyth_socket_close_connection(socket);
 105.561 -    }
 105.562 -    g_object_unref(socket);
 105.563 -    return res;
 105.564 -}
 105.565 -
 105.566 -/** 
 105.567 - * Creates a file name to a possible existing remote file,
 105.568 - * based on some fields of the LiveTV/recorded program info.
 105.569 - * 
 105.570 - * @param chan_id The channel ID number.
 105.571 - * @param start_time The start time of the recording.
 105.572 - * 
 105.573 - * @return The string representing the file name.
 105.574 - */
 105.575 -gchar          *
 105.576 -gmyth_util_create_filename(const gint chan_id, const GTimeVal * start_time)
 105.577 -{
 105.578 -    gchar          *basename = NULL;
 105.579 -
 105.580 -    g_return_val_if_fail(start_time != NULL, NULL);
 105.581 -
 105.582 -    gchar          *isodate =
 105.583 -        gmyth_util_time_to_isoformat_from_time_val_fmt("%Y%m%d%H%M%S",
 105.584 -                                                       start_time);
 105.585 -
 105.586 -    basename = g_strdup_printf("%d_%s", chan_id, isodate);
 105.587 -
 105.588 -    gmyth_debug("Basename (from chan_id and start_time): %s", basename);
 105.589 -
 105.590 -    if (isodate)
 105.591 -        g_free(isodate);
 105.592 -
 105.593 -    return basename;
 105.594 -}
 105.595 -
 105.596 -/** 
 105.597 - * Gets the channel list.
 105.598 - * 
 105.599 - * @param backend_info The GMythBackendInfo instance.
 105.600 - * 
 105.601 - * @return a pointer to a GList with all the channels.
 105.602 - */
 105.603 -GList          *
 105.604 -gmyth_util_get_channel_list(GMythBackendInfo * backend_info)
 105.605 -{
 105.606 -    GMythRecorder  *recorder;
 105.607 -    GList          *channel_list = NULL;
 105.608 -    gboolean        res = FALSE;
 105.609 -
 105.610 -    gmyth_debug("Gets channel list.");
 105.611 -
 105.612 -    g_return_val_if_fail(backend_info != NULL, FALSE);
 105.613 -
 105.614 -    recorder =
 105.615 -        gmyth_recorder_new(1,
 105.616 -                           g_string_new(gmyth_backend_info_get_hostname
 105.617 -                                        (backend_info)),
 105.618 -                           gmyth_backend_info_get_port(backend_info));
 105.619 -    res = gmyth_recorder_setup(recorder);
 105.620 -
 105.621 -    if (res == TRUE) {
 105.622 -        // GList* channel_list = gmyth_recorder_get_channel_list( recorder 
 105.623 -        // 
 105.624 -        // 
 105.625 -        // ); 
 105.626 -        gmyth_debug("Yeah, got channel list!!!");
 105.627 -        GList          *ch = NULL;
 105.628 -        GMythChannelInfo *channel_info = NULL;
 105.629 -
 105.630 -        for (ch = gmyth_recorder_get_channel_list(recorder); ch != NULL;) {
 105.631 -            channel_info = g_malloc0(sizeof(GMythChannelInfo));
 105.632 -            channel_info->channel_ID = 0;
 105.633 -            channel_info->channel_num =
 105.634 -                g_string_new(g_strdup((gchar *) ch->data));
 105.635 -            channel_info->channel_name = g_string_new("");
 105.636 -            gmyth_debug("Printing channel info... (%s)",
 105.637 -                        channel_info->channel_num->str);
 105.638 -            channel_list =
 105.639 -                g_list_append(channel_list,
 105.640 -                              g_memdup(channel_info,
 105.641 -                                       sizeof(GMythChannelInfo)));
 105.642 -
 105.643 -            ch = g_list_next(ch);
 105.644 -
 105.645 -            if (channel_info != NULL)
 105.646 -                g_free(channel_info);
 105.647 -        }
 105.648 -
 105.649 -    } /* if */
 105.650 -    else {
 105.651 -        gmyth_debug("No, couldn't get the channel list!!!");
 105.652 -    }
 105.653 -
 105.654 -    gmyth_debug("Got %d channels!!!", g_list_length(channel_list));
 105.655 -
 105.656 -
 105.657 -    g_object_unref(recorder);
 105.658 -
 105.659 -    return channel_list;
 105.660 -}
 105.661 -
 105.662 -/** 
 105.663 - * Gets all the recordings from remote encoder.
 105.664 - * 
 105.665 - * @param backend_info The GMythBackendInfo instance.
 105.666 - * 
 105.667 - * @return The program info's listage.
 105.668 - */
 105.669 -GSList         *
 105.670 -gmyth_util_get_all_recordings(GMythBackendInfo * backend_info)
 105.671 -{
 105.672 -    GSList         *program_list = NULL;
 105.673 -    GMythSocket    *socket;
 105.674 -    gboolean        res;
 105.675 -
 105.676 -    socket = gmyth_socket_new();
 105.677 -    res = gmyth_socket_connect_to_backend(socket, backend_info->hostname,
 105.678 -                                          backend_info->port, TRUE);
 105.679 -
 105.680 -    if (res == TRUE) {
 105.681 -        GMythStringList *slist = gmyth_string_list_new();
 105.682 -        guint           pos = 0;
 105.683 -
 105.684 -        gmyth_string_list_append_char_array(slist,
 105.685 -                                            "QUERY_RECORDINGS Play");
 105.686 -
 105.687 -        gmyth_socket_sendreceive_stringlist(socket, slist);
 105.688 -
 105.689 -        if (slist != NULL && (gmyth_string_list_length(slist) > 0)) {
 105.690 -            GMythProgramInfo *program = NULL;
 105.691 -
 105.692 -            gmyth_debug("OK! Got the program list [size=%d].",
 105.693 -                        gmyth_string_list_length(slist));
 105.694 -
 105.695 -            do {
 105.696 -                program =
 105.697 -                    gmyth_program_info_from_string_list_from_pos(slist,
 105.698 -                                                                 pos);
 105.699 -
 105.700 -                if (program != NULL) {
 105.701 -                    pos += 41;
 105.702 -
 105.703 -                    program_list = g_slist_append(program_list, program);
 105.704 -                } else
 105.705 -                    break;
 105.706 -
 105.707 -            }
 105.708 -            while (gmyth_string_list_length(slist) > pos);
 105.709 -
 105.710 -        }
 105.711 -        /*
 105.712 -         * if 
 105.713 -         */
 105.714 -        g_object_unref(slist);
 105.715 -
 105.716 -        gmyth_socket_close_connection(socket);
 105.717 -    }
 105.718 -    g_object_unref(socket);
 105.719 -
 105.720 -    return program_list;
 105.721 -}
 105.722 -
 105.723 -/** 
 105.724 - * Checks if the given remote file exists, and gets its remote directory.
 105.725 - * 
 105.726 - * @param backend_info The GMythBackendInfo instance.
 105.727 - * @param channel The channel name of the program info.
 105.728 - * 
 105.729 - * @return The requested program info.
 105.730 - */
 105.731 -GMythProgramInfo *
 105.732 -gmyth_util_get_recording_from_channel(GMythBackendInfo * backend_info,
 105.733 -                                      const gchar * channel)
 105.734 -{
 105.735 -    GSList         *program_list = NULL;
 105.736 -    GMythProgramInfo *program = NULL;
 105.737 -
 105.738 -    program_list = gmyth_util_get_all_recordings(backend_info);
 105.739 -
 105.740 -    if (program_list != NULL && g_slist_length(program_list) > 0) {
 105.741 -        GMythProgramInfo *program = NULL;
 105.742 -        guint           pos = 0;
 105.743 -
 105.744 -        gmyth_debug("OK! Got the program list [size=%d].",
 105.745 -                    g_slist_length(program_list));
 105.746 -
 105.747 -        while (pos < g_slist_length(program_list)) {
 105.748 -            program =
 105.749 -                (GMythProgramInfo *) g_slist_nth_data(program_list, pos);
 105.750 -
 105.751 -            if (program != NULL && program->channame != NULL &&
 105.752 -                g_ascii_strncasecmp(program->channame->str, channel,
 105.753 -                                    strlen(channel)) == 0) {
 105.754 -                break;
 105.755 -            }
 105.756 -
 105.757 -            ++pos;
 105.758 -
 105.759 -        }                       /* while */
 105.760 -
 105.761 -    }
 105.762 -    /*
 105.763 -     * if 
 105.764 -     */
 105.765 -    return program;
 105.766 -}
 105.767 -
 105.768 -#if !GLIB_CHECK_VERSION (2, 10, 0)
 105.769 -
 105.770 -/*
 105.771 - * Hacked from glib 2.10 <gtime.c> 
 105.772 - */
 105.773 -
 105.774 -static          time_t
 105.775 -mktime_utc(struct tm *tm)
 105.776 -{
 105.777 -    time_t          retval;
 105.778 -
 105.779 -#ifndef HAVE_TIMEGM
 105.780 -    static const gint days_before[] = {
 105.781 -        0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
 105.782 -    };
 105.783 -#endif
 105.784 -
 105.785 -#ifndef HAVE_TIMEGM
 105.786 -    if (tm->tm_mon < 0 || tm->tm_mon > 11)
 105.787 -        return (time_t) - 1;
 105.788 -
 105.789 -    retval = (tm->tm_year - 70) * 365;
 105.790 -    retval += (tm->tm_year - 68) / 4;
 105.791 -    retval += days_before[tm->tm_mon] + tm->tm_mday - 1;
 105.792 -
 105.793 -    if (tm->tm_year % 4 == 0 && tm->tm_mon < 2)
 105.794 -        retval -= 1;
 105.795 -
 105.796 -    retval =
 105.797 -        ((((retval * 24) + tm->tm_hour) * 60) + tm->tm_min) * 60 +
 105.798 -        tm->tm_sec;
 105.799 -#else
 105.800 -    retval = timegm(tm);
 105.801 -#endif                          /* !HAVE_TIMEGM */
 105.802 -
 105.803 -    return retval;
 105.804 -}
 105.805 -
 105.806 -gboolean
 105.807 -g_time_val_from_iso8601(const gchar * iso_date, GTimeVal * time_)
 105.808 -{
 105.809 -    struct tm       tm;
 105.810 -    long            val;
 105.811 -
 105.812 -    g_return_val_if_fail(iso_date != NULL, FALSE);
 105.813 -    g_return_val_if_fail(time_ != NULL, FALSE);
 105.814 -
 105.815 -    val = strtoul(iso_date, (char **) &iso_date, 10);
 105.816 -    if (*iso_date == '-') {
 105.817 -        /*
 105.818 -         * YYYY-MM-DD 
 105.819 -         */
 105.820 -        tm.tm_year = val - 1900;
 105.821 -        iso_date++;
 105.822 -        tm.tm_mon = strtoul(iso_date, (char **) &iso_date, 10) - 1;
 105.823 -
 105.824 -        if (*iso_date++ != '-')
 105.825 -            return FALSE;
 105.826 -
 105.827 -        tm.tm_mday = strtoul(iso_date, (char **) &iso_date, 10);
 105.828 -    } else {
 105.829 -        /*
 105.830 -         * YYYYMMDD 
 105.831 -         */
 105.832 -        tm.tm_mday = val % 100;
 105.833 -        tm.tm_mon = (val % 10000) / 100 - 1;
 105.834 -        tm.tm_year = val / 10000 - 1900;
 105.835 -    }
 105.836 -
 105.837 -    if (*iso_date++ != 'T')
 105.838 -        return FALSE;
 105.839 -
 105.840 -    val = strtoul(iso_date, (char **) &iso_date, 10);
 105.841 -    if (*iso_date == ':') {
 105.842 -        /*
 105.843 -         * hh:mm:ss 
 105.844 -         */
 105.845 -        tm.tm_hour = val;
 105.846 -        iso_date++;
 105.847 -        tm.tm_min = strtoul(iso_date, (char **) &iso_date, 10);
 105.848 -
 105.849 -        if (*iso_date++ != ':')
 105.850 -            return FALSE;
 105.851 -
 105.852 -        tm.tm_sec = strtoul(iso_date, (char **) &iso_date, 10);
 105.853 -    } else {
 105.854 -        /*
 105.855 -         * hhmmss 
 105.856 -         */
 105.857 -        tm.tm_sec = val % 100;
 105.858 -        tm.tm_min = (val % 10000) / 100;
 105.859 -        tm.tm_hour = val / 10000;
 105.860 -    }
 105.861 -
 105.862 -    time_->tv_sec = mktime_utc(&tm);
 105.863 -    time_->tv_usec = 1;
 105.864 -
 105.865 -    if (*iso_date == '.')
 105.866 -        time_->tv_usec = strtoul(iso_date + 1, (char **) &iso_date, 10);
 105.867 -
 105.868 -    if (*iso_date == '+' || *iso_date == '-') {
 105.869 -        gint            sign = (*iso_date == '+') ? -1 : 1;
 105.870 -
 105.871 -        val = 60 * strtoul(iso_date + 1, (char **) &iso_date, 10);
 105.872 -
 105.873 -        if (*iso_date == ':')
 105.874 -            val = 60 * val + strtoul(iso_date + 1, NULL, 10);
 105.875 -        else
 105.876 -            val = 60 * (val / 100) + (val % 100);
 105.877 -
 105.878 -        time_->tv_sec += (time_t) (val * sign);
 105.879 -    }
 105.880 -
 105.881 -    return TRUE;
 105.882 -}
 105.883 -
 105.884 -
 105.885 -gchar          *
 105.886 -g_time_val_to_iso8601(GTimeVal * time_)
 105.887 -{
 105.888 -    gchar          *retval;
 105.889 -
 105.890 -    g_return_val_if_fail(time_->tv_usec >= 0
 105.891 -                         && time_->tv_usec < G_USEC_PER_SEC, NULL);
 105.892 -
 105.893 -#define ISO_8601_LEN    21
 105.894 -#define ISO_8601_FORMAT "%Y-%m-%dT%H:%M:%SZ"
 105.895 -    retval = g_new0(gchar, ISO_8601_LEN + 1);
 105.896 -
 105.897 -    strftime(retval, ISO_8601_LEN, ISO_8601_FORMAT,
 105.898 -             gmtime(&(time_->tv_sec)));
 105.899 -
 105.900 -    return retval;
 105.901 -}
 105.902 -
 105.903 -
 105.904 -/*
 105.905 - * Hacked from glib 2.10 <gdate.c> 
 105.906 - */
 105.907 -
 105.908 -void
 105.909 -g_date_set_time_t(GDate * date, time_t timet)
 105.910 -{
 105.911 -    struct tm       tm;
 105.912 -
 105.913 -    g_return_if_fail(date != NULL);
 105.914 -
 105.915 -#ifdef HAVE_LOCALTIME_R
 105.916 -    localtime_r(&timet, &tm);
 105.917 -#else
 105.918 -    {
 105.919 -        struct tm      *ptm = localtime(&timet);
 105.920 -
 105.921 -        if (ptm == NULL) {
 105.922 -            /*
 105.923 -             * Happens at least in Microsoft's C library if you pass a
 105.924 -             * negative time_t. Use 2000-01-01 as default date. 
 105.925 -             */
 105.926 -#ifndef G_DISABLE_CHECKS
 105.927 -            g_return_if_fail_warning(G_LOG_DOMAIN, "g_date_set_time",
 105.928 -                                     "ptm != NULL");
 105.929 -#endif
 105.930 -
 105.931 -            tm.tm_mon = 0;
 105.932 -            tm.tm_mday = 1;
 105.933 -            tm.tm_year = 100;
 105.934 -        } else
 105.935 -            memcpy((void *) &tm, (void *) ptm, sizeof(struct tm));
 105.936 -    }
 105.937 -#endif
 105.938 -
 105.939 -    date->julian = FALSE;
 105.940 -
 105.941 -    date->month = tm.tm_mon + 1;
 105.942 -    date->day = tm.tm_mday;
 105.943 -    date->year = tm.tm_year + 1900;
 105.944 -
 105.945 -    g_return_if_fail(g_date_valid_dmy(date->day, date->month, date->year));
 105.946 -
 105.947 -    date->dmy = TRUE;
 105.948 -}
 105.949 -
 105.950 -
 105.951 -void
 105.952 -g_date_set_time_val(GDate * date, GTimeVal * timeval)
 105.953 -{
 105.954 -    g_date_set_time_t(date, (time_t) timeval->tv_sec);
 105.955 -}
 105.956 -
 105.957 -
 105.958 -
 105.959 -
 105.960 -#endif
   106.1 --- a/gmyth/src/gmyth_util.h	Mon Feb 25 17:45:36 2008 +0000
   106.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.3 @@ -1,82 +0,0 @@
   106.4 -/**
   106.5 - * GMyth Library
   106.6 - *
   106.7 - * @file gmyth/gmyth_util.h
   106.8 - * 
   106.9 - * @brief <p> This component provides utility functions 
  106.10 - * 	(dealing with dates, time, string formatting, etc.).
  106.11 - * 
  106.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
  106.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
  106.14 - * @author Rosfran Borges <rosfran.borges@indt.org.br>
  106.15 - *
  106.16 - * 
  106.17 - * This program is free software; you can redistribute it and/or modify
  106.18 - * it under the terms of the GNU Lesser General Public License as published by
  106.19 - * the Free Software Foundation; either version 2 of the License, or
  106.20 - * (at your option) any later version.
  106.21 - *
  106.22 - * This program is distributed in the hope that it will be useful,
  106.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  106.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  106.25 - * GNU General Public License for more details.
  106.26 - *
  106.27 - * You should have received a copy of the GNU Lesser General Public License
  106.28 - * along with this program; if not, write to the Free Software
  106.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  106.30 - */
  106.31 -
  106.32 -#ifndef GMYTH_UTIL_H_
  106.33 -#define GMYTH_UTIL_H_
  106.34 -
  106.35 -#include <time.h>
  106.36 -#include <glib.h>
  106.37 -
  106.38 -#include "gmyth_stringlist.h"
  106.39 -#include "gmyth_backendinfo.h"
  106.40 -#include "gmyth_programinfo.h"
  106.41 -
  106.42 -G_BEGIN_DECLS 
  106.43 -
  106.44 -typedef struct {
  106.45 -    guint64 total_space;
  106.46 -    guint64 used_space;
  106.47 -} GMythBackendDetails;
  106.48 -
  106.49 -
  106.50 -GString*        gmyth_util_time_to_isoformat                (time_t time_value);
  106.51 -GString*        gmyth_util_time_to_string                   (time_t time_value);
  106.52 -time_t          gmyth_util_string_to_time                   (GString *time_str);
  106.53 -gchar*          gmyth_util_time_to_isoformat_from_time_val_fmt
  106.54 -                                                            (const gchar *fmt_string,
  106.55 -                                                             const GTimeVal *time_val);
  106.56 -GTimeVal*       gmyth_util_string_to_time_val_fmt           (const gchar *fmt_string,
  106.57 -                                                             const gchar *time_str);
  106.58 -GTimeVal*       gmyth_util_string_to_time_val               (const gchar *time_str);
  106.59 -gchar*          gmyth_util_time_to_isoformat_from_time_val  (const GTimeVal *time);
  106.60 -gchar*          gmyth_util_time_to_mythformat_from_time_val (const GTimeVal *time);
  106.61 -gchar*          gmyth_util_time_to_string_only_date         (const GTimeVal *time);
  106.62 -gchar*          gmyth_util_time_to_string_only_time         (const GTimeVal *time);
  106.63 -gchar*          gmyth_util_time_to_string_from_time_val     (const GTimeVal *time_val);
  106.64 -struct tm*      gmyth_util_time_val_to_date                 (const GTimeVal * time);
  106.65 -
  106.66 -gboolean        gmyth_util_get_backend_details (GMythSocket *sock, GMythBackendDetails **details);
  106.67 -void            gmyth_util_backend_details_free (GMythBackendDetails *details);
  106.68 -
  106.69 -gboolean        gmyth_util_file_exists                      (GMythBackendInfo *backend_info,
  106.70 -                                                             const gchar * filename);
  106.71 -gboolean        gmyth_util_file_exists_from_socket          (GMythSocket *sock, 
  106.72 -                                                             const gchar *filename);
  106.73 -gboolean        gmyth_util_file_exists_and_get_remote_dir   (GMythBackendInfo *backend_info,
  106.74 -                                                             const gchar *filename,
  106.75 -                                                             gchar **current_dir);
  106.76 -gchar*          gmyth_util_create_filename                  (const gint chan_id,
  106.77 -                                                             const GTimeVal * start_time);
  106.78 -GList*          gmyth_util_get_channel_list                 (GMythBackendInfo *backend_info);
  106.79 -GSList*         gmyth_util_get_all_recordings               (GMythBackendInfo *backend_info);
  106.80 -GMythProgramInfo*
  106.81 -                gmyth_util_get_recording_from_channel       (GMythBackendInfo *backend_info,
  106.82 -                                                             const gchar *channel);
  106.83 -
  106.84 -G_END_DECLS
  106.85 -#endif                          /* GMYTH_UTIL_H_ */
   107.1 --- a/gmyth/src/gmyth_vlc.c	Mon Feb 25 17:45:36 2008 +0000
   107.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   107.3 @@ -1,290 +0,0 @@
   107.4 -/**
   107.5 - * GMyth Library
   107.6 - *
   107.7 - * @file gmyth/gmyth_vlc.c
   107.8 - *
   107.9 - * @brief <p> GMythVLC library provides functions that
  107.10 - * interact with a VLC server running telnet interface.
  107.11 - *
  107.12 - * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
  107.13 - * @author Artur Duque de Souza <artur.souza@indt.org.br>
  107.14 - *
  107.15 - * 
  107.16 - * This program is free software; you can redistribute it and/or modify
  107.17 - * it under the terms of the GNU Lesser General Public License as published by
  107.18 - * the Free Software Foundation; either version 2 of the License, or
  107.19 - * (at your option) any later version.
  107.20 - *
  107.21 - * This program is distributed in the hope that it will be useful,
  107.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  107.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  107.24 - * GNU General Public License for more details.
  107.25 - *
  107.26 - * You should have received a copy of the GNU Lesser General Public License
  107.27 - * along with this program; if not, write to the Free Software
  107.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  107.29 - */
  107.30 -
  107.31 -#ifdef HAVE_CONFIG_H
  107.32 -#include "config.h"
  107.33 -#endif
  107.34 -
  107.35 -#include <assert.h>
  107.36 -
  107.37 -#include "gmyth_vlc.h"
  107.38 -#include "gmyth_debug.h"
  107.39 -#include "gmyth_socket.h"
  107.40 -
  107.41 -/*
  107.42 - * static functions 
  107.43 - */
  107.44 -static int      _socket_send(int socket, gchar * msg);
  107.45 -static int      _socket_recv(int socket, gchar * buf);
  107.46 -
  107.47 -/** Primitive function to send a message through the socket
  107.48 - *
  107.49 - * @param socket 
  107.50 - * @param msg the message itself
  107.51 - * @return 0 if success
  107.52 - */
  107.53 -static int
  107.54 -_socket_send(int socket, gchar * msg)
  107.55 -{
  107.56 -    size_t          size = strlen(msg) + 2; // (\n + \0)
  107.57 -    gchar          *final = (gchar *) g_malloc0(sizeof(gchar) * size);
  107.58 -
  107.59 -    g_snprintf(final, size, "%s\n", msg);
  107.60 -
  107.61 -    if (send(socket, final, strlen(final), 0) == -1)
  107.62 -        perror("GMyth_VLC: send error");
  107.63 -
  107.64 -    g_free(final);
  107.65 -    return 0;
  107.66 -}
  107.67 -
  107.68 -
  107.69 -/** Primitive function to receive a message through the socket
  107.70 - *
  107.71 - * @param socket 
  107.72 - * @param buf Buffer to put the message
  107.73 - * @return 0 if success
  107.74 - */
  107.75 -static int
  107.76 -_socket_recv(int socket, gchar * buf)
  107.77 -{
  107.78 -    int             numbytes = 0;
  107.79 -
  107.80 -    if ((numbytes = recv(socket, buf, BUFFER - 1, 0)) == -1) {
  107.81 -        perror("GMyth_VLC: recv error");
  107.82 -        return -1;
  107.83 -    }
  107.84 -
  107.85 -    buf[numbytes - 1] = '\0';
  107.86 -    return numbytes;
  107.87 -}
  107.88 -
  107.89 -
  107.90 -/** Function that adds options to the output media
  107.91 - *
  107.92 - * @param vlc structure with options for vlc
  107.93 - * @param output the number of the output media
  107.94 - * @param kind the type of option we'll change
  107.95 - * @param the params for the option
  107.96 - * @return 0 if success
  107.97 - */
  107.98 -int
  107.99 -gmyth_vlc_setup_output(GMythVlc * vlc, int output, gchar * kind,
 107.100 -                       gchar * opts)
 107.101 -{
 107.102 -    int             ret;
 107.103 -
 107.104 -    size_t          size = strlen(opts) + 25;
 107.105 -    gchar          *msg = g_malloc0(sizeof(gchar) * size);
 107.106 -
 107.107 -    g_snprintf(msg, size, "setup output%d %s %s", output, kind, opts);
 107.108 -
 107.109 -    ret = _socket_send(vlc->sockfd, msg);
 107.110 -
 107.111 -    g_free(msg);
 107.112 -    return ret;
 107.113 -}
 107.114 -
 107.115 -
 107.116 -/** Function to clean the playlist
 107.117 - *
 107.118 - * @param vlc structure with options for vlc
 107.119 - * @param output the number of the output media
 107.120 - * @param file the file we want to insert in the playlist
 107.121 - * @return 0 if success
 107.122 - */
 107.123 -int
 107.124 -gmyth_vlc_clean_playlist(GMythVlc * vlc)
 107.125 -{
 107.126 -    return _socket_send(vlc->sockfd, "del all");
 107.127 -}
 107.128 -
 107.129 -
 107.130 -/** Function to control the playlist
 107.131 - *
 107.132 - * @param vlc structure with options for vlc
 107.133 - * @param output the number of the output media
 107.134 - * @param command play, stop or pause(just for vod)
 107.135 - * @return 0 if success
 107.136 - */
 107.137 -int
 107.138 -gmyth_vlc_control_input(GMythVlc * vlc, int output, gchar * command)
 107.139 -{
 107.140 -    size_t          size = 25;
 107.141 -    gchar          *msg = g_malloc0(sizeof(gchar) * size);
 107.142 -
 107.143 -    g_snprintf(msg, size, "control output%d %s", output, command);
 107.144 -
 107.145 -    int             ret = _socket_send(vlc->sockfd, msg);
 107.146 -
 107.147 -    g_free(msg);
 107.148 -    return ret;
 107.149 -}
 107.150 -
 107.151 -
 107.152 -
 107.153 -/** Function to insert an item in the playlist
 107.154 - *
 107.155 - * @param vlc structure with options for vlc
 107.156 - * @param output the number of the output media
 107.157 - * @param file the file we want to insert in the playlist
 107.158 - * @return 0 if success
 107.159 - */
 107.160 -int
 107.161 -gmyth_vlc_create_input(GMythVlc * vlc, int output, gchar * file)
 107.162 -{
 107.163 -    return gmyth_vlc_setup_output(vlc, output, "input", file);
 107.164 -}
 107.165 -
 107.166 -
 107.167 -/** Function to create a channel in vlc
 107.168 - *
 107.169 - * @param vlc structure with options for vlc
 107.170 - * @param type the type of channel (broadcast, vod...)
 107.171 - * @param port
 107.172 - * @return 0 if success
 107.173 - */
 107.174 -int
 107.175 -gmyth_vlc_create_channel(GMythVlc * vlc, gchar * type, int port,
 107.176 -                         int vcodec)
 107.177 -{
 107.178 -    int             ret;
 107.179 -    size_t          size = 40;
 107.180 -    gchar          *msg = (gchar *) g_malloc0(sizeof(gchar) * size);
 107.181 -
 107.182 -    g_snprintf(msg, size, "new output%d %s enabled loop", vlc->n_outputs,
 107.183 -               type);
 107.184 -
 107.185 -    ret = _socket_send(vlc->sockfd, msg);
 107.186 -
 107.187 -    if (ret > -1) {
 107.188 -        gmyth_vlc_setup_output(vlc, vlc->n_outputs, "option",
 107.189 -                               "sout-keep=1");
 107.190 -
 107.191 -        g_free(msg);
 107.192 -        size = 256;
 107.193 -        msg = (gchar *) g_malloc0(sizeof(gchar) * size);
 107.194 -
 107.195 -        if (vcodec == MPEG1)
 107.196 -            // Best transcode option for N800 (MP1V)
 107.197 -            g_snprintf(msg, size, "#transcode{vcodec=mp1v,vb=384,"
 107.198 -                       "fps=25.0,scale=1,acodec=mpga,"
 107.199 -                       "ab=64,channels=1}:duplicate{dst="
 107.200 -                       "std{access=http,mux=mpeg1,dst=" ":%d}}", port);
 107.201 -        else
 107.202 -            // Best transcode option for N800 (THEORA)
 107.203 -            g_snprintf(msg, size, "#transcode{vcodec=theo,vb=384,"
 107.204 -                       "fps=25.0,scale=1,acodec=vorb,"
 107.205 -                       "ab=64,channels=1}:duplicate{dst="
 107.206 -                       "std{access=http,mux=ogg,dst=" ":%d}}", port);
 107.207 -
 107.208 -        ret = gmyth_vlc_setup_output(vlc, vlc->n_outputs, "output", msg);
 107.209 -
 107.210 -        vlc->n_outputs++;
 107.211 -    }
 107.212 -
 107.213 -    g_free(msg);
 107.214 -
 107.215 -    return ret;
 107.216 -}
 107.217 -
 107.218 -
 107.219 -/** Function to connect to vlc on the backend
 107.220 - *
 107.221 - * @param vlc structure with options for vlc
 107.222 - * @param backend_info infos about the backend
 107.223 - * @param passwd the password for telnet interface
 107.224 - * @return 0 if success
 107.225 - */
 107.226 -int
 107.227 -gmyth_vlc_connect(GMythVlc * vlc, GMythBackendInfo * backend_info,
 107.228 -                  gchar * passwd, int port)
 107.229 -{
 107.230 -    int             numbytes;
 107.231 -
 107.232 -    if ((vlc->he = gethostbyname(backend_info->hostname)) == NULL) {
 107.233 -        herror("GMyth_VLC: gethostbyname error");
 107.234 -        return -1;
 107.235 -    }
 107.236 -
 107.237 -    if ((vlc->sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
 107.238 -        perror("GMyth_VLC: socket error");
 107.239 -        return -1;
 107.240 -    }
 107.241 -    // Socket properties
 107.242 -    vlc->their_addr.sin_family = AF_INET;
 107.243 -    vlc->their_addr.sin_port = htons(port);
 107.244 -    vlc->their_addr.sin_addr = *((struct in_addr *) vlc->he->h_addr);
 107.245 -    memset(&(vlc->their_addr.sin_zero), '\0', 8);
 107.246 -
 107.247 -    if (connect(vlc->sockfd, (struct sockaddr *) &(vlc->their_addr),
 107.248 -                sizeof(struct sockaddr)) == -1) {
 107.249 -        perror("GMyth_VLC: connect error. Check VLC's telnet interface");
 107.250 -        return -1;
 107.251 -    }
 107.252 -    // Receive the Password's Prompt
 107.253 -    numbytes = _socket_recv(vlc->sockfd, vlc->buf);
 107.254 -
 107.255 -    // Send the Password. We don't have to
 107.256 -    // care about passwords being sent in plain text
 107.257 -    // because telnet protocol does it.
 107.258 -    _socket_send(vlc->sockfd, passwd);
 107.259 -
 107.260 -    // Receive the Welcome msg
 107.261 -    numbytes = _socket_recv(vlc->sockfd, vlc->buf);
 107.262 -    if (numbytes > -1)
 107.263 -        if (strncmp(vlc->buf, "\r\nWrong password.", 17) == 0) {
 107.264 -            perror("Gmyth_VLC: passwd error. Check your passwd");
 107.265 -            return -2;
 107.266 -        }
 107.267 -
 107.268 -
 107.269 -    return 0;
 107.270 -}
 107.271 -
 107.272 -
 107.273 -/** Function to disconnect from vlc
 107.274 - *
 107.275 - * @param vlc structure with options for vlc
 107.276 - * @param backend_info infos about the backend
 107.277 - * @return 0 if success
 107.278 - */
 107.279 -int
 107.280 -gmyth_vlc_disconnect(GMythVlc * vlc)
 107.281 -{
 107.282 -
 107.283 -    int             ret;
 107.284 -
 107.285 -    ret = gmyth_vlc_clean_playlist(vlc);
 107.286 -
 107.287 -    if (ret > -1) {
 107.288 -        vlc->n_outputs = 0;
 107.289 -        vlc->n_inputs = 0;
 107.290 -    }
 107.291 -
 107.292 -    return close(vlc->sockfd);
 107.293 -}
   108.1 --- a/gmyth/src/gmyth_vlc.h	Mon Feb 25 17:45:36 2008 +0000
   108.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   108.3 @@ -1,96 +0,0 @@
   108.4 -/**
   108.5 - * GMyth Library
   108.6 - *
   108.7 - * @file gmyth/gmyth_vlc.h
   108.8 - * 
   108.9 - * @brief <p> GMythVLC library provides functions that
  108.10 - * interact with a VLC server running telnet interface.
  108.11 - *
  108.12 - * Copyright (C) 2007 INdT - Instituto Nokia de Tecnologia.
  108.13 - * @author Artur Duque de Souza <artur.souza@indt.org.br>
  108.14 - *
  108.15 - * 
  108.16 - * This program is free software; you can redistribute it and/or modify
  108.17 - * it under the terms of the GNU Lesser General Public License as published by
  108.18 - * the Free Software Foundation; either version 2 of the License, or
  108.19 - * (at your option) any later version.
  108.20 - *
  108.21 - * This program is distributed in the hope that it will be useful,
  108.22 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  108.23 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  108.24 - * GNU General Public License for more details.
  108.25 - *
  108.26 - * You should have received a copy of the GNU Lesser General Public License
  108.27 - * along with this program; if not, write to the Free Software
  108.28 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  108.29 - */
  108.30 -
  108.31 -#ifndef __GMYTH_VLC_H__
  108.32 -#define __GMYTH_VLC_H__
  108.33 -
  108.34 -#include <glib-object.h>
  108.35 -
  108.36 -#include <glib.h>
  108.37 -#include <stdio.h>
  108.38 -#include <stdlib.h>
  108.39 -#include <unistd.h>
  108.40 -#include <errno.h>
  108.41 -#include <string.h>
  108.42 -#include <netdb.h>
  108.43 -#include <sys/types.h>
  108.44 -#include <netinet/in.h>
  108.45 -#include <sys/socket.h>
  108.46 -
  108.47 -
  108.48 -#include "gmyth_backendinfo.h"
  108.49 -#include "gmyth_util.h"
  108.50 -
  108.51 -G_BEGIN_DECLS
  108.52 -#define VLC_TELNET_PORT 4212
  108.53 -#define BUFFER 512
  108.54 -#define MPEG1 0
  108.55 -#define THEORA 1
  108.56 -typedef struct _GMythVlc GMythVlc;
  108.57 -
  108.58 -struct _GMythVlc {
  108.59 -    int             sockfd;
  108.60 -
  108.61 -    // Number of outputs used
  108.62 -    int             n_outputs;
  108.63 -
  108.64 -    // Number of inputs
  108.65 -    int             n_inputs;
  108.66 -
  108.67 -    // Socket vars
  108.68 -    struct hostent *he;
  108.69 -    struct sockaddr_in their_addr;
  108.70 -
  108.71 -    char            buf[BUFFER];
  108.72 -};
  108.73 -
  108.74 -
  108.75 -
  108.76 -int             gmyth_vlc_setup_output(GMythVlc * vlc, int output,
  108.77 -                                       gchar * kind, gchar * opts);
  108.78 -
  108.79 -
  108.80 -int             gmyth_vlc_clean_playlist(GMythVlc * vlc);
  108.81 -
  108.82 -
  108.83 -int             gmyth_vlc_control_input(GMythVlc * vlc, int output,
  108.84 -                                        gchar * command);
  108.85 -
  108.86 -int             gmyth_vlc_create_input(GMythVlc * vlc, int output,
  108.87 -                                       gchar * file);
  108.88 -
  108.89 -int             gmyth_vlc_create_channel(GMythVlc * vlc, gchar * type,
  108.90 -                                         int port, int vcodec);
  108.91 -
  108.92 -int             gmyth_vlc_connect(GMythVlc * vlc,
  108.93 -                                  GMythBackendInfo * backend_info,
  108.94 -                                  gchar * passwd, int port);
  108.95 -
  108.96 -int             gmyth_vlc_disconnect(GMythVlc * vlc);
  108.97 -
  108.98 -G_END_DECLS
  108.99 -#endif                          /* __GMYTH_VLC_H__ */
   109.1 --- a/gmyth/src/gst-indent.sh	Mon Feb 25 17:45:36 2008 +0000
   109.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   109.3 @@ -1,16 +0,0 @@
   109.4 -#!/bin/sh
   109.5 -indent \
   109.6 -  --braces-on-if-line \
   109.7 -  --blank-lines-after-declarations \
   109.8 -  --case-brace-indentation0 \
   109.9 -  --case-indentation4 \
  109.10 -  --braces-after-struct-decl-line \
  109.11 -  --line-length80 \
  109.12 -  --no-tabs \
  109.13 -  --cuddle-else \
  109.14 -  --dont-line-up-parentheses \
  109.15 -  --continuation-indentation4 \
  109.16 -  --honour-newlines \
  109.17 -  --tab-size4 \
  109.18 -  --indent-level4 \
  109.19 -  $*
   110.1 --- a/gmyth/tests/Makefile.am	Mon Feb 25 17:45:36 2008 +0000
   110.2 +++ b/gmyth/tests/Makefile.am	Mon Feb 25 17:51:43 2008 +0000
   110.3 @@ -1,5 +1,5 @@
   110.4  LDADD = \
   110.5 -	$(top_srcdir)/src/libgmyth.la
   110.6 +	$(top_srcdir)/gmyth/libgmyth.la
   110.7  
   110.8  AM_LDFLAGS = \
   110.9  	@GLIB_LIBS@ @GOBJECT_LIBS@ @GTHREAD_LIBS@ @LIBCURL_LIBS@
  110.10 @@ -7,8 +7,8 @@
  110.11  INCLUDES = \
  110.12  	-I$(top_srcdir) \
  110.13  	-I$(top_builddir) \
  110.14 -	-I$(top_srcdir)/src \
  110.15 -	-I$(top_builddir)/src \
  110.16 +	-I$(top_srcdir)/gmyth \
  110.17 +	-I$(top_builddir)/gmyth \
  110.18  	$(MYSQL_CFLAGS) \
  110.19  	$(GLIB_CFLAGS) \
  110.20  	$(GOBJECT_CFLAGS) \