1 /*****************************************************************************
2 * vlm.c: VLM interface plugin
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
7 * Authors: Simon Latapie <garf@videolan.org>
8 * Laurent Aimar <fenrir@videolan.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
28 #include <stdlib.h> /* malloc(), free() */
32 #include <vlc/input.h>
35 # include <time.h> /* ctime() */
41 /*****************************************************************************
43 *****************************************************************************/
44 static char *vlm_Save( vlm_t * );
45 static int vlm_Load( vlm_t *, char *);
46 static vlm_message_t *vlm_Show( vlm_t *, vlm_media_t *, vlm_schedule_t *, char * );
47 static vlm_message_t *vlm_Help( vlm_t *, char * );
49 static vlm_media_t *vlm_MediaNew ( vlm_t *, char *, int );
50 static int vlm_MediaDelete ( vlm_t *, vlm_media_t *, char * );
51 static vlm_media_t *vlm_MediaSearch ( vlm_t *, char * );
52 static int vlm_MediaSetup ( vlm_t *, vlm_media_t *, char *, char * );
53 static int vlm_MediaControl( vlm_t *, vlm_media_t *, char *, char * );
55 static vlm_message_t* vlm_MessageNew( char *, char * );
56 static vlm_message_t* vlm_MessageAdd( vlm_message_t*, vlm_message_t* );
58 static vlm_schedule_t *vlm_ScheduleNew( vlm_t *, char *);
59 static int vlm_ScheduleDelete( vlm_t *, vlm_schedule_t *, char *);
60 static int vlm_ScheduleSetup( vlm_schedule_t *, char *, char *);
61 static vlm_schedule_t *vlm_ScheduleSearch( vlm_t *, char *);
63 static int ExecuteCommand( vlm_t *, char *, vlm_message_t **);
64 static int Manage( vlc_object_t* );
66 /*****************************************************************************
68 *****************************************************************************/
69 vlm_t *__vlm_New ( vlc_object_t *p_this )
74 /* to be sure to avoid multiple creation */
75 var_Create( p_this->p_libvlc, "vlm_mutex", VLC_VAR_MUTEX );
76 var_Get( p_this->p_libvlc, "vlm_mutex", &lockval );
77 vlc_mutex_lock( lockval.p_address );
79 if( !(vlm = vlc_object_find( p_this, VLC_OBJECT_VLM, FIND_ANYWHERE )) )
81 msg_Info( p_this, "creating vlm" );
82 if( ( vlm = vlc_object_create( p_this, VLC_OBJECT_VLM ) ) == NULL )
84 vlc_mutex_unlock( lockval.p_address );
88 vlc_mutex_init( p_this->p_vlc, &vlm->lock );
95 vlc_object_yield( vlm );
96 vlc_object_attach( vlm, p_this->p_vlc );
98 vlc_mutex_unlock( lockval.p_address );
100 if( vlc_thread_create( vlm, "vlm thread",
101 Manage, VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
103 vlc_mutex_destroy( &vlm->lock );
104 vlc_object_destroy( vlm );
111 /*****************************************************************************
113 *****************************************************************************/
114 void vlm_Delete( vlm_t *vlm )
119 var_Get( vlm->p_libvlc, "vlm_mutex", &lockval );
120 vlc_mutex_lock( lockval.p_address );
122 vlc_object_release( vlm );
124 if( vlm->i_refcount > 0 )
126 vlc_mutex_unlock( lockval.p_address );
130 vlm->b_die = VLC_TRUE;
131 vlc_thread_join( vlm );
133 vlc_mutex_destroy( &vlm->lock );
135 for( i = 0; i < vlm->i_media; i++ )
137 vlm_media_t *media = vlm->media[i];
139 vlm_MediaDelete( vlm, media, NULL );
142 if( vlm->media ) free( vlm->media );
144 for( i = 0; i < vlm->i_schedule; i++ )
146 vlm_ScheduleDelete( vlm, vlm->schedule[i], NULL );
149 if( vlm->schedule ) free( vlm->schedule );
151 vlc_object_detach( vlm );
152 vlc_object_destroy( vlm );
153 vlc_mutex_unlock( lockval.p_address );
156 /*****************************************************************************
157 * vlm_ExecuteCommand:
158 *****************************************************************************/
159 int vlm_ExecuteCommand( vlm_t *vlm, char *command, vlm_message_t **message)
163 vlc_mutex_lock( &vlm->lock );
164 result = ExecuteCommand( vlm, command, message );
165 vlc_mutex_unlock( &vlm->lock );
170 /*****************************************************************************
172 *****************************************************************************/
174 static char *FindEndCommand( char *psz )
184 while( ( *s_sent != '\"' ) && ( *s_sent != '\0' ) )
186 if( *s_sent == '\'' )
188 s_sent = FindEndCommand( s_sent );
201 if( *s_sent == '\"' )
206 else /* *s_sent == '\0' , which means the number of " is incorrect */
216 while( ( *s_sent != '\'' ) && ( *s_sent != '\0' ) )
218 if( *s_sent == '\"' )
220 s_sent = FindEndCommand( s_sent );
233 if( *s_sent == '\'' )
238 else /* *s_sent == '\0' , which means the number of ' is incorrect */
244 default: /* now we can look for spaces */
246 while( ( *s_sent != ' ' ) && ( *s_sent != '\0' ) )
248 if( ( *s_sent == '\'' ) || ( *s_sent == '\"' ) )
250 s_sent = FindEndCommand( s_sent );
262 static char *FindEndCommand( char *psz )
267 *psz != ' ' && *psz != '\t' &&
268 *psz != '\n' && *psz != '\r' )
270 if( *psz == '\'' || *psz == '"' )
274 while( *psz && *psz != d && *psz != *psz != '\n' && *psz != '\r' )
276 if( ( d == '\'' && *psz == '"' ) ||
277 ( d == '"' && *psz == '\'' ) )
279 psz = FindEndCommand( psz );
292 /* Execute a command which ends by '\0' (string) */
293 static int ExecuteCommand(vlm_t *vlm, char *command, vlm_message_t **p_message)
297 char **p_command = NULL;
299 vlm_message_t *message = NULL;
302 /* First, parse the line and cut it */
303 while( *cmd != '\0' )
315 p_temp = FindEndCommand( cmd );
323 i_temp = p_temp - cmd;
325 p_command = realloc( p_command, (i_command + 1) * sizeof( char* ) );
326 p_command[ i_command ] = malloc( (i_temp + 1) * sizeof( char ) ); // don't forget the '\0'
327 strncpy( p_command[ i_command ], cmd, i_temp );
328 (p_command[ i_command ])[ i_temp ] = '\0';
335 /* And then Interpret it */
339 message = vlm_MessageNew( "", NULL );
344 if( strcmp(p_command[0], "new") == 0 )
350 vlm_schedule_t *schedule;
352 if( strcmp(p_command[2], "schedule") == 0 )
354 /* new vlm_schedule */
355 if( vlm_ScheduleSearch( vlm, p_command[1] ) != NULL ||
356 strcmp(p_command[1], "schedule") == 0 )
359 asprintf( &error_message, "%s is already used",
361 message = vlm_MessageNew( "new", error_message );
362 free( error_message );
367 schedule = vlm_ScheduleNew( vlm, p_command[1] );
369 if( i_command > 3 ) // hey, there are properties
371 for( i = 3 ; i < i_command ; i++ )
373 if( strcmp( p_command[i], "enabled" ) == 0 ||
374 strcmp( p_command[i], "disabled" ) == 0 )
376 vlm_ScheduleSetup( schedule, p_command[i], NULL );
378 /* Beware: evrything behind append is considered as command line */
379 else if( strcmp( p_command[i], "append" ) == 0 )
386 for( j = (i + 1); j < i_command; j++ )
388 p_command[i] = realloc( p_command[i], strlen(p_command[i]) + strlen(p_command[j]) + 1 + 1);
389 strcat( p_command[i], " " );
390 strcat( p_command[i], p_command[j] );
393 vlm_ScheduleSetup( schedule, p_command[i - 1], p_command[i] );
399 if( (i+1) < i_command )
401 vlm_ScheduleSetup( schedule, p_command[i], p_command[i+1] );
406 vlm_ScheduleDelete( vlm, schedule, NULL );
407 message = vlm_MessageNew( p_command[i], "Wrong properties syntax" );
415 message = vlm_MessageNew( "new", NULL );
420 if( strcmp(p_command[2], "vod") == 0 )
424 else if( strcmp(p_command[2], "broadcast") == 0 )
426 i_type = BROADCAST_TYPE;
432 asprintf( &error_message,
433 "%s: Choose between vod or broadcast",
436 message = vlm_MessageNew( "new", error_message );
437 free( error_message );
443 if( vlm_MediaSearch( vlm, p_command[1] ) != NULL ||
444 strcmp(p_command[1], "media") == 0 )
447 asprintf( &error_message, "%s is already used",
449 message = vlm_MessageNew( "new", error_message );
450 free( error_message );
455 media = vlm_MediaNew( vlm, p_command[1], i_type );
458 message = vlm_MessageNew( "new", "could not create media" );
463 if( i_command > 3 ) // hey, there are properties
465 for( i = 3; i < i_command; i++ )
467 if( strcmp( p_command[i], "enabled" ) == 0 ||
468 strcmp( p_command[i], "disabled" ) == 0 )
470 vlm_MediaSetup( vlm, media, p_command[i], NULL );
474 if( (i+1) < i_command )
476 vlm_MediaSetup( vlm, media, p_command[i], p_command[i+1] );
481 vlm_MediaDelete( vlm, media, NULL );
482 message = vlm_MessageNew( p_command[i], "Wrong properties syntax" );
490 if( media->i_type == VOD_TYPE )
491 message = vlm_MessageNew( "new", "Warning: VOD is not "
494 message = vlm_MessageNew( "new", NULL );
500 message = vlm_MessageNew( "new", "Wrong command syntax" );
505 else if( strcmp(p_command[0], "del") == 0 )
510 vlm_schedule_t *schedule;
512 media = vlm_MediaSearch( vlm, p_command[1] );
513 schedule = vlm_ScheduleSearch( vlm, p_command[1] );
515 if( schedule != NULL )
517 vlm_ScheduleDelete( vlm, schedule, NULL );
518 message = vlm_MessageNew( "del", NULL );
522 else if( media != NULL )
524 vlm_MediaDelete( vlm, media, NULL );
525 message = vlm_MessageNew( "del", NULL );
529 else if( strcmp(p_command[1], "media") == 0 )
531 for( i = 0; i < vlm->i_media; i++ )
533 vlm_MediaDelete( vlm, vlm->media[i], NULL );
535 message = vlm_MessageNew( "del", NULL );
538 else if( strcmp(p_command[1], "schedule") == 0 )
540 for( i = 0; i < vlm->i_schedule; i++ )
542 vlm_ScheduleDelete( vlm, vlm->schedule[i], NULL );
544 message = vlm_MessageNew( "del", NULL );
547 else if( strcmp(p_command[1], "all") == 0 )
549 for( i = 0; i < vlm->i_media; i++ )
551 vlm_MediaDelete( vlm, vlm->media[i], NULL );
554 for( i = 0; i < vlm->i_schedule; i++ )
556 vlm_ScheduleDelete( vlm, vlm->schedule[i], NULL );
559 message = vlm_MessageNew( "del", NULL );
565 asprintf( &error_message, "%s: media unknown", p_command[1] );
566 message = vlm_MessageNew( "del", error_message );
567 free( error_message );
574 message = vlm_MessageNew( "setup", "Wrong command syntax" );
579 else if( strcmp(p_command[0], "show") == 0 )
583 message = vlm_Show( vlm, NULL, NULL, NULL );
587 else if( i_command == 2 )
590 vlm_schedule_t *schedule;
592 media = vlm_MediaSearch( vlm, p_command[1] );
593 schedule = vlm_ScheduleSearch( vlm, p_command[1] );
595 if( schedule != NULL )
597 message = vlm_Show( vlm, NULL, schedule, NULL );
599 else if( media != NULL )
601 message = vlm_Show( vlm, media, NULL, NULL );
605 message = vlm_Show( vlm, NULL, NULL, p_command[1] );
613 message = vlm_MessageNew( "show", "Wrong command syntax" );
618 else if( strcmp(p_command[0], "help") == 0 )
622 message = vlm_Help( vlm, NULL );
628 message = vlm_MessageNew( "help", "Wrong command syntax" );
633 else if( strcmp(p_command[0], "setup") == 0 )
638 vlm_schedule_t *schedule;
640 media = vlm_MediaSearch( vlm, p_command[1] );
641 schedule = vlm_ScheduleSearch( vlm, p_command[1] );
643 if( schedule != NULL )
645 for( i = 2 ; i < i_command ; i++ )
647 if( strcmp( p_command[i], "enabled" ) == 0 ||
648 strcmp( p_command[i], "disabled" ) == 0 )
650 vlm_ScheduleSetup( schedule, p_command[i], NULL );
652 /* Beware: evrything behind append is considered as command line */
653 else if( strcmp( p_command[i], "append" ) == 0 )
660 for( j = (i + 1); j < i_command; j++ )
662 p_command[i] = realloc( p_command[i], strlen(p_command[i]) + strlen(p_command[j]) + 1 + 1);
663 strcat( p_command[i], " " );
664 strcat( p_command[i], p_command[j] );
667 vlm_ScheduleSetup( schedule, p_command[i - 1], p_command[i] );
673 if( (i+1) < i_command )
675 vlm_ScheduleSetup( schedule, p_command[i], p_command[i+1] );
680 vlm_ScheduleDelete( vlm, schedule, NULL );
681 message = vlm_MessageNew( "setup", "Wrong properties syntax" );
688 message = vlm_MessageNew( "setup", NULL );
692 else if( media != NULL )
694 for( i = 2 ; i < i_command ; i++ )
696 if( strcmp( p_command[i], "enabled" ) == 0 ||
697 strcmp( p_command[i], "disabled" ) == 0 )
698 { /* only one argument */
699 vlm_MediaSetup( vlm, media, p_command[i], NULL );
701 else if( strcmp( p_command[i], "loop" ) == 0 ||
702 strcmp( p_command[i], "unloop" ) == 0 )
704 if( media->i_type != BROADCAST_TYPE )
706 message = vlm_MessageNew( "setup", "loop only available for broadcast" );
712 vlm_MediaSetup( vlm, media, p_command[i], NULL );
717 if( (i+1) < i_command )
719 vlm_MediaSetup( vlm, media, p_command[i], p_command[i+1] );
724 vlm_MediaDelete( vlm, media, NULL );
725 message = vlm_MessageNew( "setup", "Wrong properties syntax" );
732 message = vlm_MessageNew( "setup", NULL );
739 asprintf( &error_message, "%s unknown", p_command[1] );
740 message = vlm_MessageNew( "setup", error_message );
741 free( error_message );
749 message = vlm_MessageNew( "setup", "Wrong command syntax" );
754 else if( strcmp(p_command[0], "control") == 0 )
761 media = vlm_MediaSearch( vlm, p_command[1] );
766 asprintf( &error_message, "%s: media unknown", p_command[1] );
767 message = vlm_MessageNew( "control", error_message );
768 free( error_message );
778 psz_args = p_command[3];
786 vlm_MediaControl( vlm, media, p_command[2], psz_args );
787 message = vlm_MessageNew( "control", NULL );
794 message = vlm_MessageNew( "control", "Wrong command syntax" );
799 else if( strcmp(p_command[0], "save") == 0 )
805 file = fopen( p_command[1], "w" );
809 message = vlm_MessageNew( "save", "Unable to save file" );
817 save = vlm_Save( vlm );
819 fwrite( save, strlen( save ), 1, file );
822 message = vlm_MessageNew( "save", NULL );
829 message = vlm_MessageNew( "save", "Wrong command" );
834 else if( strcmp(p_command[0], "load") == 0 )
841 file = fopen( p_command[1], "r" );
845 message = vlm_MessageNew( "load", "Unable to load file" );
854 if( fseek( file, 0, SEEK_END) == 0 )
856 size = ftell( file );
857 fseek( file, 0, SEEK_SET);
858 buffer = malloc( size + 1 );
859 fread( buffer, 1, size, file);
860 buffer[ size ] = '\0';
861 if( vlm_Load( vlm, buffer ) )
864 message = vlm_MessageNew( "load", "error while loading file" );
872 message = vlm_MessageNew( "load", "read file error" );
877 message = vlm_MessageNew( "load", NULL );
884 message = vlm_MessageNew( "load", "Wrong command" );
891 message = vlm_MessageNew( p_command[0], "Unknown command" );
898 for( i = 0 ; i < i_command ; i++ )
900 free( p_command[i] );
903 *p_message = message;
908 static vlm_media_t *vlm_MediaSearch( vlm_t *vlm, char *psz_name )
912 for( i = 0; i < vlm->i_media; i++ )
914 if( strcmp( psz_name, vlm->media[i]->psz_name ) == 0 )
916 return vlm->media[i];
923 static vlm_media_t *vlm_MediaNew( vlm_t *vlm, char *psz_name, int i_type )
925 vlm_media_t *media = malloc( sizeof( vlm_media_t ) );
927 /* Check if we need to load the VOD server */
928 if( i_type == VOD_TYPE && !vlm->i_vod )
930 vlm->vod = vlc_object_create( vlm, VLC_OBJECT_VOD );
931 vlc_object_attach( vlm->vod, vlm );
932 vlm->vod->p_module = module_Need( vlm->vod, "vod server", 0, 0 );
933 if( !vlm->vod->p_module )
935 msg_Err( vlm, "cannot find vod server" );
940 if( i_type == VOD_TYPE ) vlm->i_vod++;
942 media->psz_name = strdup( psz_name );
943 media->b_enabled = VLC_FALSE;
944 media->b_loop = VLC_FALSE;
945 media->vod_media = NULL;
949 media->psz_output = NULL;
951 media->option = NULL;
952 media->i_type = i_type;
953 media->p_input = NULL;
955 media->item.psz_uri = strdup( psz_name );
956 media->item.psz_name = NULL;
957 media->item.i_duration = -1;
958 media->item.ppsz_options = NULL;
959 media->item.i_options = 0;
960 media->item.i_categories = 0;
961 media->item.pp_categories = NULL;
962 media->item.i_es = 0;
964 vlc_mutex_init( vlm, &media->item.lock );
966 TAB_APPEND( vlm->i_media, vlm->media, media );
971 /* for now, simple delete. After, del with options (last arg) */
972 static int vlm_MediaDelete( vlm_t *vlm, vlm_media_t *media, char *psz_name )
976 if( media == NULL ) return 1;
980 input_StopThread( media->p_input );
982 input_DestroyThread( media->p_input );
983 vlc_object_detach( media->p_input );
984 vlc_object_destroy( media->p_input );
987 TAB_REMOVE( vlm->i_media, vlm->media, media );
989 if( media->i_type == VOD_TYPE )
991 vlm_MediaSetup( vlm, media, "disabled", 0 );
995 /* Check if we need to unload the VOD server */
996 if( media->i_type == VOD_TYPE && !vlm->i_vod )
998 module_Unneed( vlm->vod, vlm->vod->p_module );
999 vlc_object_detach( vlm->vod );
1000 vlc_object_destroy( vlm->vod );
1004 if( vlm->i_media == 0 && vlm->media ) free( vlm->media );
1006 free( media->psz_name );
1008 for( i = 0; i < media->i_input; i++ ) free( media->input[i] );
1009 if( media->input ) free( media->input );
1011 if( media->psz_output ) free( media->psz_output );
1013 for( i = 0; i < media->i_option; i++ ) free( media->option[i] );
1014 if(media->option) free( media->option );
1016 if( media->item.psz_uri ) free( media->item.psz_uri );
1017 if( media->item.psz_name ) free( media->item.psz_name );
1018 vlc_mutex_destroy( &media->item.lock );
1019 for( i = 0; i < media->item.i_options; i++ )
1021 free( media->item.ppsz_options[i] );
1023 if( media->item.ppsz_options ) free( media->item.ppsz_options );
1024 /* FIXME: free the info categories. */
1031 static int vlm_MediaSetup( vlm_t *vlm, vlm_media_t *media, char *psz_cmd,
1034 if( strcmp( psz_cmd, "loop" ) == 0 )
1036 media->b_loop = VLC_TRUE;
1038 else if( strcmp( psz_cmd, "unloop" ) == 0 )
1040 media->b_loop = VLC_FALSE;
1042 else if( strcmp( psz_cmd, "enabled" ) == 0 )
1044 media->b_enabled = VLC_TRUE;
1046 else if( strcmp( psz_cmd, "disabled" ) == 0 )
1048 media->b_enabled = VLC_FALSE;
1050 else if( strcmp( psz_cmd, "input" ) == 0 )
1054 if( psz_value != NULL && strlen(psz_value) > 1 &&
1055 ( psz_value[0] == '\'' || psz_value[0] == '\"' ) &&
1056 ( psz_value[ strlen(psz_value) - 1 ] == '\'' ||
1057 psz_value[ strlen(psz_value) - 1 ] == '\"' ) )
1059 input = malloc( strlen(psz_value) - 1 );
1061 memcpy( input, psz_value + 1, strlen(psz_value) - 2 );
1062 input[ strlen(psz_value) - 2 ] = '\0';
1066 input = strdup( psz_value );
1069 TAB_APPEND( media->i_input, media->input, input );
1071 else if( strcmp( psz_cmd, "output" ) == 0 )
1073 if( media->psz_output != NULL )
1075 free( media->psz_output );
1077 media->psz_output = strdup( psz_value );
1079 else if( strcmp( psz_cmd, "option" ) == 0 )
1082 option = strdup( psz_value );
1084 TAB_APPEND( media->i_option, media->option, option );
1091 /* Check if we need to create/delete a vod media */
1092 if( media->i_type == VOD_TYPE )
1094 if( !media->b_enabled && media->vod_media )
1098 for( i = 0; i < media->item.i_es; i++ )
1100 es_format_Clean( media->item.es[i] );
1101 free( media->item.es[i] );
1103 if( media->item.es ) free( media->item.es );
1105 media->item.i_es = 0;
1107 vlm->vod->pf_media_del( vlm->vod, media->vod_media );
1108 media->vod_media = 0;
1110 else if( media->b_enabled && !media->vod_media )
1112 /* Pre-parse the input */
1113 char *psz_output = media->psz_output;
1114 if( media->psz_output )
1116 asprintf( &media->psz_output, "%s:description",
1117 media->psz_output );
1121 asprintf( &media->psz_output, "#description" );
1124 if( !vlm_MediaControl( vlm, media, "play", 0 ) && media->p_input )
1126 while( !media->p_input->b_eof && !media->p_input->b_error )
1131 input_StopThread( media->p_input );
1132 input_DestroyThread( media->p_input );
1133 vlc_object_detach( media->p_input );
1134 vlc_object_destroy( media->p_input );
1135 media->p_input = NULL;
1137 free( media->psz_output );
1138 media->psz_output = psz_output;
1141 vlm->vod->pf_media_new( vlm->vod, media->psz_name,
1149 static int vlm_MediaControl( vlm_t *vlm, vlm_media_t *media, char *psz_name,
1152 if( strcmp( psz_name, "play" ) == 0 )
1156 if( media->b_enabled == VLC_TRUE && media->i_input > 0 )
1158 if( psz_args != NULL && sscanf( psz_args, "%d", &i ) == 1 &&
1159 i < media->i_input )
1168 if( media->item.psz_uri )
1170 free( media->item.psz_uri );
1171 media->item.psz_uri =NULL;
1173 media->item.psz_uri = strdup( media->input[media->i_index] );
1175 /* FIXME!!! we need an input_item_t per input spawned */
1176 //input_ItemNew( &media->item );
1177 if( media->psz_output != NULL )
1179 media->item.ppsz_options = malloc( sizeof( char* ) );
1180 asprintf( &media->item.ppsz_options[0], "sout=%s",
1181 media->psz_output );
1182 media->item.i_options = 1;
1186 media->item.ppsz_options = NULL;
1187 media->item.i_options = 0;
1190 for( i = 0; i < media->i_option; i++ )
1192 media->item.i_options++;
1193 media->item.ppsz_options =
1194 realloc( media->item.ppsz_options,
1195 media->item.i_options * sizeof( char* ) );
1196 media->item.ppsz_options[ media->item.i_options - 1 ] =
1197 strdup( media->option[i] );
1200 media->p_input = input_CreateThread( vlm, &media->item );
1209 else if( strcmp( psz_name, "seek" ) == 0 )
1214 if( psz_args && sscanf( psz_args, "%f", &f_percentage ) == 1 )
1216 val.f_float = f_percentage / 100.0 ;
1217 var_Set( media->p_input, "position", val );
1221 else if( strcmp( psz_name, "stop" ) == 0 )
1223 /* FIXME!!! we need an input_item_t per input spawned */
1224 if( media->p_input )
1226 input_StopThread( media->p_input );
1227 input_DestroyThread( media->p_input );
1228 vlc_object_detach( media->p_input );
1229 vlc_object_destroy( media->p_input );
1230 media->p_input = NULL;
1232 //input_ItemDelete( &media->item );
1237 else if( strcmp( psz_name, "pause" ) == 0 )
1243 if( media->p_input != NULL )
1245 var_Get( media->p_input, "state", &val );
1248 if( val.i_int == PAUSE_S )
1250 if( media->p_input )
1252 val.i_int = PLAYING_S;
1253 var_Set( media->p_input, "state", val );
1258 if( media->p_input )
1260 val.i_int = PAUSE_S;
1261 var_Set( media->p_input, "state", val );
1270 static vlm_message_t *vlm_Show( vlm_t *vlm, vlm_media_t *media,
1271 vlm_schedule_t *schedule, char *psz_filter )
1277 vlm_message_t *message;
1278 vlm_message_t *message_media;
1279 vlm_message_t *message_child;
1281 message = vlm_MessageNew( "show", NULL );
1283 vlm_MessageAdd( message, vlm_MessageNew( media->psz_name, NULL ) );
1285 if( media->i_type == VOD_TYPE )
1287 vlm_MessageAdd(message_media, vlm_MessageNew("type", "vod"));
1291 vlm_MessageAdd(message_media, vlm_MessageNew("type", "broadcast"));
1294 vlm_MessageAdd( message_media,
1295 vlm_MessageNew( "enabled", media->b_enabled ?
1298 vlm_MessageAdd( message_media,
1299 vlm_MessageNew( "loop", media->b_loop ?
1302 message_child = vlm_MessageAdd( message_media,
1303 vlm_MessageNew( "inputs", NULL ) );
1305 for( i = 0; i < media->i_input; i++ )
1307 vlm_MessageAdd( message_child,
1308 vlm_MessageNew( media->input[i], NULL ) );
1311 vlm_MessageAdd( message_media,
1312 vlm_MessageNew( "output", media->psz_output ?
1313 media->psz_output : "" ) );
1315 message_child = vlm_MessageAdd( message_media,
1316 vlm_MessageNew( "options", NULL ) );
1318 for( i=0 ; i < (media->i_option) ; i++ )
1320 vlm_MessageAdd( message_child,
1321 vlm_MessageNew( media->option[i], NULL ) );
1324 if( media->p_input != NULL )
1328 var_Get( media->p_input, "state", &val );
1330 if( val.i_int == PLAYING_S )
1332 vlm_MessageAdd( message_media,
1333 vlm_MessageNew( "state", "playing" ) );
1335 else if( val.i_int == PAUSE_S )
1337 vlm_MessageAdd( message_media,
1338 vlm_MessageNew( "state", "paused" ) );
1342 vlm_MessageAdd( message_media,
1343 vlm_MessageNew( "state", "stop" ) );
1348 vlm_MessageAdd( message_media,
1349 vlm_MessageNew( "state", "stop" ) );
1355 else if( schedule != NULL )
1358 vlm_message_t *message;
1359 vlm_message_t *message_schedule;
1360 vlm_message_t *message_child;
1363 message = vlm_MessageNew( "show", NULL );
1365 vlm_MessageAdd( message, vlm_MessageNew( schedule->psz_name, 0 ) );
1367 vlm_MessageAdd( message_schedule, vlm_MessageNew("type", "schedule") );
1369 if( schedule->b_enabled == VLC_TRUE )
1371 vlm_MessageAdd(message_schedule, vlm_MessageNew("enabled", "yes"));
1375 vlm_MessageAdd(message_schedule, vlm_MessageNew("enabled", "no"));
1378 if( schedule->i_date != 0 )
1381 time_t i_time = (time_t)( schedule->i_date / 1000000 );
1384 #ifdef HAVE_LOCALTIME_R
1385 localtime_r( &i_time, &date);
1387 struct tm *p_date = localtime( &i_time );
1391 asprintf( &psz_date, "%d/%d/%d-%d:%d:%d",
1392 date.tm_year + 1900, date.tm_mon + 1, date.tm_mday,
1393 date.tm_hour, date.tm_min, date.tm_sec );
1395 vlm_MessageAdd( message_schedule,
1396 vlm_MessageNew( "date", psz_date ) );
1401 vlm_MessageAdd( message_schedule, vlm_MessageNew("date", "now") );
1404 if( schedule->i_period != 0 )
1406 time_t i_time = (time_t) ( schedule->i_period / 1000000 );
1409 date.tm_sec = (int)( i_time % 60 );
1410 i_time = i_time / 60;
1411 date.tm_min = (int)( i_time % 60 );
1412 i_time = i_time / 60;
1413 date.tm_hour = (int)( i_time % 24 );
1414 i_time = i_time / 24;
1415 date.tm_mday = (int)( i_time % 30 );
1416 i_time = i_time / 30;
1417 /* okay, okay, months are not always 30 days long */
1418 date.tm_mon = (int)( i_time % 12 );
1419 i_time = i_time / 12;
1420 date.tm_year = (int)i_time;
1422 sprintf( buffer, "%d/%d/%d-%d:%d:%d", date.tm_year, date.tm_mon,
1423 date.tm_mday, date.tm_hour, date.tm_min, date.tm_sec);
1425 vlm_MessageAdd(message_schedule, vlm_MessageNew("period", buffer));
1429 vlm_MessageAdd(message_schedule, vlm_MessageNew("period", "0"));
1432 sprintf( buffer, "%d", schedule->i_repeat );
1433 vlm_MessageAdd( message_schedule, vlm_MessageNew( "repeat", buffer ) );
1436 vlm_MessageAdd( message_schedule, vlm_MessageNew("commands", 0) );
1438 for( i = 0 ; i < schedule->i_command ; i++ )
1440 vlm_MessageAdd( message_child,
1441 vlm_MessageNew( schedule->command[i], NULL ) );
1447 else if( psz_filter && strcmp( psz_filter, "media") == 0 )
1450 vlm_message_t *message;
1451 vlm_message_t *message_child;
1453 message = vlm_MessageNew( "show", NULL );
1455 vlm_MessageAdd( message, vlm_MessageNew( "media", NULL ) );
1457 for( i = 0; i < vlm->i_media; i++ )
1459 vlm_media_t *m = vlm->media[i];
1460 vlm_message_t *message_media =
1461 vlm_MessageAdd(message_child, vlm_MessageNew(m->psz_name, 0));
1463 if( m->i_type == VOD_TYPE )
1465 vlm_MessageAdd( message_media,
1466 vlm_MessageNew( "type", "vod" ) );
1470 vlm_MessageAdd( message_media,
1471 vlm_MessageNew( "type", "broadcast" ) );
1474 if( m->b_enabled == VLC_TRUE )
1476 vlm_MessageAdd( message_media,
1477 vlm_MessageNew( "enabled", "yes" ) );
1481 vlm_MessageAdd( message_media,
1482 vlm_MessageNew( "enabled", "no" ) );
1485 if( m->p_input != NULL )
1489 var_Get( m->p_input, "state", &val );
1491 if( val.i_int == PLAYING_S )
1493 vlm_MessageAdd( message_media,
1494 vlm_MessageNew( "state", "playing" ) );
1496 else if( val.i_int == PAUSE_S )
1498 vlm_MessageAdd( message_media,
1499 vlm_MessageNew( "state", "paused" ) );
1503 vlm_MessageAdd( message_media,
1504 vlm_MessageNew( "state", "stop" ) );
1509 vlm_MessageAdd( message_media,
1510 vlm_MessageNew( "state", "stop" ) );
1516 else if( psz_filter && strcmp( psz_filter, "schedule") == 0 )
1519 vlm_message_t *message;
1520 vlm_message_t *message_child;
1522 message = vlm_MessageNew( "show", NULL );
1524 vlm_MessageAdd( message, vlm_MessageNew( "schedule", NULL ) );
1526 for( i = 0; i < vlm->i_schedule; i++ )
1528 vlm_schedule_t *s = vlm->schedule[i];
1529 vlm_message_t *message_schedule =
1530 vlm_MessageAdd(message_child, vlm_MessageNew(s->psz_name, 0));
1532 if( s->b_enabled == VLC_TRUE )
1535 mtime_t i_next_date;
1537 vlm_MessageAdd( message_schedule,
1538 vlm_MessageNew( "enabled", "yes" ) );
1540 /* calculate next date */
1543 i_next_date = s->i_date;
1545 if( s->i_period != 0 )
1548 while( s->i_date + j * s->i_period <= i_time &&
1554 i_next_date = s->i_date + j * s->i_period;
1557 if( i_next_date > i_time )
1559 time_t i_date = (time_t) (i_next_date / 1000000) ;
1563 ctime_r( &i_date, psz_date );
1565 char *psz_date = ctime( &i_date );
1568 vlm_MessageAdd( message_schedule,
1569 vlm_MessageNew("next launch", psz_date) );
1574 vlm_MessageAdd( message_schedule,
1575 vlm_MessageNew( "enabled", "no" ) );
1581 else if( psz_filter == NULL && media == NULL && schedule == NULL )
1583 vlm_message_t *show1 = vlm_Show( vlm, NULL, NULL, "media" );
1584 vlm_message_t *show2 = vlm_Show( vlm, NULL, NULL, "schedule" );
1586 vlm_MessageAdd( show1, show2->child[0] );
1588 /* We must destroy the parent node "show" of show2
1589 * and not the children */
1590 free( show2->psz_name );
1597 return vlm_MessageNew( "show", NULL );
1601 static vlm_message_t *vlm_Help( vlm_t *vlm, char *psz_filter )
1603 vlm_message_t *message;
1605 if( psz_filter == NULL )
1609 "\n new (name) vod|broadcast|schedule [properties]"
1610 "\n setup (name) (properties)"
1611 "\n show [(name)|media|schedule]"
1612 "\n del (name)|all|media|schedule"
1613 "\n control (name) (command)"
1614 "\n save (config_file)"
1615 "\n load (config_file)"
1616 "\nMedia Proprieties Syntax:"
1617 "\n input (input_name)"
1618 "\n output (output_name)"
1619 "\n option (option_name)[=value]"
1620 "\n enabled|disabled"
1621 "\n loop|unloop (broadcast only)"
1622 "\nSchedule Proprieties Syntax:"
1623 "\n enabled|disabled"
1624 "\n append (command_until_rest_of_the_line)"
1625 "\n date (year)/(month)/(day)-(hour):(minutes):(seconds)|now"
1626 "\n period (years_aka_12_months)/(months_aka_30_days)/(days)-(hours):(minutes):(seconds)"
1627 "\n repeat (number_of_repetitions)"
1628 "\nControl Commands Syntax:"
1629 "\n play\n pause\n stop\n seek (percentage)\n" );
1631 message = vlm_MessageNew( "help", NULL );
1632 vlm_MessageAdd( message, vlm_MessageNew( "Help", help ) );
1637 return vlm_MessageNew( "help", NULL );
1640 /* file must end by '\0' */
1641 static int vlm_Load( vlm_t *vlm, char *file )
1645 while( *pf != '\0' )
1647 vlm_message_t *message = NULL;
1651 while( pf[i_temp] != '\n' && pf[i_temp] != '\0' && pf[i_temp] != '\r' )
1656 if( pf[i_temp] == '\r' || pf[i_temp] == '\n' )
1659 i_next = i_temp + 1;
1666 if( ExecuteCommand( vlm, pf, &message ) )
1678 static char *vlm_Save( vlm_t *vlm )
1685 for( i = 0; i < vlm->i_media; i++ )
1687 vlm_media_t *media = vlm->media[i];
1689 if( media->i_type == VOD_TYPE )
1691 i_length += strlen( "new vod " ) + strlen(media->psz_name);
1695 i_length += strlen( "new broadcast " ) + strlen(media->psz_name);
1698 if( media->b_enabled == VLC_TRUE )
1700 i_length += strlen( "enabled" );
1704 i_length += strlen( "disabled" );
1707 if( media->b_loop == VLC_TRUE )
1709 i_length += strlen( " loop\n" );
1713 i_length += strlen( "\n" );
1716 for( j = 0; j < media->i_input; j++ )
1718 i_length += strlen( "setup input \"\"\n" ) +
1719 strlen( media->psz_name ) + strlen( media->input[j] );
1722 if( media->psz_output != NULL )
1724 i_length += strlen(media->psz_name) + strlen(media->psz_output) +
1725 strlen( "setup output \n" );
1728 for( j=0 ; j < media->i_option ; j++ )
1730 i_length += strlen(media->psz_name) + strlen(media->option[j]) +
1731 strlen("setup option \n");
1735 for( i = 0; i < vlm->i_schedule; i++ )
1737 vlm_schedule_t *schedule = vlm->schedule[i];
1739 i_length += strlen( "new schedule " ) + strlen( schedule->psz_name );
1741 if( schedule->b_enabled == VLC_TRUE )
1743 i_length += strlen( "date //-:: enabled\n" ) + 14;
1747 i_length += strlen( "date //-:: disabled\n" ) + 14;
1751 if( schedule->i_period != 0 )
1753 i_length += strlen( "setup " ) + strlen( schedule->psz_name ) +
1754 strlen( "period //-::\n" ) + 14;
1757 if( schedule->i_repeat >= 0 )
1761 sprintf( buffer, "%d", schedule->i_repeat );
1762 i_length += strlen( "setup repeat \n" ) +
1763 strlen( schedule->psz_name ) + strlen( buffer );
1770 for( j = 0; j < schedule->i_command; j++ )
1772 i_length += strlen( "setup append \n" ) +
1773 strlen( schedule->psz_name ) + strlen( schedule->command[j] );
1778 /* Don't forget the '\0' */
1780 /* now we have the length of save */
1782 p = save = malloc( i_length );
1785 /* finally we can write in it */
1786 for( i = 0; i < vlm->i_media; i++ )
1788 vlm_media_t *media = vlm->media[i];
1790 if( media->i_type == VOD_TYPE )
1792 p += sprintf( p, "new %s vod ", media->psz_name);
1796 p += sprintf( p, "new %s broadcast ", media->psz_name);
1799 if( media->b_enabled == VLC_TRUE )
1801 p += sprintf( p, "enabled" );
1805 p += sprintf( p, "disabled" );
1808 if( media->b_loop == VLC_TRUE )
1810 p += sprintf( p, " loop\n" );
1814 p += sprintf( p, "\n" );
1817 for( j = 0; j < media->i_input; j++ )
1819 p += sprintf( p, "setup %s input \"%s\"\n", media->psz_name,
1823 if( media->psz_output != NULL )
1825 p += sprintf( p, "setup %s output %s\n", media->psz_name,
1826 media->psz_output );
1829 for( j = 0; j < media->i_option; j++ )
1831 p += sprintf( p, "setup %s option %s\n", media->psz_name,
1836 /* and now, the schedule scripts */
1838 for( i = 0; i < vlm->i_schedule; i++ )
1840 vlm_schedule_t *schedule = vlm->schedule[i];
1842 time_t i_time = (time_t) ( schedule->i_date / 1000000 );
1844 #ifdef HAVE_LOCALTIME_R
1845 localtime_r( &i_time, &date);
1847 struct tm *p_date = localtime( &i_time );
1851 p += sprintf( p, "new %s schedule ", schedule->psz_name);
1853 if( schedule->b_enabled == VLC_TRUE )
1855 p += sprintf( p, "date %d/%d/%d-%d:%d:%d enabled\n",
1856 date.tm_year + 1900, date.tm_mon + 1, date.tm_mday,
1857 date.tm_hour, date.tm_min, date.tm_sec );
1861 p += sprintf( p, "date %d/%d/%d-%d:%d:%d disabled\n",
1862 date.tm_year + 1900, date.tm_mon + 1, date.tm_mday,
1863 date.tm_hour, date.tm_min, date.tm_sec);
1866 if( schedule->i_period != 0 )
1868 p += sprintf( p, "setup %s ", schedule->psz_name );
1870 i_time = (time_t) ( schedule->i_period / 1000000 );
1872 date.tm_sec = (int)( i_time % 60 );
1873 i_time = i_time / 60;
1874 date.tm_min = (int)( i_time % 60 );
1875 i_time = i_time / 60;
1876 date.tm_hour = (int)( i_time % 24 );
1877 i_time = i_time / 24;
1878 date.tm_mday = (int)( i_time % 30 );
1879 i_time = i_time / 30;
1880 /* okay, okay, months are not always 30 days long */
1881 date.tm_mon = (int)( i_time % 12 );
1882 i_time = i_time / 12;
1883 date.tm_year = (int)i_time;
1885 p += sprintf( p, "period %d/%d/%d-%d:%d:%d\n",
1886 date.tm_year, date.tm_mon, date.tm_mday,
1887 date.tm_hour, date.tm_min, date.tm_sec);
1890 if( schedule->i_repeat >= 0 )
1892 p += sprintf( p, "setup %s repeat %d\n",
1893 schedule->psz_name, schedule->i_repeat );
1897 p += sprintf( p, "\n" );
1900 for( j = 0; j < schedule->i_command; j++ )
1902 p += sprintf( p, "setup %s append %s\n",
1903 schedule->psz_name, schedule->command[j] );
1911 static vlm_schedule_t *vlm_ScheduleNew( vlm_t *vlm, char *psz_name )
1913 vlm_schedule_t *sched = malloc( sizeof( vlm_schedule_t ) );
1915 sched->psz_name = strdup( psz_name );
1916 sched->b_enabled = VLC_FALSE;
1917 sched->i_command = 0;
1918 sched->command = NULL;
1920 sched->i_period = 0;
1921 sched->i_repeat = -1;
1923 TAB_APPEND( vlm->i_schedule, vlm->schedule, sched );
1928 /* for now, simple delete. After, del with options (last arg) */
1929 static int vlm_ScheduleDelete( vlm_t *vlm, vlm_schedule_t *sched,
1939 TAB_REMOVE( vlm->i_schedule, vlm->schedule, sched );
1941 if( vlm->i_schedule == 0 && vlm->schedule ) free( vlm->schedule );
1943 free( sched->psz_name );
1945 for( i = 0; i < sched->i_command; i++ )
1947 free( sched->command[i] );
1955 static vlm_schedule_t *vlm_ScheduleSearch( vlm_t *vlm, char *psz_name )
1959 for( i = 0; i < vlm->i_schedule; i++ )
1961 if( strcmp( psz_name, vlm->schedule[i]->psz_name ) == 0 )
1963 return vlm->schedule[i];
1970 /* Ok, setup schedule command will be able to support only one (argument value) at a time */
1971 static int vlm_ScheduleSetup( vlm_schedule_t *schedule, char *psz_cmd,
1974 if( strcmp( psz_cmd, "enabled" ) == 0 )
1976 schedule->b_enabled = VLC_TRUE;
1978 else if( strcmp( psz_cmd, "disabled" ) == 0 )
1980 schedule->b_enabled = VLC_FALSE;
1982 else if( strcmp( psz_cmd, "date" ) == 0 )
1988 time.tm_sec = 0; /* seconds */
1989 time.tm_min = 0; /* minutes */
1990 time.tm_hour = 0; /* hours */
1991 time.tm_mday = 0; /* day of the month */
1992 time.tm_mon = 0; /* month */
1993 time.tm_year = 0; /* year */
1994 time.tm_wday = 0; /* day of the week */
1995 time.tm_yday = 0; /* day in the year */
1996 time.tm_isdst = 0; /* daylight saving time */
1998 /* date should be year/month/day-hour:minutes:seconds */
1999 p = strchr( psz_value, '-' );
2001 if( strcmp( psz_value, "now" ) == 0 )
2003 schedule->i_date = 0;
2005 else 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 */
2013 switch( sscanf( p + 1, "%d:%d:%d", &i, &j, &k ) )
2033 switch( sscanf( psz_value, "%d/%d/%d", &i, &j, &k ) )
2039 time.tm_mon = i - 1;
2043 time.tm_year = i - 1900;
2044 time.tm_mon = j - 1;
2051 date = mktime( &time );
2052 schedule->i_date = ((mtime_t) date) * 1000000;
2055 else if( strcmp( psz_cmd, "period" ) == 0 )
2059 char *psz_time = NULL, *psz_date = NULL;
2063 /* First, if date or period are modified, repeat should be equal to -1 */
2064 schedule->i_repeat = -1;
2066 time.tm_sec = 0; /* seconds */
2067 time.tm_min = 0; /* minutes */
2068 time.tm_hour = 0; /* hours */
2069 time.tm_mday = 0; /* day of the month */
2070 time.tm_mon = 0; /* month */
2071 time.tm_year = 0; /* year */
2072 time.tm_wday = 0; /* day of the week */
2073 time.tm_yday = 0; /* day in the year */
2074 time.tm_isdst = 0; /* daylight saving time */
2076 /* date should be year/month/day-hour:minutes:seconds */
2077 p = strchr( psz_value, '-' );
2080 psz_date = psz_value;
2087 psz_time = psz_value;
2091 switch( sscanf( psz_time, "%d:%d:%d", &i, &j, &k ) )
2110 switch( sscanf( psz_date, "%d/%d/%d", &i, &j, &k ) )
2129 /* ok, that's stupid... who is going to schedule streams every 42 years ? */
2130 date = (((( time.tm_year * 12 + time.tm_mon ) * 30 + time.tm_mday ) * 24 + time.tm_hour ) * 60 + time.tm_min ) * 60 + time.tm_sec ;
2131 schedule->i_period = ((mtime_t) date) * 1000000;
2133 else if( strcmp( psz_cmd, "repeat" ) == 0 )
2137 if( sscanf( psz_value, "%d", &i ) == 1 )
2139 schedule->i_repeat = i;
2146 else if( strcmp( psz_cmd, "append" ) == 0 )
2148 char *command = strdup( psz_value );
2150 TAB_APPEND( schedule->i_command, schedule->command, command );
2159 /*****************************************************************************
2161 *****************************************************************************/
2162 static int Manage( vlc_object_t* p_object )
2164 vlm_t *vlm = (vlm_t*)p_object;
2166 mtime_t i_lastcheck;
2169 i_lastcheck = mdate();
2173 while( !vlm->b_die )
2175 vlc_mutex_lock( &vlm->lock );
2177 /* destroy the inputs that wants to die, and launch the next input */
2178 for( i = 0; i < vlm->i_media; i++ )
2180 vlm_media_t *media = vlm->media[i];
2182 if( media->p_input != NULL &&
2183 ( media->p_input->b_eof || media->p_input->b_error ) )
2185 input_StopThread( media->p_input );
2187 input_DestroyThread( media->p_input );
2188 vlc_object_detach( media->p_input );
2189 vlc_object_destroy( media->p_input );
2190 media->p_input = NULL;
2193 if( media->i_index == media->i_input &&
2194 media->b_loop == VLC_TRUE )
2199 if( media->i_index < media->i_input )
2203 sprintf( buffer, "%d", media->i_index );
2204 vlm_MediaControl( vlm, media, "play", buffer );
2212 for( i = 0; i < vlm->i_schedule; i++ )
2214 mtime_t i_real_date = vlm->schedule[i]->i_date;
2216 if( vlm->schedule[i]->b_enabled == VLC_TRUE )
2218 if( vlm->schedule[i]->i_date == 0 ) // now !
2220 vlm->schedule[i]->i_date = (i_time / 1000000) * 1000000 ;
2221 i_real_date = i_time;
2223 else if( vlm->schedule[i]->i_period != 0 )
2226 while( vlm->schedule[i]->i_date + j *
2227 vlm->schedule[i]->i_period <= i_lastcheck &&
2228 ( vlm->schedule[i]->i_repeat > j ||
2229 vlm->schedule[i]->i_repeat == -1 ) )
2234 i_real_date = vlm->schedule[i]->i_date + j *
2235 vlm->schedule[i]->i_period;
2238 if( i_real_date <= i_time && i_real_date > i_lastcheck )
2240 for( j = 0; j < vlm->schedule[i]->i_command; j++ )
2242 vlm_message_t *message = NULL;
2244 ExecuteCommand( vlm, vlm->schedule[i]->command[j],
2247 /* for now, drop the message */
2254 i_lastcheck = i_time;
2256 vlc_mutex_unlock( &vlm->lock );
2264 static vlm_message_t* vlm_MessageNew( char *psz_name, char *psz_value )
2266 vlm_message_t *message = malloc( sizeof(vlm_message_t) );
2270 message->psz_name = strdup( psz_name );
2279 message->psz_value = strdup( psz_value );
2283 message->psz_value = NULL;
2286 message->i_child = 0;
2287 message->child = NULL;
2292 void vlm_MessageDelete( vlm_message_t* message )
2296 if( message->psz_name ) free( message->psz_name );
2297 if( message->psz_value ) free( message->psz_value );
2299 for( i = 0; i < message->i_child; i++)
2301 vlm_MessageDelete( message->child[i] );
2308 static vlm_message_t *vlm_MessageAdd( vlm_message_t* message,
2309 vlm_message_t* child )
2311 if( message == NULL ) return NULL;
2315 TAB_APPEND( message->i_child, message->child, child );