VirtualBox

Changeset 98459 in vbox for trunk


Ignore:
Timestamp:
Feb 3, 2023 10:58:36 AM (2 years ago)
Author:
vboxsync
Message:

Runtime/common/zip/tarcmd.cpp: Add support for cpio archives and archiving symlinks

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/zip/tarcmd.cpp

    r98103 r98459  
    316316
    317317/**
     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 */
     331static 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/**
    318360 * Sub-directory helper for creating archives.
    319361 *
     
    364406        return RTMsgErrorExitFailure("Destination path too long: '%s'\n", pszDst);
    365407
     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
    366418    if (!RTPATH_IS_SEP(pszDst[cchDst - 1]))
    367419    {
     
    416468                    memcpy(&pszDst[cchDst], pDirEntry->szName, pDirEntry->cbName + 1);
    417469                    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);
    418482                }
    419483                break;
     
    561625     */
    562626    if (   pOpts->enmFormat == RTZIPTARCMDFORMAT_TAR
     627        || pOpts->enmFormat == RTZIPTARCMDFORMAT_CPIO
    563628        || pOpts->enmFormat == RTZIPTARCMDFORMAT_AUTO_DEFAULT)
    564629    {
     
    704769                            rcExit2 = rtZipTarCmdArchiveFile(pOpts, hVfsFss, szSrc, aObjInfo, szDst, &ErrInfo);
    705770                        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);
    707772                        else if (RTFS_IS_FIFO(aObjInfo[0].Attr.fMode))
    708773                            rcExit2 = RTMsgErrorExitFailure("FIFO archiving is not implemented");
     
    18781943                    Opts.enmFormat    = RTZIPTARCMDFORMAT_XAR;
    18791944                else if (!strcmp(ValueUnion.psz, "cpio"))
     1945                {
    18801946                    Opts.enmFormat    = RTZIPTARCMDFORMAT_CPIO;
     1947                    Opts.enmTarFormat = RTZIPTARFORMAT_CPIO_ASCII_NEW;
     1948                }
    18811949                else
    18821950                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown archive format: '%s'", ValueUnion.psz);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette