]> git.sesse.net Git - vlc/blobdiff - src/config/file.c
Deinterlace: Add hotkey to cycle through deinterlace modes.
[vlc] / src / config / file.c
index df296188bca80404bb8f016b77af680b150af133..9ad9537e30d4de172c33339fe1d18776e93fbfcf 100644 (file)
@@ -1,24 +1,24 @@
 /*****************************************************************************
  * file.c: configuration file handling
  *****************************************************************************
- * Copyright (C) 2001-2007 the VideoLAN team
+ * Copyright (C) 2001-2007 VLC authors and VideoLAN
  * $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
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * You should have received a copy of the GNU Lesser 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
@@ -35,6 +35,9 @@
 #elif defined(HAVE_USELOCALE)
 #include <locale.h>
 #endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
 
 #include <vlc_common.h>
 #include "../libvlc.h"
@@ -42,6 +45,7 @@
 #include <vlc_fs.h>
 #include <vlc_keys.h>
 #include <vlc_modules.h>
+#include <vlc_plugin.h>
 
 #include "configuration.h"
 #include "modules/modules.h"
@@ -213,7 +217,7 @@ int config_LoadConfigFile( vlc_object_t *p_this )
             continue;
 
         const char *psz_option_value = ptr + 1;
-        switch (item->i_type)
+        switch (CONFIG_CLASS(item->i_type))
         {
             case CONFIG_ITEM_BOOL:
             case CONFIG_ITEM_INTEGER:
@@ -337,27 +341,13 @@ static int config_PrepareDir (vlc_object_t *obj)
     return ret;
 }
 
-/*****************************************************************************
- * config_SaveConfigFile: Save a module's 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)
+#undef config_SaveConfigFile
+/**
+ * Saves the in-memory configuration into a file.
+ * @return 0 on success, -1 on error.
+ */
+int config_SaveConfigFile (vlc_object_t *p_this)
 {
-    module_t *p_parser;
-    char *permanent = NULL, *temporary = NULL;
 
     if( config_PrepareDir( p_this ) )
     {
@@ -365,94 +355,36 @@ static int SaveConfigFile (vlc_object_t *p_this)
         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)
+    /*
+     * Save module config in file
+     */
+    char *temporary;
+    char *permanent = config_GetConfigFile (p_this);
+    if (permanent == NULL)
+        return -1;
+    if (asprintf (&temporary, "%s.%u", permanent, getpid ()) == -1)
+    {
+        free (permanent);
+        return -1;
+    }
+    else
     {
         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))
+        if (stat (permanent, &st) == 0 && !(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)))
-                    {
-                        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()
+    /* The temporary configuration file is per-PID. Therefore this function
      * should be serialized against itself within a given process. */
     static vlc_mutex_t lock = VLC_STATIC_MUTEX;
     vlc_mutex_lock (&lock);
@@ -462,17 +394,15 @@ static int SaveConfigFile (vlc_object_t *p_this)
     {
         vlc_rwlock_unlock (&config_lock);
         vlc_mutex_unlock (&lock);
-        module_list_free (list);
         goto error;
     }
-    file = fdopen (fd, "wt");
+    FILE *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;
     }
 
@@ -495,6 +425,8 @@ static int SaveConfigFile (vlc_object_t *p_this)
     vlc_rwlock_rdlock (&config_lock);*/
 
     /* Look for the selected module, if NULL then save everything */
+    module_t **list = module_list_get (NULL);
+    module_t *p_parser;
     for (int i = 0; (p_parser = list[i]) != NULL; i++)
     {
         module_config_t *p_item, *p_end;
@@ -502,7 +434,7 @@ static int SaveConfigFile (vlc_object_t *p_this)
         if( !p_parser->i_config_items )
             continue;
 
-        fprintf( file, "[%s]", p_parser->psz_object_name );
+        fprintf( file, "[%s]", module_get_object (p_parser) );
         if( p_parser->psz_longname )
             fprintf( file, " # %s\n\n", p_parser->psz_longname );
         else
@@ -521,7 +453,7 @@ static int SaveConfigFile (vlc_object_t *p_this)
             {
                 int64_t val = p_item->value.i;
                 config_Write (file, p_item->psz_text,
-                              (p_item->i_type == CONFIG_ITEM_BOOL)
+                             (CONFIG_CLASS(p_item->i_type) == CONFIG_ITEM_BOOL)
                                   ? N_("boolean") : N_("integer"),
                               val == p_item->orig.i,
                               p_item->psz_name, "%"PRId64, val);
@@ -547,7 +479,6 @@ static int SaveConfigFile (vlc_object_t *p_this)
                               !modified, p_item->psz_name, "%s",
                               psz_value ? psz_value : "");
             }
-            p_item->b_dirty = false;
         }
     }
     vlc_rwlock_unlock (&config_lock);
@@ -559,12 +490,6 @@ static int SaveConfigFile (vlc_object_t *p_this)
         freelocale (loc);
     }
 
-    /*
-     * Restore old settings from the config in file
-     */
-    if (bigsize)
-        fwrite (bigbuf, 1, bigsize, file);
-
     /*
      * Flush to disk and replace atomically
      */
@@ -574,7 +499,7 @@ static int SaveConfigFile (vlc_object_t *p_this)
         vlc_unlink (temporary);
         vlc_mutex_unlock (&lock);
         msg_Err (p_this, "cannot write configuration file");
-        clearerr (file);
+        fclose (file);
         goto error;
     }
 #if defined(__APPLE__) || defined(__ANDROID__)
@@ -599,54 +524,28 @@ static int SaveConfigFile (vlc_object_t *p_this)
 
     free (temporary);
     free (permanent);
-    free (bigbuf);
     return 0;
 
 error:
-    if( file )
-        fclose( file );
     free (temporary);
     free (permanent);
-    free (bigbuf);
     return -1;
 }
 
 int config_AutoSaveConfigFile( vlc_object_t *p_this )
 {
-    int ret = VLC_SUCCESS;
-    bool save = false;
+    int ret = 0;
 
     assert( p_this );
 
-    /* Check if there's anything to save */
-    module_t **list = module_list_get (NULL);
     vlc_rwlock_rdlock (&config_lock);
-    for (size_t i_index = 0; list[i_index] && !save; i_index++)
+    if (config_dirty)
     {
-        module_t *p_parser = list[i_index];
-        module_config_t *p_item, *p_end;
-
-        if( !p_parser->i_config_items ) continue;
-
-        for( p_item = p_parser->p_config, p_end = p_item + p_parser->confsize;
-             p_item < p_end && !save;
-             p_item++ )
-        {
-            save = p_item->b_dirty;
-        }
-    }
-
-    if (save)
         /* Note: this will get the read lock recursively. Ok. */
-        ret = SaveConfigFile (p_this);
+        ret = config_SaveConfigFile (p_this);
+        config_dirty = (ret != 0);
+    }
     vlc_rwlock_unlock (&config_lock);
 
-    module_list_free (list);
     return ret;
 }
-
-#undef config_SaveConfigFile
-int config_SaveConfigFile( vlc_object_t *p_this )
-{
-    return SaveConfigFile (p_this);
-}