gwenhywfar  4.8.0beta
db.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Tue Sep 09 2003
3  copyright : (C) 2003-2010 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #define DISABLE_DEBUGLOG
31 
32 #include "db_p.h"
33 #include <gwenhywfar/misc.h>
34 #include <gwenhywfar/debug.h>
35 #include <gwenhywfar/path.h>
36 #include <gwenhywfar/text.h>
37 #include <gwenhywfar/dbio.h>
38 #include <gwenhywfar/fslock.h>
39 #include <gwenhywfar/fastbuffer.h>
40 #include <gwenhywfar/syncio_file.h>
41 #include <gwenhywfar/syncio_memory.h>
42 
43 #include <stdlib.h>
44 #include <assert.h>
45 #include <string.h>
46 #include <errno.h>
47 #include <ctype.h>
48 
49 #include <sys/types.h>
50 #ifdef HAVE_SYS_STAT_H
51 # include <sys/stat.h>
52 #endif
53 #ifdef HAVE_FCNTL_H
54 # include <fcntl.h>
55 #endif
56 #ifdef HAVE_UNISTD_H
57 # include <unistd.h>
58 #endif
59 
60 
61 #define GWEN_DB_NODE_FLAGS_MASK_INTERNAL 0xf0000000
62 #define GWEN_DB_NODE_FLAGS_GROUP 0x80000000
63 
64 
65 GWEN_LIST_FUNCTIONS(GWEN_DB_NODE, GWEN_DB_Node)
66 
67 
68 
70  GWEN_DB_NODE *node;
71 
74  node->typ=t;
75  return (GWEN_DB_NODE*)node;
76 }
77 
78 
79 
80 
82  unsigned int datasize){
83  GWEN_DB_NODE *n;
84 
86  if (datasize) {
87  assert(data);
88  n->dataSize=datasize;
89  n->data.dataBin=(char*)GWEN_Memory_malloc(datasize);
90  assert(n->data.dataBin);
91  memmove(n->data.dataBin, data, datasize);
92  }
93  return n;
94 }
95 
96 
97 
99  GWEN_DB_NODE *n;
100 
102  n->data.dataInt=data;
103  return n;
104 }
105 
106 
107 
109  GWEN_DB_NODE *n;
110 
112  if (data)
113  n->data.dataChar=GWEN_Memory_strdup(data);
114  else
115  n->data.dataChar=GWEN_Memory_strdup("");
116  return n;
117 }
118 
119 
120 
122  GWEN_DB_NODE *n;
123 
125  n->data.dataPtr=data;
126  return n;
127 }
128 
129 
130 
131 GWEN_DB_NODE *GWEN_DB_Group_new(const char *name){
132  GWEN_DB_NODE *n;
133 
134  assert(name);
136  if (name)
137  n->data.dataName=GWEN_Memory_strdup(name);
138  else
139  n->data.dataName=GWEN_Memory_strdup("");
140  n->children=GWEN_DB_Node_List_new();
141  return n;
142 }
143 
144 
145 
146 GWEN_DB_NODE *GWEN_DB_Var_new(const char *name){
147  GWEN_DB_NODE *n;
148 
149  assert(name);
151  if (name)
152  n->data.dataName=GWEN_Memory_strdup(name);
153  else
154  n->data.dataName=GWEN_Memory_strdup("");
155  n->children=GWEN_DB_Node_List_new();
156  return n;
157 }
158 
159 
160 
162  GWEN_DB_NODE *n){
163  assert(parent);
164  assert(n);
165  assert(parent!=n);
166 
167  assert(parent->children!=NULL);
168  GWEN_DB_Node_List_Add(n, parent->children);
169 
170  n->parent=parent;
171 }
172 
173 
174 
176  GWEN_DB_NODE *n){
177  GWEN_DB_Node_Append_UnDirty(parent, n);
181 }
182 
183 
184 
186  GWEN_DB_NODE *n){
187  assert(parent);
188  assert(n);
189  assert(parent!=n);
190 
191  assert(parent->children!=NULL);
192  GWEN_DB_Node_List_Insert(n, parent->children);
193 
194  n->parent=parent;
195 }
196 
197 
198 
200  GWEN_DB_NODE *n){
201  GWEN_DB_Node_InsertUnDirty(parent, n);
205 }
206 
207 
208 
210  GWEN_DB_NODE *parent;
211 
212  assert(n);
213  parent=n->parent;
214  if (!parent) {
215  DBG_WARN(GWEN_LOGDOMAIN, "Node is not linked, nothing to do");
216  return;
217  }
218 
219  GWEN_DB_Node_List_Del(n);
220  n->parent=NULL;
221 }
222 
223 
224 
226  GWEN_DB_NODE *parent;
227 
228  assert(n);
229  parent=n->parent;
230  assert(parent);
231 
236 }
237 
238 
239 
241  if (n) {
243 
244  /* free children */
245  if (n->children)
246  GWEN_DB_Node_List_free(n->children);
247 
248  if (n->nodeFlags & GWEN_DB_NODE_FLAGS_SAFE) {
249  /* free dynamic (allocated) data safely */
250  switch(n->typ) {
253  if (n->data.dataName) {
254  int l=strlen(n->data.dataName);
255  if (l)
256  memset(n->data.dataName, 0, l);
257  GWEN_Memory_dealloc(n->data.dataName);
258  }
259  break;
260 
262  if (n->data.dataChar) {
263  int l=strlen(n->data.dataChar);
264  if (l)
265  memset(n->data.dataChar, 0, l);
266  GWEN_Memory_dealloc(n->data.dataChar);
267  }
268  break;
270  if (n->data.dataBin && n->dataSize) {
271  memset(n->data.dataBin, 0, n->dataSize);
272  GWEN_Memory_dealloc(n->data.dataBin);
273  }
274  break;
276  n->data.dataPtr=NULL;
277  break;
279  n->data.dataInt=0;
280  break;
281  default:
282  DBG_WARN(GWEN_LOGDOMAIN, "Unknown node type (%d)", n->typ);
283  }
284  }
285  else {
286  /* free dynamic (allocated) data */
287  switch(n->typ) {
290  GWEN_Memory_dealloc(n->data.dataName);
291  break;
292 
294  GWEN_Memory_dealloc(n->data.dataChar);
295  break;
297  GWEN_Memory_dealloc(n->data.dataBin);
298  break;
301  break;
302  default:
303  DBG_WARN(GWEN_LOGDOMAIN, "Unknown node type (%d)", n->typ);
304  }
305  }
306 
307  DBG_VERBOUS(GWEN_LOGDOMAIN, "Freeing node itself");
308  GWEN_FREE_OBJECT(n);
309  }
310 }
311 
312 
313 
315  GWEN_DB_NODE *nn;
316 
317  switch(n->typ) {
319  DBG_VERBOUS(GWEN_LOGDOMAIN, "Duplicating group \"%s\"",
320  n->data.dataName);
321  nn=GWEN_DB_Group_new(n->data.dataName);
322  break;
324  DBG_VERBOUS(GWEN_LOGDOMAIN, "Duplicating variable \"%s\"",
325  n->data.dataName);
326  nn=GWEN_DB_Var_new(n->data.dataName);
327  break;
329  nn=GWEN_DB_ValueChar_new(n->data.dataChar);
330  break;
332  nn=GWEN_DB_ValueBin_new(n->data.dataBin, n->dataSize);
333  break;
335  nn=GWEN_DB_ValuePtr_new(n->data.dataPtr);
336  break;
338  nn=GWEN_DB_ValueInt_new(n->data.dataInt);
339  break;
340  default:
341  DBG_WARN(GWEN_LOGDOMAIN, "Unknown node type (%d)", n->typ);
342  nn=0;
343  }
344 
345  /* duplicate all children and add them to the new node */
346  if (nn) {
347  const GWEN_DB_NODE *cn;
348 
349  cn=GWEN_DB_Node_List_First(n->children);
350  while(cn) {
351  GWEN_DB_NODE *ncn;
352 
353  /* duplicate child and add it */
354  ncn=GWEN_DB_Node_dup(cn);
355  if (!ncn) {
356  GWEN_DB_Node_free(nn);
357  return NULL;
358  }
360  cn=GWEN_DB_Node_List_Next(cn);
361  } /* while cn */
362  }
363 
364  return nn;
365 }
366 
367 
368 
371 }
372 
373 
374 
376  assert(n);
377  if (n->typ!=GWEN_DB_NodeType_Group) {
378  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
379  return NULL;
380  }
381  return GWEN_DB_Node_dup(n);
382 }
383 
384 
385 
387  GWEN_DB_NODE *nn;
388 
389  assert(n);
390  if (n->typ!=GWEN_DB_NodeType_Group) {
391  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
392  return NULL;
393  }
394  assert(n->children);
395  nn=GWEN_DB_Node_List_First(n->children);
396  while(nn) {
397  if (nn->typ==GWEN_DB_NodeType_Group)
398  break;
399  nn=GWEN_DB_Node_List_Next(nn);
400  } /* while node */
401  return nn;
402 }
403 
404 
405 
407  assert(n);
408  if (n->typ!=GWEN_DB_NodeType_Group) {
409  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
410  return NULL;
411  }
412  n=GWEN_DB_Node_List_Next(n);
413  while(n) {
414  if (n->typ==GWEN_DB_NodeType_Group)
415  break;
416  n=GWEN_DB_Node_List_Next(n);
417  } /* while node */
418  return n;
419 }
420 
421 
422 
424  GWEN_DB_NODE *nn;
425 
426  assert(n);
427  if (n->typ!=GWEN_DB_NodeType_Group) {
428  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
429  return NULL;
430  }
431  assert(n->children);
432  nn=GWEN_DB_Node_List_First(n->children);
433  while(nn) {
434  if (nn->typ==GWEN_DB_NodeType_Var)
435  break;
436  nn=GWEN_DB_Node_List_Next(nn);
437  } /* while node */
438  return nn;
439 }
440 
441 
442 
444  assert(n);
445  if (n->typ!=GWEN_DB_NodeType_Var) {
446  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable");
447  return NULL;
448  }
449  n=GWEN_DB_Node_List_Next(n);
450  while(n) {
451  if (n->typ==GWEN_DB_NodeType_Var)
452  break;
453  n=GWEN_DB_Node_List_Next(n);
454  } /* while node */
455  return n;
456 }
457 
458 
459 
461  GWEN_DB_NODE *nn;
462 
463  assert(n);
464  if (n->typ!=GWEN_DB_NodeType_Var) {
465  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable");
466  return NULL;
467  }
468  assert(n->children);
469  nn=GWEN_DB_Node_List_First(n->children);
470  while(nn) {
471  if (nn->typ>=GWEN_DB_NodeType_ValueChar &&
472  nn->typ<GWEN_DB_NodeType_ValueLast) {
473  break;
474  }
475  nn=GWEN_DB_Node_List_Next(nn);
476  } /* while node */
477  return nn;
478 }
479 
480 
481 
483  assert(n);
484  if (n->typ<GWEN_DB_NodeType_ValueChar ||
485  n->typ>=GWEN_DB_NodeType_ValueLast) {
486  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a value");
487  return NULL;
488  }
489 
490  n=GWEN_DB_Node_List_Next(n);
491  while(n) {
492  if (n->typ>=GWEN_DB_NodeType_ValueChar &&
494  break;
495  }
496  n=GWEN_DB_Node_List_Next(n);
497  } /* while node */
498  return n;
499 }
500 
501 
502 
504  assert(n);
505  if (n->typ>=GWEN_DB_NodeType_ValueChar &&
507  return n->typ;
508  }
509  else {
510  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a value");
512  }
513 }
514 
515 
516 
518  assert(n);
519  if (n->typ!=GWEN_DB_NodeType_ValueChar) {
520  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a char value");
521  return NULL;
522  }
523  return n->data.dataChar;
524 }
525 
526 
527 
528 int GWEN_DB_SetCharValueInNode(GWEN_DB_NODE *n, const char *s) {
529  assert(n);
530  assert(s);
531 
532  if (n->typ!=GWEN_DB_NodeType_ValueChar) {
533  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a char value");
534  return GWEN_ERROR_INVALID;
535  }
536 
537  GWEN_Memory_dealloc(n->data.dataChar);
538  n->data.dataChar=GWEN_Memory_strdup(s);
539  return 0;
540 }
541 
542 
543 
545  const char *p;
546  int res;
547 
548  assert(n);
549 
550  switch(n->typ) {
552  return n->data.dataInt;
554  p=n->data.dataChar;
555  assert(p);
556  if (sscanf(p, "%d", &res)!=1) {
557  DBG_ERROR(GWEN_LOGDOMAIN, "String in node is not an int value");
558  return 0;
559  }
560  return res;
561 
562  default:
563  DBG_ERROR(GWEN_LOGDOMAIN, "Node is neither char nor int value");
564  return 0;
565  }
566 }
567 
568 
569 
571  unsigned int *size){
572  assert(n);
573 
574  if (n->typ!=GWEN_DB_NodeType_ValueBin) {
575  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a binary value");
576  return NULL;
577  }
578 
579  *size=n->dataSize;
580  return n->data.dataBin;
581 }
582 
583 
584 
586  const char *name,
587  int idx) {
588  GWEN_DB_NODE *nn;
589 
590  assert(n);
591  assert(name);
592 
593  if (n->typ!=GWEN_DB_NodeType_Group) {
594  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
595  return NULL;
596  }
597 
598  /* find existing node */
599  assert(n->children);
600  nn=GWEN_DB_Node_List_First(n->children);
601  while(nn) {
602  if (nn->typ==GWEN_DB_NodeType_Group) {
603  if (strcasecmp(nn->data.dataName, name)==0) {
604  if (!idx)
605  /* ok, group found, return it */
606  return nn;
607  idx--;
608  } /* if entry found */
609  }
610  nn=GWEN_DB_Node_List_Next(nn);
611  } /* while node */
612 
613  return NULL;
614 }
615 
616 
617 
619  const char *name,
620  int idx) {
621  GWEN_DB_NODE *nn;
622 
623  assert(n);
624  assert(name);
625 
626  if (n->typ!=GWEN_DB_NodeType_Group) {
627  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
628  return NULL;
629  }
630 
631  /* find existing node */
632  assert(n->children);
633  nn=GWEN_DB_Node_List_First(n->children);
634  while(nn) {
635  if (nn->typ==GWEN_DB_NodeType_Var) {
636  if (strcasecmp(nn->data.dataName, name)==0) {
637  if (!idx)
638  /* ok, group found, return it */
639  return nn;
640  idx--;
641  } /* if entry found */
642  }
643  nn=GWEN_DB_Node_List_Next(nn);
644  } /* while node */
645 
646  return NULL;
647 }
648 
649 
650 
651 
652 
653 
654 
655 void* GWEN_DB_HandlePath(const char *entry,
656  void *data,
657  int idx,
658  uint32_t flags) {
659  GWEN_DB_NODE *n;
660  GWEN_DB_NODE *nn;
661 
662  n=(GWEN_DB_NODE*)data;
663 
664  /* check whether we are allowed to simply create the node */
665  if (
666  ((flags & GWEN_PATH_FLAGS_LAST) &&
667  (((flags & GWEN_PATH_FLAGS_VARIABLE) &&
668  (flags & GWEN_PATH_FLAGS_CREATE_VAR)) ||
669  (!(flags & GWEN_PATH_FLAGS_VARIABLE) &&
670  (flags & GWEN_PATH_FLAGS_CREATE_GROUP)))
671  ) ||
672  (
673  !(flags & GWEN_PATH_FLAGS_LAST) &&
674  (flags & GWEN_PATH_FLAGS_PATHCREATE))
675  ) {
676  /* simply create the new variable/group */
677  if (idx!=0) {
678  DBG_INFO(GWEN_LOGDOMAIN, "Index is not 0, not creating %s[%d]",
679  entry, idx);
680  return 0;
681  }
682  if (flags & GWEN_PATH_FLAGS_VARIABLE) {
684  "Unconditionally creating variable \"%s\"", entry);
685  nn=GWEN_DB_Var_new(entry);
686  if (flags & GWEN_DB_FLAGS_INSERT)
687  GWEN_DB_Node_Insert(n, nn);
688  else
689  GWEN_DB_Node_Append(n, nn);
690  return nn;
691  }
692  else {
694  "Unconditionally creating group \"%s\"", entry);
695  nn=GWEN_DB_Group_new(entry);
696  if (flags & GWEN_DB_FLAGS_INSERT)
697  GWEN_DB_Node_Insert(n, nn);
698  else
699  GWEN_DB_Node_Append(n, nn);
700  return nn;
701  }
702  }
703 
704  /* find the node */
705  if (flags & GWEN_PATH_FLAGS_VARIABLE) {
706  nn=GWEN_DB_FindVar(n, entry, idx);
707  }
708  else {
709  nn=GWEN_DB_FindGroup(n, entry, idx);
710  }
711 
712  if (!nn) {
713  /* node not found, check, if we are allowed to create it */
714  if (
715  (!(flags & GWEN_PATH_FLAGS_LAST) &&
716  (flags & GWEN_PATH_FLAGS_PATHMUSTEXIST)) ||
718  ) {
719  if (flags & GWEN_PATH_FLAGS_VARIABLE) {
721  "Variable \"%s\" does not exist", entry);
722  }
723  else {
725  "Group \"%s\" does not exist", entry);
726  }
727  return 0;
728  }
729  /* create the new variable/group */
730  if (idx!=0) {
731  DBG_INFO(GWEN_LOGDOMAIN, "Index is not 0, not creating %s[%d]",
732  entry, idx);
733  return 0;
734  }
735  if (flags & GWEN_PATH_FLAGS_VARIABLE) {
737  "Variable \"%s\" not found, creating", entry);
738  nn=GWEN_DB_Var_new(entry);
739  if (flags & GWEN_DB_FLAGS_INSERT)
740  GWEN_DB_Node_Insert(n, nn);
741  else
742  GWEN_DB_Node_Append(n, nn);
743  }
744  else {
746  "Group \"%s\" not found, creating", entry);
747  nn=GWEN_DB_Group_new(entry);
748  if (flags & GWEN_DB_FLAGS_INSERT)
749  GWEN_DB_Node_Insert(n, nn);
750  else
751  GWEN_DB_Node_Append(n, nn);
752  }
753  } /* if node not found */
754  else {
755  /* node does exist, check whether this is ok */
756  if (
757  ((flags & GWEN_PATH_FLAGS_LAST) &&
759  (!(flags & GWEN_PATH_FLAGS_LAST) &&
761  ) {
762  DBG_VERBOUS(GWEN_LOGDOMAIN, "Entry \"%s\" already exists", entry);
763  return 0;
764  }
765  }
766 
767  return nn;
768 }
769 
770 
771 
773  const char *path,
774  uint32_t flags){
776  n,
777  flags,
779 }
780 
781 
782 
784  assert(n);
785  if (n->children)
786  GWEN_DB_Node_List_Clear(n->children);
787 }
788 
789 
790 
792  const char *path,
793  int idx) {
794  GWEN_DB_NODE *nn;
795 
796  /* find corresponding node */
797  nn=GWEN_DB_GetNode(n,
798  path,
802  if (!nn) {
803  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found",
804  path);
805  return 0;
806  }
807 
808  /* find value */
809  assert(nn->children);
810  nn=GWEN_DB_Node_List_First(nn->children);
811  while(nn) {
812  if (nn->typ>=GWEN_DB_NodeType_ValueChar &&
813  nn->typ<GWEN_DB_NodeType_ValueLast) {
814  if (!idx)
815  return nn;
816  idx--;
817  }
818  nn=GWEN_DB_Node_List_Next(nn);
819  }
820 
821  DBG_VERBOUS(GWEN_LOGDOMAIN, "No value[%d] for path \"%s\"",
822  idx, path);
823  return NULL;
824 }
825 
826 
827 
829  const char *path) {
830  GWEN_DB_NODE *nn;
831 
832  /* find corresponding node */
833  nn=GWEN_DB_GetNode(n,
834  path,
838  if (!nn) {
839  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found",
840  path);
841  return 1;
842  }
844  GWEN_DB_Node_free(nn);
845  return 0;
846 }
847 
848 
849 
851  const char *path) {
852  GWEN_DB_NODE *nn;
853 
854  /* find corresponding node */
855  nn=GWEN_DB_GetNode(n,
856  path,
859  if (!nn) {
860  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found",
861  path);
862  return 1;
863  }
865  GWEN_DB_Node_free(nn);
866  return 0;
867 }
868 
869 
870 
872  const char *path){
873  assert(n);
874  if (path) {
875  GWEN_DB_NODE *nn;
876 
877  /* find corresponding node */
878  nn=GWEN_DB_GetNode(n,
879  path,
882  if (!nn) {
883  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found",
884  path);
885  return 1;
886  }
887  GWEN_DB_ClearNode(nn);
888  }
889  else {
891  }
892  return 0;
893 }
894 
895 
896 
898  const char *path,
899  int idx,
900  const char *defVal){
901  GWEN_DB_NODE *nn;
902 
903  nn=GWEN_DB_GetValue(n, path, idx);
904  if (!nn){
906  "Value for \"%s\" not found, returning default value",
907  path);
908  return defVal;
909  }
910  if (nn->typ!=GWEN_DB_NodeType_ValueChar) {
911  /* bad type */
913  "Bad type for path \"%s\", returning default value",
914  path);
915  return defVal;
916  }
917  return nn->data.dataChar;
918 }
919 
920 
921 
923  uint32_t flags,
924  const char *path,
925  const char *val){
926  GWEN_DB_NODE *nn;
927  GWEN_DB_NODE *nv;
928 
929  /* select/create node */
930  nn=GWEN_DB_GetNode(n,
931  path,
932  flags | GWEN_PATH_FLAGS_VARIABLE);
933  if (!nn) {
934  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
935  path);
936  return 1;
937  }
938 
939  nv=GWEN_DB_ValueChar_new(val);
940 
941  /* delete contents of this variable if wanted */
942  if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) {
943  DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path);
944  GWEN_DB_ClearNode(nn);
945  }
946 
947  /* add previously created value */
948  if (flags & GWEN_DB_FLAGS_INSERT)
949  GWEN_DB_Node_Insert(nn, nv);
950  else
951  GWEN_DB_Node_Append(nn, nv);
953  "Added char value \"%s\" to variable \"%s\"", val, path);
954 
955  return 0;
956 }
957 
958 
959 
961  const char *path,
962  const char *val,
963  int senseCase,
964  int check){
965  GWEN_DB_NODE *nn;
966  GWEN_DB_NODE *nv;
967 
968  /* select/create node */
969  nn=GWEN_DB_GetNode(n,
970  path,
972  if (!nn) {
973  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
974  path);
975  return -1;
976  }
977 
978  if (check) {
979  nv=GWEN_DB_GetFirstValue(n);
980  if (nv && nv->typ==GWEN_DB_NodeType_ValueChar) {
981  int res;
982 
983  assert(nv->data.dataChar);
984  if (senseCase)
985  res=strcasecmp(nv->data.dataChar, val)==0;
986  else
987  res=strcmp(nv->data.dataChar, val)==0;
988  if (res) {
990  "Value \"%s\" of var \"%s\" already exists",
991  val, path);
992  return 1;
993  }
994  }
995  } /* if check */
996 
997  nv=GWEN_DB_ValueChar_new(val);
998  GWEN_DB_Node_Append(nn, nv);
1000  "Added char value \"%s\" to variable \"%s\"", val, path);
1001 
1002  return 0;
1003 }
1004 
1005 
1006 
1008  const char *path,
1009  const char *val,
1010  int senseCase){
1011  GWEN_DB_NODE *nn;
1012  GWEN_DB_NODE *nv;
1013 
1014  /* select/create node */
1015  nn=GWEN_DB_GetNode(n,
1016  path,
1018  if (!nn) {
1019  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
1020  path);
1021  return -1;
1022  }
1023 
1024  nv=GWEN_DB_GetFirstValue(n);
1025  if (nv && nv->typ==GWEN_DB_NodeType_ValueChar) {
1026  int res;
1027 
1028  assert(nv->data.dataChar);
1029  if (senseCase)
1030  res=strcasecmp(nv->data.dataChar, val)==0;
1031  else
1032  res=strcmp(nv->data.dataChar, val)==0;
1033  if (res) {
1035  "Value \"%s\" of var \"%s\" already exists",
1036  val, path);
1037  GWEN_DB_Node_Unlink(nv);
1038  GWEN_DB_Node_free(nv);
1039  return 0;
1040  }
1041  }
1042 
1043  return 1;
1044 }
1045 
1046 
1047 
1049  const char *path,
1050  int idx,
1051  int defVal){
1052  GWEN_DB_NODE *nn;
1053  const char *p;
1054  int res;
1055 
1056  assert(n);
1057  nn=GWEN_DB_GetValue(n, path, idx);
1058  if (!nn){
1060  "Value[%d] for \"%s\" not found, returning default value",
1061  idx, path);
1062  return defVal;
1063  }
1064 
1065  switch(nn->typ) {
1067  return nn->data.dataInt;
1069  p=nn->data.dataChar;
1070  assert(p);
1071  if (sscanf(p, "%d", &res)!=1) {
1073  "String [%s] in node is not an int value", p);
1074  return defVal;
1075  }
1076  return res;
1077 
1078  default:
1079  DBG_ERROR(GWEN_LOGDOMAIN, "Node is neither char nor int value");
1080  return defVal;
1081  }
1082 }
1083 
1084 
1085 
1087  uint32_t flags,
1088  const char *path,
1089  int val){
1090  GWEN_DB_NODE *nn;
1091  GWEN_DB_NODE *nv;
1092 
1093  /* select/create node */
1094  nn=GWEN_DB_GetNode(n,
1095  path,
1096  flags | GWEN_PATH_FLAGS_VARIABLE);
1097  if (!nn) {
1098  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
1099  path);
1100  return 1;
1101  }
1102 
1103  /* delete contents of this variable if wanted */
1104  if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) {
1105  DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path);
1106  GWEN_DB_ClearNode(nn);
1107  }
1108 
1109  nv=GWEN_DB_ValueInt_new(val);
1110  if (flags & GWEN_DB_FLAGS_INSERT)
1111  GWEN_DB_Node_Insert(nn, nv);
1112  else
1113  GWEN_DB_Node_Append(nn, nv);
1114  DBG_VERBOUS(GWEN_LOGDOMAIN, "Added int value \"%d\" to variable \"%s\"", val, path);
1115  return 0;
1116 }
1117 
1118 
1119 
1121  const char *path,
1122  int idx,
1123  const void *defVal,
1124  unsigned int defValSize,
1125  unsigned int *returnValueSize){
1126  GWEN_DB_NODE *nn;
1127 
1128  assert(returnValueSize);
1129  nn=GWEN_DB_GetValue(n, path, idx);
1130  if (!nn){
1132  "Value for \"%s\" not found, returning default value",
1133  path);
1134  *returnValueSize=defValSize;
1135  return defVal;
1136  }
1137  if (nn->typ!=GWEN_DB_NodeType_ValueBin) {
1138  /* bad type */
1140  "Bad type for path \"%s\", returning default value",
1141  path);
1142  *returnValueSize=defValSize;
1143  return defVal;
1144  }
1145  *returnValueSize=nn->dataSize;
1146  return nn->data.dataBin;
1147 }
1148 
1149 
1150 
1152  uint32_t flags,
1153  const char *path,
1154  const void *val,
1155  unsigned int valSize){
1156  GWEN_DB_NODE *nn;
1157  GWEN_DB_NODE *nv;
1158 
1159  assert(val);
1160  /* select/create node */
1161  nn=GWEN_DB_GetNode(n,
1162  path,
1163  flags | GWEN_PATH_FLAGS_VARIABLE);
1164  if (!nn) {
1165  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
1166  path);
1167  return 1;
1168  }
1169 
1170  /* delete contents of this variable if wanted */
1171  if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) {
1172  DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path);
1173  GWEN_DB_ClearNode(nn);
1174  }
1175 
1176  nv=GWEN_DB_ValueBin_new(val, valSize);
1177  if (flags & GWEN_DB_FLAGS_INSERT)
1178  GWEN_DB_Node_Insert(nn, nv);
1179  else
1180  GWEN_DB_Node_Append(nn, nv);
1181  DBG_VERBOUS(GWEN_LOGDOMAIN, "Added bin value to variable \"%s\"", path);
1182  return 0;
1183 }
1184 
1185 
1186 
1188  const char *path,
1189  int idx,
1190  void *defVal){
1191  GWEN_DB_NODE *nn;
1192 
1193  nn=GWEN_DB_GetValue(n, path, idx);
1194  if (!nn){
1196  "Value for \"%s\" not found, returning default value",
1197  path);
1198  return defVal;
1199  }
1200  if (nn->typ!=GWEN_DB_NodeType_ValuePtr) {
1201  /* bad type */
1203  "Bad type for path \"%s\", returning default value",
1204  path);
1205  return defVal;
1206  }
1207  return nn->data.dataPtr;
1208 }
1209 
1210 
1211 
1213  uint32_t flags,
1214  const char *path,
1215  void *val){
1216  GWEN_DB_NODE *nn;
1217  GWEN_DB_NODE *nv;
1218 
1219  /* select/create node */
1220  nn=GWEN_DB_GetNode(n,
1221  path,
1222  flags | GWEN_PATH_FLAGS_VARIABLE);
1223  if (!nn) {
1224  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
1225  path);
1226  return 1;
1227  }
1228 
1229  /* delete contents of this variable if wanted */
1230  if (flags & GWEN_DB_FLAGS_OVERWRITE_VARS) {
1231  DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing variable \"%s\"", path);
1232  GWEN_DB_ClearNode(nn);
1233  }
1234 
1235  nv=GWEN_DB_ValuePtr_new(val);
1236  if (flags & GWEN_DB_FLAGS_INSERT)
1237  GWEN_DB_Node_Insert(nn, nv);
1238  else
1239  GWEN_DB_Node_Append(nn, nv);
1240  DBG_VERBOUS(GWEN_LOGDOMAIN, "Added ptr value to variable \"%s\"", path);
1241 
1242  return 0;
1243 }
1244 
1245 
1246 
1247 
1248 
1249 
1250 
1251 
1252 
1253 
1254 
1255 
1256 
1257 
1258 
1259 
1261  uint32_t flags,
1262  const char *path) {
1263  GWEN_DB_NODE *nn;
1264 
1265  /* select/create node */
1266  nn=GWEN_DB_GetNode(n,
1267  path,
1268  flags & ~GWEN_PATH_FLAGS_VARIABLE);
1269  if (!nn) {
1270  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not available",
1271  path);
1272  return NULL;
1273  }
1274 
1275  /* delete contents of this variable if wanted */
1276  if (flags & GWEN_DB_FLAGS_OVERWRITE_GROUPS) {
1277  DBG_VERBOUS(GWEN_LOGDOMAIN, "Clearing group \"%s\"", path);
1278  GWEN_DB_ClearNode(nn);
1279  }
1280 
1281  return nn;
1282 }
1283 
1284 
1285 
1287  assert(n);
1288  if (n->typ!=GWEN_DB_NodeType_Group) {
1289  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
1290  return NULL;
1291  }
1292  return n->data.dataName;
1293 }
1294 
1295 
1296 
1297 void GWEN_DB_Dump(GWEN_DB_NODE *n, int insert){
1298  if (n) {
1299  int i;
1300 
1301  for (i=0; i<insert; i++)
1302  fprintf(stderr, " ");
1303 
1304  /* dump dynamic (allocated) data */
1305  switch(n->typ) {
1307  fprintf(stderr, "Group : \"%s\"\n", n->data.dataName);
1308  break;
1309  case GWEN_DB_NodeType_Var:
1310  fprintf(stderr, "Var : \"%s\"\n", n->data.dataName);
1311  break;
1313  fprintf(stderr, "Value : \"%s\" (char)\n", n->data.dataChar);
1314  break;
1316  fprintf(stderr, "Value : %d (int)\n", n->data.dataInt);
1317  break;
1319  char *buffer;
1320 
1321  buffer=(char*)GWEN_Memory_malloc((n->dataSize*2)+1);
1322  assert(buffer);
1323  if (GWEN_Text_ToHex(n->data.dataBin, n->dataSize,
1324  buffer, (n->dataSize*2)+1)==0) {
1325  fprintf(stderr, "Value : %d bytes (bin)\n", n->dataSize);
1326  }
1327  else {
1328  fprintf(stderr, "Value : %s (bin)\n", buffer);
1329  }
1330  GWEN_Memory_dealloc(buffer);
1331  break;
1332  }
1334  fprintf(stderr, "Value : %p (ptr)\n", n->data.dataPtr);
1335  break;
1336  default:
1337  fprintf(stderr, "[unknown node type %d]\n", n->typ);
1338  }
1339 
1340  /* dump children */
1341  if (n->children) {
1342  GWEN_DB_NODE *cn;
1343 
1344  cn=GWEN_DB_Node_List_First(n->children);
1345  while(cn) {
1346  GWEN_DB_Dump(cn, insert+4);
1347  cn=GWEN_DB_Node_List_Next(cn);
1348  }
1349  }
1350  }
1351  else {
1352  fprintf(stderr, "[no node]\n");
1353  }
1354 }
1355 
1356 
1357 
1359  assert(n);
1360  assert(nn);
1361 
1362  if (n->typ!=GWEN_DB_NodeType_Group) {
1363  DBG_ERROR(GWEN_LOGDOMAIN, "Target node is not a group");
1364  return 0;
1365  }
1366 
1367  if (nn->typ!=GWEN_DB_NodeType_Group) {
1368  DBG_ERROR(GWEN_LOGDOMAIN, "Source node is not a group");
1369  return 0;
1370  }
1371 
1372  GWEN_DB_Node_Append(n, nn);
1373  return 0;
1374 }
1375 
1376 
1377 
1379  assert(n);
1380  assert(nn);
1381 
1382  if (n->typ!=GWEN_DB_NodeType_Group) {
1383  DBG_ERROR(GWEN_LOGDOMAIN, "Target node is not a group");
1384  return 0;
1385  }
1386 
1387  if (nn->typ!=GWEN_DB_NodeType_Group) {
1388  DBG_ERROR(GWEN_LOGDOMAIN, "Source node is not a group");
1389  return 0;
1390  }
1391 
1392  GWEN_DB_Node_Insert(n, nn);
1393  return 0;
1394 }
1395 
1396 
1397 
1399  GWEN_DB_NODE *cpn;
1400 
1401  assert(n);
1402  assert(nn);
1403 
1404  if (n->typ!=GWEN_DB_NodeType_Group) {
1405  DBG_ERROR(GWEN_LOGDOMAIN, "Target node is not a group");
1406  return -1;
1407  }
1408 
1409  if (nn->typ!=GWEN_DB_NodeType_Group) {
1410  DBG_ERROR(GWEN_LOGDOMAIN, "Source node is not a group");
1411  GWEN_DB_Dump(nn, 1);
1412  return -1;
1413  }
1414 
1415  nn=GWEN_DB_Node_List_First(nn->children);
1416  while (nn) {
1417  DBG_VERBOUS(GWEN_LOGDOMAIN, "Duplicating node");
1418  cpn=GWEN_DB_Node_dup(nn);
1419  GWEN_DB_Node_Append(n, cpn);
1420  nn=GWEN_DB_Node_List_Next(nn);
1421  } /* while */
1422  return 0;
1423 }
1424 
1425 
1426 
1428  assert(n);
1429  if (n->typ!=GWEN_DB_NodeType_Group) {
1430  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
1431  return;
1432  }
1434 }
1435 
1436 
1437 int GWEN_DB_VariableExists(GWEN_DB_NODE *n, const char *path){
1438  GWEN_DB_NODE *nn;
1439 
1440  /* find corresponding node */
1441  assert(n);
1442  nn=GWEN_DB_GetNode(n,
1443  path,
1447  if (!nn) {
1448  DBG_VERBOUS(GWEN_LOGDOMAIN, "Path \"%s\" not found", path);
1449  return 0;
1450  }
1451 
1452  return 1;
1453 }
1454 
1455 
1456 
1458  const char *path,
1459  unsigned int i){
1460  return (GWEN_DB_GetValue(n, path, i)!=0);
1461 }
1462 
1463 
1464 
1466  const char *p){
1467  GWEN_DB_NODE *nn;
1468 
1469  nn=GWEN_DB_FindVar(n, p, 0);
1470  if (!nn)
1471  return GWEN_DB_NodeType_Unknown;
1472 
1473  nn=GWEN_DB_GetFirstValue(nn);
1474  if (!nn)
1475  return GWEN_DB_NodeType_Unknown;
1476  return GWEN_DB_GetValueType(nn);
1477 }
1478 
1479 
1480 
1482  const char *path,
1483  unsigned int i){
1484  GWEN_DB_NODE *nn;
1485 
1486  nn=GWEN_DB_GetValue(n, path, i);
1487  if (!nn)
1488  return GWEN_DB_NodeType_Unknown;
1489  return GWEN_DB_GetValueType(nn);
1490 }
1491 
1492 
1493 void GWEN_DB_GroupRename(GWEN_DB_NODE *n, const char *newname){
1494  assert(n);
1495  assert(newname);
1496  assert(n->typ==GWEN_DB_NodeType_Group);
1497  GWEN_Memory_dealloc(n->data.dataName);
1498  n->data.dataName=GWEN_Memory_strdup(newname);
1499 }
1500 
1501 
1502 
1503 
1504 
1505 
1506 
1508  assert(n);
1509  return n->typ==GWEN_DB_NodeType_Group;
1510 }
1511 
1512 
1513 
1515  assert(n);
1516  return n->typ==GWEN_DB_NodeType_Var;
1517 }
1518 
1519 
1520 
1522  assert(n);
1523  return (n->typ>=GWEN_DB_NodeType_ValueChar &&
1524  n->typ>=GWEN_DB_NodeType_ValueLast);
1525 }
1526 
1527 
1528 
1530  void *user_data){
1531  GWEN_DB_NODE *iter;
1532  void *res;
1533 
1534  assert(node);
1535  assert(func);
1536 
1537  iter=GWEN_DB_GetFirstGroup(node);
1538  res=NULL;
1539  while(iter){
1540  res=(*func)(iter, user_data);
1541  if (res) {
1542  break;
1543  }
1544  iter=GWEN_DB_GetNextGroup(iter);
1545  }
1546  return res;
1547 }
1548 
1549 
1550 
1551 void *GWEN_DB_count_cb(GWEN_UNUSED GWEN_DB_NODE *node, void *user_data){
1552  unsigned int *a = user_data;
1553  ++(*a);
1554  return NULL;
1555 }
1556 
1557 
1558 
1559 unsigned int GWEN_DB_Groups_Count(const GWEN_DB_NODE *node){
1560  unsigned int res = 0;
1562  return res;
1563 }
1564 
1565 
1566 
1568  void *user_data){
1569  GWEN_DB_NODE *iter;
1570  void *res;
1571 
1572  assert(node);
1573  assert(func);
1574 
1575  iter=GWEN_DB_GetFirstVar(node);
1576  res=NULL;
1577  while(iter){
1578  res=(*func)(iter, user_data);
1579  if (res) {
1580  break;
1581  }
1582  iter=GWEN_DB_GetNextVar(iter);
1583  }
1584  return res;
1585 }
1586 
1587 
1588 
1589 unsigned int GWEN_DB_Variables_Count(const GWEN_DB_NODE *node){
1590  unsigned int res = 0;
1592  return res;
1593 }
1594 
1595 
1596 
1598  void *user_data){
1599  GWEN_DB_NODE *iter;
1600  void *res;
1601 
1602  assert(node);
1603  assert(func);
1604 
1605  iter=GWEN_DB_GetFirstValue(node);
1606  res=NULL;
1607  while(iter){
1608  res=(*func)(iter, user_data);
1609  if (res) {
1610  break;
1611  }
1612  iter=GWEN_DB_GetNextValue(iter);
1613  }
1614  return res;
1615 }
1616 
1617 
1618 
1619 unsigned int GWEN_DB_Values_Count(const GWEN_DB_NODE *node){
1620  unsigned int res = 0;
1622  return res;
1623 }
1624 
1625 
1626 
1628  assert(n);
1629  return n->nodeFlags;
1630 }
1631 
1632 
1633 
1635  uint32_t flags){
1636  assert(n);
1637  n->nodeFlags=flags;
1638 }
1639 
1640 
1641 
1643  uint32_t newflags,
1644  uint32_t mask){
1645  uint32_t flags;
1646 
1647  assert(n);
1648 
1649  while(n) {
1650  flags=n->nodeFlags;
1651  flags=((flags^newflags)&(mask))^flags;
1652  n->nodeFlags=flags;
1653  n=n->parent;
1654  } /* while */
1655 }
1656 
1657 
1658 
1660  uint32_t newflags,
1661  uint32_t mask){
1662  uint32_t flags;
1663  GWEN_DB_NODE *cn;
1664 
1665  assert(n);
1666 
1667  flags=n->nodeFlags;
1668  flags=((flags^newflags)&(mask))^flags;
1669  n->nodeFlags=flags;
1670 
1671  cn=GWEN_DB_Node_List_First(n->children);
1672  while(cn) {
1673  GWEN_DB_ModifyBranchFlagsDown(cn, newflags, mask);
1674  cn=GWEN_DB_Node_List_Next(cn);
1675  } /* while cn */
1676 }
1677 
1678 
1679 
1681  GWEN_DB_NODE *nn;
1682 
1683  assert(n);
1684  nn=n->parent;
1685  while(nn && nn->typ!=GWEN_DB_NodeType_Group)
1686  nn=nn->parent;
1687  return nn;
1688 }
1689 
1690 
1691 
1693  GWEN_DB_NODE *nn;
1694 
1695  assert(n);
1696  if (n->typ!=GWEN_DB_NodeType_Group) {
1697  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
1698  return NULL;
1699  }
1700  nn=GWEN_DB_Node_List_First(n->children);
1701  while(nn) {
1702  if ((nn->typ==GWEN_DB_NodeType_Group) &&
1703  (-1!=GWEN_Text_ComparePattern(nn->data.dataName, name, 0)))
1704  break;
1705  nn=GWEN_DB_Node_List_Next(nn);
1706  } /* while node */
1707  return nn;
1708 }
1709 
1710 
1711 
1713  GWEN_DB_NODE *og;
1714 
1715  og=n;
1716  assert(n);
1717  if (n->typ!=GWEN_DB_NodeType_Group) {
1718  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
1719  return NULL;
1720  }
1721  n=GWEN_DB_GetNextGroup(n);
1722  while(n) {
1723  if (-1!=GWEN_Text_ComparePattern(n->data.dataName, name, 0))
1724  break;
1725  n=GWEN_DB_GetNextGroup(n);
1726  } /* while node */
1727  assert(n!=og);
1728  return n;
1729 }
1730 
1731 
1732 
1734  GWEN_DB_NODE *nn;
1735 
1736  assert(n);
1737  if (n->typ!=GWEN_DB_NodeType_Group) {
1738  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a group");
1739  return NULL;
1740  }
1741 
1742  nn=GWEN_DB_Node_List_First(n->children);
1743  while(nn) {
1744  if ((nn->typ==GWEN_DB_NodeType_Var) &&
1745  (-1!=GWEN_Text_ComparePattern(nn->data.dataName, name, 0)))
1746  break;
1747  nn=GWEN_DB_Node_List_Next(nn);
1748  } /* while node */
1749 
1750  return nn;
1751 }
1752 
1753 
1754 
1756  GWEN_DB_NODE *og;
1757 
1758  og=n;
1759  assert(n);
1760  if (n->typ!=GWEN_DB_NodeType_Var) {
1761  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable");
1762  return NULL;
1763  }
1764  n=GWEN_DB_GetNextVar(n);
1765  while(n) {
1766  if (-1!=GWEN_Text_ComparePattern(n->data.dataName, name, 0))
1767  break;
1768  n=GWEN_DB_GetNextVar(n);
1769  } /* while node */
1770  assert(n!=og);
1771  return n;
1772 }
1773 
1774 
1775 
1777  assert(n);
1778  if (n->typ!=GWEN_DB_NodeType_Var) {
1779  DBG_ERROR(GWEN_LOGDOMAIN, "Node is not a variable");
1780  return NULL;
1781  }
1782  return n->data.dataName;
1783 }
1784 
1785 
1786 
1787 void GWEN_DB_VariableRename(GWEN_DB_NODE *n, const char *newname){
1788  assert(n);
1789  assert(newname);
1790  assert(n->typ==GWEN_DB_NodeType_Var);
1791  GWEN_Memory_dealloc(n->data.dataName);
1792  n->data.dataName=GWEN_Memory_strdup(newname);
1793 }
1794 
1795 
1796 
1797 
1798 
1799 
1800 #include "dbrw.c"
1801 
1802 
1803 
1804 
1805 
1806 
1807 
1808 
1809