dwarf: don't emit a dummy .debug_loc section
[nasm.git] / rdoff / rdlar.c
blob0922d9ec933b3b8d3443a19e9fe16157cc6540e7
1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2009 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
9 * conditions are met:
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ----------------------------------------------------------------------- */
35 * rdlar.c - new librarian/archiver for RDOFF2.
38 #include "compiler.h"
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <ctype.h>
43 #include <stdarg.h>
44 #include <errno.h>
45 #include <time.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
49 #include "rdlar.h"
51 #define PROGRAM_VERSION "0.1"
53 /** Constants **/
54 const char commands[] = "adnrtx";
55 const char modifiers[] = "cflouvV";
57 /** Global variables **/
58 char *progname = "rdlar";
59 char **_argv = NULL;
60 struct {
61 bool createok;
62 bool usefname;
63 bool align;
64 bool odate;
65 bool fresh;
66 int verbose;
67 } options = {
68 0, 0, 0, 0, 0, 0};
70 #define _ENDIANNESS 0 /* 0 for little, 1 for big */
73 * Convert int32_t to little endian (if we were compiled on big-endian machine)
75 static void int32_ttolocal(int32_t *l)
77 #if _ENDIANNESS
78 uint8_t t;
79 uint8_t *p = (uint8_t *)l;
81 t = p[0];
82 p[0] = p[3];
83 p[3] = t;
84 t = p[1];
85 p[1] = p[2];
86 p[2] = p[1];
87 #endif
91 * Print version information
93 void show_version(void)
95 puts("New RDOFF2 librarian/archiver, version " PROGRAM_VERSION);
99 * Print usage instructions
101 void usage(void)
103 printf("Usage: %s [-]{%s}[%s] libfile [module-name] [files]\n",
104 progname, commands, modifiers);
105 puts(" commands:\n"
106 " a - add module(s) to the library\n"
107 " d - delete module(s) from the library\n"
108 " n - create the library\n"
109 " r - replace module(s)\n"
110 " t - display contents of library\n"
111 " x - extract module(s)\n"
112 " command specific modifiers:\n"
113 " o - preserve original dates\n"
114 " u - only replace modules that are newer than library contents\n"
115 " generic modifiers:\n"
116 " c - do not warn if the library had to be created\n"
117 " f - use file name as a module name\n"
118 " v - be verbose\n"
119 " V - display version information");
123 * Print an error message and exit
125 void error_exit(int errcode, bool useperror, const char *fmt, ...)
127 va_list ap;
129 fprintf(stderr, "%s: ", progname);
130 va_start(ap, fmt);
131 vfprintf(stderr, fmt, ap);
132 va_end(ap);
133 putc('\n', stderr);
134 if (useperror)
135 perror(progname);
136 exit(errcode);
140 * Fill in and write a header
142 void put_header(struct rdlm_hdr *hdr, FILE * libfp, char *modname)
144 int n = 0;
146 hdr->hdrsize = sizeof(*hdr);
147 if (modname)
148 hdr->hdrsize += (n = strlen(modname) + 1);
149 if (libfp == NULL)
150 return;
151 if (fwrite(hdr, 1, sizeof(*hdr), libfp) != sizeof(*hdr) ||
152 (modname && (fwrite(modname, 1, n, libfp) != n)))
153 error_exit(3, true, "could not write header");
157 * Copy n bytes from one file to another and return last character read.
159 char copybytes(FILE * fp, FILE * fp2, int n)
161 int i, t = 0;
163 for (i = 0; i < n; i++) {
164 t = fgetc(fp);
165 if (t == EOF)
166 error_exit(1, false, "premature end of file in '%s'",
167 _argv[2]);
168 if (fp2)
169 if (fputc(t, fp2) == EOF)
170 error_exit(1, false, "write error");
172 return (char)t;
176 * Copy uint32_t from one file to another.
177 * Return local presentation of int32_t.
179 int32_t copyint32_t(FILE * fp, FILE * fp2)
181 int32_t l;
182 int i, t;
183 uint8_t *p = (uint8_t *)&l;
185 for (i = 0; i < 4; i++) {
186 t = fgetc(fp);
187 if (t == EOF)
188 error_exit(1, false, "premature end of file in '%s'",
189 _argv[2]);
190 if (fp2)
191 if (fputc(t, fp2) == EOF)
192 error_exit(1, false, "write error");
193 *p++ = t;
195 int32_ttolocal(&l);
196 return l;
200 * Create a new library
202 int create_library(char *libname)
204 FILE *libfp;
205 struct rdlm_hdr hdr;
207 hdr.magic = RDLAMAG;
208 hdr.hdrsize = 0;
209 hdr.date = time(NULL);
210 hdr.owner = getuid();
211 hdr.group = getgid();
212 hdr.mode = umask(022);
213 hdr.size = 0;
215 libfp = fopen(libname, "wb");
216 if (!libfp)
217 error_exit(1, true, "could not open '%s'\n", libname);
219 /* Write library header */
220 put_header(&hdr, libfp, NULL);
222 fclose(libfp);
223 return true;
227 * Add a module to the library
229 int add_module(FILE * libfp, const char *fname, char *modname)
231 FILE *modfp;
232 struct rdlm_hdr hdr = { RDLMMAG, 0, 0, 0, 0, 0, 0 };
233 struct stat finfo;
234 int i;
236 if (options.verbose)
237 fprintf(stderr, "adding module %s\n", modname);
239 /* Initialize some fields in the module header */
240 if (stat(fname, &finfo) < 0)
241 error_exit(1, true, "could not stat '%s'", fname);
242 hdr.date = finfo.st_mtime;
243 hdr.owner = finfo.st_uid;
244 hdr.group = finfo.st_gid;
245 hdr.size = finfo.st_size;
247 modfp = fopen(fname, "rb");
248 if (!modfp)
249 error_exit(1, true, "could not open '%s'", fname);
251 /* Write module header */
252 put_header(&hdr, libfp, modname);
254 /* Put the module itself */
255 while (!feof(modfp)) {
256 i = fgetc(modfp);
257 if (i == EOF)
258 break;
259 if (fputc(i, libfp) == EOF)
260 error_exit(1, false, "write error");
263 fclose(modfp);
264 return true;
268 * Main
270 int main(int argc, char **argv)
272 FILE *libfp, *tmpfp, *modfp = NULL;
273 struct stat finfo;
274 struct rdlm_hdr hdr;
275 char buf[MAXMODNAMELEN], *p = NULL;
276 char c;
277 int i;
279 progname = argv[0];
280 _argv = argv;
282 if (argc < 2) {
283 usage();
284 exit(1);
287 rdoff_init();
289 /* Check whether some modifiers were specified */
290 for (i = 1; i < strlen(argv[1]); i++) {
291 switch (c = argv[1][i]) {
292 case 'c':
293 options.createok = true;
294 break;
295 case 'f':
296 options.usefname = true;
297 break;
298 case 'l':
299 options.align = true;
300 break;
301 case 'o':
302 options.odate = true;
303 break;
304 case 'u':
305 options.fresh = true;
306 break;
307 case 'v':
308 options.verbose++;
309 break;
310 case 'V':
311 show_version();
312 exit(0);
313 default:
314 if (strchr(commands, c) == NULL)
315 error_exit(2, false, "invalid command or modifier '%c'",
320 if (argc < 3)
321 error_exit(2, false, "missing library name");
323 /* Process the command */
324 if (argv[1][0] == '-')
325 argv[1]++;
326 switch (c = argv[1][0]) {
327 case 'a': /* add a module */
328 if (argc < 4 || (!options.usefname && argc != 5))
329 error_exit(2, false, "invalid number of arguments");
331 /* Check if a library already exists. If not - create it */
332 if (access(argv[2], F_OK) < 0) {
333 if (!options.createok)
334 fprintf(stderr, "creating library %s\n", argv[2]);
335 create_library(argv[2]);
338 libfp = fopen(argv[2], "ab");
339 if (!libfp)
340 error_exit(1, true, "could not open '%s'", argv[2]);
342 if (!options.usefname)
343 add_module(libfp, argv[4], argv[3]);
344 else
345 for (i = 3; i < argc; i++)
346 add_module(libfp, argv[i], argv[i]);
348 fclose(libfp);
349 break;
351 case 'n': /* create library */
352 create_library(argv[2]);
353 break;
355 case 'x': /* extract module(s) */
356 if (!options.usefname)
357 argc--;
358 if (argc < 4)
359 error_exit(2, false, "required parameter missing");
360 p = options.usefname ? argv[3] : argv[4];
361 case 't': /* list library contents */
362 libfp = fopen(argv[2], "rb");
363 if (!libfp)
364 error_exit(1, true, "could not open '%s'\n", argv[2]);
366 /* Read library header */
367 if (fread(&hdr, 1, sizeof(hdr), libfp) != sizeof(hdr) ||
368 hdr.magic != RDLAMAG)
369 error_exit(1, false, "invalid library format");
371 /* Walk through the library looking for requested module */
372 while (!feof(libfp)) {
373 /* Read module header */
374 i = fread(&hdr, 1, sizeof(hdr), libfp);
375 if (feof(libfp))
376 break;
377 if (i != sizeof(hdr) || hdr.magic != RDLMMAG)
378 error_exit(1, false, "invalid module header");
379 /* Read module name */
380 i = hdr.hdrsize - sizeof(hdr);
381 if (i > sizeof(buf) || fread(buf, 1, i, libfp) != i)
382 error_exit(1, false, "invalid module name");
383 if (c == 'x') {
384 /* Check against desired name */
385 if (!strcmp(buf, argv[3])) {
386 if (options.verbose)
387 fprintf(stderr,
388 "extracting module %s to file %s\n", buf,
390 modfp = fopen(p, "wb");
391 if (!modfp)
392 error_exit(1, true, "could not open '%s'", p);
394 } else {
395 printf("%-40s ", buf);
396 if (options.verbose) {
397 printf("%ld bytes", hdr.size);
399 putchar('\n');
402 copybytes(libfp, modfp, hdr.size);
403 if (modfp)
404 break;
407 fclose(libfp);
408 if (modfp)
409 fclose(modfp);
410 else if (c == 'x')
411 error_exit(1, false, "module '%s' not found in '%s'",
412 argv[3], argv[2]);
413 break;
415 case 'r': /* replace module(s) */
416 argc--;
417 if (stat(argv[4], &finfo) < 0)
418 error_exit(1, true, "could not stat '%s'", argv[4]);
419 case 'd': /* delete module(s) */
420 if (argc < 4)
421 error_exit(2, false, "required parameter missing");
423 libfp = fopen(argv[2], "rb");
424 if (!libfp)
425 error_exit(1, true, "could not open '%s'", argv[2]);
427 /* Copy the library into a temporary file */
428 tmpfp = tmpfile();
429 if (!tmpfp)
430 error_exit(1, true, "could not open temporary file");
432 stat(argv[2], &finfo);
433 copybytes(libfp, tmpfp, finfo.st_size);
434 rewind(tmpfp);
435 freopen(argv[2], "wb", libfp);
437 /* Read library header and write it to a new file */
438 if (fread(&hdr, 1, sizeof(hdr), tmpfp) != sizeof(hdr) ||
439 hdr.magic != RDLAMAG)
440 error_exit(1, false, "invalid library format");
441 put_header(&hdr, libfp, NULL);
443 /* Walk through the library looking for requested module */
444 while (!feof(tmpfp)) {
445 /* Read module header */
446 if (fread(&hdr, 1, sizeof(hdr), tmpfp) != sizeof(hdr) ||
447 hdr.magic != RDLMMAG)
448 error_exit(1, false, "invalid module header");
449 /* Read module name */
450 i = hdr.hdrsize - sizeof(hdr);
451 if (i > sizeof(buf) || fread(buf, 1, i, tmpfp) != i)
452 error_exit(1, false, "invalid module name");
453 /* Check against desired name */
454 if (!strcmp(buf, argv[3]) &&
455 (c == 'd' || !options.odate
456 || finfo.st_mtime <= hdr.date)) {
457 if (options.verbose)
458 fprintf(stderr, "deleting module %s\n", buf);
459 fseek(tmpfp, hdr.size, SEEK_CUR);
460 break;
461 } else {
462 put_header(&hdr, libfp, buf);
463 copybytes(tmpfp, libfp, hdr.size);
467 if (c == 'r') {
468 /* Copy new module into library */
469 p = options.usefname ? argv[4] : argv[3];
470 add_module(libfp, argv[4], p);
473 /* Copy rest of library if any */
474 while (!feof(tmpfp)) {
475 if ((i = fgetc(tmpfp)) == EOF)
476 break;
478 if (fputc(i, libfp) == EOF)
479 error_exit(1, false, "write error");
482 fclose(libfp);
483 fclose(tmpfp);
484 break;
486 default:
487 error_exit(2, false, "invalid command '%c'\n", c);
490 return 0;