1 #include <ar.h> 2 #include <fcntl.h> 3 #include <libelf.h> 4 #include <stdio.h> 5 #include <unistd.h> 6 7 8 static int handle (const char *fname); 9 10 11 int 12 main (int argc, char *argv[]) 13 { 14 elf_version (EV_CURRENT); 15 16 int result = 0; 17 if (argc == 1) 18 result = handle ("a.out"); 19 else 20 for (int i = 1; i < argc; ++i) 21 result |= handle (argv[1]); 22 23 return result; 24 } 25 26 27 static int 28 handle (const char *fname) 29 { 30 int fd = open (fname, O_RDONLY); 31 if (fd == -1) 32 { 33 printf ("cannot open '%s': %m\n", fname); 34 return 1; 35 } 36 37 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 38 if (elf == NULL) 39 { 40 printf ("cannot get ELF handling for '%s': %s\n", 41 fname, elf_errmsg (-1)); 42 close (fd); 43 return 1; 44 } 45 46 if (elf_kind (elf) != ELF_K_AR) 47 { 48 printf ("'%s' is no archive\n", fname); 49 elf_end (elf); 50 close (fd); 51 return 1; 52 } 53 54 printf ("%s:\n", fname); 55 Elf *subelf = NULL; 56 Elf_Cmd cmd = ELF_C_READ_MMAP; 57 while ((subelf = elf_begin (fd, cmd, elf)) != NULL) 58 { 59 Elf_Arhdr *arhdr = elf_getarhdr (subelf); 60 if (arhdr == NULL) 61 { 62 printf ("cannot get archive header in '%s': %s\n", 63 fname, elf_errmsg (-1)); 64 elf_end (subelf); 65 elf_end (elf); 66 close (fd); 67 return 1; 68 } 69 70 off_t off = elf_getaroff (subelf); 71 72 printf ("\nOffset %llu\n" 73 " Name %s\n" 74 " Date %ld\n" 75 " UID %d\n" 76 " GID %d\n" 77 " Mode %o\n" 78 " Size %lld\n", 79 (unsigned long long int) off, 80 arhdr->ar_name, (long int) arhdr->ar_date, (int) arhdr->ar_uid, 81 (int) arhdr->ar_gid, 82 (int) arhdr->ar_mode, (long long int) arhdr->ar_size); 83 84 cmd = elf_next (subelf); 85 elf_end (subelf); 86 } 87 88 close (fd); 89 90 return 0; 91 } 92