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
00030
00031
00032
00033 char *E_(FileToUrl)( char *name, vlc_bool_t *pb_index )
00034 {
00035 char *url, *p;
00036
00037 url = p = malloc( strlen( name ) + 1 );
00038
00039 *pb_index = VLC_FALSE;
00040 if( !url || !p )
00041 {
00042 return NULL;
00043 }
00044
00045 #ifdef WIN32
00046 while( *name == '\\' || *name == '/' )
00047 #else
00048 while( *name == '/' )
00049 #endif
00050 {
00051 name++;
00052 }
00053
00054 *p++ = '/';
00055 strcpy( p, name );
00056
00057 #ifdef WIN32
00058
00059 name = p;
00060 while( *name )
00061 {
00062 if( *name == '\\' )
00063 *name = '/';
00064 name++;
00065 }
00066 #endif
00067
00068
00069 if( ( p = strrchr( url, '/' ) ) != NULL )
00070 {
00071 if( !strncmp( p, "/index.", 7 ) )
00072 {
00073 p[1] = '\0';
00074 *pb_index = VLC_TRUE;
00075 }
00076 }
00077 return url;
00078 }
00079
00080
00081 int E_(FileLoad)( FILE *f, char **pp_data, int *pi_data )
00082 {
00083 int i_read;
00084
00085
00086 *pi_data = 0;
00087 *pp_data = malloc( 1025 );
00088 while( ( i_read = fread( &(*pp_data)[*pi_data], 1, 1024, f ) ) == 1024 )
00089 {
00090 *pi_data += 1024;
00091 *pp_data = realloc( *pp_data, *pi_data + 1025 );
00092 }
00093 if( i_read > 0 )
00094 {
00095 *pi_data += i_read;
00096 }
00097 (*pp_data)[*pi_data] = '\0';
00098
00099 return VLC_SUCCESS;
00100 }
00101
00102
00103 int E_(ParseDirectory)( intf_thread_t *p_intf, char *psz_root,
00104 char *psz_dir )
00105 {
00106 intf_sys_t *p_sys = p_intf->p_sys;
00107 char dir[MAX_DIR_SIZE];
00108 #ifdef HAVE_SYS_STAT_H
00109 struct stat stat_info;
00110 #endif
00111 DIR *p_dir;
00112 struct dirent *p_dir_content;
00113 vlc_acl_t *p_acl;
00114 FILE *file;
00115
00116 char *user = NULL;
00117 char *password = NULL;
00118
00119 int i_dirlen;
00120
00121 char sep;
00122
00123 #if defined( WIN32 )
00124 sep = '\\';
00125 #else
00126 sep = '/';
00127 #endif
00128
00129 #ifdef HAVE_SYS_STAT_H
00130 if( stat( psz_dir, &stat_info ) == -1 || !S_ISDIR( stat_info.st_mode ) )
00131 {
00132 return VLC_EGENERIC;
00133 }
00134 #endif
00135
00136 if( ( p_dir = opendir( psz_dir ) ) == NULL )
00137 {
00138 msg_Err( p_intf, "cannot open dir (%s)", psz_dir );
00139 return VLC_EGENERIC;
00140 }
00141
00142 i_dirlen = strlen( psz_dir );
00143 if( i_dirlen + 10 > MAX_DIR_SIZE )
00144 {
00145 msg_Warn( p_intf, "skipping too deep dir (%s)", psz_dir );
00146 return 0;
00147 }
00148
00149 msg_Dbg( p_intf, "dir=%s", psz_dir );
00150
00151 sprintf( dir, "%s%c.access", psz_dir, sep );
00152 if( ( file = fopen( dir, "r" ) ) != NULL )
00153 {
00154 char line[1024];
00155 int i_size;
00156
00157 msg_Dbg( p_intf, "find .access in dir=%s", psz_dir );
00158
00159 i_size = fread( line, 1, 1023, file );
00160 if( i_size > 0 )
00161 {
00162 char *p;
00163 while( i_size > 0 && ( line[i_size-1] == '\n' ||
00164 line[i_size-1] == '\r' ) )
00165 {
00166 i_size--;
00167 }
00168
00169 line[i_size] = '\0';
00170
00171 p = strchr( line, ':' );
00172 if( p )
00173 {
00174 *p++ = '\0';
00175 user = strdup( line );
00176 password = strdup( p );
00177 }
00178 }
00179 msg_Dbg( p_intf, "using user=%s password=%s (read=%d)",
00180 user, password, i_size );
00181
00182 fclose( file );
00183 }
00184
00185 sprintf( dir, "%s%c.hosts", psz_dir, sep );
00186 p_acl = ACL_Create( p_intf, VLC_FALSE );
00187 if( ACL_LoadFile( p_acl, dir ) )
00188 {
00189 ACL_Destroy( p_acl );
00190 p_acl = NULL;
00191 }
00192
00193 for( ;; )
00194 {
00195
00196 if( ( p_dir_content = readdir( p_dir ) ) == NULL )
00197 {
00198 break;
00199 }
00200
00201 if( ( p_dir_content->d_name[0] == '.' )
00202 || ( i_dirlen + strlen( p_dir_content->d_name ) > MAX_DIR_SIZE ) )
00203 continue;
00204
00205 sprintf( dir, "%s%c%s", psz_dir, sep, p_dir_content->d_name );
00206 if( E_(ParseDirectory)( p_intf, psz_root, dir ) )
00207 {
00208 httpd_file_sys_t *f = NULL;
00209 httpd_handler_sys_t *h = NULL;
00210 vlc_bool_t b_index;
00211 char *psz_tmp, *psz_file, *psz_name, *psz_ext;
00212
00213 psz_tmp = vlc_fix_readdir_charset( p_intf, dir );
00214 psz_file = E_(FromUTF8)( p_intf, psz_tmp );
00215 free( psz_tmp );
00216 psz_tmp = vlc_fix_readdir_charset( p_intf,
00217 &dir[strlen( psz_root )] );
00218 psz_name = E_(FileToUrl)( psz_tmp, &b_index );
00219 free( psz_tmp );
00220 psz_ext = strrchr( psz_file, '.' );
00221 if( psz_ext != NULL )
00222 {
00223 int i;
00224 psz_ext++;
00225 for( i = 0; i < p_sys->i_handlers; i++ )
00226 if( !strcmp( p_sys->pp_handlers[i]->psz_ext, psz_ext ) )
00227 break;
00228 if( i < p_sys->i_handlers )
00229 {
00230 f = malloc( sizeof( httpd_handler_sys_t ) );
00231 h = (httpd_handler_sys_t *)f;
00232 f->b_handler = VLC_TRUE;
00233 h->p_association = p_sys->pp_handlers[i];
00234 }
00235 }
00236 if( f == NULL )
00237 {
00238 f = malloc( sizeof( httpd_file_sys_t ) );
00239 f->b_handler = VLC_FALSE;
00240 }
00241
00242 f->p_intf = p_intf;
00243 f->p_file = NULL;
00244 f->p_redir = NULL;
00245 f->p_redir2 = NULL;
00246 f->file = psz_file;
00247 f->name = psz_name;
00248 f->b_html = strstr( &dir[strlen( psz_root )], ".htm" ) ? VLC_TRUE : VLC_FALSE;
00249
00250 if( !f->name )
00251 {
00252 msg_Err( p_intf , "unable to parse directory" );
00253 closedir( p_dir );
00254 free( f );
00255 return( VLC_ENOMEM );
00256 }
00257 msg_Dbg( p_intf, "file=%s (url=%s)",
00258 f->file, f->name );
00259
00260 if( !f->b_handler )
00261 {
00262 f->p_file = httpd_FileNew( p_sys->p_httpd_host,
00263 f->name,
00264 f->b_html ? p_sys->psz_html_type :
00265 NULL,
00266 user, password, p_acl,
00267 E_(HttpCallback), f );
00268 if( f->p_file != NULL )
00269 {
00270 TAB_APPEND( p_sys->i_files, p_sys->pp_files, f );
00271 }
00272 }
00273 else
00274 {
00275 h->p_handler = httpd_HandlerNew( p_sys->p_httpd_host,
00276 f->name,
00277 user, password, p_acl,
00278 E_(HandlerCallback), h );
00279 if( h->p_handler != NULL )
00280 {
00281 TAB_APPEND( p_sys->i_files, p_sys->pp_files,
00282 (httpd_file_sys_t *)h );
00283 }
00284 }
00285
00286
00287
00288
00289 if( f && f->name[strlen(f->name) - 1] == '/' )
00290 {
00291 char *psz_redir = strdup( f->name );
00292 char *p;
00293 psz_redir[strlen( psz_redir ) - 1] = '\0';
00294
00295 msg_Dbg( p_intf, "redir=%s -> %s", psz_redir, f->name );
00296 f->p_redir = httpd_RedirectNew( p_sys->p_httpd_host, f->name, psz_redir );
00297 free( psz_redir );
00298
00299 if( b_index && ( p = strstr( f->file, "index." ) ) )
00300 {
00301 asprintf( &psz_redir, "%s%s", f->name, p );
00302
00303 msg_Dbg( p_intf, "redir=%s -> %s", psz_redir, f->name );
00304 f->p_redir2 = httpd_RedirectNew( p_sys->p_httpd_host,
00305 f->name, psz_redir );
00306
00307 free( psz_redir );
00308 }
00309 }
00310 }
00311 }
00312
00313 if( user )
00314 {
00315 free( user );
00316 }
00317 if( password )
00318 {
00319 free( password );
00320 }
00321
00322 ACL_Destroy( p_acl );
00323 closedir( p_dir );
00324
00325 return VLC_SUCCESS;
00326 }
00327
00328
00329
00330
00331
00332 char *E_(FromUTF8)( intf_thread_t *p_intf, char *psz_utf8 )
00333 {
00334 intf_sys_t *p_sys = p_intf->p_sys;
00335
00336 if ( p_sys->iconv_from_utf8 != (vlc_iconv_t)-1 )
00337 {
00338 size_t i_in = strlen(psz_utf8);
00339 size_t i_out = i_in * 2;
00340 char *psz_local = malloc(i_out + 1);
00341 char *psz_out = psz_local;
00342 size_t i_ret;
00343 char psz_tmp[i_in + 1];
00344 char *psz_in = psz_tmp;
00345 uint8_t *p = (uint8_t *)psz_tmp;
00346 strcpy( psz_tmp, psz_utf8 );
00347
00348
00349
00350 while( *p )
00351 {
00352 if( p[0] == 0xe2 && p[1] == 0x80 && p[2] == 0x99 )
00353 {
00354 *p = '\'';
00355 memmove( &p[1], &p[3], strlen(&p[3]) + 1 );
00356 }
00357 if( p[0] == 0xe2 && p[1] == 0x80 && p[2] == 0x9a )
00358 {
00359 *p = '"';
00360 memmove( &p[1], &p[3], strlen(&p[3]) + 1 );
00361 }
00362 p++;
00363 }
00364 i_in = strlen( psz_tmp );
00365
00366 i_ret = vlc_iconv( p_sys->iconv_from_utf8, &psz_in, &i_in,
00367 &psz_out, &i_out );
00368 if( i_ret == (size_t)-1 || i_in )
00369 {
00370 msg_Warn( p_intf,
00371 "failed to convert \"%s\" to desired charset (%s)",
00372 psz_utf8, strerror(errno) );
00373 free( psz_local );
00374 return strdup( psz_utf8 );
00375 }
00376
00377 *psz_out = '\0';
00378 return psz_local;
00379 }
00380 else
00381 return strdup( psz_utf8 );
00382 }
00383
00384 char *E_(ToUTF8)( intf_thread_t *p_intf, char *psz_local )
00385 {
00386 intf_sys_t *p_sys = p_intf->p_sys;
00387
00388 if ( p_sys->iconv_to_utf8 != (vlc_iconv_t)-1 )
00389 {
00390 char *psz_in = psz_local;
00391 size_t i_in = strlen(psz_in);
00392 size_t i_out = i_in * 6;
00393 char *psz_utf8 = malloc(i_out + 1);
00394 char *psz_out = psz_utf8;
00395
00396 size_t i_ret = vlc_iconv( p_sys->iconv_to_utf8, &psz_in, &i_in,
00397 &psz_out, &i_out );
00398 if( i_ret == (size_t)-1 || i_in )
00399 {
00400 msg_Warn( p_intf,
00401 "failed to convert \"%s\" to desired charset (%s)",
00402 psz_local, strerror(errno) );
00403 free( psz_utf8 );
00404 return strdup( psz_local );
00405 }
00406
00407 *psz_out = '\0';
00408 return psz_utf8;
00409 }
00410 else
00411 return strdup( psz_local );
00412 }
00413
00414
00415
00416
00417 void E_(PlaylistListNode)( intf_thread_t *p_intf, playlist_t *p_pl,
00418 playlist_item_t *p_node, char *name, mvar_t *s,
00419 int i_depth )
00420 {
00421 if( p_node != NULL )
00422 {
00423 if( p_node->i_children == -1 )
00424 {
00425 char value[512];
00426 char *psz;
00427 mvar_t *itm = E_(mvar_New)( name, "set" );
00428
00429 sprintf( value, "%d", ( p_pl->status.p_item == p_node )? 1 : 0 );
00430 E_(mvar_AppendNewVar)( itm, "current", value );
00431
00432 sprintf( value, "%d", p_node->input.i_id );
00433 E_(mvar_AppendNewVar)( itm, "index", value );
00434
00435 psz = E_(FromUTF8)( p_intf, p_node->input.psz_name );
00436 E_(mvar_AppendNewVar)( itm, "name", psz );
00437 free( psz );
00438
00439 psz = E_(FromUTF8)( p_intf, p_node->input.psz_uri );
00440 E_(mvar_AppendNewVar)( itm, "uri", psz );
00441 free( psz );
00442
00443 sprintf( value, "Item");
00444 E_(mvar_AppendNewVar)( itm, "type", value );
00445
00446 sprintf( value, "%d", i_depth );
00447 E_(mvar_AppendNewVar)( itm, "depth", value );
00448
00449 E_(mvar_AppendVar)( s, itm );
00450 }
00451 else
00452 {
00453 char value[512];
00454 char *psz;
00455 int i_child;
00456 mvar_t *itm = E_(mvar_New)( name, "set" );
00457
00458 psz = E_(FromUTF8)( p_intf, p_node->input.psz_name );
00459 E_(mvar_AppendNewVar)( itm, "name", psz );
00460 E_(mvar_AppendNewVar)( itm, "uri", psz );
00461 free( psz );
00462
00463 sprintf( value, "Node" );
00464 E_(mvar_AppendNewVar)( itm, "type", value );
00465
00466 sprintf( value, "%d", p_node->input.i_id );
00467 E_(mvar_AppendNewVar)( itm, "index", value );
00468
00469 sprintf( value, "%d", p_node->i_children);
00470 E_(mvar_AppendNewVar)( itm, "i_children", value );
00471
00472 sprintf( value, "%d", i_depth );
00473 E_(mvar_AppendNewVar)( itm, "depth", value );
00474
00475 E_(mvar_AppendVar)( s, itm );
00476
00477 for (i_child = 0 ; i_child < p_node->i_children ; i_child++)
00478 E_(PlaylistListNode)( p_intf, p_pl,
00479 p_node->pp_children[i_child],
00480 name, s, i_depth + 1);
00481
00482 }
00483 }
00484 }
00485
00486
00487
00488
00489 void E_(HandleSeek)( intf_thread_t *p_intf, char *p_value )
00490 {
00491 intf_sys_t *p_sys = p_intf->p_sys;
00492 vlc_value_t val;
00493 int i_stock = 0;
00494 uint64_t i_length;
00495 int i_value = 0;
00496 int i_relative = 0;
00497 #define POSITION_ABSOLUTE 12
00498 #define POSITION_REL_FOR 13
00499 #define POSITION_REL_BACK 11
00500 #define VL_TIME_ABSOLUTE 0
00501 #define VL_TIME_REL_FOR 1
00502 #define VL_TIME_REL_BACK -1
00503 if( p_sys->p_input )
00504 {
00505 var_Get( p_sys->p_input, "length", &val );
00506 i_length = val.i_time;
00507
00508 while( p_value[0] != '\0' )
00509 {
00510 switch(p_value[0])
00511 {
00512 case '+':
00513 {
00514 i_relative = VL_TIME_REL_FOR;
00515 p_value++;
00516 break;
00517 }
00518 case '-':
00519 {
00520 i_relative = VL_TIME_REL_BACK;
00521 p_value++;
00522 break;
00523 }
00524 case '0': case '1': case '2': case '3': case '4':
00525 case '5': case '6': case '7': case '8': case '9':
00526 {
00527 i_stock = strtol( p_value , &p_value , 10 );
00528 break;
00529 }
00530 case '%':
00531 {
00532 i_relative += POSITION_ABSOLUTE;
00533 i_value = i_stock;
00534 i_stock = 0;
00535 p_value[0] = '\0';
00536 break;
00537 }
00538 case ':':
00539 {
00540 i_value = 60 * (i_value + i_stock) ;
00541 i_stock = 0;
00542 p_value++;
00543 break;
00544 }
00545 case 'h': case 'H':
00546 {
00547 i_value += 3600 * i_stock;
00548 i_stock = 0;
00549
00550 while( ((p_value[0] < '0') || (p_value[0] > '9')) && (p_value[0] != '\0') )
00551 {
00552 p_value++;
00553 }
00554 break;
00555 }
00556 case 'm': case 'M': case '\'':
00557 {
00558 i_value += 60 * i_stock;
00559 i_stock = 0;
00560 p_value++;
00561 while( ((p_value[0] < '0') || (p_value[0] > '9')) && (p_value[0] != '\0') )
00562 {
00563 p_value++;
00564 }
00565 break;
00566 }
00567 case 's': case 'S': case '"':
00568 {
00569 i_value += i_stock;
00570 i_stock = 0;
00571 while( ((p_value[0] < '0') || (p_value[0] > '9')) && (p_value[0] != '\0') )
00572 {
00573 p_value++;
00574 }
00575 break;
00576 }
00577 default:
00578 {
00579 p_value++;
00580 break;
00581 }
00582 }
00583 }
00584
00585
00586 i_value += i_stock;
00587
00588 switch(i_relative)
00589 {
00590 case VL_TIME_ABSOLUTE:
00591 {
00592 if( (uint64_t)( i_value ) * 1000000 <= i_length )
00593 val.i_time = (uint64_t)( i_value ) * 1000000;
00594 else
00595 val.i_time = i_length;
00596
00597 var_Set( p_sys->p_input, "time", val );
00598 msg_Dbg( p_intf, "requested seek position: %dsec", i_value );
00599 break;
00600 }
00601 case VL_TIME_REL_FOR:
00602 {
00603 var_Get( p_sys->p_input, "time", &val );
00604 if( (uint64_t)( i_value ) * 1000000 + val.i_time <= i_length )
00605 {
00606 val.i_time = ((uint64_t)( i_value ) * 1000000) + val.i_time;
00607 } else
00608 {
00609 val.i_time = i_length;
00610 }
00611 var_Set( p_sys->p_input, "time", val );
00612 msg_Dbg( p_intf, "requested seek position forward: %dsec", i_value );
00613 break;
00614 }
00615 case VL_TIME_REL_BACK:
00616 {
00617 var_Get( p_sys->p_input, "time", &val );
00618 if( (int64_t)( i_value ) * 1000000 > val.i_time )
00619 {
00620 val.i_time = 0;
00621 } else
00622 {
00623 val.i_time = val.i_time - ((uint64_t)( i_value ) * 1000000);
00624 }
00625 var_Set( p_sys->p_input, "time", val );
00626 msg_Dbg( p_intf, "requested seek position backward: %dsec", i_value );
00627 break;
00628 }
00629 case POSITION_ABSOLUTE:
00630 {
00631 val.f_float = __MIN( __MAX( ((float) i_value ) / 100.0 , 0.0 ) , 100.0 );
00632 var_Set( p_sys->p_input, "position", val );
00633 msg_Dbg( p_intf, "requested seek percent: %d", i_value );
00634 break;
00635 }
00636 case POSITION_REL_FOR:
00637 {
00638 var_Get( p_sys->p_input, "position", &val );
00639 val.f_float += __MIN( __MAX( ((float) i_value ) / 100.0 , 0.0 ) , 100.0 );
00640 var_Set( p_sys->p_input, "position", val );
00641 msg_Dbg( p_intf, "requested seek percent forward: %d", i_value );
00642 break;
00643 }
00644 case POSITION_REL_BACK:
00645 {
00646 var_Get( p_sys->p_input, "position", &val );
00647 val.f_float -= __MIN( __MAX( ((float) i_value ) / 100.0 , 0.0 ) , 100.0 );
00648 var_Set( p_sys->p_input, "position", val );
00649 msg_Dbg( p_intf, "requested seek percent backward: %d", i_value );
00650 break;
00651 }
00652 default:
00653 {
00654 msg_Dbg( p_intf, "requested seek: what the f*** is going on here ?" );
00655 break;
00656 }
00657 }
00658 }
00659 #undef POSITION_ABSOLUTE
00660 #undef POSITION_REL_FOR
00661 #undef POSITION_REL_BACK
00662 #undef VL_TIME_ABSOLUTE
00663 #undef VL_TIME_REL_FOR
00664 #undef VL_TIME_REL_BACK
00665 }
00666
00667
00668
00669
00670
00671 int E_(TestURIParam)( char *psz_uri, const char *psz_name )
00672 {
00673 char *p = psz_uri;
00674
00675 while( (p = strstr( p, psz_name )) )
00676 {
00677
00678 if( (p == psz_uri || *(p - 1) == '&' || *(p - 1) == '\n')
00679 && p[strlen(psz_name)] == '=' )
00680 {
00681 return VLC_TRUE;
00682 }
00683 p++;
00684 }
00685
00686 return VLC_FALSE;
00687 }
00688 char *E_(ExtractURIValue)( char *psz_uri, const char *psz_name,
00689 char *psz_value, int i_value_max )
00690 {
00691 char *p = psz_uri;
00692
00693 while( (p = strstr( p, psz_name )) )
00694 {
00695
00696 if( (p == psz_uri || *(p - 1) == '&' || *(p - 1) == '\n')
00697 && p[strlen(psz_name)] == '=' )
00698 break;
00699 p++;
00700 }
00701
00702 if( p )
00703 {
00704 int i_len;
00705
00706 p += strlen( psz_name );
00707 if( *p == '=' ) p++;
00708
00709 if( strchr( p, '&' ) )
00710 {
00711 i_len = strchr( p, '&' ) - p;
00712 }
00713 else
00714 {
00715
00716 if( strchr( p, '\n' ) )
00717 {
00718 i_len = strchr( p, '\n' ) - p;
00719 if( i_len && *(p+i_len-1) == '\r' ) i_len--;
00720 }
00721 else
00722 {
00723 i_len = strlen( p );
00724 }
00725 }
00726 i_len = __MIN( i_value_max - 1, i_len );
00727 if( i_len > 0 )
00728 {
00729 strncpy( psz_value, p, i_len );
00730 psz_value[i_len] = '\0';
00731 }
00732 else
00733 {
00734 strncpy( psz_value, "", i_value_max );
00735 }
00736 p += i_len;
00737 }
00738 else
00739 {
00740 strncpy( psz_value, "", i_value_max );
00741 }
00742
00743 return p;
00744 }
00745
00746 void E_(DecodeEncodedURI)( char *psz )
00747 {
00748 char *dup = strdup( psz );
00749 char *p = dup;
00750
00751 while( *p )
00752 {
00753 if( *p == '%' )
00754 {
00755 char val[3];
00756 p++;
00757 if( !*p )
00758 {
00759 break;
00760 }
00761
00762 val[0] = *p++;
00763 val[1] = *p++;
00764 val[2] = '\0';
00765
00766 *psz++ = strtol( val, NULL, 16 );
00767 }
00768 else if( *p == '+' )
00769 {
00770 *psz++ = ' ';
00771 p++;
00772 }
00773 else
00774 {
00775 *psz++ = *p++;
00776 }
00777 }
00778 *psz++ = '\0';
00779 free( dup );
00780 }
00781
00782
00783
00784
00785 char *E_(FirstWord)( char *psz, char *new )
00786 {
00787 vlc_bool_t b_end;
00788
00789 while( *psz == ' ' )
00790 psz++;
00791
00792 while( *psz != '\0' && *psz != ' ' )
00793 {
00794 if( *psz == '\'' )
00795 {
00796 char c = *psz++;
00797 while( *psz != '\0' && *psz != c )
00798 {
00799 if( *psz == '\\' && psz[1] != '\0' )
00800 psz++;
00801 *new++ = *psz++;
00802 }
00803 if( *psz == c )
00804 psz++;
00805 }
00806 else
00807 {
00808 if( *psz == '\\' && psz[1] != '\0' )
00809 psz++;
00810 *new++ = *psz++;
00811 }
00812 }
00813 b_end = !*psz;
00814
00815 *new++ = '\0';
00816 if( !b_end )
00817 return psz + 1;
00818 else
00819 return NULL;
00820 }
00821
00822
00823
00824
00825
00826
00827
00828 static char *Find_end_MRL( char *psz )
00829 {
00830 char *s_sent = psz;
00831
00832 switch( *s_sent )
00833 {
00834 case '\"':
00835 {
00836 s_sent++;
00837
00838 while( ( *s_sent != '\"' ) && ( *s_sent != '\0' ) )
00839 {
00840 if( *s_sent == '\'' )
00841 {
00842 s_sent = Find_end_MRL( s_sent );
00843
00844 if( s_sent == NULL )
00845 {
00846 return NULL;
00847 }
00848 } else
00849 {
00850 s_sent++;
00851 }
00852 }
00853
00854 if( *s_sent == '\"' )
00855 {
00856 s_sent++;
00857 return s_sent;
00858 } else
00859 {
00860 return NULL;
00861 }
00862 break;
00863 }
00864 case '\'':
00865 {
00866 s_sent++;
00867
00868 while( ( *s_sent != '\'' ) && ( *s_sent != '\0' ) )
00869 {
00870 if( *s_sent == '\"' )
00871 {
00872 s_sent = Find_end_MRL( s_sent );
00873
00874 if( s_sent == NULL )
00875 {
00876 return NULL;
00877 }
00878 } else
00879 {
00880 s_sent++;
00881 }
00882 }
00883
00884 if( *s_sent == '\'' )
00885 {
00886 s_sent++;
00887 return s_sent;
00888 } else
00889 {
00890 return NULL;
00891 }
00892 break;
00893 }
00894 default:
00895 {
00896 while( ( *s_sent != ' ' ) && ( *s_sent != '\0' ) )
00897 {
00898 if( ( *s_sent == '\'' ) || ( *s_sent == '\"' ) )
00899 {
00900 s_sent = Find_end_MRL( s_sent );
00901 } else
00902 {
00903 s_sent++;
00904 }
00905 }
00906 return s_sent;
00907 }
00908 }
00909 }
00910
00911
00912
00913
00914
00915 playlist_item_t *E_(MRLParse)( intf_thread_t *p_intf, char *psz,
00916 char *psz_name )
00917 {
00918 char **ppsz_options = NULL;
00919 char *mrl;
00920 char *s_mrl = psz;
00921 int i_error = 0;
00922 char *s_temp;
00923 int i = 0;
00924 int i_options = 0;
00925 playlist_item_t * p_item = NULL;
00926
00927
00928 while( ( *s_mrl == ' ' ) && ( *s_mrl != '\0' ) )
00929 {
00930 s_mrl++;
00931 }
00932
00933
00934 s_temp = strstr( s_mrl , " :" );
00935 if( s_temp == NULL )
00936 {
00937 s_temp = s_mrl + strlen( s_mrl );
00938 } else
00939 {
00940 while( (*s_temp == ' ') && (s_temp != s_mrl ) )
00941 {
00942 s_temp--;
00943 }
00944 s_temp++;
00945 }
00946
00947
00948 if( (*s_mrl == '\'') || (*s_mrl == '\"') )
00949 {
00950 mrl = (char *)malloc( (s_temp - s_mrl - 1) * sizeof( char ) );
00951 strncpy( mrl , (s_mrl + 1) , s_temp - s_mrl - 2 );
00952 mrl[ s_temp - s_mrl - 2 ] = '\0';
00953 } else
00954 {
00955 mrl = (char *)malloc( (s_temp - s_mrl + 1) * sizeof( char ) );
00956 strncpy( mrl , s_mrl , s_temp - s_mrl );
00957 mrl[ s_temp - s_mrl ] = '\0';
00958 }
00959
00960 s_mrl = s_temp;
00961
00962
00963 while( (*s_mrl != '\0') && (i_error == 0) )
00964 {
00965 switch( *s_mrl )
00966 {
00967 case ' ':
00968 {
00969 s_mrl++;
00970 break;
00971 }
00972 case ':':
00973 {
00974 s_temp = Find_end_MRL( s_mrl );
00975
00976 if( s_temp == NULL )
00977 {
00978 i_error = 1;
00979 }
00980 else
00981 {
00982 i_options++;
00983 ppsz_options = realloc( ppsz_options , i_options *
00984 sizeof(char *) );
00985 ppsz_options[ i_options - 1 ] =
00986 malloc( (s_temp - s_mrl + 1) * sizeof(char) );
00987
00988 strncpy( ppsz_options[ i_options - 1 ] , s_mrl ,
00989 s_temp - s_mrl );
00990
00991
00992 (ppsz_options[ i_options - 1 ])[ s_temp - s_mrl ] = '\0';
00993
00994 s_mrl = s_temp;
00995 }
00996 break;
00997 }
00998 default:
00999 {
01000 i_error = 1;
01001 break;
01002 }
01003 }
01004 }
01005
01006 if( i_error != 0 )
01007 {
01008 free( mrl );
01009 }
01010 else
01011 {
01012
01013 p_item = playlist_ItemNew( p_intf, mrl, psz_name );
01014 for( i = 0 ; i< i_options ; i++ )
01015 {
01016 playlist_ItemAddOption( p_item, ppsz_options[i] );
01017 }
01018 }
01019
01020 for( i = 0; i < i_options; i++ ) free( ppsz_options[i] );
01021 if( i_options ) free( ppsz_options );
01022
01023 return p_item;
01024 }
01025
01026
01027
01028 char *E_(RealPath)( intf_thread_t *p_intf, const char *psz_src )
01029 {
01030 char *psz_dir;
01031 char *p;
01032 int i_len = strlen(psz_src);
01033 char sep;
01034
01035 #if defined( WIN32 )
01036 sep = '\\';
01037 #else
01038 sep = '/';
01039 #endif
01040
01041 psz_dir = malloc( i_len + 2 );
01042 strcpy( psz_dir, psz_src );
01043
01044
01045 psz_dir[i_len] = sep;
01046 psz_dir[i_len + 1] = '\0';
01047
01048 #ifdef WIN32
01049
01050 p = psz_dir;
01051 while( (p = strchr( p, '/' )) != NULL )
01052 {
01053 *p = sep;
01054 }
01055 #endif
01056
01057
01058 p = psz_dir;
01059 while( (p = strchr( p, sep )) != NULL )
01060 {
01061 if( p[1] == sep )
01062 memmove( &p[1], &p[2], strlen(&p[2]) + 1 );
01063 else if( p[1] == '.' && p[2] == sep )
01064 memmove( &p[1], &p[3], strlen(&p[3]) + 1 );
01065 else
01066 p++;
01067 }
01068
01069 if( psz_dir[0] == '~' )
01070 {
01071 char *dir = malloc( strlen(psz_dir)
01072 + strlen(p_intf->p_vlc->psz_userdir) );
01073
01074 sprintf( dir, "%s%s", p_intf->p_vlc->psz_userdir, psz_dir + 1 );
01075 free( psz_dir );
01076 psz_dir = dir;
01077 }
01078
01079 if( strlen(psz_dir) > 2 )
01080 {
01081
01082 p = psz_dir + 3;
01083 while( (p = strchr( p, sep )) != NULL )
01084 {
01085 if( p[-1] == '.' && p[-2] == '.' && p[-3] == sep )
01086 {
01087 char *q;
01088 p[-3] = '\0';
01089 if( (q = strrchr( psz_dir, sep )) != NULL )
01090 {
01091 memmove( q + 1, p + 1, strlen(p + 1) + 1 );
01092 p = q + 1;
01093 }
01094 else
01095 {
01096 memmove( psz_dir, p, strlen(p) + 1 );
01097 p = psz_dir + 3;
01098 }
01099 }
01100 else
01101 p++;
01102 }
01103 }
01104
01105
01106
01107 p = strrchr( psz_dir, sep );
01108 if( p != NULL && p[1] == '\0' && p != strchr( psz_dir, sep ) )
01109 *p = '\0';
01110
01111 return psz_dir;
01112 }