diff --git a/bin/untar.c b/bin/untar.c index 8ad9caf..f6f0f9d 100644 --- a/bin/untar.c +++ b/bin/untar.c @@ -6,6 +6,8 @@ int main (int argc, char* argv[]) { hio_t* hio; + hio_tar_t* untar; + FILE* fp; if (argc != 2) { @@ -20,8 +22,43 @@ int main (int argc, char* argv[]) return -1; } - hio_extract_tar(hio, argv[1]); + untar = hio_tar_open(hio, 0); + if (!untar) + { + fprintf (stderr, "Error: unable to open untar\n"); + hio_close (hio); + return -1; + } + fp = fopen(argv[1], "r"); + if (!fp) + { + fprintf (stderr, "Error: unable to open file %s\n", argv[1]); + hio_tar_close (hio); + hio_close (hio); + return -1; + } + + //hio_extract_tar(hio, argv[1]); + while (!feof(fp) && !ferror(fp)) + { + int n; + char buf[99]; /* TODO: use a different buffer size???*/ + n = fread(buf, 1, sizeof(buf), fp); + if (n > 0) + { + if (hio_tar_feed(untar, buf, n) <= -1) + { + fprintf (stderr, "Error: untar error - %s\n", hio_geterrbmsg(hio)); + break; + } + } + } + + hio_tar_feed (untar, HIO_NULL, 0); /* indicate the end of input */ + + fclose (fp); + hio_tar_close (hio); hio_close (hio); return 0; } diff --git a/lib/err.c b/lib/err.c index 52d4028..158ccdd 100644 --- a/lib/err.c +++ b/lib/err.c @@ -88,11 +88,47 @@ const hio_ooch_t* hio_geterrstr (hio_t* hio) return hio_errnum_to_errstr(hio->errnum); } +#if 0 const hio_ooch_t* hio_geterrmsg (hio_t* hio) { if (hio->errmsg.len <= 0) return hio_errnum_to_errstr(hio->errnum); return hio->errmsg.buf; } +#endif + +const hio_bch_t* hio_geterrbmsg (hio_t* hio) +{ +#if defined(HIO_OOCH_IS_BCH) + return (hio->errmsg.len <= 0)? hio_errnum_to_errstr(hio->errnum): hio->errmsg.buf; +#else + const hio_ooch_t* msg; + hio_oow_t wcslen, mbslen; + + msg = (hio->errmsg.len <= 0)? hio_errnum_to_errstr(hio->errnum): hio->errmsg.buf; + + mbslen = HIO_COUNTOF(hio->errmsg.xerrmsg); + hio_conv_ucstr_to_bcstr_with_cmgr (msg, &wcslen, hio->errmsg.xerrmsg, &mbslen, hio_getcmgr(hio)); + + return hio->errmsg.xerrmsg; +#endif +} + +const hio_uch_t* hio_geterrumsg (hio_t* hio) +{ +#if defined(HIO_OOCH_IS_BCH) + const hio_ooch_t* msg; + hio_oow_t wcslen, mbslen; + + msg = (hio->errmsg.len <= 0)? hio_errnum_to_errstrerrstr(hio->errnum): hio->errmsg.buf; + + wcslen = HIO_COUNTOF(hio->errmsg.xerrmsg); + hio_conv_bcstr_to_ucstr_with_cmgr (msg, &mbslen, hio->errmsg.xerrmsg, &wcslen, hio_getcmgr(hio), 1); + + return hio->errmsg.xerrmsg; +#else + return (hio->errmsg.len == '\0')? hio_errnum_to_errstr(hio->errnum): hio->errmsg.buf; +#endif +} void hio_geterrinf (hio_t* hio, hio_errinf_t* info) { diff --git a/lib/hio-tar.h b/lib/hio-tar.h index cd7a311..103c26a 100644 --- a/lib/hio-tar.h +++ b/lib/hio-tar.h @@ -92,6 +92,7 @@ struct hio_tar_t struct { hio_uintmax_t filesize; + hio_uintmax_t filemode; void* fp; } hi; }; diff --git a/lib/hio.h b/lib/hio.h index 9b73328..6df1bfd 100644 --- a/lib/hio.h +++ b/lib/hio.h @@ -698,6 +698,11 @@ struct hio_t hio_bch_t bch[HIO_ERRMSG_CAPA]; hio_uch_t uch[HIO_ERRMSG_CAPA]; } tmpbuf; + #if defined(HIO_OOCH_IS_BCH) + hio_uch_t xerrmsg[HIO_ERRMSG_CAPA]; + #else + hio_bch_t xerrmsg[HIO_ERRMSG_CAPA * 2]; + #endif hio_ooch_t buf[HIO_ERRMSG_CAPA]; hio_oow_t len; } errmsg; @@ -878,10 +883,20 @@ HIO_EXPORT const hio_ooch_t* hio_geterrstr ( hio_t* hio ); -HIO_EXPORT const hio_ooch_t* hio_geterrmsg ( +HIO_EXPORT const hio_uch_t* hio_geterrumsg ( hio_t* hio ); +HIO_EXPORT const hio_bch_t* hio_geterrbmsg ( + hio_t* hio +); + +#if defined(HIO_OOCH_IS_UCH) +# define hio_geterrmsg hio_geterrumsg +#else +# define hio_geterrmsg hio_geterrbmsg +#endif + HIO_EXPORT void hio_geterrinf ( hio_t* hio, hio_errinf_t* info diff --git a/lib/tar.c b/lib/tar.c index 34897e1..8d42053 100644 --- a/lib/tar.c +++ b/lib/tar.c @@ -188,9 +188,6 @@ int hio_extract_tar (hio_t* hio, const hio_bch_t* archive_file) return n; } - - - hio_tar_t* hio_tar_open (hio_t* hio, hio_oow_t xtnsize) { hio_tar_t* tar; @@ -223,6 +220,12 @@ int hio_tar_init (hio_tar_t* tar) void hio_tar_fini (hio_tar_t* tar) { + if (tar->hi.fp) + { + /* clean up */ + fclose (tar->hi.fp); + tar->hi.fp = HIO_NULL; + } } static int process_header (hio_tar_t* tar) @@ -233,6 +236,7 @@ static int process_header (hio_tar_t* tar) HIO_ASSERT (tar->hio, tar->blk.len == HIO_TAR_BLKSIZE); hdr = (hio_tar_hdr_t*)tar->blk.buf; +printf("process_header...\n"); /* all-zero byte block ends the archive */ if (HIO_MEMCMP(hdr, _end_block, HIO_TAR_BLKSIZE) == 0) { @@ -247,36 +251,77 @@ static int process_header (hio_tar_t* tar) /* if (hdr->typeflag) TODO: do different jobs depending on types... */ 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); - //mode = hio_bchars_to_uintmax(hdr->mode, HIO_COUNTOF(hdr->mode), 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.filesize > 0) + if (tar->hi.fp) { - FILE* fp; - tar->state = HIO_TAR_STATE_FILE; - - /* open here? */ -/*TODO: hdr->prefix + hdr->name */ - fp = fopen(hdr->name, "w"); - if (!fp) - { - hio_seterrwithsyserr (tar->hio, 0, errno); - return -1; - } - - tar->hi.fp = fp; + /* just in case */ + fclose (tar->hi.fp); + tar->hi.fp = HIO_NULL; } - if (tar->hi.filesize <= 0) +printf ("file size = %u [%s]\n", (unsigned int)tar->hi.filesize, hdr->name); + switch (hdr->typeflag) { - if (tar->hi.fp) + case HIO_TAR_LNKTYPE: + printf(" Ignoring hardlink %s\n", hdr->name); + break; + case HIO_TAR_SYMTYPE: + printf(" Ignoring symlink %s\n", hdr->name); + break; + case HIO_TAR_CHRTYPE: + printf(" Ignoring character device %s\n", hdr->name); + break; + case HIO_TAR_BLKTYPE: + printf(" Ignoring block device %s\n", hdr->name); + break; + case HIO_TAR_DIRTYPE: + printf(" Extracting dir %s\n", hdr->name); + #if 0 + if (tar->hio.filesize != 0) + { + /* something wrong */ + } + #endif + create_dir(hdr->name, tar->hi.filemode); + break; + case HIO_TAR_FIFOTYPE: + printf(" Ignoring FIFO %s\n", hdr->name); + break; + + case HIO_TAR_CONTTYPE: + printf(" Ignoring cont %s\n", hdr->name); + break; + + default: /* HIO_TAR_REGTYPE */ { - fclose (tar->hi.fp); - tar->hi.fp = HIO_NULL; + + FILE* fp; + + printf(" Extracting file %s\n", hdr->name); + + /* open here? */ + /*TODO: hdr->prefix + hdr->name */ + fp = fopen(hdr->name, "w"); + if (!fp) + { + hio_seterrwithsyserr (tar->hio, 0, errno); + return -1; + } + + fchmod (fileno(fp), tar->hi.filemode); + + tar->hi.fp = fp; + tar->state = HIO_TAR_STATE_FILE; + goto done; } } + + tar->state == HIO_TAR_STATE_START; } +done: return 0; } @@ -288,6 +333,7 @@ static int process_content (hio_tar_t* tar) HIO_ASSERT (tar->hio, tar->hi.filesize > 0); +printf("process_content...\n"); chunksize = tar->hi.filesize < tar->blk.len? tar->hi.filesize: tar->blk.len; /* TODO: error check */ @@ -320,6 +366,7 @@ int hio_tar_feed (hio_tar_t* tar, const void* ptr, hio_oow_t len) } } +printf ("feeding %d\n", len); while (len > 0) { hio_oow_t cplen;