1 /*- 2 * Copyright (c) 2003-2007 Tim Kientzle 3 * Copyright (c) 2011-2012 Michihiro NAKAJIMA 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include "archive_platform.h" 28 __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio.c 201170 2009-12-29 06:34:23Z kientzle $"); 29 30 #ifdef HAVE_ERRNO_H 31 #include <errno.h> 32 #endif 33 #include <stdio.h> 34 #ifdef HAVE_STDLIB_H 35 #include <stdlib.h> 36 #endif 37 #ifdef HAVE_STRING_H 38 #include <string.h> 39 #endif 40 41 #include "archive.h" 42 #include "archive_entry.h" 43 #include "archive_entry_locale.h" 44 #include "archive_private.h" 45 #include "archive_write_private.h" 46 47 static ssize_t archive_write_cpio_data(struct archive_write *, 48 const void *buff, size_t s); 49 static int archive_write_cpio_close(struct archive_write *); 50 static int archive_write_cpio_free(struct archive_write *); 51 static int archive_write_cpio_finish_entry(struct archive_write *); 52 static int archive_write_cpio_header(struct archive_write *, 53 struct archive_entry *); 54 static int archive_write_cpio_options(struct archive_write *, 55 const char *, const char *); 56 static int format_octal(int64_t, void *, int); 57 static int64_t format_octal_recursive(int64_t, char *, int); 58 static int write_header(struct archive_write *, struct archive_entry *); 59 60 struct cpio { 61 uint64_t entry_bytes_remaining; 62 63 int64_t ino_next; 64 65 struct { int64_t old; int new;} *ino_list; 66 size_t ino_list_size; 67 size_t ino_list_next; 68 69 struct archive_string_conv *opt_sconv; 70 struct archive_string_conv *sconv_default; 71 int init_default_conversion; 72 }; 73 74 #define c_magic_offset 0 75 #define c_magic_size 6 76 #define c_dev_offset 6 77 #define c_dev_size 6 78 #define c_ino_offset 12 79 #define c_ino_size 6 80 #define c_mode_offset 18 81 #define c_mode_size 6 82 #define c_uid_offset 24 83 #define c_uid_size 6 84 #define c_gid_offset 30 85 #define c_gid_size 6 86 #define c_nlink_offset 36 87 #define c_nlink_size 6 88 #define c_rdev_offset 42 89 #define c_rdev_size 6 90 #define c_mtime_offset 48 91 #define c_mtime_size 11 92 #define c_namesize_offset 59 93 #define c_namesize_size 6 94 #define c_filesize_offset 65 95 #define c_filesize_size 11 96 97 /* 98 * Set output format to 'cpio' format. 99 */ 100 int 101 archive_write_set_format_cpio(struct archive *_a) 102 { 103 struct archive_write *a = (struct archive_write *)_a; 104 struct cpio *cpio; 105 106 archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, 107 ARCHIVE_STATE_NEW, "archive_write_set_format_cpio"); 108 109 /* If someone else was already registered, unregister them. */ 110 if (a->format_free != NULL) 111 (a->format_free)(a); 112 113 cpio = (struct cpio *)calloc(1, sizeof(*cpio)); 114 if (cpio == NULL) { 115 archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data"); 116 return (ARCHIVE_FATAL); 117 } 118 a->format_data = cpio; 119 a->format_name = "cpio"; 120 a->format_options = archive_write_cpio_options; 121 a->format_write_header = archive_write_cpio_header; 122 a->format_write_data = archive_write_cpio_data; 123 a->format_finish_entry = archive_write_cpio_finish_entry; 124 a->format_close = archive_write_cpio_close; 125 a->format_free = archive_write_cpio_free; 126 a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX; 127 a->archive.archive_format_name = "POSIX cpio"; 128 return (ARCHIVE_OK); 129 } 130 131 static int 132 archive_write_cpio_options(struct archive_write *a, const char *key, 133 const char *val) 134 { 135 struct cpio *cpio = (struct cpio *)a->format_data; 136 int ret = ARCHIVE_FAILED; 137 138 if (strcmp(key, "hdrcharset") == 0) { 139 if (val == NULL || val[0] == 0) 140 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 141 "%s: hdrcharset option needs a character-set name", 142 a->format_name); 143 else { 144 cpio->opt_sconv = archive_string_conversion_to_charset( 145 &a->archive, val, 0); 146 if (cpio->opt_sconv != NULL) 147 ret = ARCHIVE_OK; 148 else 149 ret = ARCHIVE_FATAL; 150 } 151 return (ret); 152 } 153 154 /* Note: The "warn" return is just to inform the options 155 * supervisor that we didn't handle it. It will generate 156 * a suitable error if no one used this option. */ 157 return (ARCHIVE_WARN); 158 } 159 160 /* 161 * Ino values are as long as 64 bits on some systems; cpio format 162 * only allows 18 bits and relies on the ino values to identify hardlinked 163 * files. So, we can't merely "hash" the ino numbers since collisions 164 * would corrupt the archive. Instead, we generate synthetic ino values 165 * to store in the archive and maintain a map of original ino values to 166 * synthetic ones so we can preserve hardlink information. 167 * 168 * TODO: Make this more efficient. It's not as bad as it looks (most 169 * files don't have any hardlinks and we don't do any work here for those), 170 * but it wouldn't be hard to do better. 171 * 172 * TODO: Work with dev/ino pairs here instead of just ino values. 173 */ 174 static int 175 synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry) 176 { 177 int64_t ino = archive_entry_ino64(entry); 178 int ino_new; 179 size_t i; 180 181 /* 182 * If no index number was given, don't assign one. In 183 * particular, this handles the end-of-archive marker 184 * correctly by giving it a zero index value. (This is also 185 * why we start our synthetic index numbers with one below.) 186 */ 187 if (ino == 0) 188 return (0); 189 190 /* Don't store a mapping if we don't need to. */ 191 if (archive_entry_nlink(entry) < 2) { 192 return (int)(++cpio->ino_next); 193 } 194 195 /* Look up old ino; if we have it, this is a hardlink 196 * and we reuse the same value. */ 197 for (i = 0; i < cpio->ino_list_next; ++i) { 198 if (cpio->ino_list[i].old == ino) 199 return (cpio->ino_list[i].new); 200 } 201 202 /* Assign a new index number. */ 203 ino_new = (int)(++cpio->ino_next); 204 205 /* Ensure space for the new mapping. */ 206 if (cpio->ino_list_size <= cpio->ino_list_next) { 207 size_t newsize = cpio->ino_list_size < 512 208 ? 512 : cpio->ino_list_size * 2; 209 void *newlist = realloc(cpio->ino_list, 210 sizeof(cpio->ino_list[0]) * newsize); 211 if (newlist == NULL) 212 return (-1); 213 214 cpio->ino_list_size = newsize; 215 cpio->ino_list = newlist; 216 } 217 218 /* Record and return the new value. */ 219 cpio->ino_list[cpio->ino_list_next].old = ino; 220 cpio->ino_list[cpio->ino_list_next].new = ino_new; 221 ++cpio->ino_list_next; 222 return (ino_new); 223 } 224 225 226 static struct archive_string_conv * 227 get_sconv(struct archive_write *a) 228 { 229 struct cpio *cpio; 230 struct archive_string_conv *sconv; 231 232 cpio = (struct cpio *)a->format_data; 233 sconv = cpio->opt_sconv; 234 if (sconv == NULL) { 235 if (!cpio->init_default_conversion) { 236 cpio->sconv_default = 237 archive_string_default_conversion_for_write( 238 &(a->archive)); 239 cpio->init_default_conversion = 1; 240 } 241 sconv = cpio->sconv_default; 242 } 243 return (sconv); 244 } 245 246 static int 247 archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry) 248 { 249 const char *path; 250 size_t len; 251 252 if (archive_entry_filetype(entry) == 0) { 253 archive_set_error(&a->archive, -1, "Filetype required"); 254 return (ARCHIVE_FAILED); 255 } 256 257 if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0 258 && errno == ENOMEM) { 259 archive_set_error(&a->archive, ENOMEM, 260 "Can't allocate memory for Pathname"); 261 return (ARCHIVE_FATAL); 262 } 263 if (len == 0 || path == NULL || path[0] == '\0') { 264 archive_set_error(&a->archive, -1, "Pathname required"); 265 return (ARCHIVE_FAILED); 266 } 267 268 if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0) { 269 archive_set_error(&a->archive, -1, "Size required"); 270 return (ARCHIVE_FAILED); 271 } 272 return write_header(a, entry); 273 } 274 275 static int 276 write_header(struct archive_write *a, struct archive_entry *entry) 277 { 278 struct cpio *cpio; 279 const char *p, *path; 280 int pathlength, ret, ret_final; 281 int64_t ino; 282 char h[76]; 283 struct archive_string_conv *sconv; 284 struct archive_entry *entry_main; 285 size_t len; 286 287 cpio = (struct cpio *)a->format_data; 288 ret_final = ARCHIVE_OK; 289 sconv = get_sconv(a); 290 291 #if defined(_WIN32) && !defined(__CYGWIN__) 292 /* Make sure the path separators in pathname, hardlink and symlink 293 * are all slash '/', not the Windows path separator '\'. */ 294 entry_main = __la_win_entry_in_posix_pathseparator(entry); 295 if (entry_main == NULL) { 296 archive_set_error(&a->archive, ENOMEM, 297 "Can't allocate ustar data"); 298 return(ARCHIVE_FATAL); 299 } 300 if (entry != entry_main) 301 entry = entry_main; 302 else 303 entry_main = NULL; 304 #else 305 entry_main = NULL; 306 #endif 307 308 ret = archive_entry_pathname_l(entry, &path, &len, sconv); 309 if (ret != 0) { 310 if (errno == ENOMEM) { 311 archive_set_error(&a->archive, ENOMEM, 312 "Can't allocate memory for Pathname"); 313 ret_final = ARCHIVE_FATAL; 314 goto exit_write_header; 315 } 316 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 317 "Can't translate pathname '%s' to %s", 318 archive_entry_pathname(entry), 319 archive_string_conversion_charset_name(sconv)); 320 ret_final = ARCHIVE_WARN; 321 } 322 /* Include trailing null. */ 323 pathlength = (int)len + 1; 324 325 memset(h, 0, sizeof(h)); 326 format_octal(070707, h + c_magic_offset, c_magic_size); 327 format_octal(archive_entry_dev(entry), h + c_dev_offset, c_dev_size); 328 329 ino = synthesize_ino_value(cpio, entry); 330 if (ino < 0) { 331 archive_set_error(&a->archive, ENOMEM, 332 "No memory for ino translation table"); 333 ret_final = ARCHIVE_FATAL; 334 goto exit_write_header; 335 } else if (ino > 0777777) { 336 archive_set_error(&a->archive, ERANGE, 337 "Too many files for this cpio format"); 338 ret_final = ARCHIVE_FATAL; 339 goto exit_write_header; 340 } 341 format_octal(ino & 0777777, h + c_ino_offset, c_ino_size); 342 343 /* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */ 344 format_octal(archive_entry_mode(entry), h + c_mode_offset, c_mode_size); 345 format_octal(archive_entry_uid(entry), h + c_uid_offset, c_uid_size); 346 format_octal(archive_entry_gid(entry), h + c_gid_offset, c_gid_size); 347 format_octal(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size); 348 if (archive_entry_filetype(entry) == AE_IFBLK 349 || archive_entry_filetype(entry) == AE_IFCHR) 350 format_octal(archive_entry_dev(entry), h + c_rdev_offset, c_rdev_size); 351 else 352 format_octal(0, h + c_rdev_offset, c_rdev_size); 353 format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size); 354 format_octal(pathlength, h + c_namesize_offset, c_namesize_size); 355 356 /* Non-regular files don't store bodies. */ 357 if (archive_entry_filetype(entry) != AE_IFREG) 358 archive_entry_set_size(entry, 0); 359 360 /* Symlinks get the link written as the body of the entry. */ 361 ret = archive_entry_symlink_l(entry, &p, &len, sconv); 362 if (ret != 0) { 363 if (errno == ENOMEM) { 364 archive_set_error(&a->archive, ENOMEM, 365 "Can't allocate memory for Linkname"); 366 ret_final = ARCHIVE_FATAL; 367 goto exit_write_header; 368 } 369 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 370 "Can't translate linkname '%s' to %s", 371 archive_entry_symlink(entry), 372 archive_string_conversion_charset_name(sconv)); 373 ret_final = ARCHIVE_WARN; 374 } 375 if (len > 0 && p != NULL && *p != '\0') 376 ret = format_octal(strlen(p), h + c_filesize_offset, 377 c_filesize_size); 378 else 379 ret = format_octal(archive_entry_size(entry), 380 h + c_filesize_offset, c_filesize_size); 381 if (ret) { 382 archive_set_error(&a->archive, ERANGE, 383 "File is too large for cpio format."); 384 ret_final = ARCHIVE_FAILED; 385 goto exit_write_header; 386 } 387 388 ret = __archive_write_output(a, h, sizeof(h)); 389 if (ret != ARCHIVE_OK) { 390 ret_final = ARCHIVE_FATAL; 391 goto exit_write_header; 392 } 393 394 ret = __archive_write_output(a, path, pathlength); 395 if (ret != ARCHIVE_OK) { 396 ret_final = ARCHIVE_FATAL; 397 goto exit_write_header; 398 } 399 400 cpio->entry_bytes_remaining = archive_entry_size(entry); 401 402 /* Write the symlink now. */ 403 if (p != NULL && *p != '\0') { 404 ret = __archive_write_output(a, p, strlen(p)); 405 if (ret != ARCHIVE_OK) { 406 ret_final = ARCHIVE_FATAL; 407 goto exit_write_header; 408 } 409 } 410 exit_write_header: 411 if (entry_main) 412 archive_entry_free(entry_main); 413 return (ret_final); 414 } 415 416 static ssize_t 417 archive_write_cpio_data(struct archive_write *a, const void *buff, size_t s) 418 { 419 struct cpio *cpio; 420 int ret; 421 422 cpio = (struct cpio *)a->format_data; 423 if (s > cpio->entry_bytes_remaining) 424 s = (size_t)cpio->entry_bytes_remaining; 425 426 ret = __archive_write_output(a, buff, s); 427 cpio->entry_bytes_remaining -= s; 428 if (ret >= 0) 429 return (s); 430 else 431 return (ret); 432 } 433 434 /* 435 * Format a number into the specified field. 436 */ 437 static int 438 format_octal(int64_t v, void *p, int digits) 439 { 440 int64_t max; 441 int ret; 442 443 max = (((int64_t)1) << (digits * 3)) - 1; 444 if (v >= 0 && v <= max) { 445 format_octal_recursive(v, (char *)p, digits); 446 ret = 0; 447 } else { 448 format_octal_recursive(max, (char *)p, digits); 449 ret = -1; 450 } 451 return (ret); 452 } 453 454 static int64_t 455 format_octal_recursive(int64_t v, char *p, int s) 456 { 457 if (s == 0) 458 return (v); 459 v = format_octal_recursive(v, p+1, s-1); 460 *p = '0' + ((char)v & 7); 461 return (v >> 3); 462 } 463 464 static int 465 archive_write_cpio_close(struct archive_write *a) 466 { 467 int er; 468 struct archive_entry *trailer; 469 470 trailer = archive_entry_new2(NULL); 471 /* nlink = 1 here for GNU cpio compat. */ 472 archive_entry_set_nlink(trailer, 1); 473 archive_entry_set_size(trailer, 0); 474 archive_entry_set_pathname(trailer, "TRAILER!!!"); 475 er = write_header(a, trailer); 476 archive_entry_free(trailer); 477 return (er); 478 } 479 480 static int 481 archive_write_cpio_free(struct archive_write *a) 482 { 483 struct cpio *cpio; 484 485 cpio = (struct cpio *)a->format_data; 486 free(cpio->ino_list); 487 free(cpio); 488 a->format_data = NULL; 489 return (ARCHIVE_OK); 490 } 491 492 static int 493 archive_write_cpio_finish_entry(struct archive_write *a) 494 { 495 struct cpio *cpio; 496 497 cpio = (struct cpio *)a->format_data; 498 return (__archive_write_nulls(a, 499 (size_t)cpio->entry_bytes_remaining)); 500 } 501