mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 02:51:16 +00:00
Add separate qparams module for handling query parameters.
* src/qparams.c, src/qparams.h, src/Makefile.am: Added a separate 'qparams' module for handling query parameters. * src/remote_internal.c: Factor out query parameter code so it uses the 'qparams' module.
This commit is contained in:
parent
ed9788c796
commit
3b0149354b
@ -1,3 +1,11 @@
|
|||||||
|
Mon Dec 17 10:05:00 UTC 2007 Richard W.M. Jones <rjones@redhat.com>
|
||||||
|
|
||||||
|
Add separate qparams module for handling query parameters.
|
||||||
|
* src/qparams.c, src/qparams.h, src/Makefile.am: Added a
|
||||||
|
separate 'qparams' module for handling query parameters.
|
||||||
|
* src/remote_internal.c: Factor out query parameter code so
|
||||||
|
it uses the 'qparams' module.
|
||||||
|
|
||||||
Mon Dec 17 10:01:00 UTC 2007 Richard W.M. Jones <rjones@redhat.com>
|
Mon Dec 17 10:01:00 UTC 2007 Richard W.M. Jones <rjones@redhat.com>
|
||||||
|
|
||||||
Add extra utility functions to buf.c
|
Add extra utility functions to buf.c
|
||||||
|
@ -34,6 +34,7 @@ CLIENT_SOURCES = \
|
|||||||
hash.c hash.h \
|
hash.c hash.h \
|
||||||
test.c test.h \
|
test.c test.h \
|
||||||
buf.c buf.h \
|
buf.c buf.h \
|
||||||
|
qparams.c qparams.h \
|
||||||
xml.c xml.h \
|
xml.c xml.h \
|
||||||
event.c event.h \
|
event.c event.h \
|
||||||
xen_unified.c xen_unified.h \
|
xen_unified.c xen_unified.h \
|
||||||
|
245
src/qparams.c
Normal file
245
src/qparams.c
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
/* Copyright (C) 2007 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Richard W.M. Jones <rjones@redhat.com>
|
||||||
|
*
|
||||||
|
* Utility functions to help parse and assemble query strings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "buf.h"
|
||||||
|
|
||||||
|
#include "qparams.h"
|
||||||
|
|
||||||
|
struct qparam_set *
|
||||||
|
new_qparam_set (int init_alloc, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
struct qparam_set *ps;
|
||||||
|
const char *pname, *pvalue;
|
||||||
|
|
||||||
|
if (init_alloc <= 0) init_alloc = 1;
|
||||||
|
|
||||||
|
ps = malloc (sizeof (*ps));
|
||||||
|
if (!ps) return NULL;
|
||||||
|
ps->n = 0;
|
||||||
|
ps->alloc = init_alloc;
|
||||||
|
ps->p = malloc (init_alloc * sizeof (ps->p[0]));
|
||||||
|
if (!ps->p) {
|
||||||
|
free (ps);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start (args, init_alloc);
|
||||||
|
while ((pname = va_arg (args, char *)) != NULL) {
|
||||||
|
pvalue = va_arg (args, char *);
|
||||||
|
|
||||||
|
if (append_qparam (ps, pname, pvalue) == -1) {
|
||||||
|
free_qparam_set (ps);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
return ps;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
append_qparams (struct qparam_set *ps, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
const char *pname, *pvalue;
|
||||||
|
|
||||||
|
va_start (args, ps);
|
||||||
|
while ((pname = va_arg (args, char *)) != NULL) {
|
||||||
|
pvalue = va_arg (args, char *);
|
||||||
|
|
||||||
|
if (append_qparam (ps, pname, pvalue) == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure there is space to store at least one more parameter
|
||||||
|
* at the end of the set.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
grow_qparam_set (struct qparam_set *ps)
|
||||||
|
{
|
||||||
|
struct qparam *old_p;
|
||||||
|
|
||||||
|
if (ps->n >= ps->alloc) {
|
||||||
|
old_p = ps->p;
|
||||||
|
ps->p = realloc (ps->p, 2 * ps->alloc * sizeof (ps->p[0]));
|
||||||
|
if (!ps->p) {
|
||||||
|
ps->p = old_p;
|
||||||
|
perror ("realloc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ps->alloc *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
append_qparam (struct qparam_set *ps,
|
||||||
|
const char *name, const char *value)
|
||||||
|
{
|
||||||
|
char *pname, *pvalue;
|
||||||
|
|
||||||
|
pname = strdup (name);
|
||||||
|
if (!pname)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
pvalue = strdup (value);
|
||||||
|
if (!pvalue) {
|
||||||
|
free (pname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grow_qparam_set (ps) == -1) {
|
||||||
|
free (pname);
|
||||||
|
free (pvalue);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ps->p[ps->n].name = pname;
|
||||||
|
ps->p[ps->n].value = pvalue;
|
||||||
|
ps->p[ps->n].ignore = 0;
|
||||||
|
ps->n++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
qparam_get_query (const struct qparam_set *ps)
|
||||||
|
{
|
||||||
|
virBufferPtr buf;
|
||||||
|
int i, amp = 0;
|
||||||
|
|
||||||
|
buf = virBufferNew (100);
|
||||||
|
for (i = 0; i < ps->n; ++i) {
|
||||||
|
if (!ps->p[i].ignore) {
|
||||||
|
if (amp) virBufferAddChar (buf, '&');
|
||||||
|
virBufferStrcat (buf, ps->p[i].name, "=", NULL);
|
||||||
|
virBufferURIEncodeString (buf, ps->p[i].value);
|
||||||
|
amp = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return virBufferContentAndFree (buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
free_qparam_set (struct qparam_set *ps)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ps->n; ++i) {
|
||||||
|
free (ps->p[i].name);
|
||||||
|
free (ps->p[i].value);
|
||||||
|
}
|
||||||
|
free (ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct qparam_set *
|
||||||
|
qparam_query_parse (const char *query)
|
||||||
|
{
|
||||||
|
struct qparam_set *ps;
|
||||||
|
const char *name, *value, *end, *eq;
|
||||||
|
|
||||||
|
ps = new_qparam_set (0, NULL);
|
||||||
|
if (!ps) return NULL;
|
||||||
|
|
||||||
|
if (!query || query[0] == '\0') return ps;
|
||||||
|
|
||||||
|
while (*query) {
|
||||||
|
/* Find the next separator, or end of the string. */
|
||||||
|
end = strchr (query, '&');
|
||||||
|
if (!end) end = query + strlen (query);
|
||||||
|
|
||||||
|
/* Find the first '=' character between here and end. */
|
||||||
|
eq = strchr (query, '=');
|
||||||
|
if (eq && eq >= end) eq = NULL;
|
||||||
|
|
||||||
|
/* Empty section (eg. "&&"). */
|
||||||
|
if (end == query)
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
/* If there is no '=' character, then we have just "name"
|
||||||
|
* and consistent with CGI.pm we assume value is "".
|
||||||
|
*/
|
||||||
|
else if (!eq) {
|
||||||
|
name = xmlURIUnescapeString (query, end - query, NULL);
|
||||||
|
value = "";
|
||||||
|
if (!name) goto out_of_memory;
|
||||||
|
}
|
||||||
|
/* Or if we have "name=" here (works around annoying
|
||||||
|
* problem when calling xmlURIUnescapeString with len = 0).
|
||||||
|
*/
|
||||||
|
else if (eq+1 == end) {
|
||||||
|
name = xmlURIUnescapeString (query, eq - query, NULL);
|
||||||
|
value = "";
|
||||||
|
if (!name) goto out_of_memory;
|
||||||
|
}
|
||||||
|
/* If the '=' character is at the beginning then we have
|
||||||
|
* "=value" and consistent with CGI.pm we _ignore_ this.
|
||||||
|
*/
|
||||||
|
else if (query == eq)
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
/* Otherwise it's "name=value". */
|
||||||
|
else {
|
||||||
|
name = xmlURIUnescapeString (query, eq - query, NULL);
|
||||||
|
value = xmlURIUnescapeString (eq+1, end - (eq+1), NULL);
|
||||||
|
if (!name || !value) goto out_of_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append to the parameter set. */
|
||||||
|
if (append_qparam (ps, name, value) == -1) goto out_of_memory;
|
||||||
|
|
||||||
|
next:
|
||||||
|
query = end;
|
||||||
|
if (*query) query ++; /* skip '&' separator */
|
||||||
|
}
|
||||||
|
|
||||||
|
return ps;
|
||||||
|
|
||||||
|
out_of_memory:
|
||||||
|
free_qparam_set (ps);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vim: set tabstop=4:
|
||||||
|
* vim: set shiftwidth=4:
|
||||||
|
* vim: set expandtab:
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* indent-tabs-mode: nil
|
||||||
|
* c-indent-level: 4
|
||||||
|
* c-basic-offset: 4
|
||||||
|
* tab-width: 4
|
||||||
|
* End:
|
||||||
|
*/
|
70
src/qparams.h
Normal file
70
src/qparams.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/* Copyright (C) 2007 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Richard W.M. Jones <rjones@redhat.com>
|
||||||
|
*
|
||||||
|
* Utility functions to help parse and assemble query strings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _QPARAMS_H_
|
||||||
|
#define _QPARAMS_H_
|
||||||
|
|
||||||
|
/* Single web service query parameter 'name=value'. */
|
||||||
|
struct qparam {
|
||||||
|
char *name; /* Name (unescaped). */
|
||||||
|
char *value; /* Value (unescaped). */
|
||||||
|
int ignore; /* Ignore this field in qparam_get_query */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Set of parameters. */
|
||||||
|
struct qparam_set {
|
||||||
|
int n; /* number of parameters used */
|
||||||
|
int alloc; /* allocated space */
|
||||||
|
struct qparam *p; /* array of parameters */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* New parameter set. */
|
||||||
|
extern struct qparam_set *new_qparam_set (int init_alloc, ...);
|
||||||
|
|
||||||
|
/* Appending parameters. */
|
||||||
|
extern int append_qparams (struct qparam_set *ps, ...);
|
||||||
|
extern int append_qparam (struct qparam_set *ps,
|
||||||
|
const char *name, const char *value);
|
||||||
|
|
||||||
|
/* Get a query string ("name=value&name=value&...") */
|
||||||
|
extern char *qparam_get_query (const struct qparam_set *ps);
|
||||||
|
|
||||||
|
/* Parse a query string into a parameter set. */
|
||||||
|
extern struct qparam_set *qparam_query_parse (const char *query);
|
||||||
|
|
||||||
|
extern void free_qparam_set (struct qparam_set *ps);
|
||||||
|
|
||||||
|
#endif /* _QPARAMS_H_ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vim: set tabstop=4:
|
||||||
|
* vim: set shiftwidth=4:
|
||||||
|
* vim: set expandtab:
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* indent-tabs-mode: nil
|
||||||
|
* c-indent-level: 4
|
||||||
|
* c-basic-offset: 4
|
||||||
|
* tab-width: 4
|
||||||
|
* End:
|
||||||
|
*/
|
@ -74,11 +74,11 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
|
#include "buf.h"
|
||||||
|
#include "qparams.h"
|
||||||
#include "remote_internal.h"
|
#include "remote_internal.h"
|
||||||
#include "remote_protocol.h"
|
#include "remote_protocol.h"
|
||||||
|
|
||||||
#define DEBUG 0 /* Enable verbose messages on stderr. */
|
|
||||||
|
|
||||||
/* Per-connection private data. */
|
/* Per-connection private data. */
|
||||||
#define MAGIC 999 /* private_data->magic if OK */
|
#define MAGIC 999 /* private_data->magic if OK */
|
||||||
#define DEAD 998 /* private_data->magic if dead/closed */
|
#define DEAD 998 /* private_data->magic if dead/closed */
|
||||||
@ -152,22 +152,6 @@ static void make_nonnull_network (remote_nonnull_network *net_dst, virNetworkPtr
|
|||||||
/* Helper functions for remoteOpen. */
|
/* Helper functions for remoteOpen. */
|
||||||
static char *get_transport_from_scheme (char *scheme);
|
static char *get_transport_from_scheme (char *scheme);
|
||||||
|
|
||||||
/* Parse query string. */
|
|
||||||
struct query_fields {
|
|
||||||
struct query_fields *next; /* Linked list chain. */
|
|
||||||
char *name; /* Field name (unescaped). */
|
|
||||||
char *value; /* Field value (unescaped). */
|
|
||||||
int ignore; /* Ignore field in query_create. */
|
|
||||||
};
|
|
||||||
|
|
||||||
static int query_parse (const char *query,
|
|
||||||
const char *separator,
|
|
||||||
struct query_fields * *fields_out);
|
|
||||||
static int query_create (const struct query_fields *fields,
|
|
||||||
const char *separator,
|
|
||||||
char **query_out);
|
|
||||||
static void query_free (struct query_fields *fields);
|
|
||||||
|
|
||||||
/* GnuTLS functions used by remoteOpen. */
|
/* GnuTLS functions used by remoteOpen. */
|
||||||
static int initialise_gnutls (virConnectPtr conn);
|
static int initialise_gnutls (virConnectPtr conn);
|
||||||
static gnutls_session_t negotiate_gnutls_on_connection (virConnectPtr conn, struct private_data *priv, int no_verify);
|
static gnutls_session_t negotiate_gnutls_on_connection (virConnectPtr conn, struct private_data *priv, int no_verify);
|
||||||
@ -403,55 +387,59 @@ doRemoteOpen (virConnectPtr conn,
|
|||||||
* feasibly it might contain variables needed by the real driver,
|
* feasibly it might contain variables needed by the real driver,
|
||||||
* although that won't be the case for now).
|
* although that won't be the case for now).
|
||||||
*/
|
*/
|
||||||
struct query_fields *vars, *var;
|
struct qparam_set *vars;
|
||||||
|
struct qparam *var;
|
||||||
|
int i;
|
||||||
char *query;
|
char *query;
|
||||||
#ifdef HAVE_XMLURI_QUERY_RAW
|
#ifdef HAVE_XMLURI_QUERY_RAW
|
||||||
query = uri->query_raw;
|
query = uri->query_raw;
|
||||||
#else
|
#else
|
||||||
query = uri->query;
|
query = uri->query;
|
||||||
#endif
|
#endif
|
||||||
if (query_parse (query, NULL, &vars) != 0) goto failed;
|
vars = qparam_query_parse (query);
|
||||||
|
if (vars == NULL) goto failed;
|
||||||
|
|
||||||
for (var = vars; var; var = var->next) {
|
for (i = 0; i < vars->n; i++) {
|
||||||
if (strcasecmp (var->name, "name") == 0) {
|
var = &vars->p[i];
|
||||||
|
if (STRCASEEQ (var->name, "name")) {
|
||||||
name = strdup (var->value);
|
name = strdup (var->value);
|
||||||
if (!name) goto out_of_memory;
|
if (!name) goto out_of_memory;
|
||||||
var->ignore = 1;
|
var->ignore = 1;
|
||||||
} else if (strcasecmp (var->name, "command") == 0) {
|
} else if (STRCASEEQ (var->name, "command")) {
|
||||||
command = strdup (var->value);
|
command = strdup (var->value);
|
||||||
if (!command) goto out_of_memory;
|
if (!command) goto out_of_memory;
|
||||||
var->ignore = 1;
|
var->ignore = 1;
|
||||||
} else if (strcasecmp (var->name, "socket") == 0) {
|
} else if (STRCASEEQ (var->name, "socket")) {
|
||||||
sockname = strdup (var->value);
|
sockname = strdup (var->value);
|
||||||
if (!sockname) goto out_of_memory;
|
if (!sockname) goto out_of_memory;
|
||||||
var->ignore = 1;
|
var->ignore = 1;
|
||||||
} else if (strcasecmp (var->name, "auth") == 0) {
|
} else if (STRCASEEQ (var->name, "auth")) {
|
||||||
authtype = strdup (var->value);
|
authtype = strdup (var->value);
|
||||||
if (!authtype) goto out_of_memory;
|
if (!authtype) goto out_of_memory;
|
||||||
var->ignore = 1;
|
var->ignore = 1;
|
||||||
} else if (strcasecmp (var->name, "netcat") == 0) {
|
} else if (STRCASEEQ (var->name, "netcat")) {
|
||||||
netcat = strdup (var->value);
|
netcat = strdup (var->value);
|
||||||
if (!netcat) goto out_of_memory;
|
if (!netcat) goto out_of_memory;
|
||||||
var->ignore = 1;
|
var->ignore = 1;
|
||||||
} else if (strcasecmp (var->name, "no_verify") == 0) {
|
} else if (STRCASEEQ (var->name, "no_verify")) {
|
||||||
no_verify = atoi (var->value);
|
no_verify = atoi (var->value);
|
||||||
var->ignore = 1;
|
var->ignore = 1;
|
||||||
} else if (strcasecmp (var->name, "no_tty") == 0) {
|
} else if (STRCASEEQ (var->name, "no_tty")) {
|
||||||
no_tty = atoi (var->value);
|
no_tty = atoi (var->value);
|
||||||
var->ignore = 1;
|
var->ignore = 1;
|
||||||
} else if (strcasecmp (var->name, "debug") == 0) {
|
} else if (STRCASEEQ (var->name, "debug")) {
|
||||||
if (var->value &&
|
if (var->value &&
|
||||||
strcasecmp(var->value, "stdout") == 0)
|
STRCASEEQ (var->value, "stdout"))
|
||||||
priv->debugLog = stdout;
|
priv->debugLog = stdout;
|
||||||
else
|
else
|
||||||
priv->debugLog = stderr;
|
priv->debugLog = stderr;
|
||||||
}
|
}
|
||||||
#if DEBUG
|
#ifdef ENABLE_DEBUG
|
||||||
else
|
else
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"remoteOpen: "
|
"remoteOpen: "
|
||||||
"passing through variable '%s' to remote end\n",
|
"passing through variable '%s' ('%s') to remote end\n",
|
||||||
var->name);
|
var->name, var->value);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,14 +449,15 @@ doRemoteOpen (virConnectPtr conn,
|
|||||||
if (uri->query) xmlFree (uri->query);
|
if (uri->query) xmlFree (uri->query);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (query_create (vars, NULL,
|
if ((
|
||||||
#ifdef HAVE_XMLURI_QUERY_RAW
|
#ifdef HAVE_XMLURI_QUERY_RAW
|
||||||
&uri->query_raw
|
uri->query_raw =
|
||||||
#else
|
#else
|
||||||
&uri->query
|
uri->query =
|
||||||
#endif
|
#endif
|
||||||
) != 0) goto failed;
|
qparam_get_query (vars)) != 0) goto failed;
|
||||||
query_free (vars);
|
|
||||||
|
free_qparam_set (vars);
|
||||||
|
|
||||||
/* For ext transport, command is required. */
|
/* For ext transport, command is required. */
|
||||||
if (transport == trans_ext && !command) {
|
if (transport == trans_ext && !command) {
|
||||||
@ -496,7 +485,7 @@ doRemoteOpen (virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert (name);
|
assert (name);
|
||||||
#if DEBUG
|
#ifdef ENABLE_DEBUG
|
||||||
fprintf (stderr, "remoteOpen: proceeding with name = %s\n", name);
|
fprintf (stderr, "remoteOpen: proceeding with name = %s\n", name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -882,179 +871,6 @@ get_transport_from_scheme (char *scheme)
|
|||||||
return p ? p+1 : 0;
|
return p ? p+1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
query_create (const struct query_fields *fields,
|
|
||||||
const char *separator,
|
|
||||||
char **query_out)
|
|
||||||
{
|
|
||||||
/* List of characters which are safe inside names or values,
|
|
||||||
* apart from '@', IS_MARK and IS_ALPHANUM. Best to escape
|
|
||||||
* as much as possible. Certainly '=', '&' and '#' must NEVER
|
|
||||||
* be added to this list.
|
|
||||||
*/
|
|
||||||
static const xmlChar *special_chars = BAD_CAST "";
|
|
||||||
|
|
||||||
int append_sep = 0, sep_len;
|
|
||||||
xmlBufferPtr buf;
|
|
||||||
xmlChar *str;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
if (query_out) *query_out = NULL;
|
|
||||||
if (!fields) return 0;
|
|
||||||
|
|
||||||
if (separator == NULL) {
|
|
||||||
separator = "&";
|
|
||||||
sep_len = 1;
|
|
||||||
} else
|
|
||||||
sep_len = xmlStrlen (BAD_CAST separator);
|
|
||||||
|
|
||||||
buf = xmlBufferCreate ();
|
|
||||||
if (!buf) return -1;
|
|
||||||
|
|
||||||
rv = 0;
|
|
||||||
while (fields) {
|
|
||||||
if (!fields->ignore) {
|
|
||||||
if (append_sep) {
|
|
||||||
rv = xmlBufferAdd (buf, BAD_CAST separator, sep_len);
|
|
||||||
if (rv != 0) goto error;
|
|
||||||
}
|
|
||||||
append_sep = 1;
|
|
||||||
|
|
||||||
str = xmlURIEscapeStr (BAD_CAST fields->name, special_chars);
|
|
||||||
if (!str) { rv = XML_ERR_NO_MEMORY; goto error; }
|
|
||||||
rv = xmlBufferAdd (buf, str, xmlStrlen (str));
|
|
||||||
xmlFree (str);
|
|
||||||
if (rv != 0) goto error;
|
|
||||||
|
|
||||||
rv = xmlBufferAdd (buf, BAD_CAST "=", 1);
|
|
||||||
if (rv != 0) goto error;
|
|
||||||
str = xmlURIEscapeStr (BAD_CAST fields->value, special_chars);
|
|
||||||
if (!str) { rv = XML_ERR_NO_MEMORY; goto error; }
|
|
||||||
rv = xmlBufferAdd (buf, str, xmlStrlen (str));
|
|
||||||
xmlFree (str);
|
|
||||||
if (rv != 0) goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
fields = fields->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query_out && buf->content) {
|
|
||||||
*query_out = (char *) xmlStrdup (buf->content);
|
|
||||||
if (!*query_out) {
|
|
||||||
rv = XML_ERR_NO_MEMORY;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
error:
|
|
||||||
if (buf)
|
|
||||||
xmlBufferFree (buf);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
query_parse (const char *query_,
|
|
||||||
const char *separator,
|
|
||||||
struct query_fields * *fields_out)
|
|
||||||
{
|
|
||||||
struct query_fields *fields, *field, **prev;
|
|
||||||
int sep_len;
|
|
||||||
const xmlChar *query = BAD_CAST query_, *end, *eq;
|
|
||||||
char *name, *value;
|
|
||||||
|
|
||||||
if (fields_out) *fields_out = NULL;
|
|
||||||
if (!query || query[0] == '\0') return 0;
|
|
||||||
|
|
||||||
if (separator == NULL) {
|
|
||||||
separator = "&";
|
|
||||||
sep_len = 1;
|
|
||||||
} else
|
|
||||||
sep_len = xmlStrlen (BAD_CAST separator);
|
|
||||||
|
|
||||||
fields = NULL;
|
|
||||||
prev = &fields;
|
|
||||||
|
|
||||||
while (*query) {
|
|
||||||
/* Find the next separator, or end of the string. */
|
|
||||||
end = xmlStrstr (query, BAD_CAST separator);
|
|
||||||
if (!end) end = query + xmlStrlen (query);
|
|
||||||
|
|
||||||
/* Find the first '=' character between here and end. */
|
|
||||||
eq = xmlStrchr (query, '=');
|
|
||||||
if (eq && eq >= end) eq = NULL;
|
|
||||||
|
|
||||||
/* Empty section (eg. "?&"). */
|
|
||||||
if (end == query)
|
|
||||||
goto next;
|
|
||||||
/* If there is no '=' character, then we have just "name"
|
|
||||||
* and consistent with CGI.pm we assume value is "".
|
|
||||||
*/
|
|
||||||
else if (!eq) {
|
|
||||||
name = xmlURIUnescapeString ((const char *) query,
|
|
||||||
end - query, NULL);
|
|
||||||
value = (char *) xmlStrdup (BAD_CAST "");
|
|
||||||
if (!name || !value) goto out_of_memory;
|
|
||||||
}
|
|
||||||
/* Or if we have "name=" here (works around annoying
|
|
||||||
* problem when calling xmlURIUnescapeString with len = 0).
|
|
||||||
*/
|
|
||||||
else if (eq+1 == end) {
|
|
||||||
name = xmlURIUnescapeString ((const char *) query,
|
|
||||||
eq - query, NULL);
|
|
||||||
value = (char *) xmlStrdup (BAD_CAST "");
|
|
||||||
if (!name || !value) goto out_of_memory;
|
|
||||||
}
|
|
||||||
/* If the '=' character is at the beginning then we have
|
|
||||||
* "=value" and consistent with CGI.pm we _ignore_ this.
|
|
||||||
*/
|
|
||||||
else if (query == eq)
|
|
||||||
goto next;
|
|
||||||
/* Otherwise it's "name=value". */
|
|
||||||
else {
|
|
||||||
name = xmlURIUnescapeString ((const char *) query,
|
|
||||||
eq - query, NULL);
|
|
||||||
value = xmlURIUnescapeString ((const char *) eq+1,
|
|
||||||
end - (eq+1), NULL);
|
|
||||||
if (!name || !value) goto out_of_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate this field and append to the list. */
|
|
||||||
field = xmlMalloc (sizeof *field);
|
|
||||||
if (!field) goto out_of_memory;
|
|
||||||
field->next = NULL;
|
|
||||||
field->name = name;
|
|
||||||
field->value = value;
|
|
||||||
field->ignore = 0;
|
|
||||||
*prev = field;
|
|
||||||
prev = &field->next;
|
|
||||||
|
|
||||||
next:
|
|
||||||
query = end;
|
|
||||||
if (*query) query += sep_len; /* skip separator */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fields_out) *fields_out = fields;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
out_of_memory:
|
|
||||||
query_free (fields);
|
|
||||||
return XML_ERR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
query_free (struct query_fields *fields)
|
|
||||||
{
|
|
||||||
struct query_fields *t;
|
|
||||||
|
|
||||||
while (fields) {
|
|
||||||
if (fields->name) xmlFree (fields->name);
|
|
||||||
if (fields->value) xmlFree (fields->value);
|
|
||||||
t = fields;
|
|
||||||
fields = fields->next;
|
|
||||||
xmlFree (t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* GnuTLS functions used by remoteOpen. */
|
/* GnuTLS functions used by remoteOpen. */
|
||||||
static gnutls_certificate_credentials_t x509_cred;
|
static gnutls_certificate_credentials_t x509_cred;
|
||||||
|
|
||||||
@ -1100,7 +916,7 @@ initialise_gnutls (virConnectPtr conn)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Set the trusted CA cert. */
|
/* Set the trusted CA cert. */
|
||||||
#if DEBUG
|
#ifdef ENABLE_DEBUG
|
||||||
fprintf (stderr, "loading CA file %s\n", LIBVIRT_CACERT);
|
fprintf (stderr, "loading CA file %s\n", LIBVIRT_CACERT);
|
||||||
#endif
|
#endif
|
||||||
err =
|
err =
|
||||||
@ -1112,7 +928,7 @@ initialise_gnutls (virConnectPtr conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set the client certificate and private key. */
|
/* Set the client certificate and private key. */
|
||||||
#if DEBUG
|
#ifdef ENABLE_DEBUG
|
||||||
fprintf (stderr, "loading client cert and key from files %s and %s\n",
|
fprintf (stderr, "loading client cert and key from files %s and %s\n",
|
||||||
LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY);
|
LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user