53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync/* $Id$ */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync/** @file
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * IPRT - Manifest Utility.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2010-2011 Oracle Corporation
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync *
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * available from http://www.virtualbox.org. This file is free software;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * you can redistribute it and/or modify it under the terms of the GNU
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * General Public License (GPL) as published by the Free Software
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync *
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * The contents of this file may alternatively be used under the terms
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * of the Common Development and Distribution License Version 1.0
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * VirtualBox OSE distribution, in which case the provisions of the
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * CDDL are applicable instead of those of the GPL.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync *
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * You may elect to license modified versions of this file under the
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * terms and conditions of either the GPL or the CDDL or both.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync/*******************************************************************************
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync* Header Files *
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync*******************************************************************************/
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync#include <iprt/manifest.h>
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync#include <iprt/buildconfig.h>
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync#include <iprt/err.h>
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync#include <iprt/file.h>
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync#include <iprt/getopt.h>
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync#include <iprt/initterm.h>
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync#include <iprt/message.h>
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync#include <iprt/path.h>
e078c42d830539a4c29a33b8f09fc28647686743vboxsync#include <iprt/process.h>
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync#include <iprt/stream.h>
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync#include <iprt/string.h>
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync#include <iprt/vfs.h>
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync/**
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * Verify a manifest.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync *
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @returns Program exit code, failures with error message.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @param pszManifest The manifest file. NULL if standard input.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @param fStdFormat Whether to expect standard format (true) or
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * java format (false).
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @param pszChDir The directory to change into before processing
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * the files in the manifest.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsyncstatic RTEXITCODE rtManifestDoVerify(const char *pszManifest, bool fStdFormat, const char *pszChDir)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync{
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync /*
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * Open the manifest.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync int rc;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTVFSIOSTREAM hVfsIos;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (!pszManifest)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_INPUT, RTFILE_O_READ, false /*fLeaveOpen*/, &hVfsIos);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_FAILURE(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to prepare standard input for reading: %Rrc", rc);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync else
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync const char *pszError;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = RTVfsChainOpenIoStream(pszManifest, RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN, &hVfsIos, &pszError);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_FAILURE(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (pszError && *pszError)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE,
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync "RTVfsChainOpenIoStream failed with rc=%Rrc:\n"
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync " '%s'\n",
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync " %*s^\n",
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc, pszManifest, pszError - pszManifest, "");
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE,
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync "Failed with %Rrc opening the input manifest '%s'", rc, pszManifest);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync /*
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * Read it.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTMANIFEST hManifest;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = RTManifestCreate(0 /*fFlags*/, &hManifest);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_SUCCESS(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (fStdFormat)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync char szErr[4096 + 1024];
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = RTManifestReadStandardEx(hManifest, hVfsIos, szErr, sizeof(szErr));
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_SUCCESS(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTVfsIoStrmRelease(hVfsIos);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync hVfsIos = NIL_RTVFSIOSTREAM;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync /*
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * Do the verification.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync /** @todo We're missing some enumeration APIs here! */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTMsgError("The manifest read fine, but the actual verification code is yet to be written. Sorry.");
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = VERR_NOT_IMPLEMENTED;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync#if 1 /* For now, just write the manifest to stdout so we can test the read routine. */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTVFSIOSTREAM hVfsIosOut;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_OUTPUT, RTFILE_O_WRITE, false /*fLeaveOpen*/, &hVfsIosOut);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_SUCCESS(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTManifestWriteStandard(hManifest, hVfsIosOut);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTVfsIoStrmRelease(hVfsIosOut);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync#endif
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync else if (szErr[0])
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTMsgError("Error reading manifest: %s", szErr);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync else
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTMsgError("Error reading manifest: %Rrc", rc);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync else
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTMsgError("Support for Java manifest files is not implemented yet");
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = VERR_NOT_IMPLEMENTED;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTManifestRelease(hManifest);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTVfsIoStrmRelease(hVfsIos);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync}
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync/**
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * Adds a file to the manifest.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync *
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @returns IPRT status code, failures with error message.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @param hManifest The manifest to add it to.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @param pszFilename The name of the file to add.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @param fAttr The manifest attributes to add.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsyncstatic int rtManifestAddFileToManifest(RTMANIFEST hManifest, const char *pszFilename, uint32_t fAttr)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync{
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTVFSIOSTREAM hVfsIos;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync const char *pszError;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync int rc = RTVfsChainOpenIoStream(pszFilename, RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN, &hVfsIos, &pszError);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_FAILURE(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (pszError && *pszError)
36fed7bf894fc0880657eeaf16cc97bbc745b593vboxsync RTMsgError("RTVfsChainOpenIoStream failed with rc=%Rrc:\n"
36fed7bf894fc0880657eeaf16cc97bbc745b593vboxsync " '%s'\n",
36fed7bf894fc0880657eeaf16cc97bbc745b593vboxsync " %*s^\n",
36fed7bf894fc0880657eeaf16cc97bbc745b593vboxsync rc, pszFilename, pszError - pszFilename, "");
36fed7bf894fc0880657eeaf16cc97bbc745b593vboxsync else
36fed7bf894fc0880657eeaf16cc97bbc745b593vboxsync RTMsgError("Failed with %Rrc opening '%s'", rc, pszFilename);
36fed7bf894fc0880657eeaf16cc97bbc745b593vboxsync return rc;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = RTManifestEntryAddIoStream(hManifest, hVfsIos, pszFilename, fAttr);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_FAILURE(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTMsgError("RTManifestEntryAddIoStream failed for '%s': %Rrc", rc);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTVfsIoStrmRelease(hVfsIos);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return rc;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync}
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync/**
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * Create a manifest from the specified input files.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync *
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @returns Program exit code, failures with error message.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @param pszManifest The name of the output manifest file. NULL if
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * it should be written to standard output.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @param fStdFormat Whether to expect standard format (true) or
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * java format (false).
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @param pszChDir The directory to change into before processing
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * the file arguments.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @param fAttr The file attributes to put in the manifest.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @param pGetState The RTGetOpt state.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @param pUnion What the last RTGetOpt() call returned.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * @param chOpt What the last RTGetOpt() call returned.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsyncstatic RTEXITCODE rtManifestDoCreate(const char *pszManifest, bool fStdFormat, const char *pszChDir, uint32_t fAttr,
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync PRTGETOPTSTATE pGetState, PRTGETOPTUNION pUnion, int chOpt)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync{
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync /*
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * Open the manifest file.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync int rc;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTVFSIOSTREAM hVfsIos;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (!pszManifest)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_OUTPUT, RTFILE_O_WRITE, false /*fLeaveOpen*/, &hVfsIos);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_FAILURE(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to prepare standard output for writing: %Rrc", rc);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync else
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync const char *pszError;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = RTVfsChainOpenIoStream(pszManifest, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE,
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync &hVfsIos, &pszError);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_FAILURE(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (pszError && *pszError)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE,
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync "RTVfsChainOpenIoStream failed with rc=%Rrc:\n"
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync " '%s'\n",
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync " %*s^\n",
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc, pszManifest, pszError - pszManifest, "");
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE,
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync "Failed with %Rrc opening the manifest '%s'", rc, pszManifest);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync /*
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * Create the internal manifest.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTMANIFEST hManifest;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = RTManifestCreate(0 /*fFlags*/, &hManifest);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_SUCCESS(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync /*
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * Change directory and start processing the specified files.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (pszChDir)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = RTPathSetCurrent(pszChDir);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_FAILURE(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTMsgError("Failed to change directory to '%s': %Rrc", pszChDir, rc);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_SUCCESS(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync while (chOpt == VINF_GETOPT_NOT_OPTION)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = rtManifestAddFileToManifest(hManifest, pUnion->psz, fAttr);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_FAILURE(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync break;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync /* next */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync chOpt = RTGetOpt(pGetState, pUnion);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
36fed7bf894fc0880657eeaf16cc97bbc745b593vboxsync if (RT_SUCCESS(rc) && chOpt != 0)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTGetOptPrintError(chOpt, pUnion);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = chOpt < 0 ? chOpt : -chOpt;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync /*
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * Write the manifest.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_SUCCESS(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (fStdFormat)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = RTManifestWriteStandard(hManifest, hVfsIos);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_FAILURE(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTMsgError("RTManifestWriteStandard failed: %Rrc", rc);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync else
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTMsgError("Support for Java manifest files is not implemented yet");
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = VERR_NOT_IMPLEMENTED;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTManifestRelease(hManifest);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTVfsIoStrmRelease(hVfsIos);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync}
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsyncint main(int argc, char **argv)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync{
230bd8589bba39933ac5ec21482d6186d675e604vboxsync int rc = RTR3InitExe(argc, &argv, 0);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_FAILURE(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTMsgInitFailure(rc);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync /*
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * Parse arguments.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync static RTGETOPTDEF const s_aOptions[] =
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync { "--manifest", 'm', RTGETOPT_REQ_STRING },
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync { "--java", 'j', RTGETOPT_REQ_NOTHING },
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync { "--chdir", 'C', RTGETOPT_REQ_STRING },
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync { "--attribute", 'a', RTGETOPT_REQ_STRING },
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync { "--verify", 'v', RTGETOPT_REQ_NOTHING },
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync };
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync bool fVerify = false;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync bool fStdFormat = true;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync const char *pszManifest = NULL;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync const char *pszChDir = NULL;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync uint32_t fAttr = RTMANIFEST_ATTR_UNKNOWN;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTGETOPTSTATE GetState;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (RT_FAILURE(rc))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptInit failed: %Rrc", rc);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTGETOPTUNION ValueUnion;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync while ( (rc = RTGetOpt(&GetState, &ValueUnion)) != 0
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync && rc != VINF_GETOPT_NOT_OPTION)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync switch (rc)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync case 'a':
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync static struct
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync const char *pszAttr;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync uint32_t fAttr;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync } s_aAttributes[] =
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync { "size", RTMANIFEST_ATTR_SIZE },
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync { "md5", RTMANIFEST_ATTR_MD5 },
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync { "sha1", RTMANIFEST_ATTR_SHA1 },
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync { "sha256", RTMANIFEST_ATTR_SHA256 },
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync { "sha512", RTMANIFEST_ATTR_SHA512 }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync };
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync uint32_t fThisAttr = RTMANIFEST_ATTR_UNKNOWN;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync for (unsigned i = 0; i < RT_ELEMENTS(s_aAttributes); i++)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (!RTStrICmp(s_aAttributes[i].pszAttr, ValueUnion.psz))
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync fThisAttr = s_aAttributes[i].fAttr;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync break;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (fThisAttr == RTMANIFEST_ATTR_UNKNOWN)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown attribute type '%s'", ValueUnion.psz);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (fAttr == RTMANIFEST_ATTR_UNKNOWN)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync fAttr = fThisAttr;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync else
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync fAttr |= fThisAttr;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync break;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync case 'j':
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync fStdFormat = false;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync break;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync case 'm':
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (pszManifest)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Only one manifest can be specified");
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync pszManifest = ValueUnion.psz;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync break;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync case 'v':
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync fVerify = true;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync break;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync case 'C':
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (pszChDir)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Only one directory change can be specified");
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync pszChDir = ValueUnion.psz;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync break;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync case 'h':
e078c42d830539a4c29a33b8f09fc28647686743vboxsync RTPrintf("Usage: %s [--manifest <file>] [--chdir <dir>] [--attribute <attrib-name> [..]] <files>\n"
e078c42d830539a4c29a33b8f09fc28647686743vboxsync " or %s --verify [--manifest <file>] [--chdir <dir>]\n"
e078c42d830539a4c29a33b8f09fc28647686743vboxsync "\n"
e078c42d830539a4c29a33b8f09fc28647686743vboxsync "attrib-name: size, md5, sha1, sha256 or sha512\n"
e078c42d830539a4c29a33b8f09fc28647686743vboxsync , RTProcShortName(), RTProcShortName());
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTEXITCODE_SUCCESS;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync case 'V':
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision());
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTEXITCODE_SUCCESS;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync default:
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTGetOptPrintError(rc, &ValueUnion);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync /*
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync * Take action.
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync */
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTEXITCODE rcExit;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (!fVerify)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (rc != VINF_GETOPT_NOT_OPTION)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync RTMsgWarning("No files specified, the manifest will be empty.");
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (fAttr == RTMANIFEST_ATTR_UNKNOWN)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync fAttr = RTMANIFEST_ATTR_SIZE | RTMANIFEST_ATTR_MD5
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync | RTMANIFEST_ATTR_SHA1 | RTMANIFEST_ATTR_SHA256 | RTMANIFEST_ATTR_SHA512;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rcExit = rtManifestDoCreate(pszManifest, fStdFormat, pszChDir, fAttr, &GetState, &ValueUnion, rc);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync else
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync {
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (rc == VINF_GETOPT_NOT_OPTION)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX,
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync "No files should be specified when verifying a manifest (--verfiy), "
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync "only a manifest via the --manifest option");
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync if (fAttr != RTMANIFEST_ATTR_UNKNOWN)
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX,
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync "The --attribute (-a) option does not combine with --verify (-v)");
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync rcExit = rtManifestDoVerify(pszManifest, fStdFormat, pszChDir);
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync }
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync return rcExit;
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync}
53ef3f0380481e398f8edd344fc07b4e5763ba65vboxsync