static void error OF((const char *msg));
+static unsigned long total_read;
+
/* #define TAR_GZ 1 */
typedef struct Readable {
enum { FMT_U=1, FMT_Z=2, FMT_GZ=3, FMT_BZ2=4 };
/* #define xFILE FILE* */
-static int xU_Open4Read(struct Readable* self, char const* filename) { return NULL==(self->f=fopen(filename,"rb")); }
+static int xU_Open4Read(struct Readable* self, char const* filename) { total_read=0; return NULL==(self->f=fopen(filename,"rb")); }
static int xU_Close(struct Readable* self) { return fclose((FILE*)self->f); }
static unsigned xU_Read(struct Readable* self, void* buf, unsigned len) {
unsigned got=fread(buf,1,len,(FILE*)self->f);
+ total_read+=got;
return got>0 ? got : ferror((FILE*)self->f) ? 0U-1 : 0;
}
static char const* xU_Error(struct Readable* self, int *errnum_ret) { return (*errnum_ret=ferror((FILE*)self->f))?"I/O error":"OK"; }
#if HAVE_ZLIB
#include "zlib.h"
/* #define xFILE gzFile */
-static int xGZ_Open4Read(struct Readable* self, char const* filename) { return NULL==(self->f=gzopen(filename,"rb")); }
+static int xGZ_Open4Read(struct Readable* self, char const* filename) { total_read=0; return NULL==(self->f=gzopen(filename,"rb")); }
static int xGZ_Close(struct Readable* self) { return gzclose((gzFile)self->f); }
-static unsigned xGZ_Read(struct Readable* self, void* buf, unsigned len) { return gzread((gzFile)self->f,buf,len); }
+static unsigned xGZ_Read(struct Readable* self, void* buf, unsigned len) { unsigned l=gzread((gzFile)self->f,buf,len); total_read=((z_streamp)self->f)->total_in; return l; }
static char const* xGZ_Error(struct Readable* self, int *errnum_ret) { return gzerror((gzFile)self->f, errnum_ret); }
#endif
/* Tar file list or extract */
-static int tar (Readable* rin,int action,int arg,int argc,char **argv, char const* TGZfile, int verbose, void (*step)(void)) {
+static int tar (Readable* rin,int action,int arg,int argc,char **argv, char const* TGZfile, int verbose, void (*step)(void *,int), void *data) {
union tar_buffer buffer;
int is_tar_ok=0;
int len;
FILE *outfile = NULL;
char fname[BLOCKSIZE];
time_t tartime;
+ unsigned long last_read;
#if 0
while (0<(len=rin->xRead(rin, &buffer, BLOCKSIZE))) {
exit(0);
#endif
+ last_read = 0;
if (action == TGZ_LIST)
printf(" day time size file\n"
" ---------- -------- --------- -------------------------------------\n");
len = rin->xRead(rin, &buffer, BLOCKSIZE);
if (len+1 == 0)
error (rin->xError(rin, &err));
+ if (step) { step(data,total_read - last_read); last_read = total_read; }
if (!is_tar_ok && !(is_tar_ok=is_tar(buffer.buffer, len))) {
fprintf(stderr, "%s: compressed file not tared: %s\n", prog, TGZfile);
if (action == TGZ_EXTRACT) {
outfile = NULL;
utime(fname,&settime);
#endif
- if (step) step();
}
}
}
case 3: fprintf(stderr, "%s: not a tar file: %s\n", prog, TGZfile); return 1;
case 4: fprintf(stderr, "%s: cannot open tar file: %s\n", prog, TGZfile); return 1;
}
- return tar(&r, action, arg, argc, argv, TGZfile, 1, 0);
+ return tar(&r, action, arg, argc, argv, TGZfile, 1, 0, 0);
default: error("Unknown option!");
}
return 0;
#endif
void
-tarextract(char *TGZfile,char *dest,int verbose, void (*step)(void))
+tarextract(char *TGZfile,char *dest,int verbose, void (*step)(void *), void *data)
{
Readable r;
if (xOpen4Read(&r,TGZfile) == 0)
chdir( dest );
argv[0] = "fgadmin";
argv[1] = TGZfile;
- tar(&r, TGZ_EXTRACT, arg, argc, argv, TGZfile, 0, step);
+ tar(&r, TGZ_EXTRACT, arg, argc, argv, TGZfile, 0, step, data);
}
}