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