static gboolean gvir_sandbox_console_open_remote(GVirSandboxConsoleRaw *console, GError **error) { GVirSandboxConsoleRawPrivate *priv = console->priv; GVirConnection *conn = NULL; GVirDomain *dom = NULL; gchar *devname = NULL; gboolean ret = FALSE; GVirConfigDomain *conf = NULL; GList *devices = NULL, *tmp; g_object_get(console, "connection", &conn, "domain", &dom, "devname", &devname, NULL); if (!gvir_sandbox_console_get_direct(GVIR_SANDBOX_CONSOLE(console))) { priv->console = gvir_connection_get_stream(conn, 0); if (!gvir_domain_open_console(dom, priv->console, devname, 0, error)) { g_object_unref(priv->console); priv->console = NULL; goto cleanup; } } else { const gchar *pty = NULL; if (!(conf = gvir_domain_get_config(dom, 0, error))) goto cleanup; if (!(devices = gvir_config_domain_get_devices(conf))) { g_set_error(error, GVIR_SANDBOX_CONSOLE_RAW_ERROR, 0, "%s", _("No devices found for domain")); goto cleanup; } tmp = devices; while (tmp && !pty) { GVirConfigDomainDevice *dev = tmp->data; const gchar *alias = gvir_config_domain_device_get_alias(dev); if (alias && g_str_equal(alias, devname) && GVIR_CONFIG_IS_DOMAIN_CHARDEV(dev)) { GVirConfigDomainChardev *cdev = GVIR_CONFIG_DOMAIN_CHARDEV(dev); GVirConfigDomainChardevSource *csrc = gvir_config_domain_chardev_get_source(cdev); if (GVIR_CONFIG_IS_DOMAIN_CHARDEV_SOURCE_PTY(csrc)) { GVirConfigDomainChardevSourcePty *csrcpty = GVIR_CONFIG_DOMAIN_CHARDEV_SOURCE_PTY(csrc); pty = gvir_config_domain_chardev_source_pty_get_path(csrcpty); break; } } tmp = tmp->next; } if (!pty) { g_set_error(error, GVIR_SANDBOX_CONSOLE_RAW_ERROR, 0, _("No device %s found for domain"), devname); goto cleanup; } if ((priv->consolePty = open(pty, O_NOCTTY|O_RDWR)) < 0) { g_set_error(error, GVIR_SANDBOX_CONSOLE_RAW_ERROR, 0, _("Unable to open console %s"), pty); goto cleanup; } priv->consoleInput = G_UNIX_INPUT_STREAM(g_unix_input_stream_new(priv->consolePty, FALSE)); priv->consoleOutput = G_UNIX_OUTPUT_STREAM(g_unix_output_stream_new(priv->consolePty, FALSE)); } ret = TRUE; cleanup: if (conf) g_object_unref(conf); if (conn) g_object_unref(conn); if (dom) g_object_unref(dom); g_free(devname); return ret; }
static gboolean gvir_sandbox_console_raw_attach(GVirSandboxConsole *console, GUnixInputStream *localStdin, GUnixOutputStream *localStdout, GUnixOutputStream *localStderr, GError **error) { GVirSandboxConsoleRawPrivate *priv = GVIR_SANDBOX_CONSOLE_RAW(console)->priv; gboolean ret = FALSE; GVirConnection *conn = NULL; GVirDomain *dom = NULL; gchar *devname = NULL; if (priv->console) { g_set_error(error, GVIR_SANDBOX_CONSOLE_RAW_ERROR, 0, "%s", _("Console is already attached to a stream")); return FALSE; } if (localStdin && !gvir_sandbox_console_raw_start_term(GVIR_SANDBOX_CONSOLE_RAW(console), localStdin, error)) return FALSE; priv->localStdin = localStdin ? g_object_ref(localStdin) : NULL; priv->localStdout = localStdout ? g_object_ref(localStdout) : NULL; priv->localStderr = g_object_ref(localStderr); g_object_get(console, "connection", &conn, "domain", &dom, "devname", &devname, NULL); priv->console = gvir_connection_get_stream(conn, 0); if (!gvir_domain_open_console(dom, priv->console, devname, 0, error)) goto cleanup; priv->consoleToLocalLength = 4096; priv->consoleToLocal = g_new0(gchar, priv->consoleToLocalLength); if (localStdin) { priv->localToConsoleLength = 4096; priv->localToConsole = g_new0(gchar, priv->localToConsoleLength); } do_console_raw_update_events(GVIR_SANDBOX_CONSOLE_RAW(console)); ret = TRUE; cleanup: if (!ret && localStdin) gvir_sandbox_console_raw_stop_term(GVIR_SANDBOX_CONSOLE_RAW(console), localStdin, NULL); if (conn) g_object_unref(conn); if (dom) g_object_unref(dom); g_free(devname); return ret; }