patch for dpkg to support long file names (bug #26431)
Here's a patch to dpkg that enables support for long file names. I
haven't tested it extensively, but it seems to work here.
I looked at how GNU tar handled long file names and tried to imitate
that.
Drew
Index: tarfn.c
===================================================================
RCS file: /cvs/root/misc/dpkg/lib/tarfn.c,v
retrieving revision 1.1.1.1
diff -u -u -r1.1.1.1 tarfn.c
--- tarfn.c 1997/12/08 04:53:27 1.1.1.1
+++ tarfn.c 1998/10/20 21:22:48
@@ -105,6 +105,15 @@
char buffer[512];
TarInfo h;
+ char *next_long_name, *next_long_link;
+ char *bp;
+ char **longp;
+ int long_read;
+
+ next_long_name = 0;
+ next_long_link = 0;
+ long_read = 0;
+
h.UserData = userData;
while ( (status = functions->Read(userData, buffer, 512)) == 512 ) {
@@ -118,6 +127,17 @@
return -1; /* Header checksum error */
}
}
+ if (next_long_name) {
+ h.Name = next_long_name;
+ }
+
+ if (next_long_link) {
+ h.LinkName = next_long_link;
+ }
+
+ next_long_name = 0;
+ next_long_link = 0;
+
if ( h.Name[0] == '\0' ) {
errno = 0; /* Indicates broken tarfile */
return -1; /* Bad header data */
@@ -149,6 +169,67 @@
case FIFO:
status = (*functions->MakeSpecialFile)(&h);
break;
+ case GNU_LONGLINK:
+ case GNU_LONGNAME:
+ // set longp to the location of the long filename or link
+ // we're trying to deal with
+ longp = ((h.Type == GNU_LONGNAME)
+ ? &next_long_name
+ : &next_long_link);
+
+ if (*longp)
+ free(*longp);
+
+ if (NULL == (*longp = (char *)malloc(h.Size))) {
+ /* malloc failed, so bail */
+ errno = 0;
+ return -1;
+ }
+ bp = *longp;
+
+ // As far as I can tell, the way the GNU long{link,name}
+ // stuff works is like this: The first header is a "dummy"
+ // header that contains the size of the filename. The
+ // next N headers contain the filename. After the headers
+ // with the filename comes the "real" header with a bogus
+ // name or link.
+ for (long_read = h.Size; long_read > 0;
+ long_read -= 512) {
+
+ int copysize;
+
+ status = functions->Read(userData, buffer, 512);
+ // if we didn't get 512 bytes read, punt
+ if (512 != status) {
+ errno = 0;
+ return -1;
+ }
+
+ // It's kludge time. We want to read to the end of the
+ // buffer and we need to read a blocking factor at a
+ // time. The default is 20 and I don't know how
+ // to figure out what the current tar file is using
+
+ // In addition, I don't understand the
+ // relationship between blocking factor and block
+ // size. If we've read a block size, why do we
+ // need to read a blocking factor at a time? I
+ // guess it's tape releated.
+
+ // The GNU tar code is much cleaner than this
+ // stuff which seems to ignore blocking factor, so
+ // I'll go with the code flow.
+
+ copysize = long_read > 512 ? 512 : long_read;
+ memcpy (bp, buffer, copysize);
+ bp += copysize;
+
+ };
+ // This decode function expects status to be 0 after
+ // the case statement if we successfully decoded. I
+ // guess what we just did was successful.
+ status = 0;
+ break;
default:
errno = 0; /* Indicates broken tarfile */
return -1; /* Bad header field */
--
begin 644 ahobson@mindspring.com.booby.trap.yes.it.is.gzipped.twice.gz.gz
M'XL(`/*U^C`"`Y/OYF!XN?67`1/SVX.,O`P,#(<6V+V7OR#'I\$P"D;!*!@%
HHV`4C()1,`I&P2@8!:-@%(P"$'APET'ED<H7!DY;!@`$55!J2`\``$;!
` My God, it's full of stars
end
--RAA09413.908919415/computer.eng.mindspring.net--
Reply to: