⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xen_common.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  Copyright (c) 2006-2007 XenSource, 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 */#define _XOPEN_SOURCE#include <assert.h>#include <stdarg.h>#include <stddef.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <libxml/parser.h>#include <libxml/tree.h>#include <libxml/xmlsave.h>#include <libxml/xmlstring.h>#include <libxml/xpath.h>#include "xen/api/xen_common.h"#include "xen/api/xen_host.h"#include "xen_internal.h"#include "xen/api/xen_int_float_map.h"#include "xen/api/xen_int_int_map.h"#include "xen/api/xen_int_string_set_map.h"#include "xen/api/xen_string_string_map.h"/* * Whether to ignore missing structure entries.  This is not something we * want to do, once the API has stabilised, as it indicates that the server is * broken, but at the moment, complaining is just slowing development down. */#define PERMISSIVE 1static xmlXPathCompExprPtr responsePath = NULL;static xmlXPathCompExprPtr faultPath = NULL;typedef struct{    size_t size;    void *contents[];} arbitrary_map;typedef struct{    void *handle;} arbitrary_record;typedef struct{    bool is_record;    union    {        char *handle;        arbitrary_record *record;    } u;} arbitrary_record_opt;static char *make_body(const char *, abstract_value [], int);static voidparse_result(xen_session *, const char *, const abstract_type *, void *);static voidadd_value(xmlNode *, const char *, const char *);static voidadd_param(xmlNode *, const char *, const char *);static xmlNode *add_param_struct(xmlNode *);static xmlNode *add_struct_array(xmlNode *, const char *);static xmlNode *add_nested_struct(xmlNode *, const char *);static voidadd_struct_member(xmlNode *, const char *, const char *, const char *);static voidadd_unnamed_value(xmlNode *, const char *, const char *, const char *);static voidadd_struct_value(const struct abstract_type *, void *,                 void (*)(xmlNode *, const char *, const char *,                          const char *),                 const char *, xmlNode *);static xmlNode *add_container(xmlNode *parent, const char *name);static voidcall_raw(xen_session *, const char *, abstract_value [], int,         const abstract_type *, void *);static voidparse_structmap_value(xen_session *, xmlNode *, const abstract_type *,                      void *);static size_t size_of_member(const abstract_type *);static const char *get_val_as_string(const struct abstract_type *, void *, char *, size_t);voidxen_init(void){    responsePath =        xmlXPathCompile(            BAD_CAST(                "/methodResponse/params/param/value/struct/member/value"));    faultPath =        xmlXPathCompile(            BAD_CAST("/methodResponse/fault/value/struct/member/value"));}voidxen_fini(void){    xmlXPathFreeCompExpr(responsePath);    xmlXPathFreeCompExpr(faultPath);    responsePath = NULL;    faultPath = NULL;}voidxen_session_record_free(xen_session_record *record){    if (record == NULL)    {        return;    }    free(record->uuid);    xen_host_record_opt_free(record->this_host);    free(record->this_user);    free(record);}xen_session *xen_session_login_with_password(xen_call_func call_func, void *handle,                                const char *uname, const char *pwd){    abstract_value params[] =        {            { .type = &abstract_type_string,              .u.string_val = uname },            { .type = &abstract_type_string,              .u.string_val = pwd }        };    xen_session *session = malloc(sizeof(xen_session));    session->call_func = call_func;    session->handle = handle;    session->session_id = NULL;    session->ok = true;    session->error_description = NULL;    session->error_description_count = 0;    call_raw(session, "session.login_with_password", params, 2,             &abstract_type_string, &session->session_id);    return session;}voidxen_session_logout(xen_session *session){    abstract_value params[] =        {        };    xen_call_(session, "session.logout", params, 0, NULL, NULL);    if (session->error_description != NULL)    {        for (int i = 0; i < session->error_description_count; i++)        {            free(session->error_description[i]);        }        free(session->error_description);    }    free((char *)session->session_id);    free(session);}voidxen_session_clear_error(xen_session *session){    if (session->error_description != NULL)    {        for (int i = 0; i < session->error_description_count; i++)        {            free(session->error_description[i]);        }        free(session->error_description);    }    session->error_description = NULL;    session->error_description_count = 0;    session->ok = true;}boolxen_session_get_uuid(xen_session *session, char **result,                     xen_session *self_session){    abstract_value params[] =        {            { .type = &abstract_type_string,              .u.string_val = self_session->session_id }        };    xen_call_(session, "session.get_uuid", params, 1,              &abstract_type_string, result);    return session->ok;}boolxen_session_get_this_host(xen_session *session, xen_host *result,                          xen_session *self_session){    abstract_value params[] =        {            { .type = &abstract_type_string,              .u.string_val = self_session->session_id }        };    xen_call_(session, "session.get_this_host", params, 1,              &abstract_type_string, result);    return session->ok;}boolxen_session_get_this_user(xen_session *session, char **result,                          xen_session *self_session){    abstract_value params[] =        {            { .type = &abstract_type_string,              .u.string_val = self_session->session_id }        };    xen_call_(session, "session.get_this_user", params, 1,              &abstract_type_string, result);    return session->ok;}boolxen_session_get_last_active(xen_session *session, time_t *result,                            xen_session *self_session){    abstract_value params[] =        {            { .type = &abstract_type_string,              .u.string_val = self_session->session_id }        };    xen_call_(session, "session.get_last_active", params, 1,              &abstract_type_datetime, result);    return session->ok;}static const struct_member xen_session_record_struct_members[] =    {        { .key = "uuid",          .type = &abstract_type_string,          .offset = offsetof(xen_session_record, uuid) },        { .key = "this_host",          .type = &abstract_type_ref,          .offset = offsetof(xen_session_record, this_host) },        { .key = "this_user",          .type = &abstract_type_string,          .offset = offsetof(xen_session_record, this_user) },        { .key = "last_active",          .type = &abstract_type_datetime,          .offset = offsetof(xen_session_record, last_active) },    };const abstract_type xen_session_record_abstract_type_ =    {       .typename = STRUCT,       .struct_size = sizeof(xen_session_record),       .member_count =           sizeof(xen_session_record_struct_members) / sizeof(struct_member),       .members = xen_session_record_struct_members    };boolxen_session_get_record(xen_session *session, xen_session_record **result,                       xen_session *self_session){    abstract_value param_values[] =        {            { .type = &abstract_type_string,              .u.string_val = self_session->session_id }        };    abstract_type result_type = xen_session_record_abstract_type_;    *result = NULL;    XEN_CALL_("session.get_record");    return session->ok;}#define X "%02x"#define UUID_FORMAT X X X X "-" X X "-" X X "-" X X "-" X X X X X Xboolxen_uuid_string_to_bytes(char *uuid, char **bytes){    unsigned int buf[16];    *bytes = NULL;        if (strlen(uuid) != 36)        return false;    if (16 != sscanf(uuid, UUID_FORMAT,                     buf + 0, buf + 1, buf + 2, buf + 3,                     buf + 4, buf + 5,                     buf + 6, buf + 7,                     buf + 8, buf + 9,                     buf + 10, buf + 11, buf + 12, buf + 13, buf + 14,                       buf + 15))    {        return false;    }    *bytes = malloc(16);    if (*bytes == NULL)        return false;    for (int i = 0; i < 16; i++) {        (*bytes)[i] = (char)buf[i];    }    return true;}boolxen_uuid_bytes_to_string(char *bytes, char **uuid){    *uuid = malloc(37);    if (*uuid == NULL)        return false;    sprintf(*uuid, UUID_FORMAT,            bytes[0], bytes[1], bytes[2], bytes[3],            bytes[4], bytes[5],            bytes[6], bytes[7],            bytes[8], bytes[9],            bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]);    return true;}#undef UUID_FORMAT#undef Xvoidxen_uuid_free(char *uuid){    free(uuid);}voidxen_uuid_bytes_free(char *bytes){    free(bytes);}/** * @param value A pointer to the correct location as per the given * result_type.  Will be populated if the call succeeds.  In that case, and if * value is a char **, the char * itself must be freed by the caller. */voidxen_call_(xen_session *s, const char *method_name,          abstract_value params[], int param_count,          const abstract_type *result_type, void *value){    abstract_value *full_params;    if (!s->ok)    {        return;    }    full_params = malloc(sizeof(abstract_value) * (param_count + 1));    full_params[0].type = &abstract_type_string;    full_params[0].u.string_val = s->session_id;    memcpy(full_params + 1, params, param_count * sizeof(abstract_value));    call_raw(s, method_name, full_params, param_count + 1, result_type,             value);    free(full_params);}static boolbufferAdd(const void *data, size_t len, void *buffer){    return 0 == xmlBufferAdd((xmlBufferPtr)buffer, data, len);}static voidcall_raw(xen_session *s, const char *method_name,         abstract_value params[], int param_count,         const abstract_type *result_type, void *value){    xmlBufferPtr buffer = xmlBufferCreate();    char *body = make_body(method_name, params, param_count);    int error_code =        s->call_func(body, strlen(body), s->handle, buffer, &bufferAdd);    free(body);    if (error_code)    {        char **strings = malloc(2 * sizeof(char *));        strings[0] = xen_strdup_("TRANSPORT_FAULT");        strings[1] = malloc(20);        snprintf(strings[1], 20, "%d", error_code);        s->ok = false;        s->error_description = strings;        s->error_description_count = 2;    }    else    {        parse_result(s, (char *)xmlBufferContent(buffer), result_type, value);    }    xmlBufferFree(buffer);}static void server_error(xen_session *session, const char *error_string){    char **strings;    if (!session->ok)    {        /* Don't wipe out the earlier error message with this one. */        return;    }    strings = malloc(2 * sizeof(char *));    strings[0] = xen_strdup_("SERVER_FAULT");    strings[1] = xen_strdup_(error_string);    session->ok = false;    session->error_description = strings;    session->error_description_count = 2;}static void server_error_2(xen_session *session, const char *error_string,                           const char *param){    char **strings;    if (!session->ok)    {        /* Don't wipe out the earlier error message with this one. */        return;    }    strings = malloc(3 * sizeof(char *));    strings[0] = xen_strdup_("SERVER_FAULT_2");    strings[1] = xen_strdup_(error_string);    strings[2] = xen_strdup_(param);    session->ok = false;    session->error_description = strings;    session->error_description_count = 3;}static bool is_node(xmlNode *n, char *type){    return        n->type == XML_ELEMENT_NODE &&        0 == strcmp((char *)n->name, type);}static bool is_container_node(xmlNode *n, char *type){    return        is_node(n, type) &&        n->children != NULL &&        n->children == n->last &&        n->children->type == XML_ELEMENT_NODE;}/** * @return The contents of the given value, or NULL if this is not a node with * the given type.  If not NULL, the result must be freed with xmlFree(). */static xmlChar *string_from_value(xmlNode *n, char *type){    /*      <value><type>XYZ</type></value> is normal, but the XML-RPC spec also      allows <value>XYZ</value> where XYZ is to be interpreted as a string.    */    if (is_container_node(n, "value") &&        0 == strcmp((char *)n->children->name, type))    {        return            n->children->children == NULL ?                xmlStrdup(BAD_CAST("")) :                xmlNodeGetContent(n->children->children);    }    else if (0 == strcmp(type, "string") && is_node(n, "value"))    {        return            n->children == NULL ?                xmlStrdup(BAD_CAST("")) :                xmlNodeGetContent(n->children);    }    else    {        return NULL;    }}/** * Find the name node that is a child of the given one, and return its * contents, or NULL if this has no such node.  If not NULL, the result must * be freed with xmlFree(). */static xmlChar *string_from_name(xmlNode *n){    xmlNode *cur = n->children;    while (cur != NULL)    {        if (0 == strcmp((char *)cur->name, "name"))        {            return xmlNodeGetContent(cur);        }        cur = cur->next;    }    return NULL;}static int count_children(xmlNode *n, const char *name)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -