KInit
kstartupconfig.cpp
Go to the documentation of this file.00001 /**************************************************************************** 00002 00003 Copyright (C) 2005 Lubos Lunak <l.lunak@kde.org> 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a 00006 copy of this software and associated documentation files (the "Software"), 00007 to deal in the Software without restriction, including without limitation 00008 the rights to use, copy, modify, merge, publish, distribute, sublicense, 00009 and/or sell copies of the Software, and to permit persons to whom the 00010 Software is furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00018 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00020 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00021 DEALINGS IN THE SOFTWARE. 00022 00023 ****************************************************************************/ 00024 00025 /* 00026 00027 This utility helps to have some configuration options available in startkde 00028 without the need to launch anything linked to KDE libraries (which may need 00029 some time to load). 00030 00031 The configuration options are written to $KDEHOME/share/config/startupconfigkeys, 00032 one option per line, as <file> <group> <key> <default>. It is possible to 00033 use ' for quoting multiword entries. Values of these options will be written 00034 to $KDEHOME/share/config/startupconfig as a shell script that will set 00035 the values to shell variables, named <file>_<group>_<key> (all spaces replaced 00036 by underscores, everything lowercase). So e.g. line 00037 "ksplashrc KSplash Theme Default" may result in "ksplashrc_ksplash_theme=Default". 00038 00039 In order to real a whole group it is possible to use <file> <[group]>, e.g. 00040 "ksplashrc [KSplash]", which will set shell variables for all keys in the group. 00041 It is not possible to specify default values, but since the configuration options 00042 are processed in the order they are specified this can be solved by first 00043 specifying a group and then all the entries that need default values. 00044 00045 When a kconf_update script is used to update such option, kstartupconfig is run 00046 before kconf_update and therefore cannot see the change in time. To avoid this 00047 problem, together with the kconf_update script also the matching global config 00048 file should be updated (any change, kstartupconfig will see the timestamp change). 00049 00050 Note that the kdeglobals config file is not used as a depedendency for other config 00051 files. 00052 00053 Since the checking is timestamp-based, config files that are frequently updated 00054 should not be used. 00055 00056 Kstartupconfig works by storing every line from startupconfigkeys in file startupconfigfiles 00057 followed by paths of all files that are relevant to the option. Non-existent files 00058 have '!' prepended (for the case they'll be later created), the list of files is 00059 terminated by line containing '*'. If the timestamps of all relevant files are older 00060 than the timestamp of the startupconfigfile file, there's no need to update anything. 00061 Otherwise kdostartupconfig is launched to create or update all the necessary files 00062 (which already requires loading KDE libraries, but this case should be rare). 00063 00064 */ 00065 00066 #include <config.h> 00067 00068 #include <sys/types.h> 00069 #include <sys/stat.h> 00070 #include <sys/wait.h> 00071 #include <unistd.h> 00072 #include <stdio.h> 00073 #include <string.h> 00074 #include <stdlib.h> 00075 00076 int main() 00077 { 00078 char kdehome[ 1024 ]; 00079 if( getenv( "KDEHOME" )) 00080 strlcpy( kdehome, getenv( "KDEHOME" ), 1024 ); 00081 else if( getenv( "HOME" )) 00082 { 00083 strlcpy( kdehome, getenv( "HOME" ), 1024 ); 00084 strlcat( kdehome, "/.kde", 1024 ); 00085 } 00086 else 00087 return 1; 00088 char filename[ 1024 ]; 00089 strlcpy( filename, kdehome, 1024 ); 00090 strlcat( filename, "/share/config/startupconfig", 1024 ); 00091 if( access( filename, R_OK ) != 0 ) 00092 { 00093 int ret = system( "kdostartupconfig" ); 00094 return WEXITSTATUS( ret ); 00095 } 00096 strlcpy( filename, kdehome, 1024 ); 00097 strlcat( filename, "/share/config/startupconfigfiles", 1024 ); 00098 struct stat st; 00099 if( stat( filename, &st ) != 0 ) 00100 { 00101 int ret = system( "kdostartupconfig" ); 00102 return WEXITSTATUS( ret ); 00103 } 00104 time_t config_time = st.st_mtime; 00105 FILE* config = fopen( filename, "r" ); 00106 if( config == NULL ) 00107 { 00108 int ret = system( "kdostartupconfig" ); 00109 return WEXITSTATUS( ret ); 00110 } 00111 strlcpy( filename, kdehome, 1024 ); 00112 strlcat( filename, "/share/config/startupconfigkeys", 1024 ); 00113 FILE* keys = fopen( filename, "r" ); 00114 if( keys == NULL ) 00115 { 00116 fclose( config ); 00117 return 2; 00118 } 00119 bool need_update = true; 00120 for(;;) 00121 { 00122 char keyline[ 1024 ]; 00123 if( fgets( keyline, 1023, keys ) == NULL ) 00124 { 00125 need_update = false; 00126 break; 00127 } 00128 if( char* nl = strchr( keyline, '\n' )) 00129 *nl = '\0'; 00130 char line[ 1024 ]; 00131 if( fgets( line, 1023, config ) == NULL ) 00132 break; 00133 if( char* nl = strchr( line, '\n' )) 00134 *nl = '\0'; 00135 if( strcmp( keyline, line ) != 0 ) 00136 break; 00137 bool ok = false; 00138 for(;;) 00139 { 00140 if( fgets( line, 1023, config ) == NULL ) 00141 break; 00142 if( char* nl = strchr( line, '\n' )) 00143 *nl = '\0'; 00144 if( *line == '\0' ) 00145 break; 00146 if( *line == '*' ) 00147 { 00148 ok = true; 00149 break; 00150 } 00151 if( *line == '!' ) 00152 { 00153 if( access( line + 1, R_OK ) == 0 ) 00154 break; // file now exists -> update 00155 } 00156 else 00157 { 00158 struct stat st; 00159 if( stat( line, &st ) != 0 ) 00160 break; 00161 if( st.st_mtime > config_time ) 00162 break; 00163 } 00164 } 00165 if( !ok ) 00166 break; 00167 } 00168 fclose( keys ); 00169 fclose( config ); 00170 if( need_update ) 00171 { 00172 int ret = system( "kdostartupconfig" ); 00173 return WEXITSTATUS( ret ); 00174 } 00175 return 0; 00176 }