VirtualBox

Changeset 85665 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Aug 10, 2020 3:00:05 PM (4 years ago)
Author:
vboxsync
Message:

VBoxManage: Converted the sharedfolder command to RTGetOpt and refentry help. ticketref:19800

Location:
trunk/src/VBox/Frontends/VBoxManage
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp

    r85121 r85665  
    137137    { "setproperty",        USAGE_SETPROPERTY,      VBMG_CMD_TODO, handleSetProperty,          0 },
    138138    { "usbfilter",          USAGE_USBFILTER,        VBMG_CMD_TODO, handleUSBFilter,            0 },
    139     { "sharedfolder",       USAGE_SHAREDFOLDER,     VBMG_CMD_TODO, handleSharedFolder,         0 },
     139    { "sharedfolder",       USAGE_S_NEWCMD, HELP_CMD_SHAREDFOLDER, handleSharedFolder,         0 },
    140140#ifdef VBOX_WITH_GUEST_PROPS
    141141    { "guestproperty",      USAGE_GUESTPROPERTY,    VBMG_CMD_TODO, handleGuestProperty,        0 },
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h

    r84519 r85665  
    7373    USAGE_SETPROPERTY,
    7474    USAGE_USBFILTER,
    75     USAGE_SHAREDFOLDER,
    7675    USAGE_I_LOADSYMS,
    7776    USAGE_I_LOADMAP,
     
    125124#define HELP_SCOPE_USBFILTER_REMOVE     RT_BIT_64(2)
    126125
    127 #define HELP_SCOPE_SHAREDFOLDER_ADD     RT_BIT_64(0)
    128 #define HELP_SCOPE_SHAREDFOLDER_REMOVE  RT_BIT_64(1)
    129 
    130126#ifdef VBOX_WITH_GUEST_CONTROL
    131127# define HELP_SCOPE_GSTCTRL_RUN             RT_BIT(0)
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp

    r85575 r85665  
    11461146    }
    11471147
    1148     if (enmCommand == USAGE_SHAREDFOLDER || enmCommand == USAGE_S_ALL)
    1149     {
    1150         if (fSubcommandScope & HELP_SCOPE_SHAREDFOLDER_ADD)
    1151             RTStrmPrintf(pStrm,
    1152                                "%s sharedfolder %s    add <uuid|vmname>\n"
    1153                          "                            --name <name> --hostpath <hostpath>\n"
    1154                          "                            [--transient] [--readonly] [--automount]\n"
    1155                          "\n", SEP);
    1156 
    1157         if (fSubcommandScope & HELP_SCOPE_SHAREDFOLDER_REMOVE)
    1158             RTStrmPrintf(pStrm,
    1159                                "%s sharedfolder %s    remove <uuid|vmname>\n"
    1160                          "                            --name <name> [--transient]\n"
    1161                          "\n", SEP);
    1162     }
    1163 
    11641148#ifdef VBOX_WITH_GUEST_PROPS
    11651149    if (enmCommand == USAGE_GUESTPROPERTY || enmCommand == USAGE_S_ALL)
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp

    r82968 r85665  
    10691069}
    10701070
     1071/**
     1072 * sharedfolder add
     1073 */
     1074static RTEXITCODE handleSharedFolderAdd(HandlerArg *a)
     1075{
     1076    /*
     1077     * Parse arguments (argv[0] == subcommand).
     1078     */
     1079    static const RTGETOPTDEF s_aAddOptions[] =
     1080    {
     1081        { "--name",             'n', RTGETOPT_REQ_STRING },
     1082        { "-name",              'n', RTGETOPT_REQ_STRING },     // deprecated
     1083        { "--hostpath",         'p', RTGETOPT_REQ_STRING },
     1084        { "-hostpath",          'p', RTGETOPT_REQ_STRING },     // deprecated
     1085        { "--readonly",         'r', RTGETOPT_REQ_NOTHING },
     1086        { "-readonly",          'r', RTGETOPT_REQ_NOTHING },    // deprecated
     1087        { "--transient",        't', RTGETOPT_REQ_NOTHING },
     1088        { "-transient",         't', RTGETOPT_REQ_NOTHING },    // deprecated
     1089        { "--automount",        'a', RTGETOPT_REQ_NOTHING },
     1090        { "-automount",         'a', RTGETOPT_REQ_NOTHING },    // deprecated
     1091        { "--auto-mount-point", 'm', RTGETOPT_REQ_STRING },
     1092    };
     1093    const char *pszMachineName    = NULL;
     1094    const char *pszName           = NULL;
     1095    const char *pszHostPath       = NULL;
     1096    bool        fTransient        = false;
     1097    bool        fWritable         = true;
     1098    bool        fAutoMount        = false;
     1099    const char *pszAutoMountPoint = "";
     1100
     1101    RTGETOPTSTATE GetState;
     1102    RTGetOptInit(&GetState, a->argc, a->argv, s_aAddOptions, RT_ELEMENTS(s_aAddOptions), 1 /*iFirst*/, 0 /*fFlags*/);
     1103    int c;
     1104    RTGETOPTUNION ValueUnion;
     1105    while ((c = RTGetOpt(&GetState, &ValueUnion)))
     1106    {
     1107        switch (c)
     1108        {
     1109            case 'n':
     1110                pszName = ValueUnion.psz;
     1111                break;
     1112            case 'p':
     1113                pszHostPath = ValueUnion.psz;
     1114                break;
     1115            case 'r':
     1116                fWritable = false;
     1117                break;
     1118            case 't':
     1119                fTransient = true;
     1120                break;
     1121            case 'a':
     1122                fAutoMount = true;
     1123                break;
     1124            case 'm':
     1125                pszAutoMountPoint = ValueUnion.psz;
     1126                break;
     1127            case VINF_GETOPT_NOT_OPTION:
     1128                if (pszMachineName)
     1129                    return errorArgument("Machine name is given more than once: first '%s', then '%s'",
     1130                                         pszMachineName, ValueUnion.psz);
     1131                pszMachineName = ValueUnion.psz;
     1132                break;
     1133            default:
     1134                return errorGetOpt(c, &ValueUnion);
     1135        }
     1136    }
     1137
     1138    if (!pszMachineName)
     1139        return errorSyntax("No machine was specified");
     1140
     1141    if (!pszName)
     1142        return errorSyntax("No shared folder name (--name) was given");
     1143    if (strchr(pszName, ' '))
     1144        return errorSyntax("Invalid shared folder name '%s': contains space", pszName);
     1145    if (strchr(pszName, '\t'))
     1146        return errorSyntax("Invalid shared folder name '%s': contains tabs", pszName);
     1147    if (strchr(pszName, '\n') || strchr(pszName, '\r'))
     1148        return errorSyntax("Invalid shared folder name '%s': contains newline", pszName);
     1149
     1150    if (!pszHostPath)
     1151        return errorSyntax("No host path (--hostpath) was given");
     1152    char szAbsHostPath[RTPATH_MAX];
     1153    int vrc = RTPathAbs(pszHostPath, szAbsHostPath, sizeof(szAbsHostPath));
     1154    if (RT_FAILURE(vrc))
     1155        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTAbsPath failed on '%s': %Rrc", pszHostPath, vrc);
     1156
     1157    /*
     1158     * Done parsing, do some work.
     1159     */
     1160    ComPtr<IMachine> ptrMachine;
     1161    CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
     1162    AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE);
     1163
     1164    HRESULT hrc;
     1165    if (fTransient)
     1166    {
     1167        /* open an existing session for the VM */
     1168        CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
     1169
     1170        /* get the session machine */
     1171        ComPtr<IMachine> ptrSessionMachine;
     1172        CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
     1173
     1174        /* get the session console */
     1175        ComPtr<IConsole> ptrConsole;
     1176        CHECK_ERROR2I_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
     1177        if (ptrConsole.isNull())
     1178            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Machine '%s' is not currently running.", pszMachineName);
     1179
     1180        CHECK_ERROR2(hrc, ptrConsole, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
     1181                                                         fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
     1182        a->session->UnlockMachine();
     1183    }
     1184    else
     1185    {
     1186        /* open a session for the VM */
     1187        CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
     1188
     1189        /* get the mutable session machine */
     1190        ComPtr<IMachine> ptrSessionMachine;
     1191        CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
     1192
     1193        CHECK_ERROR2(hrc, ptrSessionMachine, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
     1194                                                                fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
     1195        if (SUCCEEDED(hrc))
     1196        {
     1197            CHECK_ERROR2(hrc, ptrSessionMachine, SaveSettings());
     1198        }
     1199
     1200        a->session->UnlockMachine();
     1201    }
     1202
     1203    return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
     1204}
     1205
     1206/**
     1207 * sharedfolder remove
     1208 */
     1209static RTEXITCODE handleSharedFolderRemove(HandlerArg *a)
     1210{
     1211    /*
     1212     * Parse arguments (argv[0] == subcommand).
     1213     */
     1214    static const RTGETOPTDEF s_aRemoveOptions[] =
     1215    {
     1216        { "--name",             'n', RTGETOPT_REQ_STRING },
     1217        { "-name",              'n', RTGETOPT_REQ_STRING },     // deprecated
     1218        { "--transient",        't', RTGETOPT_REQ_NOTHING },
     1219        { "-transient",         't', RTGETOPT_REQ_NOTHING },    // deprecated
     1220    };
     1221    const char *pszMachineName    = NULL;
     1222    const char *pszName           = NULL;
     1223    bool        fTransient        = false;
     1224
     1225    RTGETOPTSTATE GetState;
     1226    RTGetOptInit(&GetState, a->argc, a->argv, s_aRemoveOptions, RT_ELEMENTS(s_aRemoveOptions), 1 /*iFirst*/, 0 /*fFlags*/);
     1227    int c;
     1228    RTGETOPTUNION ValueUnion;
     1229    while ((c = RTGetOpt(&GetState, &ValueUnion)))
     1230    {
     1231        switch (c)
     1232        {
     1233            case 'n':
     1234                pszName = ValueUnion.psz;
     1235                break;
     1236            case 't':
     1237                fTransient = true;
     1238                break;
     1239            case VINF_GETOPT_NOT_OPTION:
     1240                if (pszMachineName)
     1241                    return errorArgument("Machine name is given more than once: first '%s', then '%s'",
     1242                                         pszMachineName, ValueUnion.psz);
     1243                pszMachineName = ValueUnion.psz;
     1244                break;
     1245            default:
     1246                return errorGetOpt(c, &ValueUnion);
     1247        }
     1248    }
     1249
     1250    if (!pszMachineName)
     1251        return errorSyntax("No machine was specified");
     1252    if (!pszName)
     1253        return errorSyntax("No shared folder name (--name) was given");
     1254
     1255    /*
     1256     * Done parsing, do some real work.
     1257     */
     1258    ComPtr<IMachine> ptrMachine;
     1259    CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
     1260    AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE);
     1261
     1262    HRESULT hrc;
     1263    if (fTransient)
     1264    {
     1265        /* open an existing session for the VM */
     1266        CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
     1267        /* get the session machine */
     1268        ComPtr<IMachine> ptrSessionMachine;
     1269        CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
     1270        /* get the session console */
     1271        ComPtr<IConsole> ptrConsole;
     1272        CHECK_ERROR2I_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
     1273        if (ptrConsole.isNull())
     1274            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Machine '%s' is not currently running.\n", pszMachineName);
     1275
     1276        CHECK_ERROR2(hrc, ptrConsole, RemoveSharedFolder(Bstr(pszName).raw()));
     1277
     1278        a->session->UnlockMachine();
     1279    }
     1280    else
     1281    {
     1282        /* open a session for the VM */
     1283        CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
     1284
     1285        /* get the mutable session machine */
     1286        ComPtr<IMachine> ptrSessionMachine;
     1287        CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
     1288
     1289        CHECK_ERROR2(hrc, ptrSessionMachine, RemoveSharedFolder(Bstr(pszName).raw()));
     1290
     1291        /* commit and close the session */
     1292        if (SUCCEEDED(hrc))
     1293        {
     1294            CHECK_ERROR2(hrc, ptrSessionMachine, SaveSettings());
     1295        }
     1296        a->session->UnlockMachine();
     1297    }
     1298
     1299    return SUCCEEDED(hrc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
     1300}
     1301
     1302
    10711303RTEXITCODE handleSharedFolder(HandlerArg *a)
    10721304{
    1073     HRESULT rc;
    1074 
    1075     /* we need at least a command and target */
    1076     if (a->argc < 2)
    1077         return errorSyntax(USAGE_SHAREDFOLDER, "Not enough parameters");
    1078 
    1079     const char *pszMachineName = a->argv[1];
    1080     ComPtr<IMachine> machine;
    1081     CHECK_ERROR(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), machine.asOutParam()));
    1082     if (!machine)
    1083         return RTEXITCODE_FAILURE;
     1305    if (a->argc < 1)
     1306        return errorSyntax("Not enough parameters");
    10841307
    10851308    if (!strcmp(a->argv[0], "add"))
    10861309    {
    1087         /* we need at least four more parameters */
    1088         if (a->argc < 5)
    1089             return errorSyntaxEx(USAGE_SHAREDFOLDER, HELP_SCOPE_SHAREDFOLDER_ADD, "Not enough parameters");
    1090 
    1091         char *name = NULL;
    1092         char *hostpath = NULL;
    1093         bool fTransient = false;
    1094         bool fWritable = true;
    1095         bool fAutoMount = false;
    1096         const char *pszAutoMountPoint = "";
    1097 
    1098         for (int i = 2; i < a->argc; i++)
    1099         {
    1100             if (   !strcmp(a->argv[i], "--name")
    1101                 || !strcmp(a->argv[i], "-name"))
    1102             {
    1103                 if (a->argc <= i + 1 || !*a->argv[i+1])
    1104                     return errorArgument("Missing argument to '%s'", a->argv[i]);
    1105                 i++;
    1106                 name = a->argv[i];
    1107             }
    1108             else if (   !strcmp(a->argv[i], "--hostpath")
    1109                      || !strcmp(a->argv[i], "-hostpath"))
    1110             {
    1111                 if (a->argc <= i + 1 || !*a->argv[i+1])
    1112                     return errorArgument("Missing argument to '%s'", a->argv[i]);
    1113                 i++;
    1114                 hostpath = a->argv[i];
    1115             }
    1116             else if (   !strcmp(a->argv[i], "--readonly")
    1117                      || !strcmp(a->argv[i], "-readonly"))
    1118             {
    1119                 fWritable = false;
    1120             }
    1121             else if (   !strcmp(a->argv[i], "--transient")
    1122                      || !strcmp(a->argv[i], "-transient"))
    1123             {
    1124                 fTransient = true;
    1125             }
    1126             else if (   !strcmp(a->argv[i], "--automount")
    1127                      || !strcmp(a->argv[i], "-automount"))
    1128             {
    1129                 fAutoMount = true;
    1130             }
    1131             else if (!strcmp(a->argv[i], "--auto-mount-point"))
    1132             {
    1133                 if (a->argc <= i + 1 || !*a->argv[i+1])
    1134                     return errorArgument("Missing argument to '%s'", a->argv[i]);
    1135                 i++;
    1136                 pszAutoMountPoint = a->argv[i];
    1137             }
    1138             else
    1139                 return errorSyntaxEx(USAGE_SHAREDFOLDER, HELP_SCOPE_SHAREDFOLDER_ADD, "Invalid parameter '%s'", Utf8Str(a->argv[i]).c_str());
    1140         }
    1141 
    1142         if (NULL != strstr(name, " "))
    1143             return errorSyntaxEx(USAGE_SHAREDFOLDER, HELP_SCOPE_SHAREDFOLDER_ADD, "No spaces allowed in parameter '-name'!");
    1144 
    1145         /* required arguments */
    1146         if (!name || !hostpath)
    1147         {
    1148             return errorSyntaxEx(USAGE_SHAREDFOLDER, HELP_SCOPE_SHAREDFOLDER_ADD, "Parameters --name and --hostpath are required");
    1149         }
    1150 
    1151         if (fTransient)
    1152         {
    1153             ComPtr<IConsole> console;
    1154 
    1155             /* open an existing session for the VM */
    1156             CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
    1157 
    1158             /* get the session machine */
    1159             ComPtr<IMachine> sessionMachine;
    1160             CHECK_ERROR_RET(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()), RTEXITCODE_FAILURE);
    1161 
    1162             /* get the session console */
    1163             CHECK_ERROR_RET(a->session, COMGETTER(Console)(console.asOutParam()), RTEXITCODE_FAILURE);
    1164             if (console.isNull())
    1165                 return RTMsgErrorExit(RTEXITCODE_FAILURE,
    1166                                       "Machine '%s' is not currently running.\n", pszMachineName);
    1167 
    1168             CHECK_ERROR(console, CreateSharedFolder(Bstr(name).raw(), Bstr(hostpath).raw(),
    1169                                                     fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
    1170             a->session->UnlockMachine();
    1171         }
    1172         else
    1173         {
    1174             /* open a session for the VM */
    1175             CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
    1176 
    1177             /* get the mutable session machine */
    1178             ComPtr<IMachine> sessionMachine;
    1179             a->session->COMGETTER(Machine)(sessionMachine.asOutParam());
    1180 
    1181             CHECK_ERROR(sessionMachine, CreateSharedFolder(Bstr(name).raw(), Bstr(hostpath).raw(),
    1182                                                            fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
    1183             if (SUCCEEDED(rc))
    1184                 CHECK_ERROR(sessionMachine, SaveSettings());
    1185 
    1186             a->session->UnlockMachine();
    1187         }
    1188     }
    1189     else if (!strcmp(a->argv[0], "remove"))
    1190     {
    1191         /* we need at least two more parameters */
    1192         if (a->argc < 3)
    1193             return errorSyntaxEx(USAGE_SHAREDFOLDER, HELP_SCOPE_SHAREDFOLDER_REMOVE, "Not enough parameters");
    1194 
    1195         char *name = NULL;
    1196         bool fTransient = false;
    1197 
    1198         for (int i = 2; i < a->argc; i++)
    1199         {
    1200             if (   !strcmp(a->argv[i], "--name")
    1201                 || !strcmp(a->argv[i], "-name"))
    1202             {
    1203                 if (a->argc <= i + 1 || !*a->argv[i+1])
    1204                     return errorArgument("Missing argument to '%s'", a->argv[i]);
    1205                 i++;
    1206                 name = a->argv[i];
    1207             }
    1208             else if (   !strcmp(a->argv[i], "--transient")
    1209                      || !strcmp(a->argv[i], "-transient"))
    1210             {
    1211                 fTransient = true;
    1212             }
    1213             else
    1214                 return errorSyntaxEx(USAGE_SHAREDFOLDER, HELP_SCOPE_SHAREDFOLDER_REMOVE, "Invalid parameter '%s'", Utf8Str(a->argv[i]).c_str());
    1215         }
    1216 
    1217         /* required arguments */
    1218         if (!name)
    1219             return errorSyntaxEx(USAGE_SHAREDFOLDER, HELP_SCOPE_SHAREDFOLDER_REMOVE, "Parameter --name is required");
    1220 
    1221         if (fTransient)
    1222         {
    1223             /* open an existing session for the VM */
    1224             CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
    1225             /* get the session machine */
    1226             ComPtr<IMachine> sessionMachine;
    1227             CHECK_ERROR_RET(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()), RTEXITCODE_FAILURE);
    1228             /* get the session console */
    1229             ComPtr<IConsole> console;
    1230             CHECK_ERROR_RET(a->session, COMGETTER(Console)(console.asOutParam()), RTEXITCODE_FAILURE);
    1231             if (console.isNull())
    1232                 return RTMsgErrorExit(RTEXITCODE_FAILURE,
    1233                                       "Machine '%s' is not currently running.\n", pszMachineName);
    1234 
    1235             CHECK_ERROR(console, RemoveSharedFolder(Bstr(name).raw()));
    1236 
    1237             a->session->UnlockMachine();
    1238         }
    1239         else
    1240         {
    1241             /* open a session for the VM */
    1242             CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
    1243 
    1244             /* get the mutable session machine */
    1245             ComPtr<IMachine> sessionMachine;
    1246             a->session->COMGETTER(Machine)(sessionMachine.asOutParam());
    1247 
    1248             CHECK_ERROR(sessionMachine, RemoveSharedFolder(Bstr(name).raw()));
    1249 
    1250             /* commit and close the session */
    1251             CHECK_ERROR(sessionMachine, SaveSettings());
    1252             a->session->UnlockMachine();
    1253         }
    1254     }
    1255     else
    1256         return errorSyntax(USAGE_SHAREDFOLDER, "Invalid parameter '%s'", Utf8Str(a->argv[0]).c_str());
    1257 
    1258     return RTEXITCODE_SUCCESS;
     1310        setCurrentSubcommand(HELP_SCOPE_SHAREDFOLDER_ADD);
     1311        return handleSharedFolderAdd(a);
     1312    }
     1313
     1314    if (!strcmp(a->argv[0], "remove"))
     1315    {
     1316        setCurrentSubcommand(HELP_SCOPE_SHAREDFOLDER_REMOVE);
     1317        return handleSharedFolderRemove(a);
     1318    }
     1319
     1320    return errorUnknownSubcommand(a->argv[0]);
    12591321}
    12601322
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