diff options
Diffstat (limited to 'kdat/Tape.cpp')
-rw-r--r-- | kdat/Tape.cpp | 933 |
1 files changed, 933 insertions, 0 deletions
diff --git a/kdat/Tape.cpp b/kdat/Tape.cpp new file mode 100644 index 0000000..b015376 --- /dev/null +++ b/kdat/Tape.cpp @@ -0,0 +1,933 @@ +// KDat - a tar-based DAT archiver +// Copyright (C) 1998-2000 Sean Vyain, svyain@mail.tds.net +// Copyright (C) 2001-2002 Lawrence Widman, kdat@cardiothink.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> +#include <errno.h> + +#include <qfile.h> + +#include <kmessagebox.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kapplication.h> + +#include "IndexDlg.h" +#include "KDatMainWindow.h" +#include "Options.h" +#include "Tape.h" +#include "TapeDrive.h" +#include "TapeManager.h" +#include "kdat.h" + +Tape::Tape() + : _stubbed( FALSE ), + _name( i18n( "New Tape" ) ), + _size( Options::instance()->getDefaultTapeSize() ), + _fptr( 0 ) +{ + char buffer[1024]; + gethostname( buffer, 1024 ); + time_t tm = time( NULL ); + _ctime = tm; + _mtime = tm; + _id.sprintf("%s:%d", buffer, tm); + + write(); +} + +Tape::Tape( const char * id ) + : _stubbed( TRUE ), + _id( id ), + _ctime( -1 ), + _mtime( -1 ), + _name( "<unknown>" ), + _size( -1 ), + _fptr( 0 ) +{ +} + +Tape::~Tape() +{ + clear(); +} + +void Tape::format() +{ + // Rewind tape. + if ( !TapeDrive::instance()->rewind() ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Rewinding tape failed." ), i18n("Format Failed")); + return; + } + + // Set block size for tape. + if ( !TapeDrive::instance()->setBlockSize( Options::instance()->getTapeBlockSize() ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Cannot set tape block size." ), i18n("Format Failed")); + return; + } + + // TAPE HEADER + int iv; + + // KDat magic string. + if ( TapeDrive::instance()->write( KDAT_MAGIC, KDAT_MAGIC_LENGTH ) < KDAT_MAGIC_LENGTH ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Writing magic string failed." ), i18n("Format Failed")); + return; + } + + // Tape header version number. + iv = KDAT_TAPE_HEADER_VERSION; + if ( TapeDrive::instance()->write( (const char*)&iv, 4 ) < 4 ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Writing version number failed." ), i18n("Format Failed") ); + return; + } + + // Write tape ID. Tape ID is machine name + current time. + iv = _id.length() + 1; + if ( TapeDrive::instance()->write( (const char*)&iv, 4 ) < 4 ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Writing tape ID length failed." ), i18n("Format Failed") ); + return; + } + if ( TapeDrive::instance()->write( _id, iv ) < iv ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Writing tape ID failed." ), i18n("Format Failed") ); + return; + } + + // Write end of file marker. + TapeDrive::instance()->close(); + TapeDrive::instance()->open(); + + // Write new tape index. + write(); +} + +void Tape::read() +{ + if ( !_stubbed ) { + /* 2002-01-28 LEW */ + // printf("Can't read tape data because tape isn't stubbed\n" ); + /* 2002-01-28 LEW */ + return; + } + + _stubbed = FALSE; + + /* 2002-01-28 LEW */ + // printf("Preparing to read tape data\n" ); + // QString filename1 = locateLocal( "appdata", _id); + // printf("The tape data are in \"%s\"\n", filename1.ascii() ); + /* 2002-01-28 LEW */ + + if ( !_fptr ) { + QString filename = locateLocal( "appdata", _id); + _fptr = fopen( QFile::encodeName(filename), "r" ); + + /* 2002-01-28 LEW */ +#ifdef DEBUG + // printf("Opened tape archive file \"%s\". %s %d\n", + // filename.ascii(), __FILE__, __LINE__ ); +#endif /* DEBUG */ + /* 2002-01-28 LEW */ + + } + + if ( !_fptr ) { + // No tape index file was found. + int result = KMessageBox::warningContinueCancel( KDatMainWindow::getInstance(), + i18n( "No index file was found for this tape.\n" + "Recreate the index from tape?" ), + i18n("Tape Index"), + i18n("Recreate")); + if (result == KMessageBox::Continue ) { + write(); + + IndexDlg dlg( this, KDatMainWindow::getInstance() ); + dlg.exec(); + TapeManager::instance()->addTape( this ); + return; + } else { + return; + } + } + + char buf[4096]; + + fseek( _fptr, 0, SEEK_SET ); + + // Read index file version number. + if ( !fgets( buf, 4096, _fptr ) ) { + fclose( _fptr ); + KMessageBox::error( KDatMainWindow::getInstance(), + i18n( "Reading version number failed." ), + i18n("Index File Error") ); + return; + } + int version = atoi( buf ); + + switch ( version ) { + case 1: + readVersion1Index( _fptr ); + readAll( version ); + calcRanges(); + fclose( _fptr ); + _fptr = NULL; + write(); + break; + + case 2: + readVersion2Index( _fptr ); + readAll( version ); + calcRanges(); + fclose( _fptr ); + _fptr = NULL; + write(); + break; + + case 3: + readVersion3Index( _fptr ); + readAll( version ); + calcRanges(); + fclose( _fptr ); + _fptr = NULL; + write(); + break; + + case 4: + readVersion4Index( _fptr ); + break; + + default: + { + KMessageBox::sorry( KDatMainWindow::getInstance(), + i18n( "The tape index file format is version %d. The index cannot be read by this version of KDat. Perhaps the tape index file was created by a newer version of KDat?" ).arg(version ), + i18n("Tape Index") ); + } + } +} + +void Tape::readAll( int version ) +{ + read(); + + QPtrListIterator<Archive> i( _children ); + for ( ; i.current(); ++i ) { + i.current()->readAll( version ); + } +} + +void Tape::write() +{ + QString filename = locateLocal( "appdata", _id); + + /* 2002-01-28 LEW */ +#ifdef DEBUG + // printf("Preparing to write the archive data to \"%s\". %s %d\n", + // filename.ascii(), __FILE__, __LINE__ ); +#endif /* DEBUG */ + /* 2002-01-28 LEW */ + + if ( !_fptr ) { + _fptr = fopen( QFile::encodeName(filename), "w" ); + + /* 2002-01-31 LEW */ +#ifdef DEBUG + // printf("Opened new archive file \"%s\". %s %d\n", + // filename.ascii(), __FILE__, __LINE__ ); +#endif /* DEBUG */ + /* 2002-01-31 LEW */ + + if ( !_fptr ) { + // Suck! + printf( "Tape::write() -- cannot open '%s' for writing!\n", filename.ascii() ); + return; + } + } else { + freopen( QFile::encodeName(filename), "w", _fptr ); + /* 2002-01-31 LEW */ +#ifdef DEBUG + // printf("Reopened new archive file \"%s\". %s %d\n", + // filename.ascii(), __FILE__, __LINE__ ); +#endif /* DEBUG */ + /* 2002-01-31 LEW */ + } + + int zero = 0; + + //===== Write the tape data ===== + + fprintf( _fptr, "%d\n", KDAT_INDEX_FILE_VERSION ); + fprintf( _fptr, "%s\n", _id.data() ); + + fwrite( &_ctime, sizeof( _ctime ), 1, _fptr ); + fwrite( &_mtime, sizeof( _mtime ), 1, _fptr ); + fwrite( &_size , sizeof( _size ), 1, _fptr ); + char buf[4096]; + memset( buf, 0, 4096 ); + memcpy( buf, _name.ascii(), _name.length() > 4095 ? 4095 : _name.length() ); + fwrite( buf, sizeof( char ), 4096, _fptr ); + int ival = _children.count(); + fwrite( &ival, sizeof( ival ), 1, _fptr ); + + // Fill in the archive offsets later... + int archiveTable = ftell( _fptr ); + for ( uint i = 0; i < MAX_NUM_ARCHIVES; i++ ) { + fwrite( &zero, sizeof( zero ), 1, _fptr ); + } + + //===== Write archives ===== + QPtrListIterator<Archive> i( _children ); + int count = 0; + for ( ; i.current(); ++i, count++ ) { + // Fill in the file offset. + int here = ftell( _fptr ); + fseek( _fptr, archiveTable + 4*count, SEEK_SET ); + fwrite( &here, sizeof( here ), 1, _fptr ); + fseek( _fptr, here, SEEK_SET ); + + i.current()->write( _fptr ); + } + + freopen( QFile::encodeName(filename), "r+", _fptr ); +} + +QString Tape::getID() +{ + read(); + + return _id; +} + +QString Tape::getName() +{ + read(); + + return _name; +} + +int Tape::getCTime() +{ + read(); + + return _ctime; +} + +int Tape::getMTime() +{ + read(); + + return _mtime; +} + +int Tape::getSize() +{ + read(); + + return _size; +} + +const QPtrList<Archive>& Tape::getChildren() +{ + read(); + + return _children; +} + +void Tape::setName( const QString & name ) +{ + /* 2002-01-31 LEW */ + int i; + /* 2002-01-31 LEW */ + + read(); + + if ( !_fptr ) { + // Create a new empty index file. + write(); + } + + // change file to read-write so we can update it 2002-01-31 LEW + QString filename = locateLocal( "appdata", _id); + freopen( QFile::encodeName(filename), "r+", _fptr ); + + _name = name; + + char buf[4096]; + if( fseek( _fptr, 0, SEEK_SET ) < 0 ) + { + clearerr( _fptr ); +#ifdef DEBUG /* Can't create new i18n strings now, so we'll save this for KDE 3.1 */ + /* Note to translator: this error checking was added while tracking + down a bug that turns out to be unrelated. The errors I'm looking + for here haven't happened in real use, so there is no rush to add + these checks in KDE 3.0. Thanks. - LW */ + QString msg = i18n("Error during fseek #1 while accessing archive: \""); + msg.append( getID() ); + msg.append( "\": " ); + msg.append( i18n(strerror( errno )) ); + printf("%s\n", msg.latin1()); + KMessageBox::error(NULL, msg, i18n("File Access Error")); +#endif /* DEBUG */ + return; + } + if( fgets( buf, 4096, _fptr ) == NULL ) + { + clearerr( _fptr ); +#ifdef DEBUG /* Can't create new i18n strings now, so we'll save this for KDE 3.1 */ + QString msg = i18n("Error while accessing string #1 in archive: \""); + msg.append( getID() ); + msg.append( "\": " ); + msg.append( i18n(strerror( errno )) ); + printf("%s\n", msg.latin1()); + KMessageBox::error(NULL, msg, i18n("File Access Error")); +#endif /* DEBUG */ + return; + } + if( fgets( buf, 4096, _fptr ) == NULL ) + { + clearerr( _fptr ); +#ifdef DEBUG /* Can't create new i18n strings now, so we'll save this for KDE 3.1 */ + QString msg = i18n("Error while accessing string #2 in archive: \""); + msg.append( getID() ); + msg.append( "\": " ); + msg.append( i18n(strerror( errno )) ); + printf("%s\n", msg.latin1()); + KMessageBox::error(NULL, msg, i18n("File Access Error")); +#endif /* DEBUG */ + return; + } + if( fseek( _fptr, 12, SEEK_CUR ) < 0 ) + { + clearerr( _fptr ); +#ifdef DEBUG /* Can't create new i18n strings now, so we'll save this for KDE 3.1 */ + QString msg = i18n("Error during fseek #2 while accessing archive: \""); + msg.append( getID() ); + msg.append( "\": " ); + msg.append( i18n(strerror( errno )) ); + printf("%s\n", msg.latin1()); + KMessageBox::error(NULL, msg, i18n("File Access Error")); +#endif /* DEBUG */ + return; + } + memset( buf, 0, 4096 ); + memcpy( buf, _name.ascii(), _name.length() > 4095 ? 4095 : _name.length() ); + i = fwrite( buf, sizeof( char ), 4096, _fptr ); + /* 2002-01-31 LEW */ + /* Note to translator: I know it's past the deadline, so don't translate this. I think + I fixed the bug that caused this error to occur. Thanks - LW */ + if( ( i < 4096 ) || ( ferror( _fptr ) != 0 )){ + clearerr( _fptr ); + QString msg = i18n("Error while updating archive name: "); + msg.append( i18n(strerror( errno )) ); + printf("%s\n", msg.latin1()); + KMessageBox::error(NULL, msg, i18n("File Access Error")); + // return; + /* 2002-01-31 LEW */ + } + fflush( _fptr ); + + /* 2002-01-31 LEW */ +#ifdef DEBUG + // printf("Tape::setName. wrote \"%s\" (%d bytes) into archive ID %s. %s %d\n", + // _name.ascii(), _name.length(), getID().latin1(), __FILE__, __LINE__); + // printf(" The buffer size is 4096. %d bytes were written\n", i); +#endif /* DEBUG */ + /* 2002-01-31 LEW */ + + // change back to read-only 2002-01-31 LEW + freopen( QFile::encodeName(filename), "r", _fptr ); + + TapeManager::instance()->tapeModified( this ); +} + +void Tape::setMTime( int mtime ) +{ + read(); + + if ( !_fptr ) { + // Create a new empty index file. + write(); + } + + // change file to read-write so we can update it 2002-01-31 LEW + QString filename = locateLocal( "appdata", _id); + freopen( QFile::encodeName(filename), "r+", _fptr ); + + _mtime = mtime; + + char buf[4096]; + fseek( _fptr, 0, SEEK_SET ); + fgets( buf, 4096, _fptr ); + fgets( buf, 4096, _fptr ); + fseek( _fptr, 4, SEEK_CUR ); + fwrite( &_mtime, sizeof( _mtime ), 1, _fptr ); + fflush( _fptr ); + + // change back to read-only 2002-01-31 LEW + freopen( QFile::encodeName(filename), "r", _fptr ); + + TapeManager::instance()->tapeModified( this ); +} + +void Tape::setSize( int size ) +{ + read(); + + if ( !_fptr ) { + // Create a new empty index file. + write(); + } + + _size = size; + + // change file to read-write so we can update it 2002-01-31 LEW + QString filename = locateLocal( "appdata", _id); + freopen( QFile::encodeName(filename), "r+", _fptr ); + + char buf[4096]; + fseek( _fptr, 0, SEEK_SET ); + fgets( buf, 4096, _fptr ); + fgets( buf, 4096, _fptr ); + fseek( _fptr, 8, SEEK_CUR ); + fwrite( &_size, sizeof( _size ), 1, _fptr ); + fflush( _fptr ); + + // change back to read-only 2002-01-31 LEW + freopen( QFile::encodeName(filename), "r", _fptr ); + + TapeManager::instance()->tapeModified( this ); +} + +void Tape::addChild( Archive* archive ) +{ + /* 2002-01-28 LEW */ + // printf("Preparing to add archive to tape file\n" ); + /* 2002-01-28 LEW */ + + read(); + + // change file to read-write so we can update it 2002-01-31 LEW + QString filename = locateLocal( "appdata", _id); + freopen( QFile::encodeName(filename), "r+", _fptr ); + + archive->calcRanges(); + + _children.append( archive ); + + char buf[4096]; + fseek( _fptr, 0, SEEK_END ); + int here = ftell( _fptr ); + fseek( _fptr, 0, SEEK_SET ); + fgets( buf, 4096, _fptr ); + fgets( buf, 4096, _fptr ); + fseek( _fptr, 12 + 4096, SEEK_CUR ); + int ival = _children.count(); + fwrite( &ival, sizeof( ival ), 1, _fptr ); + fseek( _fptr, ( _children.count() - 1 ) * 4, SEEK_CUR ); + fwrite( &here, sizeof( here ), 1, _fptr ); + fseek( _fptr, here, SEEK_SET ); + archive->write( _fptr ); + fflush( _fptr ); + + setMTime( time( NULL ) ); + + // change back to read-only 2002-01-31 LEW + freopen( QFile::encodeName(filename), "r", _fptr ); + + /* 2002-01-28 LEW */ + // printf("Done adding archive to tape file\n" ); + /* 2002-01-28 LEW */ +} + +void Tape::removeChild( Archive* archive ) +{ + read(); + + while ( _children.last() != archive ) { + _children.removeLast(); + } + _children.removeLast(); + + char buf[4096]; + fseek( _fptr, 0, SEEK_SET ); + fgets( buf, 4096, _fptr ); + fgets( buf, 4096, _fptr ); + fseek( _fptr, 12 + 4096, SEEK_CUR ); + int ival = _children.count(); + fwrite( &ival, sizeof( ival ), 1, _fptr ); + int here; + if ( ival > 0 ) { + fseek( _fptr, _children.count() * 4, SEEK_CUR ); + fread( &here, sizeof( here ), 1, _fptr ); + } else { + fseek( _fptr, MAX_NUM_ARCHIVES * 4, SEEK_CUR ); + here = ftell( _fptr ); + } + + QString filename = locateLocal( "appdata", _id); + truncate( QFile::encodeName(filename), here ); + freopen( QFile::encodeName(filename), "r+", _fptr ); + fflush( _fptr ); + + // change back to read-only 2002-01-31 LEW + freopen( QFile::encodeName(filename), "r", _fptr ); + + setMTime( time( NULL ) ); +} + +void Tape::clear() +{ + if ( _children.count() < 1 ) { + return; + } + + while ( _children.first() ) { + delete _children.first(); + _children.removeFirst(); + } + + char buf[4096]; + fseek( _fptr, 0, SEEK_SET ); + fgets( buf, 4096, _fptr ); + fgets( buf, 4096, _fptr ); + fseek( _fptr, 12 + 4096, SEEK_CUR ); + int ival = _children.count(); + fwrite( &ival, sizeof( ival ), 1, _fptr ); + fseek( _fptr, MAX_NUM_ARCHIVES * 4, SEEK_CUR ); + int here = ftell( _fptr ); + + QString filename = locateLocal( "appdata", _id); + truncate( QFile::encodeName(filename), here ); + freopen( QFile::encodeName(filename), "r+", _fptr ); + fflush( _fptr ); + + // change back to read-only 2002-01-31 LEW + freopen( QFile::encodeName(filename), "r", _fptr ); + + setMTime( time( NULL ) ); +} + +void Tape::readVersion1Index( FILE* fptr ) +{ + fseek( fptr, 0, SEEK_CUR ); + + char buf[4096]; + + // Read the tapeID. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading tape ID failed." ), i18n("Index File Error") ); + return; + } + QCString tapeID = buf; + tapeID.truncate( tapeID.length() - 1 ); + if ( tapeID !=_id ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Tape ID on tape does not match tape ID in index file." ), i18n("Index File Error") ); + return; + } + + // Read creation time. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading creation time failed." ), i18n("Index File Error") ); + return; + } + _ctime = atoi( buf ); + + // Read modification time. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading modification time failed." ), i18n("Index File Error") ); + return; + } + _mtime = atoi( buf ); + + // Read tape name. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading tape name failed." ), i18n("Index File Error") ); + return; + } + _name = buf; + _name.truncate( _name.length() - 1 ); + + // Read tape size. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading tape size failed." ), i18n("Index File Error") ); + return; + } + _size = atoi( buf ); + + // Read number of archives. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading archive count failed." ), i18n("Index File Error") ); + return; + } + int numArchives = atoi( buf ); + + for ( ; numArchives; numArchives-- ) { + // Read archive name. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading archive name failed." ), i18n("Index File Error") ); + return; + } + QString archiveName = buf; + archiveName.truncate( archiveName.length() - 1 ); + + // Read archive time stamp. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading archive time stamp failed." ), i18n("Index File Error") ); + return; + } + int archiveTimeStamp = atoi( buf ); + + // Read archive start block. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading archive start block failed." ), i18n("Index File Error") ); + return; + } + int archiveStartBlock = atoi( buf ); + + // Read archive end block. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading archive end block failed." ), i18n("Index File Error") ); + return; + } + int archiveEndBlock = atoi( buf ); + + // Create the archive. + Archive* archive = new Archive( this, archiveTimeStamp, archiveName ); + archive->setEndBlock( archiveEndBlock - archiveStartBlock ); + + _children.append( archive ); + + // Read the number of files. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading archive file count failed." ), i18n("Index File Error") ); + return; + } + int archiveNumFiles = atoi( buf ); + + QString tmpFileName; + int tmpFileSize = -1; + int tmpFileMTime = -1; + int tmpFileStartRecord = -1; + for ( ; archiveNumFiles; archiveNumFiles-- ) { + // Read file name. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading file name failed." ), i18n("Index File Error") ); + return; + } + QString fileName = buf; + fileName.truncate( fileName.length() - 1 ); + + // Read file size. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading file size failed." ), i18n("Index File Error") ); + return; + } + int fileSize = atoi( buf ); + + // Read file modification time. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading file modification time failed." ), i18n("Index File Error") ); + return; + } + int fileModTime = atoi( buf ); + + // Read file record number. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading file record number failed." ), i18n("Index File Error") ); + return; + } + int fileRecord = atoi( buf ); + + if ( tmpFileName.length() > 0 ) { + archive->addFile( tmpFileSize, tmpFileMTime, tmpFileStartRecord, fileRecord, tmpFileName ); + } + + tmpFileName = fileName.copy(); + tmpFileSize = fileSize; + tmpFileMTime = fileModTime; + tmpFileStartRecord = fileRecord; + } + + if ( tmpFileName.length() > 0 ) { + archive->addFile( tmpFileSize, tmpFileMTime, tmpFileStartRecord, archive->getEndBlock() * ( Options::instance()->getTapeBlockSize() / 512 ), tmpFileName ); + } + } +} + +void Tape::readVersion2Index( FILE* fptr ) +{ + fseek( fptr, 0, SEEK_CUR ); + + char buf[4096]; + + // Read the tapeID. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading tape ID failed." ), i18n("Index File Error") ); + return; + } + QCString tapeID = buf; + tapeID.truncate( tapeID.length() - 1 ); + if ( tapeID != _id ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Tape ID on tape does not match tape ID in index file." ), i18n("Index File Error") ); + return; + } + + // Read creation time. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading creation time failed." ), i18n("Index File Error") ); + return; + } + _ctime = atoi( buf ); + + // Read modification time. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading modification time failed." ), i18n("Index File Error") ); + return; + } + _mtime = atoi( buf ); + + // Read tape name. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading tape name failed." ), i18n("Index File Error") ); + return; + } + _name = buf; + _name.truncate( _name.length() - 1 ); + + // Read tape size. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading tape size failed." ), i18n("Index File Error") ); + return; + } + _size = atoi( buf ); + + // Read number of archives. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading archive count failed." ), i18n("Index File Error") ); + return; + } + int numArchives = atoi( buf ); + + int ival; + for ( ; numArchives; numArchives-- ) { + fread( &ival, sizeof( ival ), 1, fptr ); + _children.append( new Archive( this, fptr, ival ) ); + } +} + +void Tape::readVersion3Index( FILE* fptr ) +{ + fseek( fptr, 0, SEEK_CUR ); + + char buf[4097]; + buf[4096] = '\0'; + + // Read the tapeID. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading tape ID failed." ), i18n("Index File Error") ); + return; + } + QCString tapeID = buf; + tapeID.truncate( tapeID.length() - 1 ); + if ( tapeID != _id ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Tape ID on tape does not match tape ID in index file." ), i18n("Index File Error") ); + return; + } + + // Read creation time. + fread( &_ctime, sizeof( _ctime ), 1, fptr ); + + // Read modification time. + fread( &_mtime, sizeof( _mtime ), 1, fptr ); + + // Read tape size. + fread( &_size, sizeof( _size ), 1, fptr ); + + // Read tape name. + fread( buf, sizeof( char ), 4096, fptr ); + _name = buf; + + // Read number of archives. + int numArchives; + fread( &numArchives, sizeof( numArchives ), 1, fptr ); + + int ival; + for ( ; numArchives; numArchives-- ) { + fread( &ival, sizeof( ival ), 1, fptr ); + _children.append( new Archive( this, fptr, ival ) ); + } +} + +void Tape::readVersion4Index( FILE* fptr ) +{ + fseek( fptr, 0, SEEK_CUR ); + + char buf[4097]; + buf[4096] = '\0'; + + // Read the tapeID. + if ( !fgets( buf, 4096, fptr ) ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Reading tape ID failed." ), i18n("Index File Error") ); + return; + } + QCString tapeID = buf; + tapeID.truncate( tapeID.length() - 1 ); + if ( tapeID != _id ) { + KMessageBox::error( KDatMainWindow::getInstance(), i18n( "Tape ID on tape does not match tape ID in index file." ), i18n("Index File Error") ); + return; + } + + // Read creation time. + fread( &_ctime, sizeof( _ctime ), 1, fptr ); + + // Read modification time. + fread( &_mtime, sizeof( _mtime ), 1, fptr ); + + // Read tape size. + fread( &_size, sizeof( _size ), 1, fptr ); + + // Read tape name. + fread( buf, sizeof( char ), 4096, fptr ); + _name = buf; + + // Read number of archives. + int numArchives; + fread( &numArchives, sizeof( numArchives ), 1, fptr ); + + int ival; + for ( ; numArchives; numArchives-- ) { + fread( &ival, sizeof( ival ), 1, fptr ); + _children.append( new Archive( this, fptr, ival ) ); + } + + /* 2002-01-31 LEW */ +#ifdef DEBUG + printf("Read contents of archive file \"%s\". %s %d\n", + _name.latin1(), __FILE__, __LINE__ ); +#endif /* DEBUG */ + /* 2002-01-31 LEW */ +} + +void Tape::calcRanges() +{ + QPtrListIterator<Archive> it( getChildren() ); + for ( ; it.current(); ++it ) { + it.current()->calcRanges(); + } +} |