ksavefile.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <sys/types.h>
00023
00024 #ifdef HAVE_SYS_STAT_H
00025 #include <sys/stat.h>
00026 #endif
00027
00028 #include <unistd.h>
00029 #include <fcntl.h>
00030
00031 #ifdef HAVE_TEST
00032 #include <test.h>
00033 #endif
00034
00035 #include <qdatetime.h>
00036 #include <qdir.h>
00037
00038 #include "kapplication.h"
00039 #include "ksavefile.h"
00040
00041 KSaveFile::KSaveFile(const QString &filename, int mode)
00042 : mTempFile(true)
00043 {
00044
00045
00046 QString real_filename = filename;
00047
00048 QFileInfo file_info(real_filename);
00049 int c=0;
00050 while(file_info.isSymLink() && ++c<6) {
00051 real_filename = file_info.readLink();
00052 file_info.setFile( real_filename );
00053 }
00054
00055
00056
00057
00058 if (!checkAccess(real_filename, W_OK))
00059 {
00060 mTempFile.setError(EACCES);
00061 return;
00062 }
00063
00064 if (mTempFile.create(real_filename, QString::fromLatin1(".new"), mode))
00065 {
00066 mFileName = real_filename;
00067
00068
00069
00070
00071 struct stat stat_buf;
00072 if ((stat(QFile::encodeName(real_filename), &stat_buf)==0)
00073 && (stat_buf.st_uid == getuid())
00074 && (stat_buf.st_gid == getgid()))
00075 {
00076 fchmod(mTempFile.handle() , stat_buf.st_mode);
00077 }
00078 }
00079 return;
00080 }
00081
00082 KSaveFile::~KSaveFile()
00083 {
00084 if (mTempFile.bOpen)
00085 close();
00086 }
00087
00088 QString
00089 KSaveFile::name() const
00090 {
00091 return mFileName;
00092 }
00093
00094 void
00095 KSaveFile::abort()
00096 {
00097 mTempFile.unlink();
00098 mTempFile.close();
00099 }
00100
00101 bool
00102 KSaveFile::close()
00103 {
00104 if (mTempFile.name().isEmpty())
00105 return false;
00106 if (mTempFile.close())
00107 {
00108 QDir dir;
00109 bool result = dir.rename( mTempFile.name(), mFileName);
00110 if ( result )
00111 {
00112 return true;
00113 }
00114 mTempFile.setError(errno);
00115 }
00116
00117
00118 mTempFile.unlink();
00119 return false;
00120 }
00121
00122 static int
00123 write_all(int fd, const char *buf, size_t len)
00124 {
00125 while (len > 0)
00126 {
00127 int written = write(fd, buf, len);
00128 if (written < 0)
00129 {
00130 if (errno == EINTR)
00131 continue;
00132 return -1;
00133 }
00134 buf += written;
00135 len -= written;
00136 }
00137 return 0;
00138 }
00139
00140 bool KSaveFile::backupFile( const QString& qFilename, const QString& backupDir,
00141 const QString& backupExtension)
00142 {
00143 QCString cFilename = QFile::encodeName(qFilename);
00144 const char *filename = cFilename.data();
00145
00146 int fd = open( filename, O_RDONLY);
00147 if (fd < 0)
00148 return false;
00149
00150 struct stat buff;
00151 if ( fstat( fd, &buff) < 0 )
00152 {
00153 ::close( fd );
00154 return false;
00155 }
00156
00157 QCString cBackup;
00158 if ( backupDir.isEmpty() )
00159 cBackup = cFilename;
00160 else
00161 {
00162 QCString nameOnly;
00163 int slash = cFilename.findRev('/');
00164 if (slash < 0)
00165 nameOnly = cFilename;
00166 else
00167 nameOnly = cFilename.mid(slash + 1);
00168 cBackup = QFile::encodeName(backupDir);
00169 if ( backupDir[backupDir.length()-1] != '/' )
00170 cBackup += '/';
00171 cBackup += nameOnly;
00172 }
00173 cBackup += QFile::encodeName(backupExtension);
00174 const char *backup = cBackup.data();
00175 int permissions = buff.st_mode & 07777;
00176
00177 if ( stat( backup, &buff) == 0)
00178 {
00179 if ( unlink( backup ) != 0 )
00180 {
00181 ::close(fd);
00182 return false;
00183 }
00184 }
00185
00186 mode_t old_umask = umask(0);
00187 int fd2 = open( backup, O_WRONLY | O_CREAT | O_EXCL, permissions | S_IWUSR);
00188 umask(old_umask);
00189
00190 if ( fd2 < 0 )
00191 {
00192 ::close(fd);
00193 return false;
00194 }
00195
00196 char buffer[ 32*1024 ];
00197
00198 while( 1 )
00199 {
00200 int n = ::read( fd, buffer, 32*1024 );
00201 if (n == -1)
00202 {
00203 if (errno == EINTR)
00204 continue;
00205 ::close(fd);
00206 ::close(fd2);
00207 return false;
00208 }
00209 if (n == 0)
00210 break;
00211
00212 if (write_all( fd2, buffer, n))
00213 {
00214 ::close(fd);
00215 ::close(fd2);
00216 return false;
00217 }
00218 }
00219
00220 ::close( fd );
00221
00222 if (::close(fd2))
00223 return false;
00224 return true;
00225 }
This file is part of the documentation for kdecore Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Apr 21 18:42:57 2004 by
doxygen 1.3.6-20040222 written by
Dimitri van Heesch, © 1997-2003