diff options
Diffstat (limited to 'libbb/get_ar_headers.c')
-rw-r--r-- | libbb/get_ar_headers.c | 119 |
1 files changed, 0 insertions, 119 deletions
diff --git a/libbb/get_ar_headers.c b/libbb/get_ar_headers.c deleted file mode 100644 index 414498b4f..000000000 --- a/libbb/get_ar_headers.c +++ /dev/null | |||
@@ -1,119 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Utility routines. | ||
4 | * | ||
5 | * Copyright (C) tons of folks. Tracking down who wrote what | ||
6 | * isn't something I'm going to worry about... If you wrote something | ||
7 | * here, please feel free to acknowledge your work. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | * Based in part on code from sash, Copyright (c) 1999 by David I. Bell | ||
24 | * Permission has been granted to redistribute this code under the GPL. | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <stdlib.h> | ||
29 | #include <string.h> | ||
30 | #include <unistd.h> | ||
31 | #include "libbb.h" | ||
32 | |||
33 | file_headers_t *get_ar_headers(FILE *in_file) | ||
34 | { | ||
35 | typedef struct raw_ar_header_s { /* Byte Offset */ | ||
36 | char name[16]; /* 0-15 */ | ||
37 | char date[12]; /* 16-27 */ | ||
38 | char uid[6]; | ||
39 | char gid[6]; /* 28-39 */ | ||
40 | char mode[8]; /* 40-47 */ | ||
41 | char size[10]; /* 48-57 */ | ||
42 | char fmag[2]; /* 58-59 */ | ||
43 | } raw_ar_header_t; | ||
44 | |||
45 | raw_ar_header_t raw_ar_header; | ||
46 | |||
47 | file_headers_t *ar_list, *ar_entry; | ||
48 | char ar_magic[8]; | ||
49 | char *long_name=NULL; | ||
50 | |||
51 | /* check ar magic */ | ||
52 | if (fread(ar_magic, 1, 8, in_file) != 8) { | ||
53 | error_msg("cannot read magic"); | ||
54 | return(NULL); | ||
55 | } | ||
56 | |||
57 | if (strncmp(ar_magic,"!<arch>",7) != 0) { | ||
58 | error_msg("invalid magic"); | ||
59 | return(NULL); | ||
60 | } | ||
61 | |||
62 | ar_list = (file_headers_t *) xcalloc(1, sizeof(file_headers_t)); | ||
63 | |||
64 | while (fread((char *) &raw_ar_header, 1, 60, in_file) == 60) { | ||
65 | ar_entry = (file_headers_t *) xcalloc(1, sizeof(file_headers_t)); | ||
66 | /* check the end of header markers are valid */ | ||
67 | if ((raw_ar_header.fmag[0] != '`') || (raw_ar_header.fmag[1] != '\n')) { | ||
68 | char newline; | ||
69 | if (raw_ar_header.fmag[1] != '`') { | ||
70 | break; | ||
71 | } | ||
72 | /* some version of ar, have an extra '\n' after each entry */ | ||
73 | fread(&newline, 1, 1, in_file); | ||
74 | if (newline!='\n') { | ||
75 | break; | ||
76 | } | ||
77 | /* fix up the header, we started reading 1 byte too early due to a '\n' */ | ||
78 | memmove((char *) &raw_ar_header, (char *)&raw_ar_header+1, 59); | ||
79 | /* dont worry about adding the last '\n', we dont need it now */ | ||
80 | } | ||
81 | |||
82 | ar_entry->size = (size_t) atoi(raw_ar_header.size); | ||
83 | /* long filenames have '/' as the first character */ | ||
84 | if (raw_ar_header.name[0] == '/') { | ||
85 | if (raw_ar_header.name[1] == '/') { | ||
86 | /* multiple long filenames are stored as data in one entry */ | ||
87 | long_name = (char *) xrealloc(long_name, ar_entry->size); | ||
88 | fread(long_name, 1, ar_entry->size, in_file); | ||
89 | continue; | ||
90 | } | ||
91 | else { | ||
92 | /* The number after the '/' indicates the offset in the ar data section | ||
93 | (saved in variable long_name) that conatains the real filename */ | ||
94 | const int long_name_offset = (int) atoi((char *) &raw_ar_header.name[1]); | ||
95 | ar_entry->name = xmalloc(strlen(&long_name[long_name_offset])); | ||
96 | strcpy(ar_entry->name, &long_name[long_name_offset]); | ||
97 | } | ||
98 | } | ||
99 | else { | ||
100 | /* short filenames */ | ||
101 | ar_entry->name = xmalloc(16); | ||
102 | ar_entry->name = strncpy(ar_entry->name, raw_ar_header.name, 16); | ||
103 | } | ||
104 | ar_entry->name[strcspn(ar_entry->name, " /")]='\0'; | ||
105 | |||
106 | /* convert the rest of the now valid char header to its typed struct */ | ||
107 | parse_mode(raw_ar_header.mode, &ar_entry->mode); | ||
108 | ar_entry->mtime = atoi(raw_ar_header.date); | ||
109 | ar_entry->uid = atoi(raw_ar_header.uid); | ||
110 | ar_entry->gid = atoi(raw_ar_header.gid); | ||
111 | ar_entry->offset = ftell(in_file); | ||
112 | ar_entry->next = NULL; | ||
113 | |||
114 | fseek(in_file, (off_t) ar_entry->size, SEEK_CUR); | ||
115 | |||
116 | ar_list = append_archive_list(ar_list, ar_entry); | ||
117 | } | ||
118 | return(ar_list); | ||
119 | } | ||