📄 config_file.c
字号:
"%s:%d: Section header"
" must start in the first column",
file, ctx.line);
}
break;
case '#': /* Comment */
if (count == 0)
{
ch = skip_to_eoln(fd);
++ctx.line;
}
else
{
ch = EOF;
err = svn_error_createf (SVN_ERR_MALFORMED_FILE, NULL,
"%s:%d: Comment"
" must start in the first column",
file, ctx.line);
}
break;
case '\n': /* Empty line */
++ctx.line;
break;
case EOF: /* End of file or read error */
break;
default:
if (svn_stringbuf_isempty (ctx.section))
{
ch = EOF;
err = svn_error_createf (SVN_ERR_MALFORMED_FILE, NULL,
"%s:%d: Section header expected",
file, ctx.line);
}
else if (count != 0)
{
ch = EOF;
err = svn_error_createf (SVN_ERR_MALFORMED_FILE, NULL,
"%s:%d: Option expected",
file, ctx.line);
}
else
err = parse_option (&ch, &ctx);
break;
}
}
while (ch != EOF);
if (ferror (fd))
{
err = svn_error_createf (-1, /* FIXME: Wrong error code. */
NULL,
"%s:%d: Read error", file, ctx.line);
}
svn_pool_destroy (ctx.pool);
fclose (fd);
return err;
}
/* Helper for svn_config_ensure: see if ~/.subversion/auth/ and its
subdirs exist, try to create them, but don't throw errors on
failure. PATH is assumed to be a path to the user's private config
directory. */
static void
ensure_auth_dirs (const char *path,
apr_pool_t *pool)
{
svn_node_kind_t kind;
const char *auth_dir, *auth_subdir;
svn_error_t *err;
/* Ensure ~/.subversion/auth/ */
auth_dir = svn_path_join_many (pool, path, SVN_CONFIG__AUTH_SUBDIR, NULL);
err = svn_io_check_path (auth_dir, &kind, pool);
if (err || kind == svn_node_none)
{
svn_error_clear (err);
/* 'chmod 700' permissions: */
err = svn_io_dir_make (auth_dir,
(APR_UREAD | APR_UWRITE | APR_UEXECUTE),
pool);
if (err)
{
/* Don't try making subdirs if we can't make the top-level dir. */
svn_error_clear (err);
return;
}
}
/* If a provider exists that wants to store credentials in
~/.subversion, a subdirectory for the cred_kind must exist. */
auth_subdir = svn_path_join_many (pool, auth_dir,
SVN_AUTH_CRED_SIMPLE, NULL);
err = svn_io_check_path (auth_subdir, &kind, pool);
if (err || kind == svn_node_none)
{
svn_error_clear (err);
svn_error_clear (svn_io_dir_make (auth_subdir, APR_OS_DEFAULT, pool));
}
auth_subdir = svn_path_join_many (pool, auth_dir,
SVN_AUTH_CRED_USERNAME, NULL);
err = svn_io_check_path (auth_subdir, &kind, pool);
if (err || kind == svn_node_none)
{
svn_error_clear (err);
svn_error_clear (svn_io_dir_make (auth_subdir, APR_OS_DEFAULT, pool));
}
auth_subdir = svn_path_join_many (pool, auth_dir,
SVN_AUTH_CRED_SSL_SERVER_TRUST, NULL);
err = svn_io_check_path (auth_subdir, &kind, pool);
if (err || kind == svn_node_none)
{
svn_error_clear (err);
svn_error_clear (svn_io_dir_make (auth_subdir, APR_OS_DEFAULT, pool));
}
}
svn_error_t *
svn_config_ensure (const char *config_dir, apr_pool_t *pool)
{
const char *path;
svn_node_kind_t kind;
svn_error_t *err;
/* Ensure that the user-specific config directory exists. */
SVN_ERR (svn_config__user_config_path (config_dir, &path, NULL, pool));
if (! path)
return SVN_NO_ERROR;
SVN_ERR (svn_io_check_path (path, &kind, pool));
if (kind == svn_node_none)
{
err = svn_io_dir_make (path, APR_OS_DEFAULT, pool);
if (err)
{
/* Don't throw an error, but don't continue. */
svn_error_clear (err);
return SVN_NO_ERROR;
}
}
else
{
/* ### config directory already exists, but for the sake of
smooth upgrades, try to ensure that the auth/ subdirs exist
as well. we can remove this check someday in the future. */
ensure_auth_dirs (path, pool);
return SVN_NO_ERROR;
}
/* Else, there's a configuration directory. */
/* If we get errors trying to do things below, just stop and return
success. There's no _need_ to init a config directory if
something's preventing it. */
/** If non-existent, try to create a number of auth/ subdirectories. */
ensure_auth_dirs (path, pool);
/** Ensure that the `README.txt' file exists. **/
SVN_ERR (svn_config__user_config_path
(config_dir, &path, SVN_CONFIG__USR_README_FILE, pool));
if (! path) /* highly unlikely, since a previous call succeeded */
return SVN_NO_ERROR;
err = svn_io_check_path (path, &kind, pool);
if (err)
return SVN_NO_ERROR;
if (kind == svn_node_none)
{
apr_file_t *f;
const char *contents =
"This directory holds run-time configuration information for Subversion"
APR_EOL_STR
"clients. The configuration files all share the same syntax, but you"
APR_EOL_STR
"should examine a particular file to learn what configuration"
APR_EOL_STR
"directives are valid for that file."
APR_EOL_STR
APR_EOL_STR
"The syntax is standard INI format:"
APR_EOL_STR
APR_EOL_STR
" - Empty lines, and lines starting with '#', are ignored."
APR_EOL_STR
" The first significant line in a file must be a section header."
APR_EOL_STR
APR_EOL_STR
" - A section starts with a section header, which must start in"
APR_EOL_STR
" the first column:"
APR_EOL_STR
APR_EOL_STR
" [section-name]"
APR_EOL_STR
APR_EOL_STR
" - An option, which must always appear within a section, is a pair"
APR_EOL_STR
" (name, value). There are two valid forms for defining an"
APR_EOL_STR
" option, both of which must start in the first column:"
APR_EOL_STR
APR_EOL_STR
" name: value"
APR_EOL_STR
" name = value"
APR_EOL_STR
APR_EOL_STR
" Whitespace around the separator (:, =) is optional."
APR_EOL_STR
APR_EOL_STR
" - Section and option names are case-insensitive, but case is"
APR_EOL_STR
" preserved."
APR_EOL_STR
APR_EOL_STR
" - An option's value may be broken into several lines. The value"
APR_EOL_STR
" continuation lines must start with at least one whitespace."
APR_EOL_STR
" Trailing whitespace in the previous line, the newline character"
APR_EOL_STR
" and the leading whitespace in the continuation line is compressed"
APR_EOL_STR
" into a single space character."
APR_EOL_STR
APR_EOL_STR
" - All leading and trailing whitespace around a value is trimmed,"
APR_EOL_STR
" but the whitespace within a value is preserved, with the"
APR_EOL_STR
" exception of whitespace around line continuations, as"
APR_EOL_STR
" described above."
APR_EOL_STR
APR_EOL_STR
" - When a value is a boolean, any of the following strings are"
APR_EOL_STR
" recognised as truth values (case does not matter):"
APR_EOL_STR
APR_EOL_STR
" true false"
APR_EOL_STR
" yes no"
APR_EOL_STR
" on off"
APR_EOL_STR
" 1 0"
APR_EOL_STR
APR_EOL_STR
" - When a value is a list, it is comma-separated. Again, the"
APR_EOL_STR
" whitespace around each element of the list is trimmed."
APR_EOL_STR
APR_EOL_STR
" - Option values may be expanded within a value by enclosing the"
APR_EOL_STR
" option name in parentheses, preceded by a percent sign and"
APR_EOL_STR
" followed by an 's':"
APR_EOL_STR
APR_EOL_STR
" %(name)s"
APR_EOL_STR
APR_EOL_STR
" The expansion is performed recursively and on demand, during"
APR_EOL_STR
" svn_option_get. The name is first searched for in the same"
APR_EOL_STR
" section, then in the special [DEFAULT] section. If the name"
APR_EOL_STR
" is not found, the whole '%(name)s' placeholder is left"
APR_EOL_STR
" unchanged."
APR_EOL_STR
APR_EOL_STR
" Any modifications to the configuration data invalidate all"
APR_EOL_STR
" previously expanded values, so that the next svn_option_get"
APR_EOL_STR
" will take the modifications into account."
APR_EOL_STR
APR_EOL_STR
"The syntax of the configuration files is a subset of the one used by"
APR_EOL_STR
"Python's ConfigParser module; see"
APR_EOL_STR
APR_EOL_STR
" http://www.python.org/doc/current/lib/module-ConfigParser.html"
APR_EOL_STR
APR_EOL_STR
"Configuration data in the Windows registry"
APR_EOL_STR
"=========================================="
APR_EOL_STR
APR_EOL_STR
"On Windows, configuration data may also be stored in the registry. The"
APR_EOL_STR
"functions svn_config_read and svn_config_merge will read from the"
APR_EOL_STR
"registry when passed file names of the form:"
APR_EOL_STR
APR_EOL_STR
" REGISTRY:<hive>/path/to/config-key"
APR_EOL_STR
APR_EOL_STR
"The REGISTRY: prefix must be in upper case. The <hive> part must be"
APR_EOL_STR
"one of:"
APR_EOL_STR
APR_EOL_STR
" HKLM for HKEY_LOCAL_MACHINE"
APR_EOL_STR
" HKCU for HKEY_CURRENT_USER"
APR_EOL_STR
APR_EOL_STR
"The values in config-key represent the options in the [DEFAULT] section."
APR_EOL_STR
"The keys below config-key represent other sections, and their values"
APR_EOL_STR
"represent the options. Only values of type REG_SZ whose name doesn't"
APR_EOL_STR
"start with a '#' will be used; other values, as well as the keys'"
APR_EOL_STR
"default values, will be ignored."
APR_EOL_STR
APR_EOL_STR
APR_EOL_STR
"File locations"
APR_EOL_STR
"=============="
APR_EOL_STR
APR_EOL_STR
"Typically, Subversion uses two config directories, one for site-wide"
APR_EOL_STR
"configuration,"
APR_EOL_STR
APR_EOL_STR
" Unix:"
APR_EOL_STR
" /etc/subversion/servers"
APR_EOL_STR
" /etc/subversion/config"
APR_EOL_STR
" /etc/subversion/hairstyles"
APR_EOL_STR
" Windows:"
APR_EOL_STR
" %ALLUSERSPROFILE%\\Application Data\\Subversion\\servers"
APR_EOL_STR
" %ALLUSERSPROFILE%\\Application Data\\Subversion\\config"
APR_EOL_STR
" %ALLUSERSPROFILE%\\Application Data\\Subversion\\hairstyles"
APR_EOL_STR
" REGISTRY:HKLM\\Software\\Tigris.org\\Subversion\\Servers"
APR_EOL_STR
" REGISTRY:HKLM\\Software\\Tigris.org\\Subversion\\Config"
APR_EOL_STR
" REGISTRY:HKLM\\Software\\Tigris.org\\Subversion\\Hairstyles"
APR_EOL_STR
APR_EOL_STR
"and one for per-user configuration:"
APR_EOL_STR
APR_EOL_STR
" Unix:"
APR_EOL_STR
" ~/.subversion/servers"
APR_EOL_STR
" ~/.subversion/config"
APR_EOL_STR
" ~/.subversion/hairstyles"
APR_EOL_STR
" Windows:"
APR_EOL_STR
" %APPDATA%\\Subversion\\servers"
APR_EOL_STR
" %APPDATA%\\Subversion\\config"
APR_EOL_STR
" %APPDATA%\\Subversion\\hairstyles"
APR_EOL_STR
" REGISTRY:HKCU\\Software\\Tigris.org\\Subversion\\Servers"
APR_EOL_STR
" REGISTRY:HKCU\\Software\\Tigris.org\\Subversion\\Config"
APR_EOL_STR
" REGISTRY:HKCU\\Software\\Tigris.org\\Subversion\\Hairstyles"
APR_EOL_STR
APR_EOL_STR;
err = svn_io_file_open (&f, path,
(APR_WRITE | APR_CREATE | APR_EXCL),
APR_OS_DEFAULT,
pool);
if (! err)
{
SVN_ERR (svn_io_file_write_full (f, contents,
strlen (contents), NULL, pool));
SVN_ERR (svn_io_file_close (f, pool));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -