summaryrefslogtreecommitdiffstats
path: root/kinit/kstartupconfig.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kinit/kstartupconfig.cpp')
-rw-r--r--kinit/kstartupconfig.cpp176
1 files changed, 176 insertions, 0 deletions
diff --git a/kinit/kstartupconfig.cpp b/kinit/kstartupconfig.cpp
new file mode 100644
index 000000000..8bb60c127
--- /dev/null
+++ b/kinit/kstartupconfig.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+
+ Copyright (C) 2005 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+****************************************************************************/
+
+/*
+
+This utility helps to have some configuration options available in startkde
+without the need to launch anything linked to KDE libraries (which may need
+some time to load).
+
+The configuration options are written to $KDEHOME/share/config/startupconfigkeys,
+one option per line, as <file> <group> <key> <default>. It is possible to
+use ' for quoting multiword entries. Values of these options will be written
+to $KDEHOME/share/config/startupconfig as a shell script that will set
+the values to shell variables, named <file>_<group>_<key> (all spaces replaced
+by underscores, everything lowercase). So e.g. line
+"ksplashrc KSplash Theme Default" may result in "ksplashrc_ksplash_theme=Default".
+
+In order to real a whole group it is possible to use <file> <[group]>, e.g.
+"ksplashrc [KSplash]", which will set shell variables for all keys in the group.
+It is not possible to specify default values, but since the configuration options
+are processed in the order they are specified this can be solved by first
+specifying a group and then all the entries that need default values.
+
+When a kconf_update script is used to update such option, kstartupconfig is run
+before kconf_update and therefore cannot see the change in time. To avoid this
+problem, together with the kconf_update script also the matching global config
+file should be updated (any change, kstartupconfig will see the timestamp change).
+
+Note that the kdeglobals config file is not used as a depedendency for other config
+files.
+
+Since the checking is timestamp-based, config files that are frequently updated
+should not be used.
+
+Kstartupconfig works by storing every line from startupconfigkeys in file startupconfigfiles
+followed by paths of all files that are relevant to the option. Non-existent files
+have '!' prepended (for the case they'll be later created), the list of files is
+terminated by line containing '*'. If the timestamps of all relevant files are older
+than the timestamp of the startupconfigfile file, there's no need to update anything.
+Otherwise kdostartupconfig is launched to create or update all the necessary files
+(which already requires loading KDE libraries, but this case should be rare).
+
+*/
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int main()
+ {
+ char kdehome[ 1024 ];
+ if( getenv( "KDEHOME" ))
+ strlcpy( kdehome, getenv( "KDEHOME" ), 1024 );
+ else if( getenv( "HOME" ))
+ {
+ strlcpy( kdehome, getenv( "HOME" ), 1024 );
+ strlcat( kdehome, "/.kde", 1024 );
+ }
+ else
+ return 1;
+ char filename[ 1024 ];
+ strlcpy( filename, kdehome, 1024 );
+ strlcat( filename, "/share/config/startupconfig", 1024 );
+ if( access( filename, R_OK ) != 0 )
+ {
+ int ret = system( "kdostartupconfig" );
+ return WEXITSTATUS( ret );
+ }
+ strlcpy( filename, kdehome, 1024 );
+ strlcat( filename, "/share/config/startupconfigfiles", 1024 );
+ struct stat st;
+ if( stat( filename, &st ) != 0 )
+ {
+ int ret = system( "kdostartupconfig" );
+ return WEXITSTATUS( ret );
+ }
+ time_t config_time = st.st_mtime;
+ FILE* config = fopen( filename, "r" );
+ if( config == NULL )
+ {
+ int ret = system( "kdostartupconfig" );
+ return WEXITSTATUS( ret );
+ }
+ strlcpy( filename, kdehome, 1024 );
+ strlcat( filename, "/share/config/startupconfigkeys", 1024 );
+ FILE* keys = fopen( filename, "r" );
+ if( keys == NULL )
+ {
+ fclose( config );
+ return 2;
+ }
+ bool need_update = true;
+ for(;;)
+ {
+ char keyline[ 1024 ];
+ if( fgets( keyline, 1023, keys ) == NULL )
+ {
+ need_update = false;
+ break;
+ }
+ if( char* nl = strchr( keyline, '\n' ))
+ *nl = '\0';
+ char line[ 1024 ];
+ if( fgets( line, 1023, config ) == NULL )
+ break;
+ if( char* nl = strchr( line, '\n' ))
+ *nl = '\0';
+ if( strcmp( keyline, line ) != 0 )
+ break;
+ bool ok = false;
+ for(;;)
+ {
+ if( fgets( line, 1023, config ) == NULL )
+ break;
+ if( char* nl = strchr( line, '\n' ))
+ *nl = '\0';
+ if( *line == '\0' )
+ break;
+ if( *line == '*' )
+ {
+ ok = true;
+ break;
+ }
+ if( *line == '!' )
+ {
+ if( access( line + 1, R_OK ) == 0 )
+ break; // file now exists -> update
+ }
+ else
+ {
+ struct stat st;
+ if( stat( line, &st ) != 0 )
+ break;
+ if( st.st_mtime > config_time )
+ break;
+ }
+ }
+ if( !ok )
+ break;
+ }
+ fclose( keys );
+ fclose( config );
+ if( need_update )
+ {
+ int ret = system( "kdostartupconfig" );
+ return WEXITSTATUS( ret );
+ }
+ return 0;
+ }