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