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         // The links are only created if the
00335         // /usr/X11/bin/Xorg server exists, for xorg v7 the server
00336         // is located in /usr/bin and doesn't need to be linked
00337         // ----
00338         QFile loader (SAX_X11_LOADER);
00339         if (loader.exists()) {
00340                 unlink  ("/usr/X11R6/bin/X");
00341                 unlink  ("/var/X11R6/bin/X");
00342                 if ((symlink ("/var/X11R6/bin/X","/usr/X11R6/bin/X")) != 0) {
00343                         excFileOpenFailed ( errno );
00344                         qError (errorString(),EXC_FILEOPENFAILED);
00345                 }
00346                 if ((symlink (SAX_X11_LOADER    ,"/var/X11R6/bin/X")) != 0) {
00347                         excFileOpenFailed ( errno );
00348                         qError (errorString(),EXC_FILEOPENFAILED);
00349                 }
00350         }
00351 }
00352 
00353 //====================================
00354 // testConfiguration...
00355 //------------------------------------
00356 int SaXConfig::testConfiguration (void) {
00357         // .../
00360         // ----
00361         if (! createConfiguration()) {
00362                 return -1;
00363         }
00364         SaXProcessCall* test = new SaXProcessCall ();
00365         test -> addArgument ( SAX_TEST_CONFIG );
00366         test -> addArgument ( "-d"  );
00367         test -> addArgument ( ":99" );
00368         if ( ! test -> start() ) {
00369                 excProcessFailed();
00370                 qError (errorString(),EXC_PROCESSFAILED);
00371                 return -1;
00372         }
00373         int exitCode = 0;
00374         QList<QString> data = test -> readStdout();
00375         QListIterator<QString> in (data);
00376         for (; in.current(); ++in) {
00377                 QString line (*in.current());
00378                 exitCode = line.toInt();
00379         }
00380         switch (exitCode) {
00381         case 0:
00382                 //====================================
00383                 // test has failed for some reasons
00384                 //------------------------------------
00385                 return -1;
00386         break;
00387         case 2:
00388                 //====================================
00389                 // test successful + changes saved
00390                 //------------------------------------
00391                 enableXFineCache();
00392                 if (! createConfiguration()) {
00393                         enableXFineCache (false);
00394                         return false;
00395                 }
00396                 return 0;
00397         break;
00398         default:
00399                 //====================================
00400                 // test successful + changes canceled
00401                 //------------------------------------
00402                 return 1;
00403         break;
00404         }
00405 }
00406 
00407 //====================================
00408 // isChecksumOK...
00409 //------------------------------------
00410 bool SaXConfig::isChecksumOK (void) {
00411         // .../
00418         // ---
00419         QFile curConfig (SAX_SYS_CONFIG);
00420         QFile curMDFile (SAX_SYS_MD5);
00421         if (! curConfig.exists()) {
00422                 return true;
00423         }
00424         //====================================
00425         // import stored MD5 sum (sum1)
00426         //------------------------------------
00427         if ( ! curMDFile.open( IO_ReadOnly ) ) {
00428                 return true;
00429         }
00430         QTextStream stream( &curMDFile );
00431         QString MDSum1 = stream.readLine();
00432         curMDFile.close();
00433 
00434         //====================================
00435         // create current MD5 sum (sum2)
00436         //------------------------------------
00437         SaXProcessCall* md5 = new SaXProcessCall ();
00438         md5 -> addArgument ( SAX_MD5_SUM );
00439         md5 -> addArgument ( SAX_SYS_CONFIG );
00440         if ( ! md5 -> start() ) {
00441                 excProcessFailed();
00442                 qError (errorString(),EXC_PROCESSFAILED);
00443                 return true;     
00444         }
00445         QList<QString> data = md5 -> readStdout();
00446         QString MDSum2 = *data.first();
00447 
00448         //====================================
00449         // check sum1 and sum2
00450         //------------------------------------
00451         if (MDSum2.contains(MDSum1)) {
00452                 return true;
00453         }
00454         return false;
00455 }
00456 
00457 //====================================
00458 // setParseErrorValue...
00459 //------------------------------------
00460 void SaXConfig::setParseErrorValue (char* data) {
00461         // .../
00464         // ---
00465         QTextOStream (mParseErrorValue) << data;
00466 }
00467 
00468 //====================================
00469 // setParseError...
00470 //------------------------------------
00471 void SaXConfig::setParseError (char* data) {
00472         // .../
00475         // ----
00476         QTextOStream (mParseErrorString) << data;
00477         *mParseErrorString = mParseErrorString->stripWhiteSpace();
00478 }
00479 
00480 //====================================
00481 // getParseErrorValue...
00482 //------------------------------------
00483 QString SaXConfig::getParseErrorValue (void) {
00484         // .../
00487         // ----
00488         if (mParseErrorValue->isEmpty()) {
00489                 return QString("");
00490         }
00491         return *mParseErrorValue;
00492 }
00493 
00494 //====================================
00495 // getParseError...
00496 //------------------------------------
00497 QString SaXConfig::getParseError (void) {
00498         // .../
00501         // ----
00502         if (mParseErrorString->isEmpty()) {
00503                 return QString("");
00504         }
00505         return *mParseErrorString;
00506 }
00507 
00508 //====================================
00509 // removeXFineCache
00510 //------------------------------------
00511 void SaXConfig::removeXFineCache (void) {
00512         // .../
00515         // ----
00516         struct dirent* entry = NULL;
00517         DIR* cacheDir = NULL;
00518         cacheDir = opendir (SAX_XFINE_CACHE);
00519         while (1) {
00520                 entry = readdir (cacheDir);
00521                 if (! entry) {
00522                         break;
00523                 }
00524                 QString file (entry->d_name);
00525                 if ((file == ".") || (file == "..")) {
00526                         continue;
00527                 }
00528                 unlink (file.ascii());
00529         }
00530 }
00531 
00532 //====================================
00533 // error functions for libxf86config...
00534 //------------------------------------
00535 extern "C" {
00536 void VErrorF (const char *f, va_list args) {
00537         static int n,size = CONFERRORLINE;
00538         char* data = (char*)malloc (sizeof(char) * size);
00539         while (1) {
00540                 n = vsnprintf (data, size, f, args);
00541                 if ((n > -1) && (n < size)) {
00542                         break;
00543                 }
00544                 if (n > -1) {
00545                         size = n+1;
00546                 } else {
00547                         size *= 2;
00548                 }
00549                 data = (char*)realloc (data, size);
00550         }
00551         if (self) {
00552         if (strcmp(data,"\n") != 0) {
00553                 self -> setParseErrorValue (data);
00554         }
00555         }
00556 }
00557 void ErrorF (const char *f, ...) {
00558         static int n,size = CONFERRORLINE;
00559         char* data = (char*)malloc (sizeof(char) * size);
00560         va_list args;
00561         while (1) {
00562                 va_start(args, f);
00563                 n = vsnprintf (data, size, f, args);
00564                 va_end (args);
00565                 if ((n > -1) && (n < size)) {
00566                         break;
00567                 }
00568                 if (n > -1) {
00569                         size = n+1;
00570                 } else {
00571                         size *= 2;
00572                 }
00573                 data = (char*)realloc (data, size);
00574         }
00575         if (self) {
00576         if (strcmp(data,"\n") != 0) {
00577                 self -> setParseError (data);
00578         }
00579         }
00580 }
00581 }
00582 } // end namespace

Generated on Tue Nov 28 19:09:12 2006 for libsax by  doxygen 1.5.0