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
00028
00029 static int Filter( const struct dirent *foo )
00030 {
00031 return VLC_TRUE;
00032 };
00033
00034 static int InsensitiveAlphasort( const struct dirent **foo1,
00035 const struct dirent **foo2 )
00036 {
00037 return strcasecmp( (*foo1)->d_name, (*foo2)->d_name );
00038 };
00039
00040
00041
00042 mvar_t *E_(mvar_New)( const char *name, const char *value )
00043 {
00044 mvar_t *v = malloc( sizeof( mvar_t ) );
00045
00046 if( !v ) return NULL;
00047 v->name = strdup( name );
00048 v->value = strdup( value ? value : "" );
00049
00050 v->i_field = 0;
00051 v->field = malloc( sizeof( mvar_t * ) );
00052 v->field[0] = NULL;
00053
00054 return v;
00055 }
00056
00057 void E_(mvar_Delete)( mvar_t *v )
00058 {
00059 int i;
00060
00061 free( v->name );
00062 free( v->value );
00063
00064 for( i = 0; i < v->i_field; i++ )
00065 {
00066 E_(mvar_Delete)( v->field[i] );
00067 }
00068 free( v->field );
00069 free( v );
00070 }
00071
00072 void E_(mvar_AppendVar)( mvar_t *v, mvar_t *f )
00073 {
00074 v->field = realloc( v->field, sizeof( mvar_t * ) * ( v->i_field + 2 ) );
00075 v->field[v->i_field] = f;
00076 v->i_field++;
00077 }
00078
00079 mvar_t *E_(mvar_Duplicate)( const mvar_t *v )
00080 {
00081 int i;
00082 mvar_t *n;
00083
00084 n = E_(mvar_New)( v->name, v->value );
00085 for( i = 0; i < v->i_field; i++ )
00086 {
00087 E_(mvar_AppendVar)( n, E_(mvar_Duplicate)( v->field[i] ) );
00088 }
00089
00090 return n;
00091 }
00092
00093 void E_(mvar_PushVar)( mvar_t *v, mvar_t *f )
00094 {
00095 v->field = realloc( v->field, sizeof( mvar_t * ) * ( v->i_field + 2 ) );
00096 if( v->i_field > 0 )
00097 {
00098 memmove( &v->field[1], &v->field[0], sizeof( mvar_t * ) * v->i_field );
00099 }
00100 v->field[0] = f;
00101 v->i_field++;
00102 }
00103
00104 void E_(mvar_RemoveVar)( mvar_t *v, mvar_t *f )
00105 {
00106 int i;
00107 for( i = 0; i < v->i_field; i++ )
00108 {
00109 if( v->field[i] == f )
00110 {
00111 break;
00112 }
00113 }
00114 if( i >= v->i_field )
00115 {
00116 return;
00117 }
00118
00119 if( i + 1 < v->i_field )
00120 {
00121 memmove( &v->field[i], &v->field[i+1], sizeof( mvar_t * ) * ( v->i_field - i - 1 ) );
00122 }
00123 v->i_field--;
00124
00125 }
00126
00127 mvar_t *E_(mvar_GetVar)( mvar_t *s, const char *name )
00128 {
00129 int i;
00130 char base[512], *field, *p;
00131 int i_index;
00132
00133
00134
00135 field = strchr( name, '.' );
00136 if( field )
00137 {
00138 int i = field - name;
00139 strncpy( base, name, i );
00140 base[i] = '\0';
00141 field++;
00142 }
00143 else
00144 {
00145 strcpy( base, name );
00146 }
00147
00148 if( ( p = strchr( base, '[' ) ) )
00149 {
00150 *p++ = '\0';
00151 sscanf( p, "%d]", &i_index );
00152 if( i_index < 0 )
00153 {
00154 return NULL;
00155 }
00156 }
00157 else
00158 {
00159 i_index = 0;
00160 }
00161
00162 for( i = 0; i < s->i_field; i++ )
00163 {
00164 if( !strcmp( s->field[i]->name, base ) )
00165 {
00166 if( i_index > 0 )
00167 {
00168 i_index--;
00169 }
00170 else
00171 {
00172 if( field )
00173 {
00174 return E_(mvar_GetVar)( s->field[i], field );
00175 }
00176 else
00177 {
00178 return s->field[i];
00179 }
00180 }
00181 }
00182 }
00183 return NULL;
00184 }
00185
00186 char *E_(mvar_GetValue)( mvar_t *v, char *field )
00187 {
00188 if( *field == '\0' )
00189 {
00190 return v->value;
00191 }
00192 else
00193 {
00194 mvar_t *f = E_(mvar_GetVar)( v, field );
00195 if( f )
00196 {
00197 return f->value;
00198 }
00199 else
00200 {
00201 return field;
00202 }
00203 }
00204 }
00205
00206 void E_(mvar_PushNewVar)( mvar_t *vars, const char *name,
00207 const char *value )
00208 {
00209 mvar_t *f = E_(mvar_New)( name, value );
00210 E_(mvar_PushVar)( vars, f );
00211 }
00212
00213 void E_(mvar_AppendNewVar)( mvar_t *vars, const char *name,
00214 const char *value )
00215 {
00216 mvar_t *f = E_(mvar_New)( name, value );
00217 E_(mvar_AppendVar)( vars, f );
00218 }
00219
00220
00221
00222 mvar_t *E_(mvar_IntegerSetNew)( const char *name, const char *arg )
00223 {
00224 char *dup = strdup( arg );
00225 char *str = dup;
00226 mvar_t *s = E_(mvar_New)( name, "set" );
00227
00228 while( str )
00229 {
00230 char *p;
00231 int i_start,i_stop,i_step;
00232 int i_match;
00233
00234 p = strchr( str, ',' );
00235 if( p )
00236 {
00237 *p++ = '\0';
00238 }
00239
00240 i_step = 0;
00241 i_match = sscanf( str, "%d:%d:%d", &i_start, &i_stop, &i_step );
00242
00243 if( i_match == 1 )
00244 {
00245 i_stop = i_start;
00246 i_step = 1;
00247 }
00248 else if( i_match == 2 )
00249 {
00250 i_step = i_start < i_stop ? 1 : -1;
00251 }
00252
00253 if( i_match >= 1 )
00254 {
00255 int i;
00256
00257 if( ( i_start <= i_stop && i_step > 0 ) ||
00258 ( i_start >= i_stop && i_step < 0 ) )
00259 {
00260 for( i = i_start; ; i += i_step )
00261 {
00262 char value[79];
00263
00264 if( ( i_step > 0 && i > i_stop ) ||
00265 ( i_step < 0 && i < i_stop ) )
00266 {
00267 break;
00268 }
00269
00270 sprintf( value, "%d", i );
00271
00272 E_(mvar_PushNewVar)( s, name, value );
00273 }
00274 }
00275 }
00276 str = p;
00277 }
00278
00279 free( dup );
00280 return s;
00281 }
00282
00283
00284
00285
00286
00287 mvar_t *E_(mvar_PlaylistSetNew)( intf_thread_t *p_intf, char *name,
00288 playlist_t *p_pl )
00289 {
00290 playlist_view_t *p_view;
00291 mvar_t *s = E_(mvar_New)( name, "set" );
00292
00293
00294 vlc_mutex_lock( &p_pl->object_lock );
00295
00296 p_view = playlist_ViewFind( p_pl, VIEW_CATEGORY );
00297
00298 if( p_view != NULL )
00299 E_(PlaylistListNode)( p_intf, p_pl, p_view->p_root, name, s, 0 );
00300
00301 vlc_mutex_unlock( &p_pl->object_lock );
00302
00303 return s;
00304 }
00305
00306 mvar_t *E_(mvar_InfoSetNew)( intf_thread_t *p_intf, char *name,
00307 input_thread_t *p_input )
00308 {
00309 mvar_t *s = E_(mvar_New)( name, "set" );
00310 int i, j;
00311
00312 if( p_input == NULL )
00313 {
00314 return s;
00315 }
00316
00317 vlc_mutex_lock( &p_input->input.p_item->lock );
00318 for ( i = 0; i < p_input->input.p_item->i_categories; i++ )
00319 {
00320 info_category_t *p_category = p_input->input.p_item->pp_categories[i];
00321 char *psz;
00322
00323 mvar_t *cat = E_(mvar_New)( name, "set" );
00324 mvar_t *iset = E_(mvar_New)( "info", "set" );
00325
00326 psz = E_(FromUTF8)( p_intf, p_category->psz_name );
00327 E_(mvar_AppendNewVar)( cat, "name", psz );
00328 free( psz );
00329 E_(mvar_AppendVar)( cat, iset );
00330
00331 for ( j = 0; j < p_category->i_infos; j++ )
00332 {
00333 info_t *p_info = p_category->pp_infos[j];
00334 mvar_t *info = E_(mvar_New)( "info", "" );
00335 char *psz_name = E_(FromUTF8)( p_intf, p_info->psz_name );
00336 char *psz_value = E_(FromUTF8)( p_intf, p_info->psz_value );
00337
00338 msg_Dbg( p_input, "adding info name=%s value=%s",
00339 psz_name, psz_value );
00340 E_(mvar_AppendNewVar)( info, "name", psz_name );
00341 E_(mvar_AppendNewVar)( info, "value", psz_value );
00342 free( psz_name );
00343 free( psz_value );
00344 E_(mvar_AppendVar)( iset, info );
00345 }
00346 E_(mvar_AppendVar)( s, cat );
00347 }
00348 vlc_mutex_unlock( &p_input->input.p_item->lock );
00349
00350 return s;
00351 }
00352
00353 mvar_t *E_(mvar_InputVarSetNew)( intf_thread_t *p_intf, char *name,
00354 input_thread_t *p_input,
00355 const char *psz_variable )
00356 {
00357 intf_sys_t *p_sys = p_intf->p_sys;
00358 mvar_t *s = E_(mvar_New)( name, "set" );
00359 vlc_value_t val, val_list, text_list;
00360 int i_type, i;
00361
00362 if( p_input == NULL )
00363 {
00364 return s;
00365 }
00366
00367
00368 i_type = var_Type( p_sys->p_input, psz_variable );
00369
00370
00371 if( i_type & VLC_VAR_HASCHOICE )
00372 {
00373 var_Change( p_sys->p_input, psz_variable, VLC_VAR_CHOICESCOUNT, &val, NULL );
00374 if( val.i_int == 0 ) return s;
00375 if( (i_type & VLC_VAR_TYPE) != VLC_VAR_VARIABLE && val.i_int == 1 )
00376 return s;
00377 }
00378 else
00379 {
00380 return s;
00381 }
00382
00383 switch( i_type & VLC_VAR_TYPE )
00384 {
00385 case VLC_VAR_VOID:
00386 case VLC_VAR_BOOL:
00387 case VLC_VAR_VARIABLE:
00388 case VLC_VAR_STRING:
00389 case VLC_VAR_INTEGER:
00390 break;
00391 default:
00392
00393 return s;
00394 }
00395
00396 if( var_Get( p_sys->p_input, psz_variable, &val ) < 0 )
00397 {
00398 return s;
00399 }
00400
00401 if( var_Change( p_sys->p_input, psz_variable, VLC_VAR_GETLIST,
00402 &val_list, &text_list ) < 0 )
00403 {
00404 if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string );
00405 return s;
00406 }
00407
00408 for( i = 0; i < val_list.p_list->i_count; i++ )
00409 {
00410 char *psz, psz_int[16];
00411 mvar_t *itm;
00412
00413 switch( i_type & VLC_VAR_TYPE )
00414 {
00415 case VLC_VAR_STRING:
00416 itm = E_(mvar_New)( name, "set" );
00417 psz = E_(FromUTF8)( p_intf, text_list.p_list->p_values[i].psz_string );
00418 E_(mvar_AppendNewVar)( itm, "name", psz );
00419 psz = E_(FromUTF8)( p_intf, val_list.p_list->p_values[i].psz_string );
00420 E_(mvar_AppendNewVar)( itm, "id", psz );
00421 free( psz );
00422 snprintf( psz_int, sizeof(psz_int), "%d",
00423 ( !strcmp( val.psz_string,
00424 val_list.p_list->p_values[i].psz_string )
00425 && !( i_type & VLC_VAR_ISCOMMAND ) ) );
00426 E_(mvar_AppendNewVar)( itm, "selected", psz_int );
00427 E_(mvar_AppendVar)( s, itm );
00428 break;
00429
00430 case VLC_VAR_INTEGER:
00431 itm = E_(mvar_New)( name, "set" );
00432 psz = E_(FromUTF8)( p_intf, text_list.p_list->p_values[i].psz_string );
00433 E_(mvar_AppendNewVar)( itm, "name", psz );
00434 snprintf( psz_int, sizeof(psz_int), "%d",
00435 val_list.p_list->p_values[i].i_int );
00436 E_(mvar_AppendNewVar)( itm, "id", psz_int );
00437 snprintf( psz_int, sizeof(psz_int), "%d",
00438 ( val.i_int == val_list.p_list->p_values[i].i_int )
00439 && !( i_type & VLC_VAR_ISCOMMAND ) );
00440 E_(mvar_AppendNewVar)( itm, "selected", psz_int );
00441 E_(mvar_AppendVar)( s, itm );
00442 break;
00443
00444 default:
00445 break;
00446 }
00447 }
00448
00449 if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string );
00450 var_Change( p_sys->p_input, psz_variable, VLC_VAR_FREELIST, &val_list,
00451 &text_list );
00452 return s;
00453 }
00454
00455 #if 0
00456 mvar_t *E_(mvar_HttpdInfoSetNew)( char *name, httpd_t *p_httpd, int i_type )
00457 {
00458 mvar_t *s = E_(mvar_New)( name, "set" );
00459 httpd_info_t info;
00460 int i;
00461
00462 if( !p_httpd->pf_control( p_httpd, i_type, &info, NULL ) )
00463 {
00464 for( i= 0; i < info.i_count; )
00465 {
00466 mvar_t *inf;
00467
00468 inf = E_(mvar_New)( name, "set" );
00469 do
00470 {
00471
00472
00473 E_(mvar_AppendNewVar)( inf,
00474 info.info[i].psz_name,
00475 info.info[i].psz_value );
00476 i++;
00477 } while( i < info.i_count && strcmp( info.info[i].psz_name, "id" ) );
00478 E_(mvar_AppendVar)( s, inf );
00479 }
00480 }
00481
00482
00483 for( i = 0; i < info.i_count; i++ )
00484 {
00485 free( info.info[i].psz_name );
00486 free( info.info[i].psz_value );
00487 }
00488 if( info.i_count > 0 )
00489 {
00490 free( info.info );
00491 }
00492
00493 return s;
00494 }
00495 #endif
00496
00497 mvar_t *E_(mvar_FileSetNew)( intf_thread_t *p_intf, char *name,
00498 char *psz_dir )
00499 {
00500 mvar_t *s = E_(mvar_New)( name, "set" );
00501 char tmp[MAX_DIR_SIZE];
00502 #ifdef HAVE_SYS_STAT_H
00503 struct stat stat_info;
00504 #endif
00505 struct dirent **pp_dir_content;
00506 int i_dir_content, i;
00507 char sep;
00508
00509
00510 #if defined( WIN32 )
00511 sep = '\\';
00512 #else
00513 sep = '/';
00514 #endif
00515
00516 psz_dir = E_(RealPath)( p_intf, psz_dir );
00517
00518 #ifdef HAVE_SYS_STAT_H
00519 if( (stat( psz_dir, &stat_info ) == -1 || !S_ISDIR( stat_info.st_mode ))
00520 # if defined( WIN32 )
00521 && psz_dir[0] != '\0' && (psz_dir[0] != '\\' || psz_dir[1] != '\0')
00522 # endif
00523 )
00524 {
00525 free( psz_dir );
00526 return s;
00527 }
00528 #endif
00529
00530
00531 if( ( i_dir_content = scandir( psz_dir, &pp_dir_content, Filter,
00532 InsensitiveAlphasort ) ) == -1 )
00533 {
00534 msg_Warn( p_intf, "scandir error on %s (%s)", psz_dir,
00535 strerror(errno) );
00536 free( psz_dir );
00537 return s;
00538 }
00539
00540 for( i = 0; i < i_dir_content; i++ )
00541 {
00542 struct dirent *p_dir_content = pp_dir_content[i];
00543 mvar_t *f;
00544 const char *psz_ext;
00545 char *psz_name, *psz_tmp;
00546
00547 if( !strcmp( p_dir_content->d_name, "." ) )
00548 {
00549 continue;
00550 }
00551
00552 #if defined( WIN32 )
00553 if( psz_dir[0] == '\0' || (psz_dir[0] == '\\' && psz_dir[1] == '\0') )
00554 {
00555 snprintf( tmp, sizeof(tmp), "%s", p_dir_content->d_name );
00556 }
00557 else
00558 #endif
00559 {
00560 snprintf( tmp, sizeof(tmp), "%s%c%s", psz_dir, sep,
00561 p_dir_content->d_name );
00562
00563 #ifdef HAVE_SYS_STAT_H
00564 if( stat( tmp, &stat_info ) == -1 )
00565 {
00566 continue;
00567 }
00568 #endif
00569 }
00570 f = E_(mvar_New)( name, "set" );
00571
00572 psz_tmp = vlc_fix_readdir_charset( p_intf, p_dir_content->d_name );
00573 psz_name = E_(FromUTF8)( p_intf, psz_tmp );
00574 free( psz_tmp );
00575
00576
00577 psz_ext = strrchr( psz_name, '.' );
00578 E_(mvar_AppendNewVar)( f, "ext", psz_ext != NULL ? psz_ext + 1 : "" );
00579
00580 #if defined( WIN32 )
00581 if( psz_dir[0] == '\0' || (psz_dir[0] == '\\' && psz_dir[1] == '\0') )
00582 {
00583 snprintf( tmp, sizeof(tmp), "%c:", psz_name[0] );
00584 E_(mvar_AppendNewVar)( f, "name", psz_name );
00585 E_(mvar_AppendNewVar)( f, "basename", tmp );
00586 E_(mvar_AppendNewVar)( f, "type", "directory" );
00587 E_(mvar_AppendNewVar)( f, "size", "unknown" );
00588 E_(mvar_AppendNewVar)( f, "date", "unknown" );
00589 }
00590 else
00591 #endif
00592 {
00593 snprintf( tmp, sizeof(tmp), "%s%c%s", psz_dir, sep, psz_name );
00594 E_(mvar_AppendNewVar)( f, "name", tmp );
00595 E_(mvar_AppendNewVar)( f, "basename", psz_name );
00596
00597 #ifdef HAVE_SYS_STAT_H
00598 if( S_ISDIR( stat_info.st_mode ) )
00599 {
00600 E_(mvar_AppendNewVar)( f, "type", "directory" );
00601 }
00602 else if( S_ISREG( stat_info.st_mode ) )
00603 {
00604 E_(mvar_AppendNewVar)( f, "type", "file" );
00605 }
00606 else
00607 {
00608 E_(mvar_AppendNewVar)( f, "type", "unknown" );
00609 }
00610
00611 sprintf( tmp, I64Fd, (int64_t)stat_info.st_size );
00612 E_(mvar_AppendNewVar)( f, "size", tmp );
00613
00614
00615 # ifdef HAVE_CTIME_R
00616 ctime_r( &stat_info.st_mtime, tmp );
00617 E_(mvar_AppendNewVar)( f, "date", tmp );
00618 # else
00619 E_(mvar_AppendNewVar)( f, "date", ctime( &stat_info.st_mtime ) );
00620 # endif
00621
00622 #else
00623 E_(mvar_AppendNewVar)( f, "type", "unknown" );
00624 E_(mvar_AppendNewVar)( f, "size", "unknown" );
00625 E_(mvar_AppendNewVar)( f, "date", "unknown" );
00626 #endif
00627 }
00628
00629 E_(mvar_AppendVar)( s, f );
00630
00631 free( psz_name );
00632 }
00633
00634 free( psz_dir );
00635 return s;
00636 }
00637
00638 mvar_t *E_(mvar_VlmSetNew)( char *name, vlm_t *vlm )
00639 {
00640 mvar_t *s = E_(mvar_New)( name, "set" );
00641 vlm_message_t *msg;
00642 int i;
00643
00644 if( vlm == NULL ) return s;
00645
00646 if( vlm_ExecuteCommand( vlm, "show", &msg ) )
00647 {
00648 return s;
00649 }
00650
00651 for( i = 0; i < msg->i_child; i++ )
00652 {
00653
00654 vlm_message_t *ch = msg->child[i];
00655 int j;
00656
00657 for( j = 0; j < ch->i_child; j++ )
00658 {
00659
00660 vlm_message_t *el = ch->child[j];
00661 vlm_message_t *inf, *desc;
00662 mvar_t *set;
00663 char psz[500];
00664 int k;
00665
00666 sprintf( psz, "show %s", el->psz_name );
00667 if( vlm_ExecuteCommand( vlm, psz, &inf ) )
00668 continue;
00669 desc = inf->child[0];
00670
00671
00672 set = E_(mvar_New)( name, "set" );
00673 E_(mvar_AppendNewVar)( set, "name", el->psz_name );
00674
00675 for( k = 0; k < desc->i_child; k++ )
00676 {
00677 vlm_message_t *ch = desc->child[k];
00678 if( ch->i_child > 0 )
00679 {
00680 int c;
00681 mvar_t *n = E_(mvar_New)( ch->psz_name, "set" );
00682
00683 for( c = 0; c < ch->i_child; c++ )
00684 {
00685 if( ch->child[c]->psz_value )
00686 {
00687 E_(mvar_AppendNewVar)( n, ch->child[c]->psz_name, ch->child[c]->psz_value );
00688 }
00689 else
00690 {
00691 mvar_t *in = E_(mvar_New)( ch->psz_name, ch->child[c]->psz_name );
00692 E_(mvar_AppendVar)( n, in );
00693 }
00694 }
00695 E_(mvar_AppendVar)( set, n );
00696 }
00697 else
00698 {
00699 E_(mvar_AppendNewVar)( set, ch->psz_name, ch->psz_value );
00700 }
00701 }
00702 vlm_MessageDelete( inf );
00703
00704 E_(mvar_AppendVar)( s, set );
00705 }
00706 }
00707 vlm_MessageDelete( msg );
00708
00709 return s;
00710 }