⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * file.c: configuration file handling ***************************************************************************** * Copyright (C) 2001-2007 the VideoLAN team * $Id: 894ebbb14e081062cd69a7f446e5881b0612b9a4 $ * * 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. *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include "../libvlc.h"#include "vlc_charset.h"#include "vlc_keys.h"#include <errno.h>                                                  /* errno */#include <assert.h>#include <limits.h>#ifdef __APPLE__#   include <xlocale.h>#else#include <locale.h>#endif#include "configuration.h"#include "modules/modules.h"static char *ConfigKeyToString( int );static inline char *strdupnull (const char *src){    return src ? strdup (src) : NULL;}/** * Get the user's configuration file */static char *config_GetConfigFile( void ){    char *psz_dir = config_GetUserConfDir();    char *psz_configfile;    if( asprintf( &psz_configfile, "%s" DIR_SEP CONFIG_FILE, psz_dir ) == -1 )        psz_configfile = NULL;    free( psz_dir );    return psz_configfile;}static FILE *config_OpenConfigFile( vlc_object_t *p_obj, const char *mode ){    char *psz_filename = libvlc_priv (p_obj->p_libvlc)->psz_configfile;    FILE *p_stream;    if( !psz_filename )    {        psz_filename = config_GetConfigFile();    }    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,                      config_GetHomeDir() ) != -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",                              config_GetHomeDir() ) != -1 )                {                    FILE *p_readme = utf8_fopen( psz_readme, "wt" );                    if( 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 );                }            }            free( psz_old );        }    }#endif    else if( p_stream != NULL )    {        libvlc_priv (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 ){    libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc);    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( &priv->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';    /* Ensure consistent number formatting... */    locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);    locale_t baseloc = uselocale (loc);    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)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 );    if (loc != (locale_t)0)    {        uselocale (baseloc);        freelocale (loc);    }    vlc_mutex_unlock( &priv->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;}static intconfig_Write (FILE *file, const char *type, const char *desc,              bool comment, const char *name, const char *fmt, ...){    va_list ap;    int ret;    if (desc == NULL)        desc = "?";    if (fprintf (file, "# %s (%s)\n%s%s=", desc, _(type),                 comment ? "#" : "", name) < 0)        return -1;    va_start (ap, fmt);    ret = vfprintf (file, fmt, ap);    va_end (ap);    if (ret < 0)        return -1;    if (fputs ("\n\n", file) == EOF)        return -1;    return 0;}/***************************************************************************** * config_SaveConfigFile: Save a module's config options.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -