Commit 16f32e15 authored by Antoine Cellerier's avatar Antoine Cellerier

On OSes other than Windows, Mac OS X and BeOS (so it's Linux) comply with the...

On OSes other than Windows, Mac OS X and BeOS (so it's Linux) comply with the XDG Base Directory Specification version 0.6. The old configuration file (vlcrc) will be copied to the new location. Other data like caches will have to be rebuilt (the album art cache in VLC was new in 0.9.0 so it's ok to lose it). Closes #1267
parent e8f97c66
...@@ -112,6 +112,11 @@ Interfaces: ...@@ -112,6 +112,11 @@ Interfaces:
finished: http://wiki.xmms2.xmms.se/index.php/Media_Player_Interfaces . finished: http://wiki.xmms2.xmms.se/index.php/Media_Player_Interfaces .
* Motion module use disk accelerometers to keep video horizontal * Motion module use disk accelerometers to keep video horizontal
Linux Port:
* VLC now complies with the XDG Base Directory Specification version 0.6
http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
(which means that VLC doesn't use the $HOME/.vlc directory anymore)
Capture: Capture:
* new BDA device driver plugin for DVB-C/S/T capture cards on Microsoft * new BDA device driver plugin for DVB-C/S/T capture cards on Microsoft
Windows Windows
......
...@@ -38,8 +38,11 @@ struct libvlc_int_t ...@@ -38,8 +38,11 @@ struct libvlc_int_t
/* Global properties */ /* Global properties */
int i_argc; ///< command line arguments count int i_argc; ///< command line arguments count
char ** ppsz_argv; ///< command line arguments char ** ppsz_argv; ///< command line arguments
char * psz_homedir; ///< configuration directory
char * psz_userdir; ///< user's home directory char * psz_homedir; ///< user's home directory
char * psz_configdir; ///< user's configuration directory
char * psz_datadir; ///< user's data/cache directory
char * psz_configfile; ///< location of config file char * psz_configfile; ///< location of config file
playlist_t *p_playlist; ///< playlist object playlist_t *p_playlist; ///< playlist object
......
...@@ -48,19 +48,6 @@ ...@@ -48,19 +48,6 @@
* outputting an error message (in second) */ * outputting an error message (in second) */
#define THREAD_COND_TIMEOUT 1 #define THREAD_COND_TIMEOUT 1
/* The configuration file and directory */
#if defined (SYS_BEOS)
# define CONFIG_DIR "config/settings/VideoLAN Client"
#elif defined (__APPLE__)
# define CONFIG_DIR "Library/Preferences/VLC"
#elif defined( WIN32 ) || defined( UNDER_CE )
# define CONFIG_DIR "vlc"
#else
# define CONFIG_DIR ".vlc"
#endif
#define CONFIG_FILE "vlcrc"
#define PLUGINSCACHE_DIR "cache"
/***************************************************************************** /*****************************************************************************
* Interface configuration * Interface configuration
*****************************************************************************/ *****************************************************************************/
......
...@@ -148,7 +148,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -148,7 +148,7 @@ static int Open( vlc_object_t *p_this )
if( *psz == '\0' ) if( *psz == '\0' )
{ {
free( psz ); free( psz );
if( p_access->p_libvlc->psz_homedir ) if( p_access->p_libvlc->psz_homedir ) /* XXX: This should never happen */
psz = strdup( p_access->p_libvlc->psz_homedir ); psz = strdup( p_access->p_libvlc->psz_homedir );
} }
p_sys->psz_path = psz; p_sys->psz_path = psz;
......
...@@ -989,7 +989,7 @@ char *E_(RealPath)( intf_thread_t *p_intf, const char *psz_src ) ...@@ -989,7 +989,7 @@ char *E_(RealPath)( intf_thread_t *p_intf, const char *psz_src )
{ {
char *dir; char *dir;
/* This is incomplete : we should also support the ~cmassiot/ syntax. */ /* This is incomplete : we should also support the ~cmassiot/ syntax. */
asprintf( &dir, "%s%s", p_intf->p_libvlc->psz_userdir, psz_dir + 1 ); asprintf( &dir, "%s%s", p_intf->p_libvlc->psz_homedir, psz_dir + 1 );
free( psz_dir ); free( psz_dir );
psz_dir = dir; psz_dir = dir;
} }
......
...@@ -225,9 +225,9 @@ bool Win32Factory::init() ...@@ -225,9 +225,9 @@ bool Win32Factory::init()
} }
// Initialize the resource path // Initialize the resource path
m_resourcePath.push_back( (string)getIntf()->p_libvlc->psz_homedir + m_resourcePath.push_back( (string)getIntf()->p_libvlc->psz_datadir +
"\\" + CONFIG_DIR + "\\skins" ); "\\skins" );
m_resourcePath.push_back( (string)config_GetDataDir() + m_resourcePath.push_back( (dstring)config_GetDataDir() +
"\\skins" ); "\\skins" );
m_resourcePath.push_back( (string)config_GetDataDir() + m_resourcePath.push_back( (string)config_GetDataDir() +
"\\skins2" ); "\\skins2" );
......
...@@ -71,8 +71,8 @@ bool X11Factory::init() ...@@ -71,8 +71,8 @@ bool X11Factory::init()
ConnectionNumber( pDisplay ) ); ConnectionNumber( pDisplay ) );
// Initialize the resource path // Initialize the resource path
m_resourcePath.push_back( (string)getIntf()->p_libvlc->psz_homedir + m_resourcePath.push_back( (string)getIntf()->p_libvlc->psz_datadir +
m_dirSep + CONFIG_DIR + "/skins2" ); + "/skins2" );
m_resourcePath.push_back( (string)"share/skins2" ); m_resourcePath.push_back( (string)"share/skins2" );
m_resourcePath.push_back( (string)DATA_PATH + "/skins2" ); m_resourcePath.push_back( (string)DATA_PATH + "/skins2" );
......
...@@ -702,11 +702,11 @@ gnutls_ClientCreate( tls_t *p_tls ) ...@@ -702,11 +702,11 @@ gnutls_ClientCreate( tls_t *p_tls )
vlc_object_attach( p_session, p_tls ); vlc_object_attach( p_session, p_tls );
const char *homedir = p_tls->p_libvlc->psz_homedir, const char *homedir = p_tls->p_libvlc->psz_datadir,
*datadir = config_GetDataDir (); *datadir = config_GetDataDir ();
size_t l1 = strlen (homedir), l2 = strlen (datadir); size_t l1 = strlen (homedir), l2 = strlen (datadir);
char path[((l1 > l2) ? l1 : l2) + sizeof ("/"CONFIG_DIR"/ssl/private")]; char path[((l1 > l2) ? l1 : l2) + sizeof ("/ssl/private")];
// > sizeof ("/"CONFIG_DIR"/ssl/certs") // > sizeof ("/ssl/certs")
// > sizeof ("/ca-certificates.crt") // > sizeof ("/ca-certificates.crt")
i_val = gnutls_certificate_allocate_credentials( &p_sys->x509_cred ); i_val = gnutls_certificate_allocate_credentials( &p_sys->x509_cred );
...@@ -719,7 +719,7 @@ gnutls_ClientCreate( tls_t *p_tls ) ...@@ -719,7 +719,7 @@ gnutls_ClientCreate( tls_t *p_tls )
if (var_CreateGetBool (p_tls, "tls-check-cert")) if (var_CreateGetBool (p_tls, "tls-check-cert"))
{ {
sprintf (path, "%s/"CONFIG_DIR"/ssl/certs", homedir); sprintf (path, "%s/ssl/certs", homedir);
gnutls_Addx509Directory ((vlc_object_t *)p_session, gnutls_Addx509Directory ((vlc_object_t *)p_session,
p_sys->x509_cred, path, VLC_FALSE); p_sys->x509_cred, path, VLC_FALSE);
...@@ -731,7 +731,7 @@ gnutls_ClientCreate( tls_t *p_tls ) ...@@ -731,7 +731,7 @@ gnutls_ClientCreate( tls_t *p_tls )
else else
p_session->pf_handshake2 = gnutls_ContinueHandshake; p_session->pf_handshake2 = gnutls_ContinueHandshake;
sprintf (path, "%s/"CONFIG_DIR"/ssl/private", homedir); sprintf (path, "%s/ssl/private", homedir);
gnutls_Addx509Directory ((vlc_object_t *)p_session, p_sys->x509_cred, gnutls_Addx509Directory ((vlc_object_t *)p_session, p_sys->x509_cred,
path, VLC_TRUE); path, VLC_TRUE);
......
...@@ -201,7 +201,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -201,7 +201,7 @@ static int Open( vlc_object_t *p_this )
#ifdef __APPLE__ #ifdef __APPLE__
char *psz_homedir = p_this->p_libvlc->psz_homedir; char *psz_homedir = p_this->p_libvlc->psz_homedir;
if( !psz_homedir ) if( !psz_homedir ) /* XXX: This should never happen */
{ {
msg_Err( p_this, "unable to find home directory" ); msg_Err( p_this, "unable to find home directory" );
return -1; return -1;
......
...@@ -245,8 +245,8 @@ int vlclua_scripts_batch_execute( vlc_object_t *p_this, ...@@ -245,8 +245,8 @@ int vlclua_scripts_batch_execute( vlc_object_t *p_this,
char *ppsz_dir_list[] = { NULL, NULL, NULL, NULL }; char *ppsz_dir_list[] = { NULL, NULL, NULL, NULL };
char **ppsz_dir; char **ppsz_dir;
if( asprintf( &ppsz_dir_list[0], "%s" DIR_SEP CONFIG_DIR DIR_SEP "%s", p_this->p_libvlc->psz_homedir, if( asprintf( &ppsz_dir_list[0], "%s" DIR_SEP "%s",
luadirname ) < 0 ) p_this->p_libvlc->psz_datadir, luadirname ) < 0 )
return VLC_ENOMEM; return VLC_ENOMEM;
# if defined(__APPLE__) || defined(SYS_BEOS) || defined(WIN32) # if defined(__APPLE__) || defined(SYS_BEOS) || defined(WIN32)
......
...@@ -88,17 +88,17 @@ void ...@@ -88,17 +88,17 @@ void
libvlc_media_library_load( libvlc_media_library_t * p_mlib, libvlc_media_library_load( libvlc_media_library_t * p_mlib,
libvlc_exception_t * p_e ) libvlc_exception_t * p_e )
{ {
const char *psz_homedir = p_mlib->p_libvlc_instance->p_libvlc_int->psz_homedir; const char *psz_datadir = p_mlib->p_libvlc_instance->p_libvlc_int->psz_datadir;
char * psz_uri; char * psz_uri;
if( !psz_homedir ) if( !psz_datadir ) /* XXX: i doubt that this can ever happen */
{ {
libvlc_exception_raise( p_e, "Can't get HOME DIR" ); libvlc_exception_raise( p_e, "Can't get data directory" );
return; return;
} }
if( asprintf( &psz_uri, "file/xspf-open://%s" DIR_SEP CONFIG_DIR DIR_SEP if( asprintf( &psz_uri, "file/xspf-open://%s" DIR_SEP "ml.xsp",
"ml.xsp", psz_homedir ) == -1 ) psz_datadir ) == -1 )
{ {
libvlc_exception_raise( p_e, "Can't get create the path" ); libvlc_exception_raise( p_e, "Can't get create the path" );
return; return;
......
...@@ -273,9 +273,9 @@ static void __ArtCacheGetDirPath( vlc_object_t *p_obj, ...@@ -273,9 +273,9 @@ static void __ArtCacheGetDirPath( vlc_object_t *p_obj,
char * psz_album_sanitized = ArtCacheGetSanitizedFileName( psz_album ); char * psz_album_sanitized = ArtCacheGetSanitizedFileName( psz_album );
char * psz_artist_sanitized = ArtCacheGetSanitizedFileName( psz_artist ); char * psz_artist_sanitized = ArtCacheGetSanitizedFileName( psz_artist );
snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP CONFIG_DIR DIR_SEP snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP
"art" DIR_SEP "artistalbum" DIR_SEP "%s" DIR_SEP "%s", "art" DIR_SEP "artistalbum" DIR_SEP "%s" DIR_SEP "%s",
p_obj->p_libvlc->psz_homedir, p_obj->p_libvlc->psz_datadir,
psz_artist_sanitized, psz_album_sanitized ); psz_artist_sanitized, psz_album_sanitized );
free( psz_album_sanitized ); free( psz_album_sanitized );
free( psz_artist_sanitized ); free( psz_artist_sanitized );
...@@ -283,9 +283,9 @@ static void __ArtCacheGetDirPath( vlc_object_t *p_obj, ...@@ -283,9 +283,9 @@ static void __ArtCacheGetDirPath( vlc_object_t *p_obj,
else else
{ {
char * psz_title_sanitized = ArtCacheGetSanitizedFileName( psz_title ); char * psz_title_sanitized = ArtCacheGetSanitizedFileName( psz_title );
snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP CONFIG_DIR DIR_SEP snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP
"art" DIR_SEP "title" DIR_SEP "%s", "art" DIR_SEP "title" DIR_SEP "%s",
p_obj->p_libvlc->psz_homedir, p_obj->p_libvlc->psz_datadir,
psz_title_sanitized ); psz_title_sanitized );
free( psz_title_sanitized ); free( psz_title_sanitized );
} }
......
...@@ -325,25 +325,10 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] ) ...@@ -325,25 +325,10 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] )
} }
/* Set the config file stuff */ /* Set the config file stuff */
p_libvlc->psz_homedir = config_GetHomeDir(); p_libvlc->psz_homedir = config_GetHomeDir();
p_libvlc->psz_userdir = config_GetUserDir(); p_libvlc->psz_configdir = config_GetConfigDir( p_libvlc );
if( p_libvlc->psz_userdir == NULL ) p_libvlc->psz_datadir = config_GetUserDataDir( p_libvlc );
p_libvlc->psz_userdir = strdup(p_libvlc->psz_homedir); p_libvlc->psz_configfile = config_GetCustomConfigFile( p_libvlc );
p_libvlc->psz_configfile = config_GetPsz( p_libvlc, "config" );
if( (p_libvlc->psz_configfile != NULL) && (p_libvlc->psz_configfile[0] == '~')
&& (p_libvlc->psz_configfile[1] == '/') )
{
char *psz = malloc( strlen(p_libvlc->psz_userdir)
+ strlen(p_libvlc->psz_configfile) );
if( psz )
{
/* This is incomplete : we should also support the ~cmassiot/ syntax. */
sprintf( psz, "%s/%s", p_libvlc->psz_userdir,
p_libvlc->psz_configfile + 2 );
free( p_libvlc->psz_configfile );
p_libvlc->psz_configfile = psz;
} /* else keep old config stuff */
}
/* Check for plugins cache options */ /* Check for plugins cache options */
if( config_GetInt( p_libvlc, "reset-plugins-cache" ) ) if( config_GetInt( p_libvlc, "reset-plugins-cache" ) )
...@@ -1067,7 +1052,8 @@ int libvlc_InternalDestroy( libvlc_int_t *p_libvlc, vlc_bool_t b_release ) ...@@ -1067,7 +1052,8 @@ int libvlc_InternalDestroy( libvlc_int_t *p_libvlc, vlc_bool_t b_release )
module_EndBank( p_libvlc ); module_EndBank( p_libvlc );
FREENULL( p_libvlc->psz_homedir ); FREENULL( p_libvlc->psz_homedir );
FREENULL( p_libvlc->psz_userdir ); FREENULL( p_libvlc->psz_configdir );
FREENULL( p_libvlc->psz_datadir );
FREENULL( p_libvlc->psz_configfile ); FREENULL( p_libvlc->psz_configfile );
FREENULL( p_libvlc->p_hotkeys ); FREENULL( p_libvlc->p_hotkeys );
......
...@@ -84,7 +84,7 @@ static inline char *_strdupnull (const char *src) ...@@ -84,7 +84,7 @@ static inline char *_strdupnull (const char *src)
/* Item types that use a string value (i.e. serialized in the module cache) */ /* Item types that use a string value (i.e. serialized in the module cache) */
int IsConfigStringType (int type) int IsConfigStringType (int type)
{ {
static const unsigned char config_types[] = static const unsigned char config_types[] =
{ {
CONFIG_ITEM_STRING, CONFIG_ITEM_FILE, CONFIG_ITEM_MODULE, CONFIG_ITEM_STRING, CONFIG_ITEM_FILE, CONFIG_ITEM_MODULE,
CONFIG_ITEM_DIRECTORY, CONFIG_ITEM_MODULE_CAT, CONFIG_ITEM_PASSWORD, CONFIG_ITEM_DIRECTORY, CONFIG_ITEM_MODULE_CAT, CONFIG_ITEM_PASSWORD,
...@@ -98,7 +98,7 @@ int IsConfigStringType (int type) ...@@ -98,7 +98,7 @@ int IsConfigStringType (int type)
static int IsConfigIntegerType (int type) static int IsConfigIntegerType (int type)
{ {
static const unsigned char config_types[] = static const unsigned char config_types[] =
{ {
CONFIG_ITEM_INTEGER, CONFIG_ITEM_KEY, CONFIG_ITEM_BOOL, CONFIG_ITEM_INTEGER, CONFIG_ITEM_KEY, CONFIG_ITEM_BOOL,
CONFIG_CATEGORY, CONFIG_SUBCATEGORY CONFIG_CATEGORY, CONFIG_SUBCATEGORY
...@@ -786,34 +786,67 @@ void __config_ResetAll( vlc_object_t *p_this ) ...@@ -786,34 +786,67 @@ void __config_ResetAll( vlc_object_t *p_this )
static FILE *config_OpenConfigFile( vlc_object_t *p_obj, const char *mode ) static FILE *config_OpenConfigFile( vlc_object_t *p_obj, const char *mode )
{ {
static const char psz_subpath[] = DIR_SEP CONFIG_DIR DIR_SEP CONFIG_FILE; char *psz_filename = p_obj->p_libvlc->psz_configfile;
const char *psz_filename = p_obj->p_libvlc->psz_configfile;
const char *psz_homedir = p_obj->p_libvlc->psz_homedir;
size_t i_buflen = 0;
FILE *p_stream; FILE *p_stream;
if( psz_filename == NULL ) if( !psz_filename )
{ {
if( psz_homedir == NULL ) psz_filename = config_GetConfigFile( p_obj->p_libvlc );
{
msg_Err( p_obj, "no home directory defined" );
return NULL;
}
i_buflen = strlen(psz_homedir) + sizeof(psz_subpath) + 1;
}
char buf[i_buflen];
if( psz_filename == NULL )
{
sprintf( buf, "%s%s", psz_homedir, psz_subpath );
psz_filename = buf;
} }
msg_Dbg( p_obj, "opening config file (%s)", psz_filename ); msg_Dbg( p_obj, "opening config file (%s)", psz_filename );
p_stream = utf8_fopen( psz_filename, mode ); p_stream = utf8_fopen( psz_filename, mode );
if( p_stream == NULL && errno != ENOENT ) if( p_stream == NULL && errno != ENOENT )
msg_Err( p_obj, "cannot open config file (%s): %s", psz_filename, strerror(errno) ); {
msg_Err( p_obj, "cannot open config file (%s): %s",
psz_filename, strerror(errno) );
}
#if !( defined(WIN32) || defined(__APPLE__) || defined(SYS_BEOS) )
else if( p_stream == NULL && errno == ENOENT && mode[0] == 'r' )
{
/* This is the fallback for pre XDG Base Directory
* Specification configs */
char *psz_old;
if( asprintf( &psz_old, "%s" DIR_SEP CONFIG_DIR DIR_SEP CONFIG_FILE,
p_obj->p_libvlc->psz_homedir ) != -1 )
{
p_stream = utf8_fopen( psz_old, mode );
if( p_stream )
{
/* Old config file found. We want to write it at the
* new location now. */
msg_Info( p_obj->p_libvlc, "Found old config file at %s. "
"VLC will now use %s.", psz_old, psz_filename );
char *psz_readme;
if( asprintf(&psz_readme,"%s"DIR_SEP CONFIG_DIR DIR_SEP"README",
p_obj->p_libvlc->psz_homedir ) != -1 )
{
FILE *p_readme = utf8_fopen( psz_readme, "wt" );
if( p_readme )
{
fputs( "The VLC media player configuration folder has "
"moved to comply with the XDG Base "
"Directory Specification version 0.6. Your "
"configuration has been copied to the new "
"location (", p_readme );
fputs( p_obj->p_libvlc->psz_configdir, p_readme );
fputs( "). You can delete this directory and "
"all its contents.", p_readme );
fclose( p_readme );
}
free( psz_readme );
}
}
free( psz_old );
}
}
#endif
else if( p_stream != NULL )
{
p_obj->p_libvlc->psz_configfile = psz_filename;
}
return p_stream; return p_stream;
} }
...@@ -1017,6 +1050,25 @@ int config_CreateDir( vlc_object_t *p_this, const char *psz_dirname ) ...@@ -1017,6 +1050,25 @@ int config_CreateDir( vlc_object_t *p_this, const char *psz_dirname )
if( utf8_mkdir( psz_dirname ) && ( errno != EEXIST ) ) if( utf8_mkdir( psz_dirname ) && ( errno != EEXIST ) )
{ {
if( errno == ENOENT )
{
/* Let's try to create the parent directory */
char *psz_parent = strdup( psz_dirname );
char *psz_end = strrchr( psz_parent, DIR_SEP_CHAR );
if( psz_end && psz_end != psz_parent )
{
*psz_end = '\0';
if( config_CreateDir( p_this, psz_parent ) == 0 )
{
if( !utf8_mkdir( psz_dirname ) )
{
free( psz_parent );
return 0;
}
}
}
free( psz_parent );
}
msg_Err( p_this, "could not create %s (%s)", msg_Err( p_this, "could not create %s (%s)",
psz_dirname, strerror(errno) ); psz_dirname, strerror(errno) );
return -1; return -1;
...@@ -1059,23 +1111,21 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name, ...@@ -1059,23 +1111,21 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
/* Acquire config file lock */ /* Acquire config file lock */
vlc_mutex_lock( &p_this->p_libvlc->config_lock ); vlc_mutex_lock( &p_this->p_libvlc->config_lock );
if (p_this->p_libvlc->psz_configfile == NULL) if( p_this->p_libvlc->psz_configfile == NULL )
{ {
const char *psz_homedir = p_this->p_libvlc->psz_homedir; const char *psz_configdir = p_this->p_libvlc->psz_configdir;
if( !psz_homedir ) if( !psz_configdir ) /* XXX: This should never happen */
{ {
msg_Err( p_this, "no home directory defined" ); msg_Err( p_this, "no configuration directory defined" );
vlc_mutex_unlock( &p_this->p_libvlc->config_lock ); vlc_mutex_unlock( &p_this->p_libvlc->config_lock );
return -1; return -1;
} }
char dirname[strlen (psz_homedir) + sizeof (DIR_SEP CONFIG_DIR)]; config_CreateDir( p_this, psz_configdir );
sprintf (dirname, "%s" DIR_SEP CONFIG_DIR, psz_homedir);
config_CreateDir (p_this, dirname);
} }
file = config_OpenConfigFile (p_this, "rt"); file = config_OpenConfigFile( p_this, "rt" );
if (file != NULL) if( file != NULL )
{ {
/* look for file size */ /* look for file size */
fseek( file, 0L, SEEK_END ); fseek( file, 0L, SEEK_END );
...@@ -1578,7 +1628,7 @@ int __config_LoadCmdLine( vlc_object_t *p_this, int *pi_argc, char *ppsz_argv[], ...@@ -1578,7 +1628,7 @@ int __config_LoadCmdLine( vlc_object_t *p_this, int *pi_argc, char *ppsz_argv[],
free( psz_shortopts ); free( psz_shortopts );
return -1; return -1;
} }
psz_name = (char *)p_conf->psz_current; psz_name = (char *)p_conf->psz_current;
p_conf = config_FindConfig( p_this, psz_name ); p_conf = config_FindConfig( p_this, psz_name );
} }
...@@ -1815,16 +1865,120 @@ static char *GetDir( vlc_bool_t b_appdata ) ...@@ -1815,16 +1865,120 @@ static char *GetDir( vlc_bool_t b_appdata )
return FromLocaleDup( psz_localhome ); return FromLocaleDup( psz_localhome );
} }
/**
* Get the user's home directory
*/
char *config_GetHomeDir( void ) char *config_GetHomeDir( void )
{ {
return GetDir( VLC_TRUE ); return GetDir( VLC_FALSE );
} }
/**
* Get the user's main data and config directory:
* - on windows that's the App Data directory;
* - on other OSes it's the same as the home directory.
*/
char *config_GetUserDir( void );
char *config_GetUserDir( void ) char *config_GetUserDir( void )
{ {
return GetDir( VLC_FALSE ); return GetDir( VLC_TRUE );
} }
/**
* Get the user's VLC configuration directory
*/
char *config_GetConfigDir( libvlc_int_t *p_libvlc )
{
char *psz_dir;
#if defined(WIN32) || defined(__APPLE__) || defined(SYS_BEOS)
char *psz_parent = config_GetUserDir();
if( !psz_parent ) psz_parent = p_libvlc->psz_homedir;
if( asprintf( &psz_dir, "%s" DIR_SEP CONFIG_DIR, psz_parent ) == -1 )
return NULL;
return psz_dir;
#else
/* XDG Base Directory Specification - Version 0.6 */
char *psz_env = getenv( "XDG_CONFIG_HOME" );
if( psz_env )
{
if( asprintf( &psz_dir, "%s/vlc", psz_env ) == -1 )
return NULL;
return psz_dir;
}
psz_env = getenv( "HOME" );
if( !psz_env ) psz_env = p_libvlc->psz_homedir; /* not part of XDG spec but we want a sensible fallback */
if( asprintf( &psz_dir, "%s/.config/vlc", psz_env ) == -1 )
return NULL;
return psz_dir;
#endif
}
/**
* Get the user's VLC data and cache directory
* (used for stuff like the modules cache, the album art cache, ...)
*/
char *config_GetUserDataDir( libvlc_int_t *p_libvlc )
{
char *psz_dir;
#if defined(WIN32) || defined(__APPLE__) || defined(SYS_BEOS)
char *psz_parent = config_GetUserDir();
if( !psz_parent ) psz_parent = p_libvlc->psz_homedir;
if( asprintf( &psz_dir, "%s" DIR_SEP CONFIG_DIR, psz_parent ) == -1 )
return NULL;
return psz_dir;
#else
/* XDG Base Directory Specification - Version 0.6 */
char *psz_env = getenv( "XDG_DATA_HOME" );
if( psz_env )
{
if( asprintf( &psz_dir, "%s/vlc", psz_env ) == -1 )
return NULL;
return psz_dir;
}
psz_env = getenv( "HOME" );
if( !psz_env ) psz_env = p_libvlc->psz_homedir; /* not part of XDG spec but we want a sensible fallback */
if( asprintf( &psz_dir, "%s/.local/share/vlc", psz_env ) == -1 )
return NULL;
return psz_dir;
#endif
}
/**
* Get the user's configuration file
*/
char *config_GetConfigFile( libvlc_int_t *p_libvlc )
{
char *psz_configfile;
if( asprintf( &psz_configfile, "%s" DIR_SEP CONFIG_FILE,
p_libvlc->psz_configdir ) == -1 )
return NULL;
return psz_configfile;
}
/**
* Get the user's configuration file when given with the --config option
*/
char *config_GetCustomConfigFile( libvlc_int_t *p_libvlc )
{
char *psz_configfile = config_GetPsz( p_libvlc, "config" );
if( psz_configfile != NULL )
{
if( psz_configfile[0] == '~' && psz_configfile[1] == '/' )
{
/* This is incomplete: we should also support the ~cmassiot/ syntax */
char *psz_buf;
if( asprintf( &psz_buf, "%s/%s", p_libvlc->psz_homedir,
psz_configfile + 2 ) == -1 )
{
free( psz_configfile );
return NULL;
}
free( psz_configfile );
psz_configfile = psz_buf;
}
}
return psz_configfile;
}
static int ConfigStringToKey( const char *psz_key ) static int ConfigStringToKey( const char *psz_key )
{ {
......
...@@ -33,17 +33,33 @@ int config_AutoSaveConfigFile( vlc_object_t * ); ...@@ -33,17 +33,33 @@ int config_AutoSaveConfigFile( vlc_object_t * );
void config_Free( module_t * ); void config_Free( module_t * );
void config_SetCallbacks( module_config_t *, module_config_t *, size_t ); void config_SetCallbacks( module_config_t *, module_config_t *, size_t );
void config_UnsetCallbacks ( module_config_t *, size_t ); void config_UnsetCallbacks( module_config_t *, size_t );
#define config_LoadCmdLine(a,b,c,d) __config_LoadCmdLine(VLC_OBJECT(a),b,c,d) #define config_LoadCmdLine(a,b,c,d) __config_LoadCmdLine(VLC_OBJECT(a),b,c,d)
#define config_LoadConfigFile(a,b) __config_LoadConfigFile(VLC_OBJECT(a),b) #define config_LoadConfigFile(a,b) __config_LoadConfigFile(VLC_OBJECT(a),b)