|
|
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.