1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22: ^L
23:
24:
25:
26:
27:
28:
29:
30: #include "sysdep.h"
31: #include "bfd.h"
32: #include "libiberty.h"
33: #include "progress.h"
34: #include "aout/ar.h"
35: #include "libbfd.h"
36: #include "bucomm.h"
37: #include "arsup.h"
38: #include "filenames.h"
39: #include "binemul.h"
40: #include <sys/stat.h>
41:
42: #ifdef __GO32___
43: #define EXT_NAME_LEN 3
44: #else
45: #define EXT_NAME_LEN 6
46: #endif
47:
48:
49:
50: #ifndef O_BINARY
51: #define O_BINARY 0
52: #endif
53:
54:
55:
56: struct ar_hdr *
57: bfd_special_undocumented_glue (bfd * abfd, const char *filename);
58:
59:
60:
61: static void mri_emul (void);
62: static const char *normalize (const char *, bfd *);
63: static void remove_output (void);
64: static void map_over_members (bfd *, void (*)(bfd *), char **, int);
65: static void print_contents (bfd * member);
66: static void delete_members (bfd *, char **files_to_delete);
67:
68: static void move_members (bfd *, char **files_to_move);
69: static void replace_members
70: (bfd *, char **files_to_replace, bfd_boolean quick);
71: static void print_descr (bfd * abfd);
72: static void write_archive (bfd *);
73: static int ranlib_only (const char *archname);
74: static int ranlib_touch (const char *archname);
75: static void usage (int);
76: ^L
77:
78:
79: static int mri_mode;
80:
81:
82:
83:
84: extern int is_ranlib;
85:
86:
87: int silent_create = 0;
88:
89:
90: int verbose = 0;
91:
92:
93: int preserve_dates = 0;
94:
95:
96:
97: int newer_only = 0;
98:
99:
100:
101:
102:
103:
104:
105:
106: int write_armap = 0;
107:
108:
109:
110: char *posname = NULL;
111:
112:
113:
114:
115:
116: enum pos
117: {
118: pos_default, pos_before, pos_after, pos_end
119: } postype = pos_default;
120:
121: static bfd **
122: get_pos_bfd (bfd **, enum pos, const char *);
123:
124:
125:
126: static bfd_boolean counted_name_mode = 0;
127: static int counted_name_counter = 0;
128:
129:
130: static bfd_boolean ar_truncate = FALSE;
131:
132:
133:
134:
135: static bfd_boolean full_pathname = FALSE;
136:
137: int interactive = 0;
138:
139: static void
140: mri_emul (void)
141: {
142: interactive = isatty (fileno (stdin));
143: yyparse ();
144: }
145:
146:
147:
148:
149:
150: static void
151: map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count)
152: {
153: bfd *head;
154: int match_count;
155:
156: if (count == 0)
157: {
158: for (head = arch->archive_next; head; head = head->archive_next)
159: {
160: PROGRESS (1);
161: function (head);
162: }
163: return;
164: }
165:
166:
167:
168:
169:
170:
171:
172: for (; count > 0; files++, count--)
173: {
174: bfd_boolean found = FALSE;
175:
176: match_count = 0;
177: for (head = arch->archive_next; head; head = head->archive_next)
178: {
179: PROGRESS (1);
180: if (head->filename == NULL)
181: {
182:
183:
184: struct stat buf;
185: bfd_stat_arch_elt (head, &buf);
186: }
187: if ((head->filename != NULL) &&
188: (!FILENAME_CMP (normalize (*files, arch), head->filename)))
189: {
190: ++match_count;
191: if (counted_name_mode
192: && match_count != counted_name_counter)
193: {
194:
195:
196: continue;
197: }
198:
199: found = TRUE;
200: function (head);
201: }
202: }
203: if (!found)
204:
205: fprintf (stderr, _("no entry %s in archive\n"), *files);
206: }
207: }
208: ^L
209: bfd_boolean operation_alters_arch = FALSE;
210:
211: static void
212: usage (int help)
213: {
214: FILE *s;
215:
216: s = help ? stdout : stderr;
217:
218: if (! is_ranlib)
219: {
220:
221: fprintf (s, _("Usage: %s [emulation options] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n"),
222: program_name);
223:
224: fprintf (s, _(" %s -M [<mri-script]\n"), program_name);
225: fprintf (s, _(" commands:\n"));
226: fprintf (s, _(" d - delete file(s) from the archive\n"));
227: fprintf (s, _(" m[ab] - move file(s) in the archive\n"));
228: fprintf (s, _(" p - print file(s) found in the archive\n"));
229: fprintf (s, _(" q[f] - quick append file(s) to the archive\n"));
230: fprintf (s, _(" r[ab][f][u] - replace existing or insert new file(s) into the archive\n"));
231: fprintf (s, _(" t - display contents of archive\n"));
232: fprintf (s, _(" x[o] - extract file(s) from the archive\n"));
233: fprintf (s, _(" command specific modifiers:\n"));
234: fprintf (s, _(" [a] - put file(s) after [member-name]\n"));
235: fprintf (s, _(" [b] - put file(s) before [member-name] (same as [i])\n"));
236: fprintf (s, _(" [N] - use instance [count] of name\n"));
237: fprintf (s, _(" [f] - truncate inserted file names\n"));
238: fprintf (s, _(" [P] - use full path names when matching\n"));
239: fprintf (s, _(" [o] - preserve original dates\n"));
240: fprintf (s, _(" [u] - only replace files that are newer than current archive contents\n"));
241: fprintf (s, _(" generic modifiers:\n"));
242: fprintf (s, _(" [c] - do not warn if the library had to be created\n"));
243: fprintf (s, _(" [s] - create an archive index (cf. ranlib)\n"));
244: fprintf (s, _(" [S] - do not build a symbol table\n"));
245: fprintf (s, _(" [v] - be verbose\n"));
246: fprintf (s, _(" [V] - display the version number\n"));
247: fprintf (s, _(" @<file> - read options from <file>\n"));
248:
249: ar_emul_usage (s);
250: }
251: else
252: {
253:
254: fprintf (s, _("Usage: %s [options] archive\n"), program_name);
255: fprintf (s, _(" Generate an index to speed access to archives\n"));
256: fprintf (s, _(" The options are:\n\
257: @<file> Read options from <file>\n\
258: -h --help Print this help message\n\
259: -V --version Print version information\n"));
260: }
261:
262: list_supported_targets (program_name, s);
263:
264: if (REPORT_BUGS_TO[0] && help)
265: fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
266:
267: xexit (help ? 0 : 1);
268: }
269:
270:
271:
272:
273: static const char *
274: normalize (const char *file, bfd *abfd)
275: {
276: const char *filename;
277:
278: if (full_pathname)
279: return file;
280:
281: filename = strrchr (file, '/');
282: #ifdef HAVE_DOS_BASED_FILE_SYSTEM
283: {
284:
285: char *bslash = strrchr (file, '\\');
286: if (filename == NULL || (bslash != NULL && bslash > filename))
287: filename = bslash;
288: if (filename == NULL && file[0] != '\0' && file[1] == ':')
289: filename = file + 1;
290: }
291: #endif
292: if (filename != (char *) NULL)
293: filename++;
294: else
295: filename = file;
296:
297: if (ar_truncate
298: && abfd != NULL
299: && strlen (filename) > abfd->xvec->ar_max_namelen)
300: {
301: char *s;
302:
303:
304: s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
305: memcpy (s, filename, abfd->xvec->ar_max_namelen);
306: s[abfd->xvec->ar_max_namelen] = '\0';
307: filename = s;
308: }
309:
310: return filename;
311: }
312:
313:
314:
315: static const char *output_filename = NULL;
316: static FILE *output_file = NULL;
317: static bfd *output_bfd = NULL;
318:
319: static void
320: remove_output (void)
321: {
322: if (output_filename != NULL)
323: {
324: if (output_bfd != NULL)
325: bfd_cache_close (output_bfd);
326: if (output_file != NULL)
327: fclose (output_file);
328: unlink_if_ordinary (output_filename);
329: }
330: }
331:
332:
333:
334:
335: int main (int, char **);
336:
337: int
338: main (int argc, char **argv)
339: {
340: char *arg_ptr;
341: char c;
342: enum
343: {
344: none = 0, delete, replace, print_table,
345: print_files, extract, move, quick_append
346: } operation = none;
347: int arg_index;
348: char **files;
349: int file_count;
350: char *inarch_filename;
351: int show_version;
352: int i;
353: int do_posix = 0;
354:
355: #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
356: setlocale (LC_MESSAGES, "");
357: #endif
358: #if defined (HAVE_SETLOCALE)
359: setlocale (LC_CTYPE, "");
360: #endif
361: bindtextdomain (PACKAGE, LOCALEDIR);
362: textdomain (PACKAGE);
363:
364: program_name = argv[0];
365: xmalloc_set_program_name (program_name);
366:
367: expandargv (&argc, &argv);
368:
369: if (is_ranlib < 0)
370: {
371: char *temp;
372:
373: temp = strrchr (program_name, '/');
374: #ifdef HAVE_DOS_BASED_FILE_SYSTEM
375: {
376:
377: char *bslash = strrchr (program_name, '\\');
378: if (temp == NULL || (bslash != NULL && bslash > temp))
379: temp = bslash;
380: if (temp == NULL && program_name[0] != '\0' && program_name[1] == ':')
381: temp = program_name + 1;
382: }
383: #endif
384: if (temp == NULL)
385: temp = program_name;
386: else
387: ++temp;
388: if (strlen (temp) >= 6
389: && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
390: is_ranlib = 1;
391: else
392: is_ranlib = 0;
393: }
394:
395: if (argc > 1 && argv[1][0] == '-')
396: {
397: if (strcmp (argv[1], "--help") == 0)
398: usage (1);
399: else if (strcmp (argv[1], "--version") == 0)
400: {
401: if (is_ranlib)
402: print_version ("ranlib");
403: else
404: print_version ("ar");
405: }
406: }
407:
408: START_PROGRESS (program_name, 0);
409:
410: bfd_init ();
411: set_default_bfd_target ();
412:
413: show_version = 0;
414:
415: xatexit (remove_output);
416:
417: for (i = 1; i < argc; i++)
418: if (! ar_emul_parse_arg (argv[i]))
419: break;
420: argv += (i - 1);
421: argc -= (i - 1);
422:
423: if (is_ranlib)
424: {
425: int status = 0;
426: bfd_boolean touch = FALSE;
427:
428: if (argc < 2
429: || strcmp (argv[1], "--help") == 0
430: || strcmp (argv[1], "-h") == 0
431: || strcmp (argv[1], "-H") == 0)
432: usage (0);
433: if (strcmp (argv[1], "-V") == 0
434: || strcmp (argv[1], "-v") == 0
435: || CONST_STRNEQ (argv[1], "--v"))
436: print_version ("ranlib");
437: arg_index = 1;
438: if (strcmp (argv[1], "-t") == 0)
439: {
440: ++arg_index;
441: touch = TRUE;
442: }
443: while (arg_index < argc)
444: {
445: if (! touch)
446: status |= ranlib_only (argv[arg_index]);
447: else
448: status |= ranlib_touch (argv[arg_index]);
449: ++arg_index;
450: }
451: xexit (status);
452: }
453:
454: if (argc == 2 && strcmp (argv[1], "-M") == 0)
455: {
456: mri_emul ();
457: xexit (0);
458: }
459:
460: if (argc < 2)
461: usage (0);
462:
463: arg_index = 1;
464: arg_ptr = argv[arg_index];
465:
466: if (*arg_ptr == '-')
467: {
468:
469:
470: do_posix = 1;
471: ++arg_ptr;
472: }
473:
474: do
475: {
476: while ((c = *arg_ptr++) != '\0')
477: {
478: switch (c)
479: {
480: case 'd':
481: case 'm':
482: case 'p':
483: case 'q':
484: case 'r':
485: case 't':
486: case 'x':
487: if (operation != none)
488: fatal (_("two different operation options specified"));
489: switch (c)
490: {
491: case 'd':
492: operation = delete;
493: operation_alters_arch = TRUE;
494: break;
495: case 'm':
496: operation = move;
497: operation_alters_arch = TRUE;
498: break;
499: case 'p':
500: operation = print_files;
501: break;
502: case 'q':
503: operation = quick_append;
504: operation_alters_arch = TRUE;
505: break;
506: case 'r':
507: operation = replace;
508: operation_alters_arch = TRUE;
509: break;
510: case 't':
511: operation = print_table;
512: break;
513: case 'x':
514: operation = extract;
515: break;
516: }
517: case 'l':
518: break;
519: case 'c':
520: silent_create = 1;
521: break;
522: case 'o':
523: preserve_dates = 1;
524: break;
525: case 'V':
526: show_version = TRUE;
527: break;
528: case 's':
529: write_armap = 1;
530: break;
531: case 'S':
532: write_armap = -1;
533: break;
534: case 'u':
535: newer_only = 1;
536: break;
537: case 'v':
538: verbose = 1;
539: break;
540: case 'a':
541: postype = pos_after;
542: break;
543: case 'b':
544: postype = pos_before;
545: break;
546: case 'i':
547: postype = pos_before;
548: break;
549: case 'M':
550: mri_mode = 1;
551: break;
552: case 'N':
553: counted_name_mode = TRUE;
554: break;
555: case 'f':
556: ar_truncate = TRUE;
557: break;
558: case 'P':
559: full_pathname = TRUE;
560: break;
561: default:
562:
563: non_fatal (_("illegal option -- %c"), c);
564: usage (0);
565: }
566: }
567:
568:
569:
570: if (do_posix && arg_index + 1 < argc && argv[arg_index + 1][0] == '-')
571: arg_ptr = argv[++arg_index] + 1;
572: else
573: do_posix = 0;
574: }
575: while (do_posix);
576:
577: if (show_version)
578: print_version ("ar");
579:
580: ++arg_index;
581: if (arg_index >= argc)
582: usage (0);
583:
584: if (mri_mode)
585: {
586: mri_emul ();
587: }
588: else
589: {
590: bfd *arch;
591:
592:
593:
594:
595: