Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-gpu
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-gpu
Commits
2d9c9ee6
Commit
2d9c9ee6
authored
Dec 09, 2007
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Split the big config file
parent
74710712
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
2541 additions
and
8 deletions
+2541
-8
src/Makefile.am
src/Makefile.am
+5
-3
src/config/chain.c
src/config/chain.c
+2
-2
src/config/cmdline.c
src/config/cmdline.c
+428
-0
src/config/config.h
src/config/config.h
+2
-0
src/config/core.c
src/config/core.c
+1138
-0
src/config/file.c
src/config/file.c
+757
-0
src/config/intf.c
src/config/intf.c
+206
-0
src/libvlc-common.c
src/libvlc-common.c
+1
-1
src/modules/modules.c
src/modules/modules.c
+1
-1
src/playlist/loadsave.c
src/playlist/loadsave.c
+1
-1
No files found.
src/Makefile.am
View file @
2d9c9ee6
...
...
@@ -299,9 +299,11 @@ SOURCES_libvlc_common = \
misc/threads.c
\
misc/stats.c
\
misc/cpu.c
\
modules/configuration.h
\
modules/configuration.c
\
modules/configuration_chain.c
\
config/configuration.h
\
config/core.c
\
config/chain.c
\
config/file.c
\
config/cmdline.c
\
misc/events.c
\
misc/image.c
\
misc/messages.c
\
...
...
src/
modules/configuration_
chain.c
→
src/
config/
chain.c
View file @
2d9c9ee6
/*****************************************************************************
* c
onfiguration_c
hain.c : configuration module chain parsing stuff
* chain.c : configuration module chain parsing stuff
*****************************************************************************
* Copyright (C) 2002-200
6
the VideoLAN team
* Copyright (C) 2002-200
7
the VideoLAN team
* $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
...
...
src/config/cmdline.c
0 → 100644
View file @
2d9c9ee6
/*****************************************************************************
* cmdline.c: command line parsing
*****************************************************************************
* Copyright (C) 2001-2007 the VideoLAN team
* $Id$
*
* Authors: Gildas Bazin <gbazin@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.
*****************************************************************************/
#include <vlc/vlc.h>
#include "../libvlc.h"
#include "vlc_keys.h"
#include "vlc_charset.h"
#include <errno.h>
/* errno */
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
/* getuid() */
#endif
#ifdef HAVE_GETOPT_LONG
# ifdef HAVE_GETOPT_H
# include <getopt.h>
/* getopt() */
# endif
#else
# include "../extras/getopt.h"
#endif
#if defined(HAVE_GETPWUID)
# include <pwd.h>
/* getpwuid() */
#endif
#if defined( HAVE_SYS_STAT_H )
# include <sys/stat.h>
#endif
#if defined( HAVE_SYS_TYPES_H )
# include <sys/types.h>
#endif
#if defined( WIN32 )
# if !defined( UNDER_CE )
# include <direct.h>
# endif
#include <tchar.h>
#endif
#include "config.h"
#include "modules/modules.h"
/*****************************************************************************
* config_LoadCmdLine: parse command line
*****************************************************************************
* Parse command line for configuration options.
* Now that the module_bank has been initialized, we can dynamically
* generate the longopts structure used by getops. We have to do it this way
* because we don't know (and don't want to know) in advance the configuration
* options used (ie. exported) by each module.
*****************************************************************************/
int
__config_LoadCmdLine
(
vlc_object_t
*
p_this
,
int
*
pi_argc
,
const
char
*
ppsz_argv
[],
vlc_bool_t
b_ignore_errors
)
{
int
i_cmd
,
i_index
,
i_opts
,
i_shortopts
,
flag
,
i_verbose
=
0
;
module_t
*
p_parser
;
vlc_list_t
*
p_list
;
struct
option
*
p_longopts
;
int
i_modules_index
;
/* Short options */
module_config_t
*
pp_shortopts
[
256
];
char
*
psz_shortopts
;
/* Set default configuration and copy arguments */
p_this
->
p_libvlc
->
i_argc
=
*
pi_argc
;
p_this
->
p_libvlc
->
ppsz_argv
=
ppsz_argv
;
#ifdef __APPLE__
/* When VLC.app is run by double clicking in Mac OS X, the 2nd arg
* is the PSN - process serial number (a unique PID-ish thingie)
* still ok for real Darwin & when run from command line */
if
(
(
*
pi_argc
>
1
)
&&
(
strncmp
(
ppsz_argv
[
1
]
,
"-psn"
,
4
)
==
0
)
)
/* for example -psn_0_9306113 */
{
/* GDMF!... I can't do this or else the MacOSX window server will
* not pick up the PSN and not register the app and we crash...
* hence the following kludge otherwise we'll get confused w/ argv[1]
* being an input file name */
#if 0
ppsz_argv[ 1 ] = NULL;
#endif
*
pi_argc
=
*
pi_argc
-
1
;
pi_argc
--
;
return
0
;
}
#endif
/* List all modules */
p_list
=
vlc_list_find
(
p_this
,
VLC_OBJECT_MODULE
,
FIND_ANYWHERE
);
/*
* Generate the longopts and shortopts structures used by getopt_long
*/
i_opts
=
0
;
for
(
i_modules_index
=
0
;
i_modules_index
<
p_list
->
i_count
;
i_modules_index
++
)
{
p_parser
=
(
module_t
*
)
p_list
->
p_values
[
i_modules_index
].
p_object
;
/* count the number of exported configuration options (to allocate
* longopts). We also need to allocate space for two options when
* dealing with boolean to allow for --foo and --no-foo */
i_opts
+=
p_parser
->
i_config_items
+
2
*
p_parser
->
i_bool_items
;
}
p_longopts
=
malloc
(
sizeof
(
struct
option
)
*
(
i_opts
+
1
)
);
if
(
p_longopts
==
NULL
)
{
msg_Err
(
p_this
,
"out of memory"
);
vlc_list_release
(
p_list
);
return
-
1
;
}
psz_shortopts
=
malloc
(
sizeof
(
char
)
*
(
2
*
i_opts
+
1
)
);
if
(
psz_shortopts
==
NULL
)
{
msg_Err
(
p_this
,
"out of memory"
);
free
(
p_longopts
);
vlc_list_release
(
p_list
);
return
-
1
;
}
/* If we are requested to ignore errors, then we must work on a copy
* of the ppsz_argv array, otherwise getopt_long will reorder it for
* us, ignoring the arity of the options */
if
(
b_ignore_errors
)
{
ppsz_argv
=
(
const
char
**
)
malloc
(
*
pi_argc
*
sizeof
(
char
*
)
);
if
(
ppsz_argv
==
NULL
)
{
msg_Err
(
p_this
,
"out of memory"
);
free
(
psz_shortopts
);
free
(
p_longopts
);
vlc_list_release
(
p_list
);
return
-
1
;
}
memcpy
(
ppsz_argv
,
p_this
->
p_libvlc
->
ppsz_argv
,
*
pi_argc
*
sizeof
(
char
*
)
);
}
i_shortopts
=
0
;
for
(
i_index
=
0
;
i_index
<
256
;
i_index
++
)
{
pp_shortopts
[
i_index
]
=
NULL
;
}
/* Fill the p_longopts and psz_shortopts structures */
i_index
=
0
;
for
(
i_modules_index
=
0
;
i_modules_index
<
p_list
->
i_count
;
i_modules_index
++
)
{
module_config_t
*
p_item
,
*
p_end
;
p_parser
=
(
module_t
*
)
p_list
->
p_values
[
i_modules_index
].
p_object
;
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
++
)
{
/* Ignore hints */
if
(
p_item
->
i_type
&
CONFIG_HINT
)
continue
;
/* Add item to long options */
p_longopts
[
i_index
].
name
=
strdup
(
p_item
->
psz_name
);
if
(
p_longopts
[
i_index
].
name
==
NULL
)
continue
;
p_longopts
[
i_index
].
has_arg
=
(
p_item
->
i_type
==
CONFIG_ITEM_BOOL
)
?
no_argument
:
required_argument
;
p_longopts
[
i_index
].
flag
=
&
flag
;
p_longopts
[
i_index
].
val
=
0
;
i_index
++
;
/* When dealing with bools we also need to add the --no-foo
* option */
if
(
p_item
->
i_type
==
CONFIG_ITEM_BOOL
)
{
char
*
psz_name
=
malloc
(
strlen
(
p_item
->
psz_name
)
+
3
);
if
(
psz_name
==
NULL
)
continue
;
strcpy
(
psz_name
,
"no"
);
strcat
(
psz_name
,
p_item
->
psz_name
);
p_longopts
[
i_index
].
name
=
psz_name
;
p_longopts
[
i_index
].
has_arg
=
no_argument
;
p_longopts
[
i_index
].
flag
=
&
flag
;
p_longopts
[
i_index
].
val
=
1
;
i_index
++
;
psz_name
=
malloc
(
strlen
(
p_item
->
psz_name
)
+
4
);
if
(
psz_name
==
NULL
)
continue
;
strcpy
(
psz_name
,
"no-"
);
strcat
(
psz_name
,
p_item
->
psz_name
);
p_longopts
[
i_index
].
name
=
psz_name
;
p_longopts
[
i_index
].
has_arg
=
no_argument
;
p_longopts
[
i_index
].
flag
=
&
flag
;
p_longopts
[
i_index
].
val
=
1
;
i_index
++
;
}
/* If item also has a short option, add it */
if
(
p_item
->
i_short
)
{
pp_shortopts
[(
int
)
p_item
->
i_short
]
=
p_item
;
psz_shortopts
[
i_shortopts
]
=
p_item
->
i_short
;
i_shortopts
++
;
if
(
p_item
->
i_type
!=
CONFIG_ITEM_BOOL
)
{
psz_shortopts
[
i_shortopts
]
=
':'
;
i_shortopts
++
;
if
(
p_item
->
i_short
==
'v'
)
{
psz_shortopts
[
i_shortopts
]
=
':'
;
i_shortopts
++
;
}
}
}
}
}
/* We don't need the module list anymore */
vlc_list_release
(
p_list
);
/* Close the longopts and shortopts structures */
memset
(
&
p_longopts
[
i_index
],
0
,
sizeof
(
struct
option
)
);
psz_shortopts
[
i_shortopts
]
=
'\0'
;
/*
* Parse the command line options
*/
opterr
=
0
;
optind
=
0
;
/* set to 0 to tell GNU getopt to reinitialize */
while
(
(
i_cmd
=
getopt_long
(
*
pi_argc
,
(
char
**
)
ppsz_argv
,
psz_shortopts
,
p_longopts
,
&
i_index
)
)
!=
-
1
)
{
/* A long option has been recognized */
if
(
i_cmd
==
0
)
{
module_config_t
*
p_conf
;
char
*
psz_name
=
(
char
*
)
p_longopts
[
i_index
].
name
;
/* Check if we deal with a --nofoo or --no-foo long option */
if
(
flag
)
psz_name
+=
psz_name
[
2
]
==
'-'
?
3
:
2
;
/* Store the configuration option */
p_conf
=
config_FindConfig
(
p_this
,
psz_name
);
if
(
p_conf
)
{
/* Check if the option is deprecated */
if
(
p_conf
->
psz_current
)
{
if
(
p_conf
->
b_strict
)
{
fprintf
(
stderr
,
"Warning: option --%s no longer exists.
\n
"
,
p_conf
->
psz_name
);
continue
;
}
fprintf
(
stderr
,
"%s: option --%s is deprecated. Use --%s instead.
\n
"
,
b_ignore_errors
?
"Warning"
:
"Error"
,
p_conf
->
psz_name
,
p_conf
->
psz_current
);
if
(
!
b_ignore_errors
)
{
/*free */
for
(
i_index
=
0
;
p_longopts
[
i_index
].
name
;
i_index
++
)
free
(
(
char
*
)
p_longopts
[
i_index
].
name
);
free
(
p_longopts
);
free
(
psz_shortopts
);
return
-
1
;
}
psz_name
=
(
char
*
)
p_conf
->
psz_current
;
p_conf
=
config_FindConfig
(
p_this
,
psz_name
);
}
switch
(
p_conf
->
i_type
)
{
case
CONFIG_ITEM_STRING
:
case
CONFIG_ITEM_PASSWORD
:
case
CONFIG_ITEM_FILE
:
case
CONFIG_ITEM_DIRECTORY
:
case
CONFIG_ITEM_MODULE
:
case
CONFIG_ITEM_MODULE_LIST
:
case
CONFIG_ITEM_MODULE_LIST_CAT
:
case
CONFIG_ITEM_MODULE_CAT
:
config_PutPsz
(
p_this
,
psz_name
,
optarg
);
break
;
case
CONFIG_ITEM_INTEGER
:
config_PutInt
(
p_this
,
psz_name
,
strtol
(
optarg
,
0
,
0
));
break
;
case
CONFIG_ITEM_FLOAT
:
config_PutFloat
(
p_this
,
psz_name
,
(
float
)
atof
(
optarg
)
);
break
;
case
CONFIG_ITEM_KEY
:
config_PutInt
(
p_this
,
psz_name
,
ConfigStringToKey
(
optarg
)
);
break
;
case
CONFIG_ITEM_BOOL
:
config_PutInt
(
p_this
,
psz_name
,
!
flag
);
break
;
}
continue
;
}
}
/* A short option has been recognized */
if
(
pp_shortopts
[
i_cmd
]
!=
NULL
)
{
switch
(
pp_shortopts
[
i_cmd
]
->
i_type
)
{
case
CONFIG_ITEM_STRING
:
case
CONFIG_ITEM_PASSWORD
:
case
CONFIG_ITEM_FILE
:
case
CONFIG_ITEM_DIRECTORY
:
case
CONFIG_ITEM_MODULE
:
case
CONFIG_ITEM_MODULE_CAT
:
case
CONFIG_ITEM_MODULE_LIST
:
case
CONFIG_ITEM_MODULE_LIST_CAT
:
config_PutPsz
(
p_this
,
pp_shortopts
[
i_cmd
]
->
psz_name
,
optarg
);
break
;
case
CONFIG_ITEM_INTEGER
:
if
(
i_cmd
==
'v'
)
{
if
(
optarg
)
{
if
(
*
optarg
==
'v'
)
/* eg. -vvv */
{
i_verbose
++
;
while
(
*
optarg
==
'v'
)
{
i_verbose
++
;
optarg
++
;
}
}
else
{
i_verbose
+=
atoi
(
optarg
);
/* eg. -v2 */
}
}
else
{
i_verbose
++
;
/* -v */
}
config_PutInt
(
p_this
,
pp_shortopts
[
i_cmd
]
->
psz_name
,
i_verbose
);
}
else
{
config_PutInt
(
p_this
,
pp_shortopts
[
i_cmd
]
->
psz_name
,
strtol
(
optarg
,
0
,
0
)
);
}
break
;
case
CONFIG_ITEM_BOOL
:
config_PutInt
(
p_this
,
pp_shortopts
[
i_cmd
]
->
psz_name
,
1
);
break
;
}
continue
;
}
/* Internal error: unknown option */
if
(
!
b_ignore_errors
)
{
fprintf
(
stderr
,
"%s: unknown option"
" or missing mandatory argument "
,
p_this
->
p_libvlc
->
psz_object_name
);
if
(
optopt
)
{
fprintf
(
stderr
,
"`-%c'
\n
"
,
optopt
);
}
else
{
fprintf
(
stderr
,
"`%s'
\n
"
,
ppsz_argv
[
optind
-
1
]
);
}
fprintf
(
stderr
,
"Try `%s --help' for more information.
\n
"
,
p_this
->
p_libvlc
->
psz_object_name
);
for
(
i_index
=
0
;
p_longopts
[
i_index
].
name
;
i_index
++
)
free
(
(
char
*
)
p_longopts
[
i_index
].
name
);
free
(
p_longopts
);
free
(
psz_shortopts
);
return
-
1
;
}
}
/* Free allocated resources */
for
(
i_index
=
0
;
p_longopts
[
i_index
].
name
;
i_index
++
)
free
(
(
char
*
)
p_longopts
[
i_index
].
name
);
free
(
p_longopts
);
free
(
psz_shortopts
);
if
(
b_ignore_errors
)
free
(
ppsz_argv
);
return
0
;
}
src/
modules/configuration
.h
→
src/
config/config
.h
View file @
2d9c9ee6
...
...
@@ -53,6 +53,8 @@ int __config_LoadConfigFile( vlc_object_t *, const char * );
int
IsConfigStringType
(
int
type
);
int
ConfigStringToKey
(
const
char
*
);
/* The configuration file and directory */
#if defined (SYS_BEOS)
# define CONFIG_DIR "config/settings/VideoLAN Client"
...
...
src/
modules/configuration
.c
→
src/
config/core
.c
View file @
2d9c9ee6
/*****************************************************************************
* co
nfiguration
.c management of the modules configuration
* co
re
.c management of the modules configuration
*****************************************************************************
* Copyright (C) 2001-2007 the VideoLAN team
* $Id$
...
...
@@ -61,24 +61,17 @@
#include <tchar.h>
#endif
#include "config
uration
.h"
#include "config.h"
#include "modules/modules.h"
static
int
ConfigStringToKey
(
const
char
*
);
static
char
*
ConfigKeyToString
(
int
);
static
inline
char
*
strdupnull
(
const
char
*
src
)
{
if
(
src
==
NULL
)
return
NULL
;
return
strdup
(
src
);
return
src
?
strdup
(
src
)
:
NULL
;
}
static
inline
char
*
_strdupnull
(
const
char
*
src
)
{
if
(
src
==
NULL
)
return
NULL
;
return
strdup
(
_
(
src
));
return
src
?
strdup
(
_
(
src
))
:
NULL
;
}
/* Item types that use a string value (i.e. serialized in the module cache) */
...
...
@@ -784,977 +777,6 @@ void __config_ResetAll( vlc_object_t *p_this )
vlc_mutex_unlock
(
&
p_this
->
p_libvlc
->
config_lock
);
}
static
FILE
*
config_OpenConfigFile
(
vlc_object_t
*
p_obj
,
const
char
*
mode
)
{
char
*
psz_filename
=
p_obj
->
p_libvlc
->
psz_configfile
;
FILE
*
p_stream
;
if
(
!
psz_filename
)
{
psz_filename
=
config_GetConfigFile
(
p_obj
->
p_libvlc
);
}
msg_Dbg
(
p_obj
,
"opening config file (%s)"
,
psz_filename
);
p_stream
=
utf8_fopen
(
psz_filename
,
mode
);
if
(
p_stream
==
NULL
&&
errno
!=
ENOENT
)
{
msg_Err
(
p_obj
,
"cannot open config file (%s): %m"
,
psz_filename
);
}
#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
;
}
static
int
strtoi
(
const
char
*
str
)
{
char
*
end
;
long
l
;
errno
=
0
;
l
=
strtol
(
str
,
&
end
,
0
);
if
(
!
errno
)
{
if
((
l
>
INT_MAX
)
||
(
l
<
INT_MIN
))
errno
=
ERANGE
;
if
(
*
end
)
errno
=
EINVAL
;
}
return
(
int
)
l
;
}
/*****************************************************************************
* 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
)
{
vlc_list_t
*
p_list
;
FILE
*
file
;
file
=
config_OpenConfigFile
(
p_this
,
"rt"
);
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
);
/* Look for UTF-8 Byte Order Mark */
char
*
(
*
convert
)
(
const
char
*
)
=
strdupnull
;
char
bom
[
3
];
if
((
fread
(
bom
,
1
,
3
,
file
)
!=
3
)
||
memcmp
(
bom
,
"
\xEF\xBB\xBF
"
,
3
))
{
convert
=
FromLocaleDup
;
rewind
(
file
);
/* no BOM, rewind */
}
module_t
*
module
=
NULL
;
char
line
[
1024
],
section
[
1022
];
section
[
0
]
=
'\0'
;
while
(
fgets
(
line
,
1024
,
file
)
!=
NULL
)
{
/* Ignore comments and empty lines */
switch
(
line
[
0
])
{
case
'#'
:
case
'\n'
:
case
'\0'
:
continue
;
}
if
(
line
[
0
]
==
'['
)
{
char
*
ptr
=
strchr
(
line
,
']'
);
if
(
ptr
==
NULL
)
continue
;
/* syntax error; */
*
ptr
=
'\0'
;
/* New section ( = a given module) */
strcpy
(
section
,
line
+
1
);
module
=
NULL
;
if
((
psz_module_name
==
NULL
)
||
(
strcmp
(
psz_module_name
,
section
)
==
0
))
{
for
(
int
i
=
0
;
i
<
p_list
->
i_count
;
i
++
)
{
module_t
*
m
=
(
module_t
*
)
p_list
->
p_values
[
i
].
p_object
;
if
((
strcmp
(
section
,
m
->
psz_object_name
)
==
0
)
&&
(
m
->
i_config_items
>
0
))
/* ignore config-less modules */
{
module
=
m
;
if
(
psz_module_name
!=
NULL
)
msg_Dbg
(
p_this
,
"loading config for module
\"
%s
\"
"
,
section
);
break
;
}
}
}
continue
;
}
if
(
module
==
NULL
)
continue
;
/* no need to parse if there is no matching module */
char
*
ptr
=
strchr
(
line
,
'\n'
);
if
(
ptr
!=
NULL
)
*
ptr
=
'\0'
;
/* look for option name */
const
char
*
psz_option_name
=
line
;
ptr
=
strchr
(
line
,
'='
);
if
(
ptr
==
NULL
)
continue
;
/* syntax error */
*
ptr
=
'\0'
;
const
char
*
psz_option_value
=
ptr
+
1
;
/* try to match this option with one of the module's options */
for
(
size_t
i
=
0
;
i
<
module
->
confsize
;
i
++
)
{
module_config_t
*
p_item
=
module
->
p_config
+
i
;
if
((
p_item
->
i_type
&
CONFIG_HINT
)
||
strcmp
(
p_item
->
psz_name
,
psz_option_name
))
continue
;
/* We found it */
errno
=
0
;
switch
(
p_item
->
i_type
)
{
case
CONFIG_ITEM_BOOL
:
case
CONFIG_ITEM_INTEGER
:
{
long
l
=
strtoi
(
psz_option_value
);
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
;
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
->
saved
.
f
=
p_item
->
value
.
f
;
break
;
case
CONFIG_ITEM_KEY
:
if
(
!*
psz_option_value
)
break
;
/* ignore empty option */
p_item
->
value
.
i
=
ConfigStringToKey
(
psz_option_value
);
p_item
->
saved
.
i
=
p_item
->
value
.
i
;
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
;
}
}
if
(
ferror
(
file
))
{
msg_Err
(
p_this
,
"error reading configuration: %m"
);
clearerr
(
file
);
}
fclose
(
file
);
vlc_list_release
(
p_list
);
vlc_mutex_unlock
(
&
p_this
->
p_libvlc
->
config_lock
);
return
0
;
}
/*****************************************************************************
* config_CreateDir: Create configuration directory if it doesn't exist.
*****************************************************************************/
int
config_CreateDir
(
vlc_object_t
*
p_this
,
const
char
*
psz_dirname
)
{
if
(
!
psz_dirname
&&
!*
psz_dirname
)
return
-
1
;
if
(
utf8_mkdir
(
psz_dirname
,
0700
)
==
0
)
return
0
;
switch
(
errno
)
{
case
EEXIST
:
return
0
;
case
ENOENT
:
{
/* Let's try to create the parent directory */
char
psz_parent
[
strlen
(
psz_dirname
)
+
1
],
*
psz_end
;
strcpy
(
psz_parent
,
psz_dirname
);
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
,
0700
)
)
return
0
;
}
}
}
}
msg_Err
(
p_this
,
"could not create %s: %m"
,
psz_dirname
);
return
-
1
;
}
/*****************************************************************************
* config_SaveConfigFile: Save a module's config options.
*****************************************************************************
* This will save the specified module's config options to the config file.
* If psz_module_name is NULL then we save all the modules config options.
* It's no use to save the config options that kept their default values, so
* we'll try to be a bit clever here.
*
* When we save we mustn't delete the config options of the modules that
* haven't been loaded. So we cannot just create a new config file with the
* config structures we've got in memory.
* I don't really know how to deal with this nicely, so I will use a completly
* dumb method ;-)
* I will load the config file in memory, but skipping all the sections of the
* modules we want to save. Then I will create a brand new file, dump the file
* loaded in memory and then append the sections of the modules we want to
* save.
* Really stupid no ?
*****************************************************************************/
static
int
SaveConfigFile
(
vlc_object_t
*
p_this
,
const
char
*
psz_module_name
,
vlc_bool_t
b_autosave
)
{
module_t
*
p_parser
;
vlc_list_t
*
p_list
;
FILE
*
file
;
char
p_line
[
1024
],
*
p_index2
;
int
i_sizebuf
=
0
;
char
*
p_bigbuffer
,
*
p_index
;
vlc_bool_t
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
)
{
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
);
}
file
=
config_OpenConfigFile
(
p_this
,
"rt"
);
if
(
file
!=
NULL
)
{
/* look for file size */
fseek
(
file
,
0L
,
SEEK_END
);
i_sizebuf
=
ftell
(
file
);
fseek
(
file
,
0L
,
SEEK_SET
);
}
p_bigbuffer
=
p_index
=
malloc
(
i_sizebuf
+
1
);
if
(
!
p_bigbuffer
)
{
msg_Err
(
p_this
,
"out of memory"
);
if
(
file
)
fclose
(
file
);
vlc_mutex_unlock
(
&
p_this
->
p_libvlc
->
config_lock
);
return
-
1
;
}
p_bigbuffer
[
0
]
=
0
;
/* List all available modules */
p_list
=
vlc_list_find
(
p_this
,
VLC_OBJECT_MODULE
,
FIND_ANYWHERE
);
/* backup file into memory, we only need to backup the sections we won't
* save later on */
b_backup
=
0
;
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
++
)
{
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
,
strlen
(
p_parser
->
psz_object_name
)
)
)
{
if
(
!
psz_module_name
)
break
;
else
if
(
!
strcmp
(
psz_module_name
,
p_parser
->
psz_object_name
)
)
break
;
}
}
if
(
i_index
==
p_list
->
i_count
)
{
/* we don't have this section in our list so we need to back
* it up */
*
p_index2
=
0
;
#if 0
msg_Dbg( p_this, "backing up config for unknown module \"%s\"",
&p_line[1] );
#endif
*
p_index2
=
']'
;
b_backup
=
1
;
}
else
{
b_backup
=
0
;
}
}
/* save line if requested and line is valid (doesn't begin with a
* space, tab, or eol) */
if
(
b_backup
&&
(
p_line
[
0
]
!=
'\n'
)
&&
(
p_line
[
0
]
!=
' '
)
&&
(
p_line
[
0
]
!=
'\t'
)
)
{
strcpy
(
p_index
,
p_line
);
p_index
+=
strlen
(
p_line
);
}
}
if
(
file
)
fclose
(
file
);
/*
* Save module config in file
*/
file
=
config_OpenConfigFile
(
p_this
,
"wt"
);
if
(
!
file
)
{
vlc_list_release
(
p_list
);
free
(
p_bigbuffer
);
vlc_mutex_unlock
(
&
p_this
->
p_libvlc
->
config_lock
);
return
-
1
;
}
fprintf
(
file
,
"
\xEF\xBB\xBF
###
\n
### "
COPYRIGHT_MESSAGE
"
\n
###
\n\n
"
"###
\n
### lines begining with a '#' character are comments
\n
###
\n\n
"
);
/* Look for the selected module, if NULL then save everything */
for
(
i_index
=
0
;
i_index
<
p_list
->
i_count
;
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
)
)
continue
;
if
(
!
p_parser
->
i_config_items
)
continue
;
if
(
psz_module_name
)
msg_Dbg
(
p_this
,
"saving config for module
\"
%s
\"
"
,
p_parser
->
psz_object_name
);
fprintf
(
file
,
"[%s]"
,
p_parser
->
psz_object_name
);
if
(
p_parser
->
psz_longname
)
fprintf
(
file
,
" # %s
\n\n
"
,
p_parser
->
psz_longname
);
else
fprintf
(
file
,
"
\n\n
"
);
for
(
p_item
=
p_parser
->
p_config
,
p_end
=
p_item
+
p_parser
->
confsize
;
p_item
<
p_end
;
p_item
++
)
{
char
*
psz_key
;
int
i_value
=
p_item
->
value
.
i
;
float
f_value
=
p_item
->
value
.
f
;
const
char
*
psz_value
=
p_item
->
value
.
psz
;
if
(
p_item
->
i_type
&
CONFIG_HINT
)
/* ignore hints */
continue
;
/* Ignore deprecated options */
if
(
p_item
->
psz_current
)
continue
;
if
(
p_item
->
b_unsaveable
)
/*obvious*/
continue
;
if
(
b_autosave
&&
!
p_item
->
b_autosave
)
{
i_value
=
p_item
->
saved
.
i
;
f_value
=
p_item
->
saved
.
f
;
psz_value
=
p_item
->
saved
.
psz
;
if
(
!
psz_value
)
psz_value
=
p_item
->
orig
.
psz
;
}
else
{
p_item
->
b_dirty
=
VLC_FALSE
;
}
switch
(
p_item
->
i_type
)
{
case
CONFIG_ITEM_BOOL
:
case
CONFIG_ITEM_INTEGER
:
if
(
p_item
->
psz_text
)
fprintf
(
file
,
"# %s (%s)
\n
"
,
p_item
->
psz_text
,
(
p_item
->
i_type
==
CONFIG_ITEM_BOOL
)
?
_
(
"boolean"
)
:
_
(
"integer"
)
);
if
(
i_value
==
p_item
->
orig
.
i
)
fputc
(
'#'
,
file
);
fprintf
(
file
,
"%s=%i
\n
"
,
p_item
->
psz_name
,
i_value
);
p_item
->
saved
.
i
=
i_value
;
break
;
case
CONFIG_ITEM_KEY
:
if
(
p_item
->
psz_text
)
fprintf
(
file
,
"# %s (%s)
\n
"
,
p_item
->
psz_text
,
_
(
"key"
)
);
if
(
i_value
==
p_item
->
orig
.
i
)
fputc
(
'#'
,
file
);
psz_key
=
ConfigKeyToString
(
i_value
);
fprintf
(
file
,
"%s=%s
\n
"
,
p_item
->
psz_name
,
psz_key
?
psz_key
:
""
);
free
(
psz_key
);
p_item
->
saved
.
i
=
i_value
;
break
;
case
CONFIG_ITEM_FLOAT
:
if
(
p_item
->
psz_text
)
fprintf
(
file
,
"# %s (%s)
\n
"
,
p_item
->
psz_text
,
_
(
"float"
)
);
if
(
f_value
==
p_item
->
orig
.
f
)
fputc
(
'#'
,
file
);
fprintf
(
file
,
"%s=%f
\n
"
,
p_item
->
psz_name
,
(
double
)
f_value
);
p_item
->
saved
.
f
=
f_value
;
break
;
default:
if
(
p_item
->
psz_text
)
fprintf
(
file
,
"# %s (%s)
\n
"
,
p_item
->
psz_text
,
_
(
"string"
)
);
if
(
(
!
psz_value
&&
!
p_item
->
orig
.
psz
)
||
(
psz_value
&&
p_item
->
orig
.
psz
&&
!
strcmp
(
psz_value
,
p_item
->
orig
.
psz
))
)
fputc
(
'#'
,
file
);
fprintf
(
file
,
"%s=%s
\n
"
,
p_item
->
psz_name
,
psz_value
?:
""
);
if
(
b_autosave
&&
!
p_item
->
b_autosave
)
break
;
free
((
char
*
)
p_item
->
saved
.
psz
);
if
(
(
psz_value
&&
p_item
->
orig
.
psz
&&
strcmp
(
psz_value
,
p_item
->
orig
.
psz
))
||
!
psz_value
||
!
p_item
->
orig
.
psz
)
p_item
->
saved
.
psz
=
strdupnull
(
psz_value
);
else
p_item
->
saved
.
psz
=
NULL
;
}
}
fputc
(
'\n'
,
file
);
}
vlc_list_release
(
p_list
);
/*
* 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
);
return
0
;
}
int
config_AutoSaveConfigFile
(
vlc_object_t
*
p_this
)
{
vlc_list_t
*
p_list
;
int
i_index
,
i_count
;
if
(
!
p_this
)
return
-
1
;
/* 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
*
p_parser
=
(
module_t
*
)
p_list
->
p_values
[
i_index
].
p_object
;
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
++
)
{
if
(
p_item
->
b_autosave
&&
p_item
->
b_dirty
)
break
;
}
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
,
VLC_TRUE
);
}
int
__config_SaveConfigFile
(
vlc_object_t
*
p_this
,
const
char
*
psz_module_name
)
{
return
SaveConfigFile
(
p_this
,
psz_module_name
,
VLC_FALSE
);
}
/*****************************************************************************
* config_LoadCmdLine: parse command line
*****************************************************************************
* Parse command line for configuration options.
* Now that the module_bank has been initialized, we can dynamically
* generate the longopts structure used by getops. We have to do it this way
* because we don't know (and don't want to know) in advance the configuration
* options used (ie. exported) by each module.
*****************************************************************************/
int
__config_LoadCmdLine
(
vlc_object_t
*
p_this
,
int
*
pi_argc
,
const
char
*
ppsz_argv
[],
vlc_bool_t
b_ignore_errors
)
{
int
i_cmd
,
i_index
,
i_opts
,
i_shortopts
,
flag
,
i_verbose
=
0
;
module_t
*
p_parser
;
vlc_list_t
*
p_list
;
struct
option
*
p_longopts
;
int
i_modules_index
;
/* Short options */
module_config_t
*
pp_shortopts
[
256
];
char
*
psz_shortopts
;
/* Set default configuration and copy arguments */
p_this
->
p_libvlc
->
i_argc
=
*
pi_argc
;
p_this
->
p_libvlc
->
ppsz_argv
=
ppsz_argv
;
#ifdef __APPLE__
/* When VLC.app is run by double clicking in Mac OS X, the 2nd arg
* is the PSN - process serial number (a unique PID-ish thingie)
* still ok for real Darwin & when run from command line */
if
(
(
*
pi_argc
>
1
)
&&
(
strncmp
(
ppsz_argv
[
1
]
,
"-psn"
,
4
)
==
0
)
)
/* for example -psn_0_9306113 */
{
/* GDMF!... I can't do this or else the MacOSX window server will
* not pick up the PSN and not register the app and we crash...
* hence the following kludge otherwise we'll get confused w/ argv[1]
* being an input file name */
#if 0
ppsz_argv[ 1 ] = NULL;
#endif
*
pi_argc
=
*
pi_argc
-
1
;
pi_argc
--
;
return
0
;
}
#endif
/* List all modules */
p_list
=
vlc_list_find
(
p_this
,
VLC_OBJECT_MODULE
,
FIND_ANYWHERE
);
/*
* Generate the longopts and shortopts structures used by getopt_long
*/
i_opts
=
0
;
for
(
i_modules_index
=
0
;
i_modules_index
<
p_list
->
i_count
;
i_modules_index
++
)
{
p_parser
=
(
module_t
*
)
p_list
->
p_values
[
i_modules_index
].
p_object
;
/* count the number of exported configuration options (to allocate
* longopts). We also need to allocate space for two options when
* dealing with boolean to allow for --foo and --no-foo */
i_opts
+=
p_parser
->
i_config_items
+
2
*
p_parser
->
i_bool_items
;
}
p_longopts
=
malloc
(
sizeof
(
struct
option
)
*
(
i_opts
+
1
)
);
if
(
p_longopts
==
NULL
)
{
msg_Err
(
p_this
,
"out of memory"
);
vlc_list_release
(
p_list
);
return
-
1
;
}
psz_shortopts
=
malloc
(
sizeof
(
char
)
*
(
2
*
i_opts
+
1
)
);
if
(
psz_shortopts
==
NULL
)
{
msg_Err
(
p_this
,
"out of memory"
);
free
(
p_longopts
);
vlc_list_release
(
p_list
);
return
-
1
;
}
/* If we are requested to ignore errors, then we must work on a copy
* of the ppsz_argv array, otherwise getopt_long will reorder it for
* us, ignoring the arity of the options */
if
(
b_ignore_errors
)
{
ppsz_argv
=
(
const
char
**
)
malloc
(
*
pi_argc
*
sizeof
(
char
*
)
);
if
(
ppsz_argv
==
NULL
)
{
msg_Err
(
p_this
,
"out of memory"
);
free
(
psz_shortopts
);
free
(
p_longopts
);
vlc_list_release
(
p_list
);
return
-
1
;
}
memcpy
(
ppsz_argv
,
p_this
->
p_libvlc
->
ppsz_argv
,
*
pi_argc
*
sizeof
(
char
*
)
);
}
i_shortopts
=
0
;
for
(
i_index
=
0
;
i_index
<
256
;
i_index
++
)
{
pp_shortopts
[
i_index
]
=
NULL
;
}
/* Fill the p_longopts and psz_shortopts structures */
i_index
=
0
;
for
(
i_modules_index
=
0
;
i_modules_index
<
p_list
->
i_count
;
i_modules_index
++
)
{
module_config_t
*
p_item
,
*
p_end
;
p_parser
=
(
module_t
*
)
p_list
->
p_values
[
i_modules_index
].
p_object
;
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
++
)
{
/* Ignore hints */
if
(
p_item
->
i_type
&
CONFIG_HINT
)
continue
;
/* Add item to long options */
p_longopts
[
i_index
].
name
=
strdup
(
p_item
->
psz_name
);
if
(
p_longopts
[
i_index
].
name
==
NULL
)
continue
;
p_longopts
[
i_index
].
has_arg
=
(
p_item
->
i_type
==
CONFIG_ITEM_BOOL
)
?
no_argument
:
required_argument
;
p_longopts
[
i_index
].
flag
=
&
flag
;
p_longopts
[
i_index
].
val
=
0
;
i_index
++
;
/* When dealing with bools we also need to add the --no-foo
* option */
if
(
p_item
->
i_type
==
CONFIG_ITEM_BOOL
)
{
char
*
psz_name
=
malloc
(
strlen
(
p_item
->
psz_name
)
+
3
);
if
(
psz_name
==
NULL
)
continue
;
strcpy
(
psz_name
,
"no"
);
strcat
(
psz_name
,
p_item
->
psz_name
);
p_longopts
[
i_index
].
name
=
psz_name
;
p_longopts
[
i_index
].
has_arg
=
no_argument
;
p_longopts
[
i_index
].
flag
=
&
flag
;
p_longopts
[
i_index
].
val
=
1
;
i_index
++
;
psz_name
=
malloc
(
strlen
(
p_item
->
psz_name
)
+
4
);
if
(
psz_name
==
NULL
)
continue
;
strcpy
(
psz_name
,
"no-"
);
strcat
(
psz_name
,
p_item
->
psz_name
);
p_longopts
[
i_index
].
name
=
psz_name
;
p_longopts
[
i_index
].
has_arg
=
no_argument
;
p_longopts
[
i_index
].
flag
=
&
flag
;
p_longopts
[
i_index
].
val
=
1
;
i_index
++
;
}
/* If item also has a short option, add it */
if
(
p_item
->
i_short
)
{
pp_shortopts
[(
int
)
p_item
->
i_short
]
=
p_item
;
psz_shortopts
[
i_shortopts
]
=
p_item
->
i_short
;
i_shortopts
++
;
if
(
p_item
->
i_type
!=
CONFIG_ITEM_BOOL
)
{
psz_shortopts
[
i_shortopts
]
=
':'
;
i_shortopts
++
;
if
(
p_item
->
i_short
==
'v'
)
{
psz_shortopts
[
i_shortopts
]
=
':'
;
i_shortopts
++
;
}
}
}
}
}
/* We don't need the module list anymore */
vlc_list_release
(
p_list
);
/* Close the longopts and shortopts structures */
memset
(
&
p_longopts
[
i_index
],
0
,
sizeof
(
struct
option
)
);
psz_shortopts
[
i_shortopts
]
=
'\0'
;
/*
* Parse the command line options
*/
opterr
=
0
;
optind
=
0
;
/* set to 0 to tell GNU getopt to reinitialize */
while
(
(
i_cmd
=
getopt_long
(
*
pi_argc
,
(
char
**
)
ppsz_argv
,
psz_shortopts
,
p_longopts
,
&
i_index
)
)
!=
-
1
)
{
/* A long option has been recognized */
if
(
i_cmd
==
0
)
{
module_config_t
*
p_conf
;
char
*
psz_name
=
(
char
*
)
p_longopts
[
i_index
].
name
;
/* Check if we deal with a --nofoo or --no-foo long option */
if
(
flag
)
psz_name
+=
psz_name
[
2
]
==
'-'
?
3
:
2
;
/* Store the configuration option */
p_conf
=
config_FindConfig
(
p_this
,
psz_name
);
if
(
p_conf
)
{
/* Check if the option is deprecated */
if
(
p_conf
->
psz_current
)
{
if
(
p_conf
->
b_strict
)
{
fprintf
(
stderr
,
"Warning: option --%s no longer exists.
\n
"
,
p_conf
->
psz_name
);
continue
;
}
fprintf
(
stderr
,
"%s: option --%s is deprecated. Use --%s instead.
\n
"
,
b_ignore_errors
?
"Warning"
:
"Error"
,
p_conf
->
psz_name
,
p_conf
->
psz_current
);
if
(
!
b_ignore_errors
)
{
/*free */
for
(
i_index
=
0
;
p_longopts
[
i_index
].
name
;
i_index
++
)
free
(
(
char
*
)
p_longopts
[
i_index
].
name
);
free
(
p_longopts
);
free
(
psz_shortopts
);
return
-
1
;
}
psz_name
=
(
char
*
)
p_conf
->
psz_current
;
p_conf
=
config_FindConfig
(
p_this
,
psz_name
);
}
switch
(
p_conf
->
i_type
)
{
case
CONFIG_ITEM_STRING
:
case
CONFIG_ITEM_PASSWORD
:
case
CONFIG_ITEM_FILE
:
case
CONFIG_ITEM_DIRECTORY
:
case
CONFIG_ITEM_MODULE
:
case
CONFIG_ITEM_MODULE_LIST
:
case
CONFIG_ITEM_MODULE_LIST_CAT
:
case
CONFIG_ITEM_MODULE_CAT
:
config_PutPsz
(
p_this
,
psz_name
,
optarg
);
break
;
case
CONFIG_ITEM_INTEGER
:
config_PutInt
(
p_this
,
psz_name
,
strtol
(
optarg
,
0
,
0
));
break
;
case
CONFIG_ITEM_FLOAT
:
config_PutFloat
(
p_this
,
psz_name
,
(
float
)
atof
(
optarg
)
);
break
;
case
CONFIG_ITEM_KEY
:
config_PutInt
(
p_this
,
psz_name
,
ConfigStringToKey
(
optarg
)
);
break
;
case
CONFIG_ITEM_BOOL
:
config_PutInt
(
p_this
,
psz_name
,
!
flag
);
break
;
}
continue
;
}
}
/* A short option has been recognized */
if
(
pp_shortopts
[
i_cmd
]
!=
NULL
)
{
switch
(
pp_shortopts
[
i_cmd
]
->
i_type
)
{
case
CONFIG_ITEM_STRING
:
case
CONFIG_ITEM_PASSWORD
:
case
CONFIG_ITEM_FILE
:
case
CONFIG_ITEM_DIRECTORY
:
case
CONFIG_ITEM_MODULE
:
case
CONFIG_ITEM_MODULE_CAT
:
case
CONFIG_ITEM_MODULE_LIST
:
case
CONFIG_ITEM_MODULE_LIST_CAT
:
config_PutPsz
(
p_this
,
pp_shortopts
[
i_cmd
]
->
psz_name
,
optarg
);
break
;
case
CONFIG_ITEM_INTEGER
:
if
(
i_cmd
==
'v'
)
{
if
(
optarg
)
{
if
(
*
optarg
==
'v'
)
/* eg. -vvv */
{
i_verbose
++
;
while
(
*
optarg
==
'v'
)
{
i_verbose
++
;
optarg
++
;
}
}
else
{
i_verbose
+=
atoi
(
optarg
);
/* eg. -v2 */
}
}
else
{
i_verbose
++
;
/* -v */
}
config_PutInt
(
p_this
,
pp_shortopts
[
i_cmd
]
->
psz_name
,
i_verbose
);
}
else
{
config_PutInt
(
p_this
,
pp_shortopts
[
i_cmd
]
->
psz_name
,
strtol
(
optarg
,
0
,
0
)
);
}
break
;
case
CONFIG_ITEM_BOOL
:
config_PutInt
(
p_this
,
pp_shortopts
[
i_cmd
]
->
psz_name
,
1
);
break
;
}
continue
;
}
/* Internal error: unknown option */
if
(
!
b_ignore_errors
)
{
fprintf
(
stderr
,
"%s: unknown option"
" or missing mandatory argument "
,
p_this
->
p_libvlc
->
psz_object_name
);
if
(
optopt
)
{
fprintf
(
stderr
,
"`-%c'
\n
"
,
optopt
);
}
else
{
fprintf
(
stderr
,
"`%s'
\n
"
,
ppsz_argv
[
optind
-
1
]
);
}
fprintf
(
stderr
,
"Try `%s --help' for more information.
\n
"
,
p_this
->
p_libvlc
->
psz_object_name
);
for
(
i_index
=
0
;
p_longopts
[
i_index
].
name
;
i_index
++
)
free
(
(
char
*
)
p_longopts
[
i_index
].
name
);
free
(
p_longopts
);
free
(
psz_shortopts
);
return
-
1
;
}
}
/* Free allocated resources */
for
(
i_index
=
0
;
p_longopts
[
i_index
].
name
;
i_index
++
)
free
(
(
char
*
)
p_longopts
[
i_index
].
name
);
free
(
p_longopts
);
free
(
psz_shortopts
);
if
(
b_ignore_errors
)
free
(
ppsz_argv
);
return
0
;
}
/**
* config_GetDataDir: find directory where shared data is installed
*
...
...
@@ -1974,104 +996,6 @@ char *config_GetCacheDir( libvlc_int_t *p_libvlc )
#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
)
{
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
;
}
static
char
*
ConfigKeyToString
(
int
i_key
)
{
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
;
}
/* Adds an extra interface to the configuration */
void
__config_AddIntf
(
vlc_object_t
*
p_this
,
const
char
*
psz_intf
)
{
...
...
src/config/file.c
0 → 100644
View file @
2d9c9ee6
/*****************************************************************************
* file.c: configuration file handling
*****************************************************************************
* Copyright (C) 2001-2007 the VideoLAN team
* $Id$
*
* Authors: Gildas Bazin <gbazin@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.
*****************************************************************************/
#include <vlc/vlc.h>
#include "../libvlc.h"
#include "vlc_charset.h"
#include "vlc_keys.h"
#include <errno.h>
/* errno */
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#include "config.h"
#include "modules/modules.h"
static
char
*
ConfigKeyToString
(
int
);
static
inline
char
*
strdupnull
(
const
char
*
src
)
{
return
src
?
strdup
(
src
)
:
NULL
;
}
static
inline
char
*
_strdupnull
(
const
char
*
src
)
{
return
src
?
strdup
(
_
(
src
))
:
NULL
;
}
static
FILE
*
config_OpenConfigFile
(
vlc_object_t
*
p_obj
,
const
char
*
mode
)
{
char
*
psz_filename
=
p_obj
->
p_libvlc
->
psz_configfile
;
FILE
*
p_stream
;
if
(
!
psz_filename
)
{
psz_filename
=
config_GetConfigFile
(
p_obj
->
p_libvlc
);
}
msg_Dbg
(
p_obj
,
"opening config file (%s)"
,
psz_filename
);
p_stream
=
utf8_fopen
(
psz_filename
,
mode
);
if
(
p_stream
==
NULL
&&
errno
!=
ENOENT
)
{
msg_Err
(
p_obj
,
"cannot open config file (%s): %m"
,
psz_filename
);
}
#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
;
}
static
int
strtoi
(
const
char
*
str
)
{
char
*
end
;
long
l
;
errno
=
0
;
l
=
strtol
(
str
,
&
end
,
0
);
if
(
!
errno
)
{
if
((
l
>
INT_MAX
)
||
(
l
<
INT_MIN
))
errno
=
ERANGE
;
if
(
*
end
)
errno
=
EINVAL
;
}
return
(
int
)
l
;
}
/*****************************************************************************
* 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
)
{
vlc_list_t
*
p_list
;
FILE
*
file
;
file
=
config_OpenConfigFile
(
p_this
,
"rt"
);
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
);
/* Look for UTF-8 Byte Order Mark */
char
*
(
*
convert
)
(
const
char
*
)
=
strdupnull
;
char
bom
[
3
];
if
((
fread
(
bom
,
1
,
3
,
file
)
!=
3
)
||
memcmp
(
bom
,
"
\xEF\xBB\xBF
"
,
3
))
{
convert
=
FromLocaleDup
;
rewind
(
file
);
/* no BOM, rewind */
}
module_t
*
module
=
NULL
;
char
line
[
1024
],
section
[
1022
];
section
[
0
]
=
'\0'
;
while
(
fgets
(
line
,
1024
,
file
)
!=
NULL
)
{
/* Ignore comments and empty lines */
switch
(
line
[
0
])
{
case
'#'
:
case
'\n'
:
case
'\0'
:
continue
;
}
if
(
line
[
0
]
==
'['
)
{
char
*
ptr
=
strchr
(
line
,
']'
);
if
(
ptr
==
NULL
)
continue
;
/* syntax error; */
*
ptr
=
'\0'
;
/* New section ( = a given module) */
strcpy
(
section
,
line
+
1
);
module
=
NULL
;
if
((
psz_module_name
==
NULL
)
||
(
strcmp
(
psz_module_name
,
section
)
==
0
))
{
for
(
int
i
=
0
;
i
<
p_list
->
i_count
;
i
++
)
{
module_t
*
m
=
(
module_t
*
)
p_list
->
p_values
[
i
].
p_object
;
if
((
strcmp
(
section
,
m
->
psz_object_name
)
==
0
)
&&
(
m
->
i_config_items
>
0
))
/* ignore config-less modules */
{
module
=
m
;
if
(
psz_module_name
!=
NULL
)
msg_Dbg
(
p_this
,
"loading config for module
\"
%s
\"
"
,
section
);
break
;
}
}
}
continue
;
}
if
(
module
==
NULL
)
continue
;
/* no need to parse if there is no matching module */
char
*
ptr
=
strchr
(
line
,
'\n'
);
if
(
ptr
!=
NULL
)
*
ptr
=
'\0'
;
/* look for option name */
const
char
*
psz_option_name
=
line
;
ptr
=
strchr
(
line
,
'='
);
if
(
ptr
==
NULL
)
continue
;
/* syntax error */
*
ptr
=
'\0'
;
const
char
*
psz_option_value
=
ptr
+
1
;
/* try to match this option with one of the module's options */
for
(
size_t
i
=
0
;
i
<
module
->
confsize
;
i
++
)
{
module_config_t
*
p_item
=
module
->
p_config
+
i
;
if
((
p_item
->
i_type
&
CONFIG_HINT
)
||
strcmp
(
p_item
->
psz_name
,
psz_option_name
))
continue
;
/* We found it */
errno
=
0
;
switch
(
p_item
->
i_type
)
{
case
CONFIG_ITEM_BOOL
:
case
CONFIG_ITEM_INTEGER
:
{
long
l
=
strtoi
(
psz_option_value
);
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
;
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
->
saved
.
f
=
p_item
->
value
.
f
;
break
;
case
CONFIG_ITEM_KEY
:
if
(
!*
psz_option_value
)
break
;
/* ignore empty option */
p_item
->
value
.
i
=
ConfigStringToKey
(
psz_option_value
);
p_item
->
saved
.
i
=
p_item
->
value
.
i
;
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
;
}
}
if
(
ferror
(
file
))
{
msg_Err
(
p_this
,
"error reading configuration: %m"
);
clearerr
(
file
);
}
fclose
(
file
);
vlc_list_release
(
p_list
);
vlc_mutex_unlock
(
&
p_this
->
p_libvlc
->
config_lock
);
return
0
;
}
/*****************************************************************************
* config_CreateDir: Create configuration directory if it doesn't exist.
*****************************************************************************/
int
config_CreateDir
(
vlc_object_t
*
p_this
,
const
char
*
psz_dirname
)
{
if
(
!
psz_dirname
&&
!*
psz_dirname
)
return
-
1
;
if
(
utf8_mkdir
(
psz_dirname
,
0700
)
==
0
)
return
0
;
switch
(
errno
)
{
case
EEXIST
:
return
0
;
case
ENOENT
:
{
/* Let's try to create the parent directory */
char
psz_parent
[
strlen
(
psz_dirname
)
+
1
],
*
psz_end
;
strcpy
(
psz_parent
,
psz_dirname
);
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
,
0700
)
)
return
0
;
}
}
}
}
msg_Err
(
p_this
,
"could not create %s: %m"
,
psz_dirname
);
return
-
1
;
}
/*****************************************************************************
* config_SaveConfigFile: Save a module's config options.
*****************************************************************************
* This will save the specified module's config options to the config file.
* If psz_module_name is NULL then we save all the modules config options.
* It's no use to save the config options that kept their default values, so
* we'll try to be a bit clever here.
*
* When we save we mustn't delete the config options of the modules that
* haven't been loaded. So we cannot just create a new config file with the
* config structures we've got in memory.
* I don't really know how to deal with this nicely, so I will use a completly
* dumb method ;-)
* I will load the config file in memory, but skipping all the sections of the
* modules we want to save. Then I will create a brand new file, dump the file
* loaded in memory and then append the sections of the modules we want to
* save.
* Really stupid no ?
*****************************************************************************/
static
int
SaveConfigFile
(
vlc_object_t
*
p_this
,
const
char
*
psz_module_name
,
vlc_bool_t
b_autosave
)
{
module_t
*
p_parser
;
vlc_list_t
*
p_list
;
FILE
*
file
;
char
p_line
[
1024
],
*
p_index2
;
int
i_sizebuf
=
0
;
char
*
p_bigbuffer
,
*
p_index
;
vlc_bool_t
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
)
{
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
);
}
file
=
config_OpenConfigFile
(
p_this
,
"rt"
);
if
(
file
!=
NULL
)
{
/* look for file size */
fseek
(
file
,
0L
,
SEEK_END
);
i_sizebuf
=
ftell
(
file
);
fseek
(
file
,
0L
,
SEEK_SET
);
}
p_bigbuffer
=
p_index
=
malloc
(
i_sizebuf
+
1
);
if
(
!
p_bigbuffer
)
{
msg_Err
(
p_this
,
"out of memory"
);
if
(
file
)
fclose
(
file
);
vlc_mutex_unlock
(
&
p_this
->
p_libvlc
->
config_lock
);
return
-
1
;
}
p_bigbuffer
[
0
]
=
0
;
/* List all available modules */
p_list
=
vlc_list_find
(
p_this
,
VLC_OBJECT_MODULE
,
FIND_ANYWHERE
);
/* backup file into memory, we only need to backup the sections we won't
* save later on */
b_backup
=
0
;
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
++
)
{
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
,
strlen
(
p_parser
->
psz_object_name
)
)
)
{
if
(
!
psz_module_name
)
break
;
else
if
(
!
strcmp
(
psz_module_name
,
p_parser
->
psz_object_name
)
)
break
;
}
}
if
(
i_index
==
p_list
->
i_count
)
{
/* we don't have this section in our list so we need to back
* it up */
*
p_index2
=
0
;
#if 0
msg_Dbg( p_this, "backing up config for unknown module \"%s\"",
&p_line[1] );
#endif
*
p_index2
=
']'
;
b_backup
=
1
;
}
else
{
b_backup
=
0
;
}
}
/* save line if requested and line is valid (doesn't begin with a
* space, tab, or eol) */
if
(
b_backup
&&
(
p_line
[
0
]
!=
'\n'
)
&&
(
p_line
[
0
]
!=
' '
)
&&
(
p_line
[
0
]
!=
'\t'
)
)
{
strcpy
(
p_index
,
p_line
);
p_index
+=
strlen
(
p_line
);
}
}
if
(
file
)
fclose
(
file
);
/*
* Save module config in file
*/
file
=
config_OpenConfigFile
(
p_this
,
"wt"
);
if
(
!
file
)
{
vlc_list_release
(
p_list
);
free
(
p_bigbuffer
);
vlc_mutex_unlock
(
&
p_this
->
p_libvlc
->
config_lock
);
return
-
1
;
}
fprintf
(
file
,
"
\xEF\xBB\xBF
###
\n
### "
COPYRIGHT_MESSAGE
"
\n
###
\n\n
"
"###
\n
### lines begining with a '#' character are comments
\n
###
\n\n
"
);
/* Look for the selected module, if NULL then save everything */
for
(
i_index
=
0
;
i_index
<
p_list
->
i_count
;
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
)
)
continue
;
if
(
!
p_parser
->
i_config_items
)
continue
;
if
(
psz_module_name
)
msg_Dbg
(
p_this
,
"saving config for module
\"
%s
\"
"
,
p_parser
->
psz_object_name
);
fprintf
(
file
,
"[%s]"
,
p_parser
->
psz_object_name
);
if
(
p_parser
->
psz_longname
)
fprintf
(
file
,
" # %s
\n\n
"
,
p_parser
->
psz_longname
);
else
fprintf
(
file
,
"
\n\n
"
);
for
(
p_item
=
p_parser
->
p_config
,
p_end
=
p_item
+
p_parser
->
confsize
;
p_item
<
p_end
;
p_item
++
)
{
char
*
psz_key
;
int
i_value
=
p_item
->
value
.
i
;
float
f_value
=
p_item
->
value
.
f
;
const
char
*
psz_value
=
p_item
->
value
.
psz
;
if
(
p_item
->
i_type
&
CONFIG_HINT
)
/* ignore hints */
continue
;
/* Ignore deprecated options */
if
(
p_item
->
psz_current
)
continue
;
if
(
p_item
->
b_unsaveable
)
/*obvious*/
continue
;
if
(
b_autosave
&&
!
p_item
->
b_autosave
)
{
i_value
=
p_item
->
saved
.
i
;
f_value
=
p_item
->
saved
.
f
;
psz_value
=
p_item
->
saved
.
psz
;
if
(
!
psz_value
)
psz_value
=
p_item
->
orig
.
psz
;
}
else
{
p_item
->
b_dirty
=
VLC_FALSE
;
}
switch
(
p_item
->
i_type
)
{
case
CONFIG_ITEM_BOOL
:
case
CONFIG_ITEM_INTEGER
:
if
(
p_item
->
psz_text
)
fprintf
(
file
,
"# %s (%s)
\n
"
,
p_item
->
psz_text
,
(
p_item
->
i_type
==
CONFIG_ITEM_BOOL
)
?
_
(
"boolean"
)
:
_
(
"integer"
)
);
if
(
i_value
==
p_item
->
orig
.
i
)
fputc
(
'#'
,
file
);
fprintf
(
file
,
"%s=%i
\n
"
,
p_item
->
psz_name
,
i_value
);
p_item
->
saved
.
i
=
i_value
;
break
;
case
CONFIG_ITEM_KEY
:
if
(
p_item
->
psz_text
)
fprintf
(
file
,
"# %s (%s)
\n
"
,
p_item
->
psz_text
,
_
(
"key"
)
);
if
(
i_value
==
p_item
->
orig
.
i
)
fputc
(
'#'
,
file
);
psz_key
=
ConfigKeyToString
(
i_value
);
fprintf
(
file
,
"%s=%s
\n
"
,
p_item
->
psz_name
,
psz_key
?
psz_key
:
""
);
free
(
psz_key
);
p_item
->
saved
.
i
=
i_value
;
break
;
case
CONFIG_ITEM_FLOAT
:
if
(
p_item
->
psz_text
)
fprintf
(
file
,
"# %s (%s)
\n
"
,
p_item
->
psz_text
,
_
(
"float"
)
);
if
(
f_value
==
p_item
->
orig
.
f
)
fputc
(
'#'
,
file
);
fprintf
(
file
,
"%s=%f
\n
"
,
p_item
->
psz_name
,
(
double
)
f_value
);
p_item
->
saved
.
f
=
f_value
;
break
;
default:
if
(
p_item
->
psz_text
)
fprintf
(
file
,
"# %s (%s)
\n
"
,
p_item
->
psz_text
,
_
(
"string"
)
);
if
(
(
!
psz_value
&&
!
p_item
->
orig
.
psz
)
||
(
psz_value
&&
p_item
->
orig
.
psz
&&
!
strcmp
(
psz_value
,
p_item
->
orig
.
psz
))
)
fputc
(
'#'
,
file
);
fprintf
(
file
,
"%s=%s
\n
"
,
p_item
->
psz_name
,
psz_value
?:
""
);
if
(
b_autosave
&&
!
p_item
->
b_autosave
)
break
;
free
((
char
*
)
p_item
->
saved
.
psz
);
if
(
(
psz_value
&&
p_item
->
orig
.
psz
&&
strcmp
(
psz_value
,
p_item
->
orig
.
psz
))
||
!
psz_value
||
!
p_item
->
orig
.
psz
)
p_item
->
saved
.
psz
=
strdupnull
(
psz_value
);
else
p_item
->
saved
.
psz
=
NULL
;
}
}
fputc
(
'\n'
,
file
);
}
vlc_list_release
(
p_list
);
/*
* 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
);
return
0
;
}
int
config_AutoSaveConfigFile
(
vlc_object_t
*
p_this
)
{
vlc_list_t
*
p_list
;
int
i_index
,
i_count
;
if
(
!
p_this
)
return
-
1
;
/* 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
*
p_parser
=
(
module_t
*
)
p_list
->
p_values
[
i_index
].
p_object
;
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
++
)
{
if
(
p_item
->
b_autosave
&&
p_item
->
b_dirty
)
break
;
}
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
,
VLC_TRUE
);
}
int
__config_SaveConfigFile
(
vlc_object_t
*
p_this
,
const
char
*
psz_module_name
)
{
return
SaveConfigFile
(
p_this
,
psz_module_name
,
VLC_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
;
}
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
;
}
char
*
ConfigKeyToString
(
int
i_key
)
{
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
;
}
src/config/intf.c
0 → 100644
View file @
2d9c9ee6
/*****************************************************************************
* intf.c: interface configuration handling
*****************************************************************************
* Copyright (C) 2001-2007 the VideoLAN team
* $Id$
*
* Authors: Gildas Bazin <gbazin@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.
*****************************************************************************/
#include <vlc/vlc.h>
#include "../libvlc.h"
#include "vlc_keys.h"
#include "vlc_charset.h"
#include <errno.h>
/* errno */
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
/* getuid() */
#endif
#ifdef HAVE_GETOPT_LONG
# ifdef HAVE_GETOPT_H
# include <getopt.h>
/* getopt() */
# endif
#else
# include "../extras/getopt.h"
#endif
#if defined(HAVE_GETPWUID)
# include <pwd.h>
/* getpwuid() */
#endif
#if defined( HAVE_SYS_STAT_H )
# include <sys/stat.h>
#endif
#if defined( HAVE_SYS_TYPES_H )
# include <sys/types.h>
#endif
#if defined( WIN32 )
# if !defined( UNDER_CE )
# include <direct.h>
# endif
#include <tchar.h>
#endif
#include "configuration.h"
#include "modules/modules.h"
/* Adds an extra interface to the configuration */
void
__config_AddIntf
(
vlc_object_t
*
p_this
,
const
char
*
psz_intf
)
{
assert
(
psz_intf
);
char
*
psz_config
,
*
psz_parser
;
size_t
i_len
=
strlen
(
psz_intf
);
psz_config
=
psz_parser
=
config_GetPsz
(
p_this
->
p_libvlc
,
"control"
);
while
(
psz_parser
)
{
if
(
!
strncmp
(
psz_intf
,
psz_parser
,
i_len
)
)
{
free
(
psz_config
);
return
;
}
psz_parser
=
strchr
(
psz_parser
,
':'
);
if
(
psz_parser
)
psz_parser
++
;
/* skip the ':' */
}
free
(
psz_config
);
psz_config
=
psz_parser
=
config_GetPsz
(
p_this
->
p_libvlc
,
"extraintf"
);
while
(
psz_parser
)
{
if
(
!
strncmp
(
psz_intf
,
psz_parser
,
i_len
)
)
{
free
(
psz_config
);
return
;
}
psz_parser
=
strchr
(
psz_parser
,
':'
);
if
(
psz_parser
)
psz_parser
++
;
/* skip the ':' */
}
/* interface not found in the config, let's add it */
if
(
psz_config
&&
strlen
(
psz_config
)
>
0
)
{
char
*
psz_newconfig
;
if
(
asprintf
(
&
psz_newconfig
,
"%s:%s"
,
psz_config
,
psz_intf
)
!=
-
1
)
{
config_PutPsz
(
p_this
->
p_libvlc
,
"extraintf"
,
psz_newconfig
);
free
(
psz_newconfig
);
}
}
else
config_PutPsz
(
p_this
->
p_libvlc
,
"extraintf"
,
psz_intf
);
free
(
psz_config
);
}
/* Removes an extra interface from the configuration */
void
__config_RemoveIntf
(
vlc_object_t
*
p_this
,
const
char
*
psz_intf
)
{
assert
(
psz_intf
);
char
*
psz_config
,
*
psz_parser
;
size_t
i_len
=
strlen
(
psz_intf
);
psz_config
=
psz_parser
=
config_GetPsz
(
p_this
->
p_libvlc
,
"extraintf"
);
while
(
psz_parser
)
{
if
(
!
strncmp
(
psz_intf
,
psz_parser
,
i_len
)
)
{
char
*
psz_newconfig
;
char
*
psz_end
=
psz_parser
+
i_len
;
if
(
*
psz_end
==
':'
)
psz_end
++
;
*
psz_parser
=
'\0'
;
if
(
asprintf
(
&
psz_newconfig
,
"%s%s"
,
psz_config
,
psz_end
)
!=
-
1
)
{
config_PutPsz
(
p_this
->
p_libvlc
,
"extraintf"
,
psz_newconfig
);
free
(
psz_newconfig
);
}
break
;
}
psz_parser
=
strchr
(
psz_parser
,
':'
);
if
(
psz_parser
)
psz_parser
++
;
/* skip the ':' */
}
free
(
psz_config
);
psz_config
=
psz_parser
=
config_GetPsz
(
p_this
->
p_libvlc
,
"control"
);
while
(
psz_parser
)
{
if
(
!
strncmp
(
psz_intf
,
psz_parser
,
i_len
)
)
{
char
*
psz_newconfig
;
char
*
psz_end
=
psz_parser
+
i_len
;
if
(
*
psz_end
==
':'
)
psz_end
++
;
*
psz_parser
=
'\0'
;
if
(
asprintf
(
&
psz_newconfig
,
"%s%s"
,
psz_config
,
psz_end
)
!=
-
1
)
{
config_PutPsz
(
p_this
->
p_libvlc
,
"control"
,
psz_newconfig
);
free
(
psz_newconfig
);
}
break
;
}
psz_parser
=
strchr
(
psz_parser
,
':'
);
if
(
psz_parser
)
psz_parser
++
;
/* skip the ':' */
}
free
(
psz_config
);
}
/*
* Returns VLC_TRUE if the specified extra interface is present in the
* configuration, VLC_FALSE if not
*/
vlc_bool_t
__config_ExistIntf
(
vlc_object_t
*
p_this
,
const
char
*
psz_intf
)
{
assert
(
psz_intf
);
char
*
psz_config
,
*
psz_parser
;
size_t
i_len
=
strlen
(
psz_intf
);
psz_config
=
psz_parser
=
config_GetPsz
(
p_this
->
p_libvlc
,
"extraintf"
);
while
(
psz_parser
)
{
if
(
!
strncmp
(
psz_parser
,
psz_intf
,
i_len
)
)
{
free
(
psz_config
);
return
VLC_TRUE
;
}
psz_parser
=
strchr
(
psz_parser
,
':'
);
if
(
psz_parser
)
psz_parser
++
;
/* skip the ':' */
}
free
(
psz_config
);
psz_config
=
psz_parser
=
config_GetPsz
(
p_this
->
p_libvlc
,
"control"
);
while
(
psz_parser
)
{
if
(
!
strncmp
(
psz_parser
,
psz_intf
,
i_len
)
)
{
free
(
psz_config
);
return
VLC_TRUE
;
}
psz_parser
=
strchr
(
psz_parser
,
':'
);
if
(
psz_parser
)
psz_parser
++
;
/* skip the ':' */
}
free
(
psz_config
);
return
VLC_FALSE
;
}
src/libvlc-common.c
View file @
2d9c9ee6
...
...
@@ -37,7 +37,7 @@
#include <vlc_input.h>
#include "modules/modules.h"
#include "
modules/configuration
.h"
#include "
config/config
.h"
#include <errno.h>
/* ENOMEM */
#include <stdio.h>
/* sprintf() */
...
...
src/modules/modules.c
View file @
2d9c9ee6
...
...
@@ -76,7 +76,7 @@
# endif
#endif
#include "
modules/configuration
.h"
#include "
config/config
.h"
#include "libvlc.h"
#include "vlc_charset.h"
...
...
src/playlist/loadsave.c
View file @
2d9c9ee6
...
...
@@ -24,7 +24,7 @@
#include <vlc_playlist.h>
#include <vlc_events.h>
#include "playlist_internal.h"
#include "
modules/configuration
.h"
#include "
config/config
.h"
#include <vlc_charset.h>
#include <sys/types.h>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment