summaryrefslogtreecommitdiff
path: root/package/cfgfs/src/tool.c
diff options
context:
space:
mode:
Diffstat (limited to 'package/cfgfs/src/tool.c')
-rw-r--r--package/cfgfs/src/tool.c302
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));
+}