1 /* Copyright (C) 2007 Red Hat, Inc.
2 This file is part of elfutils.
3
4 This file is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 elfutils is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20
21 #include <ar.h>
22 #include <fcntl.h>
23 #include <libelf.h>
24 #include <stdio.h>
25 #include <unistd.h>
26
27
28 static int handle (const char *fname);
29
30
31 int
main(int argc,char * argv[])32 main (int argc, char *argv[])
33 {
34 elf_version (EV_CURRENT);
35
36 int result = 0;
37 if (argc == 1)
38 result = handle ("a.out");
39 else
40 for (int i = 1; i < argc; ++i)
41 result |= handle (argv[1]);
42
43 return result;
44 }
45
46
47 static int
handle(const char * fname)48 handle (const char *fname)
49 {
50 int fd = open (fname, O_RDONLY);
51 if (fd == -1)
52 {
53 printf ("cannot open '%s': %m\n", fname);
54 return 1;
55 }
56
57 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
58 if (elf == NULL)
59 {
60 printf ("cannot get ELF handling for '%s': %s\n",
61 fname, elf_errmsg (-1));
62 close (fd);
63 return 1;
64 }
65
66 if (elf_kind (elf) != ELF_K_AR)
67 {
68 printf ("'%s' is no archive\n", fname);
69 elf_end (elf);
70 close (fd);
71 return 1;
72 }
73
74 printf ("%s:\n", fname);
75 Elf *subelf = NULL;
76 Elf_Cmd cmd = ELF_C_READ_MMAP;
77 while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
78 {
79 Elf_Arhdr *arhdr = elf_getarhdr (subelf);
80 if (arhdr == NULL)
81 {
82 printf ("cannot get archive header in '%s': %s\n",
83 fname, elf_errmsg (-1));
84 elf_end (subelf);
85 elf_end (elf);
86 close (fd);
87 return 1;
88 }
89
90 off_t off = elf_getaroff (subelf);
91
92 printf ("\nOffset %llu\n"
93 " Name %s\n"
94 " Date %ld\n"
95 " UID %d\n"
96 " GID %d\n"
97 " Mode %o\n"
98 " Size %lld\n",
99 (unsigned long long int) off,
100 arhdr->ar_name, (long int) arhdr->ar_date, (int) arhdr->ar_uid,
101 (int) arhdr->ar_gid,
102 (int) arhdr->ar_mode, (long long int) arhdr->ar_size);
103
104 cmd = elf_next (subelf);
105 elf_end (subelf);
106 }
107
108 close (fd);
109
110 return 0;
111 }
112