file_read(user_data, buffer, *size) file = user_data *size = fread(buffer, 1, *size, file) extract(file_name, outer_member, inner_action) FILE *file = fopen(file_name, "rb") outer_gzip = gzip_init(&file_read, file) outer_ustar = ustar_init(outer_gzip) ustar_seek(outer_ustar, outer_member) inner_gzip = gzip_init(&ustar_read, outer_ustar) inner_ustar = ustar_init(inner_gzip) inner_action(inner_ustar) read_control(inner_ustar) unsigned char buffer[512] size ustar_seek(inner_ustar, "control") while ((ret = ustar_read(inner_ustar, buffer, &size)) == OK) fwrite(buffer, 1 size, stdout) if ret == ERROR return list_members(inner_ustar) ustar_member member while ((ret = ustar_list(inner_ustar, &member)) == OK) printf("%s", member.name) if ret == ERROR return main() if -I extract(argv[1], "control.tar.gz", &read_control) else if -c extract(argv[1], "data.tar.gz", &list_members) --- struct gzip * gzip_init(int (*read)(void *, char *, size_t *), void *user_data) int gzip_read(struct gzip *gzip, void *record) --- struct ustar * ustar_init(struct gzip *gzip) int ustar_list(struct ustar *ustar, ustar_member *member) int ustar_seek(ustruct star *ustar, const char *member) int ustar_read(struct ustar *ustar, char *buffer, size_t *size)