00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "http.h"
00027 #include "macros.h"
00028
00029 int E_(MacroParse)( macro_t *m, char *psz_src )
00030 {
00031 char *dup = strdup( (char *)psz_src );
00032 char *src = dup;
00033 char *p;
00034 int i_skip;
00035
00036 #define EXTRACT( name, l ) \
00037 src += l; \
00038 p = strchr( src, '"' ); \
00039 if( p ) \
00040 { \
00041 *p++ = '\0'; \
00042 } \
00043 m->name = strdup( src ); \
00044 if( !p ) \
00045 { \
00046 break; \
00047 } \
00048 src = p;
00049
00050
00051 m->id = NULL;
00052 m->param1 = NULL;
00053 m->param2 = NULL;
00054
00055
00056 src += 4;
00057
00058 while( *src )
00059 {
00060 while( *src == ' ')
00061 {
00062 src++;
00063 }
00064 if( !strncmp( src, "id=\"", 4 ) )
00065 {
00066 EXTRACT( id, 4 );
00067 }
00068 else if( !strncmp( src, "param1=\"", 8 ) )
00069 {
00070 EXTRACT( param1, 8 );
00071 }
00072 else if( !strncmp( src, "param2=\"", 8 ) )
00073 {
00074 EXTRACT( param2, 8 );
00075 }
00076 else
00077 {
00078 break;
00079 }
00080 }
00081 if( strstr( src, "/>" ) )
00082 {
00083 src = strstr( src, "/>" ) + 2;
00084 }
00085 else
00086 {
00087 src += strlen( src );
00088 }
00089
00090 if( m->id == NULL )
00091 {
00092 m->id = strdup( "" );
00093 }
00094 if( m->param1 == NULL )
00095 {
00096 m->param1 = strdup( "" );
00097 }
00098 if( m->param2 == NULL )
00099 {
00100 m->param2 = strdup( "" );
00101 }
00102 i_skip = src - dup;
00103
00104 free( dup );
00105 return i_skip;
00106 #undef EXTRACT
00107 }
00108
00109 void E_(MacroClean)( macro_t *m )
00110 {
00111 free( m->id );
00112 free( m->param1 );
00113 free( m->param2 );
00114 }
00115
00116 int E_(StrToMacroType)( char *name )
00117 {
00118 int i;
00119
00120 if( !name || *name == '\0')
00121 {
00122 return MVLC_UNKNOWN;
00123 }
00124 for( i = 0; StrToMacroTypeTab[i].psz_name != NULL; i++ )
00125 {
00126 if( !strcmp( name, StrToMacroTypeTab[i].psz_name ) )
00127 {
00128 return StrToMacroTypeTab[i].i_type;
00129 }
00130 }
00131 return MVLC_UNKNOWN;
00132 }
00133
00134 void E_(MacroDo)( httpd_file_sys_t *p_args,
00135 macro_t *m,
00136 char *p_request, int i_request,
00137 char **pp_data, int *pi_data,
00138 char **pp_dst )
00139 {
00140 intf_thread_t *p_intf = p_args->p_intf;
00141 intf_sys_t *p_sys = p_args->p_intf->p_sys;
00142 char control[512];
00143
00144 #define ALLOC( l ) \
00145 { \
00146 int __i__ = *pp_dst - *pp_data; \
00147 *pi_data += (l); \
00148 *pp_data = realloc( *pp_data, *pi_data ); \
00149 *pp_dst = (*pp_data) + __i__; \
00150 }
00151 #define PRINT( str ) \
00152 ALLOC( strlen( str ) + 1 ); \
00153 *pp_dst += sprintf( *pp_dst, str );
00154
00155 #define PRINTS( str, s ) \
00156 ALLOC( strlen( str ) + strlen( s ) + 1 ); \
00157 { \
00158 char * psz_cur = *pp_dst; \
00159 *pp_dst += sprintf( *pp_dst, str, s ); \
00160 while( psz_cur && *psz_cur ) \
00161 { \
00162 \
00163 if( *psz_cur == '<' ) *psz_cur = '*'; \
00164 if( *psz_cur == '>' ) *psz_cur = '*'; \
00165 psz_cur++ ; \
00166 } \
00167 }
00168
00169 switch( E_(StrToMacroType)( m->id ) )
00170 {
00171 case MVLC_CONTROL:
00172 if( i_request <= 0 )
00173 {
00174 break;
00175 }
00176 E_(ExtractURIValue)( p_request, "control", control, 512 );
00177 if( *m->param1 && !strstr( m->param1, control ) )
00178 {
00179 msg_Warn( p_intf, "unauthorized control=%s", control );
00180 break;
00181 }
00182 switch( E_(StrToMacroType)( control ) )
00183 {
00184 case MVLC_PLAY:
00185 {
00186 int i_item;
00187 char item[512];
00188
00189 E_(ExtractURIValue)( p_request, "item", item, 512 );
00190 i_item = atoi( item );
00191
00192 if( i_item == 0 )
00193 {
00194 playlist_Play( p_sys->p_playlist );
00195 msg_Dbg( p_intf, "requested playlist play" );
00196 break;
00197 }
00198 playlist_Control( p_sys->p_playlist, PLAYLIST_ITEMPLAY,
00199 playlist_ItemGetById( p_sys->p_playlist,
00200 i_item ) );
00201 msg_Dbg( p_intf, "requested playlist item: %i", i_item );
00202 break;
00203 }
00204 case MVLC_STOP:
00205 playlist_Control( p_sys->p_playlist, PLAYLIST_STOP );
00206 msg_Dbg( p_intf, "requested playlist stop" );
00207 break;
00208 case MVLC_PAUSE:
00209 playlist_Control( p_sys->p_playlist, PLAYLIST_PAUSE );
00210 msg_Dbg( p_intf, "requested playlist pause" );
00211 break;
00212 case MVLC_NEXT:
00213 playlist_Control( p_sys->p_playlist, PLAYLIST_SKIP, 1 );
00214 msg_Dbg( p_intf, "requested playlist next" );
00215 break;
00216 case MVLC_PREVIOUS:
00217 playlist_Control( p_sys->p_playlist, PLAYLIST_SKIP, -1 );
00218 msg_Dbg( p_intf, "requested playlist previous" );
00219 break;
00220 case MVLC_FULLSCREEN:
00221 if( p_sys->p_input )
00222 {
00223 vout_thread_t *p_vout;
00224 p_vout = vlc_object_find( p_sys->p_input,
00225 VLC_OBJECT_VOUT, FIND_CHILD );
00226
00227 if( p_vout )
00228 {
00229 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
00230 vlc_object_release( p_vout );
00231 msg_Dbg( p_intf, "requested fullscreen toggle" );
00232 }
00233 }
00234 break;
00235 case MVLC_SEEK:
00236 {
00237 char value[30];
00238 E_(ExtractURIValue)( p_request, "seek_value", value, 30 );
00239 E_(DecodeEncodedURI)( value );
00240 E_(HandleSeek)( p_intf, value );
00241 break;
00242 }
00243 case MVLC_VOLUME:
00244 {
00245 char vol[8];
00246 audio_volume_t i_volume;
00247 int i_value;
00248
00249 E_(ExtractURIValue)( p_request, "value", vol, 8 );
00250 aout_VolumeGet( p_intf, &i_volume );
00251 E_(DecodeEncodedURI)( vol );
00252
00253 if( vol[0] == '+' )
00254 {
00255 i_value = atoi( vol + 1 );
00256 if( (i_volume + i_value) > AOUT_VOLUME_MAX )
00257 {
00258 aout_VolumeSet( p_intf , AOUT_VOLUME_MAX );
00259 msg_Dbg( p_intf, "requested volume set: max" );
00260 }
00261 else
00262 {
00263 aout_VolumeSet( p_intf , (i_volume + i_value) );
00264 msg_Dbg( p_intf, "requested volume set: +%i", (i_volume + i_value) );
00265 }
00266 }
00267 else if( vol[0] == '-' )
00268 {
00269 i_value = atoi( vol + 1 );
00270 if( (i_volume - i_value) < AOUT_VOLUME_MIN )
00271 {
00272 aout_VolumeSet( p_intf , AOUT_VOLUME_MIN );
00273 msg_Dbg( p_intf, "requested volume set: min" );
00274 }
00275 else
00276 {
00277 aout_VolumeSet( p_intf , (i_volume - i_value) );
00278 msg_Dbg( p_intf, "requested volume set: -%i", (i_volume - i_value) );
00279 }
00280 }
00281 else if( strstr(vol, "%") != NULL )
00282 {
00283 i_value = atoi( vol );
00284 if( (i_value <= 400) && (i_value>=0) ){
00285 aout_VolumeSet( p_intf, (i_value * (AOUT_VOLUME_MAX - AOUT_VOLUME_MIN))/400+AOUT_VOLUME_MIN);
00286 msg_Dbg( p_intf, "requested volume set: %i%%", atoi( vol ));
00287 }
00288 }
00289 else
00290 {
00291 i_value = atoi( vol );
00292 if( ( i_value <= AOUT_VOLUME_MAX ) && ( i_value >= AOUT_VOLUME_MIN ) )
00293 {
00294 aout_VolumeSet( p_intf , atoi( vol ) );
00295 msg_Dbg( p_intf, "requested volume set: %i", atoi( vol ) );
00296 }
00297 }
00298 break;
00299 }
00300
00301
00302 case MVLC_ADD:
00303 {
00304 char mrl[1024], psz_name[1024];
00305 playlist_item_t *p_item;
00306
00307 E_(ExtractURIValue)( p_request, "mrl", mrl, 1024 );
00308 E_(DecodeEncodedURI)( mrl );
00309 E_(ExtractURIValue)( p_request, "name", psz_name, 1024 );
00310 E_(DecodeEncodedURI)( psz_name );
00311 if( !*psz_name )
00312 {
00313 memcpy( psz_name, mrl, 1024 );
00314 }
00315 p_item = E_(MRLParse)( p_intf, mrl, psz_name );
00316
00317 if( !p_item || !p_item->input.psz_uri ||
00318 !*p_item->input.psz_uri )
00319 {
00320 msg_Dbg( p_intf, "invalid requested mrl: %s", mrl );
00321 }
00322 else
00323 {
00324 playlist_AddItem( p_sys->p_playlist, p_item,
00325 PLAYLIST_APPEND, PLAYLIST_END );
00326 msg_Dbg( p_intf, "requested mrl add: %s", mrl );
00327 }
00328
00329 break;
00330 }
00331 case MVLC_DEL:
00332 {
00333 int i_item, *p_items = NULL, i_nb_items = 0;
00334 char item[512], *p_parser = p_request;
00335
00336
00337 while( (p_parser =
00338 E_(ExtractURIValue)( p_parser, "item", item, 512 )) )
00339 {
00340 if( !*item ) continue;
00341
00342 i_item = atoi( item );
00343 p_items = realloc( p_items, (i_nb_items + 1) *
00344 sizeof(int) );
00345 p_items[i_nb_items] = i_item;
00346 i_nb_items++;
00347 }
00348
00349 if( i_nb_items )
00350 {
00351 int i;
00352 for( i = 0; i < i_nb_items; i++ )
00353 {
00354 playlist_LockDelete( p_sys->p_playlist, p_items[i] );
00355 msg_Dbg( p_intf, "requested playlist delete: %d",
00356 p_items[i] );
00357 p_items[i] = -1;
00358 }
00359 }
00360
00361 if( p_items ) free( p_items );
00362 break;
00363 }
00364 case MVLC_KEEP:
00365 {
00366 int i_item, *p_items = NULL, i_nb_items = 0;
00367 char item[512], *p_parser = p_request;
00368 int i,j;
00369
00370
00371 while( (p_parser =
00372 E_(ExtractURIValue)( p_parser, "item", item, 512 )) )
00373 {
00374 if( !*item ) continue;
00375
00376 i_item = atoi( item );
00377 p_items = realloc( p_items, (i_nb_items + 1) *
00378 sizeof(int) );
00379 p_items[i_nb_items] = i_item;
00380 i_nb_items++;
00381 }
00382
00383 for( i = p_sys->p_playlist->i_size - 1 ; i >= 0; i-- )
00384 {
00385
00386 for( j = 0 ; j < i_nb_items ; j++ )
00387 {
00388 if( p_items[j] ==
00389 p_sys->p_playlist->pp_items[i]->input.i_id ) break;
00390 }
00391 if( j == i_nb_items )
00392 {
00393 playlist_LockDelete( p_sys->p_playlist, p_sys->p_playlist->pp_items[i]->input.i_id );
00394 msg_Dbg( p_intf, "requested playlist delete: %d",
00395 i );
00396 }
00397 }
00398
00399 if( p_items ) free( p_items );
00400 break;
00401 }
00402 case MVLC_EMPTY:
00403 {
00404 playlist_LockClear( p_sys->p_playlist );
00405 msg_Dbg( p_intf, "requested playlist empty" );
00406 break;
00407 }
00408 case MVLC_SORT:
00409 {
00410 char type[12];
00411 char order[2];
00412 char item[512];
00413 int i_order;
00414 int i_item;
00415
00416 E_(ExtractURIValue)( p_request, "type", type, 12 );
00417 E_(ExtractURIValue)( p_request, "order", order, 2 );
00418 E_(ExtractURIValue)( p_request, "item", item, 512 );
00419 i_item = atoi( item );
00420
00421 if( order[0] == '0' ) i_order = ORDER_NORMAL;
00422 else i_order = ORDER_REVERSE;
00423
00424 if( !strcmp( type , "title" ) )
00425 {
00426 playlist_RecursiveNodeSort( p_sys->p_playlist,
00427 p_sys->p_playlist->pp_views[0]->p_root,
00428 SORT_TITLE_NODES_FIRST,
00429 ( i_order == 0 ) ? ORDER_NORMAL : ORDER_REVERSE );
00430 msg_Dbg( p_intf, "requested playlist sort by title (%d)" , i_order );
00431 }
00432 else if( !strcmp( type , "author" ) )
00433 {
00434 playlist_RecursiveNodeSort( p_sys->p_playlist,
00435 p_sys->p_playlist->pp_views[0]->p_root,
00436 SORT_AUTHOR,
00437 ( i_order == 0 ) ? ORDER_NORMAL : ORDER_REVERSE );
00438 msg_Dbg( p_intf, "requested playlist sort by author (%d)" , i_order );
00439 }
00440 else if( !strcmp( type , "shuffle" ) )
00441 {
00442 playlist_RecursiveNodeSort( p_sys->p_playlist,
00443 p_sys->p_playlist->pp_views[0]->p_root,
00444 SORT_RANDOM,
00445 ( i_order == 0 ) ? ORDER_NORMAL : ORDER_REVERSE );
00446 msg_Dbg( p_intf, "requested playlist shuffle");
00447 }
00448
00449 break;
00450 }
00451 case MVLC_MOVE:
00452 {
00453 char psz_pos[6];
00454 char psz_newpos[6];
00455 int i_pos;
00456 int i_newpos;
00457 E_(ExtractURIValue)( p_request, "psz_pos", psz_pos, 6 );
00458 E_(ExtractURIValue)( p_request, "psz_newpos", psz_newpos, 6 );
00459 i_pos = atoi( psz_pos );
00460 i_newpos = atoi( psz_newpos );
00461 if ( i_pos < i_newpos )
00462 {
00463 playlist_Move( p_sys->p_playlist, i_pos, i_newpos + 1 );
00464 }
00465 else
00466 {
00467 playlist_Move( p_sys->p_playlist, i_pos, i_newpos );
00468 }
00469 msg_Dbg( p_intf, "requested move playlist item %d to %d", i_pos, i_newpos);
00470 break;
00471 }
00472
00473
00474 case MVLC_CLOSE:
00475 {
00476 char id[512];
00477 E_(ExtractURIValue)( p_request, "id", id, 512 );
00478 msg_Dbg( p_intf, "requested close id=%s", id );
00479 #if 0
00480 if( p_sys->p_httpd->pf_control( p_sys->p_httpd, HTTPD_SET_CLOSE, id, NULL ) )
00481 {
00482 msg_Warn( p_intf, "close failed for id=%s", id );
00483 }
00484 #endif
00485 break;
00486 }
00487 case MVLC_SHUTDOWN:
00488 {
00489 msg_Dbg( p_intf, "requested shutdown" );
00490 p_intf->p_vlc->b_die = VLC_TRUE;
00491 break;
00492 }
00493
00494 case MVLC_VLM_NEW:
00495 case MVLC_VLM_SETUP:
00496 {
00497 static const char *vlm_properties[11] =
00498 {
00499
00500 "enabled", "disabled", "loop", "unloop",
00501
00502 "input", "output", "option", "date", "period", "repeat", "append",
00503 };
00504 vlm_message_t *vlm_answer;
00505 char name[512];
00506 char *psz = malloc( strlen( p_request ) + 1000 );
00507 char *p = psz;
00508 char *vlm_error;
00509 int i;
00510
00511 if( p_intf->p_sys->p_vlm == NULL )
00512 p_intf->p_sys->p_vlm = vlm_New( p_intf );
00513
00514 if( p_intf->p_sys->p_vlm == NULL ) break;
00515
00516 E_(ExtractURIValue)( p_request, "name", name, 512 );
00517 if( E_(StrToMacroType)( control ) == MVLC_VLM_NEW )
00518 {
00519 char type[20];
00520 E_(ExtractURIValue)( p_request, "type", type, 20 );
00521 p += sprintf( psz, "new %s %s", name, type );
00522 }
00523 else
00524 {
00525 p += sprintf( psz, "setup %s", name );
00526 }
00527
00528 for( i = 0; i < 11; i++ )
00529 {
00530 char val[512];
00531 E_(ExtractURIValue)( p_request,
00532 vlm_properties[i], val, 512 );
00533 E_(DecodeEncodedURI)( val );
00534 if( strlen( val ) > 0 && i >= 4 )
00535 {
00536 p += sprintf( p, " %s %s", vlm_properties[i], val );
00537 }
00538 else if( E_(TestURIParam)( p_request, vlm_properties[i] ) && i < 4 )
00539 {
00540 p += sprintf( p, " %s", vlm_properties[i] );
00541 }
00542 }
00543 vlm_ExecuteCommand( p_intf->p_sys->p_vlm, psz, &vlm_answer );
00544 if( vlm_answer->psz_value == NULL )
00545 {
00546 vlm_error = strdup( "" );
00547 }
00548 else
00549 {
00550 vlm_error = malloc( strlen(vlm_answer->psz_name) +
00551 strlen(vlm_answer->psz_value) +
00552 strlen( " : ") + 1 );
00553 sprintf( vlm_error , "%s : %s" , vlm_answer->psz_name,
00554 vlm_answer->psz_value );
00555 }
00556
00557 E_(mvar_AppendNewVar)( p_args->vars, "vlm_error", vlm_error );
00558
00559 vlm_MessageDelete( vlm_answer );
00560 free( vlm_error );
00561 free( psz );
00562 break;
00563 }
00564
00565 case MVLC_VLM_DEL:
00566 {
00567 vlm_message_t *vlm_answer;
00568 char name[512];
00569 char psz[512+10];
00570 if( p_intf->p_sys->p_vlm == NULL )
00571 p_intf->p_sys->p_vlm = vlm_New( p_intf );
00572
00573 if( p_intf->p_sys->p_vlm == NULL ) break;
00574
00575 E_(ExtractURIValue)( p_request, "name", name, 512 );
00576 sprintf( psz, "del %s", name );
00577
00578 vlm_ExecuteCommand( p_intf->p_sys->p_vlm, psz, &vlm_answer );
00579
00580 vlm_MessageDelete( vlm_answer );
00581 break;
00582 }
00583
00584 case MVLC_VLM_PLAY:
00585 case MVLC_VLM_PAUSE:
00586 case MVLC_VLM_STOP:
00587 case MVLC_VLM_SEEK:
00588 {
00589 vlm_message_t *vlm_answer;
00590 char name[512];
00591 char psz[512+10];
00592 if( p_intf->p_sys->p_vlm == NULL )
00593 p_intf->p_sys->p_vlm = vlm_New( p_intf );
00594
00595 if( p_intf->p_sys->p_vlm == NULL ) break;
00596
00597 E_(ExtractURIValue)( p_request, "name", name, 512 );
00598 if( E_(StrToMacroType)( control ) == MVLC_VLM_PLAY )
00599 sprintf( psz, "control %s play", name );
00600 else if( E_(StrToMacroType)( control ) == MVLC_VLM_PAUSE )
00601 sprintf( psz, "control %s pause", name );
00602 else if( E_(StrToMacroType)( control ) == MVLC_VLM_STOP )
00603 sprintf( psz, "control %s stop", name );
00604 else if( E_(StrToMacroType)( control ) == MVLC_VLM_SEEK )
00605 {
00606 char percent[20];
00607 E_(ExtractURIValue)( p_request, "percent", percent, 512 );
00608 sprintf( psz, "control %s seek %s", name, percent );
00609 }
00610
00611 vlm_ExecuteCommand( p_intf->p_sys->p_vlm, psz, &vlm_answer );
00612
00613 vlm_MessageDelete( vlm_answer );
00614 break;
00615 }
00616 case MVLC_VLM_LOAD:
00617 case MVLC_VLM_SAVE:
00618 {
00619 vlm_message_t *vlm_answer;
00620 char file[512];
00621 char psz[512];
00622
00623 if( p_intf->p_sys->p_vlm == NULL )
00624 p_intf->p_sys->p_vlm = vlm_New( p_intf );
00625
00626 if( p_intf->p_sys->p_vlm == NULL ) break;
00627
00628 E_(ExtractURIValue)( p_request, "file", file, 512 );
00629 E_(DecodeEncodedURI)( file );
00630
00631 if( E_(StrToMacroType)( control ) == MVLC_VLM_LOAD )
00632 sprintf( psz, "load %s", file );
00633 else
00634 sprintf( psz, "save %s", file );
00635
00636 vlm_ExecuteCommand( p_intf->p_sys->p_vlm, psz, &vlm_answer );
00637
00638 vlm_MessageDelete( vlm_answer );
00639 break;
00640 }
00641
00642 default:
00643 if( *control )
00644 {
00645 PRINTS( "<!-- control param(%s) unsupported -->", control );
00646 }
00647 break;
00648 }
00649 break;
00650
00651 case MVLC_SET:
00652 {
00653 char value[512];
00654 int i;
00655 float f;
00656
00657 if( i_request <= 0 ||
00658 *m->param1 == '\0' ||
00659 strstr( p_request, m->param1 ) == NULL )
00660 {
00661 break;
00662 }
00663 E_(ExtractURIValue)( p_request, m->param1, value, 512 );
00664 E_(DecodeEncodedURI)( value );
00665
00666 switch( E_(StrToMacroType)( m->param2 ) )
00667 {
00668 case MVLC_INT:
00669 i = atoi( value );
00670 config_PutInt( p_intf, m->param1, i );
00671 break;
00672 case MVLC_FLOAT:
00673 f = atof( value );
00674 config_PutFloat( p_intf, m->param1, f );
00675 break;
00676 case MVLC_STRING:
00677 config_PutPsz( p_intf, m->param1, value );
00678 break;
00679 default:
00680 PRINTS( "<!-- invalid type(%s) in set -->", m->param2 )
00681 }
00682 break;
00683 }
00684 case MVLC_GET:
00685 {
00686 char value[512];
00687 int i;
00688 float f;
00689 char *psz;
00690
00691 if( *m->param1 == '\0' )
00692 {
00693 break;
00694 }
00695
00696 switch( E_(StrToMacroType)( m->param2 ) )
00697 {
00698 case MVLC_INT:
00699 i = config_GetInt( p_intf, m->param1 );
00700 sprintf( value, "%d", i );
00701 break;
00702 case MVLC_FLOAT:
00703 f = config_GetFloat( p_intf, m->param1 );
00704 sprintf( value, "%f", f );
00705 break;
00706 case MVLC_STRING:
00707 psz = config_GetPsz( p_intf, m->param1 );
00708 if( psz != NULL )
00709 {
00710 strncpy( value, psz,sizeof( value ) );
00711 free( psz );
00712 value[sizeof( value ) - 1] = '\0';
00713 }
00714 else
00715 *value = '\0';
00716 msg_Dbg( p_intf, "%d: value = \"%s\"", __LINE__, value );
00717 break;
00718 default:
00719 snprintf( value, sizeof( value ),
00720 "invalid type(%s) in set", m->param2 );
00721 value[sizeof( value ) - 1] = '\0';
00722 break;
00723 }
00724 PRINTS( "%s", value );
00725 break;
00726 }
00727 case MVLC_VALUE:
00728 {
00729 char *s, *v;
00730
00731 if( m->param1 )
00732 {
00733 E_(EvaluateRPN)( p_intf, p_args->vars, &p_args->stack, m->param1 );
00734 s = E_(SSPop)( &p_args->stack );
00735 v = E_(mvar_GetValue)( p_args->vars, s );
00736 }
00737 else
00738 {
00739 v = s = E_(SSPop)( &p_args->stack );
00740 }
00741
00742 PRINTS( "%s", v );
00743 free( s );
00744 break;
00745 }
00746 case MVLC_RPN:
00747 E_(EvaluateRPN)( p_intf, p_args->vars, &p_args->stack, m->param1 );
00748 break;
00749
00750
00751 case MVLC_STACK:
00752 {
00753 int i;
00754 msg_Dbg( p_intf, "stack" );
00755 for (i=0;i<(&p_args->stack)->i_stack;i++)
00756 msg_Dbg( p_intf, "%d -> %s", i, (&p_args->stack)->stack[i] );
00757 break;
00758 }
00759
00760 case MVLC_UNKNOWN:
00761 default:
00762 PRINTS( "<!-- invalid macro id=`%s' -->", m->id );
00763 msg_Dbg( p_intf, "invalid macro id=`%s'", m->id );
00764 break;
00765 }
00766 #undef PRINTS
00767 #undef PRINT
00768 #undef ALLOC
00769 }
00770
00771 char *E_(MacroSearch)( char *src, char *end, int i_mvlc, vlc_bool_t b_after )
00772 {
00773 int i_id;
00774 int i_level = 0;
00775
00776 while( src < end )
00777 {
00778 if( src + 4 < end && !strncmp( (char *)src, "<vlc", 4 ) )
00779 {
00780 int i_skip;
00781 macro_t m;
00782
00783 i_skip = E_(MacroParse)( &m, src );
00784
00785 i_id = E_(StrToMacroType)( m.id );
00786
00787 switch( i_id )
00788 {
00789 case MVLC_IF:
00790 case MVLC_FOREACH:
00791 i_level++;
00792 break;
00793 case MVLC_END:
00794 i_level--;
00795 break;
00796 default:
00797 break;
00798 }
00799
00800 E_(MacroClean)( &m );
00801
00802 if( ( i_mvlc == MVLC_END && i_level == -1 ) ||
00803 ( i_mvlc != MVLC_END && i_level == 0 && i_mvlc == i_id ) )
00804 {
00805 return src + ( b_after ? i_skip : 0 );
00806 }
00807 else if( i_level < 0 )
00808 {
00809 return NULL;
00810 }
00811
00812 src += i_skip;
00813 }
00814 else
00815 {
00816 src++;
00817 }
00818 }
00819
00820 return NULL;
00821 }
00822
00823 void E_(Execute)( httpd_file_sys_t *p_args,
00824 char *p_request, int i_request,
00825 char **pp_data, int *pi_data,
00826 char **pp_dst,
00827 char *_src, char *_end )
00828 {
00829 intf_thread_t *p_intf = p_args->p_intf;
00830
00831 char *src, *dup, *end;
00832 char *dst = *pp_dst;
00833
00834 src = dup = malloc( _end - _src + 1 );
00835 end = src +( _end - _src );
00836
00837 memcpy( src, _src, _end - _src );
00838 *end = '\0';
00839
00840
00841 while( src < end )
00842 {
00843 char *p;
00844 int i_copy;
00845
00846 p = (char *)strstr( (char *)src, "<vlc" );
00847 if( p < end && p == src )
00848 {
00849 macro_t m;
00850
00851 src += E_(MacroParse)( &m, src );
00852
00853
00854
00855 switch( E_(StrToMacroType)( m.id ) )
00856 {
00857 case MVLC_INCLUDE:
00858 {
00859 FILE *f;
00860 int i_buffer;
00861 char *p_buffer;
00862 char psz_file[MAX_DIR_SIZE];
00863 char *p;
00864 char sep;
00865
00866 #if defined( WIN32 )
00867 sep = '\\';
00868 #else
00869 sep = '/';
00870 #endif
00871
00872 if( m.param1[0] != sep )
00873 {
00874 strcpy( psz_file, p_args->file );
00875 p = strrchr( psz_file, sep );
00876 if( p != NULL )
00877 strcpy( p + 1, m.param1 );
00878 else
00879 strcpy( psz_file, m.param1 );
00880 }
00881 else
00882 {
00883 strcpy( psz_file, m.param1 );
00884 }
00885
00886 if( ( f = fopen( psz_file, "r" ) ) == NULL )
00887 {
00888 msg_Warn( p_args->p_intf,
00889 "unable to include file %s (%s)",
00890 psz_file, strerror(errno) );
00891 break;
00892 }
00893
00894
00895 E_(FileLoad)( f, &p_buffer, &i_buffer );
00896
00897
00898 E_(Execute)( p_args, p_request, i_request, pp_data, pi_data,
00899 &dst, &p_buffer[0], &p_buffer[i_buffer] );
00900 free( p_buffer );
00901 fclose(f);
00902 break;
00903 }
00904 case MVLC_IF:
00905 {
00906 vlc_bool_t i_test;
00907 char *endif;
00908
00909 E_(EvaluateRPN)( p_intf, p_args->vars, &p_args->stack, m.param1 );
00910 if( E_(SSPopN)( &p_args->stack, p_args->vars ) )
00911 {
00912 i_test = 1;
00913 }
00914 else
00915 {
00916 i_test = 0;
00917 }
00918 endif = E_(MacroSearch)( src, end, MVLC_END, VLC_TRUE );
00919
00920 if( i_test == 0 )
00921 {
00922 char *start = E_(MacroSearch)( src, endif, MVLC_ELSE, VLC_TRUE );
00923
00924 if( start )
00925 {
00926 char *stop = E_(MacroSearch)( start, endif, MVLC_END, VLC_FALSE );
00927 if( stop )
00928 {
00929 E_(Execute)( p_args, p_request, i_request,
00930 pp_data, pi_data, &dst, start, stop );
00931 }
00932 }
00933 }
00934 else if( i_test == 1 )
00935 {
00936 char *stop;
00937 if( ( stop = E_(MacroSearch)( src, endif, MVLC_ELSE, VLC_FALSE ) ) == NULL )
00938 {
00939 stop = E_(MacroSearch)( src, endif, MVLC_END, VLC_FALSE );
00940 }
00941 if( stop )
00942 {
00943 E_(Execute)( p_args, p_request, i_request,
00944 pp_data, pi_data, &dst, src, stop );
00945 }
00946 }
00947
00948 src = endif;
00949 break;
00950 }
00951 case MVLC_FOREACH:
00952 {
00953 char *endfor = E_(MacroSearch)( src, end, MVLC_END, VLC_TRUE );
00954 char *start = src;
00955 char *stop = E_(MacroSearch)( src, end, MVLC_END, VLC_FALSE );
00956
00957 if( stop )
00958 {
00959 mvar_t *index;
00960 int i_idx;
00961 mvar_t *v;
00962 if( !strcmp( m.param2, "integer" ) )
00963 {
00964 char *arg = E_(SSPop)( &p_args->stack );
00965 index = E_(mvar_IntegerSetNew)( m.param1, arg );
00966 free( arg );
00967 }
00968 else if( !strcmp( m.param2, "directory" ) )
00969 {
00970 char *arg = E_(SSPop)( &p_args->stack );
00971 index = E_(mvar_FileSetNew)( p_intf, m.param1, arg );
00972 free( arg );
00973 }
00974 else if( !strcmp( m.param2, "playlist" ) )
00975 {
00976 index = E_(mvar_PlaylistSetNew)( p_intf, m.param1,
00977 p_intf->p_sys->p_playlist );
00978 }
00979 else if( !strcmp( m.param2, "information" ) )
00980 {
00981 index = E_(mvar_InfoSetNew)( p_intf, m.param1,
00982 p_intf->p_sys->p_input );
00983 }
00984 else if( !strcmp( m.param2, "program" )
00985 || !strcmp( m.param2, "title" )
00986 || !strcmp( m.param2, "chapter" )
00987 || !strcmp( m.param2, "audio-es" )
00988 || !strcmp( m.param2, "video-es" )
00989 || !strcmp( m.param2, "spu-es" ) )
00990 {
00991 index = E_(mvar_InputVarSetNew)( p_intf, m.param1,
00992 p_intf->p_sys->p_input,
00993 m.param2 );
00994 }
00995 else if( !strcmp( m.param2, "vlm" ) )
00996 {
00997 if( p_intf->p_sys->p_vlm == NULL )
00998 p_intf->p_sys->p_vlm = vlm_New( p_intf );
00999 index = E_(mvar_VlmSetNew)( m.param1, p_intf->p_sys->p_vlm );
01000 }
01001 #if 0
01002 else if( !strcmp( m.param2, "hosts" ) )
01003 {
01004 index = E_(mvar_HttpdInfoSetNew)( m.param1, p_intf->p_sys->p_httpd, HTTPD_GET_HOSTS );
01005 }
01006 else if( !strcmp( m.param2, "urls" ) )
01007 {
01008 index = E_(mvar_HttpdInfoSetNew)( m.param1, p_intf->p_sys->p_httpd, HTTPD_GET_URLS );
01009 }
01010 else if( !strcmp( m.param2, "connections" ) )
01011 {
01012 index = E_(mvar_HttpdInfoSetNew)(m.param1, p_intf->p_sys->p_httpd, HTTPD_GET_CONNECTIONS);
01013 }
01014 #endif
01015 else if( ( v = E_(mvar_GetVar)( p_args->vars, m.param2 ) ) )
01016 {
01017 index = E_(mvar_Duplicate)( v );
01018 }
01019 else
01020 {
01021 msg_Dbg( p_intf, "invalid index constructor (%s)", m.param2 );
01022 src = endfor;
01023 break;
01024 }
01025
01026 for( i_idx = 0; i_idx < index->i_field; i_idx++ )
01027 {
01028 mvar_t *f = E_(mvar_Duplicate)( index->field[i_idx] );
01029
01030
01031
01032 free( f->name );
01033 f->name = strdup( m.param1 );
01034
01035
01036 E_(mvar_PushVar)( p_args->vars, f );
01037 E_(Execute)( p_args, p_request, i_request,
01038 pp_data, pi_data, &dst, start, stop );
01039 E_(mvar_RemoveVar)( p_args->vars, f );
01040
01041 E_(mvar_Delete)( f );
01042 }
01043 E_(mvar_Delete)( index );
01044
01045 src = endfor;
01046 }
01047 break;
01048 }
01049 default:
01050 E_(MacroDo)( p_args, &m, p_request, i_request,
01051 pp_data, pi_data, &dst );
01052 break;
01053 }
01054
01055 E_(MacroClean)( &m );
01056 continue;
01057 }
01058
01059 i_copy = ( (p == NULL || p > end ) ? end : p ) - src;
01060 if( i_copy > 0 )
01061 {
01062 int i_index = dst - *pp_data;
01063
01064 *pi_data += i_copy;
01065 *pp_data = realloc( *pp_data, *pi_data );
01066 dst = (*pp_data) + i_index;
01067
01068 memcpy( dst, src, i_copy );
01069 dst += i_copy;
01070 src += i_copy;
01071 }
01072 }
01073
01074 *pp_dst = dst;
01075 free( dup );
01076 }