ExtPackUtil.cpp revision 710d24589d0cbe0ea6e9ad143eda5bbd41000693
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * VirtualBox Main - Extension Pack Utilities and definitions, VBoxC, VBoxSVC, ++.
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * Copyright (C) 2010 Oracle Corporation
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * This file is part of VirtualBox Open Source Edition (OSE), as
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * available from http://www.virtualbox.org. This file is free software;
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * you can redistribute it and/or modify it under the terms of the GNU
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * General Public License (GPL) as published by the Free Software
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * Foundation, in version 2 as it comes in the "COPYING" file of the
ccf9d4a5c6453fa9f8b839baeee25147865fbb7dJames Phillpotts * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts/*******************************************************************************
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts* Header Files *
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts*******************************************************************************/
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * Reads the extension pack description.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * @returns NULL on success, pointer to an error message on failure (caller
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * deletes it).
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * @param a_pszDir The directory containing the description file.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * @param a_pExtPackDesc Where to store the description file.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * @param a_pObjInfo Where to store the object info for the file (unix
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * attribs). Optional.
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Joosteiprt::MiniString *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo)
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste * Clear the description.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * Validate, open and parse the XML file.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts int vrc = RTPathJoin(szFilePath, sizeof(szFilePath), a_pszDir, VBOX_EXTPACK_DESCRIPTION_NAME);
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("No VirtualBoxExtensionPack element");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts vrc = RTPathQueryInfoEx(szFilePath, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste return &(new iprt::MiniString())->printf("RTPathQueryInfoEx failed with %Rrc", vrc);
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("The XML file is symlinked, that is not allowed");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return &(new iprt::MiniString)->printf("The XML file is not a file (fMode=%#x)", ObjInfo.Attr.fMode);
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * Get the main element and check its version.
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste const xml::ElementNode *pVBoxExtPackElm = pRoot->findChildElement(NULL, "VirtualBoxExtensionPack");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("No VirtualBoxExtensionPack element");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pVBoxExtPackElm->getAttributeValue("version", strFormatVersion))
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("Missing format version");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return &(new iprt::MiniString("Unsupported format version: "))->append(strFormatVersion);
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * Read and validate the name.
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste const xml::ElementNode *pNameElm = pVBoxExtPackElm->findChildElement("Name");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("The 'Name' element is missing");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts const char *pszName = pNameElm->getValue();
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return &(new iprt::MiniString("Invalid name: "))->append(pszName);
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste const xml::ElementNode *pDescElm = pVBoxExtPackElm->findChildElement("Description");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("The 'Description' element is missing");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("The 'Description' element is empty");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (strpbrk(pszDesc, "\n\r\t\v\b") != NULL)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("The 'Description' must not contain control characters");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts const xml::ElementNode *pVersionElm = pVBoxExtPackElm->findChildElement("Version");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("The 'Version' element is missing");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts const char *pszVersion = pVersionElm->getValue();
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("The 'Version' element is empty");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!VBoxExtPackIsValidVersionString(pszVersion))
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return &(new iprt::MiniString("Invalid version string: "))->append(pszVersion);
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pVersionElm->getAttributeValue("revision", uRevision))
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts const xml::ElementNode *pMainModuleElm = pVBoxExtPackElm->findChildElement("MainModule");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("The 'MainModule' element is missing");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts const char *pszMainModule = pMainModuleElm->getValue();
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pszMainModule || *pszMainModule == '\0')
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("The 'MainModule' element is empty");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!VBoxExtPackIsValidMainModuleString(pszVersion))
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return &(new iprt::MiniString("Invalid main module string: "))->append(pszMainModule);
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * Everything seems fine, fill in the return values and return successfully.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts a_pExtPackDesc->strMainModule = pszMainModule;
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * Validates the extension pack name.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * @returns true if valid, false if not.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * @param pszName The name to validate.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpottsbool VBoxExtPackIsValidName(const char *pszName)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /* This must match the code in the extension manager. */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return false;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts while (RT_C_IS_ALNUM(*pszName) || *pszName == ' ')
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * Validates the extension pack version string.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * @returns true if valid, false if not.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * @param pszVersion The version string to validate.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpottsbool VBoxExtPackIsValidVersionString(const char *pszVersion)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return false;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /* 1.x.y.z... */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return false;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /* upper case string + numbers indicating the build type */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (*pszVersion == '-' || *pszVersion == '_')
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /* revision or nothing */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return false;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * Validates the extension pack main module string.
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste * @returns true if valid, false if not.
74b502cf428d057e78572e9fd66fb2f1861887b0Jaco Jooste * @param pszMainModule The main module string to validate.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpottsbool VBoxExtPackIsValidMainModuleString(const char *pszMainModule)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pszMainModule || *pszMainModule == '\0')
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return false;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /* Restricted charset, no extensions (dots). */