| #include <ar.h> |
| #include <fcntl.h> |
| #include <libelf.h> |
| #include <stdio.h> |
| #include <unistd.h> |
| |
| |
| static int handle (const char *fname); |
| |
| |
| int |
| main (int argc, char *argv[]) |
| { |
| elf_version (EV_CURRENT); |
| |
| int result = 0; |
| if (argc == 1) |
| result = handle ("a.out"); |
| else |
| for (int i = 1; i < argc; ++i) |
| result |= handle (argv[1]); |
| |
| return result; |
| } |
| |
| |
| static int |
| handle (const char *fname) |
| { |
| int fd = open (fname, O_RDONLY); |
| if (fd == -1) |
| { |
| printf ("cannot open '%s': %m\n", fname); |
| return 1; |
| } |
| |
| Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); |
| if (elf == NULL) |
| { |
| printf ("cannot get ELF handling for '%s': %s\n", |
| fname, elf_errmsg (-1)); |
| close (fd); |
| return 1; |
| } |
| |
| if (elf_kind (elf) != ELF_K_AR) |
| { |
| printf ("'%s' is no archive\n", fname); |
| elf_end (elf); |
| close (fd); |
| return 1; |
| } |
| |
| printf ("%s:\n", fname); |
| Elf *subelf = NULL; |
| Elf_Cmd cmd = ELF_C_READ_MMAP; |
| while ((subelf = elf_begin (fd, cmd, elf)) != NULL) |
| { |
| Elf_Arhdr *arhdr = elf_getarhdr (subelf); |
| if (arhdr == NULL) |
| { |
| printf ("cannot get archive header in '%s': %s\n", |
| fname, elf_errmsg (-1)); |
| elf_end (subelf); |
| elf_end (elf); |
| close (fd); |
| return 1; |
| } |
| |
| off_t off = elf_getaroff (subelf); |
| |
| printf ("\nOffset %llu\n" |
| " Name %s\n" |
| " Date %ld\n" |
| " UID %d\n" |
| " GID %d\n" |
| " Mode %o\n" |
| " Size %lld\n", |
| (unsigned long long int) off, |
| arhdr->ar_name, (long int) arhdr->ar_date, (int) arhdr->ar_uid, |
| (int) arhdr->ar_gid, |
| (int) arhdr->ar_mode, (long long int) arhdr->ar_size); |
| |
| cmd = elf_next (subelf); |
| elf_end (subelf); |
| } |
| |
| close (fd); |
| |
| return 0; |
| } |