Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/archival/libunarchive/get_header_ar.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 7  Line 7 
7  #include "libbb.h"  #include "libbb.h"
8  #include "unarchive.h"  #include "unarchive.h"
9    
10    static unsigned read_num(const char *str, int base)
11    {
12     /* This code works because
13     * on misformatted numbers bb_strtou returns all-ones */
14     int err = bb_strtou(str, NULL, base);
15     if (err == -1)
16     bb_error_msg_and_die("invalid ar header");
17     return err;
18    }
19    
20  char FAST_FUNC get_header_ar(archive_handle_t *archive_handle)  char FAST_FUNC get_header_ar(archive_handle_t *archive_handle)
21  {  {
  int err;  
22   file_header_t *typed = archive_handle->file_header;   file_header_t *typed = archive_handle->file_header;
23     unsigned size;
24   union {   union {
25   char raw[60];   char raw[60];
26   struct {   struct {
# Line 49  char FAST_FUNC get_header_ar(archive_han Line 59  char FAST_FUNC get_header_ar(archive_han
59   if (ar.formatted.magic[0] != '`' || ar.formatted.magic[1] != '\n')   if (ar.formatted.magic[0] != '`' || ar.formatted.magic[1] != '\n')
60   bb_error_msg_and_die("invalid ar header");   bb_error_msg_and_die("invalid ar header");
61    
62   /* FIXME: more thorough routine would be in order here */   /* FIXME: more thorough routine would be in order here
63   /* (we have something like that in tar) */   * (we have something like that in tar)
64   /* but for now we are lax. This code works because */   * but for now we are lax. */
65   /* on misformatted numbers bb_strtou returns all-ones */   typed->size = size = read_num(ar.formatted.size, 10);
  typed->mode = err = bb_strtou(ar.formatted.mode, NULL, 8);  
  if (err == -1) bb_error_msg_and_die("invalid ar header");  
  typed->mtime = err = bb_strtou(ar.formatted.date, NULL, 10);  
  if (err == -1) bb_error_msg_and_die("invalid ar header");  
  typed->uid = err = bb_strtou(ar.formatted.uid, NULL, 10);  
  if (err == -1) bb_error_msg_and_die("invalid ar header");  
  typed->gid = err = bb_strtou(ar.formatted.gid, NULL, 10);  
  if (err == -1) bb_error_msg_and_die("invalid ar header");  
  typed->size = err = bb_strtou(ar.formatted.size, NULL, 10);  
  if (err == -1) bb_error_msg_and_die("invalid ar header");  
66    
67   /* long filenames have '/' as the first character */   /* special filenames have '/' as the first character */
68   if (ar.formatted.name[0] == '/') {   if (ar.formatted.name[0] == '/') {
69     if (ar.formatted.name[1] == ' ') {
70     /* This is the index of symbols in the file for compilers */
71     data_skip(archive_handle);
72     archive_handle->offset += size;
73     return get_header_ar(archive_handle); /* Return next header */
74     }
75  #if ENABLE_FEATURE_AR_LONG_FILENAMES  #if ENABLE_FEATURE_AR_LONG_FILENAMES
  unsigned long_offset;  
   
76   if (ar.formatted.name[1] == '/') {   if (ar.formatted.name[1] == '/') {
77   /* If the second char is a '/' then this entries data section   /* If the second char is a '/' then this entries data section
78   * stores long filename for multiple entries, they are stored   * stores long filename for multiple entries, they are stored
79   * in static variable long_names for use in future entries */   * in static variable long_names for use in future entries
80   ar_long_name_size = typed->size;   */
81   ar_long_names = xmalloc(ar_long_name_size);   ar_long_name_size = size;
82   xread(archive_handle->src_fd, ar_long_names, ar_long_name_size);   free(ar_long_names);
83   archive_handle->offset += ar_long_name_size;   ar_long_names = xmalloc(size);
84   /* This ar entries data section only contained filenames for other records   xread(archive_handle->src_fd, ar_long_names, size);
85   * they are stored in the static ar_long_names for future reference */   archive_handle->offset += size;
86   return get_header_ar(archive_handle); /* Return next header */   /* Return next header */
87     return get_header_ar(archive_handle);
88   }   }
89    #else
90     bb_error_msg_and_die("long filenames not supported");
91    #endif
92     }
93     /* Only size is always present, the rest may be missing in
94     * long filename pseudo file. Thus we decode the rest
95     * after dealing with long filename pseudo file.
96     */
97     typed->mode = read_num(ar.formatted.mode, 8);
98     typed->mtime = read_num(ar.formatted.date, 10);
99     typed->uid = read_num(ar.formatted.uid, 10);
100     typed->gid = read_num(ar.formatted.gid, 10);
101    
102   if (ar.formatted.name[1] == ' ') {  #if ENABLE_FEATURE_AR_LONG_FILENAMES
103   /* This is the index of symbols in the file for compilers */   if (ar.formatted.name[0] == '/') {
104   data_skip(archive_handle);   unsigned long_offset;
  archive_handle->offset += typed->size;  
  return get_header_ar(archive_handle); /* Return next header */  
  }  
105    
106   /* The number after the '/' indicates the offset in the ar data section   /* The number after the '/' indicates the offset in the ar data section
107   * (saved in variable long_name) that conatains the real filename */   * (saved in ar_long_names) that conatains the real filename */
108   long_offset = atoi(&ar.formatted.name[1]);   long_offset = read_num(&ar.formatted.name[1], 10);
109   if (long_offset >= ar_long_name_size) {   if (long_offset >= ar_long_name_size) {
110   bb_error_msg_and_die("can't resolve long filename");   bb_error_msg_and_die("can't resolve long filename");
111   }   }
112   typed->name = xstrdup(ar_long_names + long_offset);   typed->name = xstrdup(ar_long_names + long_offset);
113  #else   } else
  bb_error_msg_and_die("long filenames not supported");  
114  #endif  #endif
115   } else {   {
116   /* short filenames */   /* short filenames */
117   typed->name = xstrndup(ar.formatted.name, 16);   typed->name = xstrndup(ar.formatted.name, 16);
118   }   }
# Line 109  char FAST_FUNC get_header_ar(archive_han Line 122  char FAST_FUNC get_header_ar(archive_han
122   if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) {   if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) {
123   archive_handle->action_header(typed);   archive_handle->action_header(typed);
124  #if ENABLE_DPKG || ENABLE_DPKG_DEB  #if ENABLE_DPKG || ENABLE_DPKG_DEB
125   if (archive_handle->sub_archive) {   if (archive_handle->dpkg__sub_archive) {
126   while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS)   while (archive_handle->dpkg__action_data_subarchive(archive_handle->dpkg__sub_archive) == EXIT_SUCCESS)
127   continue;   continue;
128   } else   } else
129  #endif  #endif

Legend:
Removed from v.983  
changed lines
  Added in v.984