- Timestamp:
- Feb 3, 2023 10:58:36 AM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/zip/tarcmd.cpp
r98103 r98459 316 316 317 317 /** 318 * Archives a symlink. 319 * 320 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + printed message. 321 * @param pOpts The options. 322 * @param hVfsFss The TAR filesystem stream handle. 323 * @param pszSrc The file path or VFS spec. 324 * @param paObjInfo[3] Array of three FS object info structures. The first 325 * one is always filled with RTFSOBJATTRADD_UNIX info. 326 * The next two may contain owner and group names if 327 * available. Buffers can be modified. 328 * @param pszDst The name to archive the file under. 329 * @param pErrInfo Error info buffer (saves stack space). 330 */ 331 static RTEXITCODE rtZipTarCmdArchiveSymlink(PRTZIPTARCMDOPS pOpts, RTVFSFSSTREAM hVfsFss, const char *pszSrc, 332 RTFSOBJINFO paObjInfo[3], const char *pszDst, PRTERRINFOSTATIC pErrInfo) 333 { 334 if (pOpts->fVerbose) 335 RTPrintf("%s\n", pszDst); 336 337 /* Open the file. */ 338 uint32_t offError; 339 RTVFSOBJ hVfsObjSrc; 340 int rc = RTVfsChainOpenObj(pszSrc, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE, 341 RTVFSOBJ_F_OPEN_SYMLINK | RTVFSOBJ_F_CREATE_NOTHING | RTPATH_F_ON_LINK, 342 &hVfsObjSrc, &offError, RTErrInfoInitStatic(pErrInfo)); 343 if (RT_FAILURE(rc)) 344 return RTVfsChainMsgErrorExitFailure("RTVfsChainOpenObj", pszSrc, rc, offError, &pErrInfo->Core); 345 346 rc = RTVfsFsStrmAdd(hVfsFss, pszDst, hVfsObjSrc, 0 /*fFlags*/); 347 RTVfsObjRelease(hVfsObjSrc); 348 349 if (RT_SUCCESS(rc)) 350 { 351 if (rc != VINF_SUCCESS) 352 RTMsgWarning("%Rrc adding '%s'", rc, pszDst); 353 return RTEXITCODE_SUCCESS; 354 } 355 return RTMsgErrorExitFailure("%Rrc adding '%s'", rc, pszDst); 356 } 357 358 359 /** 318 360 * Sub-directory helper for creating archives. 319 361 * … … 364 406 return RTMsgErrorExitFailure("Destination path too long: '%s'\n", pszDst); 365 407 408 /* For CPIO we need to add the directory entry itself first. */ 409 if (pOpts->enmFormat == RTZIPTARCMDFORMAT_CPIO) 410 { 411 RTVFSOBJ hVfsObjSrc = RTVfsObjFromDir(hVfsIoDir); 412 rc = RTVfsFsStrmAdd(hVfsFss, pszDst, hVfsObjSrc, 0 /*fFlags*/); 413 RTVfsObjRelease(hVfsObjSrc); 414 if (RT_FAILURE(rc)) 415 return RTMsgErrorExitFailure("Failed to add directory to archive: '%s' -> %Rrc\n", pszDst, rc); 416 } 417 366 418 if (!RTPATH_IS_SEP(pszDst[cchDst - 1])) 367 419 { … … 416 468 memcpy(&pszDst[cchDst], pDirEntry->szName, pDirEntry->cbName + 1); 417 469 rc = rtZipTarCmdArchiveFile(pOpts, hVfsFss, pszSrc, paObjInfo, pszDst, pErrInfo); 470 } 471 break; 472 } 473 474 case RTFS_TYPE_SYMLINK: 475 { 476 memcpy(&pszSrc[cchSrc], pDirEntry->szName, pDirEntry->cbName + 1); 477 rc = rtZipTarCmdQueryObjInfo(pszSrc, paObjInfo, 3 /* cObjInfo */); 478 if (RT_SUCCESS(rc)) 479 { 480 memcpy(&pszDst[cchDst], pDirEntry->szName, pDirEntry->cbName + 1); 481 rc = rtZipTarCmdArchiveSymlink(pOpts, hVfsFss, pszSrc, paObjInfo, pszDst, pErrInfo); 418 482 } 419 483 break; … … 561 625 */ 562 626 if ( pOpts->enmFormat == RTZIPTARCMDFORMAT_TAR 627 || pOpts->enmFormat == RTZIPTARCMDFORMAT_CPIO 563 628 || pOpts->enmFormat == RTZIPTARCMDFORMAT_AUTO_DEFAULT) 564 629 { … … 704 769 rcExit2 = rtZipTarCmdArchiveFile(pOpts, hVfsFss, szSrc, aObjInfo, szDst, &ErrInfo); 705 770 else if (RTFS_IS_SYMLINK(aObjInfo[0].Attr.fMode)) 706 rcExit2 = RTMsgErrorExitFailure("Symlink archiving is not implemented");771 rcExit2 = rtZipTarCmdArchiveSymlink(pOpts, hVfsFss, szSrc, aObjInfo, szDst, &ErrInfo); 707 772 else if (RTFS_IS_FIFO(aObjInfo[0].Attr.fMode)) 708 773 rcExit2 = RTMsgErrorExitFailure("FIFO archiving is not implemented"); … … 1878 1943 Opts.enmFormat = RTZIPTARCMDFORMAT_XAR; 1879 1944 else if (!strcmp(ValueUnion.psz, "cpio")) 1945 { 1880 1946 Opts.enmFormat = RTZIPTARCMDFORMAT_CPIO; 1947 Opts.enmTarFormat = RTZIPTARFORMAT_CPIO_ASCII_NEW; 1948 } 1881 1949 else 1882 1950 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown archive format: '%s'", ValueUnion.psz);
Note:
See TracChangeset
for help on using the changeset viewer.