Imported Upstream version 0.153
[platform/upstream/elfutils.git] / tests / arextract.c
1 /* Copyright (C) 1999, 2000, 2002 Red Hat, Inc.
2    This file is part of Red Hat elfutils.
3    Written by Ulrich Drepper <drepper@redhat.com>, 1999.
4
5    Red Hat elfutils is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by the
7    Free Software Foundation; version 2 of the License.
8
9    Red Hat 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 GNU
12    General Public License for more details.
13
14    You should have received a copy of the GNU General Public License along
15    with Red Hat elfutils; if not, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
17
18    Red Hat elfutils is an included package of the Open Invention Network.
19    An included package of the Open Invention Network is a package for which
20    Open Invention Network licensees cross-license their patents.  No patent
21    license is granted, either expressly or impliedly, by designation as an
22    included package.  Should you wish to participate in the Open Invention
23    Network licensing program, please visit www.openinventionnetwork.com
24    <http://www.openinventionnetwork.com>.  */
25
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29
30 #include <fcntl.h>
31 #include <gelf.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include <sys/param.h>
37
38
39 int
40 main (int argc, char *argv[])
41 {
42   int fd;
43   Elf *elf;
44   Elf *subelf;
45   Elf_Cmd cmd;
46   off_t offset;
47   size_t todo;
48
49   if (argc < 4)
50     exit (1);
51
52   /* Open the archive.  */
53   fd = open (argv[1], O_RDONLY);
54   if (fd == -1)
55     {
56       printf ("Cannot open input file: %m");
57       exit (1);
58     }
59
60   /* Set the ELF version.  */
61   elf_version (EV_CURRENT);
62
63   /* Create an ELF descriptor.  */
64   cmd = ELF_C_READ;
65   elf = elf_begin (fd, cmd, NULL);
66   if (elf == NULL)
67     {
68       printf ("Cannot create ELF descriptor: %s\n", elf_errmsg (-1));
69       exit (1);
70     }
71
72   /* If it is no archive punt.  */
73   if (elf_kind (elf) != ELF_K_AR)
74     {
75       printf ("`%s' is no archive\n", argv[1]);
76       exit (1);
77     }
78
79   /* Get the elements of the archive one after the other.  */
80   while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
81     {
82       /* The the header for this element.  */
83       Elf_Arhdr *arhdr = elf_getarhdr (subelf);
84
85       if (arhdr == NULL)
86         {
87           printf ("cannot get arhdr: %s\n", elf_errmsg (-1));
88           exit (1);
89         }
90
91       if (strcmp (arhdr->ar_name, argv[2]) == 0)
92         {
93           int outfd;
94
95           /* Get the offset of the file in the archive.  */
96           offset = elf_getbase (subelf);
97           if (offset == -1)
98             {
99               printf ("\
100 Failed to get base address for the archive element: %s\n",
101                       elf_errmsg (-1));
102               exit (1);
103             }
104
105           /* Open the output file.  */
106           outfd = open (argv[3], O_CREAT | O_TRUNC | O_RDWR, 0666);
107           if (outfd == -1)
108             {
109               printf ("cannot open output file: %m");
110               exit (1);
111             }
112
113           /* Now write out the data.  */
114           todo = arhdr->ar_size;
115           while (todo > 0)
116             {
117               char buf[1024];
118               ssize_t n = pread (fd, buf, MIN (sizeof buf, todo), offset);
119               if (n == 0)
120                 break;
121
122               if (write (outfd, buf, n) != n)
123                 {
124                   puts ("Writing output failed");
125                   exit (1);
126                 }
127
128               offset += n;
129               todo -= n;
130             }
131
132           /* Check whether all the date was read and written out.  */
133           if (todo != 0)
134             {
135               puts ("Reading archive member failed.");
136               exit (1);
137             }
138
139           /* Close the descriptors.  */
140           if (elf_end (subelf) != 0 || elf_end (elf) != 0)
141             {
142               printf ("Freeing ELF descriptors failed: %s", elf_errmsg (-1));
143               exit (1);
144             }
145
146           close (outfd);
147           close (fd);
148
149           /* All went well.  */
150           exit (0);
151         }
152
153       /* Get next archive element.  */
154       cmd = elf_next (subelf);
155       if (elf_end (subelf) != 0)
156         {
157           printf ("error while freeing sub-ELF descriptor: %s\n",
158                   elf_errmsg (-1));
159           exit (1);
160         }
161     }
162
163   /* When we reach this point we haven't found the given file in the
164      archive.  */
165   printf ("File `%s' not found in archive\n", argv[2]);
166   exit (1);
167 }