00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
#include <wx/wxprec.h>
00028
00029
#ifdef __BORLANDC__
00030
#pragma hdrstop
00031
#endif
00032
00033
#ifndef WX_PRECOMP
00034
00035
#include <wx/wx.h>
00036
#endif
00037
00038
#include <wx/txtstrm.h>
00039
#include <wx/wfstream.h>
00040
00041
#include "md5file.hpp"
00042
#include "appprefs.hpp"
00043
#include "md5.hpp"
00044
#include "osdep.hpp"
00045
#include "utils.hpp"
00046
00047
#include "compat.hpp"
00048
00049
00050
00051
using namespace std;
00052
00053
00054
00055
00056
00057 MD5File::MD5File() :
SumFile()
00058 {
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 void MD5File::clone(
const MD5File& source)
00071 {
00072 SumFile::clone(source);
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082 MD5File::MD5File(
const MD5File& source)
00083 {
00084
clone(source);
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 MD5File&
MD5File::operator=(
const MD5File& source)
00096 {
00097
clone(source);
00098
return *
this;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 Checksum*
MD5File::getChecksumCalculator()
const
00112
{
00113
return new MD5();
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123 wxString
MD5File::getFileType()
const
00124
{
00125
return wxString(wxT(
"MD5"));
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 bool MD5File::read(
const wxFileName& fileName)
00148 {
00149
const int MAX_INVALID = 64;
00150 wxString line;
00151 size_t l;
00152 size_t i;
00153
bool comment;
00154
bool stop;
00155
int invalid = 0;
00156
int valid = 0;
00157
int ccomment = 0;
00158 wxChar c;
00159 wxString name;
00160 wxString sum;
00161 wxFileName nameRel;
00162 wxFileName nameAbs;
00163 wxPathFormat format;
00164
00165
00166 wxLogNull logNo;
00167
00168
00169 format = static_cast<wxPathFormat>(
AppPrefs::get()->
readLong(prMD5_READ_PATH_SEPARATOR));
00170
if (format == wxPATH_NATIVE)
00171 format = getPathFormat(fileName);
00172
00173
00174 wxFileInputStream input(fileName.GetFullPath());
00175
if (!input.Ok())
00176
return false;
00177 wxTextInputStream text(input);
00178
00179
00180
reset();
00181
00182
00183 line = text.ReadLine();
00184
while (!input.Eof() && invalid - valid <= MAX_INVALID)
00185 {
00186 l = line.size();
00187
00188
00189 i = 0;
00190 stop =
false;
00191 comment = line.empty();
00192
while (!stop && !comment && i < l)
00193 {
00194 c = line[i];
00195
if (c == wxT(
';'))
00196 comment =
true;
00197
else
00198
if (line[i] == wxT(
' ') || line[i] == wxT(
'\t'))
00199 i++;
00200
else
00201 stop =
true;
00202 }
00203
00204
if (comment || i == l)
00205
00206 {
00207 valid++;
00208 ccomment++;
00209 }
00210
else
00211 {
00212
if (line.size() > 34)
00213 {
00214 sum = line.Left(32);
00215 name = line.Right(line.size() - 34);
00216
if (!
IsValidChecksum(sum) || name.empty())
00217
00218 invalid++;
00219
else
00220 {
00221 valid++;
00222
00223 nameAbs.Assign(name, format);
00224
if (!nameAbs.IsAbsolute())
00225 nameAbs.MakeAbsolute(fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00226 nameRel = nameAbs;
00227
if (!nameRel.IsRelative())
00228 nameRel.MakeRelativeTo(fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00229
00230 addChecksumData(
ChecksumData(nameRel, sum, ChecksumData::NotVerified));
00231 }
00232 }
00233
else
00234 invalid++;
00235 }
00236
00237 line = text.ReadLine();
00238 }
00239
00240 valid -= ccomment;
00241
if ((invalid - valid <= MAX_INVALID && valid > 0) ||
00242 (valid == 0 && invalid == 0))
00243 {
00244 setFileName(fileName.GetFullPath());
00245 setModified(
false);
00246
return true;
00247 }
00248
00249
return false;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 bool MD5File::write(
const wxFileName& fileName)
00270 {
00271 wxLogNull logNo;
00272 wxString line;
00273 wxDateTime d;
00274 wxFileName nameRel;
00275 wxFileName nameAbs;
00276
wxCOff_t length;
00277 wxPathFormat format;
00278
00279 wxFileOutputStream output(fileName.GetFullPath());
00280
if (!output.Ok())
00281
return false;
00282 wxTextOutputStream text(output, static_cast<wxEOL>(AppPrefs::get()->readLong(prMD5_WRITE_EOL)));
00283
00284
00285 format = static_cast<wxPathFormat>(
AppPrefs::get()->
readLong(prMD5_WRITE_PATH_SEPARATOR));
00286
00287
00288
if (
AppPrefs::get()->
readBool(prMD5_WRITE_GEN_AND_DATE))
00289 {
00290 d = wxDateTime::Now();
00291 line.Printf(wxT(
"; Generated by %s on %s at %s\n"), ::
getAppName().c_str(),
00292 d.Format(wxT(
"%Y-%m-%d")).c_str(), d.Format(wxT(
"%H:%M:%S")).c_str());
00293 text.WriteString(line);
00294 text.WriteString(wxT(
";\n"));
00295 }
00296
00297
00298
if (
AppPrefs::get()->
readBool(prMD5_WRITE_FILE_SIZE_AND_DATE))
00299 {
00300 MChecksumData::const_iterator it =
getChecksumDataBegin();
00301 MChecksumData::const_iterator end =
getChecksumDataEnd();
00302
00303
while (it != end)
00304 {
00305
const ChecksumData& cd = it->second;
00306 nameAbs = cd.
getFileName();
00307
if (!nameAbs.IsAbsolute())
00308 nameAbs.MakeAbsolute(wxFileName(this->getFileName()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00309 nameRel = nameAbs;
00310
if (!nameRel.IsRelative())
00311 nameRel.MakeRelativeTo(fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00312
00313
if ((length =
wxCGetFileLength(nameAbs.GetFullPath())) != static_cast<wxCOff_t>(wxInvalidOffset))
00314 {
00315
#if defined(wxC_USE_LARGE_FILES)
00316
text.WriteString(wxString::Format(wxT(
"; %12" wxLongLongFmtSpec
"u "), length));
00317
#else
00318
text.WriteString(wxString::Format(wxT(
"; %12u "), length));
00319
#endif
00320
d = nameAbs.GetModificationTime();
00321 text << d.Format(wxT(
"%H:%M.%S")) << wxT(
" ") << d.Format(wxT(
"%Y-%m-%d"));
00322 text << wxT(
" ") << nameRel.GetFullPath(format) << wxT(
"\n");
00323 }
00324 it++;
00325 }
00326 }
00327
00328
00329 MChecksumData::const_iterator it =
getChecksumDataBegin();
00330 MChecksumData::const_iterator end =
getChecksumDataEnd();
00331
00332
while (it != end)
00333 {
00334
const ChecksumData& cd = it->second;
00335 nameAbs = cd.
getFileName();
00336
if (!nameAbs.IsAbsolute())
00337 nameAbs.MakeAbsolute(wxFileName(this->getFileName()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00338 nameRel = nameAbs;
00339
if (!nameRel.IsRelative())
00340 nameRel.MakeRelativeTo(fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00341
00342 text << cd.
getChecksum().Lower() << wxT(
" *")
00343 << nameRel.GetFullPath(format) << wxT(
"\n");
00344 it++;
00345 }
00346
00347
if (output.IsOk())
00348 {
00349
00350 {
00351 MChecksumData::iterator it =
getChecksumDataBeginI();
00352 MChecksumData::iterator end =
getChecksumDataEndI();
00353
00354
while (it != end)
00355 {
00356
ChecksumData& cd = it->second;
00357 nameAbs = cd.
getFileName();
00358
if (!nameAbs.IsAbsolute())
00359 nameAbs.MakeAbsolute(wxFileName(this->getFileName()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00360 nameRel = nameAbs;
00361
if (!nameRel.IsRelative())
00362 nameRel.MakeRelativeTo(fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00363
00364 cd.
setFileName(nameRel);
00365 it++;
00366 }
00367 }
00368
00369 this->setFileName(fileName.GetFullPath());
00370 this->setModified(
false);
00371
return true;
00372 }
00373
else
00374
return false;
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384 bool MD5File::IsValidChecksum(
const wxString& checksum)
00385 {
00386
const wxString validCaracters = wxT(
"0123456789abcdefABCDEF");
00387 wxChar c;
00388 size_t i, j;
00389 size_t l = checksum.size();
00390 size_t s = validCaracters.size();
00391
bool OK, found;
00392
00393 i = 0;
00394 OK = (checksum.size() == 32);
00395
while (OK && i < l)
00396 {
00397 c = checksum[i];
00398 j = 0;
00399 found =
false;
00400
while (!found && j < s)
00401 {
00402
if (c == validCaracters[j])
00403 found =
true;
00404 j++;
00405 }
00406
00407
if (!found)
00408 OK =
false;
00409 i++;
00410 }
00411
00412
return OK;
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 SumFile*
MD5File::getNewInstance()
00426 {
00427
return new MD5File();
00428 }
00429