|
|
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: }
82:
83: if (!qdict_haskey(dict, "arguments")) {
84: args = qdict_new();
85: } else {
86: args = qdict_get_qdict(dict, "arguments");
87: QINCREF(args);
88: }
89:
90: switch (cmd->type) {
91: case QCT_NORMAL:
92: cmd->fn(args, &ret, errp);
93: if (!error_is_set(errp) && ret == NULL) {
94: ret = QOBJECT(qdict_new());
95: }
96: break;
97: }
98:
99: QDECREF(args);
100:
101: return ret;
102: }
103:
104: QObject *qmp_dispatch(QObject *request)
105: {
106: Error *err = NULL;
107: QObject *ret;
108: QDict *rsp;
109:
110: ret = do_qmp_dispatch(request, &err);
111:
112: rsp = qdict_new();
113: if (err) {
114: qdict_put_obj(rsp, "error", error_get_qobject(err));
115: error_free(err);
116: } else if (ret) {
117: qdict_put_obj(rsp, "return", ret);
118: } else {
119: QDECREF(rsp);
120: return NULL;
121: }
122:
123: return QOBJECT(rsp);
124: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.