VirtualBox

Changeset 42515 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 1, 2012 4:19:59 PM (13 years ago)
Author:
vboxsync
Message:

Additions/common/VBoxService: add vbox_rm.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp

    r42498 r42515  
    3333#include <iprt/string.h>
    3434#include <iprt/stream.h>
     35#include <iprt/symlink.h>
    3536
    3637#ifndef RT_OS_WINDOWS
     
    115116             /** @todo Document options! */
    116117             "ls [OPTION]... FILE... - List information about the FILEs (the current directory by default).\n"
     118             "\n"
     119             /** @todo Document options! */
     120             "rm [OPTION]... FILE... - delete FILEs (the current directory by default).\n"
    117121             "\n"
    118122             /** @todo Document options! */
     
    900904
    901905/**
     906 * Main function for tool "vbox_rm".
     907 *
     908 * @return  RTEXITCODE.
     909 * @param   argc                    Number of arguments.
     910 * @param   argv                    Pointer to argument array.
     911 */
     912static RTEXITCODE VBoxServiceToolboxRm(int argc, char **argv)
     913{
     914    static const RTGETOPTDEF s_aOptions[] =
     915    {
     916        { "--machinereadable", VBOXSERVICETOOLBOXOPT_MACHINE_READABLE,
     917          RTGETOPT_REQ_NOTHING },
     918        /* Be like POSIX, which has both 'r' and 'R'. */
     919        { NULL,                'r',
     920          RTGETOPT_REQ_NOTHING },
     921        { NULL,                'R',
     922          RTGETOPT_REQ_NOTHING },
     923    };
     924
     925    enum
     926    {
     927        VBOXSERVICETOOLBOXRMFLAG_RECURSIVE = RT_BIT_32(0)
     928    };
     929
     930    int ch;
     931    RTGETOPTUNION ValueUnion;
     932    RTGETOPTSTATE GetState;
     933    int rc = RTGetOptInit(&GetState, argc, argv,
     934                          s_aOptions, RT_ELEMENTS(s_aOptions),
     935                          1 /*iFirst*/, RTGETOPTINIT_FLAGS_OPTS_FIRST);
     936    AssertRCReturn(rc, RTEXITCODE_INIT);
     937
     938    bool     fVerbose     = false;
     939    uint32_t fFlags       = 0;
     940    uint32_t fOutputFlags = 0;
     941
     942    while (   (ch = RTGetOpt(&GetState, &ValueUnion))
     943              && RT_SUCCESS(rc))
     944    {
     945        /* For options that require an argument, ValueUnion has received the value. */
     946        switch (ch)
     947        {
     948            case 'h':
     949                VBoxServiceToolboxShowUsage();
     950                return RTEXITCODE_SUCCESS;
     951
     952            case 'V':
     953                VBoxServiceToolboxShowVersion();
     954                return RTEXITCODE_SUCCESS;
     955
     956            case VBOXSERVICETOOLBOXOPT_MACHINE_READABLE:
     957                fOutputFlags |= VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE;
     958                break;
     959
     960            case 'r':
     961            case 'R': /* Allow directories too. */
     962                fFlags |= VBOXSERVICETOOLBOXRMFLAG_RECURSIVE;
     963                break;
     964
     965            case VINF_GETOPT_NOT_OPTION:
     966                /* RTGetOpt will sort these to the end of the argv vector so
     967                 * that we will deal with them afterwards. */
     968                break;
     969
     970            default:
     971                return RTGetOptPrintError(ch, &ValueUnion);
     972        }
     973    }
     974    if (GetState.cNonOptions > argc - 1)
     975        GetState.cNonOptions = argc - 1;
     976    /* We need at least one file. */
     977    if (RT_SUCCESS(rc) && GetState.cNonOptions == 0)
     978    {
     979        RTMsgError("No files or directories specified.");
     980        return RTEXITCODE_FAILURE;
     981    }
     982
     983    if (RT_SUCCESS(rc))
     984    {
     985        /* Print magic/version. */
     986        if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE)
     987        {
     988            rc = VBoxServiceToolboxStrmInit();
     989            if (RT_FAILURE(rc))
     990                RTMsgError("Error while initializing parseable streams, rc=%Rrc\n", rc);
     991            VBoxServiceToolboxPrintStrmHeader("vbt_rm", 1 /* Stream version */);
     992        }
     993    }
     994
     995    if (RT_SUCCESS(rc))
     996    {
     997        for (int i = argc - GetState.cNonOptions; i < argc; ++i)
     998        {
     999            /* I'm sure this isn't the most effective way, but I hope it will
     1000             * be readable and reliable code. */
     1001            if (RTDirExists(argv[i]) && !RTSymlinkExists(argv[i]))
     1002            {
     1003                if (!(fFlags & VBOXSERVICETOOLBOXRMFLAG_RECURSIVE))
     1004                {
     1005                    if (!(  fOutputFlags
     1006                          & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE))
     1007                       RTMsgError("Cannot remove directory '%s' as the '-R' option was not specified.\n",
     1008                                  argv[i]);
     1009                }
     1010                else
     1011                {
     1012                    rc = RTDirRemoveRecursive(argv[i],
     1013                                              RTDIRRMREC_F_CONTENT_AND_DIR);
     1014                    if (   RT_FAILURE(rc)
     1015                        && !(  fOutputFlags
     1016                             & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE))
     1017                        RTMsgError("The following error occurred while removing directory '%s': %Rrc.\n",
     1018                                  argv[i], rc);
     1019                }
     1020            }
     1021            else if (RTPathExists(argv[i]) || RTSymlinkExists(argv[i]))
     1022            {
     1023                rc = RTFileDelete(argv[i]);
     1024                if (   RT_FAILURE(rc)
     1025                    && !(  fOutputFlags
     1026                         & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE))
     1027                    RTMsgError("The following error occurred while removing file '%s': %Rrc.\n",
     1028                              argv[i], rc);
     1029            }
     1030            else
     1031            {
     1032                if (!(fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE))
     1033                    RTMsgError("File '%s' does not exist.\n", argv[i]);
     1034            }
     1035        }
     1036
     1037        if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE) /* Output termination. */
     1038            VBoxServiceToolboxPrintStrmTermination();
     1039    }
     1040    return RTEXITCODE_SUCCESS;
     1041}
     1042
     1043
     1044/**
    9021045 * Main function for tool "vbox_mkdir".
    9031046 *
     
    11521295        { "cat",    VBoxServiceToolboxCat   },
    11531296        { "ls",     VBoxServiceToolboxLs    },
     1297        { "rm",     VBoxServiceToolboxRm    },
    11541298        { "mkdir",  VBoxServiceToolboxMkDir },
    11551299        { "stat",   VBoxServiceToolboxStat  },
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette