Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/archival/libunarchive/get_header_ar.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/archival/libunarchive/get_header_ar.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* Copyright 2001 Glenn McGrath. 2 3 * … … 4 5 */ 5 6 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <unistd.h> 7 #include "libbb.h" 10 8 #include "unarchive.h" 11 #include "libbb.h"12 9 13 10 char get_header_ar(archive_handle_t *archive_handle) 14 11 { 12 int err; 15 13 file_header_t *typed = archive_handle->file_header; 16 14 union { … … 24 22 char size[10]; 25 23 char magic[2]; 26 } format ed;24 } formatted; 27 25 } ar; 28 #if def CONFIG_FEATURE_AR_LONG_FILENAMES26 #if ENABLE_FEATURE_AR_LONG_FILENAMES 29 27 static char *ar_long_names; 30 static unsigned intar_long_name_size;28 static unsigned ar_long_name_size; 31 29 #endif 32 30 33 /* dont use bb_xread as we want to handle the error ourself */31 /* dont use xread as we want to handle the error ourself */ 34 32 if (read(archive_handle->src_fd, ar.raw, 60) != 60) { 35 33 /* End Of File */ 36 return (EXIT_FAILURE);34 return EXIT_FAILURE; 37 35 } 38 36 … … 43 41 /* fix up the header, we started reading 1 byte too early */ 44 42 memmove(ar.raw, &ar.raw[1], 59); 45 ar.raw[59] = bb_xread_char(archive_handle->src_fd);43 ar.raw[59] = xread_char(archive_handle->src_fd); 46 44 archive_handle->offset++; 47 45 } … … 49 47 50 48 /* align the headers based on the header magic */ 51 if ((ar.formated.magic[0] != '`') || (ar.formated.magic[1] != '\n')) { 52 bb_error_msg_and_die("Invalid ar header"); 53 } 49 if (ar.formatted.magic[0] != '`' || ar.formatted.magic[1] != '\n') 50 bb_error_msg_and_die("invalid ar header"); 54 51 55 typed->mode = strtol(ar.formated.mode, NULL, 8); 56 typed->mtime = atoi(ar.formated.date); 57 typed->uid = atoi(ar.formated.uid); 58 typed->gid = atoi(ar.formated.gid); 59 typed->size = atoi(ar.formated.size); 52 /* FIXME: more thorough routine would be in order here */ 53 /* (we have something like that in tar) */ 54 /* but for now we are lax. This code works because */ 55 /* on misformatted numbers bb_strtou returns all-ones */ 56 typed->mode = err = bb_strtou(ar.formatted.mode, NULL, 8); 57 if (err == -1) bb_error_msg_and_die("invalid ar header"); 58 typed->mtime = err = bb_strtou(ar.formatted.date, NULL, 10); 59 if (err == -1) bb_error_msg_and_die("invalid ar header"); 60 typed->uid = err = bb_strtou(ar.formatted.uid, NULL, 10); 61 if (err == -1) bb_error_msg_and_die("invalid ar header"); 62 typed->gid = err = bb_strtou(ar.formatted.gid, NULL, 10); 63 if (err == -1) bb_error_msg_and_die("invalid ar header"); 64 typed->size = err = bb_strtou(ar.formatted.size, NULL, 10); 65 if (err == -1) bb_error_msg_and_die("invalid ar header"); 60 66 61 67 /* long filenames have '/' as the first character */ 62 if (ar.formated.name[0] == '/') { 63 #ifdef CONFIG_FEATURE_AR_LONG_FILENAMES 64 if (ar.formated.name[1] == '/') { 68 if (ar.formatted.name[0] == '/') { 69 #if ENABLE_FEATURE_AR_LONG_FILENAMES 70 unsigned long_offset; 71 72 if (ar.formatted.name[1] == '/') { 65 73 /* If the second char is a '/' then this entries data section 66 74 * stores long filename for multiple entries, they are stored … … 68 76 ar_long_name_size = typed->size; 69 77 ar_long_names = xmalloc(ar_long_name_size); 70 bb_xread_all(archive_handle->src_fd, ar_long_names, ar_long_name_size);78 xread(archive_handle->src_fd, ar_long_names, ar_long_name_size); 71 79 archive_handle->offset += ar_long_name_size; 72 80 /* This ar entries data section only contained filenames for other records 73 81 * they are stored in the static ar_long_names for future reference */ 74 return (get_header_ar(archive_handle)); /* Return next header */ 75 } else if (ar.formated.name[1] == ' ') { 82 return get_header_ar(archive_handle); /* Return next header */ 83 } 84 85 if (ar.formatted.name[1] == ' ') { 76 86 /* This is the index of symbols in the file for compilers */ 77 87 data_skip(archive_handle); 78 88 archive_handle->offset += typed->size; 79 return (get_header_ar(archive_handle)); /* Return next header */ 80 } else { 81 /* The number after the '/' indicates the offset in the ar data section 82 (saved in variable long_name) that conatains the real filename */ 83 const unsigned int long_offset = atoi(&ar.formated.name[1]); 84 if (long_offset >= ar_long_name_size) { 85 bb_error_msg_and_die("Cant resolve long filename"); 86 } 87 typed->name = bb_xstrdup(ar_long_names + long_offset); 89 return get_header_ar(archive_handle); /* Return next header */ 88 90 } 91 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 long_offset = atoi(&ar.formatted.name[1]); 95 if (long_offset >= ar_long_name_size) { 96 bb_error_msg_and_die("can't resolve long filename"); 97 } 98 typed->name = xstrdup(ar_long_names + long_offset); 89 99 #else 90 100 bb_error_msg_and_die("long filenames not supported"); … … 92 102 } else { 93 103 /* short filenames */ 94 typed->name = bb_xstrndup(ar.formated.name, 16);104 typed->name = xstrndup(ar.formatted.name, 16); 95 105 } 96 106 … … 100 110 archive_handle->action_header(typed); 101 111 if (archive_handle->sub_archive) { 102 while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS); 112 while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS) 113 /* repeat */; 103 114 } else { 104 115 archive_handle->action_data(archive_handle); … … 112 123 lseek(archive_handle->src_fd, archive_handle->offset, SEEK_SET); 113 124 114 return (EXIT_SUCCESS);125 return EXIT_SUCCESS; 115 126 }
Note:
See TracChangeset
for help on using the changeset viewer.