From: Keith M. <kei...@us...> - 2010-08-06 22:34:57
|
Update of /cvsroot/mingw/mingw-get/src In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv7136/src Modified Files: tarproc.cpp pkgproc.h Log Message: Handle the GNU long name tar header format. Index: pkgproc.h =================================================================== RCS file: /cvsroot/mingw/mingw-get/src/pkgproc.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pkgproc.h 4 Apr 2010 15:25:36 -0000 1.3 --- pkgproc.h 6 Aug 2010 22:34:39 -0000 1.4 *************** *** 126,129 **** --- 126,130 ---- #define TAR_ENTITY_TYPE_BLKDEV '4' #define TAR_ENTITY_TYPE_DIRECTORY '5' + #define TAR_ENTITY_TYPE_GNU_LONGNAME 'L' /* Some older style tar archives may use '\0' as an alternative to '0', *************** *** 160,163 **** --- 161,165 ---- virtual int GetArchiveEntry(); virtual int ProcessEntityData( int ); + virtual char *EntityDataAsString(); /* ...those for which each specialisation is expected to Index: tarproc.cpp =================================================================== RCS file: /cvsroot/mingw/mingw-get/src/tarproc.cpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** tarproc.cpp 11 May 2010 18:13:01 -0000 1.7 --- tarproc.cpp 6 Aug 2010 22:34:39 -0000 1.8 *************** *** 232,241 **** while( GetArchiveEntry() > 0 ) { /* Found an archive entry; map it to an equivalent file system * path name, within the designated sysroot hierarchy. */ ! char *prefix = *header.field.prefix ? header.field.prefix : NULL; ! char pathname[mkpath( NULL, sysroot_path, header.field.name, prefix )]; ! mkpath( pathname, sysroot_path, header.field.name, prefix ); /* Direct further processing to the appropriate handler; (this --- 232,270 ---- while( GetArchiveEntry() > 0 ) { + char *prefix = *header.field.prefix ? header.field.prefix : NULL; + char *name = header.field.name; + + /* Handle the GNU long name header format. + * If the pathname overflows the name field, GNU tar creates a special + * entry type, where the data contains the full pathname for the + * following entry. + */ + char *longname = NULL; + if( *header.field.typeflag == TAR_ENTITY_TYPE_GNU_LONGNAME ) + { + /* Extract the full pathname from the data of this entry. + */ + longname = EntityDataAsString(); + if( !longname ) + dmh_notify( DMH_ERROR, "Unable to read a long name entry\n" ); + + /* Read the entry for which this long name is intended. + */ + if( GetArchiveEntry() <= 0 ) + dmh_notify( DMH_ERROR, "Expected a new entry after a long name entry\n" ); + + /* Use the previously determined long name as the pathname for this entry. + */ + prefix = NULL; + name = longname; + } + /* Found an archive entry; map it to an equivalent file system * path name, within the designated sysroot hierarchy. */ ! char pathname[mkpath( NULL, sysroot_path, name, prefix )]; ! mkpath( pathname, sysroot_path, name, prefix ); ! ! free( longname ); /* Direct further processing to the appropriate handler; (this *************** *** 389,392 **** --- 418,460 ---- } + char *pkgTarArchiveProcessor::EntityDataAsString() + { + /* Read the data associated with a specific header within a tar archive + * and return it as a string. The return value is stored in memory which + * is allocated by malloc; it should be freed when no longer required. + * + * It is assumed that the return data can be accommodated within available + * heap memory. Since the length isn't returned, we assume that the string + * is NUL-terminated, and that it contains no embedded NULs. + * + * In the event of any error, NULL is returned. + */ + char *data; + uint64_t bytes_to_copy = octval( header.field.size ); + + /* Round the buffer size to the smallest multiple of the record size. + */ + bytes_to_copy += sizeof( header ) - 1; + bytes_to_copy -= bytes_to_copy % sizeof( header ); + + /* Allocate the data buffer. + */ + data = (char*)(malloc( bytes_to_copy )); + if( !data ) + return NULL; + + /* Read the data into the buffer. + */ + size_t count = stream->Read( data, bytes_to_copy ); + if( count < bytes_to_copy ) + { + /* Failure to fully populate the transfer buffer, (i.e. a short + * read), indicates a corrupt archive. + */ + free( data ); + return NULL; + } + return data; + } /******************* |