untar in progress
This commit is contained in:
		
							
								
								
									
										39
									
								
								bin/untar.c
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								bin/untar.c
									
									
									
									
									
								
							@ -6,6 +6,8 @@
 | 
				
			|||||||
int main (int argc, char* argv[])
 | 
					int main (int argc, char* argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hio_t* hio;
 | 
						hio_t* hio;
 | 
				
			||||||
 | 
						hio_tar_t* untar;
 | 
				
			||||||
 | 
						FILE* fp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (argc != 2)
 | 
						if (argc != 2)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -20,8 +22,43 @@ int main (int argc, char* argv[])
 | 
				
			|||||||
		return -1;
 | 
							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);
 | 
						hio_close (hio);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										36
									
								
								lib/err.c
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								lib/err.c
									
									
									
									
									
								
							@ -88,11 +88,47 @@ const hio_ooch_t* hio_geterrstr (hio_t* hio)
 | 
				
			|||||||
	return hio_errnum_to_errstr(hio->errnum);
 | 
						return hio_errnum_to_errstr(hio->errnum);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
const hio_ooch_t* hio_geterrmsg (hio_t* hio)
 | 
					const hio_ooch_t* hio_geterrmsg (hio_t* hio)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (hio->errmsg.len <= 0) return hio_errnum_to_errstr(hio->errnum);
 | 
						if (hio->errmsg.len <= 0) return hio_errnum_to_errstr(hio->errnum);
 | 
				
			||||||
	return hio->errmsg.buf;
 | 
						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)
 | 
					void hio_geterrinf (hio_t* hio, hio_errinf_t* info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -92,6 +92,7 @@ struct hio_tar_t
 | 
				
			|||||||
	struct
 | 
						struct
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		hio_uintmax_t filesize;
 | 
							hio_uintmax_t filesize;
 | 
				
			||||||
 | 
							hio_uintmax_t filemode;
 | 
				
			||||||
		void* fp;
 | 
							void* fp;
 | 
				
			||||||
	} hi;
 | 
						} hi;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										17
									
								
								lib/hio.h
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								lib/hio.h
									
									
									
									
									
								
							@ -698,6 +698,11 @@ struct hio_t
 | 
				
			|||||||
			hio_bch_t bch[HIO_ERRMSG_CAPA];
 | 
								hio_bch_t bch[HIO_ERRMSG_CAPA];
 | 
				
			||||||
			hio_uch_t uch[HIO_ERRMSG_CAPA];
 | 
								hio_uch_t uch[HIO_ERRMSG_CAPA];
 | 
				
			||||||
		} tmpbuf;
 | 
							} 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_ooch_t buf[HIO_ERRMSG_CAPA];
 | 
				
			||||||
		hio_oow_t len;
 | 
							hio_oow_t len;
 | 
				
			||||||
	} errmsg;
 | 
						} errmsg;
 | 
				
			||||||
@ -878,10 +883,20 @@ HIO_EXPORT const hio_ooch_t* hio_geterrstr (
 | 
				
			|||||||
	hio_t* hio
 | 
						hio_t* hio
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HIO_EXPORT const hio_ooch_t* hio_geterrmsg (
 | 
					HIO_EXPORT const hio_uch_t* hio_geterrumsg (
 | 
				
			||||||
	hio_t* hio
 | 
						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_EXPORT void hio_geterrinf (
 | 
				
			||||||
	hio_t*        hio,
 | 
						hio_t*        hio,
 | 
				
			||||||
	hio_errinf_t* info
 | 
						hio_errinf_t* info
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										91
									
								
								lib/tar.c
									
									
									
									
									
								
							
							
						
						
									
										91
									
								
								lib/tar.c
									
									
									
									
									
								
							@ -188,9 +188,6 @@ int hio_extract_tar (hio_t* hio, const hio_bch_t* archive_file)
 | 
				
			|||||||
	return n;
 | 
						return n;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
hio_tar_t* hio_tar_open (hio_t* hio, hio_oow_t xtnsize)
 | 
					hio_tar_t* hio_tar_open (hio_t* hio, hio_oow_t xtnsize)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hio_tar_t* tar;
 | 
						hio_tar_t* tar;
 | 
				
			||||||
@ -223,6 +220,12 @@ int hio_tar_init (hio_tar_t* tar)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void hio_tar_fini (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)
 | 
					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);
 | 
						HIO_ASSERT (tar->hio, tar->blk.len == HIO_TAR_BLKSIZE);
 | 
				
			||||||
	hdr = (hio_tar_hdr_t*)tar->blk.buf;
 | 
						hdr = (hio_tar_hdr_t*)tar->blk.buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					printf("process_header...\n");
 | 
				
			||||||
	/* all-zero byte block ends the archive */
 | 
						/* all-zero byte block ends the archive */
 | 
				
			||||||
	if (HIO_MEMCMP(hdr, _end_block, HIO_TAR_BLKSIZE) == 0) 
 | 
						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... */
 | 
							/* 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);
 | 
							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;
 | 
								/* just in case */
 | 
				
			||||||
			tar->state = HIO_TAR_STATE_FILE;
 | 
								fclose (tar->hi.fp);
 | 
				
			||||||
 | 
								tar->hi.fp = HIO_NULL;
 | 
				
			||||||
			/* 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;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		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;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -288,6 +333,7 @@ static int process_content (hio_tar_t* tar)
 | 
				
			|||||||
	HIO_ASSERT (tar->hio, tar->hi.filesize > 0);
 | 
						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;
 | 
						chunksize = tar->hi.filesize < tar->blk.len? tar->hi.filesize: tar->blk.len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* TODO: error check */
 | 
					/* 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)
 | 
						while (len > 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		hio_oow_t cplen;
 | 
							hio_oow_t cplen;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user