2006-08-29 22:27:07 +00:00
|
|
|
/**
|
|
|
|
* conf.c: parser for a subset of the Python encoded Xen configuration files
|
|
|
|
*
|
2011-03-04 16:52:12 +00:00
|
|
|
* Copyright (C) 2006-2011 Red Hat, Inc.
|
2006-08-29 22:27:07 +00:00
|
|
|
*
|
|
|
|
* See COPYING.LIB for the License of this software
|
|
|
|
*
|
|
|
|
* Daniel Veillard <veillard@redhat.com>
|
|
|
|
*/
|
|
|
|
|
2008-01-29 18:15:54 +00:00
|
|
|
#include <config.h>
|
Use gnulib, starting with its physmem and getaddrinfo modules.
New files go into these directories:
gnulib/lib
gnulib/m4
gnulib/tests
* bootstrap: A wrapper around gnulib-tool.
* configure.in: Invoke gl_EARLY and gl_INIT, being careful to put gl_EARLY
before any macro that uses AC_COMPILE_IFELSE.
(AC_OUTPUT): Add lib/Makefile and gl-tests/Makefile. Remove m4/Makefile.
* Makefile.am (SUBDIRS): Add gnulib/lib and remove m4. Add gnulib/tests
early enough that those tests run before any libvirt unit tests.
* m4/Makefile.am: Remove file. Not needed.
* src/Makefile.am (INCLUDES): Add -I$(top_srcdir)/gnulib/lib -I../gnulib/lib.
(LDADDS, libvirt_la_LIBADD): Add ../gnulib/lib/libgnu.la.
* src/nodeinfo.c: Include "physmem.h".
* qemud/qemud.c, src/remote_internal.c: Include "getaddrinfo.h".
(MEMINFO_PATH, linuxNodeInfoMemPopulate): Remove definitions.
(virNodeInfoPopulate): Use physmem_total, not linuxNodeInfoMemPopulate.
* tests/Makefile.am (INCLUDES): Add -I$(top_srcdir)/gnulib/lib -I../gnulib/lib.
(LDADDS): Add ../gnulib/lib/libgnu.la.
* qemud/Makefile.am (libvirtd_LDADD): Add ../gnulib/lib/libgnu.la.
* tests/nodeinfotest.c (linuxTestCompareFiles): No longer read total
memory from a file.
Update expected output not to include "Memory: NNNN"
* tests/nodeinfodata/linux-nodeinfo-1.txt:
* tests/nodeinfodata/linux-nodeinfo-2.txt:
* tests/nodeinfodata/linux-nodeinfo-3.txt:
* tests/nodeinfodata/linux-nodeinfo-4.txt:
* tests/nodeinfodata/linux-nodeinfo-5.txt:
* tests/nodeinfodata/linux-nodeinfo-6.txt:
* src/test.c [WITH_TEST]: Remove definition of _GNU_SOURCE that
would conflict with the one now in "config.h".
* autogen.sh: Add -I gnulib/m4.
* src/conf.c, src/sexpr.c: Don't define _GNU_SOURCE.
Instead, include "config.h".
* qemud/qemud.c: Remove definition of _GNU_SOURCE.
* src/openvz_driver.c: Likewise.
* src/qemu_driver.c: Likewise.
* src/remote_internal.c: Likewise.
* configure.in: Use AC_CONFIG_AUX_DIR(build-aux), so that a bunch
of gettextize-generated files go into build-aux/, rather than in
the top-level directory.
* .cvsignore: Adjust.
* build-aux/.cvsignore: New file.
Author: Jim Meyering <meyering@redhat.com>
2007-12-05 21:31:07 +00:00
|
|
|
|
2006-08-29 22:27:07 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
2008-11-04 22:30:33 +00:00
|
|
|
#include "virterror_internal.h"
|
2007-06-26 22:33:22 +00:00
|
|
|
#include "buf.h"
|
2006-08-29 22:27:07 +00:00
|
|
|
#include "conf.h"
|
2008-01-07 15:21:33 +00:00
|
|
|
#include "util.h"
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
#include "c-ctype.h"
|
2008-06-06 11:09:57 +00:00
|
|
|
#include "memory.h"
|
2010-11-09 20:48:48 +00:00
|
|
|
#include "files.h"
|
2006-08-29 22:27:07 +00:00
|
|
|
|
2009-01-29 12:10:32 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_CONF
|
|
|
|
|
2006-08-29 22:27:07 +00:00
|
|
|
/************************************************************************
|
|
|
|
* *
|
|
|
|
* Structures and macros used by the mini parser *
|
|
|
|
* *
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
typedef struct _virConfParserCtxt virConfParserCtxt;
|
|
|
|
typedef virConfParserCtxt *virConfParserCtxtPtr;
|
|
|
|
|
|
|
|
struct _virConfParserCtxt {
|
|
|
|
const char* filename;
|
|
|
|
const char* base;
|
|
|
|
const char* cur;
|
|
|
|
const char *end;
|
|
|
|
int line;
|
|
|
|
|
|
|
|
virConfPtr conf;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define CUR (*ctxt->cur)
|
|
|
|
#define NEXT if (ctxt->cur < ctxt->end) ctxt->cur++;
|
|
|
|
#define IS_EOL(c) (((c) == '\n') || ((c) == '\r'))
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
|
|
|
|
#define SKIP_BLANKS_AND_EOL \
|
|
|
|
do { while ((ctxt->cur < ctxt->end) && (c_isblank(CUR) || IS_EOL(CUR))) { \
|
|
|
|
if (CUR == '\n') ctxt->line++; \
|
|
|
|
ctxt->cur++;}} while (0)
|
|
|
|
#define SKIP_BLANKS \
|
|
|
|
do { while ((ctxt->cur < ctxt->end) && (c_isblank(CUR))) \
|
|
|
|
ctxt->cur++; } while (0)
|
2006-08-29 22:27:07 +00:00
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* *
|
|
|
|
* Structures used by configuration data *
|
|
|
|
* *
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
typedef struct _virConfEntry virConfEntry;
|
|
|
|
typedef virConfEntry *virConfEntryPtr;
|
|
|
|
|
|
|
|
struct _virConfEntry {
|
|
|
|
virConfEntryPtr next;
|
|
|
|
char* name;
|
|
|
|
char* comment;
|
|
|
|
virConfValuePtr value;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _virConf {
|
|
|
|
const char* filename;
|
2009-06-19 12:34:30 +00:00
|
|
|
unsigned int flags;
|
2006-08-29 22:27:07 +00:00
|
|
|
virConfEntryPtr entries;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfError:
|
2008-09-17 14:11:21 +00:00
|
|
|
* @ctxt: the parser context if available or NULL
|
2006-08-29 22:27:07 +00:00
|
|
|
* @error: the error number
|
|
|
|
* @info: extra information string
|
|
|
|
*
|
|
|
|
* Handle an error at the xend daemon interface
|
|
|
|
*/
|
|
|
|
static void
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(virConfParserCtxtPtr ctxt,
|
|
|
|
virErrorNumber error, const char *info)
|
2006-08-29 22:27:07 +00:00
|
|
|
{
|
2008-09-17 14:11:21 +00:00
|
|
|
const char *format;
|
2006-08-29 22:27:07 +00:00
|
|
|
|
|
|
|
if (error == VIR_ERR_OK)
|
|
|
|
return;
|
|
|
|
|
2008-09-17 14:11:21 +00:00
|
|
|
/* Construct the string 'filename:line: info' if we have that. */
|
|
|
|
if (ctxt && ctxt->filename) {
|
2008-11-04 22:30:33 +00:00
|
|
|
virRaiseError(NULL, NULL, NULL, VIR_FROM_CONF, error, VIR_ERR_ERROR,
|
2008-09-17 14:11:21 +00:00
|
|
|
info, ctxt->filename, NULL,
|
|
|
|
ctxt->line, 0,
|
|
|
|
"%s:%d: %s", ctxt->filename, ctxt->line, info);
|
|
|
|
} else {
|
2008-11-04 22:30:33 +00:00
|
|
|
format = virErrorMsg(error, info);
|
|
|
|
virRaiseError(NULL, NULL, NULL, VIR_FROM_CONF, error, VIR_ERR_ERROR,
|
2008-09-17 14:11:21 +00:00
|
|
|
info, NULL, NULL,
|
|
|
|
ctxt ? ctxt->line : 0, 0,
|
|
|
|
format, info);
|
|
|
|
}
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* *
|
|
|
|
* Structures allocations and deallocations *
|
|
|
|
* *
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfFreeList:
|
|
|
|
* @list: the list to free
|
|
|
|
*
|
|
|
|
* Free a list
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
virConfFreeList(virConfValuePtr list)
|
|
|
|
{
|
|
|
|
virConfValuePtr next;
|
|
|
|
|
|
|
|
while (list != NULL) {
|
|
|
|
next = list->next;
|
2007-01-19 20:10:04 +00:00
|
|
|
list->next = NULL;
|
|
|
|
virConfFreeValue(list);
|
|
|
|
list = next;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfFreeValue:
|
|
|
|
* @val: the value to free
|
|
|
|
*
|
|
|
|
* Free a value
|
|
|
|
*/
|
2008-05-29 19:20:22 +00:00
|
|
|
void
|
2008-11-17 11:03:25 +00:00
|
|
|
virConfFreeValue(virConfValuePtr val)
|
2006-08-29 22:27:07 +00:00
|
|
|
{
|
|
|
|
if (val == NULL)
|
|
|
|
return;
|
2007-01-19 20:10:04 +00:00
|
|
|
if (val->type == VIR_CONF_STRING &&
|
|
|
|
val->str != NULL)
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(val->str);
|
2007-01-19 20:10:04 +00:00
|
|
|
if (val->type == VIR_CONF_LIST &&
|
|
|
|
val->list != NULL)
|
2006-08-29 22:27:07 +00:00
|
|
|
virConfFreeList(val->list);
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(val);
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
|
2007-03-09 20:47:12 +00:00
|
|
|
virConfPtr
|
2008-11-17 11:03:25 +00:00
|
|
|
virConfNew(void)
|
2006-08-29 22:27:07 +00:00
|
|
|
{
|
|
|
|
virConfPtr ret;
|
|
|
|
|
2008-06-06 11:09:57 +00:00
|
|
|
if (VIR_ALLOC(ret) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2006-08-29 22:27:07 +00:00
|
|
|
return(NULL);
|
|
|
|
}
|
2006-11-15 19:46:23 +00:00
|
|
|
ret->filename = NULL;
|
2009-06-19 12:34:30 +00:00
|
|
|
ret->flags = 0;
|
2006-11-15 19:46:23 +00:00
|
|
|
|
|
|
|
return(ret);
|
|
|
|
}
|
2006-08-29 22:27:07 +00:00
|
|
|
|
2006-11-15 19:46:23 +00:00
|
|
|
/**
|
|
|
|
* virConfCreate:
|
|
|
|
* @filename: the name to report errors
|
2009-06-19 12:34:30 +00:00
|
|
|
* @flags: combination of virConfFlag(s)
|
2006-11-15 19:46:23 +00:00
|
|
|
*
|
|
|
|
* Create a configuration internal structure
|
|
|
|
*
|
|
|
|
* Returns a pointer or NULL in case of error.
|
|
|
|
*/
|
|
|
|
static virConfPtr
|
2009-06-19 12:34:30 +00:00
|
|
|
virConfCreate(const char *filename, unsigned int flags)
|
2006-11-15 19:46:23 +00:00
|
|
|
{
|
|
|
|
virConfPtr ret = virConfNew();
|
2009-06-19 12:34:30 +00:00
|
|
|
if (ret) {
|
2006-11-15 19:46:23 +00:00
|
|
|
ret->filename = filename;
|
2009-06-19 12:34:30 +00:00
|
|
|
ret->flags = flags;
|
|
|
|
}
|
2006-08-29 22:27:07 +00:00
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfAddEntry:
|
|
|
|
* @conf: the conf structure
|
|
|
|
* @name: name of the entry or NULL for comment
|
|
|
|
* @value: the value if any
|
|
|
|
* @comm: extra comment for that entry if any
|
|
|
|
*
|
|
|
|
* add one entry to the conf, the parameters are included in the conf
|
|
|
|
* if successful and freed on virConfFree()
|
|
|
|
*
|
|
|
|
* Returns a pointer to the entry or NULL in case of failure
|
|
|
|
*/
|
|
|
|
static virConfEntryPtr
|
|
|
|
virConfAddEntry(virConfPtr conf, char *name, virConfValuePtr value, char *comm)
|
|
|
|
{
|
|
|
|
virConfEntryPtr ret, prev;
|
|
|
|
|
|
|
|
if (conf == NULL)
|
|
|
|
return(NULL);
|
|
|
|
if ((comm == NULL) && (name == NULL))
|
|
|
|
return(NULL);
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2008-06-06 11:09:57 +00:00
|
|
|
if (VIR_ALLOC(ret) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2006-08-29 22:27:07 +00:00
|
|
|
return(NULL);
|
|
|
|
}
|
2007-01-19 20:10:04 +00:00
|
|
|
|
2006-08-29 22:27:07 +00:00
|
|
|
ret->name = name;
|
|
|
|
ret->value = value;
|
|
|
|
ret->comment = comm;
|
|
|
|
|
|
|
|
if (conf->entries == NULL) {
|
|
|
|
conf->entries = ret;
|
|
|
|
} else {
|
|
|
|
prev = conf->entries;
|
2008-04-10 16:54:54 +00:00
|
|
|
while (prev->next != NULL)
|
|
|
|
prev = prev->next;
|
|
|
|
prev->next = ret;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* *
|
|
|
|
* Serialization *
|
|
|
|
* *
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfSaveValue:
|
|
|
|
* @buf: output buffer
|
|
|
|
* @val: a value
|
|
|
|
*
|
|
|
|
* Serialize the value to the buffer
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success, -1 in case of error.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
virConfSaveValue(virBufferPtr buf, virConfValuePtr val)
|
|
|
|
{
|
|
|
|
if (val == NULL)
|
|
|
|
return(-1);
|
|
|
|
switch (val->type) {
|
|
|
|
case VIR_CONF_NONE:
|
2008-04-10 16:54:54 +00:00
|
|
|
return(-1);
|
|
|
|
case VIR_CONF_LONG:
|
|
|
|
virBufferVSprintf(buf, "%ld", val->l);
|
|
|
|
break;
|
|
|
|
case VIR_CONF_STRING:
|
|
|
|
if (strchr(val->str, '\n') != NULL) {
|
|
|
|
virBufferVSprintf(buf, "\"\"\"%s\"\"\"", val->str);
|
|
|
|
} else if (strchr(val->str, '"') == NULL) {
|
|
|
|
virBufferVSprintf(buf, "\"%s\"", val->str);
|
|
|
|
} else if (strchr(val->str, '\'') == NULL) {
|
|
|
|
virBufferVSprintf(buf, "'%s'", val->str);
|
|
|
|
} else {
|
|
|
|
virBufferVSprintf(buf, "\"\"\"%s\"\"\"", val->str);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case VIR_CONF_LIST: {
|
|
|
|
virConfValuePtr cur;
|
|
|
|
|
|
|
|
cur = val->list;
|
|
|
|
virBufferAddLit(buf, "[ ");
|
|
|
|
if (cur != NULL) {
|
|
|
|
virConfSaveValue(buf, cur);
|
|
|
|
cur = cur->next;
|
|
|
|
while (cur != NULL) {
|
|
|
|
virBufferAddLit(buf, ", ");
|
|
|
|
virConfSaveValue(buf, cur);
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
virBufferAddLit(buf, " ]");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return(-1);
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfSaveEntry:
|
|
|
|
* @buf: output buffer
|
|
|
|
* @cur: a conf entry
|
|
|
|
*
|
|
|
|
* Serialize the entry to the buffer
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success, -1 in case of error.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
virConfSaveEntry(virBufferPtr buf, virConfEntryPtr cur)
|
|
|
|
{
|
|
|
|
if (cur->name != NULL) {
|
|
|
|
virBufferAdd(buf, cur->name, -1);
|
2008-04-10 16:54:54 +00:00
|
|
|
virBufferAddLit(buf, " = ");
|
|
|
|
virConfSaveValue(buf, cur->value);
|
|
|
|
if (cur->comment != NULL) {
|
|
|
|
virBufferAddLit(buf, " #");
|
|
|
|
virBufferAdd(buf, cur->comment, -1);
|
|
|
|
}
|
2006-08-29 22:27:07 +00:00
|
|
|
} else if (cur->comment != NULL) {
|
2008-04-10 16:54:54 +00:00
|
|
|
virBufferAddLit(buf, "#");
|
|
|
|
virBufferAdd(buf, cur->comment, -1);
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
Eliminate all uses of virBufferAdd with string literals.
* Makefile.maint (sc_prohibit_virBufferAdd_with_string_literal):
New rule.
* src/buf.h (virBufferAddLit): Define.
* src/conf.c (virConfSaveValue): Use virBufferAddLit, in place
of virBufferAdd everywhere possible.
(virConfSaveEntry): Likewise.
* src/qemu_conf.c (qemudGenerateXML, qemudGenerateNetworkXML): Likewise.
* src/qemu_driver.c (qemudGetFeatures, qemudGetCapabilities): Likewise.
* src/test.c (testDomainDumpXML, testNetworkDumpXML): Likewise.
* src/xen_internal.c (xenHypervisorMakeCapabilitiesXML): Likewise.
* src/xend_internal.c (xend_parse_sexp_desc_os): Likewise.
(xend_parse_sexp_desc, sexpr_to_xend_topology_xml): Likewise.
* src/xm_internal.c (xenXMDomainFormatXML, xenXMDomainPinVcpu): Likewise.
* src/xml.c (virSaveCpuSet, virParseXenCpuTopology): Likewise.
(virDomainParseXMLGraphicsDescImage): Likewise.
(virDomainParseXMLGraphicsDescVFB, virDomainParseXMLOSDescHVM): Likewise.
(virDomainParseXMLOSDescPV, virDomainParseXMLDiskDesc): Likewise.
(virDomainParseXMLIfDesc, virDomainParseXMLDesc): Likewise.
2008-02-05 14:22:28 +00:00
|
|
|
virBufferAddLit(buf, "\n");
|
2006-08-29 22:27:07 +00:00
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* *
|
|
|
|
* The parser core *
|
|
|
|
* *
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfParseLong:
|
|
|
|
* @ctxt: the parsing context
|
|
|
|
* @val: the result
|
|
|
|
*
|
|
|
|
* Parse one long int value
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success and -1 in case of error
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
virConfParseLong(virConfParserCtxtPtr ctxt, long *val)
|
|
|
|
{
|
|
|
|
long l = 0;
|
|
|
|
int neg = 0;
|
|
|
|
|
|
|
|
if (CUR == '-') {
|
|
|
|
neg = 1;
|
2008-04-10 16:54:54 +00:00
|
|
|
NEXT;
|
2006-08-29 22:27:07 +00:00
|
|
|
} else if (CUR == '+') {
|
|
|
|
NEXT;
|
|
|
|
}
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
if ((ctxt->cur >= ctxt->end) || (!c_isdigit(CUR))) {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated number"));
|
2008-04-10 16:54:54 +00:00
|
|
|
return(-1);
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
while ((ctxt->cur < ctxt->end) && (c_isdigit(CUR))) {
|
2006-08-29 22:27:07 +00:00
|
|
|
l = l * 10 + (CUR - '0');
|
2008-04-10 16:54:54 +00:00
|
|
|
NEXT;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
2007-10-19 10:01:01 +00:00
|
|
|
if (neg)
|
|
|
|
l = -l;
|
2006-08-29 22:27:07 +00:00
|
|
|
*val = l;
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfParseString:
|
|
|
|
* @ctxt: the parsing context
|
|
|
|
*
|
|
|
|
* Parse one string
|
|
|
|
*
|
|
|
|
* Returns a pointer to the string or NULL in case of error
|
|
|
|
*/
|
|
|
|
static char *
|
|
|
|
virConfParseString(virConfParserCtxtPtr ctxt)
|
|
|
|
{
|
|
|
|
const char *base;
|
|
|
|
char *ret = NULL;
|
|
|
|
|
|
|
|
if (CUR == '\'') {
|
|
|
|
NEXT;
|
2008-04-10 16:54:54 +00:00
|
|
|
base = ctxt->cur;
|
|
|
|
while ((ctxt->cur < ctxt->end) && (CUR != '\'') && (!IS_EOL(CUR)))
|
|
|
|
NEXT;
|
|
|
|
if (CUR != '\'') {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
|
2008-04-10 16:54:54 +00:00
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
ret = strndup(base, ctxt->cur - base);
|
2009-11-08 21:08:54 +00:00
|
|
|
if (ret == NULL) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2009-11-08 21:08:54 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-04-10 16:54:54 +00:00
|
|
|
NEXT;
|
2010-11-18 22:33:36 +00:00
|
|
|
} else if ((ctxt->cur + 6 < ctxt->end) &&
|
|
|
|
(STRPREFIX(ctxt->cur, "\"\"\""))) {
|
|
|
|
/* String starts with python-style triple quotes """ */
|
2008-04-10 16:54:54 +00:00
|
|
|
ctxt->cur += 3;
|
|
|
|
base = ctxt->cur;
|
2010-11-18 22:33:36 +00:00
|
|
|
|
2010-11-18 22:35:23 +00:00
|
|
|
/* Find the ending triple quotes */
|
2010-11-18 22:33:36 +00:00
|
|
|
while ((ctxt->cur + 2 < ctxt->end) &&
|
2010-11-18 22:35:23 +00:00
|
|
|
!(STRPREFIX(ctxt->cur, "\"\"\""))) {
|
2010-11-18 22:33:36 +00:00
|
|
|
if (CUR == '\n')
|
|
|
|
ctxt->line++;
|
|
|
|
NEXT;
|
2008-04-10 16:54:54 +00:00
|
|
|
}
|
2010-11-18 22:33:36 +00:00
|
|
|
|
|
|
|
if (!STRPREFIX(ctxt->cur, "\"\"\"")) {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
|
2008-04-10 16:54:54 +00:00
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
ret = strndup(base, ctxt->cur - base);
|
2009-11-08 21:08:54 +00:00
|
|
|
if (ret == NULL) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2009-11-08 21:08:54 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-04-10 16:54:54 +00:00
|
|
|
ctxt->cur += 3;
|
2006-08-29 22:27:07 +00:00
|
|
|
} else if (CUR == '"') {
|
|
|
|
NEXT;
|
2008-04-10 16:54:54 +00:00
|
|
|
base = ctxt->cur;
|
|
|
|
while ((ctxt->cur < ctxt->end) && (CUR != '"') && (!IS_EOL(CUR)))
|
|
|
|
NEXT;
|
|
|
|
if (CUR != '"') {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
|
2008-04-10 16:54:54 +00:00
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
ret = strndup(base, ctxt->cur - base);
|
2009-11-08 21:08:54 +00:00
|
|
|
if (ret == NULL) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2009-11-08 21:08:54 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-04-10 16:54:54 +00:00
|
|
|
NEXT;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfParseValue:
|
|
|
|
* @ctxt: the parsing context
|
|
|
|
*
|
|
|
|
* Parse one value
|
|
|
|
*
|
|
|
|
* Returns a pointer to the value or NULL in case of error
|
|
|
|
*/
|
|
|
|
static virConfValuePtr
|
|
|
|
virConfParseValue(virConfParserCtxtPtr ctxt)
|
|
|
|
{
|
|
|
|
virConfValuePtr ret, lst = NULL, tmp, prev;
|
|
|
|
virConfType type = VIR_CONF_NONE;
|
|
|
|
char *str = NULL;
|
|
|
|
long l = 0;
|
|
|
|
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
SKIP_BLANKS;
|
2006-08-29 22:27:07 +00:00
|
|
|
if (ctxt->cur >= ctxt->end) {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("expecting a value"));
|
2008-04-10 16:54:54 +00:00
|
|
|
return(NULL);
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
if ((CUR == '"') || (CUR == '\'')) {
|
|
|
|
type = VIR_CONF_STRING;
|
|
|
|
str = virConfParseString(ctxt);
|
2008-04-10 16:54:54 +00:00
|
|
|
if (str == NULL)
|
|
|
|
return(NULL);
|
2006-08-29 22:27:07 +00:00
|
|
|
} else if (CUR == '[') {
|
2009-06-22 11:54:49 +00:00
|
|
|
if (ctxt->conf->flags & VIR_CONF_FLAG_VMX_FORMAT) {
|
|
|
|
virConfError(ctxt, VIR_ERR_CONF_SYNTAX,
|
|
|
|
_("lists not allowed in VMX format"));
|
|
|
|
return(NULL);
|
|
|
|
}
|
2006-08-29 22:27:07 +00:00
|
|
|
type = VIR_CONF_LIST;
|
|
|
|
NEXT;
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
SKIP_BLANKS_AND_EOL;
|
2008-04-10 16:54:54 +00:00
|
|
|
if ((ctxt->cur < ctxt->end) && (CUR != ']')) {
|
2008-06-06 11:09:57 +00:00
|
|
|
if ((lst = virConfParseValue(ctxt)) == NULL)
|
|
|
|
return(NULL);
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
SKIP_BLANKS_AND_EOL;
|
2008-04-10 16:54:54 +00:00
|
|
|
}
|
|
|
|
while ((ctxt->cur < ctxt->end) && (CUR != ']')) {
|
2010-04-07 18:54:50 +00:00
|
|
|
|
|
|
|
/* Tell Clang that when execution reaches this point
|
|
|
|
"lst" is guaranteed to be non-NULL. This stops it
|
|
|
|
from issuing an invalid NULL-dereference warning about
|
|
|
|
"prev = lst; while (prev->next..." below. */
|
|
|
|
sa_assert (lst);
|
|
|
|
|
2008-04-10 16:54:54 +00:00
|
|
|
if (CUR != ',') {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(ctxt, VIR_ERR_CONF_SYNTAX,
|
|
|
|
_("expecting a separator in list"));
|
2008-04-10 16:54:54 +00:00
|
|
|
virConfFreeList(lst);
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
NEXT;
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
SKIP_BLANKS_AND_EOL;
|
2008-04-10 16:54:54 +00:00
|
|
|
if (CUR == ']') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
tmp = virConfParseValue(ctxt);
|
|
|
|
if (tmp == NULL) {
|
|
|
|
virConfFreeList(lst);
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
prev = lst;
|
|
|
|
while (prev->next != NULL) prev = prev->next;
|
|
|
|
prev->next = tmp;
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
SKIP_BLANKS_AND_EOL;
|
2008-04-10 16:54:54 +00:00
|
|
|
}
|
|
|
|
if (CUR == ']') {
|
|
|
|
NEXT;
|
|
|
|
} else {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(ctxt, VIR_ERR_CONF_SYNTAX,
|
|
|
|
_("list is not closed with ]"));
|
2008-04-10 16:54:54 +00:00
|
|
|
virConfFreeList(lst);
|
|
|
|
return(NULL);
|
|
|
|
}
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
} else if (c_isdigit(CUR) || (CUR == '-') || (CUR == '+')) {
|
2009-06-22 11:54:49 +00:00
|
|
|
if (ctxt->conf->flags & VIR_CONF_FLAG_VMX_FORMAT) {
|
|
|
|
virConfError(ctxt, VIR_ERR_CONF_SYNTAX,
|
|
|
|
_("numbers not allowed in VMX format"));
|
|
|
|
return(NULL);
|
|
|
|
}
|
2006-08-29 22:27:07 +00:00
|
|
|
if (virConfParseLong(ctxt, &l) < 0) {
|
2008-04-10 16:54:54 +00:00
|
|
|
return(NULL);
|
|
|
|
}
|
2006-08-29 22:27:07 +00:00
|
|
|
type = VIR_CONF_LONG;
|
|
|
|
} else {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("expecting a value"));
|
2008-04-10 16:54:54 +00:00
|
|
|
return(NULL);
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
2008-06-06 11:09:57 +00:00
|
|
|
if (VIR_ALLOC(ret) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-06-06 11:09:57 +00:00
|
|
|
virConfFreeList(lst);
|
|
|
|
VIR_FREE(str);
|
2006-08-29 22:27:07 +00:00
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
ret->type = type;
|
|
|
|
ret->l = l;
|
|
|
|
ret->str = str;
|
|
|
|
ret->list = lst;
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfParseName:
|
|
|
|
* @ctxt: the parsing context
|
|
|
|
*
|
|
|
|
* Parse one name
|
|
|
|
*
|
|
|
|
* Returns a copy of the new string, NULL in case of error
|
|
|
|
*/
|
|
|
|
static char *
|
|
|
|
virConfParseName(virConfParserCtxtPtr ctxt)
|
|
|
|
{
|
|
|
|
const char *base;
|
|
|
|
char *ret;
|
|
|
|
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
SKIP_BLANKS;
|
2006-08-29 22:27:07 +00:00
|
|
|
base = ctxt->cur;
|
|
|
|
/* TODO: probably need encoding support and UTF-8 parsing ! */
|
2009-07-27 12:21:17 +00:00
|
|
|
if (!c_isalpha(CUR) &&
|
|
|
|
!((ctxt->conf->flags & VIR_CONF_FLAG_VMX_FORMAT) && (CUR == '.'))) {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("expecting a name"));
|
2008-04-10 16:54:54 +00:00
|
|
|
return(NULL);
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
2009-06-19 12:34:30 +00:00
|
|
|
while ((ctxt->cur < ctxt->end) &&
|
|
|
|
(c_isalnum(CUR) || (CUR == '_') ||
|
2009-06-22 11:54:49 +00:00
|
|
|
((ctxt->conf->flags & VIR_CONF_FLAG_VMX_FORMAT) &&
|
2010-09-22 20:41:38 +00:00
|
|
|
((CUR == ':') || (CUR == '.') || (CUR == '-')))))
|
2006-08-29 22:27:07 +00:00
|
|
|
NEXT;
|
|
|
|
ret = strndup(base, ctxt->cur - base);
|
|
|
|
if (ret == NULL) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2006-08-29 22:27:07 +00:00
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfParseComment:
|
|
|
|
* @ctxt: the parsing context
|
|
|
|
*
|
|
|
|
* Parse one standalone comment in the configuration file
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success and -1 in case of error
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
virConfParseComment(virConfParserCtxtPtr ctxt)
|
|
|
|
{
|
|
|
|
const char *base;
|
|
|
|
char *comm;
|
|
|
|
|
|
|
|
if (CUR != '#')
|
|
|
|
return(-1);
|
|
|
|
NEXT;
|
|
|
|
base = ctxt->cur;
|
|
|
|
while ((ctxt->cur < ctxt->end) && (!IS_EOL(CUR))) NEXT;
|
|
|
|
comm = strndup(base, ctxt->cur - base);
|
|
|
|
if (comm == NULL) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2006-08-29 22:27:07 +00:00
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
virConfAddEntry(ctxt->conf, NULL, NULL, comm);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfParseSeparator:
|
|
|
|
* @ctxt: the parsing context
|
|
|
|
*
|
|
|
|
* Parse one separator between statement if not at the end.
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success and -1 in case of error
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
virConfParseSeparator(virConfParserCtxtPtr ctxt)
|
|
|
|
{
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
SKIP_BLANKS;
|
2006-08-29 22:27:07 +00:00
|
|
|
if (ctxt->cur >= ctxt->end)
|
2008-04-10 16:54:54 +00:00
|
|
|
return(0);
|
2006-08-29 22:27:07 +00:00
|
|
|
if (IS_EOL(CUR)) {
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
SKIP_BLANKS_AND_EOL;
|
2006-08-29 22:27:07 +00:00
|
|
|
} else if (CUR == ';') {
|
2008-04-10 16:54:54 +00:00
|
|
|
NEXT;
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
SKIP_BLANKS_AND_EOL;
|
2006-08-29 22:27:07 +00:00
|
|
|
} else {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("expecting a separator"));
|
2008-04-10 16:54:54 +00:00
|
|
|
return(-1);
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfParseStatement:
|
|
|
|
* @ctxt: the parsing context
|
|
|
|
*
|
|
|
|
* Parse one statement in the conf file
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success and -1 in case of error
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
virConfParseStatement(virConfParserCtxtPtr ctxt)
|
|
|
|
{
|
|
|
|
const char *base;
|
|
|
|
char *name;
|
|
|
|
virConfValuePtr value;
|
|
|
|
char *comm = NULL;
|
|
|
|
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
SKIP_BLANKS_AND_EOL;
|
2006-08-29 22:27:07 +00:00
|
|
|
if (CUR == '#') {
|
2011-03-04 16:52:12 +00:00
|
|
|
return virConfParseComment(ctxt);
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
name = virConfParseName(ctxt);
|
|
|
|
if (name == NULL)
|
2011-03-04 16:52:12 +00:00
|
|
|
return -1;
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
SKIP_BLANKS;
|
2006-08-29 22:27:07 +00:00
|
|
|
if (CUR != '=') {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("expecting an assignment"));
|
2011-03-04 16:52:12 +00:00
|
|
|
VIR_FREE(name);
|
|
|
|
return -1;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
NEXT;
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
SKIP_BLANKS;
|
2006-08-29 22:27:07 +00:00
|
|
|
value = virConfParseValue(ctxt);
|
|
|
|
if (value == NULL) {
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(name);
|
2011-03-04 16:52:12 +00:00
|
|
|
return -1;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
SKIP_BLANKS;
|
2006-08-29 22:27:07 +00:00
|
|
|
if (CUR == '#') {
|
2008-04-10 16:54:54 +00:00
|
|
|
NEXT;
|
|
|
|
base = ctxt->cur;
|
|
|
|
while ((ctxt->cur < ctxt->end) && (!IS_EOL(CUR))) NEXT;
|
|
|
|
comm = strndup(base, ctxt->cur - base);
|
|
|
|
if (comm == NULL) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(name);
|
2008-04-10 16:54:54 +00:00
|
|
|
virConfFreeValue(value);
|
2011-03-04 16:52:12 +00:00
|
|
|
return -1;
|
2008-04-10 16:54:54 +00:00
|
|
|
}
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
if (virConfAddEntry(ctxt->conf, name, value, comm) == NULL) {
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(name);
|
2008-04-10 16:54:54 +00:00
|
|
|
virConfFreeValue(value);
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(comm);
|
2011-03-04 16:52:12 +00:00
|
|
|
return -1;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
2011-03-04 16:52:12 +00:00
|
|
|
return 0;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virConfParse:
|
|
|
|
* @filename: the name to report errors
|
|
|
|
* @content: the configuration content in memory
|
|
|
|
* @len: the length in bytes
|
2009-06-19 12:34:30 +00:00
|
|
|
* @flags: combination of virConfFlag(s)
|
2006-08-29 22:27:07 +00:00
|
|
|
*
|
|
|
|
* Parse the subset of the Python language needed to handle simple
|
|
|
|
* Xen configuration files.
|
|
|
|
*
|
|
|
|
* Returns an handle to lookup settings or NULL if it failed to
|
|
|
|
* read or parse the file, use virConfFree() to free the data.
|
|
|
|
*/
|
|
|
|
static virConfPtr
|
2009-06-19 12:34:30 +00:00
|
|
|
virConfParse(const char *filename, const char *content, int len,
|
|
|
|
unsigned int flags) {
|
2006-08-29 22:27:07 +00:00
|
|
|
virConfParserCtxt ctxt;
|
|
|
|
|
|
|
|
ctxt.filename = filename;
|
|
|
|
ctxt.base = ctxt.cur = content;
|
|
|
|
ctxt.end = content + len - 1;
|
|
|
|
ctxt.line = 1;
|
|
|
|
|
2009-06-19 12:34:30 +00:00
|
|
|
ctxt.conf = virConfCreate(filename, flags);
|
2006-08-29 22:27:07 +00:00
|
|
|
if (ctxt.conf == NULL)
|
|
|
|
return(NULL);
|
|
|
|
|
|
|
|
while (ctxt.cur < ctxt.end) {
|
|
|
|
if (virConfParseStatement(&ctxt) < 0)
|
2008-04-10 16:54:54 +00:00
|
|
|
goto error;
|
|
|
|
if (virConfParseSeparator(&ctxt) < 0)
|
|
|
|
goto error;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return(ctxt.conf);
|
|
|
|
|
|
|
|
error:
|
|
|
|
virConfFree(ctxt.conf);
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* *
|
|
|
|
* The module entry points *
|
|
|
|
* *
|
|
|
|
************************************************************************/
|
|
|
|
|
2008-01-07 15:21:33 +00:00
|
|
|
/* 10 MB limit on config file size as a sanity check */
|
|
|
|
#define MAX_CONFIG_FILE_SIZE (1024*1024*10)
|
|
|
|
|
2006-08-29 22:27:07 +00:00
|
|
|
/**
|
2008-11-17 11:03:25 +00:00
|
|
|
* virConfReadFile:
|
2006-08-29 22:27:07 +00:00
|
|
|
* @filename: the path to the configuration file.
|
2009-06-19 12:34:30 +00:00
|
|
|
* @flags: combination of virConfFlag(s)
|
2006-08-29 22:27:07 +00:00
|
|
|
*
|
|
|
|
* Reads a configuration file.
|
|
|
|
*
|
|
|
|
* Returns an handle to lookup settings or NULL if it failed to
|
|
|
|
* read or parse the file, use virConfFree() to free the data.
|
|
|
|
*/
|
|
|
|
virConfPtr
|
2009-06-19 12:34:30 +00:00
|
|
|
virConfReadFile(const char *filename, unsigned int flags)
|
2006-08-29 22:27:07 +00:00
|
|
|
{
|
2008-01-07 15:21:33 +00:00
|
|
|
char *content;
|
2006-08-29 22:27:07 +00:00
|
|
|
int len;
|
2008-01-07 15:21:33 +00:00
|
|
|
virConfPtr conf;
|
2006-08-29 22:27:07 +00:00
|
|
|
|
|
|
|
if (filename == NULL) {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
2006-08-29 22:27:07 +00:00
|
|
|
return(NULL);
|
|
|
|
}
|
2008-01-07 15:21:33 +00:00
|
|
|
|
|
|
|
if ((len = virFileReadAll(filename, MAX_CONFIG_FILE_SIZE, &content)) < 0) {
|
|
|
|
return NULL;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
2008-01-07 15:21:33 +00:00
|
|
|
|
2009-06-19 12:34:30 +00:00
|
|
|
conf = virConfParse(filename, content, len, flags);
|
2008-01-07 15:21:33 +00:00
|
|
|
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(content);
|
2008-01-07 15:21:33 +00:00
|
|
|
|
|
|
|
return conf;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-11-17 11:03:25 +00:00
|
|
|
* virConfReadMem:
|
2006-08-29 22:27:07 +00:00
|
|
|
* @memory: pointer to the content of the configuration file
|
2008-04-04 07:58:29 +00:00
|
|
|
* @len: length in byte
|
2009-06-19 12:34:30 +00:00
|
|
|
* @flags: combination of virConfFlag(s)
|
2006-08-29 22:27:07 +00:00
|
|
|
*
|
|
|
|
* Reads a configuration file loaded in memory. The string can be
|
|
|
|
* zero terminated in which case @len can be 0
|
|
|
|
*
|
|
|
|
* Returns an handle to lookup settings or NULL if it failed to
|
|
|
|
* parse the content, use virConfFree() to free the data.
|
|
|
|
*/
|
|
|
|
virConfPtr
|
2009-06-19 12:34:30 +00:00
|
|
|
virConfReadMem(const char *memory, int len, unsigned int flags)
|
2006-08-29 22:27:07 +00:00
|
|
|
{
|
|
|
|
if ((memory == NULL) || (len < 0)) {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
2006-08-29 22:27:07 +00:00
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
if (len == 0)
|
|
|
|
len = strlen(memory);
|
|
|
|
|
2009-06-19 12:34:30 +00:00
|
|
|
return(virConfParse("memory conf", memory, len, flags));
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-11-17 11:03:25 +00:00
|
|
|
* virConfFree:
|
2006-08-29 22:27:07 +00:00
|
|
|
* @conf: a configuration file handle
|
|
|
|
*
|
|
|
|
* Frees all data associated to the handle
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success, -1 in case of error.
|
|
|
|
*/
|
|
|
|
int
|
2008-11-17 11:03:25 +00:00
|
|
|
virConfFree(virConfPtr conf)
|
2006-08-29 22:27:07 +00:00
|
|
|
{
|
2007-01-19 20:10:04 +00:00
|
|
|
virConfEntryPtr tmp;
|
2006-08-29 22:27:07 +00:00
|
|
|
if (conf == NULL) {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
2007-01-19 20:10:04 +00:00
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp = conf->entries;
|
|
|
|
while (tmp) {
|
|
|
|
virConfEntryPtr next;
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(tmp->name);
|
2007-01-19 20:10:04 +00:00
|
|
|
virConfFreeValue(tmp->value);
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(tmp->comment);
|
2007-01-19 20:10:04 +00:00
|
|
|
next = tmp->next;
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(tmp);
|
2007-01-19 20:10:04 +00:00
|
|
|
tmp = next;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(conf);
|
2006-08-29 22:27:07 +00:00
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-11-17 11:03:25 +00:00
|
|
|
* virConfGetValue:
|
2006-08-29 22:27:07 +00:00
|
|
|
* @conf: a configuration file handle
|
|
|
|
* @entry: the name of the entry
|
|
|
|
*
|
|
|
|
* Lookup the value associated to this entry in the configuration file
|
|
|
|
*
|
2008-02-05 19:27:37 +00:00
|
|
|
* Returns a pointer to the value or NULL if the lookup failed, the data
|
2006-08-29 22:27:07 +00:00
|
|
|
* associated will be freed when virConfFree() is called
|
|
|
|
*/
|
|
|
|
virConfValuePtr
|
2008-11-17 11:03:25 +00:00
|
|
|
virConfGetValue(virConfPtr conf, const char *setting)
|
2006-08-29 22:27:07 +00:00
|
|
|
{
|
2006-08-29 22:45:44 +00:00
|
|
|
virConfEntryPtr cur;
|
|
|
|
|
|
|
|
cur = conf->entries;
|
|
|
|
while (cur != NULL) {
|
2010-03-24 00:52:33 +00:00
|
|
|
if ((cur->name != NULL) &&
|
|
|
|
((conf->flags & VIR_CONF_FLAG_VMX_FORMAT &&
|
|
|
|
STRCASEEQ(cur->name, setting)) ||
|
|
|
|
STREQ(cur->name, setting)))
|
2008-04-10 16:54:54 +00:00
|
|
|
return(cur->value);
|
2006-08-29 22:45:44 +00:00
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
return(NULL);
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
|
2006-11-15 19:46:23 +00:00
|
|
|
/**
|
2008-11-17 11:03:25 +00:00
|
|
|
* virConfSetValue:
|
2006-11-15 19:46:23 +00:00
|
|
|
* @conf: a configuration file handle
|
|
|
|
* @entry: the name of the entry
|
|
|
|
* @value: the new configuration value
|
|
|
|
*
|
|
|
|
* Set (or replace) the value associated to this entry in the configuration
|
|
|
|
* file. The passed in 'value' will be owned by the conf object upon return
|
|
|
|
* of this method, even in case of error. It should not be referenced again
|
|
|
|
* by the caller.
|
|
|
|
*
|
|
|
|
* Returns 0 on success, or -1 on failure.
|
|
|
|
*/
|
2007-03-09 20:47:12 +00:00
|
|
|
int
|
2008-11-17 11:03:25 +00:00
|
|
|
virConfSetValue (virConfPtr conf,
|
|
|
|
const char *setting,
|
|
|
|
virConfValuePtr value)
|
2007-03-09 20:47:12 +00:00
|
|
|
{
|
2006-11-15 19:46:23 +00:00
|
|
|
virConfEntryPtr cur, prev = NULL;
|
|
|
|
|
2009-12-14 20:37:54 +00:00
|
|
|
if (value && value->type == VIR_CONF_STRING && value->str == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2006-11-15 19:46:23 +00:00
|
|
|
cur = conf->entries;
|
|
|
|
while (cur != NULL) {
|
2008-05-14 19:51:24 +00:00
|
|
|
if ((cur->name != NULL) && (STREQ(cur->name, setting))) {
|
2006-11-15 19:46:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
prev = cur;
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
2007-01-19 20:10:04 +00:00
|
|
|
|
2006-11-15 19:46:23 +00:00
|
|
|
if (!cur) {
|
2008-06-06 11:09:57 +00:00
|
|
|
if (VIR_ALLOC(cur) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2006-11-15 19:46:23 +00:00
|
|
|
virConfFreeValue(value);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
cur->comment = NULL;
|
|
|
|
if (!(cur->name = strdup(setting))) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2006-11-15 19:46:23 +00:00
|
|
|
virConfFreeValue(value);
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(cur);
|
2006-11-15 19:46:23 +00:00
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
cur->value = value;
|
|
|
|
if (prev) {
|
2007-01-19 20:10:04 +00:00
|
|
|
cur->next = prev->next;
|
2006-11-15 19:46:23 +00:00
|
|
|
prev->next = cur;
|
|
|
|
} else {
|
2007-01-19 20:10:04 +00:00
|
|
|
cur->next = conf->entries;
|
2006-11-15 19:46:23 +00:00
|
|
|
conf->entries = cur;
|
|
|
|
}
|
|
|
|
} else {
|
2010-05-17 20:38:59 +00:00
|
|
|
virConfFreeValue(cur->value);
|
2006-11-15 19:46:23 +00:00
|
|
|
cur->value = value;
|
|
|
|
}
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-29 22:27:07 +00:00
|
|
|
/**
|
2008-11-17 11:03:25 +00:00
|
|
|
* virConfWriteFile:
|
2006-08-29 22:27:07 +00:00
|
|
|
* @filename: the path to the configuration file.
|
|
|
|
* @conf: the conf
|
|
|
|
*
|
|
|
|
* Writes a configuration file back to a file.
|
|
|
|
*
|
|
|
|
* Returns the number of bytes written or -1 in case of error.
|
|
|
|
*/
|
|
|
|
int
|
2008-11-17 11:03:25 +00:00
|
|
|
virConfWriteFile(const char *filename, virConfPtr conf)
|
2006-08-29 22:27:07 +00:00
|
|
|
{
|
2008-04-28 15:14:59 +00:00
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
2006-08-29 22:27:07 +00:00
|
|
|
virConfEntryPtr cur;
|
|
|
|
int ret;
|
|
|
|
int fd;
|
2008-04-28 15:14:59 +00:00
|
|
|
char *content;
|
|
|
|
unsigned int use;
|
2006-08-29 22:27:07 +00:00
|
|
|
|
|
|
|
if (conf == NULL)
|
|
|
|
return(-1);
|
|
|
|
|
|
|
|
cur = conf->entries;
|
|
|
|
while (cur != NULL) {
|
2008-04-28 15:14:59 +00:00
|
|
|
virConfSaveEntry(&buf, cur);
|
2008-04-10 16:54:54 +00:00
|
|
|
cur = cur->next;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (virBufferError(&buf)) {
|
2009-12-09 23:00:50 +00:00
|
|
|
virBufferFreeAndReset(&buf);
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-04-28 15:14:59 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-08-29 22:27:07 +00:00
|
|
|
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR );
|
|
|
|
if (fd < 0) {
|
2009-12-09 23:00:50 +00:00
|
|
|
virBufferFreeAndReset(&buf);
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(NULL, VIR_ERR_WRITE_FAILED, _("failed to open file"));
|
2008-04-28 15:14:59 +00:00
|
|
|
return -1;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
use = virBufferUse(&buf);
|
|
|
|
content = virBufferContentAndReset(&buf);
|
|
|
|
ret = safewrite(fd, content, use);
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(content);
|
2010-11-09 20:48:48 +00:00
|
|
|
VIR_FORCE_CLOSE(fd);
|
2008-04-28 15:14:59 +00:00
|
|
|
if (ret != (int)use) {
|
2008-09-17 14:11:21 +00:00
|
|
|
virConfError(NULL, VIR_ERR_WRITE_FAILED, _("failed to save content"));
|
2008-04-28 15:14:59 +00:00
|
|
|
return -1;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
2008-04-28 15:14:59 +00:00
|
|
|
|
|
|
|
return ret;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-11-17 11:03:25 +00:00
|
|
|
* virConfWriteMem:
|
2006-08-29 22:27:07 +00:00
|
|
|
* @memory: pointer to the memory to store the config file
|
2007-10-19 08:29:13 +00:00
|
|
|
* @len: pointer to the length in bytes of the store, on output the size
|
2006-08-29 22:27:07 +00:00
|
|
|
* @conf: the conf
|
|
|
|
*
|
|
|
|
* Writes a configuration file back to a memory area. @len is an IN/OUT
|
|
|
|
* parameter, it indicates the size available in bytes, and on output the
|
|
|
|
* size required for the configuration file (even if the call fails due to
|
|
|
|
* insufficient space).
|
|
|
|
*
|
|
|
|
* Returns the number of bytes written or -1 in case of error.
|
|
|
|
*/
|
|
|
|
int
|
2008-11-17 11:03:25 +00:00
|
|
|
virConfWriteMem(char *memory, int *len, virConfPtr conf)
|
2006-08-29 22:27:07 +00:00
|
|
|
{
|
2008-04-28 15:14:59 +00:00
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
2006-08-29 22:27:07 +00:00
|
|
|
virConfEntryPtr cur;
|
2008-04-28 15:14:59 +00:00
|
|
|
char *content;
|
|
|
|
unsigned int use;
|
2006-08-29 22:27:07 +00:00
|
|
|
|
|
|
|
if ((memory == NULL) || (len == NULL) || (*len <= 0) || (conf == NULL))
|
|
|
|
return(-1);
|
|
|
|
|
|
|
|
cur = conf->entries;
|
|
|
|
while (cur != NULL) {
|
2008-04-28 15:14:59 +00:00
|
|
|
virConfSaveEntry(&buf, cur);
|
2007-01-19 20:10:04 +00:00
|
|
|
cur = cur->next;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
2008-02-05 19:27:37 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (virBufferError(&buf)) {
|
2009-12-09 23:00:50 +00:00
|
|
|
virBufferFreeAndReset(&buf);
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-04-28 15:14:59 +00:00
|
|
|
return -1;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|
2008-04-28 15:14:59 +00:00
|
|
|
|
|
|
|
use = virBufferUse(&buf);
|
|
|
|
content = virBufferContentAndReset(&buf);
|
|
|
|
|
|
|
|
if ((int)use >= *len) {
|
|
|
|
*len = (int)use;
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(content);
|
2008-04-28 15:14:59 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
memcpy(memory, content, use);
|
2008-06-06 11:09:57 +00:00
|
|
|
VIR_FREE(content);
|
2008-04-28 15:14:59 +00:00
|
|
|
*len = use;
|
|
|
|
return use;
|
2006-08-29 22:27:07 +00:00
|
|
|
}
|