Changeset 67123 in vbox for trunk/src/VBox/Runtime/common/zip
- Timestamp:
- May 28, 2017 12:19:53 PM (8 years ago)
- Location:
- trunk/src/VBox/Runtime/common/zip
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/zip/pkzipvfs.cpp
r67116 r67123 1240 1240 rtZipPkzipFss_Next, 1241 1241 NULL, 1242 NULL, 1242 1243 RTVFSFSSTREAMOPS_VERSION 1243 1244 }; -
trunk/src/VBox/Runtime/common/zip/tar.h
r67116 r67123 93 93 * @remarks The terminator character is not part of the field. */ 94 94 #define RTZIPTAR_USTAR_VERSION "00" 95 96 /** The GNU magic + version value. */ 97 #define RTZIPTAR_USTAR_GNU_MAGIC "ustar " 95 98 96 99 … … 136 139 AssertCompileMemberOffset(RTZIPTARHDRPOSIX, prefix, 345); 137 140 141 /** 142 * GNU sparse data segment descriptor entry. 143 */ 144 typedef struct RTZIPTARGNUSPARSE 145 { 146 char offset[12]; /**< Absolute offset relative to the start of the file. */ 147 char numbytes[12]; 148 } RTZIPTARGNUSPARSE; 149 AssertCompileSize(RTZIPTARGNUSPARSE, 24); 150 AssertCompileMemberOffset(RTZIPTARGNUSPARSE, offset, 0); 151 AssertCompileMemberOffset(RTZIPTARGNUSPARSE, numbytes, 12); 138 152 139 153 /** … … 161 175 char longnames[4]; 162 176 char unused[1]; 163 struct 164 { 165 char offset[12]; 166 char numbytes[12]; 167 } sparse[4]; 168 char isextended; 177 RTZIPTARGNUSPARSE sparse[4]; 178 char isextended; /**< More headers about sparse stuff if binary value 1. */ 169 179 char realsize[12]; 170 180 char unused2[17]; … … 197 207 198 208 /** 209 * GNU sparse header. 210 */ 211 typedef struct RTZIPTARHDRGNUSPARSE 212 { 213 RTZIPTARGNUSPARSE sp[21]; 214 char isextended; 215 char unused[7]; 216 } RTZIPTARHDRGNUSPARSE; 217 AssertCompileSize(RTZIPTARHDRGNUSPARSE, 512); 218 AssertCompileMemberOffset(RTZIPTARHDRGNUSPARSE, sp, 0); 219 AssertCompileMemberOffset(RTZIPTARHDRGNUSPARSE, isextended, 504); 220 AssertCompileMemberOffset(RTZIPTARHDRGNUSPARSE, unused, 505); 221 222 223 /** 199 224 * The bits common to posix and GNU. 200 225 */ … … 218 243 char not_common[155+12]; 219 244 } RTZIPTARHDRCOMMON; 245 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, name, RTZIPTARHDRPOSIX, name); 246 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, mode, RTZIPTARHDRPOSIX, mode); 247 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, uid, RTZIPTARHDRPOSIX, uid); 248 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, gid, RTZIPTARHDRPOSIX, gid); 249 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, size, RTZIPTARHDRPOSIX, size); 250 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, mtime, RTZIPTARHDRPOSIX, mtime); 251 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, chksum, RTZIPTARHDRPOSIX, chksum); 252 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, typeflag, RTZIPTARHDRPOSIX, typeflag); 253 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, linkname, RTZIPTARHDRPOSIX, linkname); 254 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, magic, RTZIPTARHDRPOSIX, magic); 255 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, version, RTZIPTARHDRPOSIX, version); 256 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, uname, RTZIPTARHDRPOSIX, uname); 257 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, gname, RTZIPTARHDRPOSIX, gname); 258 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, devmajor, RTZIPTARHDRPOSIX, devmajor); 259 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, devminor, RTZIPTARHDRPOSIX, devminor); 260 261 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, name, RTZIPTARHDRGNU, name); 262 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, mode, RTZIPTARHDRGNU, mode); 263 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, uid, RTZIPTARHDRGNU, uid); 264 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, gid, RTZIPTARHDRGNU, gid); 265 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, size, RTZIPTARHDRGNU, size); 266 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, mtime, RTZIPTARHDRGNU, mtime); 267 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, chksum, RTZIPTARHDRGNU, chksum); 268 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, typeflag, RTZIPTARHDRGNU, typeflag); 269 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, linkname, RTZIPTARHDRGNU, linkname); 270 AssertCompileMembersAtSameOffset( RTZIPTARHDRCOMMON, magic, RTZIPTARHDRGNU, magic); 271 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, uname, RTZIPTARHDRGNU, uname); 272 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, gname, RTZIPTARHDRGNU, gname); 273 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, devmajor, RTZIPTARHDRGNU, devmajor); 274 AssertCompileMembersSameSizeAndOffset(RTZIPTARHDRCOMMON, devminor, RTZIPTARHDRGNU, devminor); 275 220 276 221 277 -
trunk/src/VBox/Runtime/common/zip/tarvfs.cpp
r67116 r67123 1475 1475 rtZipTarFss_Next, 1476 1476 NULL, 1477 NULL, 1477 1478 RTVFSFSSTREAMOPS_VERSION 1478 1479 }; -
trunk/src/VBox/Runtime/common/zip/tarvfswriter.cpp
r67116 r67123 34 34 #include <iprt/assert.h> 35 35 #include <iprt/err.h> 36 #include <iprt/file.h> 36 37 #include <iprt/mem.h> 37 38 #include <iprt/path.h> … … 39 40 #include <iprt/vfs.h> 40 41 #include <iprt/vfslowlevel.h> 42 #include <iprt/zero.h> 41 43 42 44 #include "tar.h" … … 54 56 RTVFSIOSTREAM hVfsIos; 55 57 58 /** The TAR format. */ 59 RTZIPTARFORMAT enmFormat; 56 60 /** Set if we've encountered a fatal error. */ 57 61 int rcFatal; … … 85 89 8 /*uBase*/, -1 /*cchWidth*/, sizeof(pHdr->Common.chksum) - 1, RTSTR_F_ZEROPAD); 86 90 AssertRCReturn(rc, VERR_TAR_NUM_VALUE_TOO_LARGE); 91 return VINF_SUCCESS; 92 } 93 94 95 96 /** 97 * Formats a 12 character wide file offset or size field. 98 * 99 * This is mainly used for RTZIPTARHDR::Common.size, but also for formatting the 100 * sparse map. 101 * 102 * @returns IPRT status code. 103 * @param pach12Field The 12 character wide destination field. 104 * @param off The offset to set. 105 */ 106 static int rtZipTarFssWriter_FormatOffset(char pach12Field[12], uint64_t off) 107 { 108 /* 109 * Is the size small enough for the standard octal string encoding? 110 * 111 * Note! We could actually use the terminator character as well if we liked, 112 * but let not do that as it's easier to test this way. 113 */ 114 if (off < _4G * 2U) 115 { 116 int rc = RTStrFormatU64(pach12Field, 12, off, 8 /*uBase*/, -1 /*cchWidth*/, 12 - 1, RTSTR_F_ZEROPAD); 117 AssertRCReturn(rc, rc); 118 } 119 /* 120 * No, use the base 256 extension. Set the highest bit of the left most 121 * character. We don't deal with negatives here, cause the size have to 122 * be greater than zero. 123 * 124 * Note! The base-256 extension are never used by gtar or libarchive 125 * with the "ustar \0" format version, only the later 126 * "ustar\000" version. However, this shouldn't cause much 127 * trouble as they are not picky about what they read. 128 */ 129 else 130 { 131 size_t cchField = 12 - 1; 132 unsigned char *puchField = (unsigned char *)pach12Field; 133 puchField[0] = 0x80; 134 do 135 { 136 puchField[cchField--] = off & 0xff; 137 off >>= 8; 138 } while (cchField); 139 } 140 87 141 return VINF_SUCCESS; 88 142 } … … 156 210 157 211 /* 158 * Is the size small enough for the standard octal string encoding? 159 * 160 * Note! We could actually use the terminator character as well if we liked, 161 * but let not do that as it's easier to test this way. 162 */ 163 uint64_t cbObject = pObjInfo->cbObject; 164 if (cbObject < _4G * 2U) 165 { 166 rc = RTStrFormatU64(pThis->aHdrs[0].Common.size, sizeof(pThis->aHdrs[0].Common.size), cbObject, 167 8 /*uBase*/, -1 /*cchWidth*/, sizeof(pThis->aHdrs[0].Common.size) - 1, RTSTR_F_ZEROPAD); 168 AssertRCReturn(rc, rc); 169 } 170 /* 171 * No, use the base 256 extension. Set the highest bit of the left most 172 * character. We don't deal with negatives here, cause the size have to 173 * be greater than zero. 174 * 175 * Note! The base-256 extension are never used by gtar or libarchive 176 * with the "ustar \0" format version, only the later 177 * "ustar\000" version. However, this shouldn't cause much 178 * trouble as they are not picky about what they read. 179 */ 180 else 181 { 182 size_t cchField = sizeof(pThis->aHdrs[0].Common.size) - 1; 183 unsigned char *puchField = (unsigned char*)pThis->aHdrs[0].Common.size; 184 puchField[0] = 0x80; 185 do 186 { 187 puchField[cchField--] = cbObject & 0xff; 188 cbObject >>= 8; 189 } while (cchField); 190 } 212 * The file size. 213 */ 214 rc = rtZipTarFssWriter_FormatOffset(pThis->aHdrs[0].Common.size, pObjInfo->cbObject); 215 AssertRCReturn(rc, rc); 191 216 192 217 /* … … 271 296 PCRTFSOBJINFO pObjInfo, const char *pszOwnerNm, const char *pszGroupNm) 272 297 { 273 RT_NOREF(fFlags);274 275 298 /* 276 299 * Append the header. … … 279 302 if (RT_SUCCESS(rc)) 280 303 { 304 RTFOFF const offHdr = fFlags & RTVFSFSSTRM_ADD_F_STREAM ? RTVfsIoStrmTell(pThis->hVfsIos) : RTFOFF_MAX; 281 305 rc = RTVfsIoStrmWrite(pThis->hVfsIos, pThis->aHdrs, pThis->cHdrs * sizeof(pThis->aHdrs[0]), true /*fBlocking*/, NULL); 282 306 if (RT_SUCCESS(rc)) … … 296 320 if (!pbBuf) 297 321 { 298 cbBuf = sizeof(pThis->aHdrs) ;299 pbBuf = (uint8_t *)&pThis->aHdrs[ 0];322 cbBuf = sizeof(pThis->aHdrs) - sizeof(pThis->aHdrs[0]); 323 pbBuf = (uint8_t *)&pThis->aHdrs[1]; 300 324 } 301 325 } … … 304 328 * Copy the bytes. Padding the last buffer to a multiple of 512. 305 329 */ 306 uint64_t cbLeft = pObjInfo->cbObject; 307 while (cbLeft > 0 && RT_SUCCESS(rc)) 330 if (!(fFlags & RTVFSFSSTRM_ADD_F_STREAM)) 308 331 { 309 size_t cbRead = cbLeft > cbBuf ? cbBuf : (size_t)cbBuf; 310 rc = RTVfsIoStrmRead(hVfsIos, pbBuf, cbRead, true /*fBlocking*/, NULL); 311 if (RT_FAILURE(rc)) 332 uint64_t cbLeft = pObjInfo->cbObject; 333 while (cbLeft > 0) 334 { 335 size_t cbRead = cbLeft > cbBuf ? cbBuf : (size_t)cbBuf; 336 rc = RTVfsIoStrmRead(hVfsIos, pbBuf, cbRead, true /*fBlocking*/, NULL); 337 if (RT_FAILURE(rc)) 338 break; 339 340 size_t cbToWrite = cbRead; 341 if (cbRead & (sizeof(RTZIPTARHDR) - 1)) 342 { 343 size_t cbToZero = sizeof(RTZIPTARHDR) - (cbRead & (sizeof(RTZIPTARHDR) - 1)); 344 memset(&pbBuf[cbRead], 0, cbToZero); 345 cbToWrite += cbToZero; 346 } 347 348 rc = RTVfsIoStrmWrite(pThis->hVfsIos, pbBuf, cbToWrite, true /*fBlocking*/, NULL); 349 if (RT_FAILURE(rc)) 350 break; 351 pThis->cbWritten += cbToWrite; 352 cbLeft -= cbRead; 353 } 354 } 355 /* 356 * Same as above, only here we don't know the exact input length. 357 */ 358 else 359 { 360 uint64_t cbReadTotal = 0; 361 for (;;) 362 { 363 size_t cbRead = 0; 364 int rc2 = rc = RTVfsIoStrmRead(hVfsIos, pbBuf, cbBuf, true /*fBlocking*/, &cbRead); 365 if (RT_SUCCESS(rc)) 366 { 367 cbReadTotal += cbRead; 368 rc = RTVfsIoStrmWrite(pThis->hVfsIos, pbBuf, cbRead, true /*fBlocking*/, NULL); 369 if (RT_SUCCESS(rc)) 370 { 371 pThis->cbWritten += cbRead; 372 if (rc2 != VINF_EOF) 373 continue; 374 } 375 } 376 Assert(rc != VERR_EOF /* expecting VINF_EOF! */); 312 377 break; 313 314 size_t cbToWrite = cbRead; 315 if (cbRead & (sizeof(RTZIPTARHDR) - 1)) 378 } 379 380 /* Do the zero padding. */ 381 if ((cbReadTotal & (sizeof(RTZIPTARHDR) - 1)) && RT_SUCCESS(rc)) 316 382 { 317 size_t cbToZero = sizeof(RTZIPTARHDR) - (cbRead & (sizeof(RTZIPTARHDR) - 1)); 318 memset(&pbBuf[cbRead], 0, cbToZero); 319 cbToWrite += cbToZero; 383 size_t cbToZero = sizeof(RTZIPTARHDR) - (cbReadTotal & (sizeof(RTZIPTARHDR) - 1)); 384 rc = RTVfsIoStrmWrite(pThis->hVfsIos, g_abRTZero4K, cbToZero, true /*fBlocking*/, NULL); 385 if (RT_SUCCESS(rc)) 386 pThis->cbWritten += cbToZero; 320 387 } 321 388 322 rc = RTVfsIoStrmWrite(pThis->hVfsIos, pbBuf, cbToWrite, true /*fBlocking*/, NULL); 323 if (RT_FAILURE(rc)) 324 break; 325 pThis->cbWritten += cbToWrite; 326 cbLeft -= cbRead; 389 /* 390 * Update the header. We ASSUME that aHdr[0] is unmodified 391 * from before the data pumping above and just update the size. 392 */ 393 if (RT_SUCCESS(rc) && (RTFOFF)cbReadTotal != pObjInfo->cbObject) 394 { 395 RTVFSFILE hVfsFile = RTVfsIoStrmToFile(pThis->hVfsIos); 396 if (hVfsFile != NIL_RTVFSFILE) 397 { 398 RTFOFF offRestore = RTVfsFileTell(hVfsFile); 399 if (offRestore >= 0) 400 { 401 rc = rtZipTarFssWriter_FormatOffset(pThis->aHdrs[0].Common.size, cbReadTotal); 402 if (RT_SUCCESS(rc)) 403 rc = rtZipTarFssWriter_ChecksumHdr(&pThis->aHdrs[0]); 404 if (RT_SUCCESS(rc)) 405 { 406 rc = RTVfsFileWriteAt(hVfsFile, offHdr, &pThis->aHdrs[0], sizeof(pThis->aHdrs[0]), NULL); 407 if (RT_SUCCESS(rc)) 408 rc = RTVfsFileSeek(hVfsFile, offRestore, RTFILE_SEEK_BEGIN, NULL); 409 } 410 } 411 else 412 rc = (int)offRestore; 413 RTVfsFileRelease(hVfsFile); 414 } 415 else 416 AssertFailedStmt(rc = VERR_NOT_A_FILE); 417 } 327 418 } 328 419 … … 442 533 pThis->hVfsIos = NIL_RTVFSIOSTREAM; 443 534 444 /** @todo investigate zero end records. */445 446 535 return VINF_SUCCESS; 447 536 } … … 466 555 { 467 556 PRTZIPTARFSSTREAMWRITER pThis = (PRTZIPTARFSSTREAMWRITER)pvThis; 468 RT_NOREF(pThis, pszPath, hVfsObj, fFlags);469 557 470 558 /* … … 517 605 } 518 606 607 608 /** 609 * @interface_method_impl{RTVFSFSSTREAMOPS,pfnEnd} 610 */ 611 static DECLCALLBACK(int) rtZipTarFssWriter_End(void *pvThis) 612 { 613 PRTZIPTARFSSTREAMWRITER pThis = (PRTZIPTARFSSTREAMWRITER)pvThis; 614 if (RT_SUCCESS(pThis->rcFatal)) 615 { 616 /** @todo investigate zero end records. */ 617 return VINF_SUCCESS; 618 } 619 return pThis->rcFatal; 620 } 519 621 520 622 … … 536 638 NULL, 537 639 rtZipTarFssWriter_Add, 640 rtZipTarFssWriter_End, 538 641 RTVFSFSSTREAMOPS_VERSION 539 642 }; 540 643 541 644 542 RTDECL(int) RTZipTarFsStreamToIoStream(RTVFSIOSTREAM hVfsIosOut, uint32_t fFlags, PRTVFSFSSTREAM phVfsFss) 645 RTDECL(int) RTZipTarFsStreamToIoStream(RTVFSIOSTREAM hVfsIosOut, RTZIPTARFORMAT enmFormat, 646 uint32_t fFlags, PRTVFSFSSTREAM phVfsFss) 543 647 { 544 648 /* … … 548 652 *phVfsFss = NIL_RTVFSFSSTREAM; 549 653 AssertPtrReturn(hVfsIosOut, VERR_INVALID_HANDLE); 550 AssertReturn(!fFlags, VERR_INVALID_PARAMETER); 654 AssertReturn(enmFormat > RTZIPTARFORMAT_INVALID && enmFormat < RTZIPTARFORMAT_END, VERR_INVALID_PARAMETER); 655 AssertReturn(!(fFlags & ~RTZIPTAR_C_VALID_MASK), VERR_INVALID_FLAGS); 656 657 if (enmFormat == RTZIPTARFORMAT_DEFAULT) 658 enmFormat = RTZIPTARFORMAT_GNU; 659 AssertReturn(enmFormat == RTZIPTARFORMAT_GNU, VERR_NOT_IMPLEMENTED); /* Only implementing GNU output at the moment. */ 551 660 552 661 uint32_t cRefs = RTVfsIoStrmRetain(hVfsIosOut); … … 562 671 if (RT_SUCCESS(rc)) 563 672 { 564 pThis->hVfsIos = hVfsIosOut; 565 pThis->rcFatal = VINF_SUCCESS; 673 pThis->hVfsIos = hVfsIosOut; 674 pThis->enmFormat = enmFormat; 675 pThis->rcFatal = VINF_SUCCESS; 566 676 567 677 *phVfsFss = hVfsFss; -
trunk/src/VBox/Runtime/common/zip/xarvfs.cpp
r67116 r67123 1802 1802 0, 1803 1803 rtZipXarFss_Next, 1804 NULL, 1804 1805 NULL, 1805 1806 RTVFSFSSTREAMOPS_VERSION
Note:
See TracChangeset
for help on using the changeset viewer.