diff --git a/README.md b/README.md index 495791d..8d31cf2 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ int main(int argc, char** argv) if(minitar_read_entry(&mp, &entry) == 0) { printf("%s\n", entry.metadata.path); } else break; - } while(true); + } while(1); minitar_close(&mp); } ``` diff --git a/examples/list.c b/examples/list.c new file mode 100644 index 0000000..c8f85aa --- /dev/null +++ b/examples/list.c @@ -0,0 +1,24 @@ +#include +#include + +int main(int argc, char** argv) +{ + if (argc == 1) + { + fprintf(stderr, "Usage: %s [file]\n", argv[0]); + return 1; + } + struct minitar mp; + if (minitar_open(argv[1], &mp) != 0) + { + perror(argv[1]); + return 1; + } + struct minitar_entry entry; + do { + if (minitar_read_entry(&mp, &entry) == 0) { printf("%s\n", entry.metadata.path); } + else + break; + } while (1); + minitar_close(&mp); +} \ No newline at end of file diff --git a/examples/untar.c b/examples/untar.c new file mode 100644 index 0000000..97bc363 --- /dev/null +++ b/examples/untar.c @@ -0,0 +1,87 @@ +/* Simple untar example for POSIX systems using minitar. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static int untar_file(const struct minitar_entry* entry, const void* buf) +{ + int fd = open(entry->metadata.path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0644); + if (fd < 0) return 1; + + if (write(fd, buf, entry->metadata.size) < 0) return 1; + + if (fchmod(fd, entry->metadata.mode) < 0) return 1; + + return close(fd); +} + +static int untar_directory(const struct minitar_entry* entry) +{ + if (mkdir(entry->metadata.path, entry->metadata.mode) < 0) return 1; + + return 0; +} + +int main(int argc, char** argv) +{ + if (argc == 1) + { + fprintf(stderr, "Usage: %s [file]\n", argv[0]); + return 1; + } + struct minitar mp; + if (minitar_open(argv[1], &mp) != 0) + { + perror(argv[1]); + return 1; + } + struct minitar_entry entry; + do { + if (minitar_read_entry(&mp, &entry) == 0) + { + if (entry.metadata.type == MTAR_DIRECTORY) + { + int status = untar_directory(&entry); + if (status != 0) + { + fprintf(stderr, "Failed to create directory %s: %s\n", entry.metadata.path, strerror(errno)); + break; + } + + printf("mkdir %s\n", entry.metadata.path); + } + else if (entry.metadata.type == MTAR_REGULAR) + { + char* ptr = (char*)malloc(entry.metadata.size); + if (!ptr) + { + perror("malloc"); + break; + } + + minitar_read_contents(&mp, &entry, ptr, entry.metadata.size); + + int status = untar_file(&entry, ptr); + + free(ptr); + + if (status != 0) + { + fprintf(stderr, "Failed to extract file %s: %s\n", entry.metadata.path, strerror(errno)); + break; + } + + printf("untar %s\n", entry.metadata.path); + } + } + else + break; + } while (1); + minitar_close(&mp); +} \ No newline at end of file