diff --git a/bin/untar.c b/bin/untar.c index f6f0f9d..5b184cf 100644 --- a/bin/untar.c +++ b/bin/untar.c @@ -58,7 +58,7 @@ int main (int argc, char* argv[]) hio_tar_feed (untar, HIO_NULL, 0); /* indicate the end of input */ fclose (fp); - hio_tar_close (hio); + hio_tar_close (untar); hio_close (hio); return 0; } diff --git a/lib/hio-tar.h b/lib/hio-tar.h index 103c26a..60fbae8 100644 --- a/lib/hio-tar.h +++ b/lib/hio-tar.h @@ -2,6 +2,7 @@ #define _HIO_TAR_H_ #include +#include /* tar Header Block, from POSIX 1003.1-1990. */ @@ -93,6 +94,7 @@ struct hio_tar_t { hio_uintmax_t filesize; hio_uintmax_t filemode; + hio_becs_t filename; void* fp; } hi; }; @@ -102,9 +104,6 @@ typedef struct hio_tar_t hio_tar_t; extern "C" { #endif -HIO_EXPORT int hio_extract_tar (hio_t* hio, const hio_bch_t* archive_file); - - HIO_EXPORT hio_tar_t* hio_tar_open ( hio_t* hio, hio_oow_t xtnsize @@ -115,7 +114,8 @@ HIO_EXPORT void hio_tar_close ( ); HIO_EXPORT int hio_tar_init ( - hio_tar_t* tar + hio_tar_t* tar, + hio_t* hio ); HIO_EXPORT void hio_tar_fini ( diff --git a/lib/tar.c b/lib/tar.c index f0a5c7e..3cb0c54 100644 --- a/lib/tar.c +++ b/lib/tar.c @@ -56,6 +56,7 @@ static int create_dir (hio_bch_t *pathname, int mode) return n; } +#if 0 static FILE* create_file (char *pathname, int mode) { FILE *fp; @@ -113,36 +114,36 @@ static int extract_tar (hio_t* hio, FILE* fp) switch (hdr->typeflag) { case HIO_TAR_LNKTYPE: - printf(" Ignoring hardlink %s\n", hdr->name); + printf(" Ignoring hardlink %s\n", filename); break; case HIO_TAR_SYMTYPE: - printf(" Ignoring symlink %s\n", hdr->name); + printf(" Ignoring symlink %s\n", filename); break; case HIO_TAR_CHRTYPE: - printf(" Ignoring character device %s\n", hdr->name); + printf(" Ignoring character device %s\n", filename); break; case HIO_TAR_BLKTYPE: - printf(" Ignoring block device %s\n", hdr->name); + printf(" Ignoring block device %s\n", filename); break; case HIO_TAR_DIRTYPE: - printf(" Extracting dir %s\n", hdr->name); + printf(" Extracting dir %s\n", filename); if (filesize != 0) { /* something wrong */ } - create_dir(hdr->name, mode); + create_dir(filename, mode); break; case HIO_TAR_FIFOTYPE: - printf(" Ignoring FIFO %s\n", hdr->name); + printf(" Ignoring FIFO %s\n", filename); break; case HIO_TAR_CONTTYPE: - printf(" Ignoring cont %s\n", hdr->name); + printf(" Ignoring cont %s\n", filename); break; default: - printf(" Extracting file %s\n", hdr->name); - f = create_file(hdr->name, mode); + printf(" Extracting file %s\n", filename); + f = create_file(filename, mode); while (filesize > 0) { @@ -187,6 +188,7 @@ int hio_extract_tar (hio_t* hio, const hio_bch_t* archive_file) fclose (fp); return n; } +#endif hio_tar_t* hio_tar_open (hio_t* hio, hio_oow_t xtnsize) { @@ -195,7 +197,7 @@ hio_tar_t* hio_tar_open (hio_t* hio, hio_oow_t xtnsize) tar = (hio_tar_t*)hio_callocmem(hio, HIO_SIZEOF(*tar) + xtnsize); if (tar) { - if (hio_tar_init(tar) <= -1) + if (hio_tar_init(tar, hio) <= -1) { hio_freemem (hio, tar); tar = HIO_NULL; @@ -211,15 +213,18 @@ void hio_tar_close (hio_tar_t* tar) hio_freemem (tar->hio, tar); } -int hio_tar_init (hio_tar_t* tar) +int hio_tar_init (hio_tar_t* tar, hio_t* hio) { + tar->hio = hio; tar->state = HIO_TAR_STATE_START; tar->blk.len = 0; + hio_becs_init (&tar->hi.filename, tar->hio, 0); /* won't fail with the capacity of 0 */ return 0; } void hio_tar_fini (hio_tar_t* tar) { + hio_becs_fini (&tar->hi.filename); if (tar->hi.fp) { /* clean up */ @@ -241,19 +246,18 @@ printf("process_header...\n"); if (HIO_MEMCMP(hdr, _end_block, HIO_TAR_BLKSIZE) == 0) { /* TODO: is it correct? */ +printf ("end of input\n"); tar->state = HIO_TAR_STATE_END; } else { int is_sober; const hio_bch_t* endptr; - - /* if (hdr->typeflag) TODO: do different jobs depending on types... */ + const hio_bch_t* filename; tar->hi.filesize = hio_bchars_to_uintmax(hdr->size, HIO_COUNTOF(hdr->size), HIO_BCHARS_TO_UINTMAX_MAKE_OPTION(0,0,0,8), &endptr, &is_sober); tar->hi.filemode = hio_bchars_to_uintmax(hdr->mode, HIO_COUNTOF(hdr->mode), HIO_BCHARS_TO_UINTMAX_MAKE_OPTION(0,0,0,8), &endptr, &is_sober); - if (tar->hi.fp) { /* just in case */ @@ -261,29 +265,31 @@ printf("process_header...\n"); tar->hi.fp = HIO_NULL; } -printf ("file size = %u [%s] [%s]\n", (unsigned int)tar->hi.filesize, hdr->name, hdr->prefix); -/*{ - int i; - for (i = 0; i < 512; i++) printf ("%05d %c\n", i, tar->blk.buf[i]); - printf ("\n"); -}*/ + hio_becs_clear (&tar->hi.filename); + if (hio_becs_cat(&tar->hi.filename, hdr->prefix) == (hio_oow_t)-1 || + hio_becs_cat(&tar->hi.filename, hdr->name) == (hio_oow_t)-1) + { + return -1; + } + filename = HIO_BECS_PTR(&tar->hi.filename); +printf ("file size = %u [%s]\n", (unsigned int)tar->hi.filesize, filename); switch (hdr->typeflag) { case HIO_TAR_LNKTYPE: - printf(" Ignoring hardlink %s\n", hdr->name); + printf(" Ignoring hardlink %s\n", filename); break; case HIO_TAR_SYMTYPE: - printf(" Ignoring symlink %s\n", hdr->name); + printf(" Ignoring symlink %s\n", filename); break; case HIO_TAR_CHRTYPE: - printf(" Ignoring character device %s\n", hdr->name); + printf(" Ignoring character device %s\n", filename); break; case HIO_TAR_BLKTYPE: - printf(" Ignoring block device %s\n", hdr->name); + printf(" Ignoring block device %s\n", filename); break; case HIO_TAR_DIRTYPE: - printf(" Extracting dir %s\n", hdr->name); + printf(" Extracting dir %s\n", filename); #if 0 if (tar->hio.filesize != 0) { @@ -293,25 +299,22 @@ printf ("file size = %u [%s] [%s]\n", (unsigned int)tar->hi.filesize, hdr->name, create_dir(hdr->name, tar->hi.filemode); break; case HIO_TAR_FIFOTYPE: - printf(" Ignoring FIFO %s\n", hdr->name); + printf(" Ignoring FIFO %s\n", filename); break; case HIO_TAR_CONTTYPE: - printf(" Ignoring cont %s\n", hdr->name); + printf(" Ignoring cont %s\n", filename); break; default: /* HIO_TAR_REGTYPE */ { FILE* fp; - printf(" Extracting file %s\n", hdr->name); + printf(" Extracting file %s\n", filename); - /* open here? */ - /*TODO: hdr->prefix + hdr->name */ - fp = fopen(hdr->name, "w"); + fp = fopen(filename, "wb+"); if (!fp) { - printf ("unable to openf ile...\n"); hio_seterrwithsyserr (tar->hio, 0, errno); return -1; } @@ -324,7 +327,7 @@ printf ("file size = %u [%s] [%s]\n", (unsigned int)tar->hi.filesize, hdr->name, } } - tar->state == HIO_TAR_STATE_START; + tar->state = HIO_TAR_STATE_START; } done: @@ -339,8 +342,6 @@ static int process_content (hio_tar_t* tar) HIO_ASSERT (tar->hio, tar->hi.filesize > 0); HIO_ASSERT (tar->hio, tar->hi.fp != HIO_NULL); - -//printf("process_content...\n"); chunksize = tar->hi.filesize < tar->blk.len? tar->hi.filesize: tar->blk.len; /* TODO: error check */ @@ -361,6 +362,7 @@ static int process_content (hio_tar_t* tar) int hio_tar_feed (hio_tar_t* tar, const void* ptr, hio_oow_t len) { +printf ("feed len = %d\n", len); if (!ptr) { /* EOF indicator */ @@ -391,6 +393,7 @@ int hio_tar_feed (hio_tar_t* tar, const void* ptr, hio_oow_t len) { case HIO_TAR_STATE_START: if (process_header(tar) <= -1) return -1; + if (tar->state == HIO_TAR_STATE_END) printf ("remaining data len %d\n", len); break; case HIO_TAR_STATE_FILE: