cfg_get_group_*() is introduced:
authorMiklos Tirpak <miklos@iptel.org>
Wed, 12 Dec 2007 16:41:51 +0000 (16:41 +0000)
committerMiklos Tirpak <miklos@iptel.org>
Wed, 12 Dec 2007 16:41:51 +0000 (16:41 +0000)
  returns the list of declared groups

cfg_diff_*() is introduced:
  returns the pending configuration changes

cfg/cfg_ctx.c
cfg/cfg_ctx.h
doc/cfg.txt

index 1e146a9..aa1c864 100644 (file)
@@ -783,3 +783,113 @@ int cfg_help(cfg_ctx_t *ctx, str *group_name, str *var_name,
        *ch = var->def->descr;
        return 0;
 }
+
+/* return the group name and the cfg structure definition,
+ * and moves the handle to the next group
+ * Return value:
+ *     0: no more group
+ *     1: group exists
+ */
+int cfg_get_group_next(void **h,
+                       str *gname, cfg_def_t **def)
+{
+       cfg_group_t     *group;
+
+       group = (cfg_group_t *)(*h);
+       if (group == NULL) return 0;
+
+       gname->s = group->name;
+       gname->len = group->name_len;
+       (*def) = group->mapping->def;
+
+       (*h) = (void *)group->next;
+       return 1;
+}
+
+/* Initialize the handle for cfg_diff_next() */
+int cfg_diff_init(cfg_ctx_t *ctx,
+               void **h)
+{
+       if (!ctx) {
+               LOG(L_ERR, "ERROR: cfg_diff_init(): context is undefined\n");
+               return -1;
+       }
+
+       CFG_CTX_LOCK(ctx);
+       (*h) = (void *)ctx->changed_first;
+
+       return 0;
+}
+
+/* return the pending changes that have not been
+ * committed yet
+ */
+int cfg_diff_next(void **h,
+                       str *gname, str *vname,
+                       void **old_val, void **new_val,
+                       unsigned int *val_type)
+{
+       cfg_changed_var_t       *changed;
+       void    *p;
+       static str      old_s, new_s;   /* we need the value even
+                                       after the function returns */
+       int             i;
+       char            *ch;
+
+       changed = (cfg_changed_var_t *)(*h);
+       if (changed == NULL) return 0;
+
+       gname->s = changed->group->name;
+       gname->len = changed->group->name_len;
+       vname->s = changed->var->def->name;
+       vname->len = changed->var->name_len;
+
+       /* use the module's handle to access the variable
+       It means that the variable is read from the local config
+       after forking */
+       p = *(changed->group->handle) + changed->var->offset;
+
+       switch (CFG_VAR_TYPE(changed->var)) {
+       case CFG_VAR_INT:
+               memcpy(&i, p, sizeof(int));
+               *old_val = (void *)(long)i;
+               memcpy(&i, changed->new_val, sizeof(int));
+               *new_val = (void *)(long)i;
+               break;
+
+       case CFG_VAR_STRING:
+               memcpy(&ch, p, sizeof(char *));
+               *old_val = (void *)ch;
+               memcpy(&ch, changed->new_val, sizeof(char *));
+               *new_val = (void *)ch;
+               break;
+
+       case CFG_VAR_STR:
+               memcpy(&old_s, p, sizeof(str));
+               *old_val = (void *)&old_s;
+               memcpy(&new_s, changed->new_val, sizeof(str));
+               *new_val = (void *)&new_s;
+               break;
+
+       case CFG_VAR_POINTER:
+               memcpy(old_val, &p, sizeof(void *));
+               memcpy(new_val, &changed->new_val, sizeof(void *));
+               break;
+
+       }
+       *val_type = CFG_VAR_TYPE(changed->var);
+
+       (*h) = (void *)changed->next;
+       return 1;
+}
+
+/* release the handle of cfg_diff_next() */
+void cfg_diff_release(cfg_ctx_t *ctx)
+{
+       if (!ctx) {
+               LOG(L_ERR, "ERROR: cfg_diff_release(): context is undefined\n");
+               return;
+       }
+
+       CFG_CTX_UNLOCK(ctx);
+}
index 9a5e566..40ded4e 100644 (file)
@@ -106,5 +106,55 @@ int cfg_help(cfg_ctx_t *ctx, str *group_name, str *var_name,
 /* notify the drivers about the new config definition */
 void cfg_notify_drivers(char *group_name, cfg_def_t *def);
 
+/* initialize the handle for cfg_get_group_next() */
+#define cfg_get_group_init(handle) \
+       (*(handle)) = (void *)cfg_group
+
+/* returns the group name and the cfg structure definition,
+ * and moves the handle to the next group
+ * Return value:
+ *     0: no more group
+ *     1: group exists
+ *
+ * can be used as follows:
+ *
+ * void        *handle;
+ * cfg_get_group_init(&handle)
+ * while (cfg_get_group_next(&handle, &name, &def)) {
+ *     ...
+ * }
+ */
+int cfg_get_group_next(void **h,
+                       str *gname, cfg_def_t **def);
+
+/* Initialize the handle for cfg_diff_next()
+ * WARNING: keeps the context lock held, do not forget
+ * to release it with cfg_diff_release()
+ */
+int cfg_diff_init(cfg_ctx_t *ctx,
+               void **h);
+
+/* return the pending changes that have not been
+ * committed yet
+ * can be used as follows:
+ *
+ * void *handle;
+ * if (cfg_diff_init(ctx, &handle)) return -1
+ * while (cfg_diff_next(&handle
+ *                     &group_name, &var_name,
+ *                     &old_val, &new_val
+ *                     &val_type)
+ * ) {
+ *             ...
+ * }
+ * cfg_diff_release(ctx);
+ */
+int cfg_diff_next(void **h,
+                       str *gname, str *vname,
+                       void **old_val, void **new_val,
+                       unsigned int *val_type);
+
+/* destroy the handle of cfg_diff_next() */
+void cfg_diff_release(cfg_ctx_t *ctx);
 
 #endif /* _CFG_CTX_H */
index a13e500..4a2140d 100644 (file)
@@ -239,6 +239,38 @@ cfg_rollback()
 
 cfg_help()
 
+-------------------------------------------------------------------------------
+
+7. Get the list of group definitions:
+
+void   *h;
+str    gname;
+cfg_def_t      *def;
+
+cfg_get_group_init(&h);
+while(cfg_get_group_next(&h, &gname, &def)) {
+       ...
+}
+
+-------------------------------------------------------------------------------
+
+8. Get the list of pending changes that have not been committed yet:
+
+void           *h;
+str            gname, vname;
+void           *old_val, *new_val;
+unsigned int   val_type;
+
+if (cfg_diff_init(ctx, &h)) return -1;
+while(cfg_diff_next(&h,
+               &gname, &vname,
+               &old_val, &new_val,
+               &val_type)
+) {
+       ...
+}
+cfg_diff_release(ctx);
+
 
 5. Refreshing the configuration
 ===============================================================================