binutils: allow static linking
[openadk.git] / package / cfgfs / src / tool.c
bloba9e475c4acd4ef64a84dba45618b45b8e72578ab
1 /* $MirOS: contrib/hosted/fwcf/tool.c,v 1.7 2007/03/09 22:35:13 tg Exp $ */
3 /*-
4 * Copyright (c) 2006, 2007
5 * Thorsten Glaser <tg@mirbsd.de>
7 * Provided that these terms and disclaimer and all copyright notices
8 * are retained or reproduced in an accompanying document, permission
9 * is granted to deal in this work without restriction, including un-
10 * limited rights to use, publicly perform, distribute, sell, modify,
11 * merge, give away, or sublicence.
13 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
14 * the utmost extent permitted by applicable law, neither express nor
15 * implied; without malicious intent or gross negligence. In no event
16 * may a licensor, author or contributor be held liable for indirect,
17 * direct, other damage, loss, or other issues arising in any way out
18 * of dealing in the work, even if advised of the possibility of such
19 * damage or existence of a defect, except proven that it results out
20 * of said person's immediate fault when using the work as intended.
23 #include <sys/param.h>
24 #include <err.h>
25 #include <fcntl.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
30 #include "defs.h"
31 #include "compress.h"
32 #include "minilzop.h"
33 #include "pack.h"
35 static __dead void usage(void);
36 static int mkfwcf(int, const char *, int);
37 static int unfwcf(int, const char *);
38 #ifndef SMALL
39 static int refwcf(int, int, int);
40 #endif
41 static int fsopen(const char *, int, int);
43 int
44 main(int argc, char *argv[])
46 int c;
47 int mode = 0, doempty = 0;
48 int ifd, ofd;
49 #ifdef SMALL
50 int calg = -1;
51 #else
52 int calg = 0;
53 const char *infile = NULL, *outfile = NULL;
54 #endif
55 const char *dfile = NULL;
56 const char *file_root = NULL;
57 fwcf_compressor *cl;
59 #ifdef SMALL
60 while ((c = getopt(argc, argv, "D:delMUZ")) != -1)
61 #else
62 while ((c = getopt(argc, argv, "C:cD:dei:lMo:RUZ")) != -1)
63 #endif
64 switch (c) {
65 #ifndef SMALL
66 case 'C':
67 if (!(calg = strtonum(optarg, 1, 255, NULL))
68 && !(calg = compressor_getbyname(optarg)))
69 usage();
70 break;
71 case 'c':
72 calg = -1;
73 break;
74 #endif
75 case 'D':
76 if (doempty)
77 usage();
78 dfile = optarg;
79 break;
80 case 'd':
81 mode = (mode == 5 || mode == 6) ? 6 : 3;
82 break;
83 case 'e':
84 if (dfile != NULL)
85 usage();
86 doempty = 1;
87 break;
88 #ifndef SMALL
89 case 'i':
90 infile = optarg;
91 break;
92 #endif
93 case 'l':
94 return (list_compressors());
95 case 'M':
96 mode = 1;
97 break;
98 #ifndef SMALL
99 case 'o':
100 outfile = optarg;
101 break;
102 case 'R':
103 mode = 4;
104 break;
105 #endif
106 case 'U':
107 mode = 2;
108 break;
109 case 'Z':
110 mode = (mode == 3) ? 6 : 5;
111 break;
112 default:
113 usage();
115 argc -= optind;
116 argv += optind;
118 switch (mode) {
119 case 1:
120 if (argc != ((dfile == NULL) ? (1 - doempty) : 0))
121 usage();
122 break;
123 case 2:
124 if (argc != ((dfile == NULL) ? 1 : 0))
125 usage();
126 break;
127 #ifndef SMALL
128 case 3:
129 case 4:
130 if (argc || doempty || (dfile != NULL))
131 usage();
132 break;
133 #endif
134 case 5:
135 case 6:
136 if ((dfile != NULL) || doempty
137 #ifndef SMALL
138 || infile || outfile
139 #endif
141 usage();
142 break;
143 default:
144 usage();
146 if (argc)
147 file_root = *argv;
149 if (mode == 5 || mode == 6) {
150 ifd = fsopen(argc-- > 0 ? *argv++ : NULL,
151 O_RDONLY, STDIN_FILENO);
152 ofd = fsopen(argc-- > 0 ? *argv++ : NULL,
153 O_WRONLY | O_CREAT | O_TRUNC, STDOUT_FILENO);
154 if (argc > 0)
155 usage();
156 #ifndef SMALL
157 if (calg == 0)
158 /* force host tool to compress even without -c */
159 calg = -1;
160 #endif
161 goto get_calg;
164 #ifdef SMALL
165 ifd = STDIN_FILENO;
166 ofd = STDOUT_FILENO;
167 #else
168 ifd = fsopen(infile, O_RDONLY, STDIN_FILENO);
169 ofd = fsopen(outfile, O_WRONLY | O_CREAT | O_TRUNC, STDOUT_FILENO);
170 #endif
172 if (mode == 2 && dfile != NULL) {
173 char *data;
174 size_t sz;
175 int dfd;
177 if ((data = fwcf_unpack(ifd, &sz)) == NULL)
178 return (1);
179 if ((dfd = fsopen(dfile, O_WRONLY | O_CREAT | O_TRUNC,
180 STDOUT_FILENO)) < 0)
181 err(1, "open %s", dfile);
182 write_aszdata(dfd, data, sz);
183 close(dfd);
184 free(data);
185 return (0);
188 if ((mode == 2) || (mode == 3))
189 return (unfwcf(ifd, (mode == 3) ? NULL : file_root));
191 get_calg:
192 if (calg == -1) {
193 if ((cl = compress_enumerate()) != NULL)
194 for (calg = 1; calg < 257; ++calg)
195 if (cl[calg & 0xFF].name != NULL)
196 break;
198 if ((cl == NULL) || (calg == 257))
199 errx(1, "no compression algorithms found");
200 calg &= 0xFF;
203 if (mode == 5 || mode == 6)
204 return (minilzop(ifd, ofd, calg, (mode == 6)));
206 #ifndef SMALL
207 if (mode == 4)
208 return (refwcf(ifd, ofd, calg));
209 #endif
211 if (dfile != NULL) {
212 char *udata, *data;
213 size_t sz, isz;
214 int dfd;
216 if ((dfd = fsopen(dfile, O_RDONLY, STDIN_FILENO)) < 0)
217 err(1, "open %s", dfile);
218 read_aszdata(dfd, &udata, &isz);
219 close(dfd);
220 data = fwcf_pack(udata, isz, calg, &sz);
221 isz = write(ofd, data, sz);
222 free(data);
223 return (isz == sz ? 0 : 1);
226 return (mkfwcf(ofd, doempty ? NULL : file_root, calg));
229 static __dead void
230 usage(void)
232 extern const char *__progname;
234 fprintf(stderr, "Usage:"
235 #ifdef SMALL
236 " %s -M { -D <file> | -e | <directory> }"
237 "\n %s -U { -D <file> | <directory> }"
238 "\n %s -Z[d] [<infile> [<outfile>]]"
239 "\n %s -l\n", __progname, __progname, __progname, __progname);
240 #else
241 " %s -M [-c | -C <compressor>] [-o <file>]"
242 "\n { -D <file> | -e | <directory> }"
243 "\n %s [-i <file>] -U { -D <file> | <directory> }"
244 "\n %s [-i <file>] -d"
245 "\n %s -R [-c | -C <compressor>] [-i <infile>] [-o <outfile>]"
246 "\n %s -Z[d] [-c | -C <compressor>] [<infile> [<outfile>]]"
247 "\n %s -l\n",
248 __progname, __progname, __progname, __progname, __progname,
249 __progname);
250 #endif
251 exit(1);
254 static int
255 mkfwcf(int fd, const char *dir, int algo)
257 size_t sz;
258 char *data;
260 data = fwcf_packm(dir, algo, &sz);
261 return ((size_t)write(fd, data, sz) == sz ? 0 : 1);
264 static int
265 unfwcf(int fd, const char *dir)
267 char *udata;
269 if ((udata = fwcf_unpack(fd, NULL))) {
270 #ifndef SMALL
271 if (dir == NULL)
272 ft_dump(udata);
273 else
274 #endif
275 ft_creatm(udata, dir);
277 return (udata != NULL ? 0 : 1);
280 #ifndef SMALL
281 static int
282 refwcf(int ifd, int ofd, int algo)
284 char *udata, *data;
285 size_t sz, isz;
287 if ((udata = fwcf_unpack(ifd, &isz)) == NULL)
288 return (1);
289 data = fwcf_pack(udata, isz, algo, &sz);
290 return ((size_t)write(ofd, data, sz) == sz ? 0 : 1);
292 #endif
294 static int
295 fsopen(const char *fn, int mode, int altfd)
297 return (((fn == NULL) || (*fn == '\0') ||
298 ((fn[0] == '-') && (fn[1] == '\0'))) ? altfd :
299 open(fn, mode, 0666));