summaryrefslogtreecommitdiffstats
path: root/src/indmanager
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@redhat.com>2013-11-15 17:45:36 +0100
committerTomas Bzatek <tbzatek@redhat.com>2013-11-15 17:45:36 +0100
commitcb1ffc827aa461fcb31cc1de7305d7d611262c90 (patch)
tree02bf7d71eaa126c11a17047509a678acec530cb2 /src/indmanager
parentaa9cdfa38d112dbfd7805959d9892d1d572b2370 (diff)
downloadopenlmi-providers-cb1ffc827aa461fcb31cc1de7305d7d611262c90.tar.gz
openlmi-providers-cb1ffc827aa461fcb31cc1de7305d7d611262c90.tar.xz
openlmi-providers-cb1ffc827aa461fcb31cc1de7305d7d611262c90.zip
indmanager: Introduce common filter checker
The filter checker code was kinda duplicate across providers and no special plans have been made for it. This change makes passing a filter checker callback during indication manager creation no longer mandatory and default filter checker will be used when NULL. However, the list of acceptable classes need to be registered before first use. This change also brings greater flexibility of the filter query which may now consist of multiple limit conditions.
Diffstat (limited to 'src/indmanager')
-rw-r--r--src/indmanager/ind_manager.c72
-rw-r--r--src/indmanager/ind_manager.h7
2 files changed, 73 insertions, 6 deletions
diff --git a/src/indmanager/ind_manager.c b/src/indmanager/ind_manager.c
index 446137d..cae141b 100644
--- a/src/indmanager/ind_manager.c
+++ b/src/indmanager/ind_manager.c
@@ -795,10 +795,6 @@ IMManager* im_create_manager(IMInstGather gather, IMFilterChecker f_checker,
*err = IM_ERR_GATHER;
return NULL;
}
- if (!f_checker) {
- *err = IM_ERR_FILTER_CHECKER;
- return NULL;
- }
if (!watcher) {
*err = IM_ERR_WATCHER;
return NULL;
@@ -866,6 +862,50 @@ bool im_destroy_manager(IMManager *manager, const CMPIContext *ctx,
return true;
}
+static bool default_ind_filter_cb(IMManager *manager, const CMPISelectExp *filter)
+{
+ /* Looks for a class to be subscribed and matches it against a list of
+ * allowed classes. Filter query may contain more conditions, only those
+ * with a ISA operator are looked for.
+ */
+ CMPIStatus st;
+ unsigned int i;
+
+ CMPISelectCond *sec = CMGetDoc(filter, &st);
+ if (!sec)
+ return false;
+ CMPICount count = CMGetSubCondCountAndType(sec, NULL, &st);
+ if (count != 1)
+ return false;
+ CMPISubCond *sub = CMGetSubCondAt(sec, 0, &st);
+ if (!sub)
+ return false;
+ count = CMGetPredicateCount(sub, &st);
+ if (count == 0)
+ return false;
+
+ for (i = 0; i < count; i++) {
+ CMPIType type;
+ CMPIPredOp op;
+ CMPIString *lhs = NULL;
+ CMPIString *rhs = NULL;
+ CMPIPredicate *pred = CMGetPredicateAt(sub, i, &st);
+ if (!pred)
+ return false;
+ st = CMGetPredicateData(pred, &type, &op, &lhs, &rhs);
+ if (st.rc != CMPI_RC_OK || op != CMPI_PredOp_Isa)
+ continue;
+ const char *rhs_str = CMGetCharsPtr(rhs, &st);
+ if (!rhs_str)
+ continue;
+ while (manager->f_allowed_classes[i]) {
+ if (strcasecmp(rhs_str, manager->f_allowed_classes[i++]) == 0)
+ return true;
+ }
+ }
+ return false;
+}
+
bool im_verify_filter(IMManager *manager, const CMPISelectExp *filter,
const CMPIContext *ctx, IMError *err)
{
@@ -880,9 +920,18 @@ bool im_verify_filter(IMManager *manager, const CMPISelectExp *filter,
*err = IM_ERR_FILTER;
return NULL;
}
+ if (!filter && !manager->f_allowed_classes) {
+ *err = IM_ERR_FILTER_CHECKER;
+ return NULL;
+ }
manager->ctx_main = ctx;
- DEBUG("Verifying filter. Manager = %p, filter checker = %p", manager, manager->f_checker);
- return manager->f_checker(filter);
+ if (manager->f_checker) {
+ DEBUG("Verifying filter. Manager = %p, filter checker = %p", manager, manager->f_checker);
+ return manager->f_checker(filter);
+ } else {
+ DEBUG("Verifying filter. Manager = %p, using default filter checker", manager);
+ return default_ind_filter_cb(manager, filter);
+ }
}
/*
@@ -1009,6 +1058,17 @@ bool im_add_filter(IMManager *manager, CMPISelectExp *filter,
return true;
}
+bool im_register_filter_classes(IMManager *manager,
+ const char** allowed_classes, IMError *err)
+{
+ if (!manager) {
+ *err = IM_ERR_MANAGER;
+ return false;
+ }
+ manager->f_allowed_classes = allowed_classes;
+ return true;
+}
+
/*
* Decrease reference count for polled enumerations. If count is 0, remove
* the whole enumerations.
diff --git a/src/indmanager/ind_manager.h b/src/indmanager/ind_manager.h
index 01aa2e5..383f4b6 100644
--- a/src/indmanager/ind_manager.h
+++ b/src/indmanager/ind_manager.h
@@ -131,6 +131,7 @@ struct _IMManager {
IMFilterChecker f_checker;
// filters container
IMFilters *filters;
+ const char** f_allowed_classes;
// others
IMIndType type;
bool running;
@@ -196,6 +197,12 @@ bool im_add_filter(IMManager *manager, CMPISelectExp *filter,
bool im_remove_filter(IMManager *manager, const CMPISelectExp *filter,
const CMPIContext *ctx, IMError *err);
+// Register list of classes to be used with a default filter checker
+// when callback not given during im_create_manager()
+// The allowed_classes array should be kept accessible all the time
+bool im_register_filter_classes(IMManager *manager,
+ const char** allowed_classes, IMError *err);
+
// Start indications.
// Return true when correctly started, false if not and
// appropriate IMError is set,