* http.c: begin support of vlm interraction (not yet documented).
typedef struct httpd_stream_t httpd_stream_t;
/* divers */
-typedef struct vlc_meta_t vlc_meta_t;
+typedef struct vlc_meta_t vlc_meta_t;
+
+typedef struct vlm_t vlm_t;
+typedef struct vlm_message_t vlm_message_t;
/*****************************************************************************
* vlc_objects.h: vlc_object_t definition.
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: vlc_objects.h,v 1.22 2004/01/25 18:17:08 zorglub Exp $
+ * $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
#define VLC_OBJECT_PACKETIZER (-13)
#define VLC_OBJECT_ENCODER (-14)
#define VLC_OBJECT_DIALOGS (-15)
+#define VLC_OBJECT_VLM (-16)
#define VLC_OBJECT_GENERIC (-666)
/*****************************************************************************
- * .c: VLM interface plugin
+ * vlc_vlm.h: VLM interface plugin
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id$
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
+#ifndef _VLC_VLM_H
+#define _VLC_VLM_H 1
+
/* VLM specific - structures and functions */
enum
{
The parent node is ( name_of_the_command , NULL ), or
( name_of_the_command , message_error ) on error.
If a node has children, it should not have a value (=NULL).*/
-typedef struct vlm_message
+struct vlm_message_t
{
char *psz_name;
char *psz_value;
- int i_child;
-
- struct vlm_message **child;
-
-} vlm_message_t;
+ int i_child;
+ vlm_message_t **child;
+};
-typedef struct
+struct vlm_t
{
VLC_COMMON_MEMBERS
int i_schedule;
vlm_schedule_t **schedule;
-} vlm_t;
+};
#define vlm_New( a ) __vlm_New( VLC_OBJECT(a) )
-vlm_t *__vlm_New ( vlc_object_t * );
-void vlm_Delete( vlm_t * );
-int vlm_ExecuteCommand( vlm_t *, char *, vlm_message_t **);
-void vlm_MessageDelete( vlm_message_t* );
+VLC_EXPORT( vlm_t *, __vlm_New, ( vlc_object_t * ) );
+VLC_EXPORT( void, vlm_Delete, ( vlm_t * ) );
+
+VLC_EXPORT( int, vlm_ExecuteCommand, ( vlm_t *, char *, vlm_message_t **) );
+VLC_EXPORT( void, vlm_MessageDelete, ( vlm_message_t* ) );
+
+#endif
/*****************************************************************************
* Preamble
*****************************************************************************/
-/*
- * TODO:
- *
+/* TODO:
* - clean up ?
* - doc ! (mouarf ;)
- *
*/
#include <stdlib.h>
#include <vlc/vout.h> /* for fullscreen */
#include "vlc_httpd.h"
+#include "vlc_vlm.h"
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
/*****************************************************************************
* Module descriptor
*****************************************************************************/
-static int Activate ( vlc_object_t * );
-static void Close ( vlc_object_t * );
+static int Open ( vlc_object_t * );
+static void Close( vlc_object_t * );
#define HOST_TEXT N_( "Host address" )
#define HOST_LONGTEXT N_( \
add_string ( "http-host", NULL, NULL, HOST_TEXT, HOST_LONGTEXT, VLC_TRUE );
add_string ( "http-src", NULL, NULL, SRC_TEXT, SRC_LONGTEXT, VLC_TRUE );
set_capability( "interface", 0 );
- set_callbacks( Activate, Close );
+ set_callbacks( Open, Close );
vlc_module_end();
static char *uri_extract_value( char *psz_uri, char *psz_name,
char *psz_value, int i_value_max );
+static int uri_test_param( char *psz_uri, char *psz_name );
+
static void uri_decode_url_encoded( char *psz );
static char *Find_end_MRL( char *psz );
playlist_t *p_playlist;
input_thread_t *p_input;
+ vlm_t *p_vlm;
};
/*****************************************************************************
* Activate: initialize and create stuff
*****************************************************************************/
-static int Activate( vlc_object_t *p_this )
+static int Open( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t*)p_this;
intf_sys_t *p_sys;
}
p_sys->p_playlist = NULL;
p_sys->p_input = NULL;
+ p_sys->p_vlm = NULL;
p_sys->p_httpd_host = httpd_HostNew( VLC_OBJECT(p_intf), psz_address, i_port );
if( p_sys->p_httpd_host == NULL )
int i;
+ if( p_sys->p_vlm )
+ {
+ vlm_Delete( p_sys->p_vlm );
+ }
+
for( i = 0; i < p_sys->i_files; i++ )
{
httpd_FileDelete( p_sys->pp_files[i]->p_file );
return s;
}
+static mvar_t *mvar_VlmSetNew( char *name, vlm_t *vlm )
+{
+ mvar_t *s = mvar_New( name, "set" );
+ vlm_message_t *msg;
+ int i;
+
+ fprintf( stderr," mvar_VlmSetNew: name=`%s'\n", name );
+ if( vlm == NULL )
+ return s;
+ if( vlm_ExecuteCommand( vlm, "show", &msg ) )
+ {
+ return s;
+ }
+
+ for( i = 0; i < msg->i_child; i++ )
+ {
+ /* Over media, schedule */
+ vlm_message_t *ch = msg->child[i];
+ int j;
+
+ for( j = 0; j < ch->i_child; j++ )
+ {
+ /* Over name */
+ vlm_message_t *el = ch->child[j];
+ vlm_message_t *inf, *desc;
+ mvar_t *set;
+ char psz[500];
+ int k;
+
+ sprintf( psz, "show %s", el->psz_name );
+ if( vlm_ExecuteCommand( vlm, psz, &inf ) )
+ continue;
+ desc = inf->child[0];
+
+ /* Add a node with name and info */
+ set = mvar_New( name, "set" );
+ mvar_AppendNewVar( set, "name", el->psz_name );
+
+ for( k = 0; k < desc->i_child; k++ )
+ {
+ mvar_AppendNewVar( set, desc->child[k]->psz_name, desc->child[k]->psz_value );
+ }
+ vlm_MessageDelete( inf );
+
+ mvar_AppendVar( s, set );
+ }
+ }
+ vlm_MessageDelete( msg );
+
+ return s;
+}
+
+
static void SSInit( rpn_stack_t * );
static void SSClean( rpn_stack_t * );
static void EvaluateRPN( mvar_t *, rpn_stack_t *, char * );
MVLC_CLOSE,
MVLC_SHUTDOWN,
+
+ MVLC_VLM_NEW,
+ MVLC_VLM_SETUP,
+ MVLC_VLM_DEL,
+ MVLC_VLM_PLAY,
+ MVLC_VLM_PAUSE,
+ MVLC_VLM_STOP,
+ MVLC_VLM_SEEK,
+
MVLC_FOREACH,
MVLC_IF,
MVLC_RPN,
{ "close", MVLC_CLOSE },
{ "shutdown", MVLC_SHUTDOWN },
+ /* vlm control */
+ { "vlm_new", MVLC_VLM_NEW },
+ { "vlm_setup", MVLC_VLM_SETUP },
+ { "vlm_del", MVLC_VLM_DEL },
+ { "vlm_play", MVLC_VLM_PLAY },
+ { "vlm_pause", MVLC_VLM_PAUSE },
+ { "vlm_stop", MVLC_VLM_STOP },
+ { "vlm_seek", MVLC_VLM_SEEK },
+
{ "rpn", MVLC_RPN },
{ "foreach", MVLC_FOREACH },
p_intf->p_vlc->b_die = VLC_TRUE;
break;
}
+ /* vlm */
+ case MVLC_VLM_NEW:
+ case MVLC_VLM_SETUP:
+ {
+ static const char *vlm_properties[11] =
+ {
+ "input", "output", "option", "enabled", "disabled",
+ "loop", "unloop", "append", "date", "period", "repeat",
+ };
+ vlm_message_t *vlm_answer;
+ char name[512];
+ char *psz = malloc( strlen( p_request ) + 1000 );
+ char *p = psz;
+ int i;
+
+ if( p_intf->p_sys->p_vlm == NULL )
+ p_intf->p_sys->p_vlm = vlm_New( p_intf );
+
+ uri_extract_value( p_request, "name", name, 512 );
+ if( StrToMacroType( control ) == MVLC_VLM_NEW )
+ {
+ char type[20];
+ uri_extract_value( p_request, "type", type, 20 );
+ p += sprintf( psz, "new %s %s", name, type );
+ }
+ else
+ {
+ p += sprintf( psz, "setup %s", name );
+ }
+ /* Parse the request */
+ for( i = 0; i < 11; i++ )
+ {
+ char val[512];
+ uri_extract_value( p_request, vlm_properties[i], val, 512 );
+ if( strlen( val ) > 0 )
+ {
+ p += sprintf( p, " %s %s", vlm_properties[i], val );
+ }
+ else if( uri_test_param( p_request, vlm_properties[i] ) )
+ {
+ p += sprintf( p, " %s", vlm_properties[i] );
+ }
+ }
+ vlm_ExecuteCommand( p_intf->p_sys->p_vlm, psz, &vlm_answer );
+ /* FIXME do a vlm_answer -> var stack conversion */
+ vlm_MessageDelete( vlm_answer );
+ free( psz );
+ break;
+ }
+
+ case MVLC_VLM_DEL:
+ {
+ vlm_message_t *vlm_answer;
+ char name[512];
+ char psz[512+10];
+ if( p_intf->p_sys->p_vlm == NULL )
+ p_intf->p_sys->p_vlm = vlm_New( p_intf );
+
+ uri_extract_value( p_request, "name", name, 512 );
+ sprintf( psz, "del %s", name );
+
+ vlm_ExecuteCommand( p_intf->p_sys->p_vlm, psz, &vlm_answer );
+ /* FIXME do a vlm_answer -> var stack conversion */
+ vlm_MessageDelete( vlm_answer );
+ break;
+ }
+
+ case MVLC_VLM_PLAY:
+ case MVLC_VLM_PAUSE:
+ case MVLC_VLM_STOP:
+ case MVLC_VLM_SEEK:
+ {
+ vlm_message_t *vlm_answer;
+ char name[512];
+ char psz[512+10];
+ if( p_intf->p_sys->p_vlm == NULL )
+ p_intf->p_sys->p_vlm = vlm_New( p_intf );
+
+ uri_extract_value( p_request, "name", name, 512 );
+ if( StrToMacroType( control ) == MVLC_VLM_PLAY )
+ sprintf( psz, "control %s play", name );
+ else if( StrToMacroType( control ) == MVLC_VLM_PAUSE )
+ sprintf( psz, "control %s pause", name );
+ else if( StrToMacroType( control ) == MVLC_VLM_STOP )
+ sprintf( psz, "control %s stop", name );
+ else if( StrToMacroType( control ) == MVLC_VLM_SEEK )
+ {
+ char percent[20];
+ uri_extract_value( p_request, "percent", percent, 512 );
+ sprintf( psz, "control %s seek %s", name, percent );
+ }
+
+ vlm_ExecuteCommand( p_intf->p_sys->p_vlm, psz, &vlm_answer );
+ /* FIXME do a vlm_answer -> var stack conversion */
+ vlm_MessageDelete( vlm_answer );
+ break;
+ }
+
default:
PRINTS( "<!-- control param(%s) unsuported -->", control );
break;
case MVLC_RPN:
EvaluateRPN( p_args->vars, &p_args->stack, m->param1 );
break;
+
case MVLC_UNKNOWN:
default:
PRINTS( "<!-- invalid macro id=`%s' -->", m->id );
{
index = mvar_InfoSetNew( m.param1, p_intf->p_sys->p_input );
}
+ else if( !strcmp( m.param2, "vlm" ) )
+ {
+ if( p_intf->p_sys->p_vlm == NULL )
+ {
+ p_intf->p_sys->p_vlm = vlm_New( p_intf );
+ }
+ index = mvar_VlmSetNew( m.param1, p_intf->p_sys->p_vlm );
+ }
#if 0
else if( !strcmp( m.param2, "hosts" ) )
{
/****************************************************************************
* uri parser
****************************************************************************/
+static int uri_test_param( char *psz_uri, char *psz_name )
+{
+ char *p = psz_uri;
+
+ while( (p = strstr( p, psz_name )) )
+ {
+ /* Verify that we are dealing with a post/get argument */
+ if( p == psz_uri || *(p - 1) == '&' || *(p - 1) == '\n' )
+ {
+ return VLC_TRUE;
+ }
+ p++;
+ }
+
+ return VLC_FALSE;
+}
static char *uri_extract_value( char *psz_uri, char *psz_name,
char *psz_value, int i_value_max )
{
#include "network.h"
-#include "vlm.h"
+#include "vlc_vlm.h"
#if defined( WIN32 ) || defined( UNDER_CE )
#define SOCKET_CLOSE(a) closesocket(a)
+++ /dev/null
-SOURCES_telnet = telnet.c vlm.c vlm.h
* objects.c: vlc_object_t handling
*****************************************************************************
* Copyright (C) 2004 VideoLAN
- * $Id: objects.c,v 1.46 2004/03/03 13:25:24 fenrir Exp $
+ * $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
#include "vlc_codec.h"
#include "vlc_httpd.h"
+#include "vlc_vlm.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
i_size = sizeof( httpd_t );
psz_type = "http daemon";
break;
+ case VLC_OBJECT_VLM:
+ i_size = sizeof( vlm_t );
+ psz_type = "vlm dameon";
+ break;
default:
i_size = i_type > 0
? i_type > (int)sizeof(vlc_object_t)
#include <vlc/vlc.h>
#include <vlc/intf.h>
-
#include <vlc/input.h>
#ifdef HAVE_TIME_H
# include <time.h> /* ctime() */
#endif
-#include "vlm.h"
+#include "vlc_vlm.h"
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
-static char *vlm_Save( vlm_t * );
-static int vlm_Load( vlm_t *, char *);
-static vlm_media_t *vlm_MediaNew( vlm_t *, char *, int );
-static int vlm_MediaDelete( vlm_t *, vlm_media_t *, char * );
-static vlm_media_t *vlm_MediaSearch( vlm_t *, char * );
-static int vlm_MediaSetup( vlm_media_t *, char *, char * );
-static int vlm_MediaControl( vlm_t *, vlm_media_t *, char *, char * );
+static char *vlm_Save( vlm_t * );
+static int vlm_Load( vlm_t *, char *);
static vlm_message_t *vlm_Show( vlm_t *, vlm_media_t *, vlm_schedule_t *, char * );
static vlm_message_t *vlm_Help( vlm_t *, char * );
+static vlm_media_t *vlm_MediaNew ( vlm_t *, char *, int );
+static int vlm_MediaDelete ( vlm_t *, vlm_media_t *, char * );
+static vlm_media_t *vlm_MediaSearch ( vlm_t *, char * );
+static int vlm_MediaSetup ( vlm_media_t *, char *, char * );
+static int vlm_MediaControl( vlm_t *, vlm_media_t *, char *, char * );
+
static vlm_message_t* vlm_MessageNew( char * , char * );
static vlm_message_t* vlm_MessageAdd( vlm_message_t*, vlm_message_t* );
static vlm_schedule_t *vlm_ScheduleNew( vlm_t *, char *);
-static int vlm_ScheduleDelete( vlm_t *, vlm_schedule_t *, char *);
-static int vlm_ScheduleSetup( vlm_schedule_t *, char *, char *);
+static int vlm_ScheduleDelete( vlm_t *, vlm_schedule_t *, char *);
+static int vlm_ScheduleSetup( vlm_schedule_t *, char *, char *);
static vlm_schedule_t *vlm_ScheduleSearch( vlm_t *, char *);
+
static int ExecuteCommand( vlm_t *, char * , vlm_message_t **);
static int Manage( vlc_object_t* );
+/*****************************************************************************
+ * vlm_New:
+ *****************************************************************************/
+vlm_t *__vlm_New ( vlc_object_t *p_this )
+{
+ vlc_value_t lockval;
+ vlm_t *vlm = NULL;
+
+ /* to be sure to avoid multiple creation */
+ var_Create( p_this->p_libvlc, "vlm_mutex", VLC_VAR_MUTEX );
+ var_Get( p_this->p_libvlc, "vlm_mutex", &lockval );
+ vlc_mutex_lock( lockval.p_address );
+
+ if( !(vlm = vlc_object_find( p_this, VLC_OBJECT_VLM, FIND_ANYWHERE )) )
+ {
+ msg_Info( p_this, "creating vlm" );
+ if( ( vlm = vlc_object_create( p_this, VLC_OBJECT_VLM ) ) == NULL )
+ {
+ vlc_mutex_unlock( lockval.p_address );
+ return NULL;
+ }
+
+ vlc_mutex_init( p_this->p_vlc, &vlm->lock );
+ vlm->i_media = 0;
+ vlm->media = NULL;
+ vlm->i_schedule = 0;
+ vlm->schedule = NULL;
+
+ vlc_object_yield( vlm );
+ vlc_object_attach( vlm, p_this->p_vlc );
+ }
+ vlc_mutex_unlock( lockval.p_address );
+
+
+ if( vlc_thread_create( vlm, "vlm thread",
+ Manage, VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
+ {
+ vlc_mutex_destroy( &vlm->lock );
+ vlc_object_destroy( vlm );
+ return NULL;
+ }
+ return vlm;
+}
+
+/*****************************************************************************
+ * vlm_Delete:
+ *****************************************************************************/
+void vlm_Delete( vlm_t *vlm )
+{
+ vlc_value_t lockval;
+ int i;
+
+ var_Get( vlm->p_libvlc, "vlm_mutex", &lockval );
+ vlc_mutex_lock( lockval.p_address );
+
+ vlc_object_release( vlm );
+
+ if( vlm->i_refcount > 0 )
+ {
+ vlc_mutex_unlock( lockval.p_address );
+ return;
+ }
+
+ vlm->b_die = VLC_TRUE;
+ vlc_thread_join( vlm );
+
+ vlc_mutex_destroy( &vlm->lock );
+
+ for( i = 0; i < vlm->i_media; i++ )
+ {
+ vlm_media_t *media = vlm->media[i];
+
+ vlm_MediaDelete( vlm, media, NULL );
+ }
+
+ if( vlm->media ) free( vlm->media );
+
+ for( i = 0; i < vlm->i_schedule; i++ )
+ {
+ vlm_ScheduleDelete( vlm, vlm->schedule[i], NULL );
+ }
+
+ if( vlm->schedule ) free( vlm->schedule );
+
+ vlc_object_detach( vlm );
+ vlc_object_destroy( vlm );
+ vlc_mutex_unlock( lockval.p_address );
+}
+
+/*****************************************************************************
+ * vlm_ExecuteCommand:
+ *****************************************************************************/
+int vlm_ExecuteCommand( vlm_t *vlm, char *command, vlm_message_t **message)
+{
+ int result;
+
+ vlc_mutex_lock( &vlm->lock );
+ result = ExecuteCommand( vlm, command, message );
+ vlc_mutex_unlock( &vlm->lock );
+
+ return result;
+}
+
+
+/*****************************************************************************
+ *
+ *****************************************************************************/
#if 1
static char *FindEndCommand( char *psz )
{
#endif
-int vlm_ExecuteCommand( vlm_t *vlm, char *command, vlm_message_t **message)
-{
- int result;
-
- vlc_mutex_lock( &vlm->lock );
- result = ExecuteCommand( vlm, command, message );
- vlc_mutex_unlock( &vlm->lock );
-
- return result;
-}
-
/* Execute a command which ends by '\0' (string) */
-int ExecuteCommand( vlm_t *vlm, char *command , vlm_message_t **p_message)
+static int ExecuteCommand( vlm_t *vlm, char *command , vlm_message_t **p_message)
{
int i_return = 0;
int i_command = 0;
{
int i;
- if( media->p_input )
+ if( media->p_input );
{
input_StopThread( media->p_input );
input_DestroyThread( media->p_input );
return save;
}
-/*****************************************************************************
- * vlm_New:
- *****************************************************************************/
-vlm_t *__vlm_New ( vlc_object_t *p_object )
-{
- vlm_t *vlm = vlc_object_create( p_object , sizeof( vlm_t ) );
-
- vlc_mutex_init( p_object->p_vlc, &vlm->lock );
- vlm->i_media = 0;
- vlm->media = NULL;
- vlm->i_schedule = 0;
- vlm->schedule = NULL;
-
- if( vlc_thread_create( vlm, "vlm thread",
- Manage, VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
- {
-
- vlc_mutex_destroy( &vlm->lock );
- vlc_object_destroy( vlm );
- return NULL;
- }
- return vlm;
-}
-
-/*****************************************************************************
- * vlm_Delete:
- *****************************************************************************/
-void vlm_Delete( vlm_t *vlm )
-{
- int i;
-
- vlm->b_die = VLC_TRUE;
- vlc_thread_join( vlm );
-
- vlc_mutex_destroy( &vlm->lock );
-
- for( i = 0; i < vlm->i_media; i++ )
- {
- vlm_media_t *media = vlm->media[i];
-
- vlm_MediaDelete( vlm, media, NULL );
- }
-
- if( vlm->media ) free( vlm->media );
-
- for( i = 0; i < vlm->i_schedule; i++ )
- {
- vlm_ScheduleDelete( vlm, vlm->schedule[i], NULL );
- }
-
- if( vlm->schedule ) free( vlm->schedule );
-
- vlc_object_destroy( vlm );
-}
-
static vlm_schedule_t *vlm_ScheduleNew( vlm_t *vlm , char *psz_name )
{
vlm_schedule_t *sched= malloc( sizeof( vlm_schedule_t ));
{
struct tm time;
char *p;
+ char *psz_time = NULL, *psz_date = NULL;
time_t date;
+ int i,j,k;
/* First, if date or period are modified, repeat should be equal to -1 */
schedule->i_repeat = -1;
/* date should be year/month/day-hour:minutes:seconds */
p = strchr( psz_value , '-' );
-
- if( p == NULL && sscanf( psz_value, "%d:%d:%d" , &time.tm_hour, &time.tm_min, &time.tm_sec ) != 3 ) /* it must be a hour:minutes:seconds */
+ if( p )
{
- return 1;
+ psz_date = psz_value;
+ psz_time = p + 1;
+
+ *p = '\0';
}
else
{
- int i,j,k;
-
- switch( sscanf( p + 1, "%d:%d:%d" , &i, &j, &k ) )
- {
- case 1:
- time.tm_sec = i;
- break;
- case 2:
- time.tm_min = i;
- time.tm_sec = j;
- break;
- case 3:
- time.tm_hour = i;
- time.tm_min = j;
- time.tm_sec = k;
- break;
- default:
- return 1;
- }
+ psz_time = psz_value;
+ }
- *p = '\0';
- switch( sscanf( psz_value, "%d/%d/%d" , &i, &j, &k ) )
+ switch( sscanf( psz_time, "%d:%d:%d" , &i, &j, &k ) )
+ {
+ case 1:
+ time.tm_sec = i;
+ break;
+ case 2:
+ time.tm_min = i;
+ time.tm_sec = j;
+ break;
+ case 3:
+ time.tm_hour = i;
+ time.tm_min = j;
+ time.tm_sec = k;
+ break;
+ default:
+ return 1;
+ }
+ if( psz_date )
+ {
+ switch( sscanf( psz_date, "%d/%d/%d" , &i, &j, &k ) )
{
case 1:
time.tm_mday = i;
}
-void vlm_MessageDelete( vlm_message_t* message )
-{
- int i;
-
- if( message->psz_name ) free( message->psz_name );
- if( message->psz_value ) free( message->psz_value );
-
- for( i = 0; i < message->i_child; i++)
- {
- vlm_MessageDelete( message->child[i] );
- }
-
- free( message );
-}
-
static vlm_message_t* vlm_MessageNew( char *psz_name , char *psz_value )
{
vlm_message_t *message = malloc( sizeof(vlm_message_t) );
return message;
}
+void vlm_MessageDelete( vlm_message_t* message )
+{
+ int i;
+
+ if( message->psz_name ) free( message->psz_name );
+ if( message->psz_value ) free( message->psz_value );
+
+ for( i = 0; i < message->i_child; i++)
+ {
+ vlm_MessageDelete( message->child[i] );
+ }
+
+ free( message );
+}
+
/* add a child */
static vlm_message_t* vlm_MessageAdd( vlm_message_t* message , vlm_message_t* child )
{