| 377 | } |
| 378 | |
| 379 | CommandResult |
| 380 | command_process(Client &client, unsigned num, char *line) noexcept |
| 381 | { |
| 382 | Response r(client, num); |
| 383 | |
| 384 | /* get the command name (first word on the line) */ |
| 385 | /* we have to set current_command because Response::Error() |
| 386 | expects it to be set */ |
| 387 | |
| 388 | Tokenizer tokenizer(line); |
| 389 | |
| 390 | const char *cmd_name; |
| 391 | try { |
| 392 | cmd_name = tokenizer.NextWord(); |
| 393 | if (cmd_name == nullptr) { |
| 394 | r.Error(ACK_ERROR_UNKNOWN, "No command given"); |
| 395 | /* this client does not speak the MPD |
| 396 | protocol; kick the connection */ |
| 397 | return CommandResult::FINISH; |
| 398 | } |
| 399 | } catch (const std::exception &e) { |
| 400 | r.Error(ACK_ERROR_UNKNOWN, e.what()); |
| 401 | /* this client does not speak the MPD protocol; kick |
| 402 | the connection */ |
| 403 | return CommandResult::FINISH; |
| 404 | } |
| 405 | |
| 406 | try { |
| 407 | /* now parse the arguments (quoted or unquoted) */ |
| 408 | |
| 409 | StaticVector<const char *, COMMAND_ARGV_MAX> argv; |
| 410 | |
| 411 | while (true) { |
| 412 | char *a = tokenizer.NextParam(); |
| 413 | if (a == nullptr) |
| 414 | break; |
| 415 | |
| 416 | if (argv.full()) { |
| 417 | r.Error(ACK_ERROR_ARG, "Too many arguments"); |
| 418 | return CommandResult::ERROR; |
| 419 | } |
| 420 | |
| 421 | argv.push_back(a); |
| 422 | } |
| 423 | |
| 424 | const Request args{argv}; |
| 425 | |
| 426 | /* look up and invoke the command handler */ |
| 427 | |
| 428 | const struct command *cmd = |
| 429 | command_checked_lookup(r, client.GetPermission(), |
| 430 | cmd_name, args); |
| 431 | if (cmd == nullptr) |
| 432 | return CommandResult::ERROR; |
| 433 | |
| 434 | return cmd->handler(client, args, r); |
| 435 | } catch (...) { |
| 436 | PrintError(r, std::current_exception()); |
no test coverage detected