Browse code

cfg_get_group_*() is introduced: returns the list of declared groups

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

Miklos Tirpak authored on 12/12/2007 16:41:51
Showing 3 changed files
... ...
@@ -783,3 +783,113 @@ int cfg_help(cfg_ctx_t *ctx, str *group_name, str *var_name,
783 783
 	*ch = var->def->descr;
784 784
 	return 0;
785 785
 }
786
+
787
+/* return the group name and the cfg structure definition,
788
+ * and moves the handle to the next group
789
+ * Return value:
790
+ *	0: no more group
791
+ *	1: group exists
792
+ */
793
+int cfg_get_group_next(void **h,
794
+			str *gname, cfg_def_t **def)
795
+{
796
+	cfg_group_t	*group;
797
+
798
+	group = (cfg_group_t *)(*h);
799
+	if (group == NULL) return 0;
800
+
801
+	gname->s = group->name;
802
+	gname->len = group->name_len;
803
+	(*def) = group->mapping->def;
804
+
805
+	(*h) = (void *)group->next;
806
+	return 1;
807
+}
808
+
809
+/* Initialize the handle for cfg_diff_next() */
810
+int cfg_diff_init(cfg_ctx_t *ctx,
811
+		void **h)
812
+{
813
+	if (!ctx) {
814
+		LOG(L_ERR, "ERROR: cfg_diff_init(): context is undefined\n");
815
+		return -1;
816
+	}
817
+
818
+	CFG_CTX_LOCK(ctx);
819
+	(*h) = (void *)ctx->changed_first;
820
+
821
+	return 0;
822
+}
823
+
824
+/* return the pending changes that have not been
825
+ * committed yet
826
+ */
827
+int cfg_diff_next(void **h,
828
+			str *gname, str *vname,
829
+			void **old_val, void **new_val,
830
+			unsigned int *val_type)
831
+{
832
+	cfg_changed_var_t	*changed;
833
+	void	*p;
834
+	static str	old_s, new_s;	/* we need the value even
835
+					after the function returns */
836
+	int		i;
837
+	char		*ch;
838
+
839
+	changed = (cfg_changed_var_t *)(*h);
840
+	if (changed == NULL) return 0;
841
+
842
+	gname->s = changed->group->name;
843
+	gname->len = changed->group->name_len;
844
+	vname->s = changed->var->def->name;
845
+	vname->len = changed->var->name_len;
846
+
847
+	/* use the module's handle to access the variable
848
+	It means that the variable is read from the local config
849
+	after forking */
850
+	p = *(changed->group->handle) + changed->var->offset;
851
+
852
+	switch (CFG_VAR_TYPE(changed->var)) {
853
+	case CFG_VAR_INT:
854
+		memcpy(&i, p, sizeof(int));
855
+		*old_val = (void *)(long)i;
856
+		memcpy(&i, changed->new_val, sizeof(int));
857
+		*new_val = (void *)(long)i;
858
+		break;
859
+
860
+	case CFG_VAR_STRING:
861
+		memcpy(&ch, p, sizeof(char *));
862
+		*old_val = (void *)ch;
863
+		memcpy(&ch, changed->new_val, sizeof(char *));
864
+		*new_val = (void *)ch;
865
+		break;
866
+
867
+	case CFG_VAR_STR:
868
+		memcpy(&old_s, p, sizeof(str));
869
+		*old_val = (void *)&old_s;
870
+		memcpy(&new_s, changed->new_val, sizeof(str));
871
+		*new_val = (void *)&new_s;
872
+		break;
873
+
874
+	case CFG_VAR_POINTER:
875
+		memcpy(old_val, &p, sizeof(void *));
876
+		memcpy(new_val, &changed->new_val, sizeof(void *));
877
+		break;
878
+
879
+	}
880
+	*val_type = CFG_VAR_TYPE(changed->var);
881
+
882
+	(*h) = (void *)changed->next;
883
+	return 1;
884
+}
885
+
886
+/* release the handle of cfg_diff_next() */
887
+void cfg_diff_release(cfg_ctx_t *ctx)
888
+{
889
+	if (!ctx) {
890
+		LOG(L_ERR, "ERROR: cfg_diff_release(): context is undefined\n");
891
+		return;
892
+	}
893
+
894
+	CFG_CTX_UNLOCK(ctx);
895
+}
... ...
@@ -106,5 +106,55 @@ int cfg_help(cfg_ctx_t *ctx, str *group_name, str *var_name,
106 106
 /* notify the drivers about the new config definition */
107 107
 void cfg_notify_drivers(char *group_name, cfg_def_t *def);
108 108
 
109
+/* initialize the handle for cfg_get_group_next() */
110
+#define cfg_get_group_init(handle) \
111
+	(*(handle)) = (void *)cfg_group
112
+
113
+/* returns the group name and the cfg structure definition,
114
+ * and moves the handle to the next group
115
+ * Return value:
116
+ *	0: no more group
117
+ *	1: group exists
118
+ *
119
+ * can be used as follows:
120
+ *
121
+ * void	*handle;
122
+ * cfg_get_group_init(&handle)
123
+ * while (cfg_get_group_next(&handle, &name, &def)) {
124
+ * 	...
125
+ * }
126
+ */
127
+int cfg_get_group_next(void **h,
128
+			str *gname, cfg_def_t **def);
129
+
130
+/* Initialize the handle for cfg_diff_next()
131
+ * WARNING: keeps the context lock held, do not forget
132
+ * to release it with cfg_diff_release()
133
+ */
134
+int cfg_diff_init(cfg_ctx_t *ctx,
135
+		void **h);
136
+
137
+/* return the pending changes that have not been
138
+ * committed yet
139
+ * can be used as follows:
140
+ *
141
+ * void *handle;
142
+ * if (cfg_diff_init(ctx, &handle)) return -1
143
+ * while (cfg_diff_next(&handle
144
+ *			&group_name, &var_name,
145
+ *			&old_val, &new_val
146
+ *			&val_type)
147
+ * ) {
148
+ *		...
149
+ * }
150
+ * cfg_diff_release(ctx);
151
+ */
152
+int cfg_diff_next(void **h,
153
+			str *gname, str *vname,
154
+			void **old_val, void **new_val,
155
+			unsigned int *val_type);
156
+
157
+/* destroy the handle of cfg_diff_next() */
158
+void cfg_diff_release(cfg_ctx_t *ctx);
109 159
 
110 160
 #endif /* _CFG_CTX_H */
... ...
@@ -239,6 +239,38 @@ cfg_rollback()
239 239
 
240 240
 cfg_help()
241 241
 
242
+-------------------------------------------------------------------------------
243
+
244
+7. Get the list of group definitions:
245
+
246
+void	*h;
247
+str	gname;
248
+cfg_def_t	*def;
249
+
250
+cfg_get_group_init(&h);
251
+while(cfg_get_group_next(&h, &gname, &def)) {
252
+	...
253
+}
254
+
255
+-------------------------------------------------------------------------------
256
+
257
+8. Get the list of pending changes that have not been committed yet:
258
+
259
+void		*h;
260
+str		gname, vname;
261
+void		*old_val, *new_val;
262
+unsigned int	val_type;
263
+
264
+if (cfg_diff_init(ctx, &h)) return -1;
265
+while(cfg_diff_next(&h,
266
+		&gname, &vname,
267
+		&old_val, &new_val,
268
+		&val_type)
269
+) {
270
+	...
271
+}
272
+cfg_diff_release(ctx);
273
+
242 274
 
243 275
 5. Refreshing the configuration
244 276
 ===============================================================================