VBoxAutostartCfg.cpp revision b56ca3f25c9c141f3c0855b656f8f64bbfa19496
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/* $Id$ */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/** @file
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * VBoxAutostart - VirtualBox Autostart service, configuration parser.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Copyright (C) 2012 Oracle Corporation
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * available from http://www.virtualbox.org. This file is free software;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * you can redistribute it and/or modify it under the terms of the GNU
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * General Public License (GPL) as published by the Free Software
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*******************************************************************************
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync* Header Files *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync*******************************************************************************/
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/stream.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/process.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/string.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/mem.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/ctype.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/message.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "VBoxAutostart.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*******************************************************************************
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync* Constants And Macros, Structures and Typedefs *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync*******************************************************************************/
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Tokenizer instance data for the config data.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynctypedef struct CFGTOKENIZER
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /** Config file handle. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync PRTSTREAM hStrmConfig;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /** String buffer for the current line we are operating in. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync char *pszLine;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /** Size of the string buffer. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync size_t cbLine;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /** Current position in the line. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync char *pszLineCurr;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /** Current line in the config file. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned iLine;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync} CFGTOKENIZER, *PCFGTOKENIZER;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*******************************************************************************
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync* Internal Functions *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync*******************************************************************************/
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Reads the next line from the config stream.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @returns VBox status code.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param pCfgTokenizer The config tokenizer.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic int autostartConfigTokenizerReadNextLine(PCFGTOKENIZER pCfgTokenizer)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int rc = VINF_SUCCESS;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync do
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = RTStrmGetLine(pCfgTokenizer->hStrmConfig, pCfgTokenizer->pszLine,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->cbLine);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (rc == VERR_BUFFER_OVERFLOW)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync char *pszTmp;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->cbLine += 128;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pszTmp = (char *)RTMemRealloc(pCfgTokenizer->pszLine, pCfgTokenizer->cbLine);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (pszTmp)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->pszLine = pszTmp;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = VERR_NO_MEMORY;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync } while (rc == VERR_BUFFER_OVERFLOW);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->iLine++;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->pszLineCurr = pCfgTokenizer->pszLine;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Creates the config tokenizer from the given filename.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @returns VBox status code.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param pszFilename Config filename.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param ppCfgTokenizer Where to store the pointer to the config tokenizer on
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * success.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic int autostartConfigTokenizerCreate(const char *pszFilename, PCFGTOKENIZER *ppCfgTokenizer)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int rc = VINF_SUCCESS;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync PCFGTOKENIZER pCfgTokenizer = (PCFGTOKENIZER)RTMemAllocZ(sizeof(CFGTOKENIZER));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (pCfgTokenizer)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->iLine = 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->cbLine = 128;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->pszLine = (char *)RTMemAllocZ(pCfgTokenizer->cbLine);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (pCfgTokenizer->pszLine)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = RTStrmOpen(pszFilename, "r", &pCfgTokenizer->hStrmConfig);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerReadNextLine(pCfgTokenizer);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = VERR_NO_MEMORY;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = VERR_NO_MEMORY;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *ppCfgTokenizer = pCfgTokenizer;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else if ( RT_FAILURE(rc)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync && pCfgTokenizer)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (pCfgTokenizer->pszLine)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync RTMemFree(pCfgTokenizer->pszLine);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (pCfgTokenizer->hStrmConfig)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync RTStrmClose(pCfgTokenizer->hStrmConfig);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync RTMemFree(pCfgTokenizer);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Destroys the given config tokenizer.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @returns nothing.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param pCfgTokenizer The config tokenizer to destroy.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void autostartConfigTokenizerDestroy(PCFGTOKENIZER pCfgTokenizer)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (pCfgTokenizer->pszLine)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync RTMemFree(pCfgTokenizer->pszLine);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (pCfgTokenizer->hStrmConfig)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync RTStrmClose(pCfgTokenizer->hStrmConfig);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync RTMemFree(pCfgTokenizer);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Read the next token from the config file.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @returns VBox status code.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param pCfgTokenizer The config tokenizer data.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param ppszToken Where to store the start to the next token on success.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param pcchToken Where to store the number of characters of the next token
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * excluding the \0 terminator on success.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic int autostartConfigTokenizerReadNext(PCFGTOKENIZER pCfgTokenizer, const char **ppszToken,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync size_t *pcchToken)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!pCfgTokenizer->pszLineCurr)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return VERR_EOF;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int rc = VINF_SUCCESS;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (;;)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync char *pszTok = pCfgTokenizer->pszLineCurr;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Skip all spaces. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync while (RT_C_IS_BLANK(*pszTok))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pszTok++;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Check if we have to read a new line. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( *pszTok == '\0'
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync || *pszTok == '#')
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerReadNextLine(pCfgTokenizer);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_FAILURE(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* start from the beginning. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else if ( *pszTok == '='
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync || *pszTok == ',')
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *ppszToken = pszTok;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *pcchToken = 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->pszLineCurr = pszTok + 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Get the complete token. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync size_t cchToken = 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync char *pszTmp = pszTok + 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync while ( RT_C_IS_ALNUM(*pszTmp)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync || *pszTmp == '_')
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pszTmp++;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cchToken++;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *ppszToken = pszTok;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *pcchToken = cchToken;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->pszLineCurr = pszTmp;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic int autostartConfigTokenizerCheckAndConsume(PCFGTOKENIZER pCfgTokenizer, const char *pszTokCheck)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int rc = VINF_SUCCESS;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const char *pszToken = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync size_t cchToken = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerReadNext(pCfgTokenizer, &pszToken, &cchToken);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RTStrNCmp(pszToken, pszTokCheck, cchToken))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync RTMsgError("Unexpected token at line %d, expected '%s'",
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->iLine, pszTokCheck);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = VERR_INVALID_PARAMETER;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Returns the start of the next token without consuming it.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @returns VBox status code.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param pCfgTokenizer Tokenizer instance data.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param ppszTok Where to store the start of the next token on success.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic int autostartConfigTokenizerPeek(PCFGTOKENIZER pCfgTokenizer, const char **ppszTok)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int rc = VINF_SUCCESS;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (;;)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync char *pszTok = pCfgTokenizer->pszLineCurr;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Skip all spaces. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync while (RT_C_IS_BLANK(*pszTok))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pszTok++;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Check if we have to read a new line. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( *pszTok == '\0'
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync || *pszTok == '#')
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerReadNextLine(pCfgTokenizer);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_FAILURE(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* start from the beginning. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *ppszTok = pszTok;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Check whether the given token is a reserved token.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @returns true if the token is reserved or false otherwise.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param pszToken The token to check.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param cchToken Size of the token in characters.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic bool autostartConfigTokenizerIsReservedToken(const char *pszToken, size_t cchToken)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( cchToken == 1
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync && ( *pszToken == ','
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync || *pszToken == '='))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return true;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else if ( cchToken > 1
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync && ( !RTStrNCmp(pszToken, "default_policy", cchToken)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync || !RTStrNCmp(pszToken, "exception_list", cchToken)))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return true;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return false;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncDECLHIDDEN(int) autostartParseConfig(const char *pszFilename, bool *pfAllowed, uint32_t *puStartupDelay)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int rc = VINF_SUCCESS;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync char *pszUserProcess = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync bool fDefaultAllow = false;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync bool fInExceptionList = false;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync AssertPtrReturn(pfAllowed, VERR_INVALID_POINTER);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync AssertPtrReturn(puStartupDelay, VERR_INVALID_POINTER);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *pfAllowed = false;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *puStartupDelay = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = RTProcQueryUsernameA(RTProcSelf(), &pszUserProcess);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync PCFGTOKENIZER pCfgTokenizer = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerCreate(pszFilename, &pCfgTokenizer);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync do
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync size_t cchToken = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const char *pszToken = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerReadNext(pCfgTokenizer, &pszToken,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync &cchToken);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!RTStrNCmp(pszToken, "default_policy", strlen("default_policy")))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerCheckAndConsume(pCfgTokenizer, "=");
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerReadNext(pCfgTokenizer, &pszToken,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync &cchToken);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!RTStrNCmp(pszToken, "allow", strlen("allow")))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync fDefaultAllow = true;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else if (!RTStrNCmp(pszToken, "deny", strlen("deny")))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync fDefaultAllow = false;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync RTMsgError("Unexpected token at line %d, expected either 'allow' or 'deny'",
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->iLine);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = VERR_INVALID_PARAMETER;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else if (!RTStrNCmp(pszToken, "exception_list", strlen("exception_list")))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerCheckAndConsume(pCfgTokenizer, "=");
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerReadNext(pCfgTokenizer, &pszToken,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync &cchToken);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync while (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (autostartConfigTokenizerIsReservedToken(pszToken, cchToken))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync RTMsgError("Unexpected token at line %d, expected a username",
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->iLine);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = VERR_INVALID_PARAMETER;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else if (!RTStrNCmp(pszUserProcess, pszToken, strlen(pszUserProcess)))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync fInExceptionList = true;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Skip , */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerPeek(pCfgTokenizer, &pszToken);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( RT_SUCCESS(rc)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync && *pszToken == ',')
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerCheckAndConsume(pCfgTokenizer, ",");
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync AssertRC(rc);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerReadNext(pCfgTokenizer, &pszToken,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync &cchToken);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (rc == VERR_EOF)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = VINF_SUCCESS;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else if (!autostartConfigTokenizerIsReservedToken(pszToken, cchToken))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Treat as 'username = <base delay in seconds>. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerCheckAndConsume(pCfgTokenizer, "=");
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync size_t cchDelay = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const char *pszDelay = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = autostartConfigTokenizerReadNext(pCfgTokenizer, &pszDelay,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync &cchDelay);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync uint32_t uDelay = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = RTStrToUInt32Ex(pszDelay, NULL, 10, &uDelay);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (rc == VWRN_TRAILING_SPACES)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = VINF_SUCCESS;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( RT_SUCCESS(rc)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync && !RTStrNCmp(pszUserProcess, pszToken, strlen(pszUserProcess)))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *puStartupDelay = uDelay;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_FAILURE(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync RTMsgError("Unexpected token at line %d, expected a number",
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->iLine);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync RTMsgError("Unexpected token at line %d, expected a username",
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync pCfgTokenizer->iLine);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = VERR_INVALID_PARAMETER;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else if (rc == VERR_EOF)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = VINF_SUCCESS;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync } while (RT_SUCCESS(rc));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( RT_SUCCESS(rc)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync && ( (fDefaultAllow && !fInExceptionList)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync || (!fDefaultAllow && fInExceptionList)))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *pfAllowed= true;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync autostartConfigTokenizerDestroy(pCfgTokenizer);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync RTStrFree(pszUserProcess);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync