|
|
1.1 root 1: /*
2: * Core Definitions for QAPI/QMP Dispatch
3: *
4: * Copyright IBM, Corp. 2011
5: *
6: * Authors:
7: * Anthony Liguori <[email protected]>
8: *
9: * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10: * See the COPYING.LIB file in the top-level directory.
11: *
12: */
13:
14: #include "qemu-objects.h"
15: #include "qapi/qmp-core.h"
16: #include "json-parser.h"
17: #include "error.h"
18: #include "error_int.h"
19: #include "qerror.h"
20:
21: static QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp)
22: {
23: const QDictEntry *ent;
24: const char *arg_name;
25: const QObject *arg_obj;
26: bool has_exec_key = false;
27: QDict *dict = NULL;
28:
29: if (qobject_type(request) != QTYPE_QDICT) {
30: error_set(errp, QERR_QMP_BAD_INPUT_OBJECT,
31: "request is not a dictionary");
32: return NULL;
33: }
34:
35: dict = qobject_to_qdict(request);
36:
37: for (ent = qdict_first(dict); ent;
38: ent = qdict_next(dict, ent)) {
39: arg_name = qdict_entry_key(ent);
40: arg_obj = qdict_entry_value(ent);
41:
42: if (!strcmp(arg_name, "execute")) {
43: if (qobject_type(arg_obj) != QTYPE_QSTRING) {
44: error_set(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "execute",
45: "string");
46: return NULL;
47: }
48: has_exec_key = true;
49: } else if (strcmp(arg_name, "arguments")) {
50: error_set(errp, QERR_QMP_EXTRA_MEMBER, arg_name);
51: return NULL;
52: }
53: }
54:
55: if (!has_exec_key) {
56: error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, "execute");
57: return NULL;
58: }
59:
60: return dict;
61: }
62:
63: static QObject *do_qmp_dispatch(QObject *request, Error **errp)
64: {
65: const char *command;
66: QDict *args, *dict;
67: QmpCommand *cmd;
68: QObject *ret = NULL;
69:
70:
71: dict = qmp_dispatch_check_obj(request, errp);
72: if (!dict || error_is_set(errp)) {
73: return NULL;
74: }
75:
76: command = qdict_get_str(dict, "execute");
77: cmd = qmp_find_command(command);
78: if (cmd == NULL) {
79: error_set(errp, QERR_COMMAND_NOT_FOUND, command);
80: return NULL;
81: }
1.1.1.2 ! root 82: if (!cmd->enabled) {
! 83: error_set(errp, QERR_COMMAND_DISABLED, command);
! 84: return NULL;
! 85: }
1.1 root 86:
87: if (!qdict_haskey(dict, "arguments")) {
88: args = qdict_new();
89: } else {
90: args = qdict_get_qdict(dict, "arguments");
91: QINCREF(args);
92: }
93:
94: switch (cmd->type) {
95: case QCT_NORMAL:
96: cmd->fn(args, &ret, errp);
1.1.1.2 ! root 97: if (!error_is_set(errp)) {
! 98: if (cmd->options & QCO_NO_SUCCESS_RESP) {
! 99: g_assert(!ret);
! 100: } else if (!ret) {
! 101: ret = QOBJECT(qdict_new());
! 102: }
1.1 root 103: }
104: break;
105: }
106:
107: QDECREF(args);
108:
109: return ret;
110: }
111:
112: QObject *qmp_dispatch(QObject *request)
113: {
114: Error *err = NULL;
115: QObject *ret;
116: QDict *rsp;
117:
118: ret = do_qmp_dispatch(request, &err);
119:
120: rsp = qdict_new();
121: if (err) {
122: qdict_put_obj(rsp, "error", error_get_qobject(err));
123: error_free(err);
124: } else if (ret) {
125: qdict_put_obj(rsp, "return", ret);
126: } else {
127: QDECREF(rsp);
128: return NULL;
129: }
130:
131: return QOBJECT(rsp);
132: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.