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