diff options
author | Pavel Březina <pbrezina@redhat.com> | 2013-12-16 12:44:19 +0100 |
---|---|---|
committer | Pavel Březina <pbrezina@redhat.com> | 2013-12-18 14:14:45 +0100 |
commit | 500de1409a40df2cd3307d269d53dee9c601d2f5 (patch) | |
tree | db31627afa80bff39851e2f64b634a3d6bfaf302 | |
parent | 5e3a57098c4163e814ebbecf2cbb545872efeff3 (diff) | |
download | openlmi_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.mof | 2 | ||||
-rw-r--r-- | src/LMI_TestProvider.c | 409 |
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); |