X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmiracle%2Fmiracle_local.c;h=c1029a19d828530f712ed605e998370692f58dcc;hb=ced3d0b8c0520e4c8208166e3218e0caacba1efa;hp=fce4ab2214f1f07f58b5d49198b99781669762b4;hpb=661165812e3410fe2f6f49d7af882b36a0efcf82;p=melted diff --git a/src/miracle/miracle_local.c b/src/miracle/miracle_local.c index fce4ab2..c1029a1 100644 --- a/src/miracle/miracle_local.c +++ b/src/miracle/miracle_local.c @@ -1,5 +1,5 @@ /* - * dvlocal.c -- Local dv1394d Parser + * miracle_local.c -- Local Miracle Parser * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Charles Yates * @@ -27,62 +27,74 @@ #include #include -/* Library header files */ -#include +/* Needed for backtrace on linux */ +#ifdef linux +#include +#endif + +/* Valerie header files */ +#include + +/* MLT header files. */ +#include /* Application header files */ -#include -#include -#include "dvlocal.h" -#include "dvconnection.h" -#include "global_commands.h" -#include "unit_commands.h" -#include "log.h" -#include "raw1394util.h" - -/** Private dv_local structure. +#include "miracle_local.h" +#include "miracle_connection.h" +#include "miracle_commands.h" +#include "miracle_unit_commands.h" +#include "miracle_log.h" + +/** Private miracle_local structure. */ typedef struct { - dv_parser parser; + valerie_parser parser; char root_dir[1024]; } -*dv_local, dv_local_t; +*miracle_local, miracle_local_t; /** Forward declarations. */ -static dv_response dv_local_connect( dv_local ); -static dv_response dv_local_execute( dv_local, char * ); -static void dv_local_close( dv_local ); -response_codes print_help( command_argument arg ); -response_codes dv1394d_run( command_argument arg ); -response_codes dv1394d_shutdown( command_argument arg ); +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 ); +response_codes miracle_shutdown( command_argument arg ); /** DV Parser constructor. */ -dv_parser dv_parser_init_local( ) +valerie_parser miracle_parser_init_local( ) { - dv_parser parser = malloc( sizeof( dv_parser_t ) ); - dv_local local = malloc( sizeof( dv_local_t ) ); + valerie_parser parser = malloc( sizeof( valerie_parser_t ) ); + miracle_local local = malloc( sizeof( miracle_local_t ) ); if ( parser != NULL ) { - memset( parser, 0, sizeof( dv_parser_t ) ); + memset( parser, 0, sizeof( valerie_parser_t ) ); - parser->connect = (parser_connect)dv_local_connect; - parser->execute = (parser_execute)dv_local_execute; - parser->close = (parser_close)dv_local_close; + 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; if ( local != NULL ) { - memset( local, 0, sizeof( dv_local_t ) ); + memset( local, 0, sizeof( miracle_local_t ) ); local->parser = parser; local->root_dir[0] = '/'; } + + // Construct the factory + mlt_factory_init( getenv( "MLT_REPOSITORY" ) ); } return parser; } @@ -93,7 +105,7 @@ dv_parser dv_parser_init_local( ) typedef struct { int code; - char *message; + const char *message; } responses_t; @@ -123,7 +135,8 @@ typedef enum ATYPE_NONE, ATYPE_FLOAT, ATYPE_STRING, - ATYPE_INT + ATYPE_INT, + ATYPE_PAIR } arguments_types; @@ -133,7 +146,7 @@ arguments_types; typedef struct { /* The command string corresponding to this operation (e.g. "play") */ - char *command; + const char *command; /* The function associated with it */ response_codes (*operation) ( command_argument ); /* a boolean to indicate if this is a unit or global command @@ -142,7 +155,7 @@ typedef struct /* What type is the argument (RTTI :-) ATYPE_whatever */ int type; /* online help information */ - char *help; + const char *help; } command_t; @@ -156,35 +169,37 @@ command_t; static command_t vocabulary[] = { {"BYE", NULL, 0, ATYPE_NONE, "Terminates the session. Units are not removed and task queue is not flushed."}, - {"HELP", print_help, 0, ATYPE_NONE, "Display this information!"}, - {"NLS", dv1394d_list_nodes, 0, ATYPE_NONE, "List the AV/C nodes on the 1394 bus."}, - {"UADD", dv1394d_add_unit, 0, ATYPE_STRING, "Create a new DV unit (virtual VTR) to transmit to receiver specified in GUID argument."}, - {"ULS", dv1394d_list_units, 0, ATYPE_NONE, "Lists the units that have already been added to the server."}, - {"CLS", dv1394d_list_clips, 0, ATYPE_STRING, "Lists the clips at directory name argument."}, - {"SET", dv1394d_set_global_property, 0, ATYPE_STRING, "Set a server configuration property."}, - {"GET", dv1394d_get_global_property, 0, ATYPE_STRING, "Get a server configuration property."}, - {"RUN", dv1394d_run, 0, ATYPE_STRING, "Run a batch file." }, - {"LIST", dv1394d_list, 1, ATYPE_NONE, "List the playlist associated to a unit."}, - {"LOAD", dv1394d_load, 1, ATYPE_STRING, "Load clip specified in absolute filename argument."}, - {"INSERT", dv1394d_insert, 1, ATYPE_STRING, "Insert a clip at the given clip index."}, - {"REMOVE", dv1394d_remove, 1, ATYPE_NONE, "Remove a clip at the given clip index."}, - {"CLEAN", dv1394d_clean, 1, ATYPE_NONE, "Clean a unit by removing all but the currently playing clip."}, - {"MOVE", dv1394d_move, 1, ATYPE_INT, "Move a clip to another clip index."}, - {"APND", dv1394d_append, 1, ATYPE_STRING, "Append a clip specified in absolute filename argument."}, - {"PLAY", dv1394d_play, 1, ATYPE_NONE, "Play a loaded clip at speed -2000 to 2000 where 1000 = normal forward speed."}, - {"STOP", dv1394d_stop, 1, ATYPE_NONE, "Stop a loaded and playing clip."}, - {"PAUSE", dv1394d_pause, 1, ATYPE_NONE, "Pause a playing clip."}, - {"REW", dv1394d_rewind, 1, ATYPE_NONE, "Rewind a unit. If stopped, seek to beginning of clip. If playing, play fast backwards."}, - {"FF", dv1394d_ff, 1, ATYPE_NONE, "Fast forward a unit. If stopped, seek to beginning of clip. If playing, play fast forwards."}, - {"STEP", dv1394d_step, 1, ATYPE_INT, "Step argument number of frames forward or backward."}, - {"GOTO", dv1394d_goto, 1, ATYPE_INT, "Jump to frame number supplied as argument."}, - {"SIN", dv1394d_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", dv1394d_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", dv1394d_get_unit_status, 1, ATYPE_NONE, "Report information about the unit."}, - {"USET", dv1394d_set_unit_property, 1, ATYPE_STRING, "Set a unit configuration property."}, - {"UGET", dv1394d_get_unit_property, 1, ATYPE_STRING, "Get a unit configuration property."}, - {"XFER", dv1394d_transfer, 1, ATYPE_STRING, "Transfer the unit's clip to another unit specified as argument."}, - {"SHUTDOWN", dv1394d_shutdown, 0, ATYPE_NONE, "Shutdown the server."}, + {"HELP", miracle_help, 0, ATYPE_NONE, "Display this information!"}, + {"NLS", miracle_list_nodes, 0, ATYPE_NONE, "List the AV/C nodes on the 1394 bus."}, + {"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_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."}, + {"LOAD", miracle_load, 1, ATYPE_STRING, "Load clip specified in absolute filename argument."}, + {"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."}, + {"STOP", miracle_stop, 1, ATYPE_NONE, "Stop a loaded and playing clip."}, + {"PAUSE", miracle_pause, 1, ATYPE_NONE, "Pause a playing clip."}, + {"REW", miracle_rewind, 1, ATYPE_NONE, "Rewind a unit. If stopped, seek to beginning of clip. If playing, play fast backwards."}, + {"FF", miracle_ff, 1, ATYPE_NONE, "Fast forward a unit. If stopped, seek to beginning of clip. If playing, play fast forwards."}, + {"STEP", miracle_step, 1, ATYPE_INT, "Step argument number of frames forward or backward."}, + {"GOTO", miracle_goto, 1, ATYPE_INT, "Jump to frame number supplied as argument."}, + {"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_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."}, {NULL, NULL, 0, ATYPE_NONE, NULL} }; @@ -192,7 +207,7 @@ static command_t vocabulary[] = */ static char helpstr [] = - "dv1394d -- A DV over IEEE 1394 TCP Server\n" + "Miracle -- A Multimedia Playout Server\n" " Copyright (C) 2002-2003 Ushodaya Enterprises Limited\n" " Authors:\n" " Dan Dennedy \n" @@ -202,29 +217,29 @@ static char helpstr [] = /** Lookup the response message for a status code. */ -inline char *get_response_msg( int code ) +inline const char *get_response_msg( int code ) { int i = 0; for ( i = 0; responses[ i ].message != NULL && code != responses[ i ].code; i ++ ) ; return responses[ i ].message; } -/** Tell the user the dv1394d command set +/** Tell the user the miracle command set */ -response_codes print_help( command_argument cmd_arg ) +response_codes miracle_help( command_argument cmd_arg ) { int i = 0; - dv_response_printf( cmd_arg->response, 10240, "%s", helpstr ); + valerie_response_printf( cmd_arg->response, 10240, "%s", helpstr ); for ( i = 0; vocabulary[ i ].command != NULL; i ++ ) - dv_response_printf( cmd_arg->response, 1024, + valerie_response_printf( cmd_arg->response, 1024, "%-10.10s%s\n", vocabulary[ i ].command, vocabulary[ i ].help ); - dv_response_printf( cmd_arg->response, 2, "\n" ); + valerie_response_printf( cmd_arg->response, 2, "\n" ); return RESPONSE_SUCCESS_N; } @@ -232,28 +247,28 @@ response_codes print_help( command_argument cmd_arg ) /** Execute a batch file. */ -response_codes dv1394d_run( command_argument cmd_arg ) +response_codes miracle_run( command_argument cmd_arg ) { - dv_response temp = dv_parser_run( cmd_arg->parser, (char *)cmd_arg->argument ); + valerie_response temp = valerie_parser_run( cmd_arg->parser, (char *)cmd_arg->argument ); if ( temp != NULL ) { int index = 0; - dv_response_set_error( cmd_arg->response, - dv_response_get_error_code( temp ), - dv_response_get_error_string( temp ) ); + valerie_response_set_error( cmd_arg->response, + valerie_response_get_error_code( temp ), + valerie_response_get_error_string( temp ) ); - for ( index = 1; index < dv_response_count( temp ); index ++ ) - dv_response_printf( cmd_arg->response, 10240, "%s\n", dv_response_get_line( temp, index ) ); + for ( index = 1; index < valerie_response_count( temp ); index ++ ) + valerie_response_printf( cmd_arg->response, 10240, "%s\n", valerie_response_get_line( temp, index ) ); - dv_response_close( temp ); + valerie_response_close( temp ); } - return dv_response_get_error_code( cmd_arg->response ); + return valerie_response_get_error_code( cmd_arg->response ); } -response_codes dv1394d_shutdown( command_argument cmd_arg ) +response_codes miracle_shutdown( command_argument cmd_arg ) { exit( 0 ); return RESPONSE_SUCCESS; @@ -274,35 +289,64 @@ void signal_handler( int sig ) { #ifdef _GNU_SOURCE - dv1394d_log( LOG_DEBUG, "Received %s - shutting down.", strsignal(sig) ); + miracle_log( LOG_DEBUG, "Received %s - shutting down.", strsignal(sig) ); #else - dv1394d_log( LOG_DEBUG, "Received signal %i - shutting down.", sig ); + miracle_log( LOG_DEBUG, "Received signal %i - shutting down.", sig ); #endif exit(EXIT_SUCCESS); } } +static void sigsegv_handler() +{ +#ifdef linux + void *array[ 10 ]; + size_t size; + char **strings; + size_t i; + + miracle_log( LOG_CRIT, "\a\nMiracle experienced a segmentation fault.\n" + "Dumping stack from the offending thread\n\n" ); + size = backtrace( array, 10 ); + strings = backtrace_symbols( array, size ); + + miracle_log( LOG_CRIT, "Obtained %zd stack frames.\n", size ); + + for ( i = 0; i < size; i++ ) + miracle_log( LOG_CRIT, "%s", strings[ i ] ); + + 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 ); +} + + + /** Local 'connect' function. */ -static dv_response dv_local_connect( dv_local local ) +static valerie_response miracle_local_connect( miracle_local local ) { - dv_response response = dv_response_init( ); + valerie_response response = valerie_response_init( ); self = pthread_self( ); - dv_response_set_error( response, 100, "VTR Ready" ); + valerie_response_set_error( response, 100, "VTR Ready" ); signal( SIGHUP, signal_handler ); signal( SIGINT, signal_handler ); - signal( SIGTERM, signal_handler ); + signal( SIGTERM, SIG_DFL ); signal( SIGSTOP, signal_handler ); + signal( SIGPIPE, signal_handler ); + signal( SIGALRM, signal_handler ); signal( SIGCHLD, SIG_IGN ); - - raw1394_reconcile_bus(); - /* Start the raw1394 service threads for handling bus resets */ - raw1394_start_service_threads(); + if ( getenv( "MLT_SIGSEGV" ) ) + signal( SIGSEGV, sigsegv_handler ); return response; } @@ -310,18 +354,18 @@ static dv_response dv_local_connect( dv_local local ) /** Set the error and determine the message associated to this command. */ -void dv_command_set_error( command_argument cmd, response_codes code ) +void miracle_command_set_error( command_argument cmd, response_codes code ) { - dv_response_set_error( cmd->response, code, get_response_msg( code ) ); + valerie_response_set_error( cmd->response, code, get_response_msg( code ) ); } /** Parse the unit argument. */ -int dv_command_parse_unit( command_argument cmd, int argument ) +int miracle_command_parse_unit( command_argument cmd, int argument ) { int unit = -1; - char *string = dv_tokeniser_get_string( cmd->tokeniser, argument ); + char *string = valerie_tokeniser_get_string( cmd->tokeniser, argument ); if ( string != NULL && ( string[ 0 ] == 'U' || string[ 0 ] == 'u' ) && strlen( string ) > 1 ) unit = atoi( string + 1 ); return unit; @@ -330,10 +374,10 @@ int dv_command_parse_unit( command_argument cmd, int argument ) /** Parse a normal argument. */ -void *dv_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 = dv_tokeniser_get_string( cmd->tokeniser, argument ); + char *value = valerie_tokeniser_get_string( cmd->tokeniser, argument ); if ( value != NULL ) { @@ -352,6 +396,19 @@ void *dv_command_parse_argument( command_argument cmd, int argument, arguments_t 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 ) @@ -366,9 +423,9 @@ void *dv_command_parse_argument( command_argument cmd, int argument, arguments_t /** Get the error code - note that we simply the success return. */ -response_codes dv_command_get_error( command_argument cmd ) +response_codes miracle_command_get_error( command_argument cmd ) { - response_codes ret = dv_response_get_error_code( cmd->response ); + response_codes ret = valerie_response_get_error_code( cmd->response ); if ( ret == RESPONSE_SUCCESS_N || ret == RESPONSE_SUCCESS_1 ) ret = RESPONSE_SUCCESS; return ret; @@ -377,30 +434,30 @@ response_codes dv_command_get_error( command_argument cmd ) /** Execute the command. */ -static dv_response dv_local_execute( dv_local local, char *command ) +static valerie_response miracle_local_execute( miracle_local local, char *command ) { command_argument_t cmd; cmd.parser = local->parser; - cmd.response = dv_response_init( ); - cmd.tokeniser = dv_tokeniser_init( ); + 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 */ - dv_command_set_error( &cmd, RESPONSE_UNKNOWN_COMMAND ); + miracle_command_set_error( &cmd, RESPONSE_UNKNOWN_COMMAND ); /* Parse the command */ - if ( dv_tokeniser_parse_new( cmd.tokeniser, command, " " ) > 0 ) + if ( valerie_tokeniser_parse_new( cmd.tokeniser, command, " " ) > 0 ) { int index = 0; - char *value = dv_tokeniser_get_string( cmd.tokeniser, 0 ); + char *value = valerie_tokeniser_get_string( cmd.tokeniser, 0 ); int found = 0; /* Strip quotes from all tokens */ - for ( index = 0; index < dv_tokeniser_count( cmd.tokeniser ); index ++ ) - dv_util_strip( dv_tokeniser_get_string( cmd.tokeniser, index ), '\"' ); + for ( index = 0; index < valerie_tokeniser_count( cmd.tokeniser ); index ++ ) + valerie_util_strip( valerie_tokeniser_get_string( cmd.tokeniser, index ), '\"' ); /* Search the vocabulary array for value */ for ( index = 1; !found && vocabulary[ index ].command != NULL; index ++ ) @@ -412,35 +469,115 @@ static dv_response dv_local_execute( dv_local local, char *command ) { int position = 1; - dv_command_set_error( &cmd, RESPONSE_SUCCESS ); + miracle_command_set_error( &cmd, RESPONSE_SUCCESS ); if ( vocabulary[ index ].is_unit ) { - cmd.unit = dv_command_parse_unit( &cmd, position ); + cmd.unit = miracle_command_parse_unit( &cmd, position ); if ( cmd.unit == -1 ) - dv_command_set_error( &cmd, RESPONSE_MISSING_ARG ); + miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG ); position ++; } - if ( dv_command_get_error( &cmd ) == RESPONSE_SUCCESS ) + if ( miracle_command_get_error( &cmd ) == RESPONSE_SUCCESS ) { - cmd.argument = dv_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 ) - dv_command_set_error( &cmd, RESPONSE_MISSING_ARG ); + miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG ); position ++; } - if ( dv_command_get_error( &cmd ) == RESPONSE_SUCCESS ) + if ( miracle_command_get_error( &cmd ) == RESPONSE_SUCCESS ) { response_codes error = vocabulary[ index ].operation( &cmd ); - dv_command_set_error( &cmd, error ); + miracle_command_set_error( &cmd, error ); } free( cmd.argument ); } } - dv_tokeniser_close( cmd.tokeniser ); + valerie_tokeniser_close( cmd.tokeniser ); + + 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; } @@ -448,13 +585,13 @@ static dv_response dv_local_execute( dv_local local, char *command ) /** Close the parser. */ -static void dv_local_close( dv_local local ) +static void miracle_local_close( miracle_local local ) { - raw1394_stop_service_threads(); - dv1394d_delete_all_units(); - pthread_kill_other_threads_np(); - dv1394d_log( LOG_DEBUG, "Clean shutdown." ); - free( local ); - dv_clip_factory_close( ); - dv_frame_pool_close( ); + miracle_delete_all_units(); +#ifdef linux + //pthread_kill_other_threads_np(); + miracle_log( LOG_DEBUG, "Clean shutdown." ); + //free( local ); + //mlt_factory_close( ); +#endif }