#include #include #include #include #include #include #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() { } static CMPIStatus LMI_TestCleanup( CMPIInstanceMI* mi, const CMPIContext* cc, CMPIBoolean term) { CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_TestEnumInstanceNames( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop) { return KDefaultEnumerateInstanceNames( _cb, mi, cc, cr, cop); } static CMPIStatus LMI_TestEnumInstances( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, 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"); 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); } static CMPIStatus LMI_TestGetInstance( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char** 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( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const CMPIInstance* ci) { 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( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const CMPIInstance* ci, const char** properties) { 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( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop) { 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( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char* lang, const char* query) { CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } CMInstanceMIStub( LMI_Test, LMI_Test, _cb, LMI_TestInitialize()) static CMPIStatus LMI_TestMethodCleanup( CMPIMethodMI* mi, const CMPIContext* cc, CMPIBoolean term) { CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_TestInvokeMethod( CMPIMethodMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char* meth, const CMPIArgs* in, CMPIArgs* out) { return LMI_Test_DispatchMethod( _cb, mi, cc, cr, cop, meth, in, out); } CMMethodMIStub( LMI_Test, LMI_Test, _cb, LMI_TestInitialize()) KBoolean LMI_Test_SetValue( const CMPIBroker* cb, CMPIMethodMI* mi, const CMPIContext* context, const LMI_TestRef* self, const KString* value, CMPIStatus* status) { CMPIObjectPath *cop = NULL; CMPIInstance *ci = NULL; CMPIResult cr; LMI_Test lmi_test; KBoolean ret = KBOOLEAN_INIT; 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); 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 ret; } KString LMI_Test_GetValue( const CMPIBroker* cb, CMPIMethodMI* mi, const CMPIContext* context, const LMI_TestRef* self, CMPIStatus* status) { CMPIInstance *ci = NULL; CMPIObjectPath *cop = NULL; LMI_Test lmi_test; KString result = KSTRING_INIT; 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); return result; } KONKRET_REGISTRATION( "root/cimv2", "LMI_Test", "LMI_Test", "instance method");