in src/commands/cmd_server.cc [393:468]
Status Parse(const std::vector<std::string> &args) override {
subcommand_ = util::ToLower(args[1]);
// subcommand: getname id kill list info setname
if ((subcommand_ == "id" || subcommand_ == "getname" || subcommand_ == "list" || subcommand_ == "info") &&
args.size() == 2) {
return Status::OK();
}
if ((subcommand_ == "setname") && args.size() == 3) {
// Check if the charset is ok. We need to do this otherwise
// CLIENT LIST or CLIENT INFO format will break. You should always be able to
// split by space to get the different fields.
for (auto ch : args[2]) {
if (ch < '!' || ch > '~') {
return {Status::RedisInvalidCmd, "Client names cannot contain spaces, newlines or special characters"};
}
}
conn_name_ = args[2];
return Status::OK();
}
if ((subcommand_ == "kill")) {
if (args.size() == 2) {
return {Status::RedisParseErr, errInvalidSyntax};
}
if (args.size() == 3) {
addr_ = args[2];
new_format_ = false;
return Status::OK();
}
size_t i = 2;
new_format_ = true;
while (i < args.size()) {
bool more_args = i < args.size();
if (util::EqualICase(args[i], "addr") && more_args) {
addr_ = args[i + 1];
} else if (util::EqualICase(args[i], "id") && more_args) {
auto parse_result = ParseInt<uint64_t>(args[i + 1], 10);
if (!parse_result) {
return {Status::RedisParseErr, errValueNotInteger};
}
id_ = *parse_result;
} else if (util::EqualICase(args[i], "skipme") && more_args) {
if (util::EqualICase(args[i + 1], "yes")) {
skipme_ = true;
} else if (util::EqualICase(args[i + 1], "no")) {
skipme_ = false;
} else {
return {Status::RedisParseErr, errInvalidSyntax};
}
} else if (util::EqualICase(args[i], "type") && more_args) {
if (util::EqualICase(args[i + 1], "normal")) {
kill_type_ |= kTypeNormal;
} else if (util::EqualICase(args[i + 1], "pubsub")) {
kill_type_ |= kTypePubsub;
} else if (util::EqualICase(args[i + 1], "master")) {
kill_type_ |= kTypeMaster;
} else if (util::EqualICase(args[i + 1], "replica") || util::EqualICase(args[i + 1], "slave")) {
kill_type_ |= kTypeSlave;
} else {
return {Status::RedisParseErr, errInvalidSyntax};
}
} else {
return {Status::RedisParseErr, errInvalidSyntax};
}
i += 2;
}
return Status::OK();
}
return {Status::RedisInvalidCmd, "Syntax error, try CLIENT LIST|INFO|KILL ip:port|GETNAME|SETNAME"};
}