#include <stdlib.h>
#include <string.h>
#include <signal.h>
+
+/* Needed for backtrace on linux */
+#ifdef linux
#include <execinfo.h>
-#include <stdio.h>
+#endif
/* Valerie header files */
#include <valerie/valerie_util.h>
static valerie_response miracle_local_connect( miracle_local );
static valerie_response miracle_local_execute( miracle_local, char * );
+static valerie_response miracle_local_push( miracle_local, char *, mlt_service );
+static valerie_response miracle_local_receive( miracle_local, char *, char * );
static void miracle_local_close( miracle_local );
response_codes miracle_help( command_argument arg );
response_codes miracle_run( command_argument arg );
parser->connect = (parser_connect)miracle_local_connect;
parser->execute = (parser_execute)miracle_local_execute;
+ parser->push = (parser_push)miracle_local_push;
+ parser->received = (parser_received)miracle_local_receive;
parser->close = (parser_close)miracle_local_close;
parser->real = local;
ATYPE_NONE,
ATYPE_FLOAT,
ATYPE_STRING,
- ATYPE_INT
+ ATYPE_INT,
+ ATYPE_PAIR
}
arguments_types;
{"UADD", miracle_add_unit, 0, ATYPE_STRING, "Create a new DV unit (virtual VTR) to transmit to receiver specified in GUID argument."},
{"ULS", miracle_list_units, 0, ATYPE_NONE, "Lists the units that have already been added to the server."},
{"CLS", miracle_list_clips, 0, ATYPE_STRING, "Lists the clips at directory name argument."},
- {"SET", miracle_set_global_property, 0, ATYPE_STRING, "Set a server configuration property."},
+ {"SET", miracle_set_global_property, 0, ATYPE_PAIR, "Set a server configuration property."},
{"GET", miracle_get_global_property, 0, ATYPE_STRING, "Get a server configuration property."},
{"RUN", miracle_run, 0, ATYPE_STRING, "Run a batch file." },
{"LIST", miracle_list, 1, ATYPE_NONE, "List the playlist associated to a unit."},
{"INSERT", miracle_insert, 1, ATYPE_STRING, "Insert a clip at the given clip index."},
{"REMOVE", miracle_remove, 1, ATYPE_NONE, "Remove a clip at the given clip index."},
{"CLEAN", miracle_clean, 1, ATYPE_NONE, "Clean a unit by removing all but the currently playing clip."},
+ {"WIPE", miracle_wipe, 1, ATYPE_NONE, "Clean a unit by removing everything before the currently playing clip."},
+ {"CLEAR", miracle_clear, 1, ATYPE_NONE, "Clear a unit by removing all clips."},
{"MOVE", miracle_move, 1, ATYPE_INT, "Move a clip to another clip index."},
{"APND", miracle_append, 1, ATYPE_STRING, "Append a clip specified in absolute filename argument."},
{"PLAY", miracle_play, 1, ATYPE_NONE, "Play a loaded clip at speed -2000 to 2000 where 1000 = normal forward speed."},
{"SIN", miracle_set_in_point, 1, ATYPE_INT, "Set the IN point of the loaded clip to frame number argument. -1 = reset in point to 0"},
{"SOUT", miracle_set_out_point, 1, ATYPE_INT, "Set the OUT point of the loaded clip to frame number argument. -1 = reset out point to maximum."},
{"USTA", miracle_get_unit_status, 1, ATYPE_NONE, "Report information about the unit."},
- {"USET", miracle_set_unit_property, 1, ATYPE_STRING, "Set a unit configuration property."},
+ {"USET", miracle_set_unit_property, 1, ATYPE_PAIR, "Set a unit configuration property."},
{"UGET", miracle_get_unit_property, 1, ATYPE_STRING, "Get a unit configuration property."},
{"XFER", miracle_transfer, 1, ATYPE_STRING, "Transfer the unit's clip to another unit specified as argument."},
{"SHUTDOWN", miracle_shutdown, 0, ATYPE_NONE, "Shutdown the server."},
static void sigsegv_handler()
{
+#ifdef linux
void *array[ 10 ];
size_t size;
char **strings;
free( strings );
miracle_log( LOG_CRIT, "\nDone dumping - exiting.\n" );
+#else
+ miracle_log( LOG_CRIT, "\a\nMiracle experienced a segmentation fault.\n" );
+#endif
exit( EXIT_FAILURE );
}
/** Parse a normal argument.
*/
-void *miracle_command_parse_argument( command_argument cmd, int argument, arguments_types type )
+void *miracle_command_parse_argument( command_argument cmd, int argument, arguments_types type, char *command )
{
void *ret = NULL;
char *value = valerie_tokeniser_get_string( cmd->tokeniser, argument );
ret = strdup( value );
break;
+ case ATYPE_PAIR:
+ if ( strchr( command, '=' ) )
+ {
+ char *ptr = strchr( command, '=' );
+ while ( *( ptr - 1 ) != ' ' )
+ ptr --;
+ ret = strdup( ptr );
+ ptr = ret;
+ while( ptr[ strlen( ptr ) - 1 ] == ' ' )
+ ptr[ strlen( ptr ) - 1 ] = '\0';
+ }
+ break;
+
case ATYPE_INT:
ret = malloc( sizeof( int ) );
if ( ret != NULL )
if ( miracle_command_get_error( &cmd ) == RESPONSE_SUCCESS )
{
- cmd.argument = miracle_command_parse_argument( &cmd, position, vocabulary[ index ].type );
+ cmd.argument = miracle_command_parse_argument( &cmd, position, vocabulary[ index ].type, command );
if ( cmd.argument == NULL && vocabulary[ index ].type != ATYPE_NONE )
miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG );
position ++;
return cmd.response;
}
+static valerie_response miracle_local_receive( miracle_local local, char *command, char *doc )
+{
+ command_argument_t cmd;
+ cmd.parser = local->parser;
+ cmd.response = valerie_response_init( );
+ cmd.tokeniser = valerie_tokeniser_init( );
+ cmd.command = command;
+ cmd.unit = -1;
+ cmd.argument = NULL;
+ cmd.root_dir = local->root_dir;
+
+ /* Set the default error */
+ miracle_command_set_error( &cmd, RESPONSE_SUCCESS );
+
+ /* Parse the command */
+ if ( valerie_tokeniser_parse_new( cmd.tokeniser, command, " " ) > 0 )
+ {
+ int index = 0;
+ int position = 1;
+
+ /* Strip quotes from all tokens */
+ for ( index = 0; index < valerie_tokeniser_count( cmd.tokeniser ); index ++ )
+ valerie_util_strip( valerie_tokeniser_get_string( cmd.tokeniser, index ), '\"' );
+
+ cmd.unit = miracle_command_parse_unit( &cmd, position );
+ if ( cmd.unit == -1 )
+ miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG );
+ position ++;
+
+ miracle_receive( &cmd, doc );
+ miracle_command_set_error( &cmd, RESPONSE_SUCCESS );
+
+ free( cmd.argument );
+ }
+
+ valerie_tokeniser_close( cmd.tokeniser );
+
+ return cmd.response;
+}
+
+static valerie_response miracle_local_push( miracle_local local, char *command, mlt_service service )
+{
+ command_argument_t cmd;
+ cmd.parser = local->parser;
+ cmd.response = valerie_response_init( );
+ cmd.tokeniser = valerie_tokeniser_init( );
+ cmd.command = command;
+ cmd.unit = -1;
+ cmd.argument = NULL;
+ cmd.root_dir = local->root_dir;
+
+ /* Set the default error */
+ miracle_command_set_error( &cmd, RESPONSE_SUCCESS );
+
+ /* Parse the command */
+ if ( valerie_tokeniser_parse_new( cmd.tokeniser, command, " " ) > 0 )
+ {
+ int index = 0;
+ int position = 1;
+
+ /* Strip quotes from all tokens */
+ for ( index = 0; index < valerie_tokeniser_count( cmd.tokeniser ); index ++ )
+ valerie_util_strip( valerie_tokeniser_get_string( cmd.tokeniser, index ), '\"' );
+
+ cmd.unit = miracle_command_parse_unit( &cmd, position );
+ if ( cmd.unit == -1 )
+ miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG );
+ position ++;
+
+ miracle_push( &cmd, service );
+ miracle_command_set_error( &cmd, RESPONSE_SUCCESS );
+
+ free( cmd.argument );
+ }
+
+ valerie_tokeniser_close( cmd.tokeniser );
+
+ return cmd.response;
+}
+
/** Close the parser.
*/
static void miracle_local_close( miracle_local local )
{
miracle_delete_all_units();
- pthread_kill_other_threads_np();
+#ifdef linux
+ //pthread_kill_other_threads_np();
miracle_log( LOG_DEBUG, "Clean shutdown." );
- free( local );
+ //free( local );
//mlt_factory_close( );
+#endif
}