You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
4.3 KiB
118 lines
4.3 KiB
15 years ago
|
// 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 "TarParser.h"
|
||
|
|
||
|
#include "TarParser.moc"
|
||
|
|
||
|
TarParser::TarParser()
|
||
|
: _bufIdx( 0 ),
|
||
|
_blocksToSkip( 0 ),
|
||
|
_record( 0 ),
|
||
|
_longname( FALSE ),
|
||
|
_extended( FALSE ),
|
||
|
_archnameIdx( 0 )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void TarParser::slotData( const char * data, int length )
|
||
|
{
|
||
|
for ( int i = 0; i < length; i++ ) {
|
||
|
if ( _bufIdx >= 512 ) {
|
||
|
if ( _blocksToSkip > 0 ) {
|
||
|
if ( _extended ) {
|
||
|
record* rec = (record*)_buf;
|
||
|
_extended = rec->ext_hdr.isextended;
|
||
|
} else {
|
||
|
_blocksToSkip--;
|
||
|
if ( _longname ) {
|
||
|
memcpy( _archname + _archnameIdx, _buf, 512 );
|
||
|
_archnameIdx += 512;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
parseTarBlock();
|
||
|
}
|
||
|
_bufIdx = 0;
|
||
|
_record++;
|
||
|
}
|
||
|
_buf[_bufIdx++] = data[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int TarParser::parseOctal( const char* buf, int length )
|
||
|
{
|
||
|
int val = 0;
|
||
|
|
||
|
for ( int i = 0; i < length; i++ ) {
|
||
|
val *= 8;
|
||
|
if ( ( buf[i] >= '1' ) && ( buf[i] <= '7' ) ) {
|
||
|
val += buf[i] - '0';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
void TarParser::parseTarBlock()
|
||
|
{
|
||
|
record* rec = (record*)_buf;
|
||
|
|
||
|
#if 0
|
||
|
printf( "----- parsing tar block -----\n" );
|
||
|
printf( "arch_name = '%s'\n", rec->header.arch_name );
|
||
|
printf( "mode = '%s'\n", rec->header.mode );
|
||
|
printf( "uid = %d\n", parseOctal( rec->header.uid, 6 ) );
|
||
|
printf( "gid = %d\n", parseOctal( rec->header.gid, 6 ) );
|
||
|
printf( "size = %d\n", parseOctal( rec->header.size, 11 ) );
|
||
|
printf( "mtime = %d\n", parseOctal( rec->header.mtime, 11 ) );
|
||
|
printf( "chksum = '%s'\n", rec->header.chksum );
|
||
|
printf( "linkflag = '%c'\n", rec->header.linkflag );
|
||
|
printf( "arch_linkname = '%s'\n", rec->header.arch_linkname );
|
||
|
printf( "magic = '%s'\n", rec->header.magic );
|
||
|
printf( "uname = '%s'\n", rec->header.uname );
|
||
|
printf( "gname = '%s'\n", rec->header.gname );
|
||
|
printf( "devmajor = %d\n", parseOctal( rec->header.devmajor, 8 ) );
|
||
|
printf( "devminor = %d\n", parseOctal( rec->header.devminor, 8 ) );
|
||
|
printf( "atime = %d\n", parseOctal( rec->header.atime, 11 ) );
|
||
|
printf( "ctime = %d\n", parseOctal( rec->header.ctime, 11 ) );
|
||
|
printf( "offset = %d\n", parseOctal( rec->header.offset, 11 ) );
|
||
|
printf( "longnames = '%s'\n", rec->header.longnames );
|
||
|
printf( "isextended = %d\n", rec->header.isextended );
|
||
|
printf( "realsize = %d\n", parseOctal( rec->header.realsize, 11 ) );
|
||
|
#endif
|
||
|
|
||
|
if ( rec->header.magic[0] != 0 ) {
|
||
|
_blocksToSkip = ( parseOctal( rec->header.size, 11 ) + 511 ) / 512;
|
||
|
_extended = rec->header.isextended;
|
||
|
|
||
|
if ( rec->header.linkflag == LF_LONGNAME ) {
|
||
|
// The actual file name is stored in the next _blocksToSkip blocks of the tar-file.
|
||
|
_longname = TRUE;
|
||
|
_archnameIdx = 0;
|
||
|
} else {
|
||
|
if ( _longname ) {
|
||
|
_longname = FALSE;
|
||
|
emit sigEntry( _archname, parseOctal( rec->header.size, 11 ), parseOctal( rec->header.mtime, 11 ), _record );
|
||
|
} else {
|
||
|
emit sigEntry( rec->header.arch_name, parseOctal( rec->header.size, 11 ), parseOctal( rec->header.mtime, 11 ), _record );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|