| 225 | | static const char quotes[] = "\"'"; |
|---|
| 226 | | /** |
|---|
| 227 | | * FindCommandEnd: look for the end of a possibly quoted string |
|---|
| 228 | | * @return NULL on mal-formatted string, |
|---|
| 229 | | * pointer past the last character otherwise. |
|---|
| 230 | | */ |
|---|
| 231 | | static const char *FindCommandEnd( const char *psz_sent ) |
|---|
| 232 | | { |
|---|
| 233 | | char c, quote = 0; |
|---|
| 234 | | |
|---|
| 235 | | while( (c = *psz_sent) != '\0' ) |
|---|
| 236 | | { |
|---|
| 237 | | if( !quote ) |
|---|
| 238 | | { |
|---|
| 239 | | if( strchr(quotes,c) ) // opening quote |
|---|
| 240 | | quote = c; |
|---|
| 241 | | else if( isspace(c) ) // non-escaped space |
|---|
| 242 | | return psz_sent; |
|---|
| 243 | | else if( c == '\\' ) |
|---|
| 244 | | { |
|---|
| 245 | | psz_sent++; // skip escaped character |
|---|
| 246 | | if( *psz_sent == '\0' ) |
|---|
| 247 | | return psz_sent; |
|---|
| 248 | | } |
|---|
| 249 | | } |
|---|
| 250 | | else |
|---|
| 251 | | { |
|---|
| 252 | | if( c == quote ) // non-escaped matching quote |
|---|
| 253 | | quote = 0; |
|---|
| 254 | | else if( (quote == '"') && (c == '\\') ) |
|---|
| 255 | | { |
|---|
| 256 | | psz_sent++; // skip escaped character |
|---|
| 257 | | if (*psz_sent == '\0') |
|---|
| 258 | | return NULL; // error, closing quote missing |
|---|
| 259 | | } |
|---|
| 260 | | } |
|---|
| 261 | | psz_sent++; |
|---|
| 262 | | } |
|---|
| 263 | | |
|---|
| 264 | | // error (NULL) if we could not find a matching quote |
|---|
| 265 | | return quote ? NULL : psz_sent; |
|---|
| 266 | | } |
|---|
| 267 | | |
|---|
| 268 | | |
|---|
| 269 | | /** |
|---|
| 270 | | * Unescape a nul-terminated string. |
|---|
| 271 | | * Note that in and out can be identical. |
|---|
| 272 | | * |
|---|
| 273 | | * @param out output buffer (at least <strlen (in) + 1> characters long) |
|---|
| 274 | | * @param in nul-terminated string to be unescaped |
|---|
| 275 | | * |
|---|
| 276 | | * @return 0 on success, -1 on error. |
|---|
| 277 | | */ |
|---|
| 278 | | static int Unescape( char *out, const char *in ) |
|---|
| 279 | | { |
|---|
| 280 | | char c, quote = 0; |
|---|
| 281 | | |
|---|
| 282 | | while( (c = *in++) != '\0' ) |
|---|
| 283 | | { |
|---|
| 284 | | if( !quote ) |
|---|
| 285 | | { |
|---|
| 286 | | if (strchr(quotes,c)) // opening quote |
|---|
| 287 | | { |
|---|
| 288 | | quote = c; |
|---|
| 289 | | continue; |
|---|
| 290 | | } |
|---|
| 291 | | else if( c == '\\' ) |
|---|
| 292 | | { |
|---|
| 293 | | switch (c = *in++) |
|---|
| 294 | | { |
|---|
| 295 | | case '"': |
|---|
| 296 | | case '\'': |
|---|
| 297 | | case '\\': |
|---|
| 298 | | *out++ = c; |
|---|
| 299 | | continue; |
|---|
| 300 | | |
|---|
| 301 | | case '\0': |
|---|
| 302 | | *out = '\0'; |
|---|
| 303 | | return 0; |
|---|
| 304 | | } |
|---|
| 305 | | if( isspace(c) ) |
|---|
| 306 | | { |
|---|
| 307 | | *out++ = c; |
|---|
| 308 | | continue; |
|---|
| 309 | | } |
|---|
| 310 | | /* None of the special cases - copy the backslash */ |
|---|
| 311 | | *out++ = '\\'; |
|---|
| 312 | | } |
|---|
| 313 | | } |
|---|
| 314 | | else |
|---|
| 315 | | { |
|---|
| 316 | | if( c == quote ) // non-escaped matching quote |
|---|
| 317 | | { |
|---|
| 318 | | quote = 0; |
|---|
| 319 | | continue; |
|---|
| 320 | | } |
|---|
| 321 | | if( (quote == '"') && (c == '\\') ) |
|---|
| 322 | | { |
|---|
| 323 | | switch( c = *in++ ) |
|---|
| 324 | | { |
|---|
| 325 | | case '"': |
|---|
| 326 | | case '\\': |
|---|
| 327 | | *out++ = c; |
|---|
| 328 | | continue; |
|---|
| 329 | | |
|---|
| 330 | | case '\0': // should never happen |
|---|
| 331 | | *out = '\0'; |
|---|
| 332 | | return -1; |
|---|
| 333 | | } |
|---|
| 334 | | /* None of the special cases - copy the backslash */ |
|---|
| 335 | | *out++ = '\\'; |
|---|
| 336 | | } |
|---|
| 337 | | } |
|---|
| 338 | | *out++ = c; |
|---|
| 339 | | } |
|---|
| 340 | | |
|---|
| 341 | | *out = '\0'; |
|---|
| 342 | | return 0; |
|---|
| 343 | | } |
|---|
| 344 | | |
|---|
| 345 | | |
|---|
| 346 | | /***************************************************************************** |
|---|
| 347 | | * ExecuteCommand: The main state machine |
|---|
| 348 | | ***************************************************************************** |
|---|
| 349 | | * Execute a command which ends with '\0' (string) |
|---|
| 350 | | *****************************************************************************/ |
|---|
| 351 | | static int ExecuteSyntaxError( const char *psz_cmd, vlm_message_t **pp_status ) |
|---|
| 352 | | { |
|---|
| 353 | | *pp_status = vlm_MessageNew( psz_cmd, "Wrong command syntax" ); |
|---|
| 354 | | return VLC_EGENERIC; |
|---|
| 355 | | } |
|---|
| 356 | | |
|---|
| 357 | | static bool ExecuteIsMedia( vlm_t *p_vlm, const char *psz_name ) |
|---|
| 358 | | { |
|---|
| 359 | | int64_t id; |
|---|
| 360 | | |
|---|
| 361 | | if( !psz_name || vlm_ControlInternal( p_vlm, VLM_GET_MEDIA_ID, psz_name, &id ) ) |
|---|
| 362 | | return false; |
|---|
| 363 | | return true; |
|---|
| 364 | | } |
|---|
| 365 | | static bool ExecuteIsSchedule( vlm_t *p_vlm, const char *psz_name ) |
|---|
| 366 | | { |
|---|
| 367 | | if( !psz_name || !vlm_ScheduleSearch( p_vlm, psz_name ) ) |
|---|
| 368 | | return false; |
|---|
| 369 | | return true; |
|---|
| 370 | | } |
|---|
| 371 | | |
|---|
| 372 | | static int ExecuteDel( vlm_t *p_vlm, const char *psz_name, vlm_message_t **pp_status ) |
|---|
| 373 | | { |
|---|
| 374 | | vlm_media_sys_t *p_media; |
|---|
| 375 | | vlm_schedule_sys_t *p_schedule; |
|---|
| 376 | | |
|---|
| 377 | | p_media = vlm_MediaSearch( p_vlm, psz_name ); |
|---|
| 378 | | p_schedule = vlm_ScheduleSearch( p_vlm, psz_name ); |
|---|
| 379 | | |
|---|
| 380 | | if( p_schedule != NULL ) |
|---|
| 381 | | { |
|---|
| 382 | | vlm_ScheduleDelete( p_vlm, p_schedule ); |
|---|
| 383 | | } |
|---|
| 384 | | else if( p_media != NULL ) |
|---|
| 385 | | { |
|---|
| 386 | | vlm_ControlInternal( p_vlm, VLM_DEL_MEDIA, p_media->cfg.id ); |
|---|
| 387 | | } |
|---|
| 388 | | else if( !strcmp(psz_name, "media") ) |
|---|
| 389 | | { |
|---|
| 390 | | vlm_ControlInternal( p_vlm, VLM_CLEAR_MEDIAS ); |
|---|
| 391 | | } |
|---|
| 392 | | else if( !strcmp(psz_name, "schedule") ) |
|---|
| 393 | | { |
|---|
| 394 | | vlm_ControlInternal( p_vlm, VLM_CLEAR_SCHEDULES ); |
|---|
| 395 | | } |
|---|
| 396 | | else if( !strcmp(psz_name, "all") ) |
|---|
| 397 | | { |
|---|
| 398 | | vlm_ControlInternal( p_vlm, VLM_CLEAR_MEDIAS ); |
|---|
| 399 | | vlm_ControlInternal( p_vlm, VLM_CLEAR_SCHEDULES ); |
|---|
| 400 | | } |
|---|
| 401 | | else |
|---|
| 402 | | { |
|---|
| 403 | | *pp_status = vlm_MessageNew( "del", "%s: media unknown", psz_name ); |
|---|
| 404 | | return VLC_EGENERIC; |
|---|
| 405 | | } |
|---|
| 406 | | |
|---|
| 407 | | *pp_status = vlm_MessageNew( "del", vlm_NULL ); |
|---|
| 408 | | return VLC_SUCCESS; |
|---|
| 409 | | } |
|---|
| 410 | | |
|---|
| 411 | | static int ExecuteShow( vlm_t *p_vlm, const char *psz_name, vlm_message_t **pp_status ) |
|---|
| 412 | | { |
|---|
| 413 | | vlm_media_sys_t *p_media; |
|---|
| 414 | | vlm_schedule_sys_t *p_schedule; |
|---|
| 415 | | |
|---|
| 416 | | if( !psz_name ) |
|---|
| 417 | | { |
|---|
| 418 | | *pp_status = vlm_Show( p_vlm, NULL, NULL, NULL ); |
|---|
| 419 | | return VLC_SUCCESS; |
|---|
| 420 | | } |
|---|
| 421 | | |
|---|
| 422 | | p_media = vlm_MediaSearch( p_vlm, psz_name ); |
|---|
| 423 | | p_schedule = vlm_ScheduleSearch( p_vlm, psz_name ); |
|---|
| 424 | | |
|---|
| 425 | | if( p_schedule != NULL ) |
|---|
| 426 | | *pp_status = vlm_Show( p_vlm, NULL, p_schedule, NULL ); |
|---|
| 427 | | else if( p_media != NULL ) |
|---|
| 428 | | *pp_status = vlm_Show( p_vlm, p_media, NULL, NULL ); |
|---|
| 429 | | else |
|---|
| 430 | | *pp_status = vlm_Show( p_vlm, NULL, NULL, psz_name ); |
|---|
| 431 | | |
|---|
| 432 | | return VLC_SUCCESS; |
|---|
| 433 | | } |
|---|
| 434 | | |
|---|
| 435 | | static int ExecuteHelp( vlm_message_t **pp_status ) |
|---|
| 436 | | { |
|---|
| 437 | | vlm_message_t *message_child; |
|---|
| 438 | | |
|---|
| 439 | | #define MessageAdd( a ) \ |
|---|
| 440 | | vlm_MessageAdd( *pp_status, vlm_MessageNew( a, vlm_NULL ) ); |
|---|
| 441 | | #define MessageAddChild( a ) \ |
|---|
| 442 | | vlm_MessageAdd( message_child, vlm_MessageNew( a, vlm_NULL ) ); |
|---|
| 443 | | |
|---|
| 444 | | *pp_status = vlm_MessageNew( "help", vlm_NULL ); |
|---|
| 445 | | |
|---|
| 446 | | message_child = MessageAdd( "Commands Syntax:" ); |
|---|
| 447 | | MessageAddChild( "new (name) vod|broadcast|schedule [properties]" ); |
|---|
| 448 | | MessageAddChild( "setup (name) (properties)" ); |
|---|
| 449 | | MessageAddChild( "show [(name)|media|schedule]" ); |
|---|
| 450 | | MessageAddChild( "del (name)|all|media|schedule" ); |
|---|
| 451 | | MessageAddChild( "control (name) [instance_name] (command)" ); |
|---|
| 452 | | MessageAddChild( "save (config_file)" ); |
|---|
| 453 | | MessageAddChild( "export" ); |
|---|
| 454 | | MessageAddChild( "load (config_file)" ); |
|---|
| 455 | | |
|---|
| 456 | | message_child = MessageAdd( "Media Proprieties Syntax:" ); |
|---|
| 457 | | MessageAddChild( "input (input_name)" ); |
|---|
| 458 | | MessageAddChild( "inputdel (input_name)|all" ); |
|---|
| 459 | | MessageAddChild( "inputdeln input_number" ); |
|---|
| 460 | | MessageAddChild( "output (output_name)" ); |
|---|
| 461 | | MessageAddChild( "option (option_name)[=value]" ); |
|---|
| 462 | | MessageAddChild( "enabled|disabled" ); |
|---|
| 463 | | MessageAddChild( "loop|unloop (broadcast only)" ); |
|---|
| 464 | | MessageAddChild( "mux (mux_name)" ); |
|---|
| 465 | | |
|---|
| 466 | | message_child = MessageAdd( "Schedule Proprieties Syntax:" ); |
|---|
| 467 | | MessageAddChild( "enabled|disabled" ); |
|---|
| 468 | | MessageAddChild( "append (command_until_rest_of_the_line)" ); |
|---|
| 469 | | MessageAddChild( "date (year)/(month)/(day)-(hour):(minutes):" |
|---|
| 470 | | "(seconds)|now" ); |
|---|
| 471 | | MessageAddChild( "period (years_aka_12_months)/(months_aka_30_days)/" |
|---|
| 472 | | "(days)-(hours):(minutes):(seconds)" ); |
|---|
| 473 | | MessageAddChild( "repeat (number_of_repetitions)" ); |
|---|
| 474 | | |
|---|
| 475 | | message_child = MessageAdd( "Control Commands Syntax:" ); |
|---|
| 476 | | MessageAddChild( "play [input_number]" ); |
|---|
| 477 | | MessageAddChild( "pause" ); |
|---|
| 478 | | MessageAddChild( "stop" ); |
|---|
| 479 | | MessageAddChild( "seek [+-](percentage) | [+-](seconds)s | [+-](miliseconds)ms" ); |
|---|
| 480 | | |
|---|
| 481 | | return VLC_SUCCESS; |
|---|
| 482 | | } |
|---|
| 483 | | |
|---|
| 484 | | static int ExecuteControl( vlm_t *p_vlm, const char *psz_name, const int i_arg, char ** ppsz_arg, vlm_message_t **pp_status ) |
|---|
| 485 | | { |
|---|
| 486 | | vlm_media_sys_t *p_media; |
|---|
| 487 | | const char *psz_control = NULL; |
|---|
| 488 | | const char *psz_instance = NULL; |
|---|
| 489 | | const char *psz_argument = NULL; |
|---|
| 490 | | int i_index; |
|---|
| 491 | | int i_result; |
|---|
| 492 | | |
|---|
| 493 | | if( !ExecuteIsMedia( p_vlm, psz_name ) ) |
|---|
| 494 | | { |
|---|
| 495 | | *pp_status = vlm_MessageNew( "control", "%s: media unknown", psz_name ); |
|---|
| 496 | | return VLC_EGENERIC; |
|---|
| 497 | | } |
|---|
| 498 | | |
|---|
| 499 | | assert( i_arg > 0 ); |
|---|
| 500 | | |
|---|
| 501 | | #define IS(txt) ( !strcmp( ppsz_arg[i_index], (txt) ) ) |
|---|
| 502 | | i_index = 0; |
|---|
| 503 | | if( !IS("play") && !IS("stop") && !IS("pause") && !IS("seek") ) |
|---|
| 504 | | { |
|---|
| 505 | | i_index = 1; |
|---|
| 506 | | psz_instance = ppsz_arg[0]; |
|---|
| 507 | | |
|---|
| 508 | | if( i_index >= i_arg || ( !IS("play") && !IS("stop") && !IS("pause") && !IS("seek") ) ) |
|---|
| 509 | | return ExecuteSyntaxError( "control", pp_status ); |
|---|
| 510 | | } |
|---|
| 511 | | #undef IS |
|---|
| 512 | | psz_control = ppsz_arg[i_index]; |
|---|
| 513 | | |
|---|
| 514 | | if( i_index+1 < i_arg ) |
|---|
| 515 | | psz_argument = ppsz_arg[i_index+1]; |
|---|
| 516 | | |
|---|
| 517 | | p_media = vlm_MediaSearch( p_vlm, psz_name ); |
|---|
| 518 | | assert( p_media ); |
|---|
| 519 | | |
|---|
| 520 | | if( !strcmp( psz_control, "play" ) ) |
|---|
| 521 | | { |
|---|
| 522 | | int i_input_index = 0; |
|---|
| 523 | | int i; |
|---|
| 524 | | |
|---|
| 525 | | if( ( psz_argument && sscanf(psz_argument, "%d", &i) == 1 ) && i > 0 && i-1 < p_media->cfg.i_input ) |
|---|
| 526 | | { |
|---|
| 527 | | i_input_index = i-1; |
|---|
| 528 | | } |
|---|
| 529 | | else if( psz_argument ) |
|---|
| 530 | | { |
|---|
| 531 | | int j; |
|---|
| 532 | | vlm_media_t *p_cfg = &p_media->cfg; |
|---|
| 533 | | for ( j=0; j < p_cfg->i_input; j++) |
|---|
| 534 | | { |
|---|
| 535 | | if( !strcmp( p_cfg->ppsz_input[j], psz_argument ) ) |
|---|
| 536 | | { |
|---|
| 537 | | i_input_index = j; |
|---|
| 538 | | break; |
|---|
| 539 | | } |
|---|
| 540 | | } |
|---|
| 541 | | } |
|---|
| 542 | | |
|---|
| 543 | | if( p_media->cfg.b_vod ) |
|---|
| 544 | | i_result = vlm_ControlInternal( p_vlm, VLM_START_MEDIA_VOD_INSTANCE, p_media->cfg.id, psz_instance, i_input_index, NULL ); // we should get here now |
|---|
| 545 | | else |
|---|
| 546 | | i_result = vlm_ControlInternal( p_vlm, VLM_START_MEDIA_BROADCAST_INSTANCE, p_media->cfg.id, psz_instance, i_input_index ); |
|---|
| 547 | | } |
|---|
| 548 | | else if( !strcmp( psz_control, "seek" ) ) |
|---|
| 549 | | { |
|---|
| 550 | | if( psz_argument ) |
|---|
| 551 | | { |
|---|
| 552 | | bool b_relative; |
|---|
| 553 | | if( psz_argument[0] == '+' || psz_argument[0] == '-' ) |
|---|
| 554 | | b_relative = true; |
|---|
| 555 | | else |
|---|
| 556 | | b_relative = false; |
|---|
| 557 | | |
|---|
| 558 | | if( strstr( psz_argument, "ms" ) || strstr( psz_argument, "s" ) ) |
|---|
| 559 | | { |
|---|
| 560 | | /* Time (ms or s) */ |
|---|
| 561 | | int64_t i_new_time; |
|---|
| 562 | | |
|---|
| 563 | | if( strstr( psz_argument, "ms" ) ) |
|---|
| 564 | | i_new_time = 1000 * (int64_t)atoi( psz_argument ); |
|---|
| 565 | | else |
|---|
| 566 | | i_new_time = 1000000 * (int64_t)atoi( psz_argument ); |
|---|
| 567 | | |
|---|
| 568 | | if( b_relative ) |
|---|
| 569 | | { |
|---|
| 570 | | int64_t i_time = 0; |
|---|
| 571 | | vlm_ControlInternal( p_vlm, VLM_GET_MEDIA_INSTANCE_TIME, p_media->cfg.id, psz_instance, &i_time ); |
|---|
| 572 | | i_new_time += i_time; |
|---|
| 573 | | } |
|---|
| 574 | | if( i_new_time < 0 ) |
|---|
| 575 | | i_new_time = 0; |
|---|
| 576 | | i_result = vlm_ControlInternal( p_vlm, VLM_SET_MEDIA_INSTANCE_TIME, p_media->cfg.id, psz_instance, i_new_time ); |
|---|
| 577 | | } |
|---|
| 578 | | else |
|---|
| 579 | | { |
|---|
| 580 | | /* Percent */ |
|---|
| 581 | | double d_new_position = i18n_atof( psz_argument ) / 100.0; |
|---|
| 582 | | |
|---|
| 583 | | if( b_relative ) |
|---|
| 584 | | { |
|---|
| 585 | | double d_position = 0.0; |
|---|
| 586 | | |
|---|
| 587 | | vlm_ControlInternal( p_vlm, VLM_GET_MEDIA_INSTANCE_POSITION, p_media->cfg.id, psz_instance, &d_position ); |
|---|
| 588 | | d_new_position += d_position; |
|---|
| 589 | | } |
|---|
| 590 | | if( d_new_position < 0.0 ) |
|---|
| 591 | | d_new_position = 0.0; |
|---|
| 592 | | else if( d_new_position > 1.0 ) |
|---|
| 593 | | d_new_position = 1.0; |
|---|
| 594 | | i_result = vlm_ControlInternal( p_vlm, VLM_SET_MEDIA_INSTANCE_POSITION, p_media->cfg.id, psz_instance, d_new_position ); |
|---|
| 595 | | } |
|---|
| 596 | | } |
|---|
| 597 | | else |
|---|
| 598 | | { |
|---|
| 599 | | i_result = VLC_EGENERIC; |
|---|
| 600 | | } |
|---|
| 601 | | } |
|---|
| 602 | | else if( !strcmp( psz_control, "rewind" ) ) |
|---|
| 603 | | { |
|---|
| 604 | | if( psz_argument ) |
|---|
| 605 | | { |
|---|
| 606 | | const double d_scale = i18n_atof( psz_argument ); |
|---|
| 607 | | double d_position; |
|---|
| 608 | | |
|---|
| 609 | | vlm_ControlInternal( p_vlm, VLM_GET_MEDIA_INSTANCE_POSITION, p_media->cfg.id, psz_instance, &d_position ); |
|---|
| 610 | | d_position -= (d_scale / 1000.0); |
|---|
| 611 | | if( d_position < 0.0 ) |
|---|
| 612 | | d_position = 0.0; |
|---|
| 613 | | i_result = vlm_ControlInternal( p_vlm, VLM_SET_MEDIA_INSTANCE_POSITION, p_media->cfg.id, psz_instance, d_position ); |
|---|
| 614 | | } |
|---|
| 615 | | else |
|---|
| 616 | | { |
|---|
| 617 | | i_result = VLC_EGENERIC; |
|---|
| 618 | | } |
|---|
| 619 | | } |
|---|
| 620 | | else if( !strcmp( psz_control, "forward" ) ) |
|---|
| 621 | | { |
|---|
| 622 | | if( psz_argument ) |
|---|
| 623 | | { |
|---|
| 624 | | const double d_scale = i18n_atof( psz_argument ); |
|---|
| 625 | | double d_position; |
|---|
| 626 | | |
|---|
| 627 | | vlm_ControlInternal( p_vlm, VLM_GET_MEDIA_INSTANCE_POSITION, p_media->cfg.id, psz_instance, &d_position ); |
|---|
| 628 | | d_position += (d_scale / 1000.0); |
|---|
| 629 | | if( d_position > 1.0 ) |
|---|
| 630 | | d_position = 1.0; |
|---|
| 631 | | i_result = vlm_ControlInternal( p_vlm, VLM_SET_MEDIA_INSTANCE_POSITION, p_media->cfg.id, psz_instance, d_position ); |
|---|
| 632 | | |
|---|
| 633 | | } |
|---|
| 634 | | else |
|---|
| 635 | | { |
|---|
| 636 | | i_result = VLC_EGENERIC; |
|---|
| 637 | | } |
|---|
| 638 | | } |
|---|
| 639 | | else if( !strcmp( psz_control, "stop" ) ) |
|---|
| 640 | | { |
|---|
| 641 | | i_result = vlm_ControlInternal( p_vlm, VLM_STOP_MEDIA_INSTANCE, p_media->cfg.id, psz_instance ); |
|---|
| 642 | | } |
|---|
| 643 | | else if( !strcmp( psz_control, "pause" ) ) |
|---|
| 644 | | { |
|---|
| 645 | | i_result = vlm_ControlInternal( p_vlm, VLM_PAUSE_MEDIA_INSTANCE, p_media->cfg.id, psz_instance ); |
|---|
| 646 | | } |
|---|
| 647 | | else |
|---|
| 648 | | { |
|---|
| 649 | | i_result = VLC_EGENERIC; |
|---|
| 650 | | } |
|---|
| 651 | | |
|---|
| 652 | | if( i_result ) |
|---|
| 653 | | { |
|---|
| 654 | | *pp_status = vlm_MessageNew( "control", "unknown error" ); |
|---|
| 655 | | return VLC_SUCCESS; |
|---|
| 656 | | } |
|---|
| 657 | | *pp_status = vlm_MessageNew( "control", vlm_NULL ); |
|---|
| 658 | | return VLC_SUCCESS; |
|---|
| 659 | | } |
|---|
| 660 | | |
|---|
| 661 | | static int ExecuteExport( vlm_t *p_vlm, vlm_message_t **pp_status ) |
|---|
| 662 | | { |
|---|
| 663 | | char *psz_export = Save( p_vlm ); |
|---|
| 664 | | |
|---|
| 665 | | *pp_status = vlm_MessageNew( "export", psz_export ); |
|---|
| 666 | | free( psz_export ); |
|---|
| 667 | | return VLC_SUCCESS; |
|---|
| 668 | | } |
|---|
| 669 | | |
|---|
| 670 | | static int ExecuteSave( vlm_t *p_vlm, const char *psz_file, vlm_message_t **pp_status ) |
|---|
| 671 | | { |
|---|
| 672 | | FILE *f = utf8_fopen( psz_file, "wt" ); |
|---|
| 673 | | char *psz_save = NULL; |
|---|
| 674 | | |
|---|
| 675 | | if( !f ) |
|---|
| 676 | | goto error; |
|---|
| 677 | | |
|---|
| 678 | | psz_save = Save( p_vlm ); |
|---|
| 679 | | if( psz_save == NULL ) |
|---|
| 680 | | goto error; |
|---|
| 681 | | if( fputs( psz_save, f ) == EOF ) |
|---|
| 682 | | goto error;; |
|---|
| 683 | | if( fclose( f ) ) |
|---|
| 684 | | { |
|---|
| 685 | | f = NULL; |
|---|
| 686 | | goto error; |
|---|
| 687 | | } |
|---|
| 688 | | |
|---|
| 689 | | free( psz_save ); |
|---|
| 690 | | |
|---|
| 691 | | *pp_status = vlm_MessageNew( "save", vlm_NULL ); |
|---|
| 692 | | return VLC_SUCCESS; |
|---|
| 693 | | |
|---|
| 694 | | error: |
|---|
| 695 | | free( psz_save ); |
|---|
| 696 | | if( f ) |
|---|
| 697 | | fclose( f ); |
|---|
| 698 | | *pp_status = vlm_MessageNew( "save", "Unable to save to file"); |
|---|
| 699 | | return VLC_EGENERIC; |
|---|
| 700 | | } |
|---|
| 701 | | |
|---|
| 702 | | static int ExecuteLoad( vlm_t *p_vlm, const char *psz_url, vlm_message_t **pp_status ) |
|---|
| 703 | | { |
|---|
| 704 | | stream_t *p_stream = stream_UrlNew( p_vlm, psz_url ); |
|---|
| 705 | | int64_t i_size; |
|---|
| 706 | | char *psz_buffer; |
|---|
| 707 | | |
|---|
| 708 | | if( !p_stream ) |
|---|
| 709 | | { |
|---|
| 710 | | *pp_status = vlm_MessageNew( "load", "Unable to load from file" ); |
|---|
| 711 | | return VLC_EGENERIC; |
|---|
| 712 | | } |
|---|
| 713 | | |
|---|
| 714 | | /* FIXME needed ? */ |
|---|
| 715 | | if( stream_Seek( p_stream, 0 ) != 0 ) |
|---|
| 716 | | { |
|---|
| 717 | | stream_Delete( p_stream ); |
|---|
| 718 | | |
|---|
| 719 | | *pp_status = vlm_MessageNew( "load", "Read file error" ); |
|---|
| 720 | | return VLC_EGENERIC; |
|---|
| 721 | | } |
|---|
| 722 | | |
|---|
| 723 | | i_size = stream_Size( p_stream ); |
|---|
| 724 | | |
|---|
| 725 | | psz_buffer = malloc( i_size + 1 ); |
|---|
| 726 | | if( !psz_buffer ) |
|---|
| 727 | | { |
|---|
| 728 | | stream_Delete( p_stream ); |
|---|
| 729 | | |
|---|
| 730 | | *pp_status = vlm_MessageNew( "load", "Read file error" ); |
|---|
| 731 | | return VLC_EGENERIC; |
|---|
| 732 | | } |
|---|
| 733 | | |
|---|
| 734 | | stream_Read( p_stream, psz_buffer, i_size ); |
|---|
| 735 | | psz_buffer[i_size] = '\0'; |
|---|
| 736 | | |
|---|
| 737 | | stream_Delete( p_stream ); |
|---|
| 738 | | |
|---|
| 739 | | if( Load( p_vlm, psz_buffer ) ) |
|---|
| 740 | | { |
|---|
| 741 | | free( psz_buffer ); |
|---|
| 742 | | |
|---|
| 743 | | *pp_status = vlm_MessageNew( "load", "Error while loading file" ); |
|---|
| 744 | | return VLC_EGENERIC; |
|---|
| 745 | | } |
|---|
| 746 | | |
|---|
| 747 | | free( psz_buffer ); |
|---|
| 748 | | |
|---|
| 749 | | *pp_status = vlm_MessageNew( "load", vlm_NULL ); |
|---|
| 750 | | return VLC_SUCCESS; |
|---|
| 751 | | } |
|---|
| 752 | | |
|---|
| 753 | | static int ExecuteScheduleProperty( vlm_t *p_vlm, vlm_schedule_sys_t *p_schedule, bool b_new, |
|---|
| 754 | | const int i_property, char *ppsz_property[], vlm_message_t **pp_status ) |
|---|
| 755 | | { |
|---|
| 756 | | const char *psz_cmd = b_new ? "new" : "setup"; |
|---|
| 757 | | int i; |
|---|
| 758 | | |
|---|
| 759 | | for( i = 0; i < i_property; i++ ) |
|---|
| 760 | | { |
|---|
| 761 | | if( !strcmp( ppsz_property[i], "enabled" ) || |
|---|
| 762 | | !strcmp( ppsz_property[i], "disabled" ) ) |
|---|
| 763 | | { |
|---|
| 764 | | vlm_ScheduleSetup( p_schedule, ppsz_property[i], NULL ); |
|---|
| 765 | | } |
|---|
| 766 | | else if( !strcmp( ppsz_property[i], "append" ) ) |
|---|
| 767 | | { |
|---|
| 768 | | char *psz_line; |
|---|
| 769 | | int j; |
|---|
| 770 | | /* Beware: everything behind append is considered as |
|---|
| 771 | | * command line */ |
|---|
| 772 | | |
|---|
| 773 | | if( ++i >= i_property ) |
|---|
| 774 | | break; |
|---|
| 775 | | |
|---|
| 776 | | psz_line = strdup( ppsz_property[i] ); |
|---|
| 777 | | for( j = i+1; j < i_property; j++ ) |
|---|
| 778 | | { |
|---|
| 779 | | psz_line = realloc( psz_line, strlen(psz_line) + strlen(ppsz_property[j]) + 1 + 1 ); |
|---|
| 780 | | strcat( psz_line, " " ); |
|---|
| 781 | | strcat( psz_line, ppsz_property[j] ); |
|---|
| 782 | | } |
|---|
| 783 | | |
|---|
| 784 | | vlm_ScheduleSetup( p_schedule, "append", psz_line ); |
|---|
| 785 | | break; |
|---|
| 786 | | } |
|---|
| 787 | | else |
|---|
| 788 | | { |
|---|
| 789 | | if( i + 1 >= i_property ) |
|---|
| 790 | | { |
|---|
| 791 | | if( b_new ) |
|---|
| 792 | | vlm_ScheduleDelete( p_vlm, p_schedule ); |
|---|
| 793 | | return ExecuteSyntaxError( psz_cmd, pp_status ); |
|---|
| 794 | | } |
|---|
| 795 | | |
|---|
| 796 | | vlm_ScheduleSetup( p_schedule, ppsz_property[i], ppsz_property[i+1] ); |
|---|
| 797 | | i++; |
|---|
| 798 | | } |
|---|
| 799 | | } |
|---|
| 800 | | *pp_status = vlm_MessageNew( psz_cmd, vlm_NULL ); |
|---|
| 801 | | return VLC_SUCCESS; |
|---|
| 802 | | } |
|---|
| 803 | | |
|---|
| 804 | | static int ExecuteMediaProperty( vlm_t *p_vlm, int64_t id, bool b_new, |
|---|
| 805 | | const int i_property, char *ppsz_property[], vlm_message_t **pp_status ) |
|---|
| 806 | | { |
|---|
| 807 | | const char *psz_cmd = b_new ? "new" : "setup"; |
|---|
| 808 | | vlm_media_t *p_cfg = NULL; |
|---|
| 809 | | int i_result; |
|---|
| 810 | | int i; |
|---|
| 811 | | |
|---|
| 812 | | #undef ERROR |
|---|
| 813 | | #undef MISSING |
|---|
| 814 | | #define ERROR( txt ) do { *pp_status = vlm_MessageNew( psz_cmd, txt); goto error; } while(0) |
|---|
| 815 | | if( vlm_ControlInternal( p_vlm, VLM_GET_MEDIA, id, &p_cfg ) ) |
|---|
| 816 | | ERROR( "unknown media" ); |
|---|
| 817 | | |
|---|
| 818 | | #define MISSING(cmd) do { if( !psz_value ) ERROR( "missing argument for " cmd ); } while(0) |
|---|
| 819 | | for( i = 0; i < i_property; i++ ) |
|---|
| 820 | | { |
|---|
| 821 | | const char *psz_option = ppsz_property[i]; |
|---|
| 822 | | const char *psz_value = i+1 < i_property ? ppsz_property[i+1] : NULL; |
|---|
| 823 | | |
|---|
| 824 | | if( !strcmp( psz_option, "enabled" ) ) |
|---|
| 825 | | { |
|---|
| 826 | | p_cfg->b_enabled = true; |
|---|
| 827 | | } |
|---|
| 828 | | else if( !strcmp( psz_option, "disabled" ) ) |
|---|
| 829 | | { |
|---|
| 830 | | p_cfg->b_enabled = false; |
|---|
| 831 | | } |
|---|
| 832 | | else if( !strcmp( psz_option, "input" ) ) |
|---|
| 833 | | { |
|---|
| 834 | | MISSING( "input" ); |
|---|
| 835 | | TAB_APPEND( p_cfg->i_input, p_cfg->ppsz_input, strdup(psz_value) ); |
|---|
| 836 | | i++; |
|---|
| 837 | | } |
|---|
| 838 | | else if( !strcmp( psz_option, "inputdel" ) && psz_value && !strcmp( psz_value, "all" ) ) |
|---|
| 839 | | { |
|---|
| 840 | | while( p_cfg->i_input > 0 ) |
|---|
| 841 | | TAB_REMOVE( p_cfg->i_input, p_cfg->ppsz_input, p_cfg->ppsz_input[0] ); |
|---|
| 842 | | i++; |
|---|
| 843 | | } |
|---|
| 844 | | else if( !strcmp( psz_option, "inputdel" ) ) |
|---|
| 845 | | { |
|---|
| 846 | | int j; |
|---|
| 847 | | |
|---|
| 848 | | MISSING( "inputdel" ); |
|---|
| 849 | | |
|---|
| 850 | | for( j = 0; j < p_cfg->i_input; j++ ) |
|---|
| 851 | | { |
|---|
| 852 | | if( !strcmp( p_cfg->ppsz_input[j], psz_value ) ) |
|---|
| 853 | | { |
|---|
| 854 | | TAB_REMOVE( p_cfg->i_input, p_cfg->ppsz_input, p_cfg->ppsz_input[j] ); |
|---|
| 855 | | break; |
|---|
| 856 | | } |
|---|
| 857 | | } |
|---|
| 858 | | i++; |
|---|
| 859 | | } |
|---|
| 860 | | else if( !strcmp( psz_option, "inputdeln" ) ) |
|---|
| 861 | | { |
|---|
| 862 | | int i_index; |
|---|
| 863 | | |
|---|
| 864 | | MISSING( "inputdeln" ); |
|---|
| 865 | | |
|---|
| 866 | | i_index = atoi( psz_value ); |
|---|
| 867 | | if( i_index > 0 && i_index <= p_cfg->i_input ) |
|---|
| 868 | | TAB_REMOVE( p_cfg->i_input, p_cfg->ppsz_input, p_cfg->ppsz_input[i_index-1] ); |
|---|
| 869 | | i++; |
|---|
| 870 | | } |
|---|
| 871 | | else if( !strcmp( psz_option, "output" ) ) |
|---|
| 872 | | { |
|---|
| 873 | | MISSING( "output" ); |
|---|
| 874 | | |
|---|
| 875 | | free( p_cfg->psz_output ); |
|---|
| 876 | | p_cfg->psz_output = *psz_value ? strdup( psz_value ) : NULL; |
|---|
| 877 | | i++; |
|---|
| 878 | | } |
|---|
| 879 | | else if( !strcmp( psz_option, "option" ) ) |
|---|
| 880 | | { |
|---|
| 881 | | MISSING( "option" ); |
|---|
| 882 | | |
|---|
| 883 | | TAB_APPEND( p_cfg->i_option, p_cfg->ppsz_option, strdup( psz_value ) ); |
|---|
| 884 | | i++; |
|---|
| 885 | | } |
|---|
| 886 | | else if( !strcmp( psz_option, "loop" ) ) |
|---|
| 887 | | { |
|---|
| 888 | | if( p_cfg->b_vod ) |
|---|
| 889 | | ERROR( "invalid loop option for vod" ); |
|---|
| 890 | | p_cfg->broadcast.b_loop = true; |
|---|
| 891 | | } |
|---|
| 892 | | else if( !strcmp( psz_option, "unloop" ) ) |
|---|
| 893 | | { |
|---|
| 894 | | if( p_cfg->b_vod ) |
|---|
| 895 | | ERROR( "invalid unloop option for vod" ); |
|---|
| 896 | | p_cfg->broadcast.b_loop = false; |
|---|
| 897 | | } |
|---|
| 898 | | else if( !strcmp( psz_option, "mux" ) ) |
|---|
| 899 | | { |
|---|
| 900 | | MISSING( "mux" ); |
|---|
| 901 | | if( !p_cfg->b_vod ) |
|---|
| 902 | | ERROR( "invalid mux option for broadcast" ); |
|---|
| 903 | | |
|---|
| 904 | | free( p_cfg->vod.psz_mux ); |
|---|
| 905 | | p_cfg->vod.psz_mux = *psz_value ? strdup( psz_value ) : NULL; |
|---|
| 906 | | i++; |
|---|
| 907 | | } |
|---|
| 908 | | else |
|---|
| 909 | | { |
|---|
| 910 | | fprintf( stderr, "PROP: name=%s unknown\n", psz_option ); |
|---|
| 911 | | ERROR( "Wrong command syntax" ); |
|---|
| 912 | | } |
|---|
| 913 | | } |
|---|
| 914 | | #undef MISSING |
|---|
| 915 | | #undef ERROR |
|---|
| 916 | | |
|---|
| 917 | | /* */ |
|---|
| 918 | | i_result = vlm_ControlInternal( p_vlm, VLM_CHANGE_MEDIA, p_cfg ); |
|---|
| 919 | | vlm_media_Delete( p_cfg ); |
|---|
| 920 | | |
|---|
| 921 | | *pp_status = vlm_MessageNew( psz_cmd, vlm_NULL ); |
|---|
| 922 | | return i_result; |
|---|
| 923 | | |
|---|
| 924 | | error: |
|---|
| 925 | | if( p_cfg ) |
|---|
| 926 | | { |
|---|
| 927 | | if( b_new ) |
|---|
| 928 | | vlm_ControlInternal( p_vlm, VLM_DEL_MEDIA, p_cfg->id ); |
|---|
| 929 | | vlm_media_Delete( p_cfg ); |
|---|
| 930 | | } |
|---|
| 931 | | return VLC_EGENERIC; |
|---|
| 932 | | } |
|---|
| 933 | | |
|---|
| 934 | | static int ExecuteNew( vlm_t *p_vlm, const char *psz_name, const char *psz_type, const int i_property, char *ppsz_property[], vlm_message_t **pp_status ) |
|---|
| 935 | | { |
|---|
| 936 | | /* Check name */ |
|---|
| 937 | | if( !strcmp( psz_name, "all" ) || !strcmp( psz_name, "media" ) || !strcmp( psz_name, "schedule" ) ) |
|---|
| 938 | | { |
|---|
| 939 | | *pp_status = vlm_MessageNew( "new", "\"all\", \"media\" and \"schedule\" are reserved names" ); |
|---|
| 940 | | return VLC_EGENERIC; |
|---|
| 941 | | } |
|---|
| 942 | | if( ExecuteIsMedia( p_vlm, psz_name ) || ExecuteIsSchedule( p_vlm, psz_name ) ) |
|---|
| 943 | | { |
|---|
| 944 | | *pp_status = vlm_MessageNew( "new", "%s: Name already in use", psz_name ); |
|---|
| 945 | | return VLC_EGENERIC; |
|---|
| 946 | | } |
|---|
| 947 | | /* */ |
|---|
| 948 | | if( !strcmp( psz_type, "schedule" ) ) |
|---|
| 949 | | { |
|---|
| 950 | | vlm_schedule_sys_t *p_schedule = vlm_ScheduleNew( p_vlm, psz_name ); |
|---|
| 951 | | if( !p_schedule ) |
|---|
| 952 | | { |
|---|
| 953 | | *pp_status = vlm_MessageNew( "new", "could not create schedule" ); |
|---|
| 954 | | return VLC_EGENERIC; |
|---|
| 955 | | } |
|---|
| 956 | | return ExecuteScheduleProperty( p_vlm, p_schedule, true, i_property, ppsz_property, pp_status ); |
|---|
| 957 | | } |
|---|
| 958 | | else if( !strcmp( psz_type, "vod" ) || !strcmp( psz_type, "broadcast" ) ) |
|---|
| 959 | | { |
|---|
| 960 | | vlm_media_t cfg; |
|---|
| 961 | | int64_t id; |
|---|
| 962 | | |
|---|
| 963 | | vlm_media_Init( &cfg ); |
|---|
| 964 | | cfg.psz_name = strdup( psz_name ); |
|---|
| 965 | | cfg.b_vod = !strcmp( psz_type, "vod" ); |
|---|
| 966 | | |
|---|
| 967 | | if( vlm_ControlInternal( p_vlm, VLM_ADD_MEDIA, &cfg, &id ) ) |
|---|
| 968 | | { |
|---|
| 969 | | vlm_media_Clean( &cfg ); |
|---|
| 970 | | *pp_status = vlm_MessageNew( "new", "could not create media" ); |
|---|
| 971 | | return VLC_EGENERIC; |
|---|
| 972 | | } |
|---|
| 973 | | vlm_media_Clean( &cfg ); |
|---|
| 974 | | return ExecuteMediaProperty( p_vlm, id, true, i_property, ppsz_property, pp_status ); |
|---|
| 975 | | } |
|---|
| 976 | | else |
|---|
| 977 | | { |
|---|
| 978 | | *pp_status = vlm_MessageNew( "new", "%s: Choose between vod, broadcast or schedule", psz_type ); |
|---|
| 979 | | return VLC_EGENERIC; |
|---|
| 980 | | } |
|---|
| 981 | | } |
|---|
| 982 | | |
|---|
| 983 | | static int ExecuteSetup( vlm_t *p_vlm, const char *psz_name, const int i_property, char *ppsz_property[], vlm_message_t **pp_status ) |
|---|
| 984 | | { |
|---|
| 985 | | if( ExecuteIsSchedule( p_vlm, psz_name ) ) |
|---|
| 986 | | { |
|---|
| 987 | | vlm_schedule_sys_t *p_schedule = vlm_ScheduleSearch( p_vlm, psz_name ); |
|---|
| 988 | | return ExecuteScheduleProperty( p_vlm, p_schedule, false, i_property, ppsz_property, pp_status ); |
|---|
| 989 | | } |
|---|
| 990 | | else if( ExecuteIsMedia( p_vlm, psz_name ) ) |
|---|
| 991 | | { |
|---|
| 992 | | int64_t id; |
|---|
| 993 | | if( vlm_ControlInternal( p_vlm, VLM_GET_MEDIA_ID, psz_name, &id ) ) |
|---|
| 994 | | goto error; |
|---|
| 995 | | return ExecuteMediaProperty( p_vlm, id, false, i_property, ppsz_property, pp_status ); |
|---|
| 996 | | } |
|---|
| 997 | | |
|---|
| 998 | | error: |
|---|
| 999 | | *pp_status = vlm_MessageNew( "setup", "%s unknown", psz_name ); |
|---|
| 1000 | | return VLC_EGENERIC; |
|---|
| 1001 | | } |
|---|
| 1002 | | |
|---|
| 1003 | | static int ExecuteCommand( vlm_t *p_vlm, const char *psz_command, |
|---|
| 1004 | | vlm_message_t **pp_message ) |
|---|
| 1005 | | { |
|---|
| 1006 | | size_t i_command = 0; |
|---|
| 1007 | | char buf[strlen (psz_command) + 1], *psz_buf = buf; |
|---|
| 1008 | | char *ppsz_command[3+sizeof (buf) / 2]; |
|---|
| 1009 | | vlm_message_t *p_message = NULL; |
|---|
| 1010 | | |
|---|
| 1011 | | /* First, parse the line and cut it */ |
|---|
| 1012 | | while( *psz_command != '\0' ) |
|---|
| 1013 | | { |
|---|
| 1014 | | const char *psz_temp; |
|---|
| 1015 | | |
|---|
| 1016 | | if(isspace (*psz_command)) |
|---|
| 1017 | | { |
|---|
| 1018 | | psz_command++; |
|---|
| 1019 | | continue; |
|---|
| 1020 | | } |
|---|
| 1021 | | |
|---|
| 1022 | | /* support for comments */ |
|---|
| 1023 | | if( i_command == 0 && *psz_command == '#') |
|---|
| 1024 | | { |
|---|
| 1025 | | p_message = vlm_MessageNew( "", vlm_NULL ); |
|---|
| 1026 | | goto success; |
|---|
| 1027 | | } |
|---|
| 1028 | | |
|---|
| 1029 | | psz_temp = FindCommandEnd( psz_command ); |
|---|
| 1030 | | |
|---|
| 1031 | | if( psz_temp == NULL ) |
|---|
| 1032 | | { |
|---|
| 1033 | | p_message = vlm_MessageNew( "Incomplete command", psz_command ); |
|---|
| 1034 | | goto error; |
|---|
| 1035 | | } |
|---|
| 1036 | | |
|---|
| 1037 | | assert (i_command < (sizeof (ppsz_command) / sizeof (ppsz_command[0]))); |
|---|
| 1038 | | |
|---|
| 1039 | | ppsz_command[i_command] = psz_buf; |
|---|
| 1040 | | memcpy (psz_buf, psz_command, psz_temp - psz_command); |
|---|
| 1041 | | psz_buf[psz_temp - psz_command] = '\0'; |
|---|
| 1042 | | |
|---|
| 1043 | | Unescape (psz_buf, psz_buf); |
|---|
| 1044 | | |
|---|
| 1045 | | i_command++; |
|---|
| 1046 | | psz_buf += psz_temp - psz_command + 1; |
|---|
| 1047 | | psz_command = psz_temp; |
|---|
| 1048 | | |
|---|
| 1049 | | assert (buf + sizeof (buf) >= psz_buf); |
|---|
| 1050 | | } |
|---|
| 1051 | | |
|---|
| 1052 | | /* |
|---|
| 1053 | | * And then Interpret it |
|---|
| 1054 | | */ |
|---|
| 1055 | | |
|---|
| 1056 | | #define IF_EXECUTE( name, check, cmd ) if( !strcmp(ppsz_command[0], name ) ) { if( (check) ) goto syntax_error; if( (cmd) ) goto error; goto success; } |
|---|
| 1057 | | if( i_command == 0 ) |
|---|
| 1058 | | { |
|---|
| 1059 | | p_message = vlm_MessageNew( "", vlm_NULL ); |
|---|
| 1060 | | goto success; |
|---|
| 1061 | | } |
|---|
| 1062 | | else IF_EXECUTE( "del", (i_command != 2), ExecuteDel(p_vlm, ppsz_command[1], &p_message) ) |
|---|
| 1063 | | else IF_EXECUTE( "show", (i_command > 2), ExecuteShow(p_vlm, i_command > 1 ? ppsz_command[1] : NULL, &p_message) ) |
|---|
| 1064 | | else IF_EXECUTE( "help", (i_command != 1), ExecuteHelp( &p_message ) ) |
|---|
| 1065 | | else IF_EXECUTE( "control", (i_command < 3), ExecuteControl(p_vlm, ppsz_command[1], i_command - 2, &ppsz_command[2], &p_message) ) |
|---|
| 1066 | | else IF_EXECUTE( "save", (i_command != 2), ExecuteSave(p_vlm, ppsz_command[1], &p_message) ) |
|---|
| 1067 | | else IF_EXECUTE( "export", (i_command != 1), ExecuteExport(p_vlm, &p_message) ) |
|---|
| 1068 | | else IF_EXECUTE( "load", (i_command != 2), ExecuteLoad(p_vlm, ppsz_command[1], &p_message) ) |
|---|
| 1069 | | else IF_EXECUTE( "new", (i_command < 3), ExecuteNew(p_vlm, ppsz_command[1], ppsz_command[2], i_command-3, &ppsz_command[3], &p_message) ) |
|---|
| 1070 | | else IF_EXECUTE( "setup", (i_command < 2), ExecuteSetup(p_vlm, ppsz_command[1], i_command-2, &ppsz_command[2], &p_message) ) |
|---|
| 1071 | | else |
|---|
| 1072 | | { |
|---|
| 1073 | | p_message = vlm_MessageNew( ppsz_command[0], "Unknown command" ); |
|---|
| 1074 | | goto error; |
|---|
| 1075 | | } |
|---|
| 1076 | | #undef IF_EXECUTE |
|---|
| 1077 | | |
|---|
| 1078 | | success: |
|---|
| 1079 | | *pp_message = p_message; |
|---|
| 1080 | | return VLC_SUCCESS; |
|---|
| 1081 | | |
|---|
| 1082 | | syntax_error: |
|---|
| 1083 | | return ExecuteSyntaxError( ppsz_command[0], pp_message ); |
|---|
| 1084 | | |
|---|
| 1085 | | error: |
|---|
| 1086 | | *pp_message = p_message; |
|---|
| 1087 | | return VLC_EGENERIC; |
|---|
| 1088 | | } |
|---|
| 1089 | | |
|---|
| 1090 | | /***************************************************************************** |
|---|
| 1091 | | * Media handling |
|---|
| 1092 | | *****************************************************************************/ |
|---|
| 1093 | | vlm_media_sys_t *vlm_MediaSearch( vlm_t *vlm, const char *psz_name ) |
|---|
| 1094 | | { |
|---|
| 1095 | | int i; |
|---|
| 1096 | | |
|---|
| 1097 | | for( i = 0; i < vlm->i_media; i++ ) |
|---|
| 1098 | | { |
|---|
| 1099 | | if( strcmp( psz_name, vlm->media[i]->cfg.psz_name ) == 0 ) |
|---|
| 1100 | | return vlm->media[i]; |
|---|
| 1101 | | } |
|---|
| 1102 | | |
|---|
| 1103 | | return NULL; |
|---|
| 1104 | | } |
|---|
| 1105 | | |
|---|
| 1106 | | /***************************************************************************** |
|---|
| 1107 | | * Schedule handling |
|---|
| 1108 | | *****************************************************************************/ |
|---|
| 1109 | | static int64_t vlm_Date(void) |
|---|
| | 198 | int64_t vlm_Date(void) |
|---|