config.cpp

00001 /**************
00002 FILE          : config.cpp
00003 ***************
00004 PROJECT       : SaX2 - library interface
00005               :
00006 AUTHOR        : Marcus Schäfer <ms@suse.de>
00007               :
00008 BELONGS TO    : SaX2 - SuSE advanced X11 configuration 
00009               : 
00010               :
00011 DESCRIPTION   : native C++ class library to access SaX2
00012               : functionality. Easy to use interface for
00013               : //.../
00014               : - importing/exporting X11 configurations
00015               : - modifying/creating X11 configurations 
00016               : ---
00017               :
00018               :
00019 STATUS        : Status: Development
00020 **************/
00021 #include "config.h"
00022 
00023 namespace SaX {
00024 //====================================
00025 // Globals...
00026 //------------------------------------
00027 SaXConfig* self = NULL;
00028 
00029 //====================================
00030 // Constructor...
00031 //------------------------------------
00032 SaXConfig::SaXConfig (int mode) {
00033         // .../
00036         // ----
00037         configMode = mode;
00038         gotCard       = false;
00039     gotDesktop    = false;
00040     gotPointers   = false;
00041     gotKeyboard   = false;
00042     gotLayout     = false;
00043     gotPath       = false;
00044     gotExtensions = false;
00045         mDesktop      = NULL;
00046         self = this;
00047         // .../
00048         // remove all ISaX output files building apidata
00049         // ----
00050         if ( setLock() ) {
00051                 unlink (ISAXCARD);
00052                 unlink (ISAXDESKTOP);
00053                 unlink (ISAXINPUT);
00054                 unlink (ISAXKEYBOARD);
00055                 unlink (ISAXLAYOUT);
00056                 unlink (ISAXPATH);
00057                 unlink (ISAXEXTENSIONS);
00058                 unsetLock();
00059         }
00060         mParseErrorString = new QString();
00061         mParseErrorValue  = new QString();
00062 }
00063 
00064 //====================================
00065 // addImport...
00066 //------------------------------------
00067 void SaXConfig::addImport ( SaXImport* in ) {
00068         // .../
00072         // ----
00073         int ID = in->getSectionID();
00074         switch (ID) {
00075                 case SAX_CARD:
00076                 if (gotCard) {
00077                         excImportAlreadyAdded (ID);
00078                         qError (errorString(),EXC_IMPORTALREADYADDED);
00079                         return;
00080                 }
00081                 gotCard = true;
00082                 break;
00083                 case SAX_DESKTOP:
00084                 if (gotDesktop) {
00085                         excImportAlreadyAdded (ID);
00086                         qError (errorString(),EXC_IMPORTALREADYADDED);
00087                         return;
00088                 }
00089                 gotDesktop = true;
00090                 mDesktop   = in;
00091                 break;
00092                 case SAX_POINTERS:
00093                 if (gotPointers) {
00094                         excImportAlreadyAdded (ID);
00095                         qError (errorString(),EXC_IMPORTALREADYADDED);
00096                         return;
00097                 }
00098                 gotPointers = true;
00099                 break;
00100                 case SAX_KEYBOARD:
00101                 if (gotKeyboard) {
00102                         excImportAlreadyAdded (ID);
00103                         qError (errorString(),EXC_IMPORTALREADYADDED);
00104                         return;
00105                 }
00106                 gotKeyboard = true;
00107                 break;
00108                 case SAX_LAYOUT:
00109                 if (gotLayout) {
00110                         excImportAlreadyAdded (ID);
00111                         qError (errorString(),EXC_IMPORTALREADYADDED);
00112                         return;
00113                 }
00114                 gotLayout = true;
00115                 break;
00116                 case SAX_PATH:
00117                 if (gotPath) {
00118                         excImportAlreadyAdded (ID);
00119                         qError (errorString(),EXC_IMPORTALREADYADDED);
00120                         return;
00121                 }
00122                 gotPath = true;
00123                 break;
00124                 case SAX_EXTENSIONS:
00125                 if (gotExtensions) {
00126                         excImportAlreadyAdded (ID);
00127                         qError (errorString(),EXC_IMPORTALREADYADDED);
00128                         return;
00129                 }
00130                 gotExtensions = true;
00131                 break;
00132                 default:
00133                         excUnknownImport (in);
00134                         qError (errorString(),EXC_UNKNOWNIMPORT);
00135                         return;
00136                 break;
00137         }
00138         mImportList.append (in);
00139 }
00140 
00141 //====================================
00142 // enableXFineCache...
00143 //------------------------------------
00144 void SaXConfig::enableXFineCache (bool enable) {
00145         // .../
00151         // ----
00152         if (! mDesktop) {
00153                 return;
00154         }
00155         mDesktop -> setID (0);
00156         if (enable) {
00157                 mDesktop -> setItem ("ImportXFineCache","yes");
00158         } else {
00159                 mDesktop -> removeEntry ("ImportXFineCache");
00160         }
00161 }
00162 
00163 //====================================
00164 // setMode...
00165 //------------------------------------
00166 void SaXConfig::setMode (int mode) {
00167         // .../
00172         // ----
00173         configMode = mode;
00174 }
00175 
00176 //====================================
00177 // createConfiguration...
00178 //------------------------------------
00179 bool SaXConfig::createConfiguration (void) {
00180         // .../
00184         // ----
00185         if (! setLock()) {
00186                 return false;
00187         }
00188         QListIterator<SaXImport> it (mImportList);
00189         for (; it.current(); ++it) {
00190                 SaXExport exportconfig (it.current(),this);
00191                 if (! exportconfig.doExport()) {
00192                         //excExportSectionFailed ();
00193                         //qError (errorString(),EXC_EXPORTSECTIONFAILED);
00194                         unsetLock();
00195                         return false;
00196                 }
00197         }
00198         SaXProcessCall* proc = new SaXProcessCall ();
00199         proc -> addArgument ( SAX_CREATE_API );
00200         if ( ! proc -> start() ) {
00201                 excProcessFailed();
00202                 qError (errorString(),EXC_PROCESSFAILED);
00203         }
00204         QFileInfo api (SAX_API_FILE);
00205         if (! api.exists()) {
00206                 excNoAPIFileFound ();
00207                 qError (errorString(),EXC_NOAPIFILEFOUND);
00208                 unsetLock();
00209                 return false;
00210         }
00211         proc -> clearArguments ();
00212         proc -> addArgument ( ISAX );
00213         proc -> addArgument ( "-f" );
00214         proc -> addArgument ( SAX_API_FILE );
00215         proc -> addArgument ( "-c" );
00216         proc -> addArgument ( SAX_API_CONFIG );
00217         
00218         if (configMode == SAX_MERGE) {
00219                 proc -> addArgument ( "-m" );
00220         }
00221         if ( ! proc -> start() ) {
00222                 excProcessFailed();
00223                 qError (errorString(),EXC_PROCESSFAILED);
00224         }
00225         if (! xf86openConfigFile (CONFPATH,SAX_API_CONFIG,0)) {
00226                 excFileOpenFailed (0);
00227                 qError (errorString(),EXC_FILEOPENFAILED);
00228                 unsetLock();
00229                 return false;
00230         }
00231         if (! xf86readConfigFile()) {
00232                 unsetLock();
00233                 return false;
00234         } else {
00235                 xf86closeConfigFile();
00236         }
00237         removeXFineCache();
00238         unsetLock();
00239         return true;
00240 }
00241 
00242 //====================================
00243 // commitConfiguration...
00244 //------------------------------------
00245 void SaXConfig::commitConfiguration (void) {
00246         // .../
00250         // ----
00251         QFile apiConfig (SAX_API_CONFIG);
00252         QFile curConfig (SAX_SYS_CONFIG);
00253         QFile secConfig (SAX_SYS_CSAVED);
00254         QFile apiMD5 (SAX_API_MD5);
00255         QFile curMD5 (SAX_SYS_MD5);
00256 
00257         //====================================
00258         // read api created config file
00259         //------------------------------------
00260         QStringList al;
00261         if ( apiConfig.open( IO_ReadOnly ) ) {
00262                 QTextStream stream( &apiConfig );
00263                 QString line;
00264                 while ( !stream.atEnd() ) {
00265                         line = stream.readLine();
00266                         al += line;
00267                 }
00268                 apiConfig.close();
00269         } else {
00270                 return;
00271         }
00272         //====================================
00273         // read api created MD5 sum
00274         //------------------------------------
00275         QStringList ml;
00276         if ( apiMD5.open( IO_ReadOnly ) ) {
00277                 QTextStream stream( &apiMD5 );
00278                 QString line;
00279                 while ( !stream.atEnd() ) {
00280                         line = stream.readLine();
00281                         ml += line;
00282                 }
00283                 apiMD5.close();
00284         } else {
00285                 return;
00286         }
00287         //====================================
00288         // read current config file
00289         //------------------------------------
00290         QStringList cl;
00291         if ( curConfig.open( IO_ReadOnly ) ) {
00292                 QTextStream stream( &curConfig );
00293                 QString line;
00294                 while ( !stream.atEnd() ) {
00295                         line = stream.readLine();
00296                         cl += line;
00297                 }
00298                 curConfig.close();
00299         
00300                 //====================================
00301                 // create a backup copy
00302                 //------------------------------------
00303                 if ( secConfig.open( IO_WriteOnly ) ) {
00304                         QTextStream stream ( &secConfig );
00305                         for (QStringList::Iterator it = cl.begin(); it != cl.end();++it) {
00306                                 stream << *it << "\n";
00307                         }
00308                         secConfig.close();
00309                 }
00310         }
00311         //====================================
00312         // install to system
00313         //------------------------------------
00314         if ( curConfig.open( IO_WriteOnly ) ) {
00315                 QTextStream stream ( &curConfig );
00316                 for (QStringList::Iterator it = al.begin(); it != al.end();++it) {
00317                         stream << *it << "\n";
00318                 }
00319                 curConfig.close();
00320         }
00321         //====================================
00322         // install MD5 sum to system
00323         //------------------------------------
00324         if ( curMD5.open( IO_WriteOnly ) ) {
00325                 QTextStream stream ( &curMD5 );
00326                 for (QStringList::Iterator it = ml.begin(); it != ml.end();++it) {
00327                         stream << *it << "\n";
00328                 }
00329                 curMD5.close();
00330         }
00331         //====================================
00332         // create symbolic loader links
00333         //------------------------------------
00334         unlink  ("/usr/X11R6/bin/X");
00335         unlink  ("/var/X11R6/bin/X");
00336         if ((symlink ("/var/X11R6/bin/X","/usr/X11R6/bin/X")) != 0) {
00337                 excFileOpenFailed ( errno );
00338                 qError (errorString(),EXC_FILEOPENFAILED);
00339         }
00340         if ((symlink (SAX_X11_LOADER    ,"/var/X11R6/bin/X")) != 0) {
00341                 excFileOpenFailed ( errno );
00342                 qError (errorString(),EXC_FILEOPENFAILED);
00343         }
00344 }
00345 
00346 //====================================
00347 // testConfiguration...
00348 //------------------------------------
00349 int SaXConfig::testConfiguration (void) {
00350         // .../
00353         // ----
00354         if (! createConfiguration()) {
00355                 return -1;
00356         }
00357         SaXProcessCall* test = new SaXProcessCall ();
00358         test -> addArgument ( SAX_TEST_CONFIG );
00359         test -> addArgument ( "-d"  );
00360         test -> addArgument ( ":99" );
00361         if ( ! test -> start() ) {
00362                 excProcessFailed();
00363                 qError (errorString(),EXC_PROCESSFAILED);
00364                 return -1;
00365         }
00366         int exitCode = 0;
00367         QList<QString> data = test -> readStdout();
00368         QListIterator<QString> in (data);
00369         for (; in.current(); ++in) {
00370                 QString line (*in.current());
00371                 exitCode = line.toInt();
00372         }
00373         switch (exitCode) {
00374         case 0:
00375                 //====================================
00376                 // test has failed for some reasons
00377                 //------------------------------------
00378                 return -1;
00379         break;
00380         case 2:
00381                 //====================================
00382                 // test successful + changes saved
00383                 //------------------------------------
00384                 enableXFineCache();
00385                 if (! createConfiguration()) {
00386                         enableXFineCache (false);
00387                         return false;
00388                 }
00389                 return 0;
00390         break;
00391         default:
00392                 //====================================
00393                 // test successful + changes canceled
00394                 //------------------------------------
00395                 return 1;
00396         break;
00397         }
00398 }
00399 
00400 //====================================
00401 // isChecksumOK...
00402 //------------------------------------
00403 bool SaXConfig::isChecksumOK (void) {
00404         // .../
00411         // ---
00412         QFile curConfig (SAX_SYS_CONFIG);
00413         QFile curMDFile (SAX_SYS_MD5);
00414         if (! curConfig.exists()) {
00415                 return true;
00416         }
00417         //====================================
00418         // import stored MD5 sum (sum1)
00419         //------------------------------------
00420         if ( ! curMDFile.open( IO_ReadOnly ) ) {
00421                 return true;
00422         }
00423         QTextStream stream( &curMDFile );
00424         QString MDSum1 = stream.readLine();
00425         curMDFile.close();
00426 
00427         //====================================
00428         // create current MD5 sum (sum2)
00429         //------------------------------------
00430         SaXProcessCall* md5 = new SaXProcessCall ();
00431         md5 -> addArgument ( SAX_MD5_SUM );
00432         md5 -> addArgument ( SAX_SYS_CONFIG );
00433         if ( ! md5 -> start() ) {
00434                 excProcessFailed();
00435                 qError (errorString(),EXC_PROCESSFAILED);
00436                 return true;     
00437         }
00438         QList<QString> data = md5 -> readStdout();
00439         QString MDSum2 = *data.first();
00440 
00441         //====================================
00442         // check sum1 and sum2
00443         //------------------------------------
00444         if (MDSum2.contains(MDSum1)) {
00445                 return true;
00446         }
00447         return false;
00448 }
00449 
00450 //====================================
00451 // setParseErrorValue...
00452 //------------------------------------
00453 void SaXConfig::setParseErrorValue (char* data) {
00454         // .../
00457         // ---
00458         QTextOStream (mParseErrorValue) << data;
00459 }
00460 
00461 //====================================
00462 // setParseError...
00463 //------------------------------------
00464 void SaXConfig::setParseError (char* data) {
00465         // .../
00468         // ----
00469         QTextOStream (mParseErrorString) << data;
00470         *mParseErrorString = mParseErrorString->stripWhiteSpace();
00471 }
00472 
00473 //====================================
00474 // getParseErrorValue...
00475 //------------------------------------
00476 QString SaXConfig::getParseErrorValue (void) {
00477         // .../
00480         // ----
00481         if (mParseErrorValue->isEmpty()) {
00482                 return QString("");
00483         }
00484         return *mParseErrorValue;
00485 }
00486 
00487 //====================================
00488 // getParseError...
00489 //------------------------------------
00490 QString SaXConfig::getParseError (void) {
00491         // .../
00494         // ----
00495         if (mParseErrorString->isEmpty()) {
00496                 return QString("");
00497         }
00498         return *mParseErrorString;
00499 }
00500 
00501 //====================================
00502 // removeXFineCache
00503 //------------------------------------
00504 void SaXConfig::removeXFineCache (void) {
00505         // .../
00508         // ----
00509         struct dirent* entry = NULL;
00510         DIR* cacheDir = NULL;
00511         cacheDir = opendir (SAX_XFINE_CACHE);
00512         while (1) {
00513                 entry = readdir (cacheDir);
00514                 if (! entry) {
00515                         break;
00516                 }
00517                 QString file (entry->d_name);
00518                 if ((file == ".") || (file == "..")) {
00519                         continue;
00520                 }
00521                 unlink (file.ascii());
00522         }
00523 }
00524 
00525 //====================================
00526 // error functions for libxf86config...
00527 //------------------------------------
00528 extern "C" {
00529 void VErrorF (const char *f, va_list args) {
00530         static int n,size = CONFERRORLINE;
00531         char* data = (char*)malloc (sizeof(char) * size);
00532         while (1) {
00533                 n = vsnprintf (data, size, f, args);
00534                 if ((n > -1) && (n < size)) {
00535                         break;
00536                 }
00537                 if (n > -1) {
00538                         size = n+1;
00539                 } else {
00540                         size *= 2;
00541                 }
00542                 data = (char*)realloc (data, size);
00543         }
00544         if (self) {
00545         if (strcmp(data,"\n") != 0) {
00546                 self -> setParseErrorValue (data);
00547         }
00548         }
00549 }
00550 void ErrorF (const char *f, ...) {
00551         static int n,size = CONFERRORLINE;
00552         char* data = (char*)malloc (sizeof(char) * size);
00553         va_list args;
00554         while (1) {
00555                 va_start(args, f);
00556                 n = vsnprintf (data, size, f, args);
00557                 va_end (args);
00558                 if ((n > -1) && (n < size)) {
00559                         break;
00560                 }
00561                 if (n > -1) {
00562                         size = n+1;
00563                 } else {
00564                         size *= 2;
00565                 }
00566                 data = (char*)realloc (data, size);
00567         }
00568         if (self) {
00569         if (strcmp(data,"\n") != 0) {
00570                 self -> setParseError (data);
00571         }
00572         }
00573 }
00574 }
00575 } // end namespace

Generated on Mon Jun 19 12:42:49 2006 for libsax by  doxygen 1.4.6