# kio Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kshred.cpp

    00001 /*--------------------------------------------------------------------------*
    00002  KShred.h  Copyright (c) 2000 MieTerra LLC.
    00003  Credits:  Andreas F. Pour <bugs@mieterra.com>
    00004
    00005 Permission is hereby granted, free of charge, to any person obtaining a copy
    00006 of this software and associated documentation files (the "Software"), to deal
    00007 in the Software without restriction, including without limitation the rights
    00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    00009 copies of the Software, and to permit persons to whom the Software is
    00010 furnished to do so, subject to the following conditions:
    00011
    00012 The above copyright notice and this permission notice shall be included in
    00013 all copies or substantial portions of the Software.
    00014
    00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    00018 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
    00019 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    00020 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    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 // antlarr: KDE 4: Make it const QString &
    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     // assumes that 4096 is a multipe of sizeof(long int)
    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 // antlarr: KDE 4: Make it const QString &
    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   // write 'data' of size 'size' to the file
    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 // shred the file, then close and remove it
    00199 //
    00200 // UPDATED: this function now uses 35 passes based on the the article
    00201 // Peter Gutmann, "Secure Deletion of Data from Magnetic and Solid-State
    00202 // Memory", first published in the Sixth USENIX Security Symposium
    00203 // Proceedings, San Jose, CA, July 22-25, 1996 (available online at
    00204 // http://rootprompt.org/article.php3?article=473)
    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   // thirty-five times writing the entire file size
    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))     // '0x55' is 01010101
    00229     return false;
    00230   emit infoMessage(msg.arg(iteration));
    00231
    00232   if (!fillbyte((unsigned int) 0xAA))     // '0xAA' is 10101010
    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))  // '0x92', '0x49', '0x24'
    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))    // sequence of '0x00', '0x11', ..., '0xFF'
    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))  // '0x92', '0x49', '0x24'
    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

This file is part of the documentation for kio Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:24:04 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003