kio
kshred.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "kshred.h"
00024 #include <time.h>
00025 #include <klocale.h>
00026 #include <kdebug.h>
00027 #include <stdlib.h>
00028 #include <kapplication.h>
00029
00030
00031 KShred::KShred(QString fileName)
00032 {
00033 if (fileName.isEmpty())
00034 {
00035 kdError() << "KShred: missing file name in constructor" << endl;
00036 file = 0L;
00037 }
00038 else
00039 {
00040 file = new QFile();
00041 file->setName(fileName);
00042 if (!file->open(IO_ReadWrite))
00043 {
00044 kdError() << "KShred: cannot open file '" << fileName.local8Bit().data() << "' for writing\n" << endl;
00045 file = 0L;
00046 fileSize = 0;
00047 }
00048 else
00049 fileSize = file->size();
00050
00051 totalBytes = 0;
00052 bytesWritten = 0;
00053 lastSignalled = 0;
00054 tbpc = 0;
00055 fspc = 0;
00056 }
00057 }
00058
00059
00060 KShred::~KShred()
00061 {
00062 if (file != 0L)
00063 delete file;
00064 }
00065
00066
00067 bool
00068 KShred::fill1s()
00069 {
00070 return fillbyte(0xFF);
00071 }
00072
00073
00074 bool
00075 KShred::fill0s()
00076 {
00077 return fillbyte(0x0);
00078 }
00079
00080
00081 bool
00082 KShred::fillbyte(unsigned int byte)
00083 {
00084 if (file == 0L)
00085 return false;
00086 unsigned char buff[4096];
00087 memset((void *) buff, byte, 4096);
00088
00089 unsigned int n;
00090 for (unsigned int todo = fileSize; todo > 0; todo -= n)
00091 {
00092 n = (todo > 4096 ? 4096 : todo);
00093 if (!writeData(buff, n))
00094 return false;
00095 }
00096 if (!flush())
00097 return false;
00098 return file->at(0);
00099 }
00100
00101
00102 bool
00103 KShred::fillpattern(unsigned char *data, unsigned int size)
00104 {
00105 if (file == 0L)
00106 return false;
00107
00108 unsigned int n;
00109 for (unsigned int todo = fileSize; todo > 0; todo -= n)
00110 {
00111 n = (todo > size ? size : todo);
00112 if (!writeData(data, n))
00113 return false;
00114 }
00115 if (!flush())
00116 return false;
00117 return file->at(0);
00118 }
00119
00120
00121 bool
00122 KShred::fillrandom()
00123 {
00124 if (file == 0L)
00125 return false;
00126
00127 long int buff[4096 / sizeof(long int)];
00128 unsigned int n;
00129
00130 for (unsigned int todo = fileSize; todo > 0; todo -= n)
00131 {
00132 n = (todo > 4096 ? 4096 : todo);
00133
00134 int limit = (n + sizeof(long int) - 1) / sizeof(long int);
00135 for (int i = 0; i < limit; i++)
00136 buff[i] = kapp->random();
00137
00138 if (!writeData((unsigned char *) buff, n))
00139 return false;
00140 }
00141 if (!flush())
00142 return false;
00143 return file->at(0);
00144 }
00145
00146
00147
00148 bool
00149 KShred::shred(QString fileName)
00150 {
00151 if (fileName.isEmpty())
00152 return false;
00153
00154 KShred shredder(fileName);
00155 return shredder.shred();
00156 }
00157
00158
00159 bool
00160 KShred::writeData(unsigned char *data, unsigned int size)
00161 {
00162 unsigned int ret = 0;
00163
00164
00165 while ((ret < size) && (file->putch((int) data[ret]) >= 0))
00166 ret++;
00167
00168 if ((totalBytes > 0) && (ret > 0))
00169 {
00170 if (tbpc == 0)
00171 {
00172 tbpc = ((unsigned int) (totalBytes / 100)) == 0 ? 1 : totalBytes / 100;
00173 fspc = ((unsigned int) (fileSize / 100)) == 0 ? 1 : fileSize / 100;
00174 }
00175 bytesWritten += ret;
00176 unsigned int pc = (unsigned int) (bytesWritten / tbpc);
00177 if (pc > lastSignalled)
00178 {
00179 emit processedSize(fspc * pc);
00180 lastSignalled = pc;
00181 }
00182 }
00183 return ret == size;
00184 }
00185
00186
00187 bool
00188 KShred::flush()
00189 {
00190 if (file == 0L)
00191 return false;
00192
00193 file->flush();
00194 return (fsync(file->handle()) == 0);
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 bool
00207 KShred::shred()
00208 {
00209 unsigned char p[6][3] = {{'\222', '\111', '\044'}, {'\111', '\044', '\222'},
00210 {'\044', '\222', '\111'}, {'\155', '\266', '\333'},
00211 {'\266', '\333', '\155'}, {'\333', '\155', '\266'}};
00212 QString msg = i18n("Shredding: pass %1 of 35");
00213
00214 emit processedSize(0);
00215
00216
00217 totalBytes = fileSize * 35;
00218 int iteration = 1;
00219
00220 for (int ctr = 0; ctr < 4; ctr++)
00221 if (!fillrandom())
00222 return false;
00223 else
00224 {
00225 emit infoMessage(msg.arg(iteration));
00226 }
00227
00228 if (!fillbyte((unsigned int) 0x55))
00229 return false;
00230 emit infoMessage(msg.arg(iteration));
00231
00232 if (!fillbyte((unsigned int) 0xAA))
00233 return false;
00234 emit infoMessage(msg.arg(iteration));
00235
00236 for (unsigned int ctr = 0; ctr < 3; ctr++)
00237 if (!fillpattern(p[ctr], 3))
00238 return false;
00239 else
00240 {
00241 emit infoMessage(msg.arg(iteration));
00242 }
00243
00244 for (unsigned int ctr = 0; ctr <= 255 ; ctr += 17)
00245 if (!fillbyte(ctr))
00246 return false;
00247 else
00248 {
00249 emit infoMessage(msg.arg(iteration));
00250 }
00251
00252 for (unsigned int ctr = 0; ctr < 6; ctr++)
00253 if (!fillpattern(p[ctr], 3))
00254 return false;
00255 else
00256 {
00257 emit infoMessage(msg.arg(iteration));
00258 }
00259
00260 for (int ctr = 0; ctr < 4; ctr++)
00261 if (!fillrandom())
00262 return false;
00263 else
00264 {
00265 emit infoMessage(msg.arg(iteration));
00266 }
00267
00268 if (!file->remove())
00269 return false;
00270 file = 0L;
00271 emit processedSize(fileSize);
00272 return true;
00273 }
00274
00275 #include "kshred.moc"
00276