1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
// 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 );
}
}
}
}
|