[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    [PATCH] KConfigBackend
From:       Waldo Bastian <bastian () kde ! org>
Date:       2002-02-23 1:52:59
[Download RAW message or body]

The following patch implements some missing features for KConfig.

* Adds setFileWriteMode(int) to create new files with a mode other than 0600 
which is the default.
* Preserves file modes when overwriting existing files. Up till now, when you 
changed a config file to "0644" with chmod, it would be reset to 0600 the 
next time it was written to.
* Allows symlinks. Up till now, when your config file was a symlink, it would 
be reset to a regular file the next time it was written to. It now preserves 
the symlink and writes to the destination of the symlink. Stale symlinks are 
replaced with files though, t.i. the destination of the symlink must already 
exist. Now you can finally be a real geek and redirect your kdeglobals to 
/dev/null. (Or try "ln -s `tty` kdeglobals" to impress your friends and 
family. )
* Allows files to be owned by different users. When you are not the owner of 
the file but do have write permission, it will write to the file and leave 
the ownership as is. Up till now, the file would be replaced with a file that 
was owned by you.

Please review.

Cheers,
Waldo
-- 
Advanced technology only happens when people take a basic idea and add to it.
 -- Bob Bemer

["kconfigbackend.diff" (text/x-diff)]

Index: kconfig.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kconfig.cpp,v
retrieving revision 1.63
diff -u -p -r1.63 kconfig.cpp
--- kconfig.cpp	2001/12/31 20:26:01	1.63
+++ kconfig.cpp	2002/02/23 01:44:33
@@ -256,5 +256,11 @@ bool KConfig::internalHasGroup(const QCS
   return false;
 }
 
+void KConfig::setFileWriteMode(int mode)
+{
+  backEnd->setFileWriteMode(mode);
+}
+
+
 
 #include "kconfig.moc"
Index: kconfig.h
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kconfig.h,v
retrieving revision 1.43
diff -u -p -r1.43 kconfig.h
--- kconfig.h	2001/12/31 20:26:01	1.43
+++ kconfig.h	2002/02/23 01:44:33
@@ -106,6 +106,13 @@ public:
    */
   virtual void reparseConfiguration();
 
+  /**
+   * Set the file mode for newly created files.
+   *
+   * @see man:chmod(2) for a description of @p mode
+   */
+  void setFileWriteMode(int mode);
+
 protected:
 
   /**
Index: kconfigbackend.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kconfigbackend.cpp,v
retrieving revision 1.68
diff -u -p -r1.68 kconfigbackend.cpp
--- kconfigbackend.cpp	2002/01/18 20:03:19	1.68
+++ kconfigbackend.cpp	2002/02/23 01:44:33
@@ -26,6 +26,11 @@
 #ifdef HAVE_SYS_MMAN_H
 #include <sys/mman.h>
 #endif
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
 
 #undef Unsorted
 #include <qdir.h>
@@ -178,11 +183,16 @@ KConfigBackEnd::KConfigBackEnd(KConfigBa
 			       const QString &_fileName,
 			       const char * _resType,
 			       bool _useKDEGlobals)
-  : pConfig(_config), bFileImmutable(false), mConfigState(KConfigBase::NoAccess)
+  : pConfig(_config), bFileImmutable(false), mConfigState(KConfigBase::NoAccess), mFileMode(-1)
 {
    changeFileName(_fileName, _resType, _useKDEGlobals);
 }
 
+void KConfigBackEnd::setFileWriteMode(int mode)
+{
+  mFileMode = mode;
+}
+
 bool KConfigINIBackEnd::parseConfigFiles()
 {
   // Parse all desired files from the least to the most specific.
@@ -676,13 +686,73 @@ bool KConfigINIBackEnd::writeConfigFile(
   // OK now the temporary map should be full of ALL entries.
   // write it out to disk.
 
-  KSaveFile rConfigFile( filename, 0600 );
+  // Check if file exists:
+  int fileMode = bGlobal ? -1 : mFileMode;
+  bool createNew = true;
 
-  if (rConfigFile.status() != 0)
-     return bEntriesLeft;
+  struct stat buf;
+  if (lstat(QFile::encodeName(filename), &buf) == 0)
+  {
+     if (S_ISLNK(buf.st_mode))
+     {
+        // File is a symlink:
+        if (stat(QFile::encodeName(filename), &buf) == 0)
+        {
+           // Don't create new file but write to existing file instead.
+           createNew = false;
+        }
+     }
+     else if (buf.st_uid == getuid())
+     {
+        // Preserve file mode if file exists and is owned by user.
+        fileMode = buf.st_mode & 0777;
+     }
+     else
+     {
+        // File is not owned by user:
+        // Don't create new file but write to existing file instead.
+        createNew = false;
+     }
+  }
 
-  FILE *pStream = rConfigFile.fstream();
+  KSaveFile *pConfigFile = 0;
+  FILE *pStream = 0;
 
+  if (createNew)
+  {
+     pConfigFile = new KSaveFile( filename, 0600 );
+
+     if (pConfigFile->status() != 0)
+     {
+        delete pConfigFile;
+        return bEntriesLeft;
+     }
+
+     if (!bGlobal && (fileMode == -1))
+        fileMode = mFileMode;
+
+     if (fileMode != -1)
+     {   
+        fchmod(pConfigFile->handle(), fileMode);
+     }
+
+     pStream = pConfigFile->fstream();
+  }
+  else
+  {
+     // Open existing file. 
+     // We use open() to ensure that we call without O_CREAT.
+     int fd = open( QFile::encodeName(filename), O_WRONLY);
+     if (fd < 0)
+        return bEntriesLeft;
+     pStream = fdopen( fd, "w");
+     if (!pStream)
+     {
+        close(fd);
+        return bEntriesLeft;
+     }
+  }
+
   bool firstEntry = true;
 
   // Write default group
@@ -691,7 +761,17 @@ bool KConfigINIBackEnd::writeConfigFile(
   // Write all other groups
   writeEntries(pStream, aTempMap, false, firstEntry, localeString);
 
-  rConfigFile.close();
+  if (pConfigFile)
+  {
+     pConfigFile->close();
+     delete pConfigFile;
+  }
+  else
+  {
+     fclose(pStream);
+  }
 
   return bEntriesLeft;
 }
+
+
Index: kconfigbackend.h
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kconfigbackend.h,v
retrieving revision 1.19
diff -u -p -r1.19 kconfigbackend.h
--- kconfigbackend.h	2002/01/11 06:07:28	1.19
+++ kconfigbackend.h	2002/02/23 01:44:33
@@ -121,6 +121,11 @@ public:
 
   void setLocaleString(const QCString &_localeString) { localeString = _localeString; }
 
+  /**
+   * Set the file mode for newly created files.
+   */
+  void setFileWriteMode(int mode);
+
 #ifdef KDE_NO_COMPAT
 private:
 #endif
@@ -141,6 +146,7 @@ protected:
   QString mLocalFileName;
   QString mGlobalFileName;
   KConfigBase::ConfigState mConfigState;
+  int mFileMode;
 
   KConfigBackEndPrivate *d;
 };


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic