ExtPackUtil.cpp revision 710d24589d0cbe0ea6e9ad143eda5bbd41000693
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste/* $Id$ */
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste/** @file
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * VirtualBox Main - Extension Pack Utilities and definitions, VBoxC, VBoxSVC, ++.
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste */
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste/*
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * Copyright (C) 2010 Oracle Corporation
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste *
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.
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste */
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts/*******************************************************************************
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts* Header Files *
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts*******************************************************************************/
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts#include "ExtPackUtil.h"
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts#include <iprt/ctype.h>
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts#include <iprt/dir.h>
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts#include <iprt/file.h>
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts#include <iprt/param.h>
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts#include <iprt/path.h>
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts#include <iprt/string.h>
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts#include <iprt/cpp/xml.h>
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts#include <VBox/log.h>
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts/**
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * Reads the extension pack description.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts *
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.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts */
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Joosteiprt::MiniString *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo)
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste{
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /*
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste * Clear the description.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts a_pExtPackDesc->strName.setNull();
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts a_pExtPackDesc->strDescription.setNull();
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts a_pExtPackDesc->strVersion.setNull();
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts a_pExtPackDesc->uRevision = 0;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts a_pExtPackDesc->strMainModule.setNull();
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /*
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * Validate, open and parse the XML file.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts char szFilePath[RTPATH_MAX];
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts int vrc = RTPathJoin(szFilePath, sizeof(szFilePath), a_pszDir, VBOX_EXTPACK_DESCRIPTION_NAME);
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (RT_FAILURE(vrc))
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("No VirtualBoxExtensionPack element");
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste RTFSOBJINFO ObjInfo;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts vrc = RTPathQueryInfoEx(szFilePath, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste if (RT_FAILURE(vrc))
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste return &(new iprt::MiniString())->printf("RTPathQueryInfoEx failed with %Rrc", vrc);
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (a_pObjInfo)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts *a_pObjInfo = ObjInfo;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!RTFS_IS_FILE(ObjInfo.Attr.fMode))
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts {
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (RTFS_IS_SYMLINK(ObjInfo.Attr.fMode))
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);
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts }
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts xml::Document Doc;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts xml::XmlFileParser Parser;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts try
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts {
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts Parser.read(szFilePath, Doc);
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts }
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts catch (xml::XmlError Err)
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste {
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste return new iprt::MiniString(Err.what());
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste }
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste xml::ElementNode *pRoot = Doc.getRootElement();
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste /*
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * Get the main element and check its version.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts */
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste const xml::ElementNode *pVBoxExtPackElm = pRoot->findChildElement(NULL, "VirtualBoxExtensionPack");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pVBoxExtPackElm)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("No VirtualBoxExtensionPack element");
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste iprt::MiniString strFormatVersion;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pVBoxExtPackElm->getAttributeValue("version", strFormatVersion))
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("Missing format version");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!strFormatVersion.equals("1.0"))
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return &(new iprt::MiniString("Unsupported format version: "))->append(strFormatVersion);
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /*
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * Read and validate the name.
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste */
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste const xml::ElementNode *pNameElm = pVBoxExtPackElm->findChildElement("Name");
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste if (!pNameElm)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("The 'Name' element is missing");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts const char *pszName = pNameElm->getValue();
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!VBoxExtPackIsValidName(pszName))
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return &(new iprt::MiniString("Invalid name: "))->append(pszName);
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste const xml::ElementNode *pDescElm = pVBoxExtPackElm->findChildElement("Description");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pDescElm)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("The 'Description' element is missing");
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste const char *pszDesc = pDescElm->getValue();
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste if (!pszDesc || *pszDesc == '\0')
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
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts const xml::ElementNode *pVersionElm = pVBoxExtPackElm->findChildElement("Version");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pVersionElm)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return new iprt::MiniString("The 'Version' element is missing");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts const char *pszVersion = pVersionElm->getValue();
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pszVersion || *pszVersion == '\0')
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
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts uint32_t uRevision;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pVersionElm->getAttributeValue("revision", uRevision))
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts uRevision = 0;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts const xml::ElementNode *pMainModuleElm = pVBoxExtPackElm->findChildElement("MainModule");
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pMainModuleElm)
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
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /*
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * Everything seems fine, fill in the return values and return successfully.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts a_pExtPackDesc->strName = pszName;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts a_pExtPackDesc->strDescription = pszDesc;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts a_pExtPackDesc->strVersion = pszVersion;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts a_pExtPackDesc->uRevision = uRevision;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts a_pExtPackDesc->strMainModule = pszMainModule;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return NULL;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts}
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste/**
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste * Validates the extension pack name.
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste *
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * @returns true if valid, false if not.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * @param pszName The name to validate.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpottsbool VBoxExtPackIsValidName(const char *pszName)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts{
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /* This must match the code in the extension manager. */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pszName || *pszName == '\0')
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return false;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts while (RT_C_IS_ALNUM(*pszName) || *pszName == ' ')
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts pszName++;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return *pszName == '\0';
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste}
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste/**
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * Validates the extension pack version string.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts *
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * @returns true if valid, false if not.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * @param pszVersion The version string to validate.
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpottsbool VBoxExtPackIsValidVersionString(const char *pszVersion)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts{
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pszVersion || *pszVersion == '\0')
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return false;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /* 1.x.y.z... */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!RT_C_IS_DIGIT(*pszVersion))
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return false;
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste for (;;)
b9e697e180c323785bf1cb8a29f5ec6288da8ec4Jaco Jooste {
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste while (RT_C_IS_DIGIT(*pszVersion))
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts pszVersion++;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (*pszVersion != '.')
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts break;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts }
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /* upper case string + numbers indicating the build type */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (*pszVersion == '-' || *pszVersion == '_')
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts {
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts do
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts pszVersion++;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts while ( RT_C_IS_DIGIT(*pszVersion)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts || RT_C_IS_UPPER(*pszVersion)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts || *pszVersion == '-'
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts || *pszVersion == '_');
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts }
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /* revision or nothing */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (*pszVersion != '\0')
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts {
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (*pszVersion != 'r')
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return false;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts do
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts pszVersion++;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts while (RT_C_IS_DIGIT(*pszVersion));
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts }
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return *pszVersion == '\0';
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts}
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts/**
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts * Validates the extension pack main module string.
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste *
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste * @returns true if valid, false if not.
74b502cf428d057e78572e9fd66fb2f1861887b0Jaco Jooste * @param pszMainModule The main module string to validate.
63ee0c9f26b85deae17137a3965738153e0b2d20Gabor Melkvi */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpottsbool VBoxExtPackIsValidMainModuleString(const char *pszMainModule)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts{
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts if (!pszMainModule || *pszMainModule == '\0')
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts return false;
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts /* Restricted charset, no extensions (dots). */
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts while ( RT_C_IS_ALNUM(*pszMainModule)
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts || *pszMainModule == '-'
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts || *pszMainModule == '_')
74b502cf428d057e78572e9fd66fb2f1861887b0Jaco Jooste pszMainModule++;
74b502cf428d057e78572e9fd66fb2f1861887b0Jaco Jooste
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste return *pszMainModule == '\0';
7197110fbdb6deb7868581c455516161cbcf7e0fJaco Jooste}
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts
ca7a323358dc50374d5f281355842fb7edb3983eJames Phillpotts