diff options
author | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2002-12-10 00:17:22 +0000 |
---|---|---|
committer | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2002-12-10 00:17:22 +0000 |
commit | fb146fd52fc16b6a272f674a70af0f20ab07ee08 (patch) | |
tree | 4923918fadcaac4fdaa5d4197a4e5bafd22b9b2e /archival/cpio.c | |
parent | 2b59f816b16e2f55b095447484922a79a403aef3 (diff) | |
download | busybox-w32-fb146fd52fc16b6a272f674a70af0f20ab07ee08.tar.gz busybox-w32-fb146fd52fc16b6a272f674a70af0f20ab07ee08.tar.bz2 busybox-w32-fb146fd52fc16b6a272f674a70af0f20ab07ee08.zip |
rpm applet by Laurence Anderson
git-svn-id: svn://busybox.net/trunk/busybox@6150 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'archival/cpio.c')
-rw-r--r-- | archival/cpio.c | 160 |
1 files changed, 1 insertions, 159 deletions
diff --git a/archival/cpio.c b/archival/cpio.c index 8b4cc2d3e..49f3f88e4 100644 --- a/archival/cpio.c +++ b/archival/cpio.c | |||
@@ -31,12 +31,6 @@ | |||
31 | #include "unarchive.h" | 31 | #include "unarchive.h" |
32 | #include "busybox.h" | 32 | #include "busybox.h" |
33 | 33 | ||
34 | typedef struct hardlinks_s { | ||
35 | file_header_t *entry; | ||
36 | int inode; | ||
37 | struct hardlinks_s *next; | ||
38 | } hardlinks_t; | ||
39 | |||
40 | extern int cpio_main(int argc, char **argv) | 34 | extern int cpio_main(int argc, char **argv) |
41 | { | 35 | { |
42 | archive_handle_t *archive_handle; | 36 | archive_handle_t *archive_handle; |
@@ -83,159 +77,7 @@ extern int cpio_main(int argc, char **argv) | |||
83 | optind++; | 77 | optind++; |
84 | } | 78 | } |
85 | 79 | ||
86 | while (1) { | 80 | while (get_header_cpio(archive_handle) == EXIT_SUCCESS); |
87 | static hardlinks_t *saved_hardlinks = NULL; | ||
88 | static unsigned short pending_hardlinks = 0; | ||
89 | file_header_t *file_header = archive_handle->file_header; | ||
90 | char cpio_header[110]; | ||
91 | int namesize; | ||
92 | char dummy[16]; | ||
93 | int major, minor, nlink, inode; | ||
94 | char extract_flag; | ||
95 | |||
96 | if (pending_hardlinks) { /* Deal with any pending hardlinks */ | ||
97 | hardlinks_t *tmp; | ||
98 | hardlinks_t *oldtmp; | ||
99 | |||
100 | tmp = saved_hardlinks; | ||
101 | oldtmp = NULL; | ||
102 | |||
103 | while (tmp) { | ||
104 | error_msg_and_die("need to fix this\n"); | ||
105 | if (tmp->entry->link_name) { /* Found a hardlink ready to be extracted */ | ||
106 | file_header = tmp->entry; | ||
107 | if (oldtmp) { | ||
108 | oldtmp->next = tmp->next; /* Remove item from linked list */ | ||
109 | } else { | ||
110 | saved_hardlinks = tmp->next; | ||
111 | } | ||
112 | free(tmp); | ||
113 | continue; | ||
114 | } | ||
115 | oldtmp = tmp; | ||
116 | tmp = tmp->next; | ||
117 | } | ||
118 | pending_hardlinks = 0; /* No more pending hardlinks, read next file entry */ | ||
119 | } | ||
120 | |||
121 | /* There can be padding before archive header */ | ||
122 | data_align(archive_handle, 4); | ||
123 | |||
124 | if (archive_xread_all_eof(archive_handle, cpio_header, 110) == 0) { | ||
125 | return(EXIT_FAILURE); | ||
126 | } | ||
127 | archive_handle->offset += 110; | ||
128 | |||
129 | if (strncmp(&cpio_header[0], "07070", 5) != 0) { | ||
130 | printf("cpio header is %x-%x-%x-%x-%x\n", | ||
131 | cpio_header[0], | ||
132 | cpio_header[1], | ||
133 | cpio_header[2], | ||
134 | cpio_header[3], | ||
135 | cpio_header[4]); | ||
136 | error_msg_and_die("Unsupported cpio format"); | ||
137 | } | ||
138 | |||
139 | if ((cpio_header[5] != '1') && (cpio_header[5] != '2')) { | ||
140 | error_msg_and_die("Unsupported cpio format, use newc or crc"); | ||
141 | } | ||
142 | |||
143 | sscanf(cpio_header, "%6c%8x%8x%8x%8x%8x%8lx%8lx%16c%8x%8x%8x%8c", | ||
144 | dummy, &inode, (unsigned int*)&file_header->mode, | ||
145 | (unsigned int*)&file_header->uid, (unsigned int*)&file_header->gid, | ||
146 | &nlink, &file_header->mtime, &file_header->size, | ||
147 | dummy, &major, &minor, &namesize, dummy); | ||
148 | |||
149 | file_header->name = (char *) xmalloc(namesize + 1); | ||
150 | archive_xread_all(archive_handle, file_header->name, namesize); /* Read in filename */ | ||
151 | file_header->name[namesize] = '\0'; | ||
152 | archive_handle->offset += namesize; | ||
153 | |||
154 | /* Update offset amount and skip padding before file contents */ | ||
155 | data_align(archive_handle, 4); | ||
156 | |||
157 | if (strcmp(file_header->name, "TRAILER!!!") == 0) { | ||
158 | printf("%d blocks\n", (int) (archive_handle->offset % 512 ? (archive_handle->offset / 512) + 1 : archive_handle->offset / 512)); /* Always round up */ | ||
159 | if (saved_hardlinks) { /* Bummer - we still have unresolved hardlinks */ | ||
160 | hardlinks_t *tmp = saved_hardlinks; | ||
161 | hardlinks_t *oldtmp = NULL; | ||
162 | while (tmp) { | ||
163 | error_msg("%s not created: cannot resolve hardlink", tmp->entry->name); | ||
164 | oldtmp = tmp; | ||
165 | tmp = tmp->next; | ||
166 | free (oldtmp->entry->name); | ||
167 | free (oldtmp->entry); | ||
168 | free (oldtmp); | ||
169 | } | ||
170 | saved_hardlinks = NULL; | ||
171 | pending_hardlinks = 0; | ||
172 | } | ||
173 | return(EXIT_FAILURE); | ||
174 | } | ||
175 | |||
176 | if (S_ISLNK(file_header->mode)) { | ||
177 | file_header->link_name = (char *) xmalloc(file_header->size + 1); | ||
178 | archive_xread_all(archive_handle, file_header->link_name, file_header->size); | ||
179 | file_header->link_name[file_header->size] = '\0'; | ||
180 | archive_handle->offset += file_header->size; | ||
181 | file_header->size = 0; /* Stop possible seeks in future */ | ||
182 | } | ||
183 | if (nlink > 1 && !S_ISDIR(file_header->mode)) { | ||
184 | if (file_header->size == 0) { /* Put file on a linked list for later */ | ||
185 | hardlinks_t *new = xmalloc(sizeof(hardlinks_t)); | ||
186 | new->next = saved_hardlinks; | ||
187 | new->inode = inode; | ||
188 | new->entry = file_header; | ||
189 | saved_hardlinks = new; | ||
190 | continue; | ||
191 | } else { /* Found the file with data in */ | ||
192 | hardlinks_t *tmp = saved_hardlinks; | ||
193 | pending_hardlinks = 1; | ||
194 | while (tmp) { | ||
195 | if (tmp->inode == inode) { | ||
196 | tmp->entry->link_name = xstrdup(file_header->name); | ||
197 | nlink--; | ||
198 | } | ||
199 | tmp = tmp->next; | ||
200 | } | ||
201 | if (nlink > 1) { | ||
202 | error_msg("error resolving hardlink: did you create the archive with GNU cpio 2.0-2.2?"); | ||
203 | } | ||
204 | } | ||
205 | } | ||
206 | file_header->device = (major << 8) | minor; | ||
207 | |||
208 | extract_flag = FALSE; | ||
209 | if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { | ||
210 | struct stat statbuf; | ||
211 | |||
212 | extract_flag = TRUE; | ||
213 | |||
214 | /* Check if the file already exists */ | ||
215 | if (lstat (file_header->name, &statbuf) == 0) { | ||
216 | if ((archive_handle->flags & ARCHIVE_EXTRACT_UNCONDITIONAL) || (statbuf.st_mtime < file_header->mtime)) { | ||
217 | /* Remove file if flag set or its older than the file to be extracted */ | ||
218 | if (unlink(file_header->name) == -1) { | ||
219 | perror_msg_and_die("Couldnt remove old file"); | ||
220 | } | ||
221 | } else { | ||
222 | if (! archive_handle->flags & ARCHIVE_EXTRACT_QUIET) { | ||
223 | error_msg("%s not created: newer or same age file exists", file_header->name); | ||
224 | } | ||
225 | extract_flag = FALSE; | ||
226 | } | ||
227 | } | ||
228 | archive_handle->action_header(file_header); | ||
229 | } | ||
230 | |||
231 | archive_handle->action_header(file_header); | ||
232 | if (extract_flag) { | ||
233 | archive_handle->action_data(archive_handle); | ||
234 | } else { | ||
235 | data_skip(archive_handle); | ||
236 | } | ||
237 | archive_handle->offset += file_header->size; | ||
238 | } | ||
239 | 81 | ||
240 | return(EXIT_SUCCESS); | 82 | return(EXIT_SUCCESS); |
241 | } | 83 | } |