* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include <dirent.h>
#include "hw/hw.h"
#include "hw/usb.h"
#include "hw/pcmcia.h"
#include "audio/audio.h"
#include "disas.h"
#include "balloon.h"
-#include <dirent.h>
#include "qemu-timer.h"
#include "migration.h"
#include "kvm.h"
+#include "acl.h"
//#define DEBUG
//#define DEBUG_COMPLETION
readline_show_prompt(mon->rs);
}
-static void monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
- void *opaque)
+static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
+ void *opaque)
{
- readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
- /* prompt is printed on return from the command handler */
+ if (mon->rs) {
+ readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
+ /* prompt is printed on return from the command handler */
+ return 0;
+ } else {
+ monitor_printf(mon, "terminal does not support password prompting\n");
+ return -ENOTTY;
+ }
}
void monitor_flush(Monitor *mon)
int i;
for (i = 0; filename[i]; i++) {
- switch (filename[i]) {
- case ' ':
- case '"':
- case '\\':
- monitor_printf(mon, "\\%c", filename[i]);
- break;
- case '\t':
- monitor_printf(mon, "\\t");
- break;
- case '\r':
- monitor_printf(mon, "\\r");
- break;
- case '\n':
- monitor_printf(mon, "\\n");
- break;
- default:
- monitor_printf(mon, "%c", filename[i]);
- break;
- }
+ switch (filename[i]) {
+ case ' ':
+ case '"':
+ case '\\':
+ monitor_printf(mon, "\\%c", filename[i]);
+ break;
+ case '\t':
+ monitor_printf(mon, "\\t");
+ break;
+ case '\r':
+ monitor_printf(mon, "\\r");
+ break;
+ case '\n':
+ monitor_printf(mon, "\\n");
+ break;
+ default:
+ monitor_printf(mon, "%c", filename[i]);
+ break;
+ }
}
}
if (!cur_mon->mon_cpu) {
mon_set_cpu(0);
}
+ cpu_synchronize_state(cur_mon->mon_cpu, 0);
return cur_mon->mon_cpu;
}
mon_get_cpu();
for(env = first_cpu; env != NULL; env = env->next_cpu) {
+ cpu_synchronize_state(env, 0);
monitor_printf(mon, "%c CPU #%d:",
(env == mon->mon_cpu) ? '*' : ' ',
env->cpu_index);
int i;
const char *str;
+ if (!mon->rs)
+ return;
i = 0;
for(;;) {
str = readline_get_history(mon->rs, i);
static void do_change_vnc(Monitor *mon, const char *target, const char *arg)
{
if (strcmp(target, "passwd") == 0 ||
- strcmp(target, "password") == 0) {
- if (arg) {
+ strcmp(target, "password") == 0) {
+ if (arg) {
char password[9];
- strncpy(password, arg, sizeof(password));
- password[sizeof(password) - 1] = '\0';
+ strncpy(password, arg, sizeof(password));
+ password[sizeof(password) - 1] = '\0';
change_vnc_password_cb(mon, password, NULL);
} else {
monitor_read_password(mon, change_vnc_password_cb, NULL);
}
} else {
- if (vnc_display_open(NULL, target) < 0)
+ if (vnc_display_open(NULL, target) < 0)
monitor_printf(mon, "could not start VNC server on %s\n", target);
}
}
const char *arg)
{
if (strcmp(device, "vnc") == 0) {
- do_change_vnc(mon, target, arg);
+ do_change_vnc(mon, target, arg);
} else {
- do_change_block(mon, device, target, arg);
+ do_change_block(mon, device, target, arg);
}
}
if (gdbserver_start(port) < 0) {
monitor_printf(mon, "Could not open gdbserver socket on port '%s'\n",
port);
+ } else if (strcmp(port, "none") == 0) {
+ monitor_printf(mon, "Disabled gdbserver\n");
} else {
monitor_printf(mon, "Waiting gdb connection on port '%s'\n", port);
}
monitor_printf(mon, "balloon: actual=%d\n", (int)(actual >> 20));
}
+static void do_acl(Monitor *mon,
+ const char *command,
+ const char *aclname,
+ const char *match,
+ int has_index,
+ int index)
+{
+ qemu_acl *acl;
+
+ acl = qemu_acl_find(aclname);
+ if (!acl) {
+ monitor_printf(mon, "acl: unknown list '%s'\n", aclname);
+ return;
+ }
+
+ if (strcmp(command, "show") == 0) {
+ int i = 0;
+ qemu_acl_entry *entry;
+ monitor_printf(mon, "policy: %s\n",
+ acl->defaultDeny ? "deny" : "allow");
+ TAILQ_FOREACH(entry, &acl->entries, next) {
+ i++;
+ monitor_printf(mon, "%d: %s %s\n", i,
+ entry->deny ? "deny" : "allow",
+ entry->match);
+ }
+ } else if (strcmp(command, "reset") == 0) {
+ qemu_acl_reset(acl);
+ monitor_printf(mon, "acl: removed all rules\n");
+ } else if (strcmp(command, "policy") == 0) {
+ if (!match) {
+ monitor_printf(mon, "acl: missing policy parameter\n");
+ return;
+ }
+
+ if (strcmp(match, "allow") == 0) {
+ acl->defaultDeny = 0;
+ monitor_printf(mon, "acl: policy set to 'allow'\n");
+ } else if (strcmp(match, "deny") == 0) {
+ acl->defaultDeny = 1;
+ monitor_printf(mon, "acl: policy set to 'deny'\n");
+ } else {
+ monitor_printf(mon, "acl: unknown policy '%s', expected 'deny' or 'allow'\n", match);
+ }
+ } else if ((strcmp(command, "allow") == 0) ||
+ (strcmp(command, "deny") == 0)) {
+ int deny = strcmp(command, "deny") == 0 ? 1 : 0;
+ int ret;
+
+ if (!match) {
+ monitor_printf(mon, "acl: missing match parameter\n");
+ return;
+ }
+
+ if (has_index)
+ ret = qemu_acl_insert(acl, deny, match, index);
+ else
+ ret = qemu_acl_append(acl, deny, match);
+ if (ret < 0)
+ monitor_printf(mon, "acl: unable to add acl entry\n");
+ else
+ monitor_printf(mon, "acl: added rule at position %d\n", ret);
+ } else if (strcmp(command, "remove") == 0) {
+ int ret;
+
+ if (!match) {
+ monitor_printf(mon, "acl: missing match parameter\n");
+ return;
+ }
+
+ ret = qemu_acl_remove(acl, match);
+ if (ret < 0)
+ monitor_printf(mon, "acl: no matching acl entry\n");
+ else
+ monitor_printf(mon, "acl: removed rule at position %d\n", ret);
+ } else {
+ monitor_printf(mon, "acl: unknown command '%s'\n", command);
+ }
+}
+
/* Please update qemu-doc.texi when adding or changing commands */
static const mon_cmd_t mon_cmds[] = {
{ "help|?", "s?", help_cmd,
"target", "request VM to change it's memory allocation (in MB)" },
{ "set_link", "ss", do_set_link,
"name [up|down]", "change the link status of a network adapter" },
+ { "acl", "sss?i?", do_acl, "<command> <aclname> [<match>] [<index>]\n",
+ "acl show vnc.username\n"
+ "acl policy vnc.username deny\n"
+ "acl allow vnc.username fred\n"
+ "acl deny vnc.username bob\n"
+ "acl reset vnc.username\n" },
{ NULL, NULL, },
};
u = 0;
for (i = 0; i < 8; i++)
- u |= env->crf[i] << (32 - (4 * i));
+ u |= env->crf[i] << (32 - (4 * i));
return u;
}
cmd_completion(str, cmd->name);
}
} else if (!strcmp(cmd->name, "sendkey")) {
+ char *sep = strrchr(str, '-');
+ if (sep)
+ str = sep + 1;
readline_set_completion_index(cur_mon->rs, strlen(str));
for(key = key_defs; key->name != NULL; key++) {
cmd_completion(str, key->name);
cur_mon = opaque;
- for (i = 0; i < size; i++)
- readline_handle_byte(cur_mon->rs, buf[i]);
+ if (cur_mon->rs) {
+ for (i = 0; i < size; i++)
+ readline_handle_byte(cur_mon->rs, buf[i]);
+ } else {
+ if (size == 0 || buf[size - 1] != 0)
+ monitor_printf(cur_mon, "corrupted command\n");
+ else
+ monitor_handle_command(cur_mon, (char *)buf);
+ }
cur_mon = old_mon;
}
monitor_resume(mon);
}
-void monitor_suspend(Monitor *mon)
+int monitor_suspend(Monitor *mon)
{
+ if (!mon->rs)
+ return -ENOTTY;
mon->suspend_cnt++;
+ return 0;
}
void monitor_resume(Monitor *mon)
{
+ if (!mon->rs)
+ return;
if (--mon->suspend_cnt == 0)
readline_show_prompt(mon->rs);
}
}
}
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * tab-width: 8
+ * End:
+ */
+
void monitor_init(CharDriverState *chr, int flags)
{
static int is_first_init = 1;
mon->flags = flags;
if (mon->chr->focus != 0)
mon->suspend_cnt = 1; /* mux'ed monitors start suspended */
- mon->rs = readline_init(mon, monitor_find_completion);
- monitor_read_command(mon, 0);
+ if (flags & MONITOR_USE_READLINE) {
+ mon->rs = readline_init(mon, monitor_find_completion);
+ monitor_read_command(mon, 0);
+ }
qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, monitor_event,
mon);
BlockDriverCompletionFunc *completion_cb,
void *opaque)
{
+ int err;
+
if (!bdrv_key_required(bs)) {
if (completion_cb)
completion_cb(opaque, 0);
mon->password_completion_cb = completion_cb;
mon->password_opaque = opaque;
- monitor_read_password(mon, bdrv_password_cb, bs);
+ err = monitor_read_password(mon, bdrv_password_cb, bs);
+
+ if (err && completion_cb)
+ completion_cb(opaque, err);
}