diff options
Diffstat (limited to 'package/cfgfs/src/tool.c')
-rw-r--r-- | package/cfgfs/src/tool.c | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/package/cfgfs/src/tool.c b/package/cfgfs/src/tool.c new file mode 100644 index 000000000..3daf141cd --- /dev/null +++ b/package/cfgfs/src/tool.c @@ -0,0 +1,302 @@ +/* $MirOS: contrib/hosted/fwcf/tool.c,v 1.7 2007/03/09 22:35:13 tg Exp $ */ + +/*- + * Copyright (c) 2006, 2007 + * Thorsten Glaser <tg@mirbsd.de> + * + * Provided that these terms and disclaimer and all copyright notices + * are retained or reproduced in an accompanying document, permission + * is granted to deal in this work without restriction, including un- + * limited rights to use, publicly perform, distribute, sell, modify, + * merge, give away, or sublicence. + * + * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to + * the utmost extent permitted by applicable law, neither express nor + * implied; without malicious intent or gross negligence. In no event + * may a licensor, author or contributor be held liable for indirect, + * direct, other damage, loss, or other issues arising in any way out + * of dealing in the work, even if advised of the possibility of such + * damage or existence of a defect, except proven that it results out + * of said person's immediate fault when using the work as intended. + */ + +#include <sys/param.h> +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "defs.h" +#include "compress.h" +#include "minilzop.h" +#include "pack.h" + +__RCSID("$MirOS: contrib/hosted/fwcf/tool.c,v 1.7 2007/03/09 22:35:13 tg Exp $"); + +static __dead void usage(void); +static int mkfwcf(int, const char *, int); +static int unfwcf(int, const char *); +#ifndef SMALL +static int refwcf(int, int, int); +#endif +static int fsopen(const char *, int, int); + +int +main(int argc, char *argv[]) +{ + int c; + int mode = 0, doempty = 0; + int ifd, ofd; +#ifdef SMALL + int calg = -1; +#else + int calg = 0; + const char *infile = NULL, *outfile = NULL; +#endif + const char *dfile = NULL; + const char *file_root = NULL; + fwcf_compressor *cl; + +#ifdef SMALL + while ((c = getopt(argc, argv, "D:delMUZ")) != -1) +#else + while ((c = getopt(argc, argv, "C:cD:dei:lMo:RUZ")) != -1) +#endif + switch (c) { +#ifndef SMALL + case 'C': + if (!(calg = strtonum(optarg, 1, 255, NULL)) + && !(calg = compressor_getbyname(optarg))) + usage(); + break; + case 'c': + calg = -1; + break; +#endif + case 'D': + if (doempty) + usage(); + dfile = optarg; + break; + case 'd': + mode = (mode == 5 || mode == 6) ? 6 : 3; + break; + case 'e': + if (dfile != NULL) + usage(); + doempty = 1; + break; +#ifndef SMALL + case 'i': + infile = optarg; + break; +#endif + case 'l': + return (list_compressors()); + case 'M': + mode = 1; + break; +#ifndef SMALL + case 'o': + outfile = optarg; + break; + case 'R': + mode = 4; + break; +#endif + case 'U': + mode = 2; + break; + case 'Z': + mode = (mode == 3) ? 6 : 5; + break; + default: + usage(); + } + argc -= optind; + argv += optind; + + switch (mode) { + case 1: + if (argc != ((dfile == NULL) ? (1 - doempty) : 0)) + usage(); + break; + case 2: + if (argc != ((dfile == NULL) ? 1 : 0)) + usage(); + break; +#ifndef SMALL + case 3: + case 4: + if (argc || doempty || (dfile != NULL)) + usage(); + break; +#endif + case 5: + case 6: + if ((dfile != NULL) || doempty +#ifndef SMALL + || infile || outfile +#endif + ) + usage(); + break; + default: + usage(); + } + if (argc) + file_root = *argv; + + if (mode == 5 || mode == 6) { + ifd = fsopen(argc-- > 0 ? *argv++ : NULL, + O_RDONLY, STDIN_FILENO); + ofd = fsopen(argc-- > 0 ? *argv++ : NULL, + O_WRONLY | O_CREAT | O_TRUNC, STDOUT_FILENO); + if (argc > 0) + usage(); +#ifndef SMALL + if (calg == 0) + /* force host tool to compress even without -c */ + calg = -1; +#endif + goto get_calg; + } + +#ifdef SMALL + ifd = STDIN_FILENO; + ofd = STDOUT_FILENO; +#else + ifd = fsopen(infile, O_RDONLY, STDIN_FILENO); + ofd = fsopen(outfile, O_WRONLY | O_CREAT | O_TRUNC, STDOUT_FILENO); +#endif + + if (mode == 2 && dfile != NULL) { + char *data; + size_t sz; + int dfd; + + if ((data = fwcf_unpack(ifd, &sz)) == NULL) + return (1); + if ((dfd = fsopen(dfile, O_WRONLY | O_CREAT | O_TRUNC, + STDOUT_FILENO)) < 0) + err(1, "open %s", dfile); + write_aszdata(dfd, data, sz); + close(dfd); + free(data); + return (0); + } + + if ((mode == 2) || (mode == 3)) + return (unfwcf(ifd, (mode == 3) ? NULL : file_root)); + + get_calg: + if (calg == -1) { + if ((cl = compress_enumerate()) != NULL) + for (calg = 1; calg < 257; ++calg) + if (cl[calg & 0xFF].name != NULL) + break; + + if ((cl == NULL) || (calg == 257)) + errx(1, "no compression algorithms found"); + calg &= 0xFF; + } + + if (mode == 5 || mode == 6) + return (minilzop(ifd, ofd, calg, (mode == 6))); + +#ifndef SMALL + if (mode == 4) + return (refwcf(ifd, ofd, calg)); +#endif + + if (dfile != NULL) { + char *udata, *data; + size_t sz, isz; + int dfd; + + if ((dfd = fsopen(dfile, O_RDONLY, STDIN_FILENO)) < 0) + err(1, "open %s", dfile); + read_aszdata(dfd, &udata, &isz); + close(dfd); + data = fwcf_pack(udata, isz, calg, &sz); + isz = write(ofd, data, sz); + free(data); + return (isz == sz ? 0 : 1); + } + + return (mkfwcf(ofd, doempty ? NULL : file_root, calg)); +} + +static __dead void +usage(void) +{ + extern const char *__progname; + + fprintf(stderr, "Usage:" +#ifdef SMALL + " %s -M { -D <file> | -e | <directory> }" + "\n %s -U { -D <file> | <directory> }" + "\n %s -Z[d] [<infile> [<outfile>]]" + "\n %s -l\n", __progname, __progname, __progname, __progname); +#else + " %s -M [-c | -C <compressor>] [-o <file>]" + "\n { -D <file> | -e | <directory> }" + "\n %s [-i <file>] -U { -D <file> | <directory> }" + "\n %s [-i <file>] -d" + "\n %s -R [-c | -C <compressor>] [-i <infile>] [-o <outfile>]" + "\n %s -Z[d] [-c | -C <compressor>] [<infile> [<outfile>]]" + "\n %s -l\n", + __progname, __progname, __progname, __progname, __progname, + __progname); +#endif + exit(1); +} + +static int +mkfwcf(int fd, const char *dir, int algo) +{ + size_t sz; + char *data; + + data = fwcf_packm(dir, algo, &sz); + return ((size_t)write(fd, data, sz) == sz ? 0 : 1); +} + +static int +unfwcf(int fd, const char *dir) +{ + char *udata; + + if ((udata = fwcf_unpack(fd, NULL))) { +#ifndef SMALL + if (dir == NULL) + ft_dump(udata); + else +#endif + ft_creatm(udata, dir); + } + return (udata != NULL ? 0 : 1); +} + +#ifndef SMALL +static int +refwcf(int ifd, int ofd, int algo) +{ + char *udata, *data; + size_t sz, isz; + + if ((udata = fwcf_unpack(ifd, &isz)) == NULL) + return (1); + data = fwcf_pack(udata, isz, algo, &sz); + return ((size_t)write(ofd, data, sz) == sz ? 0 : 1); +} +#endif + +static int +fsopen(const char *fn, int mode, int altfd) +{ + return (((fn == NULL) || (*fn == '\0') || + ((fn[0] == '-') && (fn[1] == '\0'))) ? altfd : + open(fn, mode, 0666)); +} |