* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-#include <vlc/vlc.h>
-#include "../libvlc.h"
-#include "vlc_charset.h"
-#include "vlc_keys.h"
-
#include <errno.h> /* errno */
#include <assert.h>
#include <limits.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#ifdef __APPLE__
+# include <xlocale.h>
+#elif defined(HAVE_USELOCALE)
+#include <locale.h>
+#endif
+
+#include <vlc_common.h>
+#include "../libvlc.h"
+#include <vlc_charset.h>
+#include <vlc_fs.h>
+#include <vlc_keys.h>
+#include <vlc_modules.h>
#include "configuration.h"
#include "modules/modules.h"
-static char *ConfigKeyToString( int );
-
static inline char *strdupnull (const char *src)
{
return src ? strdup (src) : NULL;
}
-static FILE *config_OpenConfigFile( vlc_object_t *p_obj, const char *mode )
+/**
+ * Get the user's configuration file
+ */
+static char *config_GetConfigFile( vlc_object_t *obj )
{
- char *psz_filename = p_obj->p_libvlc->psz_configfile;
- FILE *p_stream;
-
- if( !psz_filename )
+ char *psz_file = var_CreateGetNonEmptyString( obj, "config" );
+ var_Destroy( obj, "config" );
+ if( psz_file == NULL )
{
- psz_filename = config_GetConfigFile( p_obj->p_libvlc );
+ char *psz_dir = config_GetUserDir( VLC_CONFIG_DIR );
+
+ if( asprintf( &psz_file, "%s" DIR_SEP CONFIG_FILE, psz_dir ) == -1 )
+ psz_file = NULL;
+ free( psz_dir );
}
+ return psz_file;
+}
+
+static FILE *config_OpenConfigFile( vlc_object_t *p_obj )
+{
+ char *psz_filename = config_GetConfigFile( p_obj );
+ if( psz_filename == NULL )
+ return NULL;
msg_Dbg( p_obj, "opening config file (%s)", psz_filename );
- p_stream = utf8_fopen( psz_filename, mode );
+ FILE *p_stream = vlc_fopen( psz_filename, "rt" );
if( p_stream == NULL && errno != ENOENT )
{
msg_Err( p_obj, "cannot open config file (%s): %m",
}
#if !( defined(WIN32) || defined(__APPLE__) || defined(SYS_BEOS) )
- else if( p_stream == NULL && errno == ENOENT && mode[0] == 'r' )
+ else if( p_stream == NULL && errno == ENOENT )
{
/* This is the fallback for pre XDG Base Directory
* Specification configs */
+ char *home = config_GetUserDir(VLC_HOME_DIR);
char *psz_old;
- if( asprintf( &psz_old, "%s" DIR_SEP CONFIG_DIR DIR_SEP CONFIG_FILE,
- p_obj->p_libvlc->psz_homedir ) != -1 )
+
+ if( home != NULL
+ && asprintf( &psz_old, "%s/.vlc/" CONFIG_FILE,
+ home ) != -1 )
{
- p_stream = utf8_fopen( psz_old, mode );
+ p_stream = vlc_fopen( psz_old, "rt" );
if( p_stream )
{
/* Old config file found. We want to write it at the
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 )
+ if( asprintf(&psz_readme,"%s/.vlc/README",
+ home ) != -1 )
{
- FILE *p_readme = utf8_fopen( psz_readme, "wt" );
+ FILE *p_readme = vlc_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 );
+ fprintf( p_readme, "The VLC media player "
+ "configuration folder has moved to comply\n"
+ "with the XDG Base Directory Specification "
+ "version 0.6. Your\nconfiguration has been "
+ "copied to the new location:\n%s\nYou can "
+ "delete this directory and all its contents.",
+ psz_filename);
fclose( p_readme );
}
free( psz_readme );
}
+ /* Remove the old configuration file so that --reset-config
+ * can work properly. Fortunately, Linux allows removing
+ * open files - with most filesystems. */
+ unlink( psz_old );
}
free( psz_old );
}
+ free( home );
}
#endif
- else if( p_stream != NULL )
- {
- p_obj->p_libvlc->psz_configfile = psz_filename;
- }
-
+ free( psz_filename );
return p_stream;
}
-static int strtoi (const char *str)
+static int64_t strtoi (const char *str)
{
char *end;
- long l;
+ long long l;
errno = 0;
- l = strtol (str, &end, 0);
+ l = strtoll (str, &end, 0);
if (!errno)
{
- if ((l > INT_MAX) || (l < INT_MIN))
+#if (LLONG_MAX > 0x7fffffffffffffffLL)
+ if (l > 0x7fffffffffffffffLL
+ || l < -0x8000000000000000LL)
errno = ERANGE;
+#endif
if (*end)
errno = EINVAL;
}
- return (int)l;
+ return l;
}
-
+#undef config_LoadConfigFile
/*****************************************************************************
* config_LoadConfigFile: loads the configuration file.
*****************************************************************************
* This function is called to load the config options stored in the config
* file.
*****************************************************************************/
-int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
+int config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
{
- vlc_list_t *p_list;
FILE *file;
- file = config_OpenConfigFile (p_this, "rt");
+ file = config_OpenConfigFile (p_this);
if (file == NULL)
return VLC_EGENERIC;
- /* Acquire config file lock */
- vlc_mutex_lock( &p_this->p_libvlc->config_lock );
-
/* Look for the selected module, if NULL then save everything */
- p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
+ module_t **list = module_list_get (NULL);
/* Look for UTF-8 Byte Order Mark */
char * (*convert) (const char *) = strdupnull;
char line[1024], section[1022];
section[0] = '\0';
+ /* Ensure consistent number formatting... */
+ locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
+ locale_t baseloc = uselocale (loc);
+
+ vlc_rwlock_wrlock (&config_lock);
while (fgets (line, 1024, file) != NULL)
{
/* Ignore comments and empty lines */
if ((psz_module_name == NULL)
|| (strcmp (psz_module_name, section) == 0))
{
- for (int i = 0; i < p_list->i_count; i++)
+ for (int i = 0; list[i]; i++)
{
- module_t *m = (module_t *)p_list->p_values[i].p_object;
+ module_t *m = list[i];
if ((strcmp (section, m->psz_object_name) == 0)
&& (m->i_config_items > 0)) /* ignore config-less modules */
case CONFIG_ITEM_BOOL:
case CONFIG_ITEM_INTEGER:
{
- long l = strtoi (psz_option_value);
+ int64_t l = strtoi (psz_option_value);
+ if ((l > p_item->max.i) || (l < p_item->min.i))
+ errno = ERANGE;
if (errno)
msg_Warn (p_this, "Integer value (%s) for %s: %m",
psz_option_value, psz_option_name);
else
- p_item->saved.i = p_item->value.i = (int)l;
+ p_item->saved.i = p_item->value.i = l;
break;
}
case CONFIG_ITEM_FLOAT:
if( !*psz_option_value )
break; /* ignore empty option */
- p_item->value.f = (float)i18n_atof( psz_option_value);
+ p_item->value.f = (float)atof (psz_option_value);
p_item->saved.f = p_item->value.f;
break;
break;
default:
- vlc_mutex_lock( p_item->p_lock );
-
/* free old string */
free( (char*) p_item->value.psz );
free( (char*) p_item->saved.psz );
p_item->value.psz = convert (psz_option_value);
p_item->saved.psz = strdupnull (p_item->value.psz);
-
- vlc_mutex_unlock( p_item->p_lock );
break;
}
-
break;
}
}
+ vlc_rwlock_unlock (&config_lock);
if (ferror (file))
{
}
fclose (file);
- vlc_list_release( p_list );
-
- vlc_mutex_unlock( &p_this->p_libvlc->config_lock );
+ module_list_free (list);
+ if (loc != (locale_t)0)
+ {
+ uselocale (baseloc);
+ freelocale (loc);
+ }
return 0;
}
*****************************************************************************/
int config_CreateDir( vlc_object_t *p_this, const char *psz_dirname )
{
- if( !psz_dirname && !*psz_dirname ) return -1;
+ if( !psz_dirname || !*psz_dirname ) return -1;
- if( utf8_mkdir( psz_dirname, 0700 ) == 0 )
+ if( vlc_mkdir( psz_dirname, 0700 ) == 0 )
return 0;
switch( errno )
*psz_end = '\0';
if( config_CreateDir( p_this, psz_parent ) == 0 )
{
- if( !utf8_mkdir( psz_dirname, 0700 ) )
+ if( !vlc_mkdir( psz_dirname, 0700 ) )
return 0;
}
}
}
}
- msg_Err( p_this, "could not create %s: %m", psz_dirname );
+ msg_Warn( p_this, "could not create %s: %m", psz_dirname );
return -1;
}
static int
-config_Write (FILE *file, const char *type, const char *desc,
+config_Write (FILE *file, const char *desc, const char *type,
bool comment, const char *name, const char *fmt, ...)
{
va_list ap;
if (desc == NULL)
desc = "?";
- if (fprintf (file, "# %s (%s)\n%s%s=", desc, _(type),
+ if (fprintf (file, "# %s (%s)\n%s%s=", desc, vlc_gettext (type),
comment ? "#" : "", name) < 0)
return -1;
}
+static int config_PrepareDir (vlc_object_t *obj)
+{
+ char *psz_configdir = config_GetUserDir (VLC_CONFIG_DIR);
+ if (psz_configdir == NULL)
+ return -1;
+
+ int ret = config_CreateDir (obj, psz_configdir);
+ free (psz_configdir);
+ return ret;
+}
+
/*****************************************************************************
* config_SaveConfigFile: Save a module's config options.
*****************************************************************************
bool b_autosave )
{
module_t *p_parser;
- vlc_list_t *p_list;
- FILE *file;
+ FILE *file = NULL;
+ char *permanent = NULL, *temporary = NULL;
char p_line[1024], *p_index2;
- int i_sizebuf = 0;
- char *p_bigbuffer, *p_index;
+ unsigned long i_sizebuf = 0;
+ char *p_bigbuffer = NULL, *p_index;
bool b_backup;
int i_index;
- /* Acquire config file lock */
- vlc_mutex_lock( &p_this->p_libvlc->config_lock );
-
- if( p_this->p_libvlc->psz_configfile == NULL )
+ if( config_PrepareDir( p_this ) )
{
- const char *psz_configdir = p_this->p_libvlc->psz_configdir;
- if( !psz_configdir ) /* XXX: This should never happen */
- {
- msg_Err( p_this, "no configuration directory defined" );
- vlc_mutex_unlock( &p_this->p_libvlc->config_lock );
- return -1;
- }
-
- config_CreateDir( p_this, psz_configdir );
+ msg_Err( p_this, "no configuration directory" );
+ return -1;
}
- file = config_OpenConfigFile( p_this, "rt" );
+ file = config_OpenConfigFile( p_this );
if( file != NULL )
{
- /* look for file size */
- fseek( file, 0L, SEEK_END );
- i_sizebuf = ftell( file );
- fseek( file, 0L, SEEK_SET );
+ struct stat st;
+
+ /* Some users make vlcrc read-only to prevent changes.
+ * The atomic replacement scheme breaks this "feature",
+ * so we check for read-only by hand. */
+ if (fstat (fileno (file), &st)
+ || !(st.st_mode & S_IWUSR))
+ {
+ msg_Err (p_this, "configuration file is read-only");
+ goto error;
+ }
+ i_sizebuf = ( st.st_size < LONG_MAX ) ? st.st_size : 0;
}
p_bigbuffer = p_index = malloc( i_sizebuf+1 );
if( !p_bigbuffer )
- {
- if( file ) fclose( file );
- vlc_mutex_unlock( &p_this->p_libvlc->config_lock );
- return -1;
- }
+ goto error;
p_bigbuffer[0] = 0;
/* List all available modules */
- p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
+ module_t **list = module_list_get (NULL);
/* backup file into memory, we only need to backup the sections we won't
* save later on */
- b_backup = 0;
+ b_backup = false;
while( file && fgets( p_line, 1024, file ) )
{
if( (p_line[0] == '[') && (p_index2 = strchr(p_line,']')))
{
/* we found a section, check if we need to do a backup */
- for( i_index = 0; i_index < p_list->i_count; i_index++ )
+ for( i_index = 0; (p_parser = list[i_index]) != NULL; i_index++ )
{
- p_parser = (module_t *)p_list->p_values[i_index].p_object ;
-
if( ((p_index2 - &p_line[1])
== (int)strlen(p_parser->psz_object_name) )
&& !memcmp( &p_line[1], p_parser->psz_object_name,
}
}
- if( i_index == p_list->i_count )
+ if( list[i_index] == NULL )
{
/* we don't have this section in our list so we need to back
* it up */
#endif
*p_index2 = ']';
- b_backup = 1;
+ b_backup = true;
}
else
{
- b_backup = 0;
+ b_backup = false;
}
}
p_index += strlen( p_line );
}
}
- if( file ) fclose( file );
-
+ if( file )
+ fclose( file );
+ file = NULL;
/*
* Save module config in file
*/
+ permanent = config_GetConfigFile (p_this);
+ if (!permanent)
+ {
+ module_list_free (list);
+ goto error;
+ }
- file = config_OpenConfigFile (p_this, "wt");
- if( !file )
+ if (asprintf (&temporary, "%s.%u", permanent, getpid ()) == -1)
{
- vlc_list_release( p_list );
- free( p_bigbuffer );
- vlc_mutex_unlock( &p_this->p_libvlc->config_lock );
- return -1;
+ temporary = NULL;
+ module_list_free (list);
+ goto error;
}
- fprintf( file, "\xEF\xBB\xBF###\n### " COPYRIGHT_MESSAGE "\n###\n\n"
- "###\n### lines beginning with a '#' character are comments\n###\n\n" );
+ /* Configuration lock must be taken before vlcrc serializer below. */
+ vlc_rwlock_rdlock (&config_lock);
+
+ /* The temporary configuration file is per-PID. Therefore SaveConfigFile()
+ * should be serialized against itself within a given process. */
+ static vlc_mutex_t lock = VLC_STATIC_MUTEX;
+ vlc_mutex_lock (&lock);
+
+ int fd = vlc_open (temporary, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);
+ if (fd == -1)
+ {
+ vlc_rwlock_unlock (&config_lock);
+ vlc_mutex_unlock (&lock);
+ module_list_free (list);
+ goto error;
+ }
+ file = fdopen (fd, "wt");
+ if (file == NULL)
+ {
+ msg_Err (p_this, "cannot create configuration file: %m");
+ vlc_rwlock_unlock (&config_lock);
+ close (fd);
+ vlc_mutex_unlock (&lock);
+ module_list_free (list);
+ goto error;
+ }
+
+ fprintf( file,
+ "\xEF\xBB\xBF###\n"
+ "### "PACKAGE_NAME" "PACKAGE_VERSION"\n"
+ "###\n"
+ "\n"
+ "###\n"
+ "### lines beginning with a '#' character are comments\n"
+ "###\n"
+ "\n" );
+
+ /* Ensure consistent number formatting... */
+ locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
+ locale_t baseloc = uselocale (loc);
+
+ /* We would take the config lock here. But this would cause a lock
+ * inversion with the serializer above and config_AutoSaveConfigFile().
+ vlc_rwlock_rdlock (&config_lock);*/
/* Look for the selected module, if NULL then save everything */
- for( i_index = 0; i_index < p_list->i_count; i_index++ )
+ for( i_index = 0; (p_parser = list[i_index]) != NULL; i_index++ )
{
module_config_t *p_item, *p_end;
- p_parser = (module_t *)p_list->p_values[i_index].p_object ;
if( psz_module_name && strcmp( psz_module_name,
p_parser->psz_object_name ) )
p_item < p_end;
p_item++ )
{
- /* Do not save the new value in the configuration file
- * if doing an autosave, and the item is not an "autosaved" one. */
- bool b_retain = b_autosave && !p_item->b_autosave;
-
if ((p_item->i_type & CONFIG_HINT) /* ignore hint */
|| p_item->b_removed /* ignore deprecated option */
|| p_item->b_unsaveable) /* ignore volatile option */
continue;
+ /* Do not save the new value in the configuration file
+ * if doing an autosave, and the item is not an "autosaved" one. */
+ bool b_retain = b_autosave && !p_item->b_autosave;
+
if (IsConfigIntegerType (p_item->i_type))
{
- int val = b_retain ? p_item->saved.i : p_item->value.i;
+ int64_t val = b_retain ? p_item->saved.i : p_item->value.i;
if (p_item->i_type == CONFIG_ITEM_KEY)
{
char *psz_key = ConfigKeyToString (val);
(p_item->i_type == CONFIG_ITEM_BOOL)
? N_("boolean") : N_("integer"),
val == p_item->orig.i,
- p_item->psz_name, "%d", val);
+ p_item->psz_name, "%"PRId64, val);
p_item->saved.i = val;
}
else
p_item->b_dirty = false;
}
}
+ vlc_rwlock_unlock (&config_lock);
- vlc_list_release( p_list );
+ module_list_free (list);
+ if (loc != (locale_t)0)
+ {
+ uselocale (baseloc);
+ freelocale (loc);
+ }
/*
* Restore old settings from the config in file
fputs( p_bigbuffer, file );
free( p_bigbuffer );
- fclose( file );
- vlc_mutex_unlock( &p_this->p_libvlc->config_lock );
+ /*
+ * Flush to disk and replace atomically
+ */
+ fflush (file); /* Flush from run-time */
+ if (ferror (file))
+ {
+ vlc_unlink (temporary);
+ vlc_mutex_unlock (&lock);
+ msg_Err (p_this, "cannot write configuration file");
+ clearerr (file);
+ goto error;
+ }
+#ifndef WIN32
+#ifdef __APPLE__
+ fsync (fd); /* Flush from OS */
+#else
+ fdatasync (fd); /* Flush from OS */
+#endif
+ /* Atomically replace the file... */
+ if (vlc_rename (temporary, permanent))
+ vlc_unlink (temporary);
+ /* (...then synchronize the directory, err, TODO...) */
+ /* ...and finally close the file */
+ vlc_mutex_unlock (&lock);
+#endif
+ fclose (file);
+#ifdef WIN32
+ /* Windows cannot remove open files nor overwrite existing ones */
+ vlc_unlink (permanent);
+ if (vlc_rename (temporary, permanent))
+ vlc_unlink (temporary);
+ vlc_mutex_unlock (&lock);
+#endif
+ free (temporary);
+ free (permanent);
return 0;
+
+error:
+ if( file )
+ fclose( file );
+ free (temporary);
+ free (permanent);
+ free( p_bigbuffer );
+ return -1;
}
int config_AutoSaveConfigFile( vlc_object_t *p_this )
{
- vlc_list_t *p_list;
- int i_index, i_count;
+ int ret = VLC_SUCCESS;
+ bool save = false;
assert( p_this );
/* Check if there's anything to save */
- vlc_mutex_lock( &p_this->p_libvlc->config_lock );
- p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
- i_count = p_list->i_count;
- for( i_index = 0; i_index < i_count; i_index++ )
+ module_t **list = module_list_get (NULL);
+ vlc_rwlock_rdlock (&config_lock);
+ for (size_t i_index = 0; list[i_index] && !save; i_index++)
{
- module_t *p_parser = (module_t *)p_list->p_values[i_index].p_object ;
+ module_t *p_parser = list[i_index];
module_config_t *p_item, *p_end;
if( !p_parser->i_config_items ) continue;
for( p_item = p_parser->p_config, p_end = p_item + p_parser->confsize;
- p_item < p_end;
+ p_item < p_end && !save;
p_item++ )
{
- if( p_item->b_autosave && p_item->b_dirty ) break;
+ save = p_item->b_autosave && p_item->b_dirty;
}
- if( p_item < p_end ) break;
}
- vlc_list_release( p_list );
- vlc_mutex_unlock( &p_this->p_libvlc->config_lock );
- if( i_index == i_count ) return VLC_SUCCESS;
- return SaveConfigFile( p_this, 0, true );
-}
-
-int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
-{
- return SaveConfigFile( p_this, psz_module_name, false );
-}
-
-/**
- * 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;
-}
+ if (save)
+ /* Note: this will get the read lock recursively. Ok. */
+ ret = SaveConfigFile (p_this, NULL, true);
+ vlc_rwlock_unlock (&config_lock);
-int ConfigStringToKey( const char *psz_key )
-{
- int i_key = 0;
- unsigned int i;
- const char *psz_parser = strchr( psz_key, '-' );
- while( psz_parser && psz_parser != psz_key )
- {
- for( i = 0; i < sizeof(vlc_modifiers) / sizeof(key_descriptor_t); i++ )
- {
- if( !strncasecmp( vlc_modifiers[i].psz_key_string, psz_key,
- strlen( vlc_modifiers[i].psz_key_string ) ) )
- {
- i_key |= vlc_modifiers[i].i_key_code;
- }
- }
- psz_key = psz_parser + 1;
- psz_parser = strchr( psz_key, '-' );
- }
- for( i = 0; i < sizeof(vlc_keys) / sizeof( key_descriptor_t ); i++ )
- {
- if( !strcasecmp( vlc_keys[i].psz_key_string, psz_key ) )
- {
- i_key |= vlc_keys[i].i_key_code;
- break;
- }
- }
- return i_key;
+ module_list_free (list);
+ return ret;
}
-char *ConfigKeyToString( int i_key )
+#undef config_SaveConfigFile
+int config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
{
- char *psz_key = malloc( 100 );
- char *p;
- size_t index;
-
- if ( !psz_key )
- {
- return NULL;
- }
- *psz_key = '\0';
- p = psz_key;
-
- for( index = 0; index < (sizeof(vlc_modifiers) / sizeof(key_descriptor_t));
- index++ )
- {
- if( i_key & vlc_modifiers[index].i_key_code )
- {
- p += sprintf( p, "%s-", vlc_modifiers[index].psz_key_string );
- }
- }
- for( index = 0; index < (sizeof(vlc_keys) / sizeof( key_descriptor_t));
- index++)
- {
- if( (int)( i_key & ~KEY_MODIFIER ) == vlc_keys[index].i_key_code )
- {
- p += sprintf( p, "%s", vlc_keys[index].psz_key_string );
- break;
- }
- }
- return psz_key;
+ return SaveConfigFile( p_this, psz_module_name, false );
}
-