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 close();
00085 }
00086
00087 QString
00088 KSaveFile::name() const
00089 {
00090 return mFileName;
00091 }
00092
00093 void
00094 KSaveFile::abort()
00095 {
00096 mTempFile.unlink();
00097 mTempFile.close();
00098 }
00099
00100 bool
00101 KSaveFile::close()
00102 {
00103 if (mTempFile.name().isEmpty())
00104 return false;
00105 if (mTempFile.close())
00106 {
00107 QDir dir;
00108 bool result = dir.rename( mTempFile.name(), mFileName);
00109 if ( result )
00110 {
00111 return true;
00112 }
00113 mTempFile.setError(errno);
00114 }
00115
00116
00117 mTempFile.unlink();
00118 return false;
00119 }
00120
00121 static int
00122 write_all(int fd, const char *buf, size_t len)
00123 {
00124 while (len > 0)
00125 {
00126 int written = write(fd, buf, len);
00127 if (written < 0)
00128 {
00129 if (errno == EINTR)
00130 continue;
00131 return -1;
00132 }
00133 buf += written;
00134 len -= written;
00135 }
00136 return 0;
00137 }
00138
00139 bool KSaveFile::backupFile( const QString& qFilename, const QString& backupDir,
00140 const QString& backupExtension)
00141 {
00142 QCString cFilename = QFile::encodeName(qFilename);
00143 const char *filename = cFilename.data();
00144
00145 int fd = open( filename, O_RDONLY);
00146 if (fd < 0)
00147 return false;
00148
00149 struct stat buff;
00150 if ( fstat( fd, &buff) < 0 )
00151 {
00152 ::close( fd );
00153 return false;
00154 }
00155
00156 QCString cBackup;
00157 if ( backupDir.isEmpty() )
00158 cBackup = cFilename;
00159 else
00160 {
00161 QCString nameOnly;
00162 int slash = cFilename.findRev('/');
00163 if (slash < 0)
00164 nameOnly = cFilename;
00165 else
00166 nameOnly = cFilename.mid(slash + 1);
00167 cBackup = QFile::encodeName(backupDir);
00168 if ( backupDir[backupDir.length()-1] != '/' )
00169 cBackup += '/';
00170 cBackup += nameOnly;
00171 }
00172 cBackup += QFile::encodeName(backupExtension);
00173 const char *backup = cBackup.data();
00174 int permissions = buff.st_mode & 07777;
00175
00176 if ( stat( backup, &buff) == 0)
00177 {
00178 if ( unlink( backup ) != 0 )
00179 {
00180 ::close(fd);
00181 return false;
00182 }
00183 }
00184
00185 mode_t old_umask = umask(0);
00186 int fd2 = open( backup, O_WRONLY | O_CREAT | O_EXCL, permissions | S_IWUSR);
00187 umask(old_umask);
00188
00189 if ( fd2 < 0 )
00190 {
00191 ::close(fd);
00192 return false;
00193 }
00194
00195 char buffer[ 32*1024 ];
00196
00197 while( 1 )
00198 {
00199 int n = ::read( fd, buffer, 32*1024 );
00200 if (n == -1)
00201 {
00202 if (errno == EINTR)
00203 continue;
00204 ::close(fd);
00205 ::close(fd2);
00206 return false;
00207 }
00208 if (n == 0)
00209 break;
00210
00211 if (write_all( fd2, buffer, n))
00212 {
00213 ::close(fd);
00214 ::close(fd2);
00215 return false;
00216 }
00217 }
00218
00219 ::close( fd );
00220
00221 if (::close(fd2))
00222 return false;
00223 return true;
00224 }
This file is part of the documentation for kdecore Library Version 3.2.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Mar 4 22:43:31 2004 by
doxygen 1.3.6-20040222 written by
Dimitri van Heesch, © 1997-2003