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 #include "archive_write_set_format_private.h" 47 48 static ssize_t archive_write_odc_data(struct archive_write *, 49 const void *buff, size_t s); 50 static int archive_write_odc_close(struct archive_write *); 51 static int archive_write_odc_free(struct archive_write *); 52 static int archive_write_odc_finish_entry(struct archive_write *); 53 static int archive_write_odc_header(struct archive_write *, 54 struct archive_entry *); 55 static int archive_write_odc_options(struct archive_write *, 56 const char *, const char *); 57 static int format_octal(int64_t, void *, int); 58 static int64_t format_octal_recursive(int64_t, char *, int); 59 static int write_header(struct archive_write *, struct archive_entry *); 60 61 struct cpio { 62 uint64_t entry_bytes_remaining; 63 64 int64_t ino_next; 65 66 struct { int64_t old; int new;} *ino_list; 67 size_t ino_list_size; 68 size_t ino_list_next; 69 70 struct archive_string_conv *opt_sconv; 71 struct archive_string_conv *sconv_default; 72 int init_default_conversion; 73 }; 74 75 #define c_magic_offset 0 76 #define c_magic_size 6 77 #define c_dev_offset 6 78 #define c_dev_size 6 79 #define c_ino_offset 12 80 #define c_ino_size 6 81 #define c_mode_offset 18 82 #define c_mode_size 6 83 #define c_uid_offset 24 84 #define c_uid_size 6 85 #define c_gid_offset 30 86 #define c_gid_size 6 87 #define c_nlink_offset 36 88 #define c_nlink_size 6 89 #define c_rdev_offset 42 90 #define c_rdev_size 6 91 #define c_mtime_offset 48 92 #define c_mtime_size 11 93 #define c_namesize_offset 59 94 #define c_namesize_size 6 95 #define c_filesize_offset 65 96 #define c_filesize_size 11 97 98 /* 99 * Set output format to 'cpio' format. 100 */ 101 int 102 archive_write_set_format_cpio_odc(struct archive *_a) 103 { 104 struct archive_write *a = (struct archive_write *)_a; 105 struct cpio *cpio; 106 107 archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, 108 ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_odc"); 109 110 /* If someone else was already registered, unregister them. */ 111 if (a->format_free != NULL) 112 (a->format_free)(a); 113 114 cpio = (struct cpio *)calloc(1, sizeof(*cpio)); 115 if (cpio == NULL) { 116 archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data"); 117 return (ARCHIVE_FATAL); 118 } 119 a->format_data = cpio; 120 a->format_name = "cpio"; 121 a->format_options = archive_write_odc_options; 122 a->format_write_header = archive_write_odc_header; 123 a->format_write_data = archive_write_odc_data; 124 a->format_finish_entry = archive_write_odc_finish_entry; 125 a->format_close = archive_write_odc_close; 126 a->format_free = archive_write_odc_free; 127 a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX; 128 a->archive.archive_format_name = "POSIX cpio"; 129 return (ARCHIVE_OK); 130 } 131 132 static int 133 archive_write_odc_options(struct archive_write *a, const char *key, 134 const char *val) 135 { 136 struct cpio *cpio = (struct cpio *)a->format_data; 137 int ret = ARCHIVE_FAILED; 138 139 if (strcmp(key, "hdrcharset") == 0) { 140 if (val == NULL || val[0] == 0) 141 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 142 "%s: hdrcharset option needs a character-set name", 143 a->format_name); 144 else { 145 cpio->opt_sconv = archive_string_conversion_to_charset( 146 &a->archive, val, 0); 147 if (cpio->opt_sconv != NULL) 148 ret = ARCHIVE_OK; 149 else 150 ret = ARCHIVE_FATAL; 151 } 152 return (ret); 153 } 154 155 /* Note: The "warn" return is just to inform the options 156 * supervisor that we didn't handle it. It will generate 157 * a suitable error if no one used this option. */ 158 return (ARCHIVE_WARN); 159 } 160 161 /* 162 * Ino values are as long as 64 bits on some systems; cpio format 163 * only allows 18 bits and relies on the ino values to identify hardlinked 164 * files. So, we can't merely "hash" the ino numbers since collisions 165 * would corrupt the archive. Instead, we generate synthetic ino values 166 * to store in the archive and maintain a map of original ino values to 167 * synthetic ones so we can preserve hardlink information. 168 * 169 * TODO: Make this more efficient. It's not as bad as it looks (most 170 * files don't have any hardlinks and we don't do any work here for those), 171 * but it wouldn't be hard to do better. 172 * 173 * TODO: Work with dev/ino pairs here instead of just ino values. 174 */ 175 static int 176 synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry) 177 { 178 int64_t ino = archive_entry_ino64(entry); 179 int ino_new; 180 size_t i; 181 182 /* 183 * If no index number was given, don't assign one. In 184 * particular, this handles the end-of-archive marker 185 * correctly by giving it a zero index value. (This is also 186 * why we start our synthetic index numbers with one below.) 187 */ 188 if (ino == 0) 189 return (0); 190 191 /* Don't store a mapping if we don't need to. */ 192 if (archive_entry_nlink(entry) < 2) { 193 return (int)(++cpio->ino_next); 194 } 195 196 /* Look up old ino; if we have it, this is a hardlink 197 * and we reuse the same value. */ 198 for (i = 0; i < cpio->ino_list_next; ++i) { 199 if (cpio->ino_list[i].old == ino) 200 return (cpio->ino_list[i].new); 201 } 202 203 /* Assign a new index number. */ 204 ino_new = (int)(++cpio->ino_next); 205 206 /* Ensure space for the new mapping. */ 207 if (cpio->ino_list_size <= cpio->ino_list_next) { 208 size_t newsize = cpio->ino_list_size < 512 209 ? 512 : cpio->ino_list_size * 2; 210 void *newlist = realloc(cpio->ino_list, 211 sizeof(cpio->ino_list[0]) * newsize); 212 if (newlist == NULL) 213 return (-1); 214 215 cpio->ino_list_size = newsize; 216 cpio->ino_list = newlist; 217 } 218 219 /* Record and return the new value. */ 220 cpio->ino_list[cpio->ino_list_next].old = ino; 221 cpio->ino_list[cpio->ino_list_next].new = ino_new; 222 ++cpio->ino_list_next; 223 return (ino_new); 224 } 225 226 227 static struct archive_string_conv * 228 get_sconv(struct archive_write *a) 229 { 230 struct cpio *cpio; 231 struct archive_string_conv *sconv; 232 233 cpio = (struct cpio *)a->format_data; 234 sconv = cpio->opt_sconv; 235 if (sconv == NULL) { 236 if (!cpio->init_default_conversion) { 237 cpio->sconv_default = 238 archive_string_default_conversion_for_write( 239 &(a->archive)); 240 cpio->init_default_conversion = 1; 241 } 242 sconv = cpio->sconv_default; 243 } 244 return (sconv); 245 } 246 247 static int 248 archive_write_odc_header(struct archive_write *a, struct archive_entry *entry) 249 { 250 const char *path; 251 size_t len; 252 253 if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) { 254 archive_set_error(&a->archive, -1, "Filetype required"); 255 return (ARCHIVE_FAILED); 256 } 257 258 if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0 259 && errno == ENOMEM) { 260 archive_set_error(&a->archive, ENOMEM, 261 "Can't allocate memory for Pathname"); 262 return (ARCHIVE_FATAL); 263 } 264 if (len == 0 || path == NULL || path[0] == '\0') { 265 archive_set_error(&a->archive, -1, "Pathname required"); 266 return (ARCHIVE_FAILED); 267 } 268 269 if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0) { 270 archive_set_error(&a->archive, -1, "Size required"); 271 return (ARCHIVE_FAILED); 272 } 273 return write_header(a, entry); 274 } 275 276 static int 277 write_header(struct archive_write *a, struct archive_entry *entry) 278 { 279 struct cpio *cpio; 280 const char *p, *path; 281 int pathlength, ret, ret_final; 282 int64_t ino; 283 char h[76]; 284 struct archive_string_conv *sconv; 285 struct archive_entry *entry_main; 286 size_t len; 287 288 cpio = (struct cpio *)a->format_data; 289 ret_final = ARCHIVE_OK; 290 sconv = get_sconv(a); 291 292 #if defined(_WIN32) && !defined(__CYGWIN__) 293 /* Make sure the path separators in pathname, hardlink and symlink 294 * are all slash '/', not the Windows path separator '\'. */ 295 entry_main = __la_win_entry_in_posix_pathseparator(entry); 296 if (entry_main == NULL) { 297 archive_set_error(&a->archive, ENOMEM, 298 "Can't allocate ustar data"); 299 return(ARCHIVE_FATAL); 300 } 301 if (entry != entry_main) 302 entry = entry_main; 303 else 304 entry_main = NULL; 305 #else 306 entry_main = NULL; 307 #endif 308 309 ret = archive_entry_pathname_l(entry, &path, &len, sconv); 310 if (ret != 0) { 311 if (errno == ENOMEM) { 312 archive_set_error(&a->archive, ENOMEM, 313 "Can't allocate memory for Pathname"); 314 ret_final = ARCHIVE_FATAL; 315 goto exit_write_header; 316 } 317 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 318 "Can't translate pathname '%s' to %s", 319 archive_entry_pathname(entry), 320 archive_string_conversion_charset_name(sconv)); 321 ret_final = ARCHIVE_WARN; 322 } 323 /* Include trailing null. */ 324 pathlength = (int)len + 1; 325 326 memset(h, 0, sizeof(h)); 327 format_octal(070707, h + c_magic_offset, c_magic_size); 328 format_octal(archive_entry_dev(entry), h + c_dev_offset, c_dev_size); 329 330 ino = synthesize_ino_value(cpio, entry); 331 if (ino < 0) { 332 archive_set_error(&a->archive, ENOMEM, 333 "No memory for ino translation table"); 334 ret_final = ARCHIVE_FATAL; 335 goto exit_write_header; 336 } else if (ino > 0777777) { 337 archive_set_error(&a->archive, ERANGE, 338 "Too many files for this cpio format"); 339 ret_final = ARCHIVE_FATAL; 340 goto exit_write_header; 341 } 342 format_octal(ino & 0777777, h + c_ino_offset, c_ino_size); 343 344 /* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */ 345 format_octal(archive_entry_mode(entry), h + c_mode_offset, c_mode_size); 346 format_octal(archive_entry_uid(entry), h + c_uid_offset, c_uid_size); 347 format_octal(archive_entry_gid(entry), h + c_gid_offset, c_gid_size); 348 format_octal(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size); 349 if (archive_entry_filetype(entry) == AE_IFBLK 350 || archive_entry_filetype(entry) == AE_IFCHR) 351 format_octal(archive_entry_rdev(entry), h + c_rdev_offset, c_rdev_size); 352 else 353 format_octal(0, h + c_rdev_offset, c_rdev_size); 354 format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size); 355 format_octal(pathlength, h + c_namesize_offset, c_namesize_size); 356 357 /* Non-regular files don't store bodies. */ 358 if (archive_entry_filetype(entry) != AE_IFREG) 359 archive_entry_set_size(entry, 0); 360 361 /* Symlinks get the link written as the body of the entry. */ 362 ret = archive_entry_symlink_l(entry, &p, &len, sconv); 363 if (ret != 0) { 364 if (errno == ENOMEM) { 365 archive_set_error(&a->archive, ENOMEM, 366 "Can't allocate memory for Linkname"); 367 ret_final = ARCHIVE_FATAL; 368 goto exit_write_header; 369 } 370 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 371 "Can't translate linkname '%s' to %s", 372 archive_entry_symlink(entry), 373 archive_string_conversion_charset_name(sconv)); 374 ret_final = ARCHIVE_WARN; 375 } 376 if (len > 0 && p != NULL && *p != '\0') 377 ret = format_octal(strlen(p), h + c_filesize_offset, 378 c_filesize_size); 379 else 380 ret = format_octal(archive_entry_size(entry), 381 h + c_filesize_offset, c_filesize_size); 382 if (ret) { 383 archive_set_error(&a->archive, ERANGE, 384 "File is too large for cpio format."); 385 ret_final = ARCHIVE_FAILED; 386 goto exit_write_header; 387 } 388 389 ret = __archive_write_output(a, h, sizeof(h)); 390 if (ret != ARCHIVE_OK) { 391 ret_final = ARCHIVE_FATAL; 392 goto exit_write_header; 393 } 394 395 ret = __archive_write_output(a, path, pathlength); 396 if (ret != ARCHIVE_OK) { 397 ret_final = ARCHIVE_FATAL; 398 goto exit_write_header; 399 } 400 401 cpio->entry_bytes_remaining = archive_entry_size(entry); 402 403 /* Write the symlink now. */ 404 if (p != NULL && *p != '\0') { 405 ret = __archive_write_output(a, p, strlen(p)); 406 if (ret != ARCHIVE_OK) { 407 ret_final = ARCHIVE_FATAL; 408 goto exit_write_header; 409 } 410 } 411 exit_write_header: 412 archive_entry_free(entry_main); 413 return (ret_final); 414 } 415 416 static ssize_t 417 archive_write_odc_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_odc_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_odc_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_odc_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