Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/archival/libunarchive/get_header_cpio.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_cpio.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* Copyright 2002 Laurence Anderson 2 3 * … … 4 5 */ 5 6 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <unistd.h> 10 #include <sys/sysmacros.h> /* major() and minor() */ 7 #include "libbb.h" 11 8 #include "unarchive.h" 12 #include "libbb.h"13 9 14 10 typedef struct hardlinks_s { 15 file_header_t *entry;11 char *name; 16 12 int inode; 17 13 struct hardlinks_s *next; … … 21 17 { 22 18 static hardlinks_t *saved_hardlinks = NULL; 23 static unsigned short pending_hardlinks = 0; 19 static unsigned pending_hardlinks = 0; 20 static int inode; 21 24 22 file_header_t *file_header = archive_handle->file_header; 25 23 char cpio_header[110]; 26 24 int namesize; 27 25 char dummy[16]; 28 int major, minor, nlink , inode;26 int major, minor, nlink; 29 27 30 28 if (pending_hardlinks) { /* Deal with any pending hardlinks */ 31 hardlinks_t *tmp; 32 hardlinks_t *oldtmp; 29 hardlinks_t *tmp, *oldtmp; 33 30 34 31 tmp = saved_hardlinks; 35 32 oldtmp = NULL; 36 33 34 file_header->link_target = file_header->name; 35 file_header->size = 0; 36 37 37 while (tmp) { 38 bb_error_msg_and_die("need to fix this\n"); 39 if (tmp->entry->link_name) { /* Found a hardlink ready to be extracted */ 40 file_header = tmp->entry; 41 if (oldtmp) { 42 oldtmp->next = tmp->next; /* Remove item from linked list */ 43 } else { 44 saved_hardlinks = tmp->next; 45 } 46 free(tmp); 38 if (tmp->inode != inode) { 39 tmp = tmp->next; 47 40 continue; 48 41 } 42 43 file_header->name = tmp->name; 44 45 if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { 46 archive_handle->action_data(archive_handle); 47 archive_handle->action_header(archive_handle->file_header); 48 } 49 50 pending_hardlinks--; 51 49 52 oldtmp = tmp; 50 53 tmp = tmp->next; 54 free(oldtmp->name); 55 free(oldtmp); 56 if (oldtmp == saved_hardlinks) 57 saved_hardlinks = tmp; 51 58 } 52 pending_hardlinks = 0; /* No more pending hardlinks, read next file entry */ 59 60 file_header->name = file_header->link_target; 61 62 if (pending_hardlinks > 1) { 63 bb_error_msg("error resolving hardlink: archive made by GNU cpio 2.0-2.2?"); 64 } 65 66 /* No more pending hardlinks, read next file entry */ 67 pending_hardlinks = 0; 53 68 } 54 69 … … 57 72 58 73 if (archive_xread_all_eof(archive_handle, (unsigned char*)cpio_header, 110) == 0) { 59 return (EXIT_FAILURE);74 return EXIT_FAILURE; 60 75 } 61 76 archive_handle->offset += 110; 62 77 63 if ((strncmp(&cpio_header[0], "07070", 5) != 0) || ((cpio_header[5] != '1') && (cpio_header[5] != '2'))) { 64 bb_error_msg_and_die("Unsupported cpio format, use newc or crc"); 78 if (strncmp(&cpio_header[0], "07070", 5) != 0 79 || (cpio_header[5] != '1' && cpio_header[5] != '2') 80 ) { 81 bb_error_msg_and_die("unsupported cpio format, use newc or crc"); 65 82 } 66 83 67 84 { 68 69 85 unsigned long tmpsize; 86 sscanf(cpio_header, "%6c%8x%8x%8x%8x%8x%8lx%8lx%16c%8x%8x%8x%8c", 70 87 dummy, &inode, (unsigned int*)&file_header->mode, 71 88 (unsigned int*)&file_header->uid, (unsigned int*)&file_header->gid, 72 89 &nlink, &file_header->mtime, &tmpsize, 73 90 dummy, &major, &minor, &namesize, dummy); 74 91 file_header->size = tmpsize; 75 92 } 76 93 77 file_header->name = (char *) xzalloc(namesize + 1); 78 archive_xread_all(archive_handle, file_header->name, namesize); /* Read in filename */ 94 free(file_header->name); 95 file_header->name = xzalloc(namesize + 1); 96 /* Read in filename */ 97 xread(archive_handle->src_fd, file_header->name, namesize); 79 98 archive_handle->offset += namesize; 80 99 … … 83 102 84 103 if (strcmp(file_header->name, "TRAILER!!!") == 0) { 85 printf("%d blocks\n", (int) (archive_handle->offset % 512 ? (archive_handle->offset / 512) + 1 : archive_handle->offset / 512)); /* Always round up */ 104 /* Always round up */ 105 printf("%d blocks\n", (int) (archive_handle->offset % 512 ? 106 archive_handle->offset / 512 + 1 : 107 archive_handle->offset / 512 108 )); 86 109 if (saved_hardlinks) { /* Bummer - we still have unresolved hardlinks */ 87 110 hardlinks_t *tmp = saved_hardlinks; 88 111 hardlinks_t *oldtmp = NULL; 89 112 while (tmp) { 90 bb_error_msg("%s not created: cannot resolve hardlink", tmp-> entry->name);113 bb_error_msg("%s not created: cannot resolve hardlink", tmp->name); 91 114 oldtmp = tmp; 92 115 tmp = tmp->next; 93 free (oldtmp->entry->name); 94 free (oldtmp->entry); 95 free (oldtmp); 116 free(oldtmp->name); 117 free(oldtmp); 96 118 } 97 119 saved_hardlinks = NULL; 98 120 pending_hardlinks = 0; 99 121 } 100 return (EXIT_FAILURE);122 return EXIT_FAILURE; 101 123 } 102 124 103 125 if (S_ISLNK(file_header->mode)) { 104 file_header->link_ name = (char *)xzalloc(file_header->size + 1);105 archive_xread_all(archive_handle, file_header->link_name, file_header->size);126 file_header->link_target = xzalloc(file_header->size + 1); 127 xread(archive_handle->src_fd, file_header->link_target, file_header->size); 106 128 archive_handle->offset += file_header->size; 107 129 file_header->size = 0; /* Stop possible seeks in future */ 108 130 } else { 109 file_header->link_ name= NULL;131 file_header->link_target = NULL; 110 132 } 111 133 if (nlink > 1 && !S_ISDIR(file_header->mode)) { … … 114 136 new->next = saved_hardlinks; 115 137 new->inode = inode; 116 new->entry = file_header; 138 /* name current allocated, freed later */ 139 new->name = file_header->name; 140 file_header->name = NULL; 117 141 saved_hardlinks = new; 118 return(EXIT_SUCCESS); // Skip this one 119 } else { /* Found the file with data in */ 120 hardlinks_t *tmp = saved_hardlinks; 121 pending_hardlinks = 1; 122 while (tmp) { 123 if (tmp->inode == inode) { 124 tmp->entry->link_name = bb_xstrdup(file_header->name); 125 nlink--; 126 } 127 tmp = tmp->next; 128 } 129 if (nlink > 1) { 130 bb_error_msg("error resolving hardlink: did you create the archive with GNU cpio 2.0-2.2?"); 131 } 142 return EXIT_SUCCESS; /* Skip this one */ 132 143 } 144 /* Found the file with data in */ 145 pending_hardlinks = nlink; 133 146 } 134 147 file_header->device = makedev(major, minor); … … 143 156 archive_handle->offset += file_header->size; 144 157 145 free(file_header->link_ name);158 free(file_header->link_target); 146 159 147 return (EXIT_SUCCESS);160 return EXIT_SUCCESS; 148 161 }
Note:
See TracChangeset
for help on using the changeset viewer.