diff options
author | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2023-01-26 15:59:04 +0000 |
---|---|---|
committer | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2023-01-26 15:59:04 +0000 |
commit | fcc9abb339c27abd18346d20ce693cd027c103b6 (patch) | |
tree | 64f8a43a08e48852dc288909aa345d3563ada1d8 | |
parent | d0ed83a85a90f697288ee7b7e9d25f259dcbf2fd (diff) | |
download | VirtualBox-svn-fcc9abb339c27abd18346d20ce693cd027c103b6.tar.gz |
Runtime,Main: Remove the now unused and deprecated RTTar* API in favor of the VFS implementation, move the header declaring the tar headers to iprt/formats so the appliance code can access some required defines
git-svn-id: https://www.virtualbox.org/svn/vbox/trunk@98322 cfe28804-0f27-0410-a406-dd0f0b0b656f
-rw-r--r-- | include/iprt/formats/tar.h (renamed from src/VBox/Runtime/common/zip/tar.h) | 4 | ||||
-rw-r--r-- | include/iprt/tar.h | 184 | ||||
-rw-r--r-- | src/VBox/Main/include/ApplianceImpl.h | 1 | ||||
-rw-r--r-- | src/VBox/Main/src-all/ExtPackUtil.cpp | 1 | ||||
-rw-r--r-- | src/VBox/Main/src-server/ApplianceImplExport.cpp | 6 | ||||
-rw-r--r-- | src/VBox/Main/src-server/ApplianceImplImport.cpp | 3 | ||||
-rw-r--r-- | src/VBox/Runtime/Makefile.kmk | 2 | ||||
-rw-r--r-- | src/VBox/Runtime/common/zip/tar.cpp | 713 | ||||
-rw-r--r-- | src/VBox/Runtime/common/zip/tarvfs.cpp | 2 | ||||
-rw-r--r-- | src/VBox/Runtime/common/zip/tarvfsreader.h | 2 | ||||
-rw-r--r-- | src/VBox/Runtime/common/zip/tarvfswriter.cpp | 2 | ||||
-rw-r--r-- | src/VBox/Runtime/include/internal/magics.h | 8 |
12 files changed, 13 insertions, 915 deletions
diff --git a/src/VBox/Runtime/common/zip/tar.h b/include/iprt/formats/tar.h index b20a0e2b756..4a4235bc2fd 100644 --- a/src/VBox/Runtime/common/zip/tar.h +++ b/include/iprt/formats/tar.h @@ -67,6 +67,10 @@ #define RTZIPTAR_TF_GNU_VOLDHR 'V' /** @} */ +/** Maximum length of a tar filename, excluding the terminating '\0'. More + * does not fit into a tar record. */ +#define RTZIPTAR_NAME_MAX 99 + /** * The ancient tar header. diff --git a/include/iprt/tar.h b/include/iprt/tar.h deleted file mode 100644 index be6ce0fac7d..00000000000 --- a/include/iprt/tar.h +++ /dev/null @@ -1,184 +0,0 @@ -/** @file - * IPRT - Tar archive I/O. - */ - -/* - * Copyright (C) 2009-2023 Oracle and/or its affiliates. - * - * This file is part of VirtualBox base platform packages, as - * available from https://www.virtualbox.org. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, in version 3 of the - * License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <https://www.gnu.org/licenses>. - * - * The contents of this file may alternatively be used under the terms - * of the Common Development and Distribution License Version 1.0 - * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included - * in the VirtualBox distribution, in which case the provisions of the - * CDDL are applicable instead of those of the GPL. - * - * You may elect to license modified versions of this file under the - * terms and conditions of either the GPL or the CDDL or both. - * - * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 - */ - -#ifndef IPRT_INCLUDED_tar_h -#define IPRT_INCLUDED_tar_h -#ifndef RT_WITHOUT_PRAGMA_ONCE -# pragma once -#endif - -#include <iprt/cdefs.h> -#include <iprt/types.h> -#include <iprt/time.h> - -RT_C_DECLS_BEGIN - -/** @defgroup grp_rt_tar RTTar - Tar archive I/O - * @ingroup grp_rt - * - * @deprecated Only used for legacy code and writing. Migrate new code to the - * VFS interface, add the write part when needed. - * - * @{ - */ - -/** A tar handle */ -typedef R3PTRTYPE(struct RTTARINTERNAL *) RTTAR; -/** Pointer to a RTTAR interface handle. */ -typedef RTTAR *PRTTAR; -/** Nil RTTAR interface handle. */ -#define NIL_RTTAR ((RTTAR)0) - -/** A tar file handle */ -typedef R3PTRTYPE(struct RTTARFILEINTERNAL *) RTTARFILE; -/** Pointer to a RTTARFILE interface handle. */ -typedef RTTARFILE *PRTTARFILE; -/** Nil RTTARFILE interface handle. */ -#define NIL_RTTARFILE ((RTTARFILE)0) - -/** Maximum length of a tar filename, excluding the terminating '\0'. More - * does not fit into a tar record. */ -#define RTTAR_NAME_MAX 99 - -/** - * Creates a Tar archive. - * - * Use the mask to specify the access type. - * - * @returns IPRT status code. - * - * @param phTar Where to store the RTTAR handle. - * @param pszTarname The file name of the tar archive to create. Should - * not exist. - * @param fMode Open flags, i.e a combination of the RTFILE_O_* defines. - * The ACCESS, ACTION and DENY flags are mandatory! - */ -RTR3DECL(int) RTTarOpen(PRTTAR phTar, const char *pszTarname, uint32_t fMode); - -/** - * Close the Tar archive. - * - * @returns IPRT status code. - * - * @param hTar Handle to the RTTAR interface. - */ -RTR3DECL(int) RTTarClose(RTTAR hTar); - -/** - * Open a file in the Tar archive. - * - * @returns IPRT status code. - * - * @param hTar The handle of the tar archive. - * @param phFile Where to store the handle to the opened file. - * @param pszFilename Path to the file which is to be opened. (UTF-8) - * @param fOpen Open flags, i.e a combination of the RTFILE_O_* defines. - * The ACCESS, ACTION flags are mandatory! DENY flags - * are currently not supported. - * - * @remarks Write mode means append mode only. It is not possible to make - * changes to existing files. - * - * @remarks Currently it is not possible to open more than one file in write - * mode. Although open more than one file in read only mode (even when - * one file is opened in write mode) is always possible. - */ -RTR3DECL(int) RTTarFileOpen(RTTAR hTar, PRTTARFILE phFile, const char *pszFilename, uint32_t fOpen); - -/** - * Close the file opened by RTTarFileOpen. - * - * @returns IPRT status code. - * - * @param hFile The file handle to close. - */ -RTR3DECL(int) RTTarFileClose(RTTARFILE hFile); - -/** - * Read bytes from a file at a given offset. - * This function may modify the file position. - * - * @returns IPRT status code. - * - * @param hFile Handle to the file. - * @param off Where to read. - * @param pvBuf Where to put the bytes we read. - * @param cbToRead How much to read. - * @param pcbRead Where to return how much we actually read. If NULL - * an error will be returned for a partial read. - */ -RTR3DECL(int) RTTarFileReadAt(RTTARFILE hFile, uint64_t off, void *pvBuf, size_t cbToRead, size_t *pcbRead); - -/** - * Write bytes to a file at a given offset. - * This function may modify the file position. - * - * @returns IPRT status code. - * - * @param hFile Handle to the file. - * @param off Where to write. - * @param pvBuf What to write. - * @param cbToWrite How much to write. - * @param pcbWritten Where to return how much we actually wrote. If NULL - * an error will be returned for a partial write. - */ -RTR3DECL(int) RTTarFileWriteAt(RTTARFILE hFile, uint64_t off, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten); - -/** - * Query the size of the file. - * - * @returns IPRT status code. - * - * @param hFile Handle to the file. - * @param pcbSize Where to store the filesize. - */ -RTR3DECL(int) RTTarFileGetSize(RTTARFILE hFile, uint64_t *pcbSize); - -/** - * Set the size of the file. - * - * @returns IPRT status code. - * - * @param hFile Handle to the file. - * @param cbSize The new file size. - */ -RTR3DECL(int) RTTarFileSetSize(RTTARFILE hFile, uint64_t cbSize); - -/** @} */ - -RT_C_DECLS_END - -#endif /* !IPRT_INCLUDED_tar_h */ - diff --git a/src/VBox/Main/include/ApplianceImpl.h b/src/VBox/Main/include/ApplianceImpl.h index 487a0820c15..97d2d533f46 100644 --- a/src/VBox/Main/include/ApplianceImpl.h +++ b/src/VBox/Main/include/ApplianceImpl.h @@ -38,7 +38,6 @@ /** @todo This file needs massive cleanup. Split IAppliance in a public and * private classes. */ -#include <iprt/tar.h> #include "ovfreader.h" #include <set> diff --git a/src/VBox/Main/src-all/ExtPackUtil.cpp b/src/VBox/Main/src-all/ExtPackUtil.cpp index 7d3c634b753..f81604736ac 100644 --- a/src/VBox/Main/src-all/ExtPackUtil.cpp +++ b/src/VBox/Main/src-all/ExtPackUtil.cpp @@ -41,7 +41,6 @@ #include <iprt/sha.h> #include <iprt/string.h> #include <iprt/vfs.h> -#include <iprt/tar.h> #include <iprt/zip.h> #include <iprt/cpp/xml.h> diff --git a/src/VBox/Main/src-server/ApplianceImplExport.cpp b/src/VBox/Main/src-server/ApplianceImplExport.cpp index 0d42486f891..002151b1bbf 100644 --- a/src/VBox/Main/src-server/ApplianceImplExport.cpp +++ b/src/VBox/Main/src-server/ApplianceImplExport.cpp @@ -34,6 +34,8 @@ #include <iprt/stream.h> #include <iprt/zip.h> +#include <iprt/formats/tar.h> + #include <VBox/version.h> #include "ApplianceImpl.h" @@ -415,7 +417,7 @@ HRESULT Machine::exportTo(const ComPtr<IAppliance> &aAppliance, const com::Utf8S if (FAILED(hrc)) throw hrc; strTargetImageName = Utf8StrFmt("%s-disk%.3d.vmdk", strBasename.c_str(), ++pAppliance->m->cDisks); - if (strTargetImageName.length() > RTTAR_NAME_MAX) + if (strTargetImageName.length() > RTZIPTAR_NAME_MAX) throw setError(VBOX_E_NOT_SUPPORTED, tr("Cannot attach disk '%s' -- file name too long"), strTargetImageName.c_str()); @@ -506,7 +508,7 @@ HRESULT Machine::exportTo(const ComPtr<IAppliance> &aAppliance, const com::Utf8S continue; strTargetImageName = Utf8StrFmt("%s-disk%.3d.iso", strBasename.c_str(), ++pAppliance->m->cDisks); - if (strTargetImageName.length() > RTTAR_NAME_MAX) + if (strTargetImageName.length() > RTZIPTAR_NAME_MAX) throw setError(VBOX_E_NOT_SUPPORTED, tr("Cannot attach image '%s' -- file name too long"), strTargetImageName.c_str()); diff --git a/src/VBox/Main/src-server/ApplianceImplImport.cpp b/src/VBox/Main/src-server/ApplianceImplImport.cpp index e61f098a250..a9eee22a181 100644 --- a/src/VBox/Main/src-server/ApplianceImplImport.cpp +++ b/src/VBox/Main/src-server/ApplianceImplImport.cpp @@ -33,7 +33,6 @@ #include <iprt/file.h> #include <iprt/sha.h> #include <iprt/manifest.h> -#include <iprt/tar.h> #include <iprt/zip.h> #include <iprt/stream.h> #include <iprt/crypto/digest.h> @@ -42,6 +41,8 @@ #include <iprt/crypto/x509.h> #include <iprt/rand.h> +#include <iprt/formats/tar.h> + #include <VBox/vd.h> #include <VBox/com/array.h> diff --git a/src/VBox/Runtime/Makefile.kmk b/src/VBox/Runtime/Makefile.kmk index 115dc558c9f..053d9f0d6e4 100644 --- a/src/VBox/Runtime/Makefile.kmk +++ b/src/VBox/Runtime/Makefile.kmk @@ -746,7 +746,6 @@ RuntimeBaseR3_SOURCES := \ common/vfs/vfsstdpipe.cpp \ common/vfs/vfsprintf.cpp \ common/zip/cpiovfs.cpp \ - common/zip/tar.cpp \ common/zip/tarcmd.cpp \ common/zip/tarvfs.cpp \ common/zip/tarvfswriter.cpp \ @@ -2455,7 +2454,6 @@ RuntimeBldProg_SOURCES = \ common/vfs/vfsstdfile.cpp \ common/vfs/vfsstdpipe.cpp \ common/zip/gzipvfs.cpp \ - common/zip/tar.cpp \ common/zip/tarcmd.cpp \ common/zip/tarvfs.cpp \ common/zip/tarvfswriter.cpp \ diff --git a/src/VBox/Runtime/common/zip/tar.cpp b/src/VBox/Runtime/common/zip/tar.cpp deleted file mode 100644 index 60f03125b06..00000000000 --- a/src/VBox/Runtime/common/zip/tar.cpp +++ /dev/null @@ -1,713 +0,0 @@ -/* $Id$ */ -/** @file - * IPRT - Tar archive I/O. - */ - -/* - * Copyright (C) 2009-2023 Oracle and/or its affiliates. - * - * This file is part of VirtualBox base platform packages, as - * available from https://www.virtualbox.org. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, in version 3 of the - * License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <https://www.gnu.org/licenses>. - * - * The contents of this file may alternatively be used under the terms - * of the Common Development and Distribution License Version 1.0 - * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included - * in the VirtualBox distribution, in which case the provisions of the - * CDDL are applicable instead of those of the GPL. - * - * You may elect to license modified versions of this file under the - * terms and conditions of either the GPL or the CDDL or both. - * - * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 - */ - - -/********************************************************************************************************************************* -* Header Files * -*********************************************************************************************************************************/ -#include "internal/iprt.h" -#include <iprt/tar.h> - -#include <iprt/asm.h> -#include <iprt/assert.h> -#include <iprt/err.h> -#include <iprt/file.h> -#include <iprt/mem.h> -#include <iprt/path.h> -#include <iprt/string.h> -#include <iprt/vfs.h> -#include <iprt/zip.h> - - -#include "internal/magics.h" -#include "tar.h" - - -/********************************************************************************************************************************* -* Structures and Typedefs * -*********************************************************************************************************************************/ -/** @name RTTARRECORD::h::linkflag - * @{ */ -#define LF_OLDNORMAL '\0' /**< Normal disk file, Unix compatible */ -#define LF_NORMAL '0' /**< Normal disk file */ -#define LF_LINK '1' /**< Link to previously dumped file */ -#define LF_SYMLINK '2' /**< Symbolic link */ -#define LF_CHR '3' /**< Character special file */ -#define LF_BLK '4' /**< Block special file */ -#define LF_DIR '5' /**< Directory */ -#define LF_FIFO '6' /**< FIFO special file */ -#define LF_CONTIG '7' /**< Contiguous file */ -/** @} */ - -/** - * A tar file header. - */ -typedef union RTTARRECORD -{ - char d[512]; - struct h - { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char chksum[8]; - char linkflag; - char linkname[100]; - char magic[8]; - char uname[32]; - char gname[32]; - char devmajor[8]; - char devminor[8]; - } h; -} RTTARRECORD; -AssertCompileSize(RTTARRECORD, 512); -AssertCompileMemberOffset(RTTARRECORD, h.size, 100+8*3); -AssertCompileMemberSize(RTTARRECORD, h.name, RTTAR_NAME_MAX+1); -/** Pointer to a tar file header. */ -typedef RTTARRECORD *PRTTARRECORD; - -/** Pointer to a tar file handle. */ -typedef struct RTTARFILEINTERNAL *PRTTARFILEINTERNAL; - -/** - * The internal data of a tar handle. - */ -typedef struct RTTARINTERNAL -{ - /** The magic (RTTAR_MAGIC). */ - uint32_t u32Magic; - /** The handle to the tar file. */ - RTFILE hTarFile; - /** The open mode for hTarFile. */ - uint32_t fOpenMode; - /** Whether a file within the archive is currently open for writing. - * Only one can be open. */ - bool fFileOpenForWrite; - /** The tar file VFS handle (for reading). */ - RTVFSFILE hVfsFile; - /** The tar file system VFS handle. */ - RTVFSFSSTREAM hVfsFss; - /** Set if hVfsFss is at the start of the stream and doesn't need rewinding. */ - bool fFssAtStart; -} RTTARINTERNAL; -/** Pointer to a the internal data of a tar handle. */ -typedef RTTARINTERNAL* PRTTARINTERNAL; - -/** - * The internal data of a file within a tar file. - */ -typedef struct RTTARFILEINTERNAL -{ - /** The magic (RTTARFILE_MAGIC). */ - uint32_t u32Magic; - /** The open mode. */ - uint32_t fOpenMode; - /** Pointer to back to the tar file. */ - PRTTARINTERNAL pTar; - /** The name of the file. */ - char *pszFilename; - /** The offset into the archive where the file header starts. */ - uint64_t offStart; - /** The size of the file. */ - uint64_t cbSize; - /** The size set by RTTarFileSetSize(). */ - uint64_t cbSetSize; - /** The current offset within this file. */ - uint64_t offCurrent; - /** The VFS I/O stream (only for reading atm). */ - RTVFSIOSTREAM hVfsIos; -} RTTARFILEINTERNAL; -/** Pointer to the internal data of a tar file. */ -typedef RTTARFILEINTERNAL *PRTTARFILEINTERNAL; - - - -/********************************************************************************************************************************* -* Defined Constants And Macros * -*********************************************************************************************************************************/ - -/** Validates a handle and returns VERR_INVALID_HANDLE if not valid. */ -/* RTTAR */ -#define RTTAR_VALID_RETURN_RC(hHandle, rc) \ - do { \ - AssertPtrReturn((hHandle), (rc)); \ - AssertReturn((hHandle)->u32Magic == RTTAR_MAGIC, (rc)); \ - } while (0) -/* RTTARFILE */ -#define RTTARFILE_VALID_RETURN_RC(hHandle, rc) \ - do { \ - AssertPtrReturn((hHandle), (rc)); \ - AssertReturn((hHandle)->u32Magic == RTTARFILE_MAGIC, (rc)); \ - } while (0) - -/** Validates a handle and returns VERR_INVALID_HANDLE if not valid. */ -/* RTTAR */ -#define RTTAR_VALID_RETURN(hHandle) RTTAR_VALID_RETURN_RC((hHandle), VERR_INVALID_HANDLE) -/* RTTARFILE */ -#define RTTARFILE_VALID_RETURN(hHandle) RTTARFILE_VALID_RETURN_RC((hHandle), VERR_INVALID_HANDLE) - -/** Validates a handle and returns (void) if not valid. */ -/* RTTAR */ -#define RTTAR_VALID_RETURN_VOID(hHandle) \ - do { \ - AssertPtrReturnVoid(hHandle); \ - AssertReturnVoid((hHandle)->u32Magic == RTTAR_MAGIC); \ - } while (0) -/* RTTARFILE */ -#define RTTARFILE_VALID_RETURN_VOID(hHandle) \ - do { \ - AssertPtrReturnVoid(hHandle); \ - AssertReturnVoid((hHandle)->u32Magic == RTTARFILE_MAGIC); \ - } while (0) - - -RTR3DECL(int) RTTarOpen(PRTTAR phTar, const char *pszTarname, uint32_t fMode) -{ - AssertReturn(fMode & RTFILE_O_WRITE, VERR_INVALID_PARAMETER); - - /* - * Create a tar instance. - */ - PRTTARINTERNAL pThis = (PRTTARINTERNAL)RTMemAllocZ(sizeof(RTTARINTERNAL)); - if (!pThis) - return VERR_NO_MEMORY; - - pThis->u32Magic = RTTAR_MAGIC; - pThis->fOpenMode = fMode; - pThis->hVfsFile = NIL_RTVFSFILE; - pThis->hVfsFss = NIL_RTVFSFSSTREAM; - pThis->fFssAtStart = false; - - /* - * Open the tar file. - */ - int rc = RTFileOpen(&pThis->hTarFile, pszTarname, fMode); - if (RT_SUCCESS(rc)) - { - *phTar = pThis; - return VINF_SUCCESS; - } - - RTMemFree(pThis); - return rc; -} - - -RTR3DECL(int) RTTarClose(RTTAR hTar) -{ - if (hTar == NIL_RTTAR) - return VINF_SUCCESS; - - PRTTARINTERNAL pInt = hTar; - RTTAR_VALID_RETURN(pInt); - - int rc = VINF_SUCCESS; - - /* gtar gives a warning, but the documentation says EOF is indicated by a - * zero block. Disabled for now. */ -#if 0 - { - /* Append the EOF record which is filled all by zeros */ - RTTARRECORD record; - RT_ZERO(record); - rc = RTFileWrite(pInt->hTarFile, &record, sizeof(record), NULL); - } -#endif - - if (pInt->hVfsFss != NIL_RTVFSFSSTREAM) - { - uint32_t cRefs = RTVfsFsStrmRelease(pInt->hVfsFss); Assert(cRefs != UINT32_MAX); NOREF(cRefs); - pInt->hVfsFss = NIL_RTVFSFSSTREAM; - } - - if (pInt->hVfsFile != NIL_RTVFSFILE) - { - uint32_t cRefs = RTVfsFileRelease(pInt->hVfsFile); Assert(cRefs != UINT32_MAX); NOREF(cRefs); - pInt->hVfsFile = NIL_RTVFSFILE; - } - - if (pInt->hTarFile != NIL_RTFILE) - { - rc = RTFileClose(pInt->hTarFile); - pInt->hTarFile = NIL_RTFILE; - } - - pInt->u32Magic = RTTAR_MAGIC_DEAD; - - RTMemFree(pInt); - - return rc; -} - - -/** - * Creates a tar file handle for a read-only VFS stream object. - * - * @returns IPRT status code. - * @param pszName The file name. Automatically freed on failure. - * @param hVfsIos The VFS I/O stream we create the handle around. - * The reference is NOT consumed. - * @param fOpen The open flags. - * @param ppFile Where to return the handle. - */ -static int rtTarFileCreateHandleForReadOnly(char *pszName, RTVFSIOSTREAM hVfsIos, uint32_t fOpen, PRTTARFILEINTERNAL *ppFile) -{ - int rc; - PRTTARFILEINTERNAL pNewFile = (PRTTARFILEINTERNAL)RTMemAllocZ(sizeof(*pNewFile)); - if (pNewFile) - { - RTFSOBJINFO ObjInfo; - rc = RTVfsIoStrmQueryInfo(hVfsIos, &ObjInfo, RTFSOBJATTRADD_UNIX); - if (RT_SUCCESS(rc)) - { - pNewFile->u32Magic = RTTARFILE_MAGIC; - pNewFile->pTar = NULL; - pNewFile->pszFilename = pszName; - pNewFile->offStart = UINT64_MAX; - pNewFile->cbSize = ObjInfo.cbObject; - pNewFile->cbSetSize = 0; - pNewFile->offCurrent = 0; - pNewFile->fOpenMode = fOpen; - pNewFile->hVfsIos = hVfsIos; - - uint32_t cRefs = RTVfsIoStrmRetain(hVfsIos); Assert(cRefs != UINT32_MAX); NOREF(cRefs); - - *ppFile = pNewFile; - return VINF_SUCCESS; - } - - RTMemFree(pNewFile); - } - else - rc = VERR_NO_MEMORY; - RTStrFree(pszName); - return rc; -} - - -/* Only used for write handles. */ -static PRTTARFILEINTERNAL rtTarFileCreateForWrite(PRTTARINTERNAL pInt, const char *pszFilename, uint32_t fOpen) -{ - PRTTARFILEINTERNAL pFileInt = (PRTTARFILEINTERNAL)RTMemAllocZ(sizeof(RTTARFILEINTERNAL)); - if (!pFileInt) - return NULL; - - pFileInt->u32Magic = RTTARFILE_MAGIC; - pFileInt->pTar = pInt; - pFileInt->fOpenMode = fOpen; - pFileInt->pszFilename = RTStrDup(pszFilename); - pFileInt->hVfsIos = NIL_RTVFSIOSTREAM; - if (pFileInt->pszFilename) - return pFileInt; - - RTMemFree(pFileInt); - return NULL; - -} - - -RTR3DECL(int) RTTarFileOpen(RTTAR hTar, PRTTARFILE phFile, const char *pszFilename, uint32_t fOpen) -{ - /* Write only interface now. */ - AssertReturn(fOpen & RTFILE_O_WRITE, VERR_INVALID_PARAMETER); - - PRTTARINTERNAL pInt = hTar; - RTTAR_VALID_RETURN(pInt); - - if (!pInt->hTarFile) - return VERR_INVALID_HANDLE; - - if (fOpen & RTFILE_O_WRITE) - { - if (!(pInt->fOpenMode & RTFILE_O_WRITE)) - return VERR_WRITE_PROTECT; - if (pInt->fFileOpenForWrite) - return VERR_TOO_MANY_OPEN_FILES; - } - - int rc = VINF_SUCCESS; - if (!(fOpen & RTFILE_O_WRITE)) - { - /* - * Rewind the stream if necessary. - */ - if (!pInt->fFssAtStart) - { - if (pInt->hVfsFss != NIL_RTVFSFSSTREAM) - { - uint32_t cRefs = RTVfsFsStrmRelease(pInt->hVfsFss); Assert(cRefs != UINT32_MAX); NOREF(cRefs); - pInt->hVfsFss = NIL_RTVFSFSSTREAM; - } - - if (pInt->hVfsFile == NIL_RTVFSFILE) - { - rc = RTVfsFileFromRTFile(pInt->hTarFile, RTFILE_O_READ, true /*fLeaveOpen*/, &pInt->hVfsFile); - if (RT_FAILURE(rc)) - return rc; - } - - RTVFSIOSTREAM hVfsIos = RTVfsFileToIoStream(pInt->hVfsFile); - rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0 /*fFlags*/, &pInt->hVfsFss); - RTVfsIoStrmRelease(hVfsIos); - if (RT_FAILURE(rc)) - return rc; - } - - /* - * Search the file system stream. - */ - pInt->fFssAtStart = false; - for (;;) - { - char *pszName; - RTVFSOBJTYPE enmType; - RTVFSOBJ hVfsObj; - rc = RTVfsFsStrmNext(pInt->hVfsFss, &pszName, &enmType, &hVfsObj); - if (rc == VERR_EOF) - return VERR_FILE_NOT_FOUND; - if (RT_FAILURE(rc)) - return rc; - - if (!RTStrCmp(pszName, pszFilename)) - { - if (enmType == RTVFSOBJTYPE_FILE || enmType == RTVFSOBJTYPE_IO_STREAM) - rc = rtTarFileCreateHandleForReadOnly(pszName, RTVfsObjToIoStream(hVfsObj), fOpen, phFile); - else - { - rc = VERR_UNEXPECTED_FS_OBJ_TYPE; - RTStrFree(pszName); - } - RTVfsObjRelease(hVfsObj); - break; - } - RTStrFree(pszName); - RTVfsObjRelease(hVfsObj); - } /* Search loop. */ - } - else - { - PRTTARFILEINTERNAL pFileInt = rtTarFileCreateForWrite(pInt, pszFilename, fOpen); - if (!pFileInt) - return VERR_NO_MEMORY; - - pInt->fFileOpenForWrite = true; - - /* If we are in write mode, we also in append mode. Add an dummy - * header at the end of the current file. It will be filled by the - * close operation. */ - rc = RTFileSeek(pFileInt->pTar->hTarFile, 0, RTFILE_SEEK_END, &pFileInt->offStart); - if (RT_SUCCESS(rc)) - { - RTTARRECORD record; - RT_ZERO(record); - rc = RTFileWrite(pFileInt->pTar->hTarFile, &record, sizeof(RTTARRECORD), NULL); - } - - if (RT_SUCCESS(rc)) - *phFile = (RTTARFILE)pFileInt; - else - { - /* Cleanup on failure */ - if (pFileInt->pszFilename) - RTStrFree(pFileInt->pszFilename); - RTMemFree(pFileInt); - } - } - - return rc; -} - - -static void rtTarSizeToRec(PRTTARRECORD pRecord, uint64_t cbSize) -{ - /* - * Small enough for the standard octal string encoding? - * - * Note! We could actually use the terminator character as well if we liked, - * but let not do that as it's easier to test this way. - */ - if (cbSize < _4G * 2U) - RTStrPrintf(pRecord->h.size, sizeof(pRecord->h.size), "%0.11llo", cbSize); - else - { - /* - * Base 256 extension. Set the highest bit of the left most character. - * We don't deal with negatives here, cause the size have to be greater - * than zero. - * - * Note! The base-256 extension are never used by gtar or libarchive - * with the "ustar \0" format version, only the later - * "ustar\000" version. However, this shouldn't cause much - * trouble as they are not picky about what they read. - */ - size_t cchField = sizeof(pRecord->h.size) - 1; - unsigned char *puchField = (unsigned char*)pRecord->h.size; - puchField[0] = 0x80; - do - { - puchField[cchField--] = cbSize & 0xff; - cbSize >>= 8; - } while (cchField); - } -} - - -static int rtTarCreateHeaderRecord(PRTTARRECORD pRecord, const char *pszSrcName, uint64_t cbSize, - RTUID uid, RTGID gid, RTFMODE fmode, int64_t mtime) -{ - /** @todo check for field overflows. */ - /* Fill the header record */ -// RT_ZERO(pRecord); - done by the caller. - /** @todo use RTStrCopy */ - size_t cb = RTStrPrintf(pRecord->h.name, sizeof(pRecord->h.name), "%s", pszSrcName); - if (cb < strlen(pszSrcName)) - return VERR_BUFFER_OVERFLOW; - RTStrPrintf(pRecord->h.mode, sizeof(pRecord->h.mode), "%0.7o", fmode); - RTStrPrintf(pRecord->h.uid, sizeof(pRecord->h.uid), "%0.7o", uid); - RTStrPrintf(pRecord->h.gid, sizeof(pRecord->h.gid), "%0.7o", gid); - rtTarSizeToRec(pRecord, cbSize); - RTStrPrintf(pRecord->h.mtime, sizeof(pRecord->h.mtime), "%0.11llo", mtime); - RTStrPrintf(pRecord->h.magic, sizeof(pRecord->h.magic), "ustar "); - RTStrPrintf(pRecord->h.uname, sizeof(pRecord->h.uname), "someone"); - RTStrPrintf(pRecord->h.gname, sizeof(pRecord->h.gname), "someone"); - pRecord->h.linkflag = LF_NORMAL; - - /* Create the checksum out of the new header */ - int32_t iUnsignedChksum, iSignedChksum; - if (rtZipTarCalcChkSum((PCRTZIPTARHDR)pRecord, &iUnsignedChksum, &iSignedChksum)) - return VERR_TAR_END_OF_FILE; - - /* Format the checksum */ - RTStrPrintf(pRecord->h.chksum, sizeof(pRecord->h.chksum), "%0.7o", iUnsignedChksum); - - return VINF_SUCCESS; -} - - -DECLINLINE(void *) rtTarMemTmpAlloc(size_t *pcbSize) -{ - *pcbSize = 0; - /* Allocate a reasonably large buffer, fall back on a tiny one. - * Note: has to be 512 byte aligned and >= 512 byte. */ - size_t cbTmp = _1M; - void *pvTmp = RTMemTmpAlloc(cbTmp); - if (!pvTmp) - { - cbTmp = sizeof(RTTARRECORD); - pvTmp = RTMemTmpAlloc(cbTmp); - } - *pcbSize = cbTmp; - return pvTmp; -} - - -static int rtTarAppendZeros(PRTTARFILEINTERNAL pFileInt, uint64_t cbSize) -{ - /* Allocate a temporary buffer for copying the tar content in blocks. */ - size_t cbTmp = 0; - void *pvTmp = rtTarMemTmpAlloc(&cbTmp); - if (!pvTmp) - return VERR_NO_MEMORY; - RT_BZERO(pvTmp, cbTmp); - - int rc = VINF_SUCCESS; - uint64_t cbAllWritten = 0; - size_t cbWritten = 0; - for (;;) - { - if (cbAllWritten >= cbSize) - break; - size_t cbToWrite = RT_MIN(cbSize - cbAllWritten, cbTmp); - rc = RTTarFileWriteAt(pFileInt, pFileInt->offCurrent, pvTmp, cbToWrite, &cbWritten); - if (RT_FAILURE(rc)) - break; - cbAllWritten += cbWritten; - } - - RTMemTmpFree(pvTmp); - - return rc; -} - - -RTR3DECL(int) RTTarFileClose(RTTARFILE hFile) -{ - /* Already closed? */ - if (hFile == NIL_RTTARFILE) - return VINF_SUCCESS; - - PRTTARFILEINTERNAL pFileInt = hFile; - RTTARFILE_VALID_RETURN(pFileInt); - - int rc = VINF_SUCCESS; - - /* In write mode: */ - if ((pFileInt->fOpenMode & (RTFILE_O_WRITE | RTFILE_O_READ)) == RTFILE_O_WRITE) - { - pFileInt->pTar->fFileOpenForWrite = false; - do - { - /* If the user has called RTTarFileSetSize in the meantime, we have - to make sure the file has the right size. */ - if (pFileInt->cbSetSize > pFileInt->cbSize) - { - rc = rtTarAppendZeros(pFileInt, pFileInt->cbSetSize - pFileInt->cbSize); - if (RT_FAILURE(rc)) - break; - } - - /* If the written size isn't 512 byte aligned, we need to fix this. */ - RTTARRECORD record; - RT_ZERO(record); - uint64_t cbSizeAligned = RT_ALIGN(pFileInt->cbSize, sizeof(RTTARRECORD)); - if (cbSizeAligned != pFileInt->cbSize) - { - /* Note the RTFile method. We didn't increase the cbSize or cbCurrentPos here. */ - rc = RTFileWriteAt(pFileInt->pTar->hTarFile, - pFileInt->offStart + sizeof(RTTARRECORD) + pFileInt->cbSize, - &record, - cbSizeAligned - pFileInt->cbSize, - NULL); - if (RT_FAILURE(rc)) - break; - } - - /* Create a header record for the file */ - /** @todo mode, gid, uid, mtime should be setable (or detected myself) */ - RTTIMESPEC time; - RTTimeNow(&time); - rc = rtTarCreateHeaderRecord(&record, pFileInt->pszFilename, pFileInt->cbSize, - 0, 0, 0600, RTTimeSpecGetSeconds(&time)); - if (RT_FAILURE(rc)) - break; - - /* Write this at the start of the file data */ - rc = RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->offStart, &record, sizeof(RTTARRECORD), NULL); - if (RT_FAILURE(rc)) - break; - } - while (0); - } - - /* - * Now cleanup and delete the handle. - */ - if (pFileInt->pszFilename) - RTStrFree(pFileInt->pszFilename); - if (pFileInt->hVfsIos != NIL_RTVFSIOSTREAM) - { - RTVfsIoStrmRelease(pFileInt->hVfsIos); - pFileInt->hVfsIos = NIL_RTVFSIOSTREAM; - } - pFileInt->u32Magic = RTTARFILE_MAGIC_DEAD; - RTMemFree(pFileInt); - - return rc; -} - - -RTR3DECL(int) RTTarFileReadAt(RTTARFILE hFile, uint64_t off, void *pvBuf, size_t cbToRead, size_t *pcbRead) -{ - PRTTARFILEINTERNAL pFileInt = hFile; - RTTARFILE_VALID_RETURN(pFileInt); - - size_t cbTmpRead = 0; - int rc = RTVfsIoStrmReadAt(pFileInt->hVfsIos, off, pvBuf, cbToRead, true /*fBlocking*/, &cbTmpRead); - if (RT_SUCCESS(rc)) - { - pFileInt->offCurrent = off + cbTmpRead; - if (pcbRead) - *pcbRead = cbTmpRead; - if (rc == VINF_EOF) - rc = pcbRead ? VINF_SUCCESS : VERR_EOF; - } - else if (pcbRead) - *pcbRead = 0; - return rc; -} - - -RTR3DECL(int) RTTarFileWriteAt(RTTARFILE hFile, uint64_t off, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten) -{ - PRTTARFILEINTERNAL pFileInt = hFile; - RTTARFILE_VALID_RETURN(pFileInt); - - if ((pFileInt->fOpenMode & RTFILE_O_WRITE) != RTFILE_O_WRITE) - return VERR_ACCESS_DENIED; - - size_t cbTmpWritten = 0; - int rc = RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->offStart + 512 + off, pvBuf, cbToWrite, &cbTmpWritten); - pFileInt->cbSize += cbTmpWritten; - pFileInt->offCurrent = off + cbTmpWritten; - if (pcbWritten) - *pcbWritten = cbTmpWritten; - - return rc; -} - - -RTR3DECL(int) RTTarFileGetSize(RTTARFILE hFile, uint64_t *pcbSize) -{ - /* Validate input */ - AssertPtrReturn(pcbSize, VERR_INVALID_POINTER); - - PRTTARFILEINTERNAL pFileInt = hFile; - RTTARFILE_VALID_RETURN(pFileInt); - - *pcbSize = RT_MAX(pFileInt->cbSetSize, pFileInt->cbSize); - - return VINF_SUCCESS; -} - - -RTR3DECL(int) RTTarFileSetSize(RTTARFILE hFile, uint64_t cbSize) -{ - PRTTARFILEINTERNAL pFileInt = hFile; - RTTARFILE_VALID_RETURN(pFileInt); - - if ((pFileInt->fOpenMode & RTFILE_O_WRITE) != RTFILE_O_WRITE) - return VERR_WRITE_ERROR; - - /** @todo If cbSize is smaller than pFileInt->cbSize we have to - * truncate the current file. */ - pFileInt->cbSetSize = cbSize; - - return VINF_SUCCESS; -} - diff --git a/src/VBox/Runtime/common/zip/tarvfs.cpp b/src/VBox/Runtime/common/zip/tarvfs.cpp index 02513a54c8a..269f2bc2609 100644 --- a/src/VBox/Runtime/common/zip/tarvfs.cpp +++ b/src/VBox/Runtime/common/zip/tarvfs.cpp @@ -51,7 +51,7 @@ #include <iprt/vfs.h> #include <iprt/vfslowlevel.h> -#include "tar.h" +#include <iprt/formats/tar.h> #include "tarvfsreader.h" diff --git a/src/VBox/Runtime/common/zip/tarvfsreader.h b/src/VBox/Runtime/common/zip/tarvfsreader.h index 6bec4f25612..4f0c0828ec8 100644 --- a/src/VBox/Runtime/common/zip/tarvfsreader.h +++ b/src/VBox/Runtime/common/zip/tarvfsreader.h @@ -40,7 +40,7 @@ # pragma once #endif -#include "tar.h" +#include <iprt/formats/tar.h> /** diff --git a/src/VBox/Runtime/common/zip/tarvfswriter.cpp b/src/VBox/Runtime/common/zip/tarvfswriter.cpp index 43f791142cb..baf5713c3d9 100644 --- a/src/VBox/Runtime/common/zip/tarvfswriter.cpp +++ b/src/VBox/Runtime/common/zip/tarvfswriter.cpp @@ -52,7 +52,7 @@ #include <iprt/vfslowlevel.h> #include <iprt/zero.h> -#include "tar.h" +#include <iprt/formats/tar.h> #include "tarvfsreader.h" diff --git a/src/VBox/Runtime/include/internal/magics.h b/src/VBox/Runtime/include/internal/magics.h index 1d553bc456e..90d33db2343 100644 --- a/src/VBox/Runtime/include/internal/magics.h +++ b/src/VBox/Runtime/include/internal/magics.h @@ -237,14 +237,6 @@ #define RTTCPSERVER_MAGIC UINT32_C(0x19470304) /** Magic value for RTTCPSERVER::u32Magic. (Harlan Ellison) */ #define RTUDPSERVER_MAGIC UINT32_C(0x19340527) -/** The value of RTTAR::u32Magic. (Donald Ervin Knuth) */ -#define RTTAR_MAGIC UINT32_C(0x19380110) -/** The value of RTTAR::u32Magic after RTTarClose(). */ -#define RTTAR_MAGIC_DEAD ~RTTAR_MAGIC -/** The value of RTTARFILE::u32Magic. (Abraham Stoker) */ -#define RTTARFILE_MAGIC UINT32_C(0x18471108) -/** The value of RTTARFILE::u32Magic after RTTarFileClose(). */ -#define RTTARFILE_MAGIC_DEAD UINT32_C(0x19120420) /** RTTESTINT::u32Magic value. (Daniel Kehlmann) */ #define RTTESTINT_MAGIC UINT32_C(0x19750113) /** RTTHREADCTXHOOKINT::u32Magic value. (Dennis MacAlistair Ritchie) */ |