25 |
int major, minor, nlink, mode, inode; |
int major, minor, nlink, mode, inode; |
26 |
unsigned size, uid, gid, mtime; |
unsigned size, uid, gid, mtime; |
27 |
|
|
|
#define hardlinks_to_create (*(hardlinks_t **)(&archive_handle->ah_priv[0])) |
|
|
#define created_hardlinks (*(hardlinks_t **)(&archive_handle->ah_priv[1])) |
|
|
#define block_count (archive_handle->ah_priv[2]) |
|
|
// if (!archive_handle->ah_priv_inited) { |
|
|
// archive_handle->ah_priv_inited = 1; |
|
|
// hardlinks_to_create = NULL; |
|
|
// created_hardlinks = NULL; |
|
|
// } |
|
|
|
|
28 |
/* There can be padding before archive header */ |
/* There can be padding before archive header */ |
29 |
data_align(archive_handle, 4); |
data_align(archive_handle, 4); |
30 |
|
|
61 |
file_header->name = xzalloc(namesize + 1); |
file_header->name = xzalloc(namesize + 1); |
62 |
/* Read in filename */ |
/* Read in filename */ |
63 |
xread(archive_handle->src_fd, file_header->name, namesize); |
xread(archive_handle->src_fd, file_header->name, namesize); |
64 |
|
if (file_header->name[0] == '/') { |
65 |
|
/* Testcase: echo /etc/hosts | cpio -pvd /tmp |
66 |
|
* Without this code, it tries to unpack /etc/hosts |
67 |
|
* into "/etc/hosts", not "etc/hosts". |
68 |
|
*/ |
69 |
|
char *p = file_header->name; |
70 |
|
do p++; while (*p == '/'); |
71 |
|
overlapping_strcpy(file_header->name, p); |
72 |
|
} |
73 |
archive_handle->offset += namesize; |
archive_handle->offset += namesize; |
74 |
|
|
75 |
/* Update offset amount and skip padding before file contents */ |
/* Update offset amount and skip padding before file contents */ |
77 |
|
|
78 |
if (strcmp(file_header->name, "TRAILER!!!") == 0) { |
if (strcmp(file_header->name, "TRAILER!!!") == 0) { |
79 |
/* Always round up. ">> 9" divides by 512 */ |
/* Always round up. ">> 9" divides by 512 */ |
80 |
block_count = (void*)(ptrdiff_t) ((archive_handle->offset + 511) >> 9); |
archive_handle->cpio__blocks = (uoff_t)(archive_handle->offset + 511) >> 9; |
81 |
goto create_hardlinks; |
goto create_hardlinks; |
82 |
} |
} |
83 |
|
|
103 |
strcpy(new->name, file_header->name); |
strcpy(new->name, file_header->name); |
104 |
/* Put file on a linked list for later */ |
/* Put file on a linked list for later */ |
105 |
if (size == 0) { |
if (size == 0) { |
106 |
new->next = hardlinks_to_create; |
new->next = archive_handle->cpio__hardlinks_to_create; |
107 |
hardlinks_to_create = new; |
archive_handle->cpio__hardlinks_to_create = new; |
108 |
return EXIT_SUCCESS; /* Skip this one */ |
return EXIT_SUCCESS; /* Skip this one */ |
109 |
/* TODO: this breaks cpio -t (it does not show hardlinks) */ |
/* TODO: this breaks cpio -t (it does not show hardlinks) */ |
110 |
} |
} |
111 |
new->next = created_hardlinks; |
new->next = archive_handle->cpio__created_hardlinks; |
112 |
created_hardlinks = new; |
archive_handle->cpio__created_hardlinks = new; |
113 |
} |
} |
114 |
file_header->device = makedev(major, minor); |
file_header->device = makedev(major, minor); |
115 |
|
|
116 |
if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { |
if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { |
117 |
archive_handle->action_data(archive_handle); |
archive_handle->action_data(archive_handle); |
118 |
|
//TODO: run "echo /etc/hosts | cpio -pv /tmp" twice. On 2nd run: |
119 |
|
//cpio: etc/hosts not created: newer or same age file exists |
120 |
|
//etc/hosts <-- should NOT show it |
121 |
|
//2 blocks <-- should say "0 blocks" |
122 |
archive_handle->action_header(file_header); |
archive_handle->action_header(file_header); |
123 |
} else { |
} else { |
124 |
data_skip(archive_handle); |
data_skip(archive_handle); |
137 |
free(file_header->link_target); |
free(file_header->link_target); |
138 |
free(file_header->name); |
free(file_header->name); |
139 |
|
|
140 |
while (hardlinks_to_create) { |
while (archive_handle->cpio__hardlinks_to_create) { |
141 |
hardlinks_t *cur; |
hardlinks_t *cur; |
142 |
hardlinks_t *make_me = hardlinks_to_create; |
hardlinks_t *make_me = archive_handle->cpio__hardlinks_to_create; |
143 |
|
|
144 |
hardlinks_to_create = make_me->next; |
archive_handle->cpio__hardlinks_to_create = make_me->next; |
145 |
|
|
146 |
memset(file_header, 0, sizeof(*file_header)); |
memset(file_header, 0, sizeof(*file_header)); |
147 |
file_header->mtime = make_me->mtime; |
file_header->mtime = make_me->mtime; |
153 |
/*file_header->link_target = NULL;*/ |
/*file_header->link_target = NULL;*/ |
154 |
|
|
155 |
/* Try to find a file we are hardlinked to */ |
/* Try to find a file we are hardlinked to */ |
156 |
cur = created_hardlinks; |
cur = archive_handle->cpio__created_hardlinks; |
157 |
while (cur) { |
while (cur) { |
158 |
/* TODO: must match maj/min too! */ |
/* TODO: must match maj/min too! */ |
159 |
if (cur->inode == make_me->inode) { |
if (cur->inode == make_me->inode) { |
171 |
if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) |
if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) |
172 |
archive_handle->action_data(archive_handle); |
archive_handle->action_data(archive_handle); |
173 |
/* Move to the list of created hardlinked files */ |
/* Move to the list of created hardlinked files */ |
174 |
make_me->next = created_hardlinks; |
make_me->next = archive_handle->cpio__created_hardlinks; |
175 |
created_hardlinks = make_me; |
archive_handle->cpio__created_hardlinks = make_me; |
176 |
next_link: ; |
next_link: ; |
177 |
} |
} |
178 |
|
|
179 |
while (created_hardlinks) { |
while (archive_handle->cpio__created_hardlinks) { |
180 |
hardlinks_t *p = created_hardlinks; |
hardlinks_t *p = archive_handle->cpio__created_hardlinks; |
181 |
created_hardlinks = p->next; |
archive_handle->cpio__created_hardlinks = p->next; |
182 |
free(p); |
free(p); |
183 |
} |
} |
184 |
|
|