VBoxServiceToolBox.cpp revision c80170800394cbf2746e3136b41886c2d11617ae
/* $Id$ */
/** @file
* VBoxServiceToolBox - Internal (BusyBox-like) toolbox.
*/
/*
* Copyright (C) 2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include <stdio.h>
#include <iprt/buildconfig.h>
#ifndef RT_OS_WINDOWS
#endif
#include <VBox/VBoxGuestLib.h>
#include "VBoxServiceInternal.h"
#include "VBoxServiceUtils.h"
#define CAT_OPT_NO_CONTENT_INDEXED 1000
/**
*/
typedef struct VBOXSERVICETOOLBOXPATHENTRY
{
/** Our node. */
/** Name of the entry. */
char *pszName;
/**
* Displays a help text to stdout.
*/
static void VBoxServiceToolboxShowUsage(void)
{
RTPrintf("Toolbox Usage:\n"
"cat [FILE] - Concatenate FILE(s), or standard input, to standard output\n"
"\n"
"mkdir - Make directories\n"
"\n");
}
/**
* Displays the program's version number.
*/
static void VBoxServiceToolboxShowVersion(void)
{
}
/**
* Displays an error message because of syntax error.
*
* @return VERR_INVALID_PARAMETER
* @param pszFormat
*/
static int VBoxServiceToolboxErrorSyntax(const char *pszFormat, ...)
{
RTPrintf("\n"
return VERR_INVALID_PARAMETER;
}
/**
* Destroys a path buffer list.
*
* @return IPRT status code.
* @param pList Pointer to list to destroy.
*/
{
/** @todo use RTListForEachSafe */
while (pNode)
{
? NULL
}
}
/**
*
* @return IPRT status code.
* @param pList Pointer to list to add entry to.
* @param pszName Name of entry to add.
*/
{
int rc = VINF_SUCCESS;
PVBOXSERVICETOOLBOXPATHENTRY pNode = (PVBOXSERVICETOOLBOXPATHENTRY)RTMemAlloc(sizeof(VBOXSERVICETOOLBOXPATHENTRY));
if (pNode)
{
}
else
rc = VERR_NO_MEMORY;
return rc;
}
/**
* Performs the actual output operation of "vbox_cat".
*
* @return IPRT status code.
* @param hInput Handle of input file (if any) to use;
* else stdin will be used.
* @param hOutput Handle of output file (if any) to use;
* else stdout will be used.
*/
{
int rc = VINF_SUCCESS;
if (hInput == NIL_RTFILE)
{
if (RT_FAILURE(rc))
}
if (hOutput == NIL_RTFILE)
{
if (RT_FAILURE(rc))
}
if (RT_SUCCESS(rc))
{
for (;;)
{
{
cbRead = 0;
}
else
{
if ( cbRead == 0
&& rc == VERR_BROKEN_PIPE)
{
rc = VINF_SUCCESS;
}
break;
}
}
}
return rc;
}
/**
* Main function for tool "vbox_mkdir".
*
* @return RTEXITCODE.
* @param argc Number of arguments.
* @param argv Pointer to argument array.
*/
{
static const RTGETOPTDEF s_aOptions[] =
{
};
int ch;
int rc = VINF_SUCCESS;
bool fMakeParentDirs = false;
bool fVerbose = false;
/* Init directory list. */
&& RT_SUCCESS(rc))
{
/* For options that require an argument, ValueUnion has received the value. */
switch (ch)
{
case 'h':
return RTEXITCODE_SUCCESS;
case 'p':
fMakeParentDirs = true;
break;
case 'm':
{
RTMsgError("mkdir: Mode flag strings not implemented yet! Use octal numbers instead.\n");
return RTEXITCODE_SYNTAX;
}
break;
case 'v':
fVerbose = true;
break;
case 'V':
return RTEXITCODE_SUCCESS;
case VINF_GETOPT_NOT_OPTION:
{
/* Add path(s) to buffer. This enables processing multiple paths
* at once.
*
* Since the non-options (RTGETOPTINIT_FLAGS_OPTS_FIRST) come last when
* processing this loop it's safe to immediately exit on syntax errors
* or showing the help text (see above). */
break;
}
default:
}
}
if (RT_SUCCESS(rc))
{
if (fMakeParentDirs || newMode)
{
#ifndef RT_OS_WINDOWS
if (newMode)
#endif
}
{
rc = fMakeParentDirs ?
{
if (pMsg)
RTMsgError("mkdir: Could not create directory '%s': %s\n",
else
}
}
}
else if (fVerbose)
}
/**
* Main function for tool "vbox_cat".
*
* @return RTEXITCODE.
* @param argc Number of arguments.
* @param argv Pointer to argument array.
*/
{
static const RTGETOPTDEF s_aOptions[] =
{
/* Sorted by short ops. */
};
int ch;
int rc = VINF_SUCCESS;
bool fUsageOK = true;
char szOutput[RTPATH_MAX] = { 0 };
/* Init directory list. */
&& RT_SUCCESS(rc))
{
/* For options that require an argument, ValueUnion has received the value. */
switch (ch)
{
case 'a':
case 'b':
case 'e':
case 'E':
case 'n':
case 's':
case 't':
case 'T':
case 'v':
RTMsgError("cat: Sorry, option '%s' is not implemented yet!\n",
break;
case 'h':
return RTEXITCODE_SUCCESS;
case 'o':
rc = VERR_NO_MEMORY;
break;
case 'u':
/* Ignored. */
break;
case 'V':
return RTEXITCODE_SUCCESS;
break;
case VINF_GETOPT_NOT_OPTION:
{
/* Add file(s) to buffer. This enables processing multiple paths
* at once.
*
* Since the non-options (RTGETOPTINIT_FLAGS_OPTS_FIRST) come last when
* processing this loop it's safe to immediately exit on syntax errors
* or showing the help text (see above). */
break;
}
default:
}
}
if (RT_SUCCESS(rc))
{
{
if (RT_FAILURE(rc))
RTMsgError("cat: Could not create output file '%s'! rc=%Rrc\n",
}
if (RT_SUCCESS(rc))
{
/* Process each input file. */
{
if (RT_SUCCESS(rc))
{
}
else
{
if (pMsg)
RTMsgError("cat: Could not open input file '%s': %s\n",
else
}
if (RT_FAILURE(rc))
break;
}
/* If not input files were defined, process stdin. */
}
}
if (hOutput != NIL_RTFILE)
}
/**
* Entry point for internal toolbox.
*
* @return True if an internal tool was handled, false if not.
* @param argc Number of arguments.
* @param argv Pointer to argument array.
* @param piExitCode Pointer to receive exit code when internal command
* was handled.
*/
{
if (argc > 0) /* Do we have at least a main command? */
{
{
return true;
}
{
return true;
}
}
return false;
}