summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2013-12-16 12:44:19 +0100
committerPavel Březina <pbrezina@redhat.com>2013-12-18 14:14:45 +0100
commit500de1409a40df2cd3307d269d53dee9c601d2f5 (patch)
treedb31627afa80bff39851e2f64b634a3d6bfaf302
parent5e3a57098c4163e814ebbecf2cbb545872efeff3 (diff)
downloadopenlmi_test-wip.tar.gz
openlmi_test-wip.tar.xz
openlmi_test-wip.zip
test provider: id:value databasewip
This provider will read /tmp/lmitest as id:value type of database.
-rw-r--r--mof/LMI_Test.mof2
-rw-r--r--src/LMI_TestProvider.c409
2 files changed, 392 insertions, 19 deletions
diff --git a/mof/LMI_Test.mof b/mof/LMI_Test.mof
index b58de9f..a0ea538 100644
--- a/mof/LMI_Test.mof
+++ b/mof/LMI_Test.mof
@@ -5,6 +5,6 @@ class LMI_Test
uint32 Id;
string Value;
- uint32 SetValue([In] string value);
+ boolean SetValue([In] string value);
string GetValue();
};
diff --git a/src/LMI_TestProvider.c b/src/LMI_TestProvider.c
index b208716..95420d3 100644
--- a/src/LMI_TestProvider.c
+++ b/src/LMI_TestProvider.c
@@ -1,8 +1,135 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
#include <konkret/konkret.h>
#include "LMI_Test.h"
+#define false 0
+#define true 1
+
+#define DB_PATH "/tmp/lmitest"
+#define DB_TMP_PATH DB_PATH"-XXXXXX"
+
+#define CHECK_PARAM(object, param) do { \
+ if (!(object).param.exists || (object).param.null) { \
+ CMReturn(CMPI_RC_ERR_INVALID_PARAMETER); \
+ } \
+} while (0)
+
+#define OPEN_FILE(file, path, mode) do { \
+ errno = 0; \
+ file = fopen(path, mode); \
+ if (db == NULL) { \
+ if (errno == ENOENT) { \
+ CMReturn(CMPI_RC_ERR_NOT_FOUND); \
+ } \
+ CMReturn(CMPI_RC_ERR_FAILED); \
+ } \
+} while (0)
+
+#define OPEN_DATABASE(db, mode) OPEN_FILE(db, DB_PATH, mode)
+
static const CMPIBroker* _cb = NULL;
+static int parse_line(const char *record, unsigned int *_id, char **_value)
+{
+ char *delim = NULL;
+ char *value = NULL;
+ char *line = NULL;
+ unsigned int id;
+ int ret;
+
+ line = strdup(record);
+ if (line == NULL) {
+ return ENOMEM;
+ }
+
+ delim = strchr(line, ':');
+ if (delim == NULL) {
+ ret = EINVAL;
+ goto done;
+ }
+
+ *delim = '\0';
+
+ errno = 0;
+ id = strtoul(line, NULL, 10);
+ if (errno != 0) {
+ ret = errno;
+ goto done;
+ }
+
+ if (_value != NULL) {
+ value = strndup(delim + 1, strlen(delim + 1) - 1); /* without \n */
+ if (value == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ *_value = value;
+ }
+
+ *_id = id;
+ ret = 0;
+
+done:
+ if (line != NULL) {
+ free(line);
+ }
+
+ return ret;
+}
+
+static int create_tmp_db(char *mode, char **_path, FILE **_stream)
+{
+ char template[100] = DB_PATH"-XXXXXX";
+ FILE *stream = NULL;
+ char *path = NULL;
+ int fd;
+ int ret;
+
+ fd = mkstemp(template);
+ if (fd == -1) {
+ return EIO;
+ }
+
+ stream = fdopen(fd, mode);
+ if (stream == NULL) {
+ ret = errno;
+ close(fd);
+ return ret;
+ }
+
+ path = strdup(template);
+ if (path == NULL) {
+ return ENOMEM;
+ }
+
+ *_path = path;
+ *_stream = stream;
+
+ return 0;
+}
+
+static int replace_db(const char *new_db)
+{
+ int ret;
+
+ ret = remove(DB_PATH);
+ if (ret == -1) {
+ return errno;
+ }
+
+ ret = rename(new_db, DB_PATH);
+ if (ret == -1) {
+ return errno;
+ }
+
+ return 0;
+}
+
static void LMI_TestInitialize()
{
}
@@ -32,12 +159,36 @@ static CMPIStatus LMI_TestEnumInstances(
const CMPIObjectPath* cop,
const char** properties)
{
+ FILE *db = NULL;
LMI_Test lmi_test;
+ size_t num_chars;
+ char *line = NULL;
+ char *value = NULL;
+ unsigned int id;
+ int ret;
+
+ OPEN_DATABASE(db, "r");
- LMI_Test_Init(&lmi_test, _cb, KNameSpace(cop));
- LMI_Test_Set_Id(&lmi_test, 1);
- KReturnInstance(cr, lmi_test);
+ while (getline(&line, &num_chars, db) != -1) {
+ if (line[0] == '\0' || line[0] == '\n') {
+ continue;
+ }
+ ret = parse_line(line, &id, &value);
+ if (ret != 0) {
+ free(line);
+ fclose(db);
+ CMReturn(CMPI_RC_ERR_FAILED);
+ }
+
+ LMI_Test_Init(&lmi_test, _cb, KNameSpace(cop));
+ LMI_Test_Set_Id(&lmi_test, id);
+ LMI_Test_Set_Value(&lmi_test, value);
+ KReturnInstance(cr, lmi_test);
+ }
+
+ free(line);
+ fclose(db);
CMReturn(CMPI_RC_OK);
}
@@ -48,8 +199,49 @@ static CMPIStatus LMI_TestGetInstance(
const CMPIObjectPath* cop,
const char** properties)
{
- return KDefaultGetInstance(
- _cb, mi, cc, cr, cop, properties);
+ LMI_TestRef ref;
+ FILE *db = NULL;
+ LMI_Test lmi_test;
+ size_t num_chars;
+ char *line = NULL;
+ char *value = NULL;
+ unsigned int id;
+ int ret;
+
+ LMI_TestRef_InitFromObjectPath(&ref, _cb, cop);
+
+ CHECK_PARAM(ref, Id);
+
+ OPEN_DATABASE(db, "r");
+
+ while (getline(&line, &num_chars, db) != -1) {
+ if (line[0] == '\0' || line[0] == '\n') {
+ continue;
+ }
+
+ ret = parse_line(line, &id, &value);
+ if (ret != 0) {
+ free(line);
+ fclose(db);
+ CMReturn(CMPI_RC_ERR_FAILED);
+ }
+
+ if (id != ref.Id.value) {
+ continue;
+ }
+
+ LMI_Test_Init(&lmi_test, _cb, KNameSpace(cop));
+ LMI_Test_Set_Id(&lmi_test, id);
+ LMI_Test_Set_Value(&lmi_test, value);
+ KReturnInstance(cr, lmi_test);
+
+ free(line);
+ fclose(db);
+ CMReturn(CMPI_RC_OK);
+ }
+
+ fclose(db);
+ CMReturn(CMPI_RC_ERR_NOT_FOUND);
}
static CMPIStatus LMI_TestCreateInstance(
@@ -59,7 +251,30 @@ static CMPIStatus LMI_TestCreateInstance(
const CMPIObjectPath* cop,
const CMPIInstance* ci)
{
- CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+ FILE *db = NULL;
+ LMI_Test lmi_test;
+ int ret;
+
+ LMI_Test_InitFromInstance(&lmi_test, _cb, ci);
+
+ CHECK_PARAM(lmi_test, Id);
+ CHECK_PARAM(lmi_test, Value);
+
+ OPEN_DATABASE(db, "a");
+
+ ret = fprintf(db, "%u:%s\n", lmi_test.Id.value, lmi_test.Value.chars);
+ if (ret <= 0) {
+ fclose(db);
+ CMReturn(CMPI_RC_ERR_FAILED);
+ }
+
+ fflush(db);
+
+ CMReturnObjectPath(cr, LMI_Test_ToObjectPath(&lmi_test, NULL));
+ CMReturnDone(cr);
+
+ fclose(db);
+ CMReturn(CMPI_RC_OK);
}
static CMPIStatus LMI_TestModifyInstance(
@@ -70,7 +285,73 @@ static CMPIStatus LMI_TestModifyInstance(
const CMPIInstance* ci,
const char** properties)
{
- CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+ FILE *db = NULL;
+ FILE *newdb = NULL;
+ char *newdb_path = NULL;
+ LMI_Test lmi_test;
+ char *line = NULL;
+ size_t num_chars;
+ char *value = NULL;
+ unsigned int id;
+ int ret;
+
+ LMI_Test_InitFromInstance(&lmi_test, _cb, ci);
+ CHECK_PARAM(lmi_test, Id);
+ CHECK_PARAM(lmi_test, Value);
+
+ OPEN_DATABASE(db, "r");
+ ret = create_tmp_db("w", &newdb_path, &newdb);
+ if (ret != 0) {
+ goto done;
+ }
+
+ while (getline(&line, &num_chars, db) != -1) {
+ if (line[0] == '\0' || line[0] == '\n') {
+ continue;
+ }
+
+ ret = parse_line(line, &id, &value);
+ if (ret != 0) {
+ goto done;
+ }
+
+ if (id == lmi_test.Id.value) {
+ ret = fprintf(newdb, "%u:%s\n", id, lmi_test.Value.chars);
+ } else {
+ ret = fprintf(newdb, "%u:%s\n", id, value);
+ }
+ free(value);
+ if (ret <= 0) {
+ goto done;
+ }
+ }
+
+ fflush(newdb);
+
+ ret = replace_db(newdb_path);
+
+done:
+ if (line != NULL) {
+ free(line);
+ }
+
+ if (newdb_path != NULL) {
+ free(newdb_path);
+ }
+
+ if (db != NULL) {
+ fclose(db);
+ }
+
+ if (newdb != NULL) {
+ fclose(newdb);
+ }
+
+ if (ret != 0) {
+ CMReturn(CMPI_RC_ERR_FAILED);
+ }
+
+ CMReturn(CMPI_RC_OK);
}
static CMPIStatus LMI_TestDeleteInstance(
@@ -79,7 +360,70 @@ static CMPIStatus LMI_TestDeleteInstance(
const CMPIResult* cr,
const CMPIObjectPath* cop)
{
- CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+ FILE *db = NULL;
+ FILE *newdb = NULL;
+ char *newdb_path = NULL;
+ LMI_TestRef ref;
+ char *line = NULL;
+ size_t num_chars;
+ unsigned int id;
+ int ret;
+
+ LMI_TestRef_InitFromObjectPath(&ref, _cb, cop);
+ CHECK_PARAM(ref, Id);
+
+ OPEN_DATABASE(db, "r");
+ ret = create_tmp_db("w", &newdb_path, &newdb);
+ if (ret != 0) {
+ goto done;
+ }
+
+ while (getline(&line, &num_chars, db) != -1) {
+ if (line[0] == '\0' || line[0] == '\n') {
+ continue;
+ }
+
+ ret = parse_line(line, &id, NULL);
+ if (ret != 0) {
+ goto done;
+ }
+
+ if (id == ref.Id.value) {
+ continue;
+ }
+
+ ret = fprintf(newdb, "%s", line);
+ if (ret <= 0) {
+ goto done;
+ }
+ }
+
+ fflush(newdb);
+
+ ret = replace_db(newdb_path);
+
+done:
+ if (line != NULL) {
+ free(line);
+ }
+
+ if (newdb_path != NULL) {
+ free(newdb_path);
+ }
+
+ if (db != NULL) {
+ fclose(db);
+ }
+
+ if (newdb != NULL) {
+ fclose(newdb);
+ }
+
+ if (ret != 0) {
+ CMReturn(CMPI_RC_ERR_FAILED);
+ }
+
+ CMReturn(CMPI_RC_OK);
}
static CMPIStatus LMI_TestExecQuery(
@@ -126,7 +470,7 @@ CMMethodMIStub(
_cb,
LMI_TestInitialize())
-KUint32 LMI_Test_SetValue(
+KBoolean LMI_Test_SetValue(
const CMPIBroker* cb,
CMPIMethodMI* mi,
const CMPIContext* context,
@@ -134,18 +478,38 @@ KUint32 LMI_Test_SetValue(
const KString* value,
CMPIStatus* status)
{
- CMPIInstance *instance;
+ CMPIObjectPath *cop = NULL;
+ CMPIInstance *ci = NULL;
+ CMPIResult cr;
LMI_Test lmi_test;
- KUint32 result = KUINT32_INIT;
+ KBoolean ret = KBOOLEAN_INIT;
- instance = LMI_TestRef_ToInstance(self, status);
- LMI_Test_InitFromInstance(&lmi_test, cb, instance);
+ cop = LMI_TestRef_ToObjectPath(self, status);
+ if (!KOkay(*status)) {
+ KBoolean_Set(&ret, false);
+ return ret;
+ }
+ LMI_Test_Init(&lmi_test, cb, KNameSpace(cop));
+ LMI_Test_Set_Id(&lmi_test, self->Id.value);
LMI_Test_Set_Value(&lmi_test, value->chars);
- KUint32_Set(&result, 0);
+ ci = LMI_Test_ToInstance(&lmi_test, status);
+ if (!KOkay(*status)) {
+ KBoolean_Set(&ret, false);
+ return ret;
+ }
+
+ *status = LMI_TestModifyInstance(NULL, context, &cr, cop, ci, NULL);
+ if (!KOkay(*status)) {
+ KBoolean_Set(&ret, false);
+ return ret;
+ }
+
+ KBoolean_Set(&ret, true);
KSetStatus(status, OK);
- return result;
+
+ return ret;
}
KString LMI_Test_GetValue(
@@ -155,13 +519,22 @@ KString LMI_Test_GetValue(
const LMI_TestRef* self,
CMPIStatus* status)
{
- CMPIInstance *instance;
+ CMPIInstance *ci = NULL;
+ CMPIObjectPath *cop = NULL;
LMI_Test lmi_test;
KString result = KSTRING_INIT;
- instance = LMI_TestRef_ToInstance(self, status);
- LMI_Test_InitFromInstance(&lmi_test, cb, instance);
+ cop = LMI_TestRef_ToObjectPath(self, status);
+ if (!KOkay(*status)) {
+ return (KString)KSTRING_INIT;
+ }
+
+ ci = CBGetInstance(cb, context, cop, NULL, status);
+ if (!KOkay(*status)) {
+ return (KString)KSTRING_INIT;
+ }
+ LMI_Test_InitFromInstance(&lmi_test, cb, ci);
result = lmi_test.Value;
KSetStatus(status, OK);