diff options
Diffstat (limited to 'kinit/kstartupconfig.cpp')
-rw-r--r-- | kinit/kstartupconfig.cpp | 176 |
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; + } |