in src/adu-shell/src/main.cpp [59:228]
int ParseLaunchArguments(const int argc, char** argv, ADUShell_LaunchArguments* launchArgs)
{
if (launchArgs == nullptr)
{
return -1;
}
int result = 0;
launchArgs->updateType = nullptr;
launchArgs->updateAction = nullptr;
launchArgs->targetData = nullptr;
launchArgs->logFile = nullptr;
launchArgs->showVersion = false;
#if _ADU_DEBUG
launchArgs->logLevel = ADUC_LOG_DEBUG;
#else
launchArgs->logLevel = ADUC_LOG_INFO;
#endif
launchArgs->argc = argc;
launchArgs->argv = argv;
launchArgs->configFolder = ADUC_CONF_FOLDER;
while (result == 0)
{
// clang-format off
// "--version" | Show adu-shell version number.
//
// "--update-type" | An ADU Update Type.
// e.g., "microsoft/apt", "microsoft/script", "common".
//
// "--update-action" | An action to perform.
// e.g., "initialize", "download", "install", "apply", "cancel", "rollback", "reboot".
//
// "--target-data" | A string contains data for a target command.
// e.g., for microsoft/apt download action, this is a single-quoted string
// contains space-delimited list of package names.
//
// "--target-options" | Additional options for a target command.
//
// "--target-log-folder" | Some target command requires specific logs storage.
//
// "--log-level" | Log verbosity level.
//
// "--config-folder" | Path to the folder containing the ADU configuration files.
//
static struct option long_options[] =
{
{ "version", no_argument, nullptr, 'v' },
{ "update-type", required_argument, nullptr, 't' },
{ "update-action", required_argument, nullptr, 'a' },
{ "target-data", required_argument, nullptr, 'd' },
{ "target-options", required_argument, nullptr, 'o' },
{ "target-log-folder", required_argument, nullptr, 'f' },
{ "log-level", required_argument, nullptr, 'l' },
{ "config-folder", required_argument, nullptr, 'F' },
{ nullptr, 0, nullptr, 0 }
};
// clang-format on
/* getopt_long stores the option index here. */
int option_index = 0;
int option = getopt_long(argc, argv, "vt:a:d:o:f:l:F;", long_options, &option_index);
/* Detect the end of the options. */
if (option == -1)
{
break;
}
switch (option)
{
case 'v':
launchArgs->showVersion = true;
break;
case 't':
launchArgs->updateType = optarg;
break;
case 'F':
launchArgs->configFolder = optarg;
break;
case 'a':
launchArgs->updateAction = optarg;
launchArgs->action = ADUShellActionFromString(launchArgs->updateAction);
break;
case 'd':
launchArgs->targetData = optarg;
break;
case 'o':
launchArgs->targetOptions.emplace_back(optarg);
break;
case 'f':
launchArgs->logFile = optarg;
break;
case 'l': {
char* endptr;
errno = 0; /* To distinguish success/failure after call */
int64_t logLevel = strtol(optarg, &endptr, 10);
if (errno != 0 || endptr == optarg || logLevel < ADUC_LOG_DEBUG || logLevel > ADUC_LOG_ERROR)
{
printf("Invalid log level after '--log-level' or '-l' option. Expected value: 0-3.");
result = -1;
}
else
{
launchArgs->logLevel = static_cast<ADUC_LOG_SEVERITY>(logLevel);
}
break;
}
case '?':
switch (optopt)
{
case 't':
printf("Missing an Update Type string after '--update-type' or '-t' option.");
break;
case 'd':
printf("Missing a target data string after '--target-data' or '-d' option. Expected quoted string.");
break;
case 'o':
printf(
"Missing a target options string after '--target-options' or '-o' option. Expected quoted string.");
break;
case 'l':
printf("Invalid log level after '--log-level' or '-l' option. Expected value: 0-3.");
break;
case 'f':
printf("Missing a log folder path after '--target-log-folder' or '-f' option.");
break;
case 'F':
printf("Missing a config folder path after '--config-folder' or '-c' option.");
break;
default:
printf("Missing an option value after -%c.\n", optopt);
break;
}
result = -1;
break;
default:
printf("Ignoring unknown argument: character code %d", option);
}
}
if (launchArgs->updateType == nullptr)
{
printf("Missing --update-type option.\n");
result = -1;
}
if (launchArgs->updateAction == nullptr)
{
printf("Missing --update-action option.\n");
result = -1;
}
return result;
}