tarcmd.cpp revision c2d403aafae5a578452b1a316762d615f583893b
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/* $Id$ */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/** @file
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * IPRT - A mini TAR Command.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/*
8502773207230763deba3e622495f2099398dcb0vboxsync * Copyright (C) 2010-2013 Oracle Corporation
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync *
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * available from http://www.virtualbox.org. This file is free software;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * you can redistribute it and/or modify it under the terms of the GNU
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * General Public License (GPL) as published by the Free Software
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync *
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * The contents of this file may alternatively be used under the terms
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * of the Common Development and Distribution License Version 1.0
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * VirtualBox OSE distribution, in which case the provisions of the
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * CDDL are applicable instead of those of the GPL.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync *
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * You may elect to license modified versions of this file under the
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * terms and conditions of either the GPL or the CDDL or both.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/*******************************************************************************
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync* Header Files *
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync*******************************************************************************/
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#include <iprt/zip.h>
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#include <iprt/asm.h>
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#include <iprt/buildconfig.h>
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#include <iprt/ctype.h>
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#include <iprt/dir.h>
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#include <iprt/file.h>
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#include <iprt/getopt.h>
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#include <iprt/initterm.h>
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#include <iprt/mem.h>
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#include <iprt/message.h>
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#include <iprt/param.h>
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#include <iprt/path.h>
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#include <iprt/stream.h>
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#include <iprt/string.h>
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#include <iprt/symlink.h>
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync#include <iprt/vfs.h>
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/*******************************************************************************
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync* Defined Constants And Macros *
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync*******************************************************************************/
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#define RTZIPTARCMD_OPT_DELETE 1000
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#define RTZIPTARCMD_OPT_OWNER 1001
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#define RTZIPTARCMD_OPT_GROUP 1002
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#define RTZIPTARCMD_OPT_UTC 1003
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#define RTZIPTARCMD_OPT_PREFIX 1004
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#define RTZIPTARCMD_OPT_FILE_MODE_AND_MASK 1005
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#define RTZIPTARCMD_OPT_FILE_MODE_OR_MASK 1006
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#define RTZIPTARCMD_OPT_DIR_MODE_AND_MASK 1007
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#define RTZIPTARCMD_OPT_DIR_MODE_OR_MASK 1008
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync#define RTZIPTARCMD_OPT_FORMAT 1009
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync/** File format. */
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsynctypedef enum RTZIPTARFORMAT
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync{
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync RTZIPTARFORMAT_INVALID = 0,
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync /** Autodetect if possible, defaulting to TAR. */
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync RTZIPTARFORMAT_AUTO_DEFAULT,
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync /** TAR. */
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync RTZIPTARFORMAT_TAR,
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync /** XAR. */
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync RTZIPTARFORMAT_XAR
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync} RTZIPTARFORMAT;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/*******************************************************************************
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync* Structures and Typedefs *
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync*******************************************************************************/
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/**
8502773207230763deba3e622495f2099398dcb0vboxsync * IPRT TAR option structure.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsynctypedef struct RTZIPTARCMDOPS
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync{
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync /** The file format. */
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync RTZIPTARFORMAT enmFormat;
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /** The operation (Acdrtux or RTZIPTARCMD_OPT_DELETE). */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync int iOperation;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /** The long operation option name. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync const char *pszOperation;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /** The directory to change into when packing and unpacking. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync const char *pszDirectory;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /** The tar file name. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync const char *pszFile;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /** Whether we're verbose or quiet. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync bool fVerbose;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /** Whether to preserve the original file owner when restoring. */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync bool fPreserveOwner;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /** Whether to preserve the original file group when restoring. */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync bool fPreserveGroup;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /** Whether to skip restoring the modification time (only time stored by the
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * traditional TAR format). */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync bool fNoModTime;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /** The compressor/decompressor method to employ (0, z or j). */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync char chZipper;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /** The owner to set. NULL if not applicable.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Always resolved into uidOwner for extraction. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync const char *pszOwner;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /** The owner ID to set. NIL_RTUID if not applicable. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTUID uidOwner;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /** The group to set. NULL if not applicable.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Always resolved into gidGroup for extraction. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync const char *pszGroup;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /** The group ID to set. NIL_RTGUID if not applicable. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTGID gidGroup;
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync /** Display the modification times in UTC instead of local time. */
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync bool fDisplayUtc;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /** File mode AND mask. */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTFMODE fFileModeAndMask;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /** File mode OR mask. */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTFMODE fFileModeOrMask;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /** Directory mode AND mask. */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTFMODE fDirModeAndMask;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /** Directory mode OR mask. */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTFMODE fDirModeOrMask;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /** What to prefix all names with when creating, adding, whatever. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync const char *pszPrefix;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /** The number of files(, directories or whatever) specified. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync uint32_t cFiles;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /** Array of files(, directories or whatever).
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Terminated by a NULL entry. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync const char * const *papszFiles;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync} RTZIPTARCMDOPS;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/** Pointer to the IPRT tar options. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsynctypedef RTZIPTARCMDOPS *PRTZIPTARCMDOPS;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync/**
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Callback used by rtZipTarDoWithMembers
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @returns rcExit or RTEXITCODE_FAILURE.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pOpts The tar options.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param hVfsObj The tar object to display
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pszName The name.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param rcExit The current exit code.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsynctypedef RTEXITCODE (*PFNDOWITHMEMBER)(PRTZIPTARCMDOPS pOpts, RTVFSOBJ hVfsObj, const char *pszName, RTEXITCODE rcExit);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/**
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Checks if @a pszName is a member of @a papszNames, optionally returning the
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * index.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync *
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * @returns true if the name is in the list, otherwise false.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * @param pszName The name to find.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * @param papszNames The array of names.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * @param piName Where to optionally return the array index.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsyncstatic bool rtZipTarCmdIsNameInArray(const char *pszName, const char * const *papszNames, uint32_t *piName)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync{
c2d403aafae5a578452b1a316762d615f583893bvboxsync for (uint32_t iName = 0; papszNames[iName]; iName++)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (!strcmp(papszNames[iName], pszName))
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (piName)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync *piName = iName;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return true;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return false;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync}
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/**
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Opens the input archive specified by the options.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync *
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + printed message.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * @param pOpts The options.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * @param phVfsFss Where to return the TAR filesystem stream handle.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsyncstatic RTEXITCODE rtZipTarCmdOpenInputArchive(PRTZIPTARCMDOPS pOpts, PRTVFSFSSTREAM phVfsFss)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync{
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync int rc;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /*
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Open the input file.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTVFSIOSTREAM hVfsIos;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if ( pOpts->pszFile
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync && strcmp(pOpts->pszFile, "-") != 0)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync const char *pszError;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rc = RTVfsChainOpenIoStream(pOpts->pszFile,
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN,
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync &hVfsIos,
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync &pszError);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (RT_FAILURE(rc))
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (pszError && *pszError)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE,
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync "RTVfsChainOpenIoStream failed with rc=%Rrc:\n"
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync " '%s'\n",
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync " %*s^\n",
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rc, pOpts->pszFile, pszError - pOpts->pszFile, "");
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE,
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync "Failed with %Rrc opening the input archive '%s'", rc, pOpts->pszFile);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync else
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_INPUT,
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN,
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync true /*fLeaveOpen*/,
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync &hVfsIos);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (RT_FAILURE(rc))
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to prepare standard in for reading: %Rrc", rc);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /*
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Pass it thru a decompressor?
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTVFSIOSTREAM hVfsIosDecomp = NIL_RTVFSIOSTREAM;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync switch (pOpts->chZipper)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /* no */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case '\0':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rc = VINF_SUCCESS;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /* gunzip */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'z':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rc = RTZipGzipDecompressIoStream(hVfsIos, 0 /*fFlags*/, &hVfsIosDecomp);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (RT_FAILURE(rc))
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTMsgError("Failed to open gzip decompressor: %Rrc", rc);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /* bunzip2 */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'j':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rc = VERR_NOT_SUPPORTED;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTMsgError("bzip2 is not supported by this build");
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /* bug */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync default:
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rc = VERR_INTERNAL_ERROR_2;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTMsgError("unknown decompression method '%c'", pOpts->chZipper);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (RT_FAILURE(rc))
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTVfsIoStrmRelease(hVfsIos);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTEXITCODE_FAILURE;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (hVfsIosDecomp != NIL_RTVFSIOSTREAM)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTVfsIoStrmRelease(hVfsIos);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync hVfsIos = hVfsIosDecomp;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync hVfsIosDecomp = NIL_RTVFSIOSTREAM;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /*
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync * Open the filesystem stream.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync if (pOpts->enmFormat == RTZIPTARFORMAT_TAR)
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0/*fFlags*/, phVfsFss);
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync else if (pOpts->enmFormat == RTZIPTARFORMAT_XAR)
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync#ifdef IPRT_WITH_XAR /* Requires C++ and XML, so only in some configruation of IPRT. */
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync rc = RTZipXarFsStreamFromIoStream(hVfsIos, 0/*fFlags*/, phVfsFss);
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync#else
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync rc = VERR_NOT_SUPPORTED;
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync#endif
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync else /** @todo make RTZipTarFsStreamFromIoStream fail if not tar file! */
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0/*fFlags*/, phVfsFss);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTVfsIoStrmRelease(hVfsIos);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (RT_FAILURE(rc))
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to open tar filesystem stream: %Rrc", rc);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTEXITCODE_SUCCESS;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync}
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/**
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Worker for the --list and --extract commands.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @returns The appropriate exit code.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pOpts The tar options.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pfnCallback The command specific callback.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsyncstatic RTEXITCODE rtZipTarDoWithMembers(PRTZIPTARCMDOPS pOpts, PFNDOWITHMEMBER pfnCallback)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync{
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Allocate a bitmap to go with the file list. This will be used to
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * indicate which files we've processed and which not.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync uint32_t *pbmFound = NULL;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (pOpts->cFiles)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync pbmFound = (uint32_t *)RTMemAllocZ(((pOpts->cFiles + 31) / 32) * sizeof(uint32_t));
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (!pbmFound)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to allocate the found-file-bitmap");
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Open the input archive.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTVFSFSSTREAM hVfsFssIn;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTEXITCODE rcExit = rtZipTarCmdOpenInputArchive(pOpts, &hVfsFssIn);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (rcExit == RTEXITCODE_SUCCESS)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Process the stream.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync for (;;)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Retrive the next object.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync char *pszName;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTVFSOBJ hVfsObj;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync int rc = RTVfsFsStrmNext(hVfsFssIn, &pszName, NULL, &hVfsObj);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (rc != VERR_EOF)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsFsStrmNext returned %Rrc", rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync break;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Should we process this entry?
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync uint32_t iFile = UINT32_MAX;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if ( !pOpts->cFiles
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync || rtZipTarCmdIsNameInArray(pszName, pOpts->papszFiles, &iFile) )
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (pbmFound)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync ASMBitSet(pbmFound, iFile);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = pfnCallback(pOpts, hVfsObj, pszName, rcExit);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Release the current object and string.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTVfsObjRelease(hVfsObj);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTStrFree(pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Complain about any files we didn't find.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync for (uint32_t iFile = 0; iFile < pOpts->cFiles; iFile++)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (!ASMBitTest(pbmFound, iFile))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTMsgError("%s: Was not found in the archive", pOpts->papszFiles[iFile]);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = RTEXITCODE_FAILURE;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
c2d403aafae5a578452b1a316762d615f583893bvboxsync
c2d403aafae5a578452b1a316762d615f583893bvboxsync RTVfsFsStrmRelease(hVfsFssIn);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTMemFree(pbmFound);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return rcExit;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync}
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync/**
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Checks if the name contains any escape sequences.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * An escape sequence would generally be one or more '..' references. On DOS
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * like system, something that would make up a drive letter reference is also
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * considered an escape sequence.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @returns true / false.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pszName The name to consider.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsyncstatic bool rtZipTarHasEscapeSequence(const char *pszName)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync{
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (pszName[0] == ':')
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return true;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#endif
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync while (*pszName)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync while (RTPATH_IS_SEP(*pszName))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync pszName++;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if ( pszName[0] == '.'
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync && pszName[1] == '.'
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync && (pszName[2] == '\0' || RTPATH_IS_SLASH(pszName[2])) )
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return true;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync while (*pszName && !RTPATH_IS_SEP(*pszName))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync pszName++;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return false;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync}
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync/**
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Queries the user ID to use when extracting a member.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync *
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * @returns rcExit or RTEXITCODE_FAILURE.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pOpts The tar options.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pUser The user info.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pszName The file name to use when complaining.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * @param rcExit The current exit code.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pUid Where to return the user ID.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsyncstatic RTEXITCODE rtZipTarQueryExtractOwner(PRTZIPTARCMDOPS pOpts, PCRTFSOBJINFO pOwner, const char *pszName, RTEXITCODE rcExit,
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync PRTUID pUid)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync{
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (pOpts->uidOwner != NIL_RTUID)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *pUid = pOpts->uidOwner;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync else if (pOpts->fPreserveGroup)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (!pOwner->Attr.u.UnixGroup.szName[0])
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *pUid = pOwner->Attr.u.UnixOwner.uid;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync else
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *pUid = NIL_RTUID;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: User resolving is not implemented.", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync else
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *pUid = NIL_RTUID;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return rcExit;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync}
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync/**
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Queries the group ID to use when extracting a member.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @returns rcExit or RTEXITCODE_FAILURE.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pOpts The tar options.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pGroup The group info.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pszName The file name to use when complaining.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param rcExit The current exit code.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pGid Where to return the group ID.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsyncstatic RTEXITCODE rtZipTarQueryExtractGroup(PRTZIPTARCMDOPS pOpts, PCRTFSOBJINFO pGroup, const char *pszName, RTEXITCODE rcExit,
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync PRTGID pGid)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync{
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (pOpts->gidGroup != NIL_RTGID)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *pGid = pOpts->gidGroup;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync else if (pOpts->fPreserveGroup)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (!pGroup->Attr.u.UnixGroup.szName[0])
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *pGid = pGroup->Attr.u.UnixGroup.gid;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync else
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *pGid = NIL_RTGID;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Group resolving is not implemented.", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync else
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *pGid = NIL_RTGID;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return rcExit;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync}
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync/**
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Extracts a file.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Since we can restore permissions and attributes more efficiently by working
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * directly on the file handle, we have special code path for files.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync *
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @returns rcExit or RTEXITCODE_FAILURE.
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync * @param pOpts The tar options.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param hVfsObj The tar object to display
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param rcExit The current exit code.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pUnixInfo The unix fs object info.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pOwner The owner info.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pGroup The group info.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsyncstatic RTEXITCODE rtZipTarCmdExtractFile(PRTZIPTARCMDOPS pOpts, RTVFSOBJ hVfsObj, RTEXITCODE rcExit,
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync const char *pszDst, PCRTFSOBJINFO pUnixInfo, PCRTFSOBJINFO pOwner, PCRTFSOBJINFO pGroup)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync{
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Open the destination file and create a stream object for it.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync uint32_t fOpen = RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_ACCESS_ATTR_DEFAULT
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync | ((RTFS_UNIX_IWUSR | RTFS_UNIX_IRUSR) << RTFILE_O_CREATE_MODE_SHIFT);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTFILE hFile;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync int rc = RTFileOpen(&hFile, pszDst, fOpen);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error creating file: %Rrc", pszDst, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTVFSIOSTREAM hVfsIosDst;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTVfsIoStrmFromRTFile(hFile, fOpen, true /*fLeaveOpen*/, &hVfsIosDst);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_SUCCESS(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Pump the data thru.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTVFSIOSTREAM hVfsIosSrc = RTVfsObjToIoStream(hVfsObj);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTVfsUtilPumpIoStreams(hVfsIosSrc, hVfsIosDst, (uint32_t)RT_MIN(pUnixInfo->cbObject, _1M));
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_SUCCESS(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Correct the file mode and other attributes.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (!pOpts->fNoModTime)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTFileSetTimes(hFile, NULL, &pUnixInfo->ModificationTime, NULL, NULL);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error setting times: %Rrc", pszDst, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if ( pOpts->uidOwner != NIL_RTUID
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync || pOpts->gidGroup != NIL_RTGID
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync || pOpts->fPreserveOwner
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync || pOpts->fPreserveGroup)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTUID uidFile;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = rtZipTarQueryExtractOwner(pOpts, pOwner, pszDst, rcExit, &uidFile);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTGID gidFile;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = rtZipTarQueryExtractGroup(pOpts, pGroup, pszDst, rcExit, &gidFile);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (uidFile != NIL_RTUID || gidFile != NIL_RTGID)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTFileSetOwner(hFile, uidFile, gidFile);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error owner/group: %Rrc", pszDst, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#endif
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTFMODE fMode = (pUnixInfo->Attr.fMode & pOpts->fFileModeAndMask) | pOpts->fFileModeOrMask;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTFileSetMode(hFile, fMode | RTFS_TYPE_FILE);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error changing mode: %Rrc", pszDst, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync else
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error writing out file: %Rrc", pszDst, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTVfsIoStrmRelease(hVfsIosSrc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTVfsIoStrmRelease(hVfsIosDst);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync else
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error creating I/O stream for file: %Rrc", pszDst, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTFileClose(hFile);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return rcExit;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync}
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync/**
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @callback_method_impl{PFNDOWITHMEMBER, Implements --extract.}
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsyncstatic RTEXITCODE rtZipTarCmdExtractCallback(PRTZIPTARCMDOPS pOpts, RTVFSOBJ hVfsObj, const char *pszName, RTEXITCODE rcExit)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync{
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (pOpts->fVerbose)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTPrintf("%s\n", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Query all the information.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTFSOBJINFO UnixInfo;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync int rc = RTVfsObjQueryInfo(hVfsObj, &UnixInfo, RTFSOBJATTRADD_UNIX);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsObjQueryInfo returned %Rrc on '%s'", rc, pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTFSOBJINFO Owner;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTVfsObjQueryInfo(hVfsObj, &Owner, RTFSOBJATTRADD_UNIX_OWNER);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE,
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync "RTVfsObjQueryInfo(,,UNIX_OWNER) returned %Rrc on '%s'",
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc, pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTFSOBJINFO Group;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTVfsObjQueryInfo(hVfsObj, &Group, RTFSOBJATTRADD_UNIX_GROUP);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE,
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync "RTVfsObjQueryInfo(,,UNIX_OWNER) returned %Rrc on '%s'",
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc, pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync const char *pszLinkType = NULL;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync char szTarget[RTPATH_MAX];
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync szTarget[0] = '\0';
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTVFSSYMLINK hVfsSymlink = RTVfsObjToSymlink(hVfsObj);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (hVfsSymlink != NIL_RTVFSSYMLINK)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTVfsSymlinkRead(hVfsSymlink, szTarget, sizeof(szTarget));
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTVfsSymlinkRelease(hVfsSymlink);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: RTVfsSymlinkRead failed: %Rrc", pszName, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (!RTFS_IS_SYMLINK(UnixInfo.Attr.fMode))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Hardlinks are not supported.", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (!szTarget[0])
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Link target is empty.", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync else if (RTFS_IS_SYMLINK(UnixInfo.Attr.fMode))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to get symlink object for '%s'", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (rtZipTarHasEscapeSequence(pszName))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Name '%s' contains an escape sequence.", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Construct the path to the extracted member.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync char szDst[RTPATH_MAX];
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTPathJoin(szDst, sizeof(szDst), pOpts->pszDirectory ? pOpts->pszDirectory : ".", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Failed to construct destination path for: %Rrc", pszName, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Extract according to the type.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync switch (UnixInfo.Attr.fMode & RTFS_TYPE_MASK)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync case RTFS_TYPE_FILE:
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return rtZipTarCmdExtractFile(pOpts, hVfsObj, rcExit, szDst, &UnixInfo, &Owner, &Group);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync case RTFS_TYPE_DIRECTORY:
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTDirCreateFullPath(szDst, UnixInfo.Attr.fMode & RTFS_UNIX_ALL_ACCESS_PERMS);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error creating directory: %Rrc", szDst, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync break;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync case RTFS_TYPE_SYMLINK:
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTSymlinkCreate(szDst, szTarget, RTSYMLINKTYPE_UNKNOWN, 0);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error creating symbolic link: %Rrc", szDst, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync break;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync case RTFS_TYPE_FIFO:
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: FIFOs are not supported.", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync case RTFS_TYPE_DEV_CHAR:
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: FIFOs are not supported.", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync case RTFS_TYPE_DEV_BLOCK:
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Block devices are not supported.", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync case RTFS_TYPE_SOCKET:
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Sockets are not supported.", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync case RTFS_TYPE_WHITEOUT:
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Whiteouts are not support.", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync default:
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Unknown file type.", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Set other attributes as requested .
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * .
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Note! File extraction does get here.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (!pOpts->fNoModTime)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTPathSetTimesEx(szDst, NULL, &UnixInfo.ModificationTime, NULL, NULL, RTPATH_F_ON_LINK);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc) && rc != VERR_NOT_SUPPORTED && rc != VERR_NS_SYMLINK_SET_TIME)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error changing modification time: %Rrc.", pszName, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if ( pOpts->uidOwner != NIL_RTUID
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync || pOpts->gidGroup != NIL_RTGID
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync || pOpts->fPreserveOwner
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync || pOpts->fPreserveGroup)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTUID uidFile;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = rtZipTarQueryExtractOwner(pOpts, &Owner, szDst, rcExit, &uidFile);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTGID gidFile;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = rtZipTarQueryExtractGroup(pOpts, &Group, szDst, rcExit, &gidFile);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (uidFile != NIL_RTUID || gidFile != NIL_RTGID)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTPathSetOwnerEx(szDst, uidFile, gidFile, RTPATH_F_ON_LINK);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error owner/group: %Rrc", szDst, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#endif
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
d809f5627a423664bd420048579ee741164d13f5vboxsync#if !defined(RT_OS_WINDOWS) /** @todo implement RTPathSetMode on windows... */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (!RTFS_IS_SYMLINK(UnixInfo.Attr.fMode)) /* RTPathSetMode follows symbolic links atm. */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTFMODE fMode;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RTFS_IS_DIRECTORY(UnixInfo.Attr.fMode))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync fMode = (UnixInfo.Attr.fMode & (pOpts->fDirModeAndMask | RTFS_TYPE_MASK)) | pOpts->fDirModeOrMask;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync else
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync fMode = (UnixInfo.Attr.fMode & (pOpts->fFileModeAndMask | RTFS_TYPE_MASK)) | pOpts->fFileModeOrMask;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTPathSetMode(szDst, fMode);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_FAILURE(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error changing mode: %Rrc", szDst, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
d809f5627a423664bd420048579ee741164d13f5vboxsync#endif
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return rcExit;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync}
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync/**
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @callback_method_impl{PFNDOWITHMEMBER, Implements --list.}
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsyncstatic RTEXITCODE rtZipTarCmdListCallback(PRTZIPTARCMDOPS pOpts, RTVFSOBJ hVfsObj, const char *pszName, RTEXITCODE rcExit)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync{
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * This is very simple in non-verbose mode.
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (!pOpts->fVerbose)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTPrintf("%s\n", pszName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return rcExit;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /*
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Query all the information.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTFSOBJINFO UnixInfo;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync int rc = RTVfsObjQueryInfo(hVfsObj, &UnixInfo, RTFSOBJATTRADD_UNIX);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (RT_FAILURE(rc))
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsObjQueryInfo returned %Rrc on '%s'", rc, pszName);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RT_ZERO(UnixInfo);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTFSOBJINFO Owner;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rc = RTVfsObjQueryInfo(hVfsObj, &Owner, RTFSOBJATTRADD_UNIX_OWNER);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (RT_FAILURE(rc))
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE,
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync "RTVfsObjQueryInfo(,,UNIX_OWNER) returned %Rrc on '%s'",
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rc, pszName);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RT_ZERO(Owner);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTFSOBJINFO Group;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rc = RTVfsObjQueryInfo(hVfsObj, &Group, RTFSOBJATTRADD_UNIX_GROUP);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (RT_FAILURE(rc))
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE,
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync "RTVfsObjQueryInfo(,,UNIX_OWNER) returned %Rrc on '%s'",
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync rc, pszName);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RT_ZERO(Group);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync const char *pszLinkType = NULL;
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync char szTarget[RTPATH_MAX];
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync szTarget[0] = '\0';
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync RTVFSSYMLINK hVfsSymlink = RTVfsObjToSymlink(hVfsObj);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync if (hVfsSymlink != NIL_RTVFSSYMLINK)
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync {
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync rc = RTVfsSymlinkRead(hVfsSymlink, szTarget, sizeof(szTarget));
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync if (RT_FAILURE(rc))
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsSymlinkRead returned %Rrc on '%s'", rc, pszName);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync RTVfsSymlinkRelease(hVfsSymlink);
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync pszLinkType = RTFS_IS_SYMLINK(UnixInfo.Attr.fMode) ? "->" : "link to";
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync }
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync else if (RTFS_IS_SYMLINK(UnixInfo.Attr.fMode))
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to get symlink object for '%s'", pszName);
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /*
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Translate the mode mask.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync char szMode[16];
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync switch (UnixInfo.Attr.fMode & RTFS_TYPE_MASK)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case RTFS_TYPE_FIFO: szMode[0] = 'f'; break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case RTFS_TYPE_DEV_CHAR: szMode[0] = 'c'; break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case RTFS_TYPE_DIRECTORY: szMode[0] = 'd'; break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case RTFS_TYPE_DEV_BLOCK: szMode[0] = 'b'; break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case RTFS_TYPE_FILE: szMode[0] = '-'; break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case RTFS_TYPE_SYMLINK: szMode[0] = 'l'; break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case RTFS_TYPE_SOCKET: szMode[0] = 's'; break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case RTFS_TYPE_WHITEOUT: szMode[0] = 'w'; break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync default: szMode[0] = '?'; break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync if (pszLinkType && szMode[0] != 's')
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync szMode[0] = 'h';
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync szMode[1] = UnixInfo.Attr.fMode & RTFS_UNIX_IRUSR ? 'r' : '-';
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync szMode[2] = UnixInfo.Attr.fMode & RTFS_UNIX_IWUSR ? 'w' : '-';
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync szMode[3] = UnixInfo.Attr.fMode & RTFS_UNIX_IXUSR ? 'x' : '-';
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync szMode[4] = UnixInfo.Attr.fMode & RTFS_UNIX_IRGRP ? 'r' : '-';
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync szMode[5] = UnixInfo.Attr.fMode & RTFS_UNIX_IWGRP ? 'w' : '-';
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync szMode[6] = UnixInfo.Attr.fMode & RTFS_UNIX_IXGRP ? 'x' : '-';
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync szMode[7] = UnixInfo.Attr.fMode & RTFS_UNIX_IROTH ? 'r' : '-';
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync szMode[8] = UnixInfo.Attr.fMode & RTFS_UNIX_IWOTH ? 'w' : '-';
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync szMode[9] = UnixInfo.Attr.fMode & RTFS_UNIX_IXOTH ? 'x' : '-';
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync szMode[10] = '\0';
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /** @todo sticky and set-uid/gid bits. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /*
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Make sure we've got valid owner and group strings.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (!Owner.Attr.u.UnixGroup.szName[0])
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTStrPrintf(Owner.Attr.u.UnixOwner.szName, sizeof(Owner.Attr.u.UnixOwner.szName),
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync "%u", UnixInfo.Attr.u.Unix.uid);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (!Group.Attr.u.UnixOwner.szName[0])
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTStrPrintf(Group.Attr.u.UnixGroup.szName, sizeof(Group.Attr.u.UnixGroup.szName),
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync "%u", UnixInfo.Attr.u.Unix.gid);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /*
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Format the modification time.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync char szModTime[32];
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync RTTIME ModTime;
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync PRTTIME pTime;
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync if (!pOpts->fDisplayUtc)
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync pTime = RTTimeLocalExplode(&ModTime, &UnixInfo.ModificationTime);
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync else
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync pTime = RTTimeExplode(&ModTime, &UnixInfo.ModificationTime);
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync if (!pTime)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RT_ZERO(ModTime);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTStrPrintf(szModTime, sizeof(szModTime), "%04d-%02u-%02u %02u:%02u",
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync ModTime.i32Year, ModTime.u8Month, ModTime.u8MonthDay, ModTime.u8Hour, ModTime.u8Minute);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /*
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Format the size and figure how much space is needed between the
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * user/group and the size.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync char szSize[64];
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync size_t cchSize;
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync switch (UnixInfo.Attr.fMode & RTFS_TYPE_MASK)
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync {
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync case RTFS_TYPE_DEV_CHAR:
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync case RTFS_TYPE_DEV_BLOCK:
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync cchSize = RTStrPrintf(szSize, sizeof(szSize), "%u,%u",
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync RTDEV_MAJOR(UnixInfo.Attr.u.Unix.Device), RTDEV_MINOR(UnixInfo.Attr.u.Unix.Device));
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync break;
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync default:
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync cchSize = RTStrPrintf(szSize, sizeof(szSize), "%RU64", UnixInfo.cbObject);
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync break;
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync size_t cchUserGroup = strlen(Owner.Attr.u.UnixOwner.szName)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync + 1
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync + strlen(Group.Attr.u.UnixGroup.szName);
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync ssize_t cchPad = cchUserGroup + cchSize + 1 < 19
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync ? 19 - (cchUserGroup + cchSize + 1)
4eb5a468e1ff750304441e03d1b2311ce049956avboxsync : 0;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /*
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Go to press.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync if (pszLinkType)
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync RTPrintf("%s %s/%s%*s %s %s %s %s %s\n",
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync szMode,
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync Owner.Attr.u.UnixOwner.szName, Group.Attr.u.UnixGroup.szName,
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync cchPad, "",
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync szSize,
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync szModTime,
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync pszName,
1a62088b18e24a01c1dc85e13d60468e78bd649dvboxsync pszLinkType,
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync szTarget);
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync else
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync RTPrintf("%s %s/%s%*s %s %s %s\n",
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync szMode,
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync Owner.Attr.u.UnixOwner.szName, Group.Attr.u.UnixGroup.szName,
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync cchPad, "",
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync szSize,
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync szModTime,
1c434bf12564eb5a885b3f7e230b7638955004cevboxsync pszName);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return rcExit;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync}
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync/**
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * Display usage.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync *
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * @param pszProgName The program name.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsyncstatic void rtZipTarUsage(const char *pszProgName)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync{
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /*
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * 0 1 2 3 4 5 6 7 8
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync * 012345678901234567890123456789012345678901234567890123456789012345678901234567890
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTPrintf("Usage: %s [options]\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync "\n",
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync pszProgName);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTPrintf("Operations:\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -A, --concatenate, --catenate\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Append the content of one tar archive to another. (not impl)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -c, --create\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Create a new tar archive. (not impl)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -d, --diff, --compare\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Compare atar archive with the file system. (not impl)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -r, --append\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Append more files to the tar archive. (not impl)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -t, --list\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " List the contents of the tar archive.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -u, --update\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Update the archive, adding files that are newer than the\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " ones in the archive. (not impl)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -x, --extract, --get\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Extract the files from the tar archive.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " --delete\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Delete files from the tar archive.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync "\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync );
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTPrintf("Basic Options:\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -C <dir>, --directory <dir> (-A, -C, -d, -r, -u, -x)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Sets the base directory for input and output file members.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " This does not apply to --file, even if it preceeds it.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -f <archive>, --file <archive> (all)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " The tar file to create or process. '-' indicates stdout/stdin,\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " which is is the default.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -v, --verbose (all)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Verbose operation.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -p, --preserve-permissions (-x)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Preserve all permissions when extracting. Must be used\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " before the mode mask options as it will change some of these.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -j, --bzip2 (all)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Compress/decompress the archive with bzip2.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -z, --gzip, --gunzip, --ungzip (all)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Compress/decompress the archive with gzip.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync "\n");
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTPrintf("Misc Options:\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " --owner <uid/username> (-A, -C, -d, -r, -u, -x)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Set the owner of extracted and archived files to the user specified.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " --group <uid/username> (-A, -C, -d, -r, -u, -x)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Set the group of extracted and archived files to the group specified.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " --utc (-t)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Display timestamps as UTC instead of local time.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync "\n");
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTPrintf("IPRT Options:\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " --prefix <dir-prefix> (-A, -C, -d, -r, -u)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Directory prefix to give the members added to the archive.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " --file-mode-and-mask <octal-mode> (-A, -C, -d, -r, -u, -x)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Restrict the access mode of regular and special files.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " --file-mode-and-mask <octal-mode> (-A, -C, -d, -r, -u, -x)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Include the given access mode for regular and special files.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " --dir-mode-and-mask <octal-mode> (-A, -C, -d, -r, -u, -x)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Restrict the access mode of directories.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " --dir-mode-and-mask <octal-mode> (-A, -C, -d, -r, -u, -x)\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Include the given access mode for directories.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync "\n");
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RTPrintf("Standard Options:\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -h, -?, --help\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Display this help text.\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " -V, --version\n"
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync " Display version number.\n");
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync}
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
ff74d28041a2179e652244a3f7b64d34c2dfc87avboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsyncRTDECL(RTEXITCODE) RTZipTarCmd(unsigned cArgs, char **papszArgs)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync{
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /*
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Parse the command line.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync *
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * N.B. This is less flexible that your regular tar program in that it
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * requires the operation to be specified as an option. On the other
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * hand, you can specify it where ever you like in the command line.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync static const RTGETOPTDEF s_aOptions[] =
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /* operations */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--concatenate", 'A', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--catenate", 'A', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--create", 'c', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--diff", 'd', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--compare", 'd', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--append", 'r', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--list", 't', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--update", 'u', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--extract", 'x', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--get", 'x', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--delete", RTZIPTARCMD_OPT_DELETE, RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /* basic options */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--directory", 'C', RTGETOPT_REQ_STRING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--file", 'f', RTGETOPT_REQ_STRING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--preserve-permissions", 'p', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--bzip2", 'j', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--gzip", 'z', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--gunzip", 'z', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--ungzip", 'z', RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /* other options. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--owner", RTZIPTARCMD_OPT_OWNER, RTGETOPT_REQ_STRING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync { "--group", RTZIPTARCMD_OPT_GROUP, RTGETOPT_REQ_STRING },
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync { "--utc", RTZIPTARCMD_OPT_UTC, RTGETOPT_REQ_NOTHING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /* IPRT extensions */
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync { "--prefix", RTZIPTARCMD_OPT_PREFIX, RTGETOPT_REQ_STRING },
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync { "--file-mode-and-mask", RTZIPTARCMD_OPT_FILE_MODE_AND_MASK, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT },
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync { "--file-mode-or-mask", RTZIPTARCMD_OPT_FILE_MODE_OR_MASK, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT },
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync { "--dir-mode-and-mask", RTZIPTARCMD_OPT_DIR_MODE_AND_MASK, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT },
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync { "--dir-mode-or-mask", RTZIPTARCMD_OPT_DIR_MODE_OR_MASK, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT },
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync { "--format", RTZIPTARCMD_OPT_FORMAT, RTGETOPT_REQ_STRING },
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync };
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTGETOPTSTATE GetState;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1,
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTGETOPTINIT_FLAGS_OPTS_FIRST);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (RT_FAILURE(rc))
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOpt failed: %Rrc", rc);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTZIPTARCMDOPS Opts;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync RT_ZERO(Opts);
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync Opts.enmFormat = RTZIPTARFORMAT_AUTO_DEFAULT;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.uidOwner = NIL_RTUID;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.gidGroup = NIL_RTUID;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fFileModeAndMask = RTFS_UNIX_ALL_ACCESS_PERMS;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fDirModeAndMask = RTFS_UNIX_ALL_ACCESS_PERMS;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#if 0
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RTPermIsSuperUser())
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fFileModeAndMask = RTFS_UNIX_ALL_PERMS;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fDirModeAndMask = RTFS_UNIX_ALL_PERMS;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fPreserveOwner = true;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fPreserveGroup = true;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync#endif
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTGETOPTUNION ValueUnion;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync while ( (rc = RTGetOpt(&GetState, &ValueUnion)) != 0
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync && rc != VINF_GETOPT_NOT_OPTION)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync switch (rc)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /* operations */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'A':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'c':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'd':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'r':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 't':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'u':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'x':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case RTZIPTARCMD_OPT_DELETE:
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (Opts.iOperation)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Conflicting tar operation (%s already set, now %s)",
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Opts.pszOperation, ValueUnion.pDef->pszLong);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Opts.iOperation = rc;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Opts.pszOperation = ValueUnion.pDef->pszLong;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /* basic options */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'C':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (Opts.pszDirectory)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "You may only specify -C/--directory once");
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Opts.pszDirectory = ValueUnion.psz;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'f':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (Opts.pszFile)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "You may only specify -f/--file once");
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Opts.pszFile = ValueUnion.psz;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'v':
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync Opts.fVerbose = true;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'p':
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fFileModeAndMask = RTFS_UNIX_ALL_PERMS;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fDirModeAndMask = RTFS_UNIX_ALL_PERMS;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fPreserveOwner = true;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fPreserveGroup = true;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'j':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'z':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (Opts.chZipper)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "You may only specify one compressor / decompressor");
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Opts.chZipper = rc;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case RTZIPTARCMD_OPT_OWNER:
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (Opts.pszOwner)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "You may only specify --owner once");
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Opts.pszOwner = ValueUnion.psz;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTStrToUInt32Full(Opts.pszOwner, 0, &ValueUnion.u32);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_SUCCESS(rc) && rc != VINF_SUCCESS)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX,
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync "Error convering --owner '%s' into a number: %Rrc", Opts.pszOwner, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_SUCCESS(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.uidOwner = ValueUnion.u32;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.pszOwner = NULL;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case RTZIPTARCMD_OPT_GROUP:
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (Opts.pszGroup)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "You may only specify --group once");
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Opts.pszGroup = ValueUnion.psz;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rc = RTStrToUInt32Full(Opts.pszGroup, 0, &ValueUnion.u32);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_SUCCESS(rc) && rc != VINF_SUCCESS)
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX,
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync "Error convering --group '%s' into a number: %Rrc", Opts.pszGroup, rc);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync if (RT_SUCCESS(rc))
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync {
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.gidGroup = ValueUnion.u32;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.pszGroup = NULL;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync case RTZIPTARCMD_OPT_UTC:
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync Opts.fDisplayUtc = true;
cf9045d402be1e8b7344a439eaefe2ca4c2b53d3vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /* iprt extensions */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case RTZIPTARCMD_OPT_PREFIX:
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (Opts.pszPrefix)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "You may only specify --prefix once");
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Opts.pszPrefix = ValueUnion.psz;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync break;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync case RTZIPTARCMD_OPT_FILE_MODE_AND_MASK:
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fFileModeAndMask = ValueUnion.u32 & RTFS_UNIX_ALL_PERMS;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync break;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync case RTZIPTARCMD_OPT_FILE_MODE_OR_MASK:
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fFileModeOrMask = ValueUnion.u32 & RTFS_UNIX_ALL_PERMS;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync break;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync case RTZIPTARCMD_OPT_DIR_MODE_AND_MASK:
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fDirModeAndMask = ValueUnion.u32 & RTFS_UNIX_ALL_PERMS;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync break;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync case RTZIPTARCMD_OPT_DIR_MODE_OR_MASK:
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync Opts.fDirModeOrMask = ValueUnion.u32 & RTFS_UNIX_ALL_PERMS;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync break;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync case RTZIPTARCMD_OPT_FORMAT:
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync if (!strcmp(ValueUnion.psz, "auto") || !strcmp(ValueUnion.psz, "default"))
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync Opts.enmFormat = RTZIPTARFORMAT_AUTO_DEFAULT;
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync else if (!strcmp(ValueUnion.psz, "tar"))
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync Opts.enmFormat = RTZIPTARFORMAT_TAR;
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync else if (!strcmp(ValueUnion.psz, "xar"))
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync Opts.enmFormat = RTZIPTARFORMAT_XAR;
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync else
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown archive format: '%s'", ValueUnion.psz);
ab65f9ce33765b251219fbf18b19d3e56fdf5d2cvboxsync break;
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync /* Standard bits. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'h':
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync rtZipTarUsage(RTPathFilename(papszArgs[0]));
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTEXITCODE_SUCCESS;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'V':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision());
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTEXITCODE_SUCCESS;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync default:
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTGetOptPrintError(rc, &ValueUnion);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (rc == VINF_GETOPT_NOT_OPTION)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /* this is kind of ugly. */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Assert((unsigned)GetState.iNext - 1 <= cArgs);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Opts.papszFiles = (const char * const *)&papszArgs[GetState.iNext - 1];
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Opts.cFiles = cArgs - GetState.iNext + 1;
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /*
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Post proceess the options.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if (Opts.iOperation == 0)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Opts.iOperation = 't';
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync Opts.pszOperation = "--list";
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if ( Opts.iOperation == 'x'
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync && Opts.pszOwner)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "The use of --owner with %s has not implemented yet", Opts.pszOperation);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync if ( Opts.iOperation == 'x'
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync && Opts.pszGroup)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "The use of --group with %s has not implemented yet", Opts.pszOperation);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync /*
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync * Do the job.
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync */
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync switch (Opts.iOperation)
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync {
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 't':
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return rtZipTarDoWithMembers(&Opts, rtZipTarCmdListCallback);
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync case 'x':
7bc0784812dcf63751c5eebfdd1c5d24ac26b389vboxsync return rtZipTarDoWithMembers(&Opts, rtZipTarCmdExtractCallback);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'A':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'c':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'd':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'r':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case 'u':
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync case RTZIPTARCMD_OPT_DELETE:
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "The operation %s is not implemented yet", Opts.pszOperation);
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync default:
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Internal error");
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync }
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync}
1e7030f54deae0a8aa27817ab26c5d6d6c246541vboxsync