2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file src/cyad/CommandlineParser/CyadCommandlineParser.cpp
18 * @author Aleksander Zdyb <a.zdyb@samsung.com>
20 * @brief Commandline parser for Cyad
29 #include <cyad/CommandlineParser/PolicyParsingException.h>
31 #include "CyadCommandlineParser.h"
35 namespace CyadCmdlineArgs {
36 const char HELP = 'h';
37 const char * const HELP_LONG = "help";
39 const char SET_BUCKET = 'b';
40 const char * const SET_BUCKET_LONG = "set-bucket";
42 const char DELETE_BUCKET = 'd';
43 const char * const DELETE_BUCKET_LONG = "delete-bucket";
45 const char POLICY = 'p';
46 const char * const POLICY_LONG = "policy";
48 const char METADATA = 'm';
49 const char * const METADATA_LONG = "metadata";
52 namespace CyadCmdlineErrors {
53 const char * const UNKNOWN_ERROR = "Unknown error";
54 const char * const NO_OPTION = "No option specified";
55 const char * const UNKNOWN_OPTION = "Unknown option";
56 const char * const UNKNOWN_OPTION_SET_BUCKET = "Unknown option in --set-bucket";
57 const char * const UNKNOWN_OPTION_DELETE_BUCKET = "Unknown option in --delete-bucket";
58 const char * const NO_POLICY = "No --policy specified";
59 const char * const NO_BUCKET = "No bucket specified";
60 const char * const INVALID_POLICY = "Invalid --policy option";
63 CyadCommandlineParser::CyadCommandlineParser(int argc, char * const *argv)
64 : m_argc(argc), m_argv(argv) {}
66 CyadCommandlineParser::~CyadCommandlineParser() {}
68 std::shared_ptr<CyadCommand> CyadCommandlineParser::parseMain(void) {
69 namespace Args = CyadCmdlineArgs;
71 const struct option long_options[] = {
72 { Args::HELP_LONG, no_argument, nullptr, Args::HELP },
73 { Args::SET_BUCKET_LONG, required_argument, nullptr, Args::SET_BUCKET },
74 { Args::DELETE_BUCKET_LONG, required_argument, nullptr, Args::DELETE_BUCKET },
75 { nullptr, 0, nullptr, 0 }
78 optind = 0; // On entry to `getopt', zero means this is the first call; initialize.
80 std::stringstream optstr;
81 optstr << ":" << Args::HELP
82 << Args::SET_BUCKET << ":"
83 << Args::DELETE_BUCKET << ":";
85 while ((opt = getopt_long(m_argc, m_argv, optstr.str().c_str(), long_options, nullptr)) != -1) {
88 return std::make_shared<HelpCyadCommand>();
90 case Args::SET_BUCKET:
91 return parseSetBucket(optarg);
93 case Args::DELETE_BUCKET:
94 return parseDeleteBucket(optarg);
96 case '?': // Unknown option
97 return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::UNKNOWN_OPTION);
99 case ':': // Missing argument
101 case Args::SET_BUCKET:
102 case Args::DELETE_BUCKET:
103 return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::NO_BUCKET);
105 // Shall never happen, but let's just make compiler happy.
106 return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::UNKNOWN_ERROR);
109 return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::UNKNOWN_OPTION);
113 return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::NO_OPTION);
116 std::shared_ptr<CyadCommand> CyadCommandlineParser::parseSetBucket(const std::string &bucketId) {
117 namespace Args = CyadCmdlineArgs;
118 namespace Errors = CyadCmdlineErrors;
120 const struct option long_options[] = {
121 { Args::POLICY_LONG, required_argument, nullptr, Args::POLICY },
122 { Args::METADATA_LONG, required_argument, nullptr, Args::METADATA },
123 { nullptr, 0, nullptr, 0 }
127 std::string metadata;
130 std::stringstream optstr;
132 << Args::POLICY << ":"
133 << Args::METADATA << ":";
135 while ((opt = getopt_long(m_argc, m_argv, optstr.str().c_str(), long_options, nullptr)) != -1) {
144 return std::make_shared<ErrorCyadCommand>(Errors::UNKNOWN_OPTION_SET_BUCKET);
149 return std::make_shared<ErrorCyadCommand>(Errors::NO_POLICY);
152 auto policyType = parsePolicyType(policy);
153 return std::make_shared<SetBucketCyadCommand>(bucketId, PolicyResult(policyType, metadata));
154 } catch (const PolicyParsingException &) {
155 return std::make_shared<ErrorCyadCommand>(Errors::INVALID_POLICY);
159 std::shared_ptr<CyadCommand> CyadCommandlineParser::parseDeleteBucket(const std::string &bucketId) {
160 namespace Errors = CyadCmdlineErrors;
162 // Expect no additional options
163 const struct option long_options[] = {
164 { nullptr, 0, nullptr, 0 }
167 if (getopt_long(m_argc, m_argv, ":", long_options, nullptr) == -1) {
168 return std::make_shared<DeleteBucketCyadCommand>(bucketId);
170 return std::make_shared<ErrorCyadCommand>(Errors::UNKNOWN_OPTION_DELETE_BUCKET);
174 PolicyType CyadCommandlineParser::parsePolicyType(const std::string &rawPolicy) {
175 if (rawPolicy == "DENY")
176 return CYNARA_ADMIN_DENY;
177 if (rawPolicy == "NONE")
178 return CYNARA_ADMIN_NONE;
179 if (rawPolicy == "BUCKET")
180 return CYNARA_ADMIN_BUCKET;
181 if (rawPolicy == "ALLOW")
182 return CYNARA_ADMIN_ALLOW;
184 // If base for std::stoi is set to 0, it detects base by itself from the format of the sequence
186 return std::stoi(rawPolicy, nullptr, 0);
187 } catch (const std::logic_error &) {
188 throw PolicyParsingException();
192 } /* namespace Cynara */