예제 #1
0
static void default_values(starter_config_t *cfg)
{
	if (cfg == NULL)
		return;

	memset(cfg, 0, sizeof(struct starter_config));

	/* is there enough space for all seen flags? */
	assert(KW_SETUP_LAST - KW_SETUP_FIRST <
		sizeof(cfg->setup.seen) * BITS_PER_BYTE);
	assert(KW_CONN_LAST  - KW_CONN_FIRST <
		sizeof(cfg->conn_default.seen) * BITS_PER_BYTE);
	assert(KW_END_LAST - KW_END_FIRST <
		sizeof(cfg->conn_default.right.seen) * BITS_PER_BYTE);
	assert(KW_CA_LAST - KW_CA_FIRST <
		sizeof(cfg->ca_default.seen) * BITS_PER_BYTE);

	cfg->setup.seen        = SEEN_NONE;
	cfg->setup.uniqueids   = TRUE;

#ifdef START_CHARON
	cfg->setup.charonstart = TRUE;
#endif

	cfg->conn_default.seen    = SEEN_NONE;
	cfg->conn_default.startup = STARTUP_NO;
	cfg->conn_default.state   = STATE_IGNORE;
	cfg->conn_default.mode    = MODE_TUNNEL;
	cfg->conn_default.options = SA_OPTION_MOBIKE;

	cfg->conn_default.ike                   = strdupnull(ike_defaults);
	cfg->conn_default.esp                   = strdupnull(esp_defaults);
	cfg->conn_default.sa_ike_life_seconds   = IKE_LIFETIME_DEFAULT;
	cfg->conn_default.sa_ipsec_life_seconds = IPSEC_LIFETIME_DEFAULT;
	cfg->conn_default.sa_rekey_margin       = SA_REPLACEMENT_MARGIN_DEFAULT;
	cfg->conn_default.sa_rekey_fuzz         = SA_REPLACEMENT_FUZZ_DEFAULT;
	cfg->conn_default.sa_keying_tries       = SA_REPLACEMENT_RETRIES_DEFAULT;
	cfg->conn_default.install_policy        = TRUE;
	cfg->conn_default.dpd_delay             =  30; /* seconds */
	cfg->conn_default.dpd_timeout           = 150; /* seconds */

	cfg->conn_default.left.seen  = SEEN_NONE;
	cfg->conn_default.right.seen = SEEN_NONE;

	cfg->conn_default.left.sendcert  = CERT_SEND_IF_ASKED;
	cfg->conn_default.right.sendcert = CERT_SEND_IF_ASKED;

	cfg->conn_default.left.ikeport = 500;
	cfg->conn_default.right.ikeport = 500;

	cfg->conn_default.left.to_port = 0xffff;
	cfg->conn_default.right.to_port = 0xffff;

	cfg->ca_default.seen = SEEN_NONE;
}
예제 #2
0
파일: core.c 프로젝트: Aakash-729/vlc
/*****************************************************************************
 * config_GetPsz: get the string value of a string variable
 *****************************************************************************
 * This function is used to get the value of variables which are internally
 * represented by a string (CONFIG_ITEM_STRING, CONFIG_ITEM_*FILE,
 * CONFIG_ITEM_DIRECTORY, CONFIG_ITEM_PASSWORD, and CONFIG_ITEM_MODULE).
 *
 * Important note: remember to free() the returned char* because it's a
 *   duplicate of the actual value. It isn't safe to return a pointer to the
 *   actual value as it can be modified at any time.
 *****************************************************************************/
char * config_GetPsz( vlc_object_t *p_this, const char *psz_name )
{
    module_config_t *p_config;

    p_config = config_FindConfig( p_this, psz_name );

    /* sanity checks */
    if( !p_config )
    {
        msg_Err( p_this, "option %s does not exist", psz_name );
        return NULL;
    }

    if (!IsConfigStringType (p_config->i_type))
    {
        msg_Err( p_this, "option %s does not refer to a string", psz_name );
        return NULL;
    }

    /* return a copy of the string */
    vlc_rwlock_rdlock (&config_lock);
    char *psz_value = strdupnull (p_config->value.psz);
    vlc_rwlock_unlock (&config_lock);

    return psz_value;
}
예제 #3
0
/*
 * initialize a ca object with the default ca
 */
static void ca_default(char *name, starter_ca_t *ca, starter_ca_t *def)
{
	memcpy(ca, def, sizeof(starter_ca_t));
	ca->name = strdupnull(name);

	clone_args(KW_CA_FIRST, KW_CA_LAST, (char *)ca, (char *)def);
}
예제 #4
0
파일: core.c 프로젝트: paa/vlc
/*****************************************************************************
 * config_ResetAll: reset the configuration data for all the modules.
 *****************************************************************************/
void config_ResetAll( vlc_object_t *p_this )
{
    VLC_UNUSED(p_this);
    module_t *p_module;
    module_t **list = module_list_get (NULL);

    vlc_rwlock_wrlock (&config_lock);
    for (size_t j = 0; (p_module = list[j]) != NULL; j++)
    {
        if( p_module->b_submodule ) continue;

        for (size_t i = 0; i < p_module->confsize; i++ )
        {
            module_config_t *p_config = p_module->p_config + i;

            if (IsConfigIntegerType (p_config->i_type))
                p_config->value.i = p_config->orig.i;
            else
            if (IsConfigFloatType (p_config->i_type))
                p_config->value.f = p_config->orig.f;
            else
            if (IsConfigStringType (p_config->i_type))
            {
                free ((char *)p_config->value.psz);
                p_config->value.psz =
                        strdupnull (p_config->orig.psz);
            }
        }
    }
    vlc_rwlock_unlock (&config_lock);

    module_list_free (list);
}
예제 #5
0
/* TODO : documenation */
void
emphasis_cover_change(Emphasis_Gui *gui, char *artist, char *album)
{
  Cover_Info *ci;
  Cover_Info *old;

  ci = malloc(sizeof(Cover_Info));
  if(ci == NULL) { return; }

  ci->artist = strdupnull(artist);
  ci->album  = strdupnull(album);

  old = gui->cover_queue;
  gui->cover_queue = ci;

  emphasis_cover_clear_queue(old);
}
예제 #6
0
/*
 * initialize a conn object with the default conn
 */
static void conn_default(char *name, starter_conn_t *conn, starter_conn_t *def)
{
	memcpy(conn, def, sizeof(starter_conn_t));
	conn->name = strdupnull(name);

	clone_args(KW_CONN_FIRST, KW_CONN_LAST, (char *)conn, (char *)def);
	clone_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->left, (char *)&def->left);
	clone_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->right, (char *)&def->right);
}
예제 #7
0
/*
 * parse a ca section
 */
static void load_ca(starter_ca_t *ca, kw_list_t *kw, starter_config_t *cfg)
{
	char *ca_name = (ca->name == NULL)? "%default":ca->name;

	for ( ; kw; kw = kw->next)
	{
		bool assigned = FALSE;

		kw_token_t token = kw->entry->token;

		if (token == KW_AUTO)
		{
			token = KW_CA_SETUP;
		}
		else if (token == KW_ALSO)
		{
			if (cfg->parse_also)
			{
				also_t *also = malloc_thing(also_t);

				also->name = strdupnull(kw->value);
				also->next = ca->also;
				ca->also = also;

				DBG2(DBG_APP, "  also=%s", kw->value);
			}
			continue;
		}

		if (token < KW_CA_FIRST || token > KW_CA_LAST)
		{
			DBG1(DBG_APP, "# unsupported keyword '%s' in ca '%s'",
				 kw->entry->name, ca_name);
			cfg->err++;
			continue;
		}

		if (is_deprecated(token, kw, ca_name))
		{
			cfg->non_fatal_err++;
			continue;
		}

		if (!assign_arg(token, KW_CA_FIRST, kw, (char *)ca, &assigned))
		{
			DBG1(DBG_APP, "  bad argument value in ca '%s'", ca_name);
			cfg->err++;
		}
	}

	/* treat 'route' and 'start' as 'add' */
	if (ca->startup != STARTUP_NO)
		ca->startup = STARTUP_ADD;
}
예제 #8
0
파일: confread.c 프로젝트: mikma/strongswan
/*
 * handles left|rightfirewall and left|rightupdown parameters
 */
static void handle_firewall(const char *label, starter_end_t *end,
							starter_config_t *cfg)
{
	if (end->firewall)
	{
		if (end->updown != NULL)
		{
			DBG1(DBG_APP, "# cannot have both %sfirewall and %supdown", label,
				 label);
			cfg->err++;
		}
		else
		{
			end->updown = strdupnull(firewall_defaults);
			end->firewall = FALSE;
		}
	}
}
예제 #9
0
파일: file.c 프로젝트: banketree/faplayer
/*****************************************************************************
 * 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,
                           bool b_autosave )
{
    module_t *p_parser;
    char *permanent = NULL, *temporary = NULL;

    if( config_PrepareDir( p_this ) )
    {
        msg_Err( p_this, "no configuration directory" );
        return -1;
    }

    /* List all available modules */
    module_t **list = module_list_get (NULL);

    char *bigbuf = NULL;
    size_t bigsize = 0;
    FILE *file = config_OpenConfigFile (p_this);
    if (file != NULL)
    {
        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;
        }

        bigsize = (st.st_size < LONG_MAX) ? st.st_size : 0;
        bigbuf = malloc (bigsize + 1);
        if (bigbuf == NULL)
            goto error;

        /* backup file into memory, we only need to backup the sections we
         * won't save later on */
        char *p_index = bigbuf;
        char *line = NULL;
        size_t bufsize;
        ssize_t linelen;
        bool backup = false;

        while ((linelen = getline (&line, &bufsize, file)) != -1)
        {
            char *p_index2;

            if ((line[0] == '[') && (p_index2 = strchr(line,']')))
            {
                /* we found a new section, check if we need to do a backup */
                backup = true;
                for (int i = 0; (p_parser = list[i]) != NULL; i++)
                {
                    if (!strncmp (line + 1, p_parser->psz_object_name,
                                  strlen (p_parser->psz_object_name))
                     && ((psz_module_name == NULL)
                      || !strcmp (psz_module_name, p_parser->psz_object_name)))
                    {
                        backup = false; /* no, we will rewrite it! */
                        break;
                    }
                }
            }

            /* save line if requested and line is valid (doesn't begin with a
             * space, tab, or eol) */
            if (backup && !memchr ("\n\t ", line[0], 3))
            {
                memcpy (p_index, line, linelen);
                p_index += linelen;
            }
        }
        fclose (file);
        file = NULL;
        free (line);
        *p_index = '\0';
        bigsize = p_index - bigbuf;
    }

    /*
     * Save module config in file
     */
    permanent = config_GetConfigFile (p_this);
    if (!permanent)
    {
        module_list_free (list);
        goto error;
    }

    if (asprintf (&temporary, "%s.%u", permanent, getpid ()) == -1)
    {
        temporary = NULL;
        module_list_free (list);
        goto error;
    }

    /* 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 (int i = 0; (p_parser = list[i]) != NULL; i++)
    {
        module_config_t *p_item, *p_end;

        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++ )
        {
            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))
            {
                int64_t val = b_retain ? p_item->saved.i : p_item->value.i;
                config_Write (file, p_item->psz_text,
                              (p_item->i_type == CONFIG_ITEM_BOOL)
                                  ? N_("boolean") : N_("integer"),
                              val == p_item->orig.i,
                              p_item->psz_name, "%"PRId64, val);
                p_item->saved.i = val;
            }
            else
            if (IsConfigFloatType (p_item->i_type))
            {
                float val = b_retain ? p_item->saved.f : p_item->value.f;
                config_Write (file, p_item->psz_text, N_("float"),
                              val == p_item->orig.f,
                              p_item->psz_name, "%f", val);
                p_item->saved.f = val;
            }
            else
            {
                const char *psz_value = b_retain ? p_item->saved.psz
                                                 : p_item->value.psz;
                bool modified;

                assert (IsConfigStringType (p_item->i_type));

                if (b_retain && (psz_value == NULL)) /* FIXME: hack */
                    psz_value = p_item->orig.psz;

                modified =
                    (psz_value != NULL)
                        ? ((p_item->orig.psz != NULL)
                            ? (strcmp (psz_value, p_item->orig.psz) != 0)
                            : true)
                        : (p_item->orig.psz != NULL);

                config_Write (file, p_item->psz_text, N_("string"),
                              !modified, p_item->psz_name, "%s",
                              psz_value ? psz_value : "");

                if ( !b_retain )
                {

                    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;
                }
            }

            if (!b_retain)
                p_item->b_dirty = false;
        }
    }
    vlc_rwlock_unlock (&config_lock);

    module_list_free (list);
    if (loc != (locale_t)0)
    {
        uselocale (baseloc);
        freelocale (loc);
    }

    /*
     * Restore old settings from the config in file
     */
    if (bigsize)
        fwrite (bigbuf, 1, bigsize, file);

    /*
     * 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);
    free (bigbuf);
    return 0;

error:
    if( file )
        fclose( file );
    free (temporary);
    free (permanent);
    free (bigbuf);
    return -1;
}
예제 #10
0
파일: file.c 프로젝트: banketree/faplayer
/*****************************************************************************
 * 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 )
{
    FILE *file;

    file = config_OpenConfigFile (p_this);
    if (file == NULL)
        return VLC_EGENERIC;

    /* 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 */
    }

    char *line = NULL;
    size_t bufsize;
    ssize_t linelen;

    /* Ensure consistent number formatting... */
    locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
    locale_t baseloc = uselocale (loc);

    vlc_rwlock_wrlock (&config_lock);
    while ((linelen = getline (&line, &bufsize, file)) != -1)
    {
        line[linelen - 1] = '\0'; /* trim newline */

        /* Ignore comments, section and empty lines */
        if (memchr ("#[", line[0], 3) != NULL)
            continue;

        /* look for option name */
        const char *psz_option_name = line;

        char *ptr = strchr (line, '=');
        if (ptr == NULL)
            continue; /* syntax error */
        *ptr = '\0';

        module_config_t *item = config_FindConfig (p_this, psz_option_name);
        if (item == NULL)
            continue;

        const char *psz_option_value = ptr + 1;
        switch (item->i_type)
        {
            case CONFIG_ITEM_BOOL:
            case CONFIG_ITEM_INTEGER:
            {
                int64_t l;

                errno = 0;
                l = strtoi (psz_option_value);
                if ((l > item->max.i) || (l < item->min.i))
                    errno = ERANGE;
                if (errno)
                    msg_Warn (p_this, "Integer value (%s) for %s: %m",
                              psz_option_value, psz_option_name);
                else
                    item->saved.i = item->value.i = l;
                break;
            }

            case CONFIG_ITEM_FLOAT:
                if (!*psz_option_value)
                    break;                    /* ignore empty option */
                item->value.f = (float)atof (psz_option_value);
                item->saved.f = item->value.f;
                break;

            default:
                free ((char *)item->value.psz);
                free ((char *)item->saved.psz);
                item->value.psz = convert (psz_option_value);
                item->saved.psz = strdupnull (item->value.psz);
                break;
        }
    }
    vlc_rwlock_unlock (&config_lock);
    free (line);

    if (ferror (file))
    {
        msg_Err (p_this, "error reading configuration: %m");
        clearerr (file);
    }
    fclose (file);

    if (loc != (locale_t)0)
    {
        uselocale (baseloc);
        freelocale (loc);
    }
    return 0;
}
예제 #11
0
파일: confread.c 프로젝트: mikma/strongswan
/*
 * parse left|right specific options
 */
static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token,
				   char *key, char *value, starter_config_t *cfg)
{
	bool assigned = FALSE;

	if (is_deprecated(token, key, conn->name))
	{
		cfg->non_fatal_err++;
		return;
	}

	if (!assign_arg(token, KW_END_FIRST, key, value, end, &assigned))
	{
		goto err;
	}

	/* post processing of some keywords that were assigned automatically */
	switch (token)
	{
		case KW_HOST:
			if (value && strlen(value) > 0 && value[0] == '%')
			{
				if (streq(value, "%defaultroute"))
				{
					value = "%any";
				}
				if (!streq(value, "%any") && !streq(value, "%any4") &&
					!streq(value, "%any6"))
				{	/* allow_any prefix */
					end->allow_any = TRUE;
					value++;
				}
			}
			free(end->host);
			end->host = strdupnull(value);
			break;
		case KW_SOURCEIP:
			conn->mode = MODE_TUNNEL;
			conn->proxy_mode = FALSE;
			break;
		case KW_SENDCERT:
			if (end->sendcert == CERT_YES_SEND)
			{
				end->sendcert = CERT_ALWAYS_SEND;
			}
			else if (end->sendcert == CERT_NO_SEND)
			{
				end->sendcert = CERT_NEVER_SEND;
			}
			break;
		default:
			break;
	}

	if (assigned)
	{
		return;
	}

	/* individual processing of keywords that were not assigned automatically */
	switch (token)
	{
		case KW_PROTOPORT:
		{
			struct protoent *proto;
			struct servent *svc;
			char *sep, *port = "", *endptr;
			long int p;

			sep = strchr(value, '/');
			if (sep)
			{	/* protocol/port */
				*sep = '\0';
				port = sep + 1;
			}

			if (streq(value, "%any"))
			{
				end->protocol = 0;
			}
			else
			{
				proto = getprotobyname(value);
				if (proto)
				{
					end->protocol = proto->p_proto;
				}
				else
				{
					p = strtol(value, &endptr, 0);
					if ((*value && *endptr) || p < 0 || p > 0xff)
					{
						DBG1(DBG_APP, "# bad protocol: %s=%s", key, value);
						goto err;
					}
					end->protocol = (uint8_t)p;
				}
			}
			if (streq(port, "%any"))
			{
				end->from_port = 0;
				end->to_port = 0xffff;
			}
			else if (streq(port, "%opaque"))
			{
				end->from_port = 0xffff;
				end->to_port = 0;
			}
			else if (*port)
			{
				svc = getservbyname(port, NULL);
				if (svc)
				{
					end->from_port = end->to_port = ntohs(svc->s_port);
				}
				else
				{
					p = strtol(port, &endptr, 0);
					if (p < 0 || p > 0xffff)
					{
						DBG1(DBG_APP, "# bad port: %s=%s", key, port);
						goto err;
					}
					end->from_port = p;
					if (*endptr == '-')
					{
						port = endptr + 1;
						p = strtol(port, &endptr, 0);
						if (p < 0 || p > 0xffff)
						{
							DBG1(DBG_APP, "# bad port: %s=%s", key, port);
							goto err;
						}
					}
					end->to_port = p;
					if (*endptr)
					{
						DBG1(DBG_APP, "# bad port: %s=%s", key, port);
						goto err;
					}
				}
			}
			if (sep)
			{	/* restore the original text in case also= is used */
				*sep = '/';
			}
			break;
		}
		default:
			break;
	}
	return;

err:
	DBG1(DBG_APP, "  bad argument value in conn '%s'", conn->name);
	cfg->err++;
}
예제 #12
0
파일: file.c 프로젝트: FLYKingdom/vlc
/*****************************************************************************
 * 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,
                           bool b_autosave )
{
    module_t *p_parser;
    FILE *file = NULL;
    char *permanent = NULL, *temporary = NULL;
    char p_line[1024], *p_index2;
    unsigned long i_sizebuf = 0;
    char *p_bigbuffer = NULL, *p_index;
    bool b_backup;
    int i_index;

    if( config_PrepareDir( p_this ) )
    {
        msg_Err( p_this, "no configuration directory" );
        goto error;
    }

    file = config_OpenConfigFile( p_this );
    if( file != NULL )
    {
        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 )
        goto error;
    p_bigbuffer[0] = 0;

    /* List all available modules */
    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 = 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; (p_parser = list[i_index]) != NULL; i_index++ )
            {
                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( list[i_index] == NULL )
            {
                /* 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 = true;
            }
            else
            {
                b_backup = false;
            }
        }

        /* 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 );
    file = NULL;

    /*
     * Save module config in file
     */
    permanent = config_GetConfigFile (p_this);
    if (!permanent)
    {
        module_list_free (list);
        goto error;
    }

    if (asprintf (&temporary, "%s.%u", permanent, getpid ()) == -1)
    {
        temporary = NULL;
        module_list_free (list);
        goto error;
    }

    /* 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 = utf8_open (temporary, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);
    if (fd == -1)
    {
        vlc_mutex_unlock (&lock);
        module_list_free (list);
        goto error;
    }
    file = fdopen (fd, "wt");
    if (file == NULL)
    {
        close (fd);
        vlc_mutex_unlock (&lock);
        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" );

    /* Ensure consistent number formatting... */
    locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
    locale_t baseloc = uselocale (loc);

    /* Look for the selected module, if NULL then save everything */
    for( i_index = 0; (p_parser = list[i_index]) != NULL; i_index++ )
    {
        module_config_t *p_item, *p_end;

        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++ )
        {
            if ((p_item->i_type & CONFIG_HINT) /* ignore hint */
             || p_item->b_removed              /* ignore deprecated option */
             || p_item->b_unsaveable)          /* ignore volatile option */
                continue;

            vlc_mutex_lock (p_item->p_lock);

            /* 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;
                if (p_item->i_type == CONFIG_ITEM_KEY)
                {
                    char *psz_key = ConfigKeyToString (val);
                    config_Write (file, p_item->psz_text, N_("key"),
                                  val == p_item->orig.i,
                                  p_item->psz_name, "%s",
                                  psz_key ? psz_key : "");
                    free (psz_key);
                }
                else
                    config_Write (file, p_item->psz_text,
                                  (p_item->i_type == CONFIG_ITEM_BOOL)
                                      ? N_("boolean") : N_("integer"),
                                  val == p_item->orig.i,
                                  p_item->psz_name, "%d", val);
                p_item->saved.i = val;
            }
            else
            if (IsConfigFloatType (p_item->i_type))
            {
                float val = b_retain ? p_item->saved.f : p_item->value.f;
                config_Write (file, p_item->psz_text, N_("float"),
                              val == p_item->orig.f,
                              p_item->psz_name, "%f", val);
                p_item->saved.f = val;
            }
            else
            {
                const char *psz_value = b_retain ? p_item->saved.psz
                                                 : p_item->value.psz;
                bool modified;

                assert (IsConfigStringType (p_item->i_type));

                if (b_retain && (psz_value == NULL)) /* FIXME: hack */
                    psz_value = p_item->orig.psz;

                modified =
                    (psz_value != NULL)
                        ? ((p_item->orig.psz != NULL)
                            ? (strcmp (psz_value, p_item->orig.psz) != 0)
                            : true)
                        : (p_item->orig.psz != NULL);

                config_Write (file, p_item->psz_text, N_("string"),
                              !modified, p_item->psz_name, "%s",
                              psz_value ? psz_value : "");

                if ( !b_retain )
                {

                    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;
                }
            }

            if (!b_retain)
                p_item->b_dirty = false;
            vlc_mutex_unlock (p_item->p_lock);
        }
    }

    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 );

    /*
     * Flush to disk and replace atomically
     */
    fflush (file); /* Flush from run-time */
#ifndef WIN32
    fdatasync (fd); /* Flush from OS */
    /* Atomically replace the file... */
    if (utf8_rename (temporary, permanent))
        utf8_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 */
    utf8_unlink (permanent);
    if (utf8_rename (temporary, permanent))
        utf8_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;
}
예제 #13
0
파일: file.c 프로젝트: FLYKingdom/vlc
/*****************************************************************************
 * 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 )
{
    FILE *file;

    file = config_OpenConfigFile (p_this);
    if (file == NULL)
        return VLC_EGENERIC;

    /* Look for the selected module, if NULL then save everything */
    module_t **list = module_list_get (NULL);

    /* 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; list[i]; i++)
                {
                    module_t *m = list[i];

                    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;

            vlc_mutex_lock( p_item->p_lock );
            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:
                    /* 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);
                    break;
            }
            vlc_mutex_unlock( p_item->p_lock );
            break;
        }
    }

    if (ferror (file))
    {
        msg_Err (p_this, "error reading configuration: %m");
        clearerr (file);
    }
    fclose (file);

    module_list_free (list);
    if (loc != (locale_t)0)
    {
        uselocale (baseloc);
        freelocale (loc);
    }
    return 0;
}
예제 #14
0
/*
 * parse a conn section
 */
static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
{
	char *conn_name = (conn->name == NULL)? "%default":conn->name;

	for ( ; kw; kw = kw->next)
	{
		bool assigned = FALSE;

		kw_token_t token = kw->entry->token;

		if (token >= KW_LEFT_FIRST && token <= KW_LEFT_LAST)
		{
			kw_end(conn, &conn->left, token - KW_LEFT_FIRST + KW_END_FIRST
				,  kw, conn_name, cfg);
			continue;
		}
		else if (token >= KW_RIGHT_FIRST && token <= KW_RIGHT_LAST)
		{
			kw_end(conn, &conn->right, token - KW_RIGHT_FIRST + KW_END_FIRST
				 , kw, conn_name, cfg);
			continue;
		}

		if (token == KW_AUTO)
		{
			token = KW_CONN_SETUP;
		}
		else if (token == KW_ALSO)
		{
			if (cfg->parse_also)
			{
				also_t *also = malloc_thing(also_t);

				also->name = strdupnull(kw->value);
				also->next = conn->also;
				conn->also = also;

				DBG2(DBG_APP, "  also=%s", kw->value);
			}
			continue;
		}

		if (token < KW_CONN_FIRST || token > KW_CONN_LAST)
		{
			DBG1(DBG_APP, "# unsupported keyword '%s' in conn '%s'",
				 kw->entry->name, conn_name);
			cfg->err++;
			continue;
		}

		if (is_deprecated(token, kw, conn_name))
		{
			cfg->non_fatal_err++;
			continue;
		}

		if (!assign_arg(token, KW_CONN_FIRST, kw, (char *)conn, &assigned))
		{
			DBG1(DBG_APP, "  bad argument value in conn '%s'", conn_name);
			cfg->err++;
			continue;
		}

		if (assigned)
			continue;

		switch (token)
		{
		case KW_TYPE:
			conn->mode = MODE_TRANSPORT;
			conn->proxy_mode = FALSE;
			if (streq(kw->value, "tunnel"))
			{
				conn->mode = MODE_TUNNEL;
			}
			else if (streq(kw->value, "beet"))
			{
				conn->mode = MODE_BEET;
			}
			else if (streq(kw->value, "transport_proxy"))
			{
				conn->mode = MODE_TRANSPORT;
				conn->proxy_mode = TRUE;
			}
			else if (streq(kw->value, "passthrough") || streq(kw->value, "pass"))
			{
				conn->mode = MODE_PASS;
			}
			else if (streq(kw->value, "drop") || streq(kw->value, "reject"))
			{
				conn->mode = MODE_DROP;
			}
			else if (!streq(kw->value, "transport"))
			{
				DBG1(DBG_APP, "# bad policy value: %s=%s", kw->entry->name,
					 kw->value);
				cfg->err++;
			}
			break;
		case KW_COMPRESS:
			KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_COMPRESS)
			break;
		case KW_AUTH:
			KW_SA_OPTION_FLAG("ah", "esp", SA_OPTION_AUTHENTICATE)
			break;
		case KW_MARK:
			if (!handle_mark(kw->value, &conn->mark_in))
			{
				cfg->err++;
				break;
			}
			conn->mark_out = conn->mark_in;
			break;
		case KW_MARK_IN:
			if (!handle_mark(kw->value, &conn->mark_in))
			{
				cfg->err++;
			}
			break;
		case KW_MARK_OUT:
			if (!handle_mark(kw->value, &conn->mark_out))
			{
				cfg->err++;
			}
			break;
		case KW_TFC:
			if (streq(kw->value, "%mtu"))
			{
				conn->tfc = -1;
			}
			else
			{
				char *endptr;

				conn->tfc = strtoul(kw->value, &endptr, 10);
				if (*endptr != '\0')
				{
					DBG1(DBG_APP, "# bad integer value: %s=%s", kw->entry->name,
						 kw->value);
					cfg->err++;
				}
			}
			break;
		case KW_KEYINGTRIES:
			if (streq(kw->value, "%forever"))
			{
				conn->sa_keying_tries = 0;
			}
			else
			{
				char *endptr;

				conn->sa_keying_tries = strtoul(kw->value, &endptr, 10);
				if (*endptr != '\0')
				{
					DBG1(DBG_APP, "# bad integer value: %s=%s", kw->entry->name,
						 kw->value);
					cfg->err++;
				}
			}
			break;
		case KW_REKEY:
			KW_SA_OPTION_FLAG("no", "yes", SA_OPTION_DONT_REKEY)
			break;
		case KW_REAUTH:
			KW_SA_OPTION_FLAG("no", "yes", SA_OPTION_DONT_REAUTH)
			break;
		case KW_MOBIKE:
			KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_MOBIKE)
			break;
		case KW_FORCEENCAPS:
			KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_FORCE_ENCAP)
			break;
		case KW_MODECONFIG:
			KW_SA_OPTION_FLAG("push", "pull", SA_OPTION_MODECFG_PUSH)
			break;
		case KW_XAUTH:
			KW_SA_OPTION_FLAG("server", "client", SA_OPTION_XAUTH_SERVER)
			break;
		default:
			break;
		}
	}

	handle_firewall("left", &conn->left, cfg);
	handle_firewall("right", &conn->right, cfg);
}