/* $MirOS: contrib/hosted/fwcf/tool.c,v 1.7 2007/03/09 22:35:13 tg Exp $ */ /*- * Copyright (c) 2006, 2007 * Thorsten Glaser * * 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 #include #include #include #include #include #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 | -e | }" "\n %s -U { -D | }" "\n %s -Z[d] [ []]" "\n %s -l\n", __progname, __progname, __progname, __progname); #else " %s -M [-c | -C ] [-o ]" "\n { -D | -e | }" "\n %s [-i ] -U { -D | }" "\n %s [-i ] -d" "\n %s -R [-c | -C ] [-i ] [-o ]" "\n %s -Z[d] [-c | -C ] [ []]" "\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)); }