]> git.sesse.net Git - vlc/blobdiff - src/config/file.c
config: if read-only, refuse to save the configuration
[vlc] / src / config / file.c
index 6c411f23ed9308c07c889b69aac826845a45c6b9..9417e552bfa5a1d0ccf759167874b013d54e96aa 100644 (file)
  * 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.
+ * 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>
 #include <locale.h>
 #endif
 
+#include <vlc_common.h>
+#include "../libvlc.h"
+#include "vlc_charset.h"
+#include "vlc_keys.h"
+
 #include "configuration.h"
 #include "modules/modules.h"
 
@@ -430,12 +430,18 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
     file = config_OpenConfigFile( p_this );
     if( file != NULL )
     {
-        /* look for file size */
-        fseek( file, 0L, SEEK_END );
-        i_sizebuf = ftell( file );
-        fseek( file, 0L, SEEK_SET );
-        if( i_sizebuf >= LONG_MAX )
-            i_sizebuf = 0;
+        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 );
@@ -680,7 +686,8 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
 #ifndef WIN32
     fdatasync (fd); /* Flush from OS */
     /* Atomically replace the file... */
-    utf8_rename (temporary, permanent);
+    if (utf8_rename (temporary, permanent))
+        utf8_unlink (temporary);
     /* (...then synchronize the directory, err, TODO...) */
     /* ...and finally close the file */
     vlc_mutex_unlock (&lock);
@@ -689,7 +696,8 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
 #ifdef WIN32
     /* Windows cannot remove open files nor overwrite existing ones */
     utf8_unlink (permanent);
-    utf8_rename (temporary, permanent);
+    if (utf8_rename (temporary, permanent))
+        utf8_unlink (temporary);
     vlc_mutex_unlock (&lock);
 #endif
 
@@ -744,11 +752,11 @@ int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
 int ConfigStringToKey( const char *psz_key )
 {
     int i_key = 0;
-    unsigned int i;
+    size_t 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++ )
+        for( i = 0; i < vlc_num_modifiers; ++i )
         {
             if( !strncasecmp( vlc_modifiers[i].psz_key_string, psz_key,
                               strlen( vlc_modifiers[i].psz_key_string ) ) )
@@ -759,7 +767,7 @@ int ConfigStringToKey( const char *psz_key )
         psz_key = psz_parser + 1;
         psz_parser = strchr( psz_key, '-' );
     }
-    for( i = 0; i < sizeof(vlc_keys) / sizeof( key_descriptor_t ); i++ )
+    for( i = 0; i < vlc_num_keys; ++i )
     {
         if( !strcasecmp( vlc_keys[i].psz_key_string, psz_key ) )
         {
@@ -772,7 +780,10 @@ int ConfigStringToKey( const char *psz_key )
 
 char *ConfigKeyToString( int i_key )
 {
-    char *psz_key = malloc( 100 );
+    // Worst case appears to be 45 characters:
+    // "Command-Meta-Ctrl-Shift-Alt-Browser Favorites"
+    enum { keylen=64 };
+    char *psz_key = malloc( keylen );
     char *p;
     size_t index;
 
@@ -783,20 +794,20 @@ char *ConfigKeyToString( int i_key )
     *psz_key = '\0';
     p = psz_key;
 
-    for( index = 0; index < (sizeof(vlc_modifiers) / sizeof(key_descriptor_t));
-         index++ )
+    for( index = 0; index < vlc_num_modifiers; ++index )
     {
         if( i_key & vlc_modifiers[index].i_key_code )
         {
-            p += sprintf( p, "%s-", vlc_modifiers[index].psz_key_string );
+            p += snprintf( p, keylen-(psz_key-p), "%s-",
+                           vlc_modifiers[index].psz_key_string );
         }
     }
-    for( index = 0; index < (sizeof(vlc_keys) / sizeof( key_descriptor_t));
-         index++)
+    for( index = 0; index < vlc_num_keys; ++index )
     {
         if( (int)( i_key & ~KEY_MODIFIER ) == vlc_keys[index].i_key_code )
         {
-            p += sprintf( p, "%s", vlc_keys[index].psz_key_string );
+            p += snprintf( p, keylen-(psz_key-p), "%s",
+                           vlc_keys[index].psz_key_string );
             break;
         }
     }