From b4753b60b9ba7535ac9e590c5c1e0de8d81250c0 Mon Sep 17 00:00:00 2001 From: Dave Vasilevsky Date: Thu, 14 Oct 2010 02:14:58 -0400 Subject: [PATCH] Woops, forgot to add pixz.c, how embarassing! --- .gitignore | 5 +-- pixz.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 pixz.c diff --git a/.gitignore b/.gitignore index 8feb964..2402b11 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,4 @@ -list -write -read -pread +pixz *.o diff --git a/pixz.c b/pixz.c new file mode 100644 index 0000000..b002847 --- /dev/null +++ b/pixz.c @@ -0,0 +1,112 @@ +#include "pixz.h" +#include + +typedef enum { + OP_WRITE, + OP_READ, + OP_EXTRACT, + OP_LIST +} pixz_op_t; + +static bool strsuf(char *big, char *small); +static char *subsuf(char *in, char *suf1, char *suf2); +static char *auto_output(pixz_op_t op, char *in); + + +int main(int argc, char **argv) { + uint32_t level = LZMA_PRESET_DEFAULT; + bool tar = true; + pixz_op_t op = OP_WRITE; + char *ipath = NULL, *opath = NULL; + + int ch; + while ((ch = getopt(argc, argv, "dxli:o:tv0123456789")) != -1) { + switch (ch) { + case 'd': op = OP_READ; break; + case 'x': op = OP_EXTRACT; break; + case 'l': op = OP_LIST; break; + case 'i': ipath = optarg; break; + case 'o': opath = optarg; break; + case 't': tar = false; break; + default: + if (optopt >= '0' && optopt <= '9') { + level = optopt - '0'; + } else { + die("Unknown option"); + } + } + } + argc -= optind; + argv += optind; + + gInFile = stdin; + gOutFile = stdout; + bool iremove = false; + if (op != OP_EXTRACT && argc >= 1) { + if (argc > 2 || (op == OP_LIST && argc == 2)) + die("Too many arguments"); + if (ipath) + die("Multiple input files specified"); + ipath = argv[0]; + + if (argc == 2) { + if (opath) + die("Multiple output files specified"); + opath = argv[1]; + } else if (op != OP_LIST) { + iremove = true; + opath = auto_output(op, argv[0]); + } + } + + if (ipath && !(gInFile = fopen(ipath, "r"))) + die("Can't open input file"); + if (opath && !(gOutFile = fopen(opath, "w"))) + die("Can't open output file"); + + switch (op) { + case OP_WRITE: pixz_write(tar, level); break; + case OP_READ: pixz_read(tar, 0, NULL); break; + case OP_EXTRACT: pixz_read(tar, argc, argv); break; + case OP_LIST: pixz_list(tar); + } + + if (iremove) + unlink(ipath); + + return 0; +} + +#define SUF(_op, _s1, _s2) ({ \ + if (op == OP_##_op) { \ + char *r = subsuf(in, _s1, _s2); \ + if (r) \ + return r; \ + } \ +}) + +static char *auto_output(pixz_op_t op, char *in) { + SUF(READ, ".tar.xz", ".tar"); + SUF(READ, ".tpxz", ".tar"); + SUF(READ, ".xz", ""); + SUF(WRITE, ".tar", ".tpxz"); + SUF(WRITE, "", ".xz"); + die("Unknown suffix"); + return NULL; +} + +static bool strsuf(char *big, char *small) { + size_t bl = strlen(big), sl = strlen(small); + return strcmp(big + bl - sl, small) == 0; +} + +static char *subsuf(char *in, char *suf1, char *suf2) { + if (!strsuf(in, suf1)) + return NULL; + + size_t li = strlen(in), l1 = strlen(suf1), l2 = strlen(suf2); + char *r = malloc(li + l2 - l1 + 1); + memcpy(r, in, li - l1); + strcpy(r + li - l1, suf2); + return r; +}