[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

get debian smaller



 Hello!

I'm currently RedHat Linux user and have got to know GNU Debian Linux, which seems to be much more powerful than RedHat. Perhaps I'll be a Debian user soon. But unfortunality it is a very large distribution with 14 CD's. That's why I have decided to do something for getting Debian smaller. You are currently using the tar archiver and gzip with the maximal compression rate for creating the deb files. That's more efficient than most of the packaging systems I've ever seen but I think there could be done more to build the archives smaller. Tar puts a lot of unused garbarge inside the output, which is well compressable, of course, but there are ways to get it even smaller. Unfortunately, my suggestion introduces a very new archive design which isn't backward compatible. The first step of generation is to collect all users and groups of the files due to involve. This stuff comes after the uncompressed section size, so each group and user name will placed only one time in the archive and each node has one word to identify user and group. To save space, there are only 256 user/group entrys available for one archive section. The next part is the fs structure with date/time informations, attributs as well as the user and group byte and the entry name themself. Each entry has a size of 13 bytes + entry name length or a symlink path or device numbers for block or char nodes. It is not the whole path defined for a new format just like in tar but only what is minimally neccessary to describe the file structure. The new structure supports even more node types than tar. Actually all available under Linux. After all there comes the file contents. BZip2 compresses the whole archive. At the beginning I thought to reach a much better compression rate than before but gzip is not so bad as I thought. However file - rich archives or large text documents may become a lot smaller, especially the dev system or the kernel sources. (On my system a archive with the new deb format, containing the dev tree is 63% smaller than that, compressed with the current format) The process is much slower especially the archive creation, but one advantage to the current system is the content listing speed, which is a lot faster than now. And there is no dependency to the tar tool anymore. You will find an example solution attached, which demonstrates the archive creation and extraction. For creation you need the additional "a" - argument to enable the new format. I have no idea if you want this kind of support - all I know about debian is, there are a lot of rules and code changes needs much time to get into the code - so I have stopped developing after my main minds were working. But I think there could be done much with dpkg to get it better. For example a diff package for the several kernel source versions which inherits from one host package. This could provide a more user friendly interface for the arch - kernel source - patches. Then the user could get an extracted source tree in /usr/src/linux-xxxx. Another thing could be to design a deb format which holds the source packages in one file.....

With kind reguards
Christian Fasshauer
diff -Naur dpkg-1.10.9.orig/dpkg-deb/build.c dpkg-1.10.9.chng/dpkg-deb/build.c
--- dpkg-1.10.9.orig/dpkg-deb/build.c	2002-05-20 07:56:02.000000000 +0200
+++ dpkg-1.10.9.chng/dpkg-deb/build.c	2003-01-04 19:09:25.000000000 +0100
@@ -42,6 +42,7 @@
 #include <dpkg.h>
 #include <dpkg-db.h>
 #include "dpkg-deb.h"
+#include <dar.h>
 
 #ifndef S_ISLNK
 # define S_ISLNK(mode) ((mode&0xF000) == S_IFLNK)
@@ -365,6 +366,20 @@
    * build something. Lets start by making the ar-wrapper.
    */
   if (!(ar=fopen(debar,"wb"))) ohshite(_("unable to create `%.255s'"),debar);
+  if (advancedFormat) {
+    char *buf= malloc(255);
+    /* using the advanced debian archive format */
+    if (chdir(directory)) ohshite(_("failed to chdir to `%.225s'"),directory);
+    if (!(buf= getcwd(buf,255))) ohshite("error on saving directory");
+    if (chdir(BUILDCONTROLDIR)) ohshite(_("failed to chdir to .../DEBIAN"));
+    fprintf(ar, "!<advDebAr>\n%c",0);
+    dar(ar,NULL,0,NULL);
+    if (chdir(buf)) ohshite(_("failed to chdir to `%.225s'"),buf);
+    dar(ar,NULL,0,NULL);
+    free(buf);
+    if (fclose(ar)) werr(debar);
+    exit(0);
+  }
   if (setvbuf(ar, 0, _IONBF, 0)) ohshite(_("unable to unbuffer `%.255s'"),debar);
   /* Fork a tar to package the control-section of the package */
   m_pipe(p1);
diff -Naur dpkg-1.10.9.orig/dpkg-deb/dpkg-deb.h dpkg-1.10.9.chng/dpkg-deb/dpkg-deb.h
--- dpkg-1.10.9.orig/dpkg-deb/dpkg-deb.h	2002-05-20 07:56:02.000000000 +0200
+++ dpkg-1.10.9.chng/dpkg-deb/dpkg-deb.h	2002-12-27 20:44:44.000000000 +0100
@@ -30,6 +30,7 @@
 extern int debugflag, nocheckflag, oldformatflag;
 extern const struct cmdinfo *cipaction;
 extern dofunction *action;
+extern char advancedFormat;
 
 void extracthalf(const char *debar, const char *directory,
                  const char *taroption, int admininfo);
diff -Naur dpkg-1.10.9.orig/dpkg-deb/extract.c dpkg-1.10.9.chng/dpkg-deb/extract.c
--- dpkg-1.10.9.orig/dpkg-deb/extract.c	2002-05-06 18:18:15.000000000 +0200
+++ dpkg-1.10.9.chng/dpkg-deb/extract.c	2003-01-08 18:55:29.000000000 +0100
@@ -41,6 +41,7 @@
 #include <dpkg.h>
 #include <dpkg-deb.h>
 #include <myopt.h>
+#include <dar.h>
 
 static void movecontrolfiles(const char *thing) {
   char buf[200];
@@ -105,7 +106,7 @@
   int gzactualread;
 #endif
   
-  ar= fopen(debar,"r"); if (!ar) ohshite(_("failed to read archive `%.255s'"),debar);
+  ar= fopen(debar,"rb"); if (!ar) ohshite(_("failed to read archive `%.255s'"),debar);
   if (fstat(fileno(ar),&stab)) ohshite(_("failed to fstat archive"));
   if (!fgets(versionbuf,sizeof(versionbuf),ar)) readfail(ar,debar,_("version number"));
 
@@ -201,6 +202,22 @@
     errno=0; if (fread(ctrlarea,1,ctrllennum,ar) != ctrllennum)
       readfail(ar,debar,_("ctrlarea"));
 
+  } else if (!strcmp(versionbuf,"!<advDebAr>\n")) {
+    char *buf= (char *) malloc(255);
+    if (strcmp(taroption,"tv")) {
+      if(!(buf= getcwd(buf,255))) ohshite("cannot save current directory");
+      if(mkdir(directory,0777)) ohshite("failed to create directory %.225s/%.225s", buf, directory);
+      if(chdir(directory)) ohshite("cannot change to directory %.225s/%.225s", buf, directory);
+    }
+    if (!strcmp(taroption,"xp"))
+      darextr(ar,1,darf_EXTRACT);
+    else if (!strcmp(taroption,"xpv"))
+      darextr(ar,1,darf_EXTRACT | darf_VIEW);
+    else
+      darextr(ar,1,darf_VIEW);
+    if (strcmp(taroption,"tv")) 
+      if (chdir(buf)) ohshite("cannot change to directory %.225s", buf);
+    free(buf);
   } else {
     
     if (!strncmp(versionbuf,"!<arch>",7)) {
diff -Naur dpkg-1.10.9.orig/dpkg-deb/main.c dpkg-1.10.9.chng/dpkg-deb/main.c
--- dpkg-1.10.9.orig/dpkg-deb/main.c	2002-09-01 06:47:03.000000000 +0200
+++ dpkg-1.10.9.chng/dpkg-deb/main.c	2002-12-27 20:46:34.000000000 +0100
@@ -102,6 +102,7 @@
 const char* compression=NULL;
 const struct cmdinfo *cipaction=0;
 dofunction *action=0;
+char advancedFormat=0;
 
 static void helponly(const struct cmdinfo *cip, const char *value) NONRETURNING;
 static void helponly(const struct cmdinfo *cip, const char *value) {
@@ -145,6 +146,7 @@
   { "nocheck",       0,   0,  &nocheckflag,   0,  0,            1  },
   { "compression",  'z',  1,  0,   &compression,  0,            1  },
   { "showformat",    0,   1,  0, &showformat,     0                },
+  { "advformat",    'a',  0,  &advancedFormat,0,  0,            1  },
   { "help",         'h',  0,  0, 0,               helponly         },
   { "version",       0,   0,  0, 0,               versiononly      },
   { "licence",       0,   0,  0, 0,               showcopyright    }, /* UK spelling */
diff -Naur dpkg-1.10.9.orig/include/dar.h dpkg-1.10.9.chng/include/dar.h
--- dpkg-1.10.9.orig/include/dar.h	1970-01-01 01:00:00.000000000 +0100
+++ dpkg-1.10.9.chng/include/dar.h	2003-01-08 18:00:17.000000000 +0100
@@ -0,0 +1,61 @@
+/* debian archiver
+ */
+ 
+#include <sys/types.h>
+ 
+void *dar(FILE *ar, const char *dir, unsigned char mode, void *addr);
+void darextr(FILE *ar,unsigned char secNo, unsigned char flags);
+
+struct darHeader {
+
+  unsigned short attr;
+  time_t time;
+  unsigned char user, group;
+  unsigned int size;
+
+};
+
+struct darTree {
+
+  void *next;
+  void *child;
+  unsigned char type;
+  char name[255];
+
+};
+
+struct darExtr {
+
+  char *name;
+  struct darHeader dh;
+  char *link;
+  unsigned short dev;
+  void *next;
+  
+};
+
+#define dar_FILE	0
+#define dar_DIR		1
+#define dar_CHR		2
+#define dar_BLCK	3
+#define dar_FIFO	4
+#define dar_SYLI	5
+#define dar_SOCK	6
+
+#define dar_ax		8
+#define dar_aw		16
+#define dar_ar		32
+#define dar_gx		64
+#define dar_gw		128
+#define dar_gr		256
+#define dar_ox		512
+#define dar_ow		1024
+#define dar_or		2048
+
+#define dar_STBIT	4096
+#define dar_GRID	8192
+#define dar_USRID	16384
+
+#define darf_VIEW	1
+#define darf_EXTRACT	2
+
diff -Naur dpkg-1.10.9.orig/lib/dar.c dpkg-1.10.9.chng/lib/dar.c
--- dpkg-1.10.9.orig/lib/dar.c	1970-01-01 01:00:00.000000000 +0100
+++ dpkg-1.10.9.chng/lib/dar.c	2003-01-08 22:13:16.000000000 +0100
@@ -0,0 +1,420 @@
+/* Debian archiver
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <stdlib.h>
+#include <string.h>
+#include <bzlib.h>
+#include <time.h>
+#include <utime.h>
+
+#include <dar.h>
+#include <config.h>
+#include <dpkg.h>
+
+char **gulist;
+
+unsigned char guitem(char *it);
+unsigned char guitem(char *it) {
+
+  unsigned char cnt;
+  
+  for (cnt= 0;gulist[cnt] && cnt != 255;cnt ++)
+    if (!strcmp(gulist[cnt],it))
+      break;
+
+  if (gulist[cnt] && cnt == 255) ohshite("dar: group and user array exhaused.");
+
+  if (!gulist[cnt]) {
+    gulist= (char **) realloc(gulist,sizeof(char *)*(cnt+2));
+    gulist[cnt]= (char *) malloc(strlen(it)+1);
+    strcpy(gulist[cnt],it);
+    gulist[cnt+1]= 0;
+  }
+  
+  return cnt;
+
+}
+
+unsigned char ftpe(struct stat *st);
+unsigned char ftpe(struct stat *st) {
+
+  if ((st->st_mode & S_IFMT) == S_IFLNK) return dar_SYLI;
+  if (S_ISREG(st->st_mode)) return dar_FILE;
+  if (S_ISDIR(st->st_mode)) return dar_DIR;
+  if (S_ISCHR(st->st_mode)) return dar_CHR;
+  if (S_ISBLK(st->st_mode)) return dar_BLCK;
+  if (S_ISFIFO(st->st_mode)) return dar_FIFO;
+  if (S_ISSOCK(st->st_mode)) return dar_SOCK;
+
+  ohshite("dar: unable to find file type.");
+
+}
+
+void fwrstat(BZFILE *fd, struct stat *st, char *fname);
+void fwrstat(BZFILE *fd, struct stat *st, char *fname) {
+
+  struct darHeader dh;
+  struct passwd *usr;
+  struct group *grp;
+  int bzerr;
+
+  dh.attr= ftpe(st);
+
+  if (S_IXOTH & st->st_mode) dh.attr |= dar_ax;
+  if (S_IWOTH & st->st_mode) dh.attr |= dar_aw;
+  if (S_IROTH & st->st_mode) dh.attr |= dar_ar;
+  if (S_IXGRP & st->st_mode) dh.attr |= dar_gx;
+  if (S_IWGRP & st->st_mode) dh.attr |= dar_gw;
+  if (S_IRGRP & st->st_mode) dh.attr |= dar_gr;
+  if (S_IXUSR & st->st_mode) dh.attr |= dar_ox;
+  if (S_IWUSR & st->st_mode) dh.attr |= dar_ow;
+  if (S_IRUSR & st->st_mode) dh.attr |= dar_or;
+
+  if (S_ISVTX & st->st_mode) dh.attr |= dar_STBIT;
+  if (S_ISGID & st->st_mode) dh.attr |= dar_GRID;
+  if (S_ISUID & st->st_mode) dh.attr |= dar_USRID;
+
+  dh.time= st->st_mtime;
+
+  if (!(usr= getpwuid(st->st_uid))) ohshite("dar: error on getting file owner");
+  if (!(grp= getgrgid(st->st_gid))) ohshite("dar: error on getting file group");
+
+  dh.user= guitem(usr->pw_name);
+  dh.group= guitem(grp->gr_name);
+
+  dh.size= st->st_size;
+
+  BZ2_bzWrite(&bzerr, fd, &dh,sizeof(struct darHeader));
+  if (bzerr) ohshite("bz2 - error %i", bzerr);
+
+}
+
+void bzWrite(BZFILE *fd, void *buf, unsigned int len);
+void bzWrite(BZFILE *fd, void *buf, unsigned int len) {
+
+  int err;
+
+  BZ2_bzWrite(&err,fd,buf,len);
+  if (err)
+    ohshite("BZ2 compression error %i", err);
+
+}
+
+void bzRead(BZFILE *fd, void *buf, unsigned int len);
+void bzRead(BZFILE *fd, void *buf, unsigned int len) {
+
+  int err;
+
+  BZ2_bzRead(&err,fd,buf,len);
+  if (err && err != BZ_STREAM_END)
+    ohshite( "bzip decompression error %i",err);
+
+}
+
+void *dar(FILE *fd, const char *dir, unsigned char mode, void *addr) {
+
+  struct dirent *de;
+  struct stat   st;
+  struct passwd *usr;
+  struct group  *grp;
+  void *dtroot;
+  struct darTree *dyTree= NULL;
+  unsigned char i;
+  unsigned char modee= !mode ? 2 : mode;
+  DIR *dp;
+  char buf[1024];
+  unsigned int pos, br;
+  char *pt;
+  FILE *fl;
+  unsigned short linkLength;
+  int bzerr;
+  BZFILE *zf;
+
+  if (mode != 3)
+    dtroot= (void*) dyTree= (struct dartree*) malloc(sizeof(struct darTree));
+  else
+    dtroot= addr;
+
+  if (!mode) {
+    pos= ftell(fd);
+    fprintf(fd,"xxxx");
+    gulist= (char **) malloc(sizeof(char *));
+    *gulist= 0;
+    mode= 1;
+    dir= ".";
+    zf= BZ2_bzWriteOpen(&bzerr,fd,9,0,5);
+    if (bzerr) ohshite("error %i while bz2 initialization",bzerr);
+  } else
+    zf= (BZFILE *) fd;
+  
+  for (;mode <= modee && mode != 3;mode++)
+    if(!(dp= opendir(".")))
+      ohshite("dar cannot open directory");
+    else {
+      while((de= readdir(dp)))
+        if (strcmp(de->d_name,".") && strcmp(de->d_name,"..") && ((!addr && strcmp(de->d_name, "DEBIAN")) || addr) ) {
+	  if (lstat(de->d_name,&st)) ohshite("dar: stat error on file %.225s", de->d_name);
+	  switch (mode) {
+	    case 1: {
+	      if (!(usr= getpwuid(st.st_uid))) ohshite("dar: error on getting item owner %.225s", de->d_name);
+	      if (!(grp= getgrgid(st.st_gid))) ohshite("dar: error on getting item group %.225s", de->d_name);
+	      guitem(usr->pw_name);
+	      guitem(grp->gr_name);
+	    } break;
+	    case 2: {
+	      sprintf(buf,"%c%s",(char)strlen(de->d_name),de->d_name);
+	      bzWrite(zf,&buf,strlen(de->d_name)+1);
+	      fwrstat(zf,&st,de->d_name);
+	    } break;
+	  }
+          if (mode==2) 
+	    switch (ftpe(&st)) {
+	      case dar_BLCK:
+	      case dar_CHR: bzWrite(zf,&st.st_rdev,2); break;
+	      case dar_SYLI: if ((linkLength= readlink(de->d_name,(char *)&buf,sizeof(buf))) == -1) 
+	                      ohshite("dar: error analyzing symlink %.225s", de->d_name);
+			buf[linkLength]= 0;
+			bzWrite(zf,&linkLength,sizeof(short));
+			bzWrite(zf,&buf,linkLength);break;
+	    }
+	  if (mode==1) {
+	    dyTree= (struct darTree*) dyTree->next= malloc(sizeof(struct darTree));
+	    strcpy(dyTree->name,de->d_name);
+	    dyTree->type= ftpe(&st);
+	    dyTree->child= NULL;
+	  }
+	  if (ftpe(&st) == dar_DIR) {
+	    if (chdir(de->d_name)) ohshite("dar: unable to enter dir %.225s", de->d_name);
+	    if (mode==1)
+	      dyTree->child= dar((FILE *)zf,NULL,mode,(void*)1);
+	    else
+	      dar((FILE *)zf,NULL,mode,(void *)1);
+            if (chdir("..")) ohshite("dar: cannot go back to previous dir.");
+	    if (mode==2) {
+              sprintf(buf,"%c",0);
+	      bzWrite(zf,&buf,1);
+	    }
+	  } 
+        }
+      dyTree->next= NULL;
+	
+      if (mode != modee) {
+        for (i=0;gulist[i];i++);
+        bzWrite(zf,&i,sizeof(char));
+        while (i--) {
+          sprintf(buf, "%c%s", (char) strlen(gulist[i]), gulist[i]);
+	  bzWrite(zf,&buf,strlen(gulist[i])+sizeof(char));
+	}
+      }
+    closedir(dp);
+    }
+
+
+  if (!addr) {
+    sprintf(buf,"%c",0);
+    bzWrite(zf,&buf,sizeof(char));
+    }
+  if (!addr || mode == 3) {
+    dyTree= (struct darTree*) dtroot;
+    while (dyTree->next) {
+      dtroot= (void*) dyTree;
+      dyTree= (struct darTree*) dyTree->next;
+      free(dtroot);
+      pt= (char*) malloc(strlen(dir)+strlen(dyTree->name)+2);
+      sprintf(pt,"%s/%s",dir,dyTree->name);
+      if (dyTree->child)
+	dar(zf,pt,3,dyTree->child);
+      if (dyTree->type == dar_FILE) {
+        fl= fopen(pt,"rb");
+        do {
+	  br= fread(&buf,1,sizeof(buf),fl);
+	  bzWrite(zf,&buf,br);
+	} while(br==sizeof(buf));
+        fclose(fl);
+      }
+      free(pt);
+      fflush( stdout);
+    }
+  }
+  if (!addr) {
+   int t;
+   free(dyTree);
+   BZ2_bzWriteClose(&bzerr,zf,0,&t,&t);
+   br= ftell(fd)-pos-sizeof(unsigned int);
+   fseek(fd,pos,SEEK_SET);
+   fwrite(&br,1,sizeof(unsigned int),fd);
+   fseek(fd,pos+br+sizeof(unsigned int),SEEK_SET);
+   for (i=0;gulist[i];i++)
+     free(gulist[i]);
+   free(gulist);
+   if (bzerr)
+     ohshite("bz error %i",bzerr);
+   }
+  return dtroot;
+
+}
+
+void darextr(FILE *fd, unsigned char secNo, unsigned char flags) {
+
+  unsigned int id= 0;
+  unsigned char i= 0, j;
+  struct darHeader dh;
+  char *path;
+  unsigned short sv;
+  struct darExtr *de;
+  void *estart;
+  BZFILE *zf;
+  char type;
+  struct tm *tme;
+  char *buf;
+  FILE *f;
+  struct utimbuf ft;
+  
+  fseek(fd,13,SEEK_SET);
+  do {
+    fseek(fd,id,SEEK_CUR);
+    fread(&id,1,sizeof(unsigned int),fd);
+  } while (i++ < secNo);
+
+  zf= BZ2_bzReadOpen(&id,fd,NULL,NULL,NULL,NULL);
+  if (id) ohshite( "bz - err %i", id);
+  bzRead(zf,&i,1);
+  gulist= (char **) malloc((i+1)*sizeof(char*));
+  gulist[i]= NULL;
+  while (i--) {
+    bzRead(zf,&j,1);
+    gulist[i] = (char *) malloc(j+1);
+    bzRead(zf,gulist[i],j);
+    gulist[i][j]= 0;
+  }
+
+  de= (struct darExtr *) estart= malloc(sizeof(struct darExtr));
+  sv= 1;
+  
+  do {
+    bzRead(zf,&i,1);
+    de->name= (char *) malloc(i+1);
+    bzRead(zf,de->name,i);
+    de->name[i]= 0;
+    if (i) { 
+      bzRead(zf,&dh,sizeof(struct darHeader));
+      de->dh= dh;
+      switch ((unsigned short)(dh.attr << 13)) {
+        case dar_CHR << 13:
+        case dar_BLCK << 13: bzRead(zf,&de->dev,sizeof(short)); break;
+        case dar_SYLI << 13: bzRead(zf,&de->dev,sizeof(short));
+                            de->link= (char *) malloc(de->dev+1);
+	  		    de->link[de->dev]= 0;
+			    bzRead(zf,de->link,de->dev); 
+			    break;
+        case dar_DIR << 13: sv++;
+      }
+    } else sv--;
+  de= (struct darExtr *) de->next= malloc(sizeof(struct darExtr));
+  } while (sv);
+
+  de= (struct darExtr *) estart;
+  path= (char *) malloc(1);
+  strcpy(path, ".");
+  j= 1;
+  do {
+    i= strlen(de->name);
+    path= (char *) realloc(path, j+i+2);
+    sprintf(&path[j],"/%s",de->name);
+    switch ((unsigned short)(de->dh.attr << 13)) {
+      case dar_CHR << 13: type= 'c'; break;
+      case dar_BLCK << 13: type= 'b'; break;
+      case dar_SYLI << 13: type= 'l'; break;
+      case dar_DIR << 13: type= 'd'; break;
+      case dar_FILE << 13: type= '-'; break;
+      default : type= '?'; break;
+    }
+    tme= localtime(&de->dh.time);
+
+    if (flags & darf_VIEW)
+      printf( "%c%c%c%c%c%c%c%c%c%c %s/%s %10i %i-%.2i-%.2i %.2i:%.2i:%.2i %s%s%s\n",
+            type,
+	    de->dh.attr & dar_or ? 'r' : '-',
+	    de->dh.attr & dar_ow ? 'w' : '-',
+	    de->dh.attr & dar_ox ? 'x' : '-',
+	    de->dh.attr & dar_gr ? 'r' : '-',
+	    de->dh.attr & dar_gw ? 'w' : '-',
+	    de->dh.attr & dar_gx ? 'x' : '-',
+	    de->dh.attr & dar_ar ? 'r' : '-',
+	    de->dh.attr & dar_aw ? 'w' : '-',
+	    de->dh.attr & dar_ax ? 'x' : '-',
+	    gulist[de->dh.user],
+	    gulist[de->dh.group],
+	    de->dh.size,
+	    tme->tm_year + 1900, tme->tm_mon+1, tme->tm_wday+1, tme->tm_hour, tme->tm_min, tme->tm_sec,
+	    path,
+	    type == 'l' ? " -> " : "",
+	    type == 'l' ? de->link : "");
+
+    if (flags & darf_EXTRACT) {
+      switch((unsigned short)(de->dh.attr << 13)) {
+        case dar_FILE << 13: buf= malloc(1024);
+			     f= fopen(path,"wb");
+			     do {
+			       bzRead(zf,buf,(de->dh.size > 1024 ? 1024 : de->dh.size));
+			       de->dh.size -= fwrite(buf,1,(de->dh.size > 1024 ? 1024 : de->dh.size),f);
+			     } while (de->dh.size);
+			     free(buf);
+			     fclose(f);
+			     break;
+	case dar_DIR << 13: mkdir(path,NULL); break;
+	case dar_SYLI << 13: symlink(de->link,path);break;
+	case dar_BLCK << 13: mknod(path,S_IFBLK,de->dev); break;
+	case dar_CHR << 13: mknod(path,S_IFCHR,de->dev); break;
+	case dar_FIFO << 13: mknod(path,S_IFIFO,de->dev); break;
+	case dar_SOCK << 13: mknod(path,S_IFSOCK,de->dev); break;
+      }    
+      chmod(path,(de->dh.attr & dar_USRID ? S_ISUID : 0) |
+                 (de->dh.attr & dar_GRID ? S_ISGID : 0 ) |
+		 (de->dh.attr & dar_STBIT ? S_ISVTX : 0) |
+		 (de->dh.attr & dar_or ? S_IRUSR : 0 ) |
+		 (de->dh.attr & dar_ow ? S_IWUSR : 0 ) |
+		 (de->dh.attr & dar_ox ? S_IXUSR : 0 ) |
+		 (de->dh.attr & dar_gr ? S_IRGRP : 0 ) |
+		 (de->dh.attr & dar_gw ? S_IWGRP : 0 ) |
+		 (de->dh.attr & dar_gx ? S_IXGRP : 0 ) |
+		 (de->dh.attr & dar_ar ? S_IROTH : 0 ) |
+		 (de->dh.attr & dar_aw ? S_IWOTH : 0 ) |
+		 (de->dh.attr & dar_ax ? S_IXOTH : 0 ) );
+      ft.actime= ft.modtime= de->dh.time;
+      utime(path,&ft);
+    }
+
+
+    if (type == 'l') free(de->link);
+    
+    j += i+1;
+    if ((unsigned short)(de->dh.attr << 13) != dar_DIR << 13)
+      while (path[--j] != '/');
+    do {
+      estart= (void *) de;
+      free(de->name);
+      de= (struct darExtr *) de->next;
+      free(estart);
+      i= strlen(de->name);
+      while (!i && j && path[--j] != '/');
+    } while (!i && j);
+  } while (j);
+
+  free(de->next);
+  free(de);
+  free(path);
+  for(i=0;gulist[i];i++)
+    free(gulist[i]);
+  free(gulist);
+  BZ2_bzReadClose(&id,zf);
+  
+}
diff -Naur dpkg-1.10.9.orig/lib/Makefile.in dpkg-1.10.9.chng/lib/Makefile.in
--- dpkg-1.10.9.orig/lib/Makefile.in	2002-05-24 07:16:43.000000000 +0200
+++ dpkg-1.10.9.chng/lib/Makefile.in	2002-12-29 13:10:18.000000000 +0100
@@ -9,7 +9,7 @@
 SOURCES		= compat.c database.c dbmodify.c dump.c ehandle.c fields.c \
 		    lock.c mlib.c myopt.c nfmalloc.c parse.c parsehelp.c \
 		    showcright.c showpkg.c tarfn.c varbuf.c vercmp.c md5.c \
-		    utils.c startup.c
+		    utils.c startup.c dar.c
 
 OBJECTS		= $(patsubst %.c, %.o, $(SOURCES))
 GENFILES	= $(OBJECTS) libdpkg.a
diff -Naur dpkg-1.10.9.orig/Makefile.conf.in dpkg-1.10.9.chng/Makefile.conf.in
--- dpkg-1.10.9.orig/Makefile.conf.in	2002-07-14 22:15:06.000000000 +0200
+++ dpkg-1.10.9.chng/Makefile.conf.in	2003-01-04 21:02:49.000000000 +0100
@@ -61,7 +61,7 @@
 CPPFLAGS		= @CPPFLAGS@
 LD			= @LD@
 LDFLAGS			= @LDFLAGS@ -L../lib -L../optlib
-LIBS			= @LIBS@ -ldpkg -lopt $(ZLIB_LIBS)
+LIBS			= @LIBS@ -ldpkg -lopt $(ZLIB_LIBS) -lbz2
 
 RANLIB			= @RANLIB@
 

Reply to: