Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

mvar.c

00001 /*****************************************************************************
00002  * mvar.c : Variables handling for the HTTP Interface
00003  *****************************************************************************
00004  * Copyright (C) 2001-2005 the VideoLAN team
00005  * $Id: http.c 12225 2005-08-18 10:01:30Z massiot $
00006  *
00007  * Authors: Gildas Bazin <[email protected]>
00008  *          Laurent Aimar <[email protected]>
00009  *          Christophe Massiot <[email protected]>
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00024  *****************************************************************************/
00025 
00026 #include "http.h"
00027 
00028 /* Utility function for scandir */
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     /* FIXME should do a realloc */
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     /* format: name[index].field */
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 /* arg= start[:stop[:step]],.. */
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  * Special sets handling
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 ); /* FIXME */
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     /* Check the type of the object variable */
00368     i_type = var_Type( p_sys->p_input, psz_variable );
00369 
00370     /* Make sure we want to display the variable */
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         /* Variable doesn't exist or isn't handled */
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     /* clean up everything */
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                 /* fprintf( stderr," mvar_HttpdInfoSetNew: append name=`%s' value=`%s'\n",
00472                             info.info[i].psz_name, info.info[i].psz_value ); */
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     /* free mem */
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     /* convert all / to native separator */
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     /* parse psz_src dir */
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         /* put file extension in 'ext' */
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             /* FIXME memory leak FIXME */
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         /* Over media, schedule */
00654         vlm_message_t *ch = msg->child[i];
00655         int j;
00656 
00657         for( j = 0; j < ch->i_child; j++ )
00658         {
00659             /* Over name */
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             /* Add a node with name and info */
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 }

Generated on Tue Dec 20 10:14:30 2005 for vlc-0.8.4a by  doxygen 1.4.2