Question is whether we want another dependency in spicec or not. On the other hand is URI processing not as trivial as it seems. Maybe making it a configure flag?
For spice-gtk glib would provide similar routines to parse URI strings. --- client/application.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ client/application.h | 1 + configure.ac | 19 +++++++++++++++ 3 files changed, 81 insertions(+), 0 deletions(-) diff --git a/client/application.cpp b/client/application.cpp index d865e84..a9e86d1 100644 --- a/client/application.cpp +++ b/client/application.cpp @@ -53,6 +53,8 @@ #include <smartcard_channel.h> #endif +#include <uriparser/Uri.h> + #define STICKY_KEY_PIXMAP ALT_IMAGE_RES_ID #define STICKY_KEY_TIMEOUT 750 @@ -2130,6 +2132,56 @@ bool Application::set_disabled_display_effects(CmdLineParser& parser, char *val, return true; } +bool Application::parse_connection_uri(const char* uri, std::string& host, int& port, int& sport, std::string& password) +{ + UriParserStateA state; + UriUriA uri_object; + + state.uri = &uri_object; + + if (uriParseUriA(&state, uri) != URI_SUCCESS) { + uriFreeUriMembersA(&uri_object); + return false; + } + + if ((uri_object.scheme.afterLast != uri_object.scheme.first + 5) || + (strncmp(uri_object.scheme.first, "spice", 5) != 0)) { + uriFreeUriMembersA(&uri_object); + return false; + } + + host.assign(uri_object.hostText.first, uri_object.hostText.afterLast); + + UriQueryListA* queryList; + int itemCount; + + if (uriDissectQueryMallocA(&queryList, &itemCount, + uri_object.query.first, uri_object.query.afterLast) != URI_SUCCESS) { + uriFreeUriMembersA(&uri_object); + return false; + } + + for (UriQueryListA* i(queryList); i != NULL; i = i->next) { + if ((strcmp(i->key, "port") == 0) && (i->value != NULL)) { + port = str_to_port(i->value); + continue; + } + if ((strcmp(i->key, "tls-port") == 0) && (i->value != NULL)) { + sport = str_to_port(i->value); + continue; + } + if ((strcmp(i->key, "password") == 0) && (i->value != NULL)) { + password = i->value; + continue; + } + /* ignore all other parameters for now */ + } + + uriFreeQueryListA(queryList); + uriFreeUriMembersA(&uri_object); + return true; +} + void Application::on_cmd_line_invalid_arg(const char* arg0, const char* what, const char* val) { Platform::term_printf("%s: invalid %s value %s\n", arg0, what, val); @@ -2185,6 +2237,7 @@ bool Application::process_cmd_line(int argc, char** argv) SPICE_OPT_HOST = CmdLineParser::OPTION_FIRST_AVILABLE, SPICE_OPT_PORT, SPICE_OPT_SPORT, + SPICE_OPT_URI, SPICE_OPT_PASSWORD, SPICE_OPT_FULL_SCREEN, SPICE_OPT_SECURE_CHANNELS, @@ -2225,6 +2278,7 @@ bool Application::process_cmd_line(int argc, char** argv) parser.add(SPICE_OPT_HOST, "host", "spice server address", "host", true, 'h'); parser.add(SPICE_OPT_PORT, "port", "spice server port", "port", true, 'p'); parser.add(SPICE_OPT_SPORT, "secure-port", "spice server secure port", "port", true, 's'); + parser.add(SPICE_OPT_URI, "uri", "spice uri", "uri", true); parser.add(SPICE_OPT_SECURE_CHANNELS, "secure-channels", "force secure connection on the specified channels", "channel", true); @@ -2301,6 +2355,13 @@ bool Application::process_cmd_line(int argc, char** argv) } break; } + case SPICE_OPT_URI: { + if (parse_connection_uri(val, host, port, sport, password) == false) { + on_cmd_line_invalid_arg(argv[0], "uri", val); + return false; + } + break; + } case SPICE_OPT_FULL_SCREEN: if (val) { if (strcmp(val, "auto-conf")) { diff --git a/client/application.h b/client/application.h index f9bbd53..f6ec524 100644 --- a/client/application.h +++ b/client/application.h @@ -289,6 +289,7 @@ private: bool set_canvas_option(CmdLineParser& parser, char *val, const char* arg0); bool set_disabled_display_effects(CmdLineParser& parser, char *val, const char* arg0, DisplaySetting& disp_setting); + bool parse_connection_uri(const char* uri, std::string& host, int& port, int& sport, std::string& password); void on_cmd_line_invalid_arg(const char* arg0, const char* what, const char* val); bool process_cmd_line(int argc, char** argv); void register_channels(); diff --git a/configure.ac b/configure.ac index 511d94e..ef4d68e 100644 --- a/configure.ac +++ b/configure.ac @@ -297,6 +297,25 @@ AC_SUBST(JPEG_LIBS) AC_CHECK_LIB(z, deflate, Z_LIBS='-lz', AC_MSG_ERROR([zlib not found])) AC_SUBST(Z_LIBS) +URIPARSER_MISSING="Please install uriparser 0.7.5 or later. + On a Debian-based system enter 'sudo apt-get install liburiparser-dev'." +AC_CHECK_LIB(uriparser, uriParseUriA,, AC_MSG_ERROR(${URIPARSER_MISSING})) +AC_CHECK_HEADER(uriparser/Uri.h,, AC_MSG_ERROR(${URIPARSER_MISSING})) + +URIPARSER_TOO_OLD="uriparser 0.7.5 or later is required, your copy is too old." +AC_COMPILE_IFELSE([ +#include <uriparser/Uri.h> +#if (defined(URI_VER_MAJOR) && defined(URI_VER_MINOR) && defined(URI_VER_RELEASE) \ +&& ((URI_VER_MAJOR > 0) \ +|| ((URI_VER_MAJOR == 0) && (URI_VER_MINOR > 7)) \ +|| ((URI_VER_MAJOR == 0) && (URI_VER_MINOR == 7) && (URI_VER_RELEASE >= 5)) \ +)) +/* FINE */ +#else +# error uriparser not recent enough +#endif +],,AC_MSG_ERROR(${URIPARSER_TOO_OLD})) + dnl =========================================================================== dnl check compiler flags -- 1.7.3.4 -- stepping stone GmbH Neufeldstrasse 9 CH-3012 Bern Telefon: +41 31 332 53 63 www.stepping-stone.ch tiziano.muel...@stepping-stone.ch _______________________________________________ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel