gwenhywfar  4.99.25rc9
msgengine.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Fri Jul 04 2003
3  copyright : (C) 2019 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 #ifdef HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28 
29 #define DISABLE_DEBUGLOG
30 /*#define HEAVY_DEBUG_MSGENGINE*/
31 
32 
33 #include <gwenhywfar/gwenhywfarapi.h>
34 #include <msgengine_p.h>
35 #include <gwenhywfar/xml.h>
36 #include <gwenhywfar/text.h>
37 #include <gwenhywfar/misc.h>
38 #include <gwenhywfar/path.h>
39 #include <gwenhywfar/debug.h>
40 #include <gwenhywfar/buffer.h>
41 #include <stdlib.h>
42 #include <assert.h>
43 #include <string.h>
44 #include <ctype.h>
45 
46 
47 
48 
49 static int _groupReadElement(GWEN_MSGENGINE *e,
50  GWEN_BUFFER *msgbuf,
51  GWEN_XMLNODE *n,
52  GWEN_XMLNODE *rnode,
53  GWEN_DB_NODE *gr,
54  char currentDelimiter,
55  char currentTerminator,
56  const char *delimiters,
57  uint32_t flags);
58 
59 
60 
61 
62 
64 
65 
67 {
68  GWEN_MSGENGINE *e;
69 
72  e->charsToEscape=strdup(GWEN_MSGENGINE_CHARSTOESCAPE);
73  e->delimiters=strdup(GWEN_MSGENGINE_DEFAULT_DELIMITERS);
74  e->globalValues=GWEN_DB_Group_new("globalvalues");
75  e->escapeChar='\\';
76 
77  e->usage=1;
78  return e;
79 }
80 
81 
83 {
84  if (e) {
85  assert(e->usage);
86  if (--(e->usage)==0) {
88 
89  if (e->inheritorData && e->freeDataPtr)
90  e->freeDataPtr(e);
91  if (e->ownDefs)
92  GWEN_XMLNode_free(e->defs);
93  free(e->charsToEscape);
94  free(e->delimiters);
95  GWEN_DB_Group_free(e->globalValues);
96  if (e->trustInfos) {
97  /* free trustInfos */
99 
100  td=e->trustInfos;
101  while (td) {
102  tdn=td->next;
104  td=tdn;
105  } /* while */
106  }
107  GWEN_FREE_OBJECT(e);
108  }
109  }
110 }
111 
112 
113 
115 {
116  assert(e);
117  e->usage++;
118 }
119 
120 
122 {
123  assert(e);
124  e->escapeChar=c;
125 }
126 
127 
128 
130 {
131  assert(e);
132  return e->escapeChar;
133 }
134 
135 
136 
138 {
139  assert(e);
140  free(e->charsToEscape);
141  e->charsToEscape=strdup(c);
142 }
143 
144 
145 
147 {
148  assert(e);
149  return e->charsToEscape;
150 }
151 
152 
153 
155 {
156  assert(e);
157  free(e->delimiters);
158  if (s)
159  e->delimiters=strdup(s);
160  else
161  e->delimiters=strdup(GWEN_MSGENGINE_DEFAULT_DELIMITERS);
162 }
163 
164 
165 
167 {
168  assert(e);
169  return e->delimiters;
170 }
171 
172 
173 
174 void GWEN_MsgEngine_SetMode(GWEN_MSGENGINE *e, const char *mode)
175 {
176  GWEN_DB_NODE *db;
177 
178  assert(e);
180 
181  if (mode)
184  "engine/secmode",
185  mode);
186  else
187  GWEN_DB_DeleteVar(db, "engine/secmode");
188 }
189 
190 
192 {
193  GWEN_DB_NODE *db;
194 
195  assert(e);
197  return GWEN_DB_GetCharValue(db, "engine/secmode", 0, 0);
198 }
199 
200 
201 
203 {
204  GWEN_DB_NODE *globalValues;
205 
206  assert(e);
207  if (e->getGlobalValuesPtr) {
208  globalValues=e->getGlobalValuesPtr(e);
209  if (!globalValues)
210  globalValues=e->globalValues;
211  }
212  else {
213  globalValues=e->globalValues;
214  }
215  assert(globalValues);
216  return globalValues;
217 }
218 
219 
220 
222 {
223  GWEN_DB_NODE *db;
224 
225  assert(e);
227  return GWEN_DB_GetIntValue(db, "engine/pversion", 0, 0);
228 }
229 
230 
231 
233  unsigned int p)
234 {
235  GWEN_DB_NODE *db;
236 
237  assert(e);
239 
242  "engine/pversion",
243  p);
244 }
245 
246 
247 
249 {
250  assert(e);
251  return e->defs;
252 }
253 
254 
256  GWEN_XMLNODE *n,
257  int take)
258 {
259  assert(e);
260  if (e->ownDefs)
261  GWEN_XMLNode_free(e->defs);
262  e->defs=n;
263  e->ownDefs=take;
264 }
265 
266 
267 
270 {
271  assert(e);
272  e->getGlobalValuesPtr=p;
273 }
274 
275 
276 
278 {
279  assert(e);
280  return e->getGlobalValuesPtr;
281 }
282 
283 
284 
287 {
288  assert(e);
289  e->typeReadPtr=p;
290 }
291 
292 
293 
295 {
296  assert(e);
297  return e->typeReadPtr;
298 }
299 
300 
301 
304 {
305  assert(e);
306  e->typeWritePtr=p;
307 }
308 
309 
310 
312 {
313  assert(e);
314  return e->typeWritePtr;
315 }
316 
317 
318 
321 {
322  assert(e);
323  e->typeCheckPtr=p;
324 }
325 
326 
327 
329 {
330  assert(e);
331  return e->typeCheckPtr;
332 }
333 
334 
335 
336 
337 
338 
341 {
342  assert(e);
343  e->binTypeReadPtr=p;
344 }
345 
346 
347 
349 {
350  assert(e);
351  return e->binTypeReadPtr;
352 }
353 
354 
355 
358 {
359  assert(e);
360  e->binTypeWritePtr=p;
361 }
362 
363 
364 
366 {
367  assert(e);
368  return e->binTypeWritePtr;
369 }
370 
371 
372 
375 {
376  assert(e);
377  e->getCharValuePtr=p;
378 }
379 
380 
381 
384 {
385  assert(e);
386  e->getIntValuePtr=p;
387 }
388 
389 
390 
393 {
394  assert(e);
395  DBG_WARN(GWEN_LOGDOMAIN, "GWEN_MsgEngine_SetFreeDataFunction: Deprecated");
396  e->freeDataPtr=p;
397 }
398 
399 
400 
402 {
403  assert(e);
404  return e->inheritorData;
405 }
406 
407 
408 
410 {
411  assert(e);
412  DBG_WARN(GWEN_LOGDOMAIN, "GWEN_MsgEngine_SetInheritorData: Deprecated");
413  if (e->inheritorData && e->freeDataPtr)
414  e->freeDataPtr(e);
415  e->inheritorData=d;
416 }
417 
418 
419 
421  GWEN_BUFFER *gbuf,
422  GWEN_BUFFER *data,
423  GWEN_XMLNODE *node)
424 {
425  unsigned int minsize;
426  unsigned int maxsize;
427  unsigned int fixSize;
428  unsigned int startPos;
429  int filler;
430  const char *type;
431  const char *name;
432  int rv;
433 
434  /* get some sizes */
435  minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize", "0"));
436  maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize", "0"));
437  fixSize=atoi(GWEN_XMLNode_GetProperty(node, "size", "0"));
438  filler=atoi(GWEN_XMLNode_GetProperty(node, "filler", "0"));
439  type=GWEN_XMLNode_GetProperty(node, "type", "ASCII");
440  name=GWEN_XMLNode_GetProperty(node, "name", "<unnamed>");
441  startPos=GWEN_Buffer_GetPos(gbuf);
442 
443  /* check sizes */
444  if (minsize && GWEN_Buffer_GetUsedBytes(data)<minsize) {
445  DBG_ERROR(GWEN_LOGDOMAIN, "Data too short (minsize is %d)", minsize);
446  return -1;
447  }
448  if (maxsize && GWEN_Buffer_GetUsedBytes(data)>maxsize) {
449  DBG_ERROR(GWEN_LOGDOMAIN, "Data too long (maxsize is %d)", maxsize);
450  return -1;
451  }
452 
453  rv=1;
454  if (e->typeWritePtr) {
455  rv=e->typeWritePtr(e,
456  gbuf,
457  data,
458  node);
459  }
460  if (rv==-1) {
461  DBG_INFO(GWEN_LOGDOMAIN, "External type writing failed");
462  return -1;
463  }
464  else if (rv==1) {
465  int i;
466 
467  /* type not handled externally, so handle it myself */
468  if (strcasecmp(type, "bin")==0) {
469  DBG_DEBUG(GWEN_LOGDOMAIN, "Writing binary data (%d bytes added to %d bytes)",
472  if (GWEN_Buffer_AllocRoom(gbuf, 10+GWEN_Buffer_GetUsedBytes(data))) {
473  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
474  return -1;
475  }
476  sprintf(GWEN_Buffer_GetPosPointer(gbuf),
477  "@%d@",
479 
480 
481  i=strlen(GWEN_Buffer_GetPosPointer(gbuf));
482  GWEN_Buffer_IncrementPos(gbuf, i);
484  GWEN_Buffer_AppendBuffer(gbuf, data);
485  } /* if type is "bin" */
486  else if (strcasecmp(type, "num")==0) {
487  //int num;
488  unsigned int len;
489  unsigned int lj;
490 
491  //num=atoi(GWEN_Buffer_GetPosPointer(data));
492  len=strlen(GWEN_Buffer_GetPosPointer(data));
493 
494  if (atoi(GWEN_XMLNode_GetProperty(node, "leftfill", "0"))) {
495  if (GWEN_Buffer_AllocRoom(gbuf, maxsize+1)) {
496  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
497  return -1;
498  }
499 
500  /* fill left */
501  for (lj=0; lj<(maxsize-len); lj++)
502  GWEN_Buffer_AppendByte(gbuf, '0');
503 
504  /* write value */
505  for (lj=0; lj<len; lj++)
507  }
508  else if (atoi(GWEN_XMLNode_GetProperty(node, "rightfill", "0"))) {
509  if (GWEN_Buffer_AllocRoom(gbuf, maxsize+1)) {
510  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
511  return -1;
512  }
513 
514  /* write value */
515  for (lj=0; lj<len; lj++)
517 
518  /* fill right */
519  for (lj=0; lj<(maxsize-len); lj++)
520  GWEN_Buffer_AppendByte(gbuf, '0');
521  }
522  else {
523  if (GWEN_Buffer_AllocRoom(gbuf, maxsize+1)) {
524  DBG_ERROR(GWEN_LOGDOMAIN, "Maxsize in XML file is higher than the buffer size");
525  return -1;
526  }
527  for (lj=0; lj<len; lj++)
529  }
530  } /* if type is num */
531  else {
532  /* TODO: Check for valids */
533  const char *p;
534  int lastWasEscape;
535  unsigned int pcount;
536 
538  pcount=0;
539  lastWasEscape=0;
540  while (*p && pcount<GWEN_Buffer_GetUsedBytes(data)) {
541  int c;
542 
543  c=(unsigned char)*p;
544  if (lastWasEscape) {
545  lastWasEscape=0;
546  switch (c) {
547  case 'r':
548  c='\r';
549  break;
550  case 'n':
551  c='\n';
552  break;
553  case 'f':
554  c='\f';
555  break;
556  case 't':
557  c='\t';
558  break;
559  default:
560  c=(unsigned char)*p;
561  } /* switch */
562  }
563  else {
564  if (*p=='\\') {
565  lastWasEscape=1;
566  c=-1;
567  }
568  else
569  c=(unsigned char)*p;
570  }
571  if (c!=-1) {
572  int needsEscape;
573 
574  needsEscape=0;
575  if (c==e->escapeChar)
576  needsEscape=1;
577  else {
578  if (e->charsToEscape)
579  if (strchr(e->charsToEscape, c))
580  needsEscape=1;
581  }
582  if (needsEscape) {
583  /* write escape char */
584  if (GWEN_Buffer_AppendByte(gbuf,
585  e->escapeChar)) {
586  return -1;
587  }
588  }
589  if (GWEN_Buffer_AppendByte(gbuf, c)) {
590  return -1;
591  }
592  }
593  p++;
594  pcount++;
595  } /* while */
596  if (pcount<GWEN_Buffer_GetUsedBytes(data)) {
597  DBG_WARN(GWEN_LOGDOMAIN, "Premature end of string (%d<%d)",
598  pcount, GWEN_Buffer_GetUsedBytes(data));
599  }
600  if (*p) {
602  "String for \"%s\" (type %s) is longer than expected "
603  "(no #0 at pos=%d)",
604  name, type,
605  GWEN_Buffer_GetUsedBytes(data)-1);
606  }
607  } /* if type is not BIN */
608  } /* if type not external */
609  else {
610  DBG_INFO(GWEN_LOGDOMAIN, "Type \"%s\" (for %s) is external (write)",
611  type, name);
612 
613  } /* if external type */
614 
615  /* fill data */
616  if (fixSize) {
617  uint32_t bs;
618  unsigned int j;
619 
620  bs=GWEN_Buffer_GetPos(gbuf)-startPos;
621  if (bs>fixSize) {
623  "Data too long (size is %d, fixed size is %d)",
624  bs, fixSize);
625  return -1;
626  }
627 
628  for (j=bs; j<fixSize; j++)
629  GWEN_Buffer_AppendByte(gbuf, (unsigned char)filler);
630  }
631 
632  return 0;
633 }
634 
635 
636 
638  const char *type)
639 {
640  if (e->typeCheckPtr) {
642 
643  vt=e->typeCheckPtr(e, type);
644  if (vt!=GWEN_DB_NodeType_Unknown) {
646  return 1;
647  }
648  }
649  return
650  (strcasecmp(type, "alpha")==0) ||
651  (strcasecmp(type, "ascii")==0) ||
652  (strcasecmp(type, "an")==0) ||
653  (strcasecmp(type, "float")==0);
654 }
655 
656 
657 
659  const char *type)
660 {
661  if (e->typeCheckPtr) {
663 
664  vt=e->typeCheckPtr(e, type);
665  if (vt!=GWEN_DB_NodeType_Unknown) {
667  return 1;
668  }
669  }
670  return
671  (strcasecmp(type, "num")==0);
672 }
673 
674 
675 
677  const char *type)
678 {
679  if (e->typeCheckPtr) {
681 
682  vt=e->typeCheckPtr(e, type);
683  if (vt!=GWEN_DB_NodeType_Unknown) {
685  return 1;
686  }
687  }
688  return
689  (strcasecmp(type, "bin")==0);
690 }
691 
692 
693 
695  GWEN_XMLNODE *node,
696  GWEN_BUFFER *mbuf)
697 {
698  /* get data from within the XML node */
699  GWEN_XMLNODE *n;
700  const char *type;
701 
702 
703  type=GWEN_XMLNode_GetProperty(node, "type", "ascii");
705  "Getting data of type \"%s\" from within XML file", type);
707  if (!n) {
708  DBG_DEBUG(GWEN_LOGDOMAIN, "No child");
709  return 1;
710  }
711 
712  if (GWEN_MsgEngine__IsBinTyp(e, type)) {
713  const char *dp;
714  //unsigned int dplen;
715  const char *stype;
716 
717  stype=GWEN_XMLNode_GetProperty(node, "storedAs", type);
718  if (GWEN_MsgEngine__IsBinTyp(e, stype)) {
719  dp=GWEN_XMLNode_GetData(n);
720  //dplen=strlen(dp);
721  if (GWEN_Text_FromHexBuffer(dp, mbuf)) {
722  DBG_INFO(GWEN_LOGDOMAIN, "here");
723  return -1;
724  }
725  } /* if stored as bin */
726  else {
727  /* stored as char */
729  }
730  } /* if binType */
731  else {
733  }
734 
735  return 0;
736 }
737 
738 
739 
740 
741 
743  GWEN_BUFFER *gbuf,
744  GWEN_XMLNODE *node,
745  GWEN_DB_NODE *gr,
746  int loopNr,
747  int isOptional,
748  GWEN_XMLNODE_PATH *nodePath)
749 {
750  const char *name;
751  const char *type;
752  //unsigned int minsize;
753  //unsigned int maxsize;
754  char numbuffer[256];
755  const char *pdata;
756  unsigned int datasize;
757  GWEN_BUFFER *data;
758  GWEN_BUFFER *tdata;
759  int handled;
760 
761  pdata=0;
762  handled=0;
763  data=0;
764  tdata=0;
765 
766  /* get type */
767  type=GWEN_XMLNode_GetProperty(node, "type", "ASCII");
768  DBG_DEBUG(GWEN_LOGDOMAIN, "Type is \"%s\"", type);
769  /* get some sizes */
770  //minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize","0"));
771  //maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize","0"));
772 
773  if (e->binTypeWritePtr &&
774  GWEN_MsgEngine__IsBinTyp(e, type) &&
775  atoi(GWEN_XMLNode_GetProperty(node, "writebin", "1"))) {
776  int rv;
777 
778  data=GWEN_Buffer_new(0,
779  64,
780  0,
781  1);
782 
783  rv=e->binTypeWritePtr(e, node, gr, data);
784  if (rv==-1) {
785  /* error */
786  DBG_INFO(GWEN_LOGDOMAIN, "called from here");
787  return -1;
788  }
789  else if (rv==0) {
790  handled=1;
791  }
792  else if (rv==1) {
793  GWEN_Buffer_free(data);
794  data=0;
795  }
796  }
797 
798  if (!handled) {
799  /* get name */
800  name=GWEN_XMLNode_GetProperty(node, "name", 0);
801  if (!name) {
802  int rv;
803 
804  /* get data from within the XML node */
805  tdata=GWEN_Buffer_new(0, 32, 0, 1);
806  GWEN_Buffer_SetStep(tdata, 256);
807  rv=GWEN_MsgEngine__GetInline(e, node, tdata);
808  if (rv==0) {
809  pdata=GWEN_Buffer_GetStart(tdata);
810  datasize=GWEN_Buffer_GetUsedBytes(tdata);
811  }
812  else {
813  GWEN_Buffer_free(tdata);
814  tdata=0;
815  pdata="";
816  datasize=0;
817  }
818  } /* if (!name) */
819  else {
820  const char *nptr;
821 
822  DBG_DEBUG(GWEN_LOGDOMAIN, "Name provided (%s), loop is %d", name, loopNr);
823  nptr=name;
824 
825  if (gr) {
827  int idata;
828 
829  /* Variable type of DB takes precedence
830  */
831  vt=GWEN_DB_GetValueTypeByPath(gr, nptr, loopNr);
832  if (vt==GWEN_DB_NodeType_Unknown) {
833  if (GWEN_MsgEngine__IsCharTyp(e, type))
835  else if (GWEN_MsgEngine__IsIntTyp(e, type))
837  else if (GWEN_MsgEngine__IsBinTyp(e, type))
839  else {
841  "Unable to determine parameter "
842  "type (%s), assuming \"char\" for this matter", type);
844  }
845  }
846 
847  /* get the value of the given var from the db */
848  switch (vt) {
850  DBG_DEBUG(GWEN_LOGDOMAIN, "Type of \"%s\" is char", name);
851  pdata=GWEN_DB_GetCharValue(gr, nptr, loopNr, 0);
852  if (pdata) {
853  DBG_DEBUG(GWEN_LOGDOMAIN, "Value of \"%s\" is %s", nptr, pdata);
854  datasize=strlen(pdata);
855  }
856  else
857  datasize=0;
858  break;
859 
861  DBG_DEBUG(GWEN_LOGDOMAIN, "Type of \"%s\" is int", name);
862  if (GWEN_DB_ValueExists(gr, nptr, loopNr)) {
863  idata=GWEN_DB_GetIntValue(gr, nptr, loopNr, 0);
864  if (-1==GWEN_Text_NumToString(idata, numbuffer,
865  sizeof(numbuffer), 0)) {
866  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
867  GWEN_Buffer_free(data);
868  return -1;
869  }
870  DBG_DEBUG(GWEN_LOGDOMAIN, "Value of \"%s\" is %d", nptr, idata);
871  pdata=numbuffer;
872  datasize=strlen(numbuffer);
873  }
874  break;
875 
877  DBG_DEBUG(GWEN_LOGDOMAIN, "Type of \"%s\" is bin", name);
878  pdata=GWEN_DB_GetBinValue(gr, nptr, loopNr, 0, 0, &datasize);
879  break;
880 
881  default:
882  DBG_WARN(GWEN_LOGDOMAIN, "Unsupported parameter type (%d)", vt);
883  break;
884  } /* switch vt */
885  } /* if gr */
886 
887  if (!pdata) {
888  GWEN_XMLNODE_PATH *copyOfNodePath;
889 
890  copyOfNodePath=GWEN_XMLNode_Path_dup(nodePath);
891 
892  /* still no data, try to get it from the XML file */
893  DBG_DEBUG(GWEN_LOGDOMAIN, "Searching for value of \"%s\"", name);
895  node, copyOfNodePath, nptr,
896  &datasize);
897  GWEN_XMLNode_Path_free(copyOfNodePath);
898  if (pdata) {
899  DBG_DEBUG(GWEN_LOGDOMAIN, "Found value of \"%s\"", name);
900  }
901  }
902 
903  if (!pdata) {
904  int rv;
905 
906  /* get data from within the XML node */
907  tdata=GWEN_Buffer_new(0, 32, 0, 1);
908  GWEN_Buffer_SetStep(tdata, 256);
909  rv=GWEN_MsgEngine__GetInline(e, node, tdata);
910  if (rv==0) {
911  pdata=GWEN_Buffer_GetStart(tdata);
912  datasize=GWEN_Buffer_GetUsedBytes(tdata);
913  }
914  else {
915  GWEN_Buffer_free(tdata);
916  tdata=0;
917  }
918  }
919 
920  if (pdata==0) {
921  if (isOptional) {
922  DBG_INFO(GWEN_LOGDOMAIN, "Value not found, omitting element \"%s[%d]\"",
923  name, loopNr);
924  GWEN_Buffer_free(data);
925  return 1;
926  }
927  else {
929  "Value for element \"%s[%d]\" (mode \"%s\") not found",
930  name, loopNr,
932  GWEN_DB_Dump(gr, 4);
933  GWEN_Buffer_free(data);
934  return -1;
935  }
936  }
937  }
938 
939  if (!data)
940  data=GWEN_Buffer_new((char *)pdata,
941  datasize,
942  datasize,
943  0 /* dont take ownership*/);
944  }
945 
946  /* write value */
948  gbuf,
949  data,
950  node)!=0) {
951  DBG_INFO(GWEN_LOGDOMAIN, "Could not write value");
952  GWEN_Buffer_free(data);
953  GWEN_Buffer_free(tdata);
954  return -1;
955  }
956  GWEN_Buffer_free(data);
957  GWEN_Buffer_free(tdata);
958 
959  return 0;
960 }
961 
962 
963 
965  const char *pname,
966  int version,
967  const char *pvalue)
968 {
969  return GWEN_MsgEngine_FindNodeByProperty(e, "GROUP", pname, version, pvalue);
970 }
971 
972 
973 
975  const char *t,
976  const char *pname,
977  int version,
978  const char *pvalue)
979 {
980  GWEN_XMLNODE *n;
981  const char *p;
982  int i;
983  const char *mode;
984  unsigned int proto;
985  char buffer[256];
986 
987  if ((strlen(t)+4)>sizeof(buffer)) {
988  DBG_ERROR(GWEN_LOGDOMAIN, "Type name too long.");
989  return 0;
990  }
991 
992  mode=GWEN_MsgEngine_GetMode(e);
994  if (!e->defs) {
995  DBG_INFO(GWEN_LOGDOMAIN, "No definitions available");
996  return 0;
997  }
998  n=e->defs;
1000 
1001  /* find type+"S" */
1002  strcpy(buffer, t);
1003  strcat(buffer, "S");
1004  while (n) {
1006  p=GWEN_XMLNode_GetData(n);
1007  assert(p);
1008  if (strcasecmp(p, buffer)==0)
1009  break;
1010  }
1011  n=GWEN_XMLNode_Next(n);
1012  } /* while */
1013 
1014  if (!n) {
1015  DBG_INFO(GWEN_LOGDOMAIN, "No definitions available for type \"%s\"", t);
1016  return 0;
1017  }
1018 
1019  /* find approppriate group definition */
1020  if (!mode)
1021  mode="";
1022  n=GWEN_XMLNode_GetChild(n);
1023  if (!n) {
1024  DBG_INFO(GWEN_LOGDOMAIN, "No definitions inside \"%s\"", buffer);
1025  return 0;
1026  }
1027 
1028  /* find type+"def" */
1029  strcpy(buffer, t);
1030  strcat(buffer, "def");
1031  while (n) {
1033  p=GWEN_XMLNode_GetData(n);
1034  assert(p);
1035  if (strcasecmp(p, buffer)==0) {
1036  p=GWEN_XMLNode_GetProperty(n, pname, "");
1037  if (strcasecmp(p, pvalue)==0) {
1038  i=atoi(GWEN_XMLNode_GetProperty(n, "pversion", "0"));
1039  if (proto==0 || (int)proto==i || i==0) {
1040  i=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
1041  if (version==0 || version==i) {
1042  p=GWEN_XMLNode_GetProperty(n, "mode", "");
1043  if (strcasecmp(p, mode)==0 || !*p) {
1044  DBG_DEBUG(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\" found",
1045  pname, pvalue);
1046  return n;
1047  }
1048  }
1049  }
1050  }
1051  }
1052  }
1053  n=GWEN_XMLNode_Next(n);
1054  } /* while */
1055 
1056  DBG_INFO(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\"(%d) not found",
1057  pname,
1058  pvalue,
1059  version);
1060  return 0;
1061 }
1062 
1063 
1064 
1066  const char *t,
1067  const char *pname,
1068  int version,
1069  const char *pvalue)
1070 {
1071  GWEN_XMLNODE *n;
1072  const char *p;
1073  int i;
1074  const char *mode;
1075  unsigned int proto;
1076  char buffer[256];
1077 
1078  if ((strlen(t)+4)>sizeof(buffer)) {
1079  DBG_ERROR(GWEN_LOGDOMAIN, "Type name too long.");
1080  return 0;
1081  }
1082 
1083  mode=GWEN_MsgEngine_GetMode(e);
1085  if (!e->defs) {
1086  DBG_INFO(GWEN_LOGDOMAIN, "No definitions available");
1087  return 0;
1088  }
1089  n=e->defs;
1090  n=GWEN_XMLNode_GetChild(n);
1091 
1092  /* find type+"S" */
1093  strcpy(buffer, t);
1094  strcat(buffer, "S");
1095  while (n) {
1097  p=GWEN_XMLNode_GetData(n);
1098  assert(p);
1099  if (strcasecmp(p, buffer)==0)
1100  break;
1101  }
1102  n=GWEN_XMLNode_Next(n);
1103  } /* while */
1104 
1105  if (!n) {
1106  DBG_INFO(GWEN_LOGDOMAIN, "No definitions available for type \"%s\"", t);
1107  return 0;
1108  }
1109 
1110  /* find approppriate group definition */
1111  if (!mode)
1112  mode="";
1113  n=GWEN_XMLNode_GetChild(n);
1114  if (!n) {
1115  DBG_INFO(GWEN_LOGDOMAIN, "No definitions inside \"%s\"", buffer);
1116  return 0;
1117  }
1118 
1119  /* find type+"def" */
1120  strcpy(buffer, t);
1121  strcat(buffer, "def");
1122  while (n) {
1124  p=GWEN_XMLNode_GetData(n);
1125  assert(p);
1126  if (strcasecmp(p, buffer)==0) {
1127  p=GWEN_XMLNode_GetProperty(n, pname, "");
1128  if (strcasecmp(p, pvalue)==0) {
1129  i=atoi(GWEN_XMLNode_GetProperty(n, "pversion", "0"));
1130  if (proto==0 || (int)proto==i) {
1131  i=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
1132  if (version==0 || version==i) {
1133  p=GWEN_XMLNode_GetProperty(n, "mode", "");
1134  if (strcasecmp(p, mode)==0 || !*p) {
1135  DBG_DEBUG(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\" found",
1136  pname, pvalue);
1137  return n;
1138  }
1139  }
1140  }
1141  }
1142  }
1143  }
1144  n=GWEN_XMLNode_Next(n);
1145  } /* while */
1146 
1147  DBG_INFO(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\"(%d) not found",
1148  pname,
1149  pvalue,
1150  version);
1151  return 0;
1152 }
1153 
1154 
1155 
1157  const char *pvalue,
1158  GWEN_XMLNODE *node,
1159  GWEN_XMLNODE *dnode,
1160  unsigned int *datasize)
1161 {
1162  const char *p;
1163  static char pbuffer[256];
1164  GWEN_DB_NODE *globalValues;
1165 
1166  globalValues=GWEN_MsgEngine__GetGlobalValues(e);
1167  assert(globalValues);
1168 
1169  if (pvalue) {
1170  DBG_DEBUG(GWEN_LOGDOMAIN, "Transforming value \"%s\"", pvalue);
1171  /* check whether the value is a property */
1172  p=pvalue;
1173  while (*p && isspace((int)*p))
1174  p++;
1175  if (*p=='$' || *p=='+') {
1176  /* global property */
1177  int incr;
1178 
1179  incr=(*p=='+');
1180  p++;
1181 
1182  DBG_DEBUG(GWEN_LOGDOMAIN, "Getting global property \"%s\"", p);
1183  if (incr) {
1184  int z;
1185 
1186  z=GWEN_DB_GetIntValue(globalValues, p, 0, 0);
1187  DBG_DEBUG(GWEN_LOGDOMAIN, "Incrementing global property \"%s\" (%d)",
1188  p, z);
1189  if (GWEN_Text_NumToString(z, pbuffer, sizeof(pbuffer), 0)<1) {
1190  DBG_ERROR(GWEN_LOGDOMAIN, "Error converting num to string");
1191  return 0;
1192  }
1193 
1194  z++;
1195  DBG_DEBUG(GWEN_LOGDOMAIN, "Setting global property \"%s\"=%d", p, z);
1196  GWEN_DB_SetIntValue(globalValues,
1199  p, z);
1200  pvalue=pbuffer;
1201  *datasize=strlen(pvalue);
1202  }
1203  else {
1204  int z;
1205  GWEN_DB_NODE_TYPE vt;
1206  const char *type = "should_be_known";
1207  /* default value; otherwise the compiler issues a warning */
1208 
1209  DBG_DEBUG(GWEN_LOGDOMAIN, "Getting global property \"%s\"", p);
1210  vt=GWEN_DB_GetVariableType(globalValues, p);
1211  if (vt==GWEN_DB_NodeType_Unknown) {
1212  if (!GWEN_DB_VariableExists(globalValues, p)) {
1213  DBG_ERROR(GWEN_LOGDOMAIN, "Unable to determine type of \"%s\"", p);
1214  return 0;
1215  }
1216  type=GWEN_XMLNode_GetProperty(dnode, "type", "ascii");
1217  if (GWEN_MsgEngine__IsCharTyp(e, type))
1219  else if (GWEN_MsgEngine__IsIntTyp(e, type))
1221  else if (GWEN_MsgEngine__IsBinTyp(e, type))
1223  else {
1225  "Unable to determine type of \"%s\" (xml)", p);
1226  return 0;
1227  }
1228  }
1229 
1230  switch (vt) {
1232  pvalue=GWEN_DB_GetCharValue(globalValues, p, 0, "");
1233  *datasize=strlen(pvalue);
1234  break;
1235 
1237  z=GWEN_DB_GetIntValue(globalValues, p, 0, 0);
1238  if (GWEN_Text_NumToString(z, pbuffer, sizeof(pbuffer), 0)<1) {
1239  DBG_ERROR(GWEN_LOGDOMAIN, "Error converting num to string");
1240  return 0;
1241  }
1242  pvalue=pbuffer;
1243  *datasize=strlen(pvalue);
1244  break;
1245 
1247  pvalue=GWEN_DB_GetBinValue(globalValues, p, 0,
1248  0, 0,
1249  datasize);
1250  break;
1251 
1252  default:
1253  DBG_ERROR(GWEN_LOGDOMAIN, "Unknown type %s", type);
1254  return 0;
1255  } /* switch */
1256  }
1257  DBG_DEBUG(GWEN_LOGDOMAIN, "Value transformed");
1258  }
1259  else if (*p=='%') {
1260  /* local property */
1261  p++;
1262 
1263  DBG_DEBUG(GWEN_LOGDOMAIN, "Getting property \"%s\"", p);
1264  pvalue=GWEN_XMLNode_GetProperty(node, p, 0);
1265  if (pvalue) {
1266  *datasize=strlen(pvalue);
1267  DBG_DEBUG(GWEN_LOGDOMAIN, "Transformed value \"%s\"", pvalue);
1268  }
1269  else
1270  *datasize=0;
1271  }
1272  else if (*p=='?') {
1273  GWEN_DB_NODE_TYPE vt;
1274  int z;
1275  const char *dtype;
1276 
1277  /* get type */
1278  dtype=GWEN_XMLNode_GetProperty(dnode, "type", "ASCII");
1279 
1280  /* program variable accessable via callback */
1281  p++;
1282  DBG_DEBUG(GWEN_LOGDOMAIN, "Getting program variable \"%s\"", p);
1283 
1284  pvalue=0;
1285  if (GWEN_MsgEngine__IsCharTyp(e, dtype))
1287  else if (GWEN_MsgEngine__IsIntTyp(e, dtype))
1289  else {
1291  }
1292 
1293  switch (vt) {
1295  if (e->getCharValuePtr) {
1296  pvalue=e->getCharValuePtr(e, p, 0);
1297  if (pvalue)
1298  *datasize=strlen(pvalue);
1299  }
1300  break;
1301 
1303  if (e->getIntValuePtr) {
1304  z=e->getIntValuePtr(e, p, 0);
1305  if (GWEN_Text_NumToString(z, pbuffer, sizeof(pbuffer), 0)<1) {
1306  DBG_ERROR(GWEN_LOGDOMAIN, "Error converting num to string");
1307  return 0;
1308  }
1309  pvalue=pbuffer;
1310  *datasize=strlen(pvalue);
1311  }
1312  else {
1313  DBG_NOTICE(GWEN_LOGDOMAIN, "Callback for getIntValue not set");
1314  }
1315  break;
1316 
1317  default:
1318  DBG_ERROR(GWEN_LOGDOMAIN, "Unhandled type %s", dtype);
1319  return 0;
1320  } /* switch */
1321 
1322  DBG_DEBUG(GWEN_LOGDOMAIN, "Value transformed");
1323  }
1324  else {
1325  *datasize=strlen(pvalue);
1326  }
1327  }
1328  return pvalue;
1329 }
1330 
1331 
1332 
1334  GWEN_XMLNODE *refnode,
1335  const char *name,
1336  int topDown)
1337 {
1338  const char *pvalue;
1339  GWEN_XMLNODE *pn;
1340  const char *lastValue;
1341 
1342  DBG_DEBUG(GWEN_LOGDOMAIN, "Searching for value of \"%s\" in properties", name);
1343  lastValue=0;
1344 
1345  pvalue=GWEN_XMLNode_GetProperty(node, name, 0);
1346  if (pvalue) {
1347  if (!topDown)
1348  return pvalue;
1349  DBG_DEBUG(GWEN_LOGDOMAIN, "Found a value (%s), but will look further", pvalue);
1350  lastValue=pvalue;
1351  }
1352 
1353  pn=refnode;
1354  while (pn) {
1355  pvalue=GWEN_XMLNode_GetProperty(pn, name, 0);
1356  if (pvalue) {
1357  if (!topDown)
1358  return pvalue;
1359  DBG_DEBUG(GWEN_LOGDOMAIN, "Found a value (%s), but will look further", pvalue);
1360  lastValue=pvalue;
1361  }
1362  pn=GWEN_XMLNode_GetParent(pn);
1363  } /* while */
1364  return lastValue;
1365 }
1366 
1367 
1368 
1370  GWEN_XMLNODE *refnode)
1371 {
1372  int value;
1373  GWEN_XMLNODE *pn;
1374  int highestTrust;
1375 
1376  highestTrust=0;
1377 
1378  value=atoi(GWEN_XMLNode_GetProperty(node, "trustlevel", "0"));
1379  if (value>highestTrust)
1380  highestTrust=value;
1381 
1382  pn=node;
1383  while (pn) {
1384  value=atoi(GWEN_XMLNode_GetProperty(pn, "trustlevel", "0"));
1385  if (value>highestTrust)
1386  highestTrust=value;
1387  pn=GWEN_XMLNode_GetParent(pn);
1388  } /* while */
1389 
1390  pn=refnode;
1391  while (pn) {
1392  value=atoi(GWEN_XMLNode_GetProperty(pn, "trustlevel", "0"));
1393  if (value>highestTrust)
1394  highestTrust=value;
1395  pn=GWEN_XMLNode_GetParent(pn);
1396  } /* while */
1397  return highestTrust;
1398 }
1399 
1400 
1401 
1403  GWEN_XMLNODE *node,
1404  GWEN_XMLNODE_PATH *nodePath,
1405  const char *name,
1406  unsigned int *datasize)
1407 {
1408  const char *pvalue;
1409  GWEN_XMLNODE *pn;
1410  char *bufferPtr;
1411  int topDown;
1412  const char *lastValue;
1413  unsigned int lastDataSize;
1414  unsigned int ldatasize;
1415 
1416  DBG_DEBUG(GWEN_LOGDOMAIN, "Searching for value of \"%s\" in <VALUES>",
1417  name);
1418  if (!node) {
1419  DBG_WARN(GWEN_LOGDOMAIN, "No node !");
1420  }
1421  topDown=atoi(GWEN_XMLNode_GetProperty(node, "topdown", "0"));
1422  lastValue=0;
1423  lastDataSize=0;
1424 
1425  bufferPtr=0;
1426 
1427  /*pn=GWEN_XMLNode_GetParent(node);*/
1428  pn=GWEN_XMLNode_Path_Surface(nodePath);
1429  while (pn) {
1430  const char *ppath;
1431  /*
1432  if (GWEN_XMLNode_GetType(pn)==GWEN_XMLNodeTypeTag) {
1433  DBG_NOTICE(GWEN_LOGDOMAIN, "Checking node \"%s\"",
1434  GWEN_XMLNode_GetData(pn));
1435  }*/
1436  pvalue=GWEN_MsgEngine__findInValues(e, pn, node, name, &ldatasize);
1437  if (pvalue) {
1438  if (!topDown) {
1439  free(bufferPtr);
1440  *datasize=ldatasize;
1441  return pvalue;
1442  }
1443  DBG_DEBUG(GWEN_LOGDOMAIN, "Found a value, but will look further");
1444  lastValue=pvalue;
1445  lastDataSize=ldatasize;
1446  }
1447 
1448  ppath=GWEN_XMLNode_GetProperty(pn, "name", "");
1449 
1450  if (*ppath) {
1451  int i;
1452  char *tmpptr;
1453 
1454  if (bufferPtr) {
1455  i=strlen(bufferPtr)+strlen(ppath)+2;
1456  tmpptr=(char *)malloc(i);
1457  assert(tmpptr);
1458  sprintf(tmpptr, "%s/%s", ppath, bufferPtr);
1459  free(bufferPtr);
1460  bufferPtr=tmpptr;
1461  }
1462  else {
1463  i=strlen(ppath)+strlen(name)+2;
1464  tmpptr=(char *)malloc(i);
1465  assert(tmpptr);
1466  sprintf(tmpptr, "%s/%s", ppath, name);
1467  bufferPtr=tmpptr;
1468  }
1469  name=bufferPtr;
1470  }
1471  pn=GWEN_XMLNode_Path_Surface(nodePath);
1472  } /* while */
1473 
1474  free(bufferPtr);
1475  if (!lastValue)
1476  *datasize=0;
1477  else
1478  *datasize=lastDataSize;
1479  return lastValue;
1480 }
1481 
1482 
1483 
1485  GWEN_XMLNODE *node,
1486  GWEN_XMLNODE *dnode,
1487  const char *name,
1488  unsigned int *datasize)
1489 {
1490  GWEN_XMLNODE *pn;
1491 
1492  DBG_VERBOUS(GWEN_LOGDOMAIN, "Looking for value of \"%s\" in <VALUES>", name);
1493  pn=GWEN_XMLNode_GetChild(node);
1494 
1495  while (pn) {
1497  GWEN_XMLNODE *n;
1498  const char *p;
1499 
1500  p=GWEN_XMLNode_GetData(pn);
1501  assert(p);
1502  DBG_DEBUG(GWEN_LOGDOMAIN, "Checking %s", p);
1503  if (strcasecmp(p, "VALUES")==0) {
1504  DBG_DEBUG(GWEN_LOGDOMAIN, "<values> found");
1505  /* <preset> found, check all values */
1506  n=GWEN_XMLNode_GetChild(pn);
1507  while (n) {
1509  p=GWEN_XMLNode_GetData(n);
1510  assert(p);
1511  if (strcasecmp(p, "VALUE")==0) {
1512  const char *pname;
1513  const char *pvalue;
1514 
1515  pname=GWEN_XMLNode_GetProperty(n, "path", 0);
1516  if (pname) {
1517  DBG_DEBUG(GWEN_LOGDOMAIN, "Comparing against \"%s\"", pname);
1518  if (strcasecmp(name, pname)==0) {
1519  GWEN_XMLNODE *dn;
1520 
1521  dn=GWEN_XMLNode_GetChild(n);
1522  while (dn) {
1524  pvalue=GWEN_XMLNode_GetData(dn);
1525  if (pvalue) {
1526  DBG_DEBUG(GWEN_LOGDOMAIN, "Transforming \"%s\"", pvalue);
1528  pvalue,
1529  node,
1530  dnode,
1531  datasize);
1532  }
1533  if (pvalue)
1534  return pvalue;
1535  }
1536  dn=GWEN_XMLNode_Next(dn);
1537  } /* while dn */
1538  } /* if path matches name */
1539  } /* if path given */
1540  } /* if VALUE tag */
1541  } /* if TAG */
1542  n=GWEN_XMLNode_Next(n);
1543  } /* while */
1544  break; /* REMOVE this to check multiple groups */
1545  } /* if <preset> found */
1546  } /* if tag */
1547  pn=GWEN_XMLNode_Next(pn);
1548  } /* while node */
1549 
1550  DBG_DEBUG(GWEN_LOGDOMAIN, "No value found for \"%s\" in <VALUES>", name);
1551  return 0;
1552 }
1553 
1554 
1555 
1557  GWEN_XMLNODE *node,
1558  const char *t,
1559  int version,
1560  const char *pvalue)
1561 {
1562  GWEN_XMLNODE *n;
1563  const char *p;
1564  int i;
1565  const char *mode;
1566  unsigned int proto;
1567  char buffer[256];
1568 
1569  if ((strlen(t)+4)>sizeof(buffer)) {
1570  DBG_ERROR(GWEN_LOGDOMAIN, "Type name too long.");
1571  return 0;
1572  }
1573 
1574  mode=GWEN_MsgEngine_GetMode(e);
1576 
1577  /* find type+"S" */
1578  strcpy(buffer, t);
1579  strcat(buffer, "S");
1580  n=GWEN_XMLNode_FindFirstTag(node, buffer, 0, 0);
1581  if (!n) {
1583  "No definitions here for type \"%s\"", t);
1584  return 0;
1585  }
1586 
1587  /* find approppriate group definition */
1588  if (!mode)
1589  mode="";
1591  if (!n) {
1592  DBG_INFO(GWEN_LOGDOMAIN, "No definitions inside \"%s\"", buffer);
1593  return 0;
1594  }
1595 
1596  /* find type+"def" */
1597  strcpy(buffer, t);
1598  strcat(buffer, "def");
1599  while (n) {
1600  p=GWEN_XMLNode_GetData(n);
1601  assert(p);
1602  if (strcasecmp(p, buffer)==0 ||
1603  strcasecmp(p, t)==0) {
1604  p=GWEN_XMLNode_GetProperty(n, "id", "");
1605  if (strcasecmp(p, pvalue)!=0)
1606  p=GWEN_XMLNode_GetProperty(n, "name", "");
1607  if (strcasecmp(p, pvalue)==0) {
1608  i=atoi(GWEN_XMLNode_GetProperty(n, "pversion", "0"));
1609  if (proto==0 || (int)proto==i || i==0) {
1610  i=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
1611  if (version==0 || version==i) {
1612  p=GWEN_XMLNode_GetProperty(n, "mode", "");
1613  if (strcasecmp(p, mode)==0 || !*p) {
1615  "Group definition for \"%s=%s\" found",
1616  t, pvalue);
1617  return n;
1618  }
1619  }
1620  }
1621  }
1622  }
1624  } /* while */
1625 
1627  "Group definition for \"%s=%s\"(%d) not found here",
1628  t,
1629  pvalue,
1630  version);
1631  return 0;
1632 }
1633 
1634 
1635 
1637  GWEN_XMLNODE *node,
1638  const GWEN_XMLNODE_PATH *nodePath,
1639  const char *t,
1640  int version,
1641  const char *pvalue)
1642 {
1643  GWEN_XMLNODE *n;
1644  GWEN_XMLNODE *nLast = 0;
1645  GWEN_XMLNODE *nRes = 0;
1646  GWEN_XMLNODE_PATH *pathCopy;
1647 
1648  assert(node);
1649  assert(nodePath);
1650  assert(t);
1651  assert(pvalue);
1652 
1653  pathCopy=GWEN_XMLNode_Path_dup(nodePath);
1654  n=GWEN_XMLNode_Path_Surface(pathCopy);
1655  /* first try all nodes along the path */
1656  while (n) {
1657  nLast=n;
1658  nRes=GWEN_MsgEngine__GetGroup(e, n, t, version, pvalue);
1659  if (nRes)
1660  break;
1661  n=GWEN_XMLNode_Path_Surface(pathCopy);
1662  }
1663  GWEN_XMLNode_Path_free(pathCopy);
1664  if (nRes) {
1665  /* already found */
1666  if (nRes==node) {
1667  DBG_ERROR(GWEN_LOGDOMAIN, "Loop detected.");
1668  return 0;
1669  }
1670  return nRes;
1671  }
1672 
1673  if (nLast)
1674  n=nLast;
1675  else
1676  n=node;
1677 
1678  if (n) {
1680  while (n) {
1681  nRes=GWEN_MsgEngine__GetGroup(e, n, t, version, pvalue);
1682  if (nRes)
1683  break;
1685  }
1686  }
1687 
1688  /* try root as a last resort */
1689  if (!nRes && e->defs)
1690  nRes=GWEN_MsgEngine__GetGroup(e, e->defs, t, version, pvalue);
1691 
1692  if (!nRes) {
1694  "Group definition for \"%s=%s\"(%d) not found",
1695  t,
1696  pvalue,
1697  version);
1698  return 0;
1699  }
1700  if (nRes==node) {
1701  DBG_ERROR(GWEN_LOGDOMAIN, "Loop detected.");
1702  return 0;
1703  }
1704  return nRes;
1705 }
1706 
1707 
1708 
1710  GWEN_BUFFER *gbuf,
1711  GWEN_XMLNODE *node,
1712  GWEN_XMLNODE *rnode,
1713  GWEN_DB_NODE *gr,
1714  int groupIsOptional,
1715  GWEN_XMLNODE_PATH *nodePath)
1716 {
1717  GWEN_XMLNODE *n;
1718  const char *p;
1719  char delimiter;
1720  char terminator;
1721  int isFirstElement;
1722  int omittedElements;
1723  int hasEntries;
1724 
1725 
1726  /* get some settings */
1727  if (rnode) {
1728  /* get delimiter */
1729  p=GWEN_XMLNode_GetProperty(rnode,
1730  "delimiter",
1732  "delimiter",
1733  ""));
1734  delimiter=*p;
1735 
1736  /* get terminating char, if any */
1737  p=GWEN_XMLNode_GetProperty(rnode,
1738  "terminator",
1740  "terminator",
1741  ""));
1742  terminator=*p;
1743  }
1744  else {
1745  /* get delimiter */
1746  p=GWEN_XMLNode_GetProperty(node,
1747  "delimiter",
1748  "");
1749  delimiter=*p;
1750 
1751  /* get terminating char, if any */
1752  p=GWEN_XMLNode_GetProperty(node, "terminator", "");
1753  terminator=*p;
1754  }
1755 
1756  /* handle all child entries */
1757  n=GWEN_XMLNode_GetChild(node);
1758  isFirstElement=1;
1759  omittedElements=0;
1760  hasEntries=0;
1761  if (!n) {
1762  DBG_INFO(GWEN_LOGDOMAIN, "No subnodes !");
1763  }
1764  while (n) {
1765  int t;
1766  unsigned int minnum;
1767  unsigned int maxnum;
1768  int gversion;
1769  const char *addEmptyMode;
1770  unsigned int loopNr;
1771 
1772  minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum", "1"));
1773  maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum", "1"));
1774  gversion=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
1775  addEmptyMode=GWEN_XMLNode_GetProperty(n, "addemptymode", "one");
1776 
1777  DBG_DEBUG(GWEN_LOGDOMAIN, "Omitted elements: %d", omittedElements);
1778  t=GWEN_XMLNode_GetType(n);
1779  if (t==GWEN_XMLNodeTypeTag) {
1780  const char *typ;
1781 
1782  typ=GWEN_XMLNode_GetData(n);
1783  if (typ==0) {
1784  DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed tag found (internal error?)");
1785  return -1;
1786  }
1787  if (strcasecmp(typ, "ELEM")==0) {
1788  /* element tag found */
1789  int j;
1790  int rv;
1791 
1792  DBG_VERBOUS(GWEN_LOGDOMAIN, "Found an element");
1793  /* write element as often as needed */
1794  for (loopNr=0; loopNr<maxnum; loopNr++) {
1795  unsigned int posBeforeElement;
1796 
1797  posBeforeElement=GWEN_Buffer_GetPos(gbuf);
1798 
1799  /* write delimiter, if needed */
1800  if (delimiter) {
1801  DBG_VERBOUS(GWEN_LOGDOMAIN, "Appending %d delimiters",
1802  omittedElements);
1803  for (j=0; j<omittedElements; j++) {
1804  if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
1805  DBG_INFO(GWEN_LOGDOMAIN, "called from here");
1806  return -1;
1807  }
1808  }
1809  if (!isFirstElement)
1810  if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
1811  DBG_INFO(GWEN_LOGDOMAIN, "called from here");
1812  return -1;
1813  }
1814  }
1815 
1817  gbuf,
1818  n,
1819  gr,
1820  loopNr,
1821  loopNr>=minnum ||
1822  (groupIsOptional && !hasEntries),
1823  nodePath);
1824  if (rv==-1) {
1825  DBG_INFO(GWEN_LOGDOMAIN, "Error writing element");
1826  DBG_INFO(GWEN_LOGDOMAIN, "Node is:");
1827  GWEN_XMLNode_Dump(n, 1);
1828  if (gr) {
1829  DBG_INFO(GWEN_LOGDOMAIN, "Data is:");
1830  GWEN_DB_Dump(gr, 1);
1831  }
1832  return -1;
1833  }
1834  else if (rv==0) {
1835  isFirstElement=0;
1836  omittedElements=0;
1837  hasEntries=1;
1838  DBG_DEBUG(GWEN_LOGDOMAIN, "Element written");
1839  }
1840  else {
1841  /* element is optional, not found */
1842  /* restore position */
1843  GWEN_Buffer_SetPos(gbuf, posBeforeElement);
1844  GWEN_Buffer_Crop(gbuf, 0, posBeforeElement);
1845 
1846  if (strcasecmp(addEmptyMode, "max")==0) {
1847  DBG_DEBUG(GWEN_LOGDOMAIN, "Adding max empty");
1848  omittedElements+=(maxnum-loopNr);
1849  }
1850  else if (strcasecmp(addEmptyMode, "min")==0) {
1851  DBG_DEBUG(GWEN_LOGDOMAIN, "Adding min empty");
1852  if (loopNr<minnum)
1853  omittedElements+=(minnum-loopNr);
1854  }
1855  else if (strcasecmp(addEmptyMode, "one")==0) {
1856  if (loopNr==0)
1857  omittedElements++;
1858  }
1859  else if (strcasecmp(addEmptyMode, "none")==0) {
1860  }
1861  else {
1862  DBG_ERROR(GWEN_LOGDOMAIN, "Unknown addemptymode \"%s\"",
1863  addEmptyMode);
1864  return -1;
1865  }
1866  break;
1867  }
1868  } /* for */
1869  }
1870  else if (strcasecmp(typ, "VALUES")==0) {
1871  }
1872  else if (strcasecmp(typ, "DESCR")==0) {
1873  }
1874  else {
1875  /* group tag found */
1876  GWEN_XMLNODE *gn;
1877  GWEN_DB_NODE *gcfg;
1878  const char *gname;
1879  const char *gtype;
1880  unsigned int posBeforeGroup;
1881 
1882  DBG_VERBOUS(GWEN_LOGDOMAIN, "Found a group");
1883 
1884  gcfg=0;
1885  gtype=GWEN_XMLNode_GetProperty(n, "type", 0);
1886  if (!gtype) {
1887  /* no "type" property, so use this group directly */
1888  DBG_INFO(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", typ);
1889  gtype="";
1890  gn=n;
1891  }
1892  else {
1893  DBG_VERBOUS(GWEN_LOGDOMAIN, "<%s> tag is of type \"%s\"", typ, gtype);
1894  gn=GWEN_MsgEngine_GetGroup(e, n, nodePath, typ,
1895  gversion, gtype);
1896  if (!gn) {
1897  DBG_INFO(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", typ);
1898  return -1;
1899  }
1900  }
1901 
1902  gname=NULL;
1903  gcfg=NULL;
1904  if (gr) {
1905  gname=GWEN_XMLNode_GetProperty(n, "name", 0);
1906  if (gname) {
1907  DBG_VERBOUS(GWEN_LOGDOMAIN, "Group \"%s\" using special data", gname);
1908  gcfg=GWEN_DB_FindFirstGroup(gr, gname);
1909  }
1910  else {
1911  DBG_DEBUG(GWEN_LOGDOMAIN, "Unnamed group, using basic data");
1912  /* TODO: check for maxnum==1, since only then the following line makes sense */
1913  gcfg=gr;
1914  }
1915  }
1916 
1917  /* write group as often as needed */
1918  for (loopNr=0; loopNr<maxnum; loopNr++) {
1919  int rv;
1920  int groupIsEmpty;
1921 
1922  groupIsEmpty=0;
1923  posBeforeGroup=GWEN_Buffer_GetPos(gbuf);
1924 
1925  /* write delimiter, if needed */
1926  if (delimiter) {
1927  int j;
1928 
1929  DBG_VERBOUS(GWEN_LOGDOMAIN, "Appending %d delimiters",
1930  omittedElements);
1931  for (j=0; j<omittedElements; j++) {
1932  if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
1933  DBG_INFO(GWEN_LOGDOMAIN, "called from here");
1934  return -1;
1935  }
1936  }
1937  if (!isFirstElement)
1938  if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
1939  DBG_INFO(GWEN_LOGDOMAIN, "called from here");
1940  return -1;
1941  }
1942  }
1943 
1944  /* find next matching group */
1945  if (gcfg==0) {
1946  DBG_DEBUG(GWEN_LOGDOMAIN, "No group found");
1947  if (loopNr>=minnum)
1948  groupIsEmpty=1;
1949  }
1950 
1951  if (groupIsEmpty) {
1952  /* empty group, flag as such */
1953  rv=1;
1954  }
1955  else {
1956  int dive;
1957 
1958  /* write group */
1959  if (GWEN_XMLNode_Path_Dive(nodePath, n)) {
1960  DBG_INFO(GWEN_LOGDOMAIN, "Called from here");
1961  return -1;
1962  }
1963  if (n==gn)
1964  dive=1;
1965  else {
1966  if (GWEN_XMLNode_Path_Dive(nodePath, gn)) {
1967  DBG_INFO(GWEN_LOGDOMAIN, "Called from here");
1968  return -1;
1969  }
1970  dive=2;
1971  }
1973  gbuf,
1974  gn,
1975  n,
1976  gcfg,
1977  loopNr>=minnum || groupIsOptional,
1978  nodePath);
1979  GWEN_XMLNode_Path_Surface(nodePath);
1980  if (dive==2)
1981  GWEN_XMLNode_Path_Surface(nodePath);
1982  }
1983 
1984  if (rv==-1) {
1985  DBG_INFO(GWEN_LOGDOMAIN, "Could not write group \"%s\"", gtype);
1986  if (gn) {
1987  DBG_INFO(GWEN_LOGDOMAIN, "Node is:");
1988  GWEN_XMLNode_Dump(gn, 1);
1989  }
1990  if (n) {
1991  DBG_INFO(GWEN_LOGDOMAIN, "Referring node is:");
1992  GWEN_XMLNode_Dump(n, 1);
1993  }
1994  if (gr) {
1995  DBG_INFO(GWEN_LOGDOMAIN, "Data is:");
1996  GWEN_DB_Dump(gr, 1);
1997  }
1998  return -1;
1999  }
2000  else if (rv==0) {
2001  isFirstElement=0;
2002  omittedElements=0;
2003  hasEntries=1;
2004  DBG_DEBUG(GWEN_LOGDOMAIN, "Element written");
2005  }
2006  else {
2007  /* group is optional, not found */
2008  /* restore position */
2009  GWEN_Buffer_SetPos(gbuf, posBeforeGroup);
2010  GWEN_Buffer_Crop(gbuf, 0, posBeforeGroup);
2011 
2012  if (strcasecmp(addEmptyMode, "max")==0) {
2013  DBG_DEBUG(GWEN_LOGDOMAIN, "Adding max empty");
2014  omittedElements+=(maxnum-loopNr);
2015  }
2016  else if (strcasecmp(addEmptyMode, "min")==0) {
2017  DBG_DEBUG(GWEN_LOGDOMAIN, "Adding min empty");
2018  if (loopNr<minnum)
2019  omittedElements+=(minnum-loopNr);
2020  }
2021  else if (strcasecmp(addEmptyMode, "one")==0) {
2022  if (loopNr==0)
2023  omittedElements++;
2024  }
2025  else if (strcasecmp(addEmptyMode, "none")==0) {
2026  }
2027  else {
2028  DBG_ERROR(GWEN_LOGDOMAIN, "Unknown addemptymode \"%s\"",
2029  addEmptyMode);
2030  return -1;
2031  }
2032  break;
2033  }
2034 
2035  /* use next group next time if any */
2036  if (gcfg && gname)
2037  gcfg=GWEN_DB_FindNextGroup(gcfg, gname);
2038  } /* for */
2039  } /* if "GROUP" */
2040  } /* if TAG */
2041  else if (t==GWEN_XMLNodeTypeData) {
2042  }
2043  else {
2044  DBG_DEBUG(GWEN_LOGDOMAIN, "Unhandled node type %d", t);
2045  }
2046  n=GWEN_XMLNode_Next(n);
2047  } /* while */
2048 
2049  /* write terminating character, if any */
2050  if (terminator) {
2051  if (GWEN_Buffer_AppendByte(gbuf, terminator)) {
2052  DBG_INFO(GWEN_LOGDOMAIN, "called from here");
2053  return -1;
2054  }
2055  }
2056 
2057  if (!hasEntries) {
2058  DBG_INFO(GWEN_LOGDOMAIN, "No entries in node");
2059  }
2060  return hasEntries?0:1;
2061 }
2062 
2063 
2064 
2066  GWEN_XMLNODE *node,
2067  GWEN_BUFFER *gbuf,
2068  GWEN_DB_NODE *msgData)
2069 {
2070  GWEN_XMLNODE_PATH *np;
2071  int rv;
2072 
2073  assert(e);
2074  assert(node);
2075  assert(msgData);
2076 
2077  np=GWEN_XMLNode_Path_new();
2078  GWEN_XMLNode_Path_Dive(np, node);
2080  gbuf,
2081  node,
2082  0,
2083  msgData,
2084  0,
2085  np);
2087  if (rv) {
2088  const char *p;
2089 
2090  p=GWEN_XMLNode_GetData(node);
2091  if (p) {
2092  DBG_INFO(GWEN_LOGDOMAIN, "Error writing group \"%s\"", p);
2093  }
2094  else {
2095  DBG_INFO(GWEN_LOGDOMAIN, "Error writing group");
2096  }
2097  return -1;
2098  }
2099 
2100  return 0;
2101 }
2102 
2103 
2104 
2106  const char *msgName,
2107  int msgVersion,
2108  GWEN_BUFFER *gbuf,
2109  GWEN_DB_NODE *msgData)
2110 {
2111  GWEN_XMLNODE *group;
2112 
2113  group=GWEN_MsgEngine_FindGroupByProperty(e, "id", msgVersion, msgName);
2114  if (!group) {
2115  DBG_ERROR(GWEN_LOGDOMAIN, "Group \"%s\" not found\n", msgName);
2116  return -1;
2117  }
2119  group,
2120  gbuf,
2121  msgData);
2122 }
2123 
2124 
2125 
2127  GWEN_XMLNODE *node)
2128 {
2129  GWEN_XMLNODE *nsrc, *ndst;
2130 
2131  assert(e);
2132  assert(node);
2133 
2134  if (!e->defs) {
2135  e->defs=GWEN_XMLNode_dup(node);
2136  e->ownDefs=1;
2137  return 0;
2138  }
2139 
2140  nsrc=GWEN_XMLNode_GetChild(node);
2141  while (nsrc) {
2144  GWEN_XMLNode_GetData(nsrc));
2145  if (ndst) {
2146  GWEN_XMLNODE *n;
2147 
2148  n=GWEN_XMLNode_GetChild(nsrc);
2149  while (n) {
2150  GWEN_XMLNODE *newNode;
2151 
2152  DBG_DEBUG(GWEN_LOGDOMAIN, "Adding node \"%s\"", GWEN_XMLNode_GetData(n));
2153  newNode=GWEN_XMLNode_dup(n);
2154  GWEN_XMLNode_AddChild(ndst, newNode);
2155  n=GWEN_XMLNode_Next(n);
2156  } /* while n */
2157  }
2158  else {
2159  GWEN_XMLNODE *newNode;
2160 
2161  DBG_DEBUG(GWEN_LOGDOMAIN, "Adding branch \"%s\"", GWEN_XMLNode_GetData(nsrc));
2162  newNode=GWEN_XMLNode_dup(nsrc);
2163  GWEN_XMLNode_AddChild(e->defs, newNode);
2164  }
2165  } /* if TAG */
2166  nsrc=GWEN_XMLNode_Next(nsrc);
2167  } /* while */
2168 
2169  return 0;
2170 }
2171 
2172 
2173 
2175  const char *path,
2176  GWEN_XMLNODE *node,
2177  GWEN_STRINGLIST *sl,
2178  uint32_t flags)
2179 {
2180  const char *name;
2181  const char *type;
2182  const char *npath;
2183  unsigned int minsize;
2184  unsigned int maxsize;
2185  unsigned int minnum;
2186  unsigned int maxnum;
2187  int j;
2188  int isSet;
2189  char nbuffer[256];
2191 
2192  /* get type */
2193  type=GWEN_XMLNode_GetProperty(node, "type", "ASCII");
2194 
2195  /* get some sizes */
2196  minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize", "0"));
2197  maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize", "0"));
2198  minnum=atoi(GWEN_XMLNode_GetProperty(node, "minnum", "1"));
2199  maxnum=atoi(GWEN_XMLNode_GetProperty(node, "maxnum", "1"));
2200 
2201  npath="";
2202  isSet=0;
2203 
2204  /* get name */
2205  name=GWEN_XMLNode_GetProperty(node, "name", 0);
2206  if (path==0)
2207  path="";
2208 
2209  if (name) {
2210  /* get value of a config variable */
2211  if (strlen(path)+strlen(name)+10>=sizeof(nbuffer)) {
2212  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2213  return -1;
2214  }
2215  if (*path)
2216  sprintf(nbuffer, "%s/%s", path, name);
2217  else
2218  sprintf(nbuffer, "%s", name);
2219  npath=nbuffer;
2220  }
2221 
2223  while (en) {
2224  if (GWEN_StringListEntry_Data(en))
2225  if (strcasecmp(GWEN_StringListEntry_Data(en), npath)==0) {
2226  isSet=1;
2227  break;
2228  }
2230  } /* while */
2231 
2232  if (isSet && (flags & GWEN_MSGENGINE_SHOW_FLAGS_NOSET))
2233  return 0;
2234 
2235  fprintf(stdout, " %s",
2236  npath);
2237  j=GWEN_MSGENGINE_VARNAME_WIDTH-strlen(npath);
2238  if (j>0) {
2239  int i;
2240 
2241  for (i=0; i<j; i++)
2242  fprintf(stdout, " ");
2243  }
2244  fprintf(stdout, "| %s", type);
2245  j=GWEN_MSGENGINE_TYPENAME_WIDTH-strlen(type);
2246  if (j>0) {
2247  int i;
2248 
2249  for (i=0; i<j; i++)
2250  fprintf(stdout, " ");
2251  }
2252  fprintf(stdout, "| %4d-%4d", minsize, maxsize);
2253  fprintf(stdout, " | %3d ", maxnum);
2254  fprintf(stdout, " |");
2255  if (minnum==0)
2256  fprintf(stdout, " optvar");
2257  if (flags & GWEN_MSGENGINE_SHOW_FLAGS_OPTIONAL)
2258  fprintf(stdout, " optgrp");
2259 
2260  if (isSet) {
2261  fprintf(stdout, " set");
2262  }
2263 
2264  fprintf(stdout, "\n");
2265 
2266  return 0;
2267 }
2268 
2269 
2270 
2272  const char *path,
2273  GWEN_XMLNODE *node,
2274  GWEN_STRINGLIST *sl,
2275  uint32_t flags)
2276 {
2277  GWEN_XMLNODE *n;
2278  //int isFirstElement;
2279  /*int omittedElements;*/
2280  int rv;
2281 
2282  /* setup data */
2283  n=GWEN_XMLNode_GetChild(node);
2284 
2285  if (path==0)
2286  path="";
2287  if (*path=='/')
2288  path++;
2289 
2290  while (n) {
2292  const char *p;
2293 
2294  p=GWEN_XMLNode_GetData(n);
2295  assert(p);
2296  DBG_DEBUG(GWEN_LOGDOMAIN, "Checking %s", p);
2297  if (strcasecmp(p, "VALUES")==0)
2298  break;
2299  } /* if tag */
2300  n=GWEN_XMLNode_Next(n);
2301  } /* while */
2302 
2303  if (n) {
2304  DBG_DEBUG(GWEN_LOGDOMAIN, "<preset> found");
2305  /* <preset> found, handle all values */
2306  n=GWEN_XMLNode_GetChild(n);
2307  while (n) {
2309  const char *p;
2310 
2311  p=GWEN_XMLNode_GetData(n);
2312  assert(p);
2313  if (strcasecmp(p, "VALUE")==0) {
2314  const char *pname;
2315  const char *pvalue;
2316 
2317  pname=GWEN_XMLNode_GetProperty(n, "path", 0);
2318  if (pname) {
2319  GWEN_XMLNODE *dn;
2320 
2321  /* path found, find data */
2322  dn=GWEN_XMLNode_GetChild(n);
2323  while (dn) {
2325  pvalue=GWEN_XMLNode_GetData(dn);
2326  if (pvalue) {
2327  char pbuffer[256];
2328 
2329  /* check whether the value is a property */
2330  p=pvalue;
2331  while (*p && isspace((int)*p))
2332  p++;
2333  if (strlen(path)+strlen(pname)+2>sizeof(pbuffer)) {
2334  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2335  return -1;
2336  }
2337  if (*path)
2338  sprintf(pbuffer, "%s/%s", path, pname);
2339  else
2340  sprintf(pbuffer, "%s", pname);
2342  pbuffer,
2343  0,
2344  1);
2345  }
2346  break;
2347  }
2348  dn=GWEN_XMLNode_Next(dn);
2349  } /* while dn */
2350  } /* if path given */
2351  } /* if VALUE tag */
2352  } /* if TAG */
2353  n=GWEN_XMLNode_Next(n);
2354  } /* while */
2355  } /* if <preset> found */
2356 
2357  /* now handle all child entries */
2358  n=GWEN_XMLNode_GetChild(node);
2359  //isFirstElement=1;
2360  /*omittedElements=0;*/
2361  while (n) {
2362  int t;
2363  unsigned int minnum;
2364  unsigned int maxnum;
2365  int gversion;
2366  //const char *addEmptyMode;
2367  unsigned int loopNr;
2368  unsigned int lflags;
2369 
2370  minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum", "1"));
2371  maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum", "1"));
2372  gversion=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
2373  //addEmptyMode=GWEN_XMLNode_GetProperty(n, "addemptymode","one");
2374 
2375  lflags=flags;
2376 
2377  /*DBG_DEBUG(GWEN_LOGDOMAIN, "Omitted elements: %d", omittedElements);*/
2378  t=GWEN_XMLNode_GetType(n);
2379  if (t==GWEN_XMLNodeTypeTag) {
2380  const char *typ;
2381 
2382  typ=GWEN_XMLNode_GetData(n);
2383  if (typ==0) {
2384  DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed tag found (internal error?)");
2385  return -1;
2386  }
2387  if (strcasecmp(typ, "ELEM")==0) {
2388  /* element tag found */
2389 
2390  /* write element as often as needed */
2392  path,
2393  n,
2394  sl,
2395  lflags);
2396  if (rv==-1)
2397  return -1;
2398  else {
2399  //isFirstElement=0;
2400  /*omittedElements=0;*/
2401  }
2402  }
2403  else if (strcasecmp(typ, "VALUES")==0) {
2404  }
2405  else if (strcasecmp(typ, "DESCR")==0) {
2406  }
2407  else {
2408  /* group tag found */
2409  GWEN_XMLNODE *gn;
2410  const char *gname;
2411  const char *gtype;
2412 
2413  if (minnum==0)
2414  lflags|=GWEN_MSGENGINE_SHOW_FLAGS_OPTIONAL;
2415 
2416  gtype=GWEN_XMLNode_GetProperty(n, "type", 0);
2417  if (!gtype) {
2418  /* no "type" property, so use this group directly */
2419  DBG_DEBUG(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", typ);
2420  gtype="";
2421  gn=n;
2422  }
2423  else {
2424  gn=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", gversion, gtype);
2425  if (!gn) {
2426  DBG_DEBUG(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", typ);
2427  return -1;
2428  }
2429  }
2430 
2431  /* write group as often as needed */
2432  for (loopNr=0; loopNr<maxnum; loopNr++) {
2433  /* find group */
2434  char pbuffer[256];
2435  const char *npath;
2436 
2437  /* get configuration */
2438  gname=GWEN_XMLNode_GetProperty(n, "name", 0);
2439  if (gname) {
2440  if (loopNr==0) {
2441  if (strlen(path)+strlen(gname)+1>sizeof(pbuffer)) {
2442  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2443  return -1;
2444  }
2445  sprintf(pbuffer, "%s/%s", path, gname);
2446  npath=pbuffer;
2447  }
2448  else {
2449  /* this is not the first one, so create new name */
2450  if (strlen(path)+strlen(gname)+10>sizeof(pbuffer)) {
2451  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2452  return -1;
2453  }
2454  if (*path)
2455  sprintf(pbuffer, "%s/%s%d", path, gname, loopNr);
2456  else
2457  sprintf(pbuffer, "%s%d", gname, loopNr);
2458  /* get the value of the given var */
2459  npath=pbuffer;
2460  }
2461  } /* if name given */
2462  else
2463  npath=path;
2464 
2465  /* write group */
2466  if (GWEN_MsgEngine__ShowGroup(e, npath, gn, sl, lflags)) {
2467  DBG_INFO(GWEN_LOGDOMAIN, "Could not show group \"%s\"", gtype);
2468  return -1;
2469  }
2470  } /* for */
2471  }
2472  }
2473  n=GWEN_XMLNode_Next(n);
2474  } /* while */
2475 
2476  return 0;
2477 }
2478 
2479 
2480 
2482  const char *typ,
2483  const char *msgName,
2484  int msgVersion,
2485  uint32_t flags)
2486 {
2487  GWEN_XMLNODE *group;
2488  GWEN_STRINGLIST *sl;
2489  int i, j;
2490  const char *p;
2491 
2492  sl=GWEN_StringList_new();
2493 
2494  fprintf(stdout, "Message \"%s\" version %d\n",
2495  msgName, msgVersion);
2496  for (i=0; i<76; i++)
2497  fprintf(stdout, "=");
2498  fprintf(stdout, "\n");
2499  p=" Variable";
2500  fprintf(stdout, "%s", p);
2501  i=GWEN_MSGENGINE_VARNAME_WIDTH-strlen(p);
2502  for (j=0; j<i; j++)
2503  fprintf(stdout, " ");
2504 
2505  fprintf(stdout, " |");
2506  p=" Type";
2507  fprintf(stdout, "%s", p);
2508  i=GWEN_MSGENGINE_TYPENAME_WIDTH-strlen(p);
2509  for (j=0; j<i; j++)
2510  fprintf(stdout, " ");
2511 
2512  fprintf(stdout, " | Size | Num | Flags\n");
2513  for (i=0; i<76; i++)
2514  fprintf(stdout, "-");
2515  fprintf(stdout, "\n");
2516 
2517  group=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", msgVersion, msgName);
2518  if (!group) {
2519  DBG_ERROR(GWEN_LOGDOMAIN, "Group \"%s\" not found\n", msgName);
2521  return -1;
2522  }
2523 
2525  "",
2526  group,
2527  sl,
2528  flags)) {
2529  DBG_INFO(GWEN_LOGDOMAIN, "Error showing group \"%s\"", msgName);
2531  return -1;
2532  }
2533 
2535 
2536  return 0;
2537 }
2538 
2539 
2540 
2542  const char *path,
2543  GWEN_XMLNODE *node,
2544  GWEN_STRINGLIST *sl,
2545  GWEN_XMLNODE *listNode,
2546  uint32_t flags)
2547 {
2548  const char *name;
2549  //const char *type;
2550  const char *npath;
2551  int isSet;
2552  char nbuffer[256];
2554  GWEN_XMLNODE *nn;
2555 
2556  /* get type */
2557  //type=GWEN_XMLNode_GetProperty(node, "type","ASCII");
2558 
2559  npath="";
2560  isSet=0;
2561 
2562  /* get name */
2563  name=GWEN_XMLNode_GetProperty(node, "name", 0);
2564  if (path==0)
2565  path="";
2566 
2567  if (name) {
2568  /* get value of a config variable */
2569  if (strlen(path)+strlen(name)+10>=sizeof(nbuffer)) {
2570  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2571  return -1;
2572  }
2573  if (*path)
2574  sprintf(nbuffer, "%s/%s", path, name);
2575  else
2576  sprintf(nbuffer, "%s", name);
2577  npath=nbuffer;
2578  }
2579 
2581  while (en) {
2582  if (GWEN_StringListEntry_Data(en))
2583  if (strcasecmp(GWEN_StringListEntry_Data(en), npath)==0) {
2584  isSet=1;
2585  break;
2586  }
2588  } /* while */
2589 
2590  if (isSet && (flags & GWEN_MSGENGINE_SHOW_FLAGS_NOSET))
2591  return 0;
2592 
2593  nn=GWEN_XMLNode_dup(node);
2594  if (isSet)
2595  GWEN_XMLNode_SetProperty(nn, "GWEN_set", "1");
2596  GWEN_XMLNode_SetProperty(nn, "GWEN_path", npath);
2597  GWEN_XMLNode_AddChild(listNode, nn);
2598 
2599  return 0;
2600 }
2601 
2602 
2603 
2605  const char *path,
2606  GWEN_XMLNODE *node,
2607  GWEN_STRINGLIST *sl,
2608  GWEN_XMLNODE *listNode,
2609  uint32_t flags)
2610 {
2611  GWEN_XMLNODE *n;
2612  int rv;
2613 
2614  /* setup data */
2615  n=GWEN_XMLNode_GetChild(node);
2616 
2617  if (path==0)
2618  path="";
2619  if (*path=='/')
2620  path++;
2621 
2622  while (n) {
2624  const char *p;
2625 
2626  p=GWEN_XMLNode_GetData(n);
2627  assert(p);
2628  DBG_DEBUG(GWEN_LOGDOMAIN, "Checking %s", p);
2629  if (strcasecmp(p, "VALUES")==0)
2630  break;
2631  } /* if tag */
2632  n=GWEN_XMLNode_Next(n);
2633  } /* while */
2634 
2635  if (n) {
2636  DBG_DEBUG(GWEN_LOGDOMAIN, "<values> found");
2637  /* <values> found, handle all values */
2638  n=GWEN_XMLNode_GetChild(n);
2639  while (n) {
2641  const char *p;
2642 
2643  p=GWEN_XMLNode_GetData(n);
2644  assert(p);
2645  if (strcasecmp(p, "VALUE")==0) {
2646  const char *pname;
2647  const char *pvalue;
2648 
2649  pname=GWEN_XMLNode_GetProperty(n, "path", 0);
2650  if (pname) {
2651  GWEN_XMLNODE *dn;
2652 
2653  /* path found, find data */
2654  dn=GWEN_XMLNode_GetChild(n);
2655  while (dn) {
2657  pvalue=GWEN_XMLNode_GetData(dn);
2658  if (pvalue) {
2659  char pbuffer[256];
2660 
2661  /* check whether the value is a property */
2662  p=pvalue;
2663  while (*p && isspace((int)*p))
2664  p++;
2665  if (strlen(path)+strlen(pname)+2>sizeof(pbuffer)) {
2666  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2667  return -1;
2668  }
2669  if (*path)
2670  sprintf(pbuffer, "%s/%s", path, pname);
2671  else
2672  sprintf(pbuffer, "%s", pname);
2673  DBG_INFO(GWEN_LOGDOMAIN, "Found preset value for %s", pbuffer);
2675  pbuffer,
2676  0,
2677  1);
2678  }
2679  break;
2680  }
2681  dn=GWEN_XMLNode_Next(dn);
2682  } /* while dn */
2683  } /* if path given */
2684  } /* if VALUE tag */
2685  } /* if TAG */
2686  n=GWEN_XMLNode_Next(n);
2687  } /* while */
2688  } /* if <values> found */
2689 
2690  /* now handle all child entries */
2691  n=GWEN_XMLNode_GetChild(node);
2692  while (n) {
2693  int t;
2694  int gversion;
2695  unsigned int lflags;
2696 
2697  gversion=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
2698  lflags=flags;
2699 
2700  t=GWEN_XMLNode_GetType(n);
2701  if (t==GWEN_XMLNodeTypeTag) {
2702  const char *typ;
2703 
2704  typ=GWEN_XMLNode_GetData(n);
2705  if (typ==0) {
2706  DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed tag found (internal error?)");
2707  return -1;
2708  }
2709  if (strcasecmp(typ, "ELEM")==0) {
2710  /* element tag found */
2711 
2712  /* list element */
2714  path,
2715  n,
2716  sl,
2717  listNode,
2718  lflags);
2719  if (rv==-1)
2720  return -1;
2721  }
2722  else if (strcasecmp(typ, "VALUES")==0) {
2723  }
2724  else if (strcasecmp(typ, "DESCR")==0) {
2725  }
2726  else {
2727  /* group tag found */
2728  GWEN_XMLNODE *gn;
2729  GWEN_XMLNODE *nn;
2730  const char *gname;
2731  const char *gtype;
2732  char pbuffer[256];
2733  const char *npath;
2734 
2735  gtype=GWEN_XMLNode_GetProperty(n, "type", 0);
2736  if (!gtype) {
2737  /* no "type" property, so use this group directly */
2738  DBG_DEBUG(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", typ);
2739  gtype="";
2740  gn=n;
2741  }
2742  else {
2743  gn=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", gversion, gtype);
2744  if (!gn) {
2745  DBG_DEBUG(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", typ);
2746  return -1;
2747  }
2748  }
2749 
2750  /* get configuration */
2751  gname=GWEN_XMLNode_GetProperty(n, "name", 0);
2752  if (gname) {
2753  if (strlen(path)+strlen(gname)+1>sizeof(pbuffer)) {
2754  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
2755  return -1;
2756  }
2757 
2758  if (*path)
2759  sprintf(pbuffer, "%s/%s", path, gname);
2760  else
2761  sprintf(pbuffer, "%s", gname);
2762  npath=pbuffer;
2763  } /* if name given */
2764  else
2765  npath=path;
2766 
2767  nn=GWEN_XMLNode_dup(n);
2768  if (gn!=n)
2769  GWEN_XMLNode_CopyProperties(nn, gn, 0);
2770  GWEN_XMLNode_SetProperty(nn, "GWEN_path", npath);
2771  GWEN_XMLNode_AddChild(listNode, nn);
2772 
2773  /* write group */
2774  if (GWEN_MsgEngine__ListGroup(e, npath, gn, sl, nn, lflags)) {
2775  DBG_INFO(GWEN_LOGDOMAIN, "Could not list group \"%s\"", gtype);
2776  return -1;
2777  }
2778  }
2779  }
2780  n=GWEN_XMLNode_Next(n);
2781  } /* while */
2782 
2783  return 0;
2784 }
2785 
2786 
2787 
2789  const char *typ,
2790  const char *msgName,
2791  int msgVersion,
2792  uint32_t flags)
2793 {
2794  GWEN_XMLNODE *group;
2795  GWEN_STRINGLIST *sl;
2796  GWEN_XMLNODE *listNode;
2797 
2798  group=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", msgVersion, msgName);
2799  if (!group)
2800  group=GWEN_MsgEngine_FindNodeByProperty(e, typ, "code",
2801  msgVersion, msgName);
2802  if (!group) {
2803  DBG_ERROR(GWEN_LOGDOMAIN, "Group \"%s\" (version %d) not found\n",
2804  msgName, msgVersion);
2805  return 0;
2806  }
2807 
2808  sl=GWEN_StringList_new();
2809  /* copy group, but remove all children (we only want the properties) */
2810  listNode=GWEN_XMLNode_dup(group);
2811  GWEN_XMLNode_RemoveChildren(listNode);
2812 
2813  if (GWEN_MsgEngine__ListGroup(e, "", group, sl, listNode, flags)) {
2814  DBG_INFO(GWEN_LOGDOMAIN, "Error showing group \"%s\"", msgName);
2816  GWEN_XMLNode_free(listNode);
2817  return 0;
2818  }
2819 
2821 
2822  return listNode;
2823 }
2824 
2825 
2826 
2827 
2828 
2829 
2830 
2832  GWEN_BUFFER *msgbuf,
2833  GWEN_XMLNODE *node,
2834  GWEN_XMLNODE *rnode,
2835  GWEN_BUFFER *vbuf,
2836  const char *delimiters,
2837  uint32_t flags)
2838 {
2839  unsigned int minsize;
2840  unsigned int maxsize;
2841  unsigned int size;
2842  unsigned int minnum;
2843  GWEN_MSGENGINE_TRUSTLEVEL trustLevel;
2844  //unsigned int posInMsg;
2845  const char *type;
2846  int rv;
2847  unsigned int realSize;
2848 
2849  /* get some sizes */
2850  //posInMsg=GWEN_Buffer_GetPos(msgbuf);
2851  realSize=0;
2852  size=atoi(GWEN_XMLNode_GetProperty(node, "size", "0"));
2853  minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize", "0"));
2854  maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize", "0"));
2855  minnum=atoi(GWEN_XMLNode_GetProperty(node, "minnum", "1"));
2856  type=GWEN_XMLNode_GetProperty(node, "type", "ASCII");
2857 
2858  rv=1;
2859  if (e->typeReadPtr) {
2860  rv=e->typeReadPtr(e,
2861  msgbuf,
2862  node,
2863  vbuf,
2864  e->escapeChar,
2865  delimiters);
2866  }
2867  if (rv==-1) {
2868  DBG_INFO(GWEN_LOGDOMAIN, "External type reading failed on type \"%s\"", type);
2869  return -1;
2870  }
2871  else if (rv==1) {
2872  if (strcasecmp(type, "bin")==0) {
2873  if (GWEN_Buffer_GetBytesLeft(msgbuf)==0) {
2874  DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (@num@ expected)");
2875  return -1;
2876  }
2877  else {
2878  char lbuffer[16];
2879  int c;
2880  char *p;
2881  int l;
2882 
2883  p=lbuffer;
2884  c=GWEN_Buffer_ReadByte(msgbuf);
2885  if (c!='@') {
2886  DBG_ERROR(GWEN_LOGDOMAIN, "\"@num@\" expected");
2887  return -1;
2888  }
2889 
2890  c=0;
2891  while (GWEN_Buffer_GetBytesLeft(msgbuf)>0) {
2892  c=GWEN_Buffer_ReadByte(msgbuf);
2893  if (c==-1) {
2894  DBG_ERROR(GWEN_LOGDOMAIN, "\"@\" expected");
2895  return -1;
2896  }
2897  if (c=='@')
2898  break;
2899  *p=(char)c;
2900  p++;
2901  } /* while */
2902  *p=0;
2903  if (c!='@') {
2904  DBG_ERROR(GWEN_LOGDOMAIN, "\"@num@\" expected");
2905  return -1;
2906  }
2907  if (sscanf(lbuffer, "%d", &l)!=1) {
2908  DBG_ERROR(GWEN_LOGDOMAIN, "Bad number format");
2909  return -1;
2910  }
2911  DBG_DEBUG(GWEN_LOGDOMAIN, "Reading binary: %d bytes from pos %d (msgsize=%d)",
2912  l,
2913  GWEN_Buffer_GetPos(msgbuf),
2914  GWEN_Buffer_GetUsedBytes(msgbuf));
2915  if (GWEN_Buffer_GetBytesLeft(msgbuf) < (unsigned) l) {
2916  DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (binary beyond end)");
2917  return -1;
2918  }
2919  if (GWEN_Buffer_AppendBytes(vbuf,
2920  GWEN_Buffer_GetPosPointer(msgbuf),
2921  l)) {
2922  DBG_DEBUG(GWEN_LOGDOMAIN, "Called from here");
2923  return -1;
2924  }
2925  GWEN_Buffer_IncrementPos(msgbuf, l);
2926  }
2927  } /* if bin */
2928  else {
2929  /* type is not bin */
2930  int lastWasEscape;
2931  int isEscaped;
2932  int br;
2933 
2934  isEscaped=0;
2935  lastWasEscape=0;
2936 
2937  br=0;
2938  while (GWEN_Buffer_GetBytesLeft(msgbuf) &&
2939  (size==0 || br<(int)size)) {
2940  int c;
2941 
2942  c=GWEN_Buffer_ReadByte(msgbuf);
2943  if (lastWasEscape) {
2944  lastWasEscape=0;
2945  isEscaped=1;
2946  }
2947  else {
2948  isEscaped=0;
2949  if (c==e->escapeChar) {
2950  lastWasEscape=1;
2951  c=-1;
2952  }
2953  }
2954  if (c!=-1) {
2955  if (!isEscaped && (c && strchr(delimiters, c)!=0)) {
2956  /* delimiter found, step back */
2957  GWEN_Buffer_DecrementPos(msgbuf, 1);
2958  break;
2959  }
2960  else {
2961  if (c=='\\' || iscntrl(c)) {
2963  "Found a bad character (%02x) in type \"%s\", "
2964  "converting to SPACE",
2965  (unsigned int)c,
2966  type);
2967  c=' ';
2968  }
2969  if (GWEN_Buffer_AppendByte(vbuf, c)) {
2970  DBG_DEBUG(GWEN_LOGDOMAIN, "Called from here");
2971  return -1;
2972  }
2973  br++;
2974  }
2975  }
2976  } /* while */
2977  } /* if !bin */
2978  } /* if type not external */
2979  else {
2980  DBG_DEBUG(GWEN_LOGDOMAIN, "Type \"%s\" is external (read)", type);
2981  }
2982 
2983  realSize=GWEN_Buffer_GetUsedBytes(vbuf);
2984 
2985  /* check the value */
2986  if (realSize==0) {
2987  DBG_DEBUG(GWEN_LOGDOMAIN, "Datasize is 0");
2988  if (minnum==0) {
2989  DBG_DEBUG(GWEN_LOGDOMAIN, "... but thats ok");
2990  /* value is empty, and that is allowed */
2991  return 1;
2992  }
2993  else {
2994  DBG_ERROR(GWEN_LOGDOMAIN, "Value missing");
2995  GWEN_XMLNode_Dump(node, 1);
2996  return -1;
2997  }
2998  }
2999 
3000  /* check minimum size */
3001  if (minsize!=0 && realSize<minsize) {
3002  DBG_INFO(GWEN_LOGDOMAIN, "Value too short (%d<%d).",
3003  realSize,
3004  minsize);
3005  return -1;
3006  }
3007 
3008  /* check maximum size */
3009  if (maxsize!=0 && realSize>maxsize) {
3010  DBG_INFO(GWEN_LOGDOMAIN, "Value too long (%d>%d).",
3011  realSize, maxsize);
3012  return -1;
3013  }
3014 
3016  /* add trust data to msgEngine */
3017  const char *descr;
3018 
3019  trustLevel=GWEN_MsgEngine_GetHighestTrustLevel(node, rnode);
3020  if (trustLevel) {
3021  unsigned int ustart;
3022 
3023  ustart=GWEN_Buffer_GetPos(msgbuf)-realSize;
3024  descr=GWEN_XMLNode_GetProperty(node, "name", 0);
3026  GWEN_Buffer_GetStart(vbuf),
3027  realSize,
3028  descr,
3029  trustLevel,
3030  ustart)) {
3031  DBG_INFO(GWEN_LOGDOMAIN, "called from here");
3032  return -1;
3033  }
3034  }
3035  }
3036 
3037  return 0;
3038 }
3039 
3040 
3041 
3043  GWEN_BUFFER *msgbuf,
3044  GWEN_XMLNODE *node,
3045  GWEN_XMLNODE *rnode,
3046  GWEN_DB_NODE *gr,
3047  const char *delimiters,
3048  uint32_t flags)
3049 {
3050  //unsigned int minsize;
3051  //unsigned int maxsize;
3052  unsigned int minnum;
3053  unsigned int maxnum;
3054  const char *p;
3055  char delimiter;
3056  char terminator;
3057  GWEN_XMLNODE *n;
3058  int abortLoop;
3059  GWEN_BUFFER *delimBuffer=0;
3060 
3061  /* get some settings */
3062  if (rnode) {
3063  /* get delimiter */
3064  p=GWEN_XMLNode_GetProperty(rnode, "delimiter", GWEN_XMLNode_GetProperty(node, "delimiter", ""));
3065  delimiter=*p;
3066 
3067  /* get terminating char, if any */
3068  p=GWEN_XMLNode_GetProperty(rnode, "terminator", GWEN_XMLNode_GetProperty(node, "terminator", ""));
3069  terminator=*p;
3070  }
3071  else {
3072  /* get delimiter */
3073  p=GWEN_XMLNode_GetProperty(node, "delimiter", "");
3074  delimiter=*p;
3075 
3076  /* get terminating char, if any */
3077  p=GWEN_XMLNode_GetProperty(node, "terminator", "");
3078  terminator=*p;
3079  }
3080 
3081  delimBuffer=GWEN_Buffer_new(0, strlen(delimiters)+2, 0, 1);
3082  GWEN_Buffer_AppendString(delimBuffer, delimiters);
3083  if (delimiter)
3084  GWEN_Buffer_AppendByte(delimBuffer, delimiter);
3085  if (terminator)
3086  GWEN_Buffer_AppendByte(delimBuffer, terminator);
3087 
3088  DBG_DEBUG(GWEN_LOGDOMAIN, "Delimiters are \"%s\" and \"%c\"", delimiters, delimiter);
3089 
3090  n=GWEN_XMLNode_GetChild(node);
3091  while (n) {
3093  const char *type;
3094 
3095  if (GWEN_Buffer_GetBytesLeft(msgbuf)==0)
3096  break;
3097 
3098  type=GWEN_XMLNode_GetData(n);
3099 
3100 #ifdef HEAVY_DEBUG_MSGENGINE
3101  DBG_NOTICE(GWEN_LOGDOMAIN, "Reading group from here :");
3104  3);
3105 #endif
3106  if (strcasecmp(type, "ELEM")==0) {
3107  int rv;
3108 
3109  rv=_groupReadElement(e, msgbuf, n, rnode, gr, delimiter, terminator, GWEN_Buffer_GetStart(delimBuffer), flags);
3110  if (rv<0) {
3111  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
3112  GWEN_Buffer_free(delimBuffer);
3113  return rv;
3114  }
3115  n=GWEN_XMLNode_Next(n);
3116  } /* if ELEM */
3117  else if (strcasecmp(type, "VALUES")==0) {
3118  n=GWEN_XMLNode_Next(n);
3119  }
3120  else if (strcasecmp(type, "DESCR")==0) {
3121  n=GWEN_XMLNode_Next(n);
3122  }
3123  else {
3124  /* group tag found */
3125  GWEN_XMLNODE *gn;
3126  GWEN_DB_NODE *gcfg;
3127  const char *gname;
3128  const char *gtype;
3129  unsigned int gversion;
3130  unsigned int loopNr;
3131 
3132  DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading group");
3133  minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum", "1"));
3134  maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum", "1"));
3135  gversion=atoi(GWEN_XMLNode_GetProperty(n, "version", "0"));
3136  gtype=GWEN_XMLNode_GetProperty(n, "type", 0);
3137  if (!gtype) {
3138  /* no "type" property, so use this group directly */
3139  DBG_INFO(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", type);
3140  gtype="";
3141  gn=n;
3142  }
3143  else {
3144  gn=GWEN_MsgEngine_FindNodeByProperty(e, type, "id", gversion, gtype);
3145  if (!gn) {
3146  DBG_INFO(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", type);
3147  GWEN_Buffer_free(delimBuffer);
3148  return -1;
3149  }
3150  }
3151 
3152  /* get configuration */
3153  loopNr=0;
3154  abortLoop=0;
3155  while ((maxnum==0 || loopNr<maxnum) && !abortLoop) {
3156  int c;
3157 
3158  DBG_DEBUG(GWEN_LOGDOMAIN, "Reading group type %s", gtype);
3159  if (GWEN_Buffer_GetBytesLeft(msgbuf)==0)
3160  break;
3161  c=GWEN_Buffer_PeekByte(msgbuf);
3162  if (c && strchr(GWEN_Buffer_GetStart(delimBuffer), c)) {
3163  abortLoop=1;
3164  }
3165  else {
3166  gname=GWEN_XMLNode_GetProperty(n, "name", 0);
3167  if (gname) {
3168  DBG_DEBUG(GWEN_LOGDOMAIN, "Creating group \"%s\"", gname);
3170  if (!gcfg) {
3171  DBG_ERROR(GWEN_LOGDOMAIN, "Could not select group \"%s\"", gname);
3172  GWEN_Buffer_free(delimBuffer);
3173  return -1;
3174  }
3175  DBG_DEBUG(GWEN_LOGDOMAIN, "Created group \"%s\"", gname);
3176  } /* if name given */
3177  else
3178  gcfg=gr;
3179 
3180  /* read group */
3181  DBG_DEBUG(GWEN_LOGDOMAIN, "Reading group \"%s\"", gname);
3183  msgbuf,
3184  gn,
3185  n,
3186  gcfg,
3187  GWEN_Buffer_GetStart(delimBuffer),
3188  flags)) {
3189  DBG_INFO(GWEN_LOGDOMAIN, "Could not read group \"%s\"", gtype);
3190  GWEN_Buffer_free(delimBuffer);
3191  return -1;
3192  }
3193  }
3194  if (GWEN_Buffer_GetBytesLeft(msgbuf)) {
3195  if (delimiter) {
3196  if (GWEN_Buffer_PeekByte(msgbuf)==delimiter) {
3197  GWEN_Buffer_IncrementPos(msgbuf, 1);
3198  if (abortLoop && maxnum) {
3199  uint32_t loopOpt=loopNr+1;
3200 
3201  if (maxnum-loopOpt>GWEN_Buffer_GetBytesLeft(msgbuf))
3202  /* Suspicious but not necessarily invalid, let's see */
3203  maxnum=loopOpt+GWEN_Buffer_GetBytesLeft(msgbuf);
3204  for (; loopOpt<maxnum; loopOpt++) {
3205  if (GWEN_Buffer_PeekByte(msgbuf)!=delimiter)
3206  break;
3207  GWEN_Buffer_IncrementPos(msgbuf, 1);
3208  }
3209  if (loopOpt+1==maxnum && terminator) {
3210  if (GWEN_Buffer_PeekByte(msgbuf)==terminator) {
3211  GWEN_Buffer_IncrementPos(msgbuf, 1);
3212  loopOpt++;
3213  }
3214  }
3215  if (loopOpt<maxnum) {
3217  "Delimiting character missing (pos=%d [%x]) "
3218  "expecting \"%c\", got \"%c\")",
3219  GWEN_Buffer_GetPos(msgbuf),
3220  GWEN_Buffer_GetPos(msgbuf),
3221  delimiter,
3222  GWEN_Buffer_PeekByte(msgbuf));
3223  GWEN_XMLNode_Dump(n, 2);
3224  GWEN_Buffer_free(delimBuffer);
3225  return -1;
3226  }
3227  }
3228  }
3229  }
3230  }
3231  loopNr++;
3232  } /* while */
3233  if (loopNr<minnum) {
3234  DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (too few group repeats)");
3235  GWEN_Buffer_free(delimBuffer);
3236  return -1;
3237  }
3238  n=GWEN_XMLNode_Next(n);
3239  } /* if GROUP */
3240  } /* if TAG */
3241  else {
3242  n=GWEN_XMLNode_Next(n);
3243  }
3244  } /* while */
3245 
3246  /* check whether there still are nodes which have not been read */
3247  while (n) {
3249  if (strcasecmp(GWEN_XMLNode_GetData(n), "ELEM")==0 ||
3250  strcasecmp(GWEN_XMLNode_GetData(n), "GROUP")==0) {
3251  unsigned int i;
3252 
3253  i=atoi(GWEN_XMLNode_GetProperty(n, "minnum", "1"));
3254  if (i) {
3255  DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (still tags to parse)");
3256  GWEN_XMLNode_Dump(n, 2);
3257  GWEN_Buffer_free(delimBuffer);
3258  return -1;
3259  }
3260  }
3261  }
3262  n=GWEN_XMLNode_Next(n);
3263  }
3264 
3265 
3266  if (terminator) {
3267  /* skip terminator */
3268  if (GWEN_Buffer_GetBytesLeft(msgbuf)) {
3269  if (GWEN_Buffer_PeekByte(msgbuf)==terminator) {
3270  GWEN_Buffer_IncrementPos(msgbuf, 1);
3271  }
3272  else {
3274  "Terminating character missing (pos=%d [%x]) "
3275  "expecting \"%c\", got \"%c\")",
3276  GWEN_Buffer_GetPos(msgbuf),
3277  GWEN_Buffer_GetPos(msgbuf),
3278  terminator,
3279  GWEN_Buffer_PeekByte(msgbuf));
3280  GWEN_XMLNode_Dump(node, 1);
3281  GWEN_Buffer_free(delimBuffer);
3282  return -1;
3283  }
3284  }
3285  else {
3286  DBG_ERROR(GWEN_LOGDOMAIN, "Terminating character missing");
3287  GWEN_Buffer_free(delimBuffer);
3288  return -1;
3289  }
3290  }
3291 
3292  GWEN_Buffer_free(delimBuffer);
3293  return 0;
3294 }
3295 
3296 
3297 
3299  GWEN_BUFFER *msgbuf,
3300  GWEN_XMLNODE *n,
3301  GWEN_XMLNODE *rnode,
3302  GWEN_DB_NODE *gr,
3303  char currentDelimiter,
3304  char currentTerminator,
3305  const char *delimiters,
3306  uint32_t flags)
3307 {
3308  unsigned int loopNr;
3309  unsigned int minnum;
3310  unsigned int maxnum;
3311  const char *name;
3312  int abortLoop;
3313 
3314  DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading element");
3315 
3316  /* get some sizes */
3317  //minsize=atoi(GWEN_XMLNode_GetProperty(n, "minsize","0"));
3318  //maxsize=atoi(GWEN_XMLNode_GetProperty(n, "maxsize","0"));
3319  minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum", "1"));
3320  maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum", "1"));
3321  name=GWEN_XMLNode_GetProperty(n, "name", 0);
3322 
3323  loopNr=0;
3324  abortLoop=0;
3325  while ((maxnum==0 || loopNr<maxnum) && !abortLoop) {
3326  int c;
3327 
3328  DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading %s", name);
3329  if (GWEN_Buffer_GetBytesLeft(msgbuf)==0)
3330  break;
3331  c=GWEN_Buffer_PeekByte(msgbuf);
3332  if (c==-1) {
3333  DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
3334  return -1;
3335  }
3336 
3338  "Checking delimiter at pos %x "
3339  "(whether \"%c\" is in \"%s\")",
3340  GWEN_Buffer_GetPos(msgbuf),
3341  c, delimiters);
3342  if (c && strchr(delimiters, c)) {
3343  abortLoop=1;
3345  "Found delimiter (\"%c\" is in \"%s\")",
3346  c, delimiters);
3347  } /* if delimiter found */
3348  else {
3349  /* current char is not a delimiter */
3350  if (name==0) {
3351  DBG_VERBOUS(GWEN_LOGDOMAIN, "no name");
3352  }
3353  else {
3354  /* name is given */
3355  int rv;
3356  const char *dtype;
3357  GWEN_BUFFER *vbuf;
3358 
3359  DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading value from pos %x", GWEN_Buffer_GetPos(msgbuf));
3361 #ifdef HEAVY_DEBUG_MSGENGINE
3362  DBG_ERROR(GWEN_LOGDOMAIN, "Reading value from here:\n");
3364  GWEN_Buffer_GetBytesLeft(msgbuf),
3365  1);
3366 #endif
3367 
3368  rv=GWEN_MsgEngine__ReadValue(e, msgbuf, n, rnode, vbuf, delimiters, flags);
3369  if (rv==1) {
3370  DBG_INFO(GWEN_LOGDOMAIN, "Empty value");
3371  }
3372  else if (rv==-1) {
3373  DBG_INFO(GWEN_LOGDOMAIN, "Error parsing node \"%s\" (ELEM)", name);
3374  GWEN_Buffer_free(vbuf);
3375  return -1;
3376  }
3377 
3378  GWEN_Buffer_Rewind(vbuf);
3379 
3380  /* special handling for binary data */
3381  dtype=GWEN_XMLNode_GetProperty(n, "type", "");
3382  if (GWEN_MsgEngine__IsBinTyp(e, dtype)) {
3383  if (atoi(GWEN_XMLNode_GetProperty(n, "readbin", "1")) && e->binTypeReadPtr) {
3384  rv=e->binTypeReadPtr(e, n, gr, vbuf);
3385  }
3386  else
3387  rv=1;
3388  if (rv==-1) {
3389  DBG_INFO(GWEN_LOGDOMAIN, "Called from here");
3390  GWEN_Buffer_free(vbuf);
3391  return -1;
3392  }
3393  else if (rv==1) {
3394  /* bin type not handled, so handle it myself */
3395  if (GWEN_DB_SetBinValue(gr,
3397  name,
3398  GWEN_Buffer_GetStart(vbuf),
3399  GWEN_Buffer_GetUsedBytes(vbuf))) {
3400  DBG_INFO(GWEN_LOGDOMAIN, "Could not set value for \"%s\"", name);
3401  GWEN_Buffer_free(vbuf);
3402  return -1;
3403  }
3404  }
3405  } /* if type is bin */
3406  else if (GWEN_MsgEngine__IsIntTyp(e, dtype)) {
3407  int z;
3408 
3409  if (1!=sscanf(GWEN_Buffer_GetStart(vbuf), "%d", &z)) {
3410  DBG_INFO(GWEN_LOGDOMAIN, "Value for \"%s\" is not an integer", name);
3411  return -1;
3412  }
3413  if (GWEN_DB_SetIntValue(gr, GWEN_DB_FLAGS_DEFAULT, name, z)) {
3414  DBG_INFO(GWEN_LOGDOMAIN, "Could not set int value for \"%s\"", name);
3415  return -1;
3416  }
3417  } /* if type is int */
3418  else {
3419  DBG_DEBUG(GWEN_LOGDOMAIN, "Value is \"%s\"", GWEN_Buffer_GetStart(vbuf));
3420  if (GWEN_DB_SetCharValue(gr,
3422  name,
3423  GWEN_Buffer_GetStart(vbuf))) {
3424  DBG_INFO(GWEN_LOGDOMAIN, "Could not set value for \"%s\"", name);
3425  return -1;
3426  }
3427  } /* if !bin */
3428 
3429  GWEN_Buffer_free(vbuf);
3430  } /* if name is given */
3431  } /* if current char is not a delimiter */
3432 
3433  if (GWEN_Buffer_GetBytesLeft(msgbuf)) {
3434  if (currentDelimiter) {
3435  if (GWEN_Buffer_PeekByte(msgbuf)==currentDelimiter) {
3436  GWEN_Buffer_IncrementPos(msgbuf, 1);
3437  if (abortLoop && maxnum) {
3438  uint32_t loopOpt=loopNr+1;
3439 
3440  if (maxnum-loopOpt>GWEN_Buffer_GetBytesLeft(msgbuf))
3441  /* Suspicious but not necessarily invalid, let's see */
3442  maxnum=loopOpt+GWEN_Buffer_GetBytesLeft(msgbuf);
3443  for (; loopOpt<maxnum; loopOpt++) {
3444  if (GWEN_Buffer_PeekByte(msgbuf)!=currentDelimiter)
3445  break;
3446  GWEN_Buffer_IncrementPos(msgbuf, 1);
3447  }
3448  if (loopOpt+1==maxnum && currentTerminator) {
3449  if (GWEN_Buffer_PeekByte(msgbuf)==currentTerminator) {
3450  GWEN_Buffer_IncrementPos(msgbuf, 1);
3451  loopOpt++;
3452  }
3453  }
3454  if (loopOpt<maxnum) {
3456  "Delimiting character missing (pos=%d [%x]) "
3457  "expecting \"%c\", got \"%c\")",
3458  GWEN_Buffer_GetPos(msgbuf),
3459  GWEN_Buffer_GetPos(msgbuf),
3460  currentDelimiter,
3461  GWEN_Buffer_PeekByte(msgbuf));
3462  GWEN_XMLNode_Dump(n, 2);
3463  return -1;
3464  }
3465  }
3466  }
3467  }
3468  }
3469  loopNr++;
3470  } /* while */
3471  if (loopNr<minnum) {
3472  DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (too few ELEM repeats)");
3473  GWEN_XMLNode_Dump(n, 2);
3474  return -1;
3475  }
3476 
3477  return 0;
3478 }
3479 
3480 
3481 
3482 
3483 
3485  GWEN_XMLNODE *group,
3486  GWEN_BUFFER *msgbuf,
3487  GWEN_DB_NODE *msgData,
3488  uint32_t flags)
3489 {
3490 
3492  msgbuf,
3493  group,
3494  0,
3495  msgData,
3496  e->delimiters,
3497  flags)) {
3498  DBG_INFO(GWEN_LOGDOMAIN, "Error reading group");
3499  return -1;
3500  }
3501 
3502  return 0;
3503 }
3504 
3505 
3506 
3508  const char *path,
3509  const char *value)
3510 {
3511  GWEN_DB_NODE *globalValues;
3512 
3513  assert(e);
3514  globalValues=GWEN_MsgEngine__GetGlobalValues(e);
3515  assert(globalValues);
3516  return GWEN_DB_SetCharValue(globalValues,
3519  path, value);
3520 }
3521 
3522 
3523 
3525  const char *path,
3526  int value)
3527 {
3528  GWEN_DB_NODE *globalValues;
3529 
3530  assert(e);
3531  globalValues=GWEN_MsgEngine__GetGlobalValues(e);
3532  assert(globalValues);
3533  return GWEN_DB_SetIntValue(globalValues,
3536  path, value);
3537 }
3538 
3539 
3540 
3542  const char *path,
3543  const char *defValue)
3544 {
3545  GWEN_DB_NODE *globalValues;
3546 
3547  assert(e);
3548  globalValues=GWEN_MsgEngine__GetGlobalValues(e);
3549  assert(globalValues);
3550  return GWEN_DB_GetCharValue(globalValues,
3551  path, 0, defValue);
3552 }
3553 
3554 
3555 
3557  const char *path,
3558  int defValue)
3559 {
3560  GWEN_DB_NODE *globalValues;
3561 
3562  assert(e);
3563  globalValues=GWEN_MsgEngine__GetGlobalValues(e);
3564  assert(globalValues);
3565  return GWEN_DB_GetIntValue(globalValues,
3566  path, 0, defValue);
3567 }
3568 
3569 
3570 
3571 /* --------------------------------------------------------------- FUNCTION */
3573  GWEN_BUFFER *msgbuf,
3574  unsigned char escapeChar,
3575  unsigned char delimiter)
3576 {
3577  int esc;
3578 
3579  esc=0;
3580  while (GWEN_Buffer_GetBytesLeft(msgbuf)) {
3581  int nc;
3582 
3583  if (esc) {
3584  esc=0;
3585  /* skip byte */
3586  nc=GWEN_Buffer_ReadByte(msgbuf);
3587  if (nc<0) {
3588  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", nc);
3589  return -1;
3590  }
3591  }
3592  else {
3593  int i;
3594  unsigned char c;
3595 
3596  i=GWEN_Buffer_ReadByte(msgbuf);
3597  if (i<0) {
3598  DBG_INFO(GWEN_LOGDOMAIN, "called from here");
3599  return 0;
3600  }
3601  c=(unsigned int)i;
3602  if (c==escapeChar) { /* escape */
3603  esc=1;
3604  }
3605  else if (c=='@') {
3606  /* skip binary data */
3607  char lbuffer[16];
3608  char *p;
3609  int l;
3610 
3611  p=lbuffer;
3612  while (1) {
3613  nc=GWEN_Buffer_ReadByte(msgbuf);
3614  if (nc<0) {
3615  DBG_ERROR(GWEN_LOGDOMAIN, "\"@num@\" expected");
3616  return -1;
3617  }
3618  if (nc=='@')
3619  break;
3620  *p=nc;
3621  p++;
3622  } /* while */
3623  *p=0;
3624  if (sscanf(lbuffer, "%d", &l)!=1) {
3625  DBG_ERROR(GWEN_LOGDOMAIN, "Bad number format");
3626  return -1;
3627  }
3628  if (GWEN_Buffer_GetUsedBytes(msgbuf)-GWEN_Buffer_GetPos(msgbuf)
3629  < (unsigned) l) {
3630  DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (binary beyond end)");
3631  return -1;
3632  }
3633  GWEN_Buffer_IncrementPos(msgbuf, l);
3634  }
3635  else if (c==delimiter) {/* segment-end */
3636  return 0;
3637  break;
3638  }
3639  }
3640  } /* while */
3641 
3642  DBG_ERROR(GWEN_LOGDOMAIN, "End of segment not found");
3643  return -1;
3644 }
3645 
3646 
3647 
3648 /* --------------------------------------------------------------- FUNCTION */
3650  const char *gtype,
3651  GWEN_BUFFER *mbuf,
3652  GWEN_DB_NODE *gr,
3653  uint32_t flags)
3654 {
3655  unsigned int segments;
3656 
3657  segments=0;
3658 
3659  while (GWEN_Buffer_GetBytesLeft(mbuf)) {
3660  GWEN_XMLNODE *node;
3661  unsigned int posBak;
3662  const char *p;
3663  GWEN_DB_NODE *tmpdb;
3664  int segVer;
3665 
3666  /* find head segment description */
3667  tmpdb=GWEN_DB_Group_new("tmpdb");
3669  "id",
3670  0,
3671  "SegHead");
3672  if (node==0) {
3673  DBG_ERROR(GWEN_LOGDOMAIN, "Segment description not found");
3674  GWEN_DB_Group_free(tmpdb);
3675  return -1;
3676  }
3677 
3678  /* parse head segment */
3679  posBak=GWEN_Buffer_GetPos(mbuf);
3681  node,
3682  mbuf,
3683  tmpdb,
3684  flags)) {
3685  DBG_ERROR(GWEN_LOGDOMAIN, "Error parsing segment head");
3686  GWEN_DB_Group_free(tmpdb);
3687  return -1;
3688  }
3689 
3690  /* get segment code */
3691  segVer=GWEN_DB_GetIntValue(tmpdb,
3692  "version",
3693  0,
3694  0);
3695  p=GWEN_DB_GetCharValue(tmpdb,
3696  "code",
3697  0,
3698  0);
3699  if (!p) {
3700  DBG_ERROR(GWEN_LOGDOMAIN, "No segment code for %s ? This seems to be a bad msg...",
3701  gtype);
3702  GWEN_Buffer_SetPos(mbuf, posBak);
3703  DBG_ERROR(GWEN_LOGDOMAIN, "Full message (pos=%04x)", posBak);
3706  1);
3707  GWEN_DB_Dump(tmpdb, 1);
3708  GWEN_DB_Group_free(tmpdb);
3709  return -1;
3710  }
3711 
3712  /* try to find corresponding XML node */
3714  gtype,
3715  "code",
3716  segVer,
3717  p);
3718  if (node==0) {
3719  unsigned int ustart;
3720 
3721  ustart=GWEN_Buffer_GetPos(mbuf);
3722  ustart++; /* skip delimiter */
3723 
3724  /* node not found, skip it */
3726  "Unknown segment \"%s\" (Segnum=%d, version=%d, ref=%d)",
3727  p,
3728  GWEN_DB_GetIntValue(tmpdb, "seq", 0, -1),
3729  GWEN_DB_GetIntValue(tmpdb, "version", 0, -1),
3730  GWEN_DB_GetIntValue(tmpdb, "ref", 0, -1));
3731  if (GWEN_MsgEngine_SkipSegment(e, mbuf, '?', '\'')) {
3732  DBG_ERROR(GWEN_LOGDOMAIN, "Error skipping segment \"%s\"", p);
3733  GWEN_DB_Group_free(tmpdb);
3734  return -1;
3735  }
3737  unsigned int usize;
3738 
3739  usize=GWEN_Buffer_GetPos(mbuf)-ustart-1;
3740 #if 0
3742  usize,
3743  stderr, 1);
3744 #endif
3746  GWEN_Buffer_GetStart(mbuf)+ustart,
3747  usize,
3748  p,
3750  ustart)) {
3751  DBG_INFO(GWEN_LOGDOMAIN, "called from here");
3752  GWEN_DB_Group_free(tmpdb);
3753  return -1;
3754  }
3755  } /* if trustInfo handling wanted */
3756  }
3757  else {
3758  /* ok, node available, get the corresponding description and parse
3759  * the segment */
3760  const char *id;
3761  GWEN_DB_NODE *storegrp;
3762  unsigned int startPos;
3763 
3764  /* restore start position, since the segment head is part of a full
3765  * description, so we need to restart reading from the very begin */
3766  GWEN_Buffer_SetPos(mbuf, posBak);
3767 
3768  /* create group in DB for this segment */
3769  id=GWEN_XMLNode_GetProperty(node, "id", p);
3770  storegrp=GWEN_DB_GetGroup(gr,
3772  id);
3773  assert(storegrp);
3774 
3775  /* store the start position of this segment within the DB */
3776  startPos=GWEN_Buffer_GetPos(mbuf);
3777  GWEN_DB_SetIntValue(storegrp,
3779  "segment/pos",
3780  startPos);
3781 
3782  /* parse the segment */
3784  node,
3785  mbuf,
3786  storegrp,
3787  flags)) {
3788  DBG_ERROR(GWEN_LOGDOMAIN, "Error parsing segment \"%s\" at %d (%x)",
3789  p,
3790  GWEN_Buffer_GetPos(mbuf)-startPos,
3791  GWEN_Buffer_GetPos(mbuf)-startPos);
3793  GWEN_Buffer_GetUsedBytes(mbuf)-startPos,
3794  1);
3795  DBG_ERROR(GWEN_LOGDOMAIN, "Stored data so far:");
3796  GWEN_DB_Dump(storegrp, 2);
3797  GWEN_DB_Group_free(tmpdb);
3798  return -1;
3799  }
3800 
3801  /* store segment size within DB */
3802  GWEN_DB_SetIntValue(storegrp,
3804  "segment/length",
3805  GWEN_Buffer_GetPos(mbuf)-startPos);
3806  segments++;
3807  }
3808  GWEN_DB_Group_free(tmpdb);
3809  } /* while */
3810 
3811  /* done */
3812  if (segments) {
3813  DBG_DEBUG(GWEN_LOGDOMAIN, "Parsed %d segments", segments);
3814  return 0;
3815  }
3816  else {
3817  DBG_INFO(GWEN_LOGDOMAIN, "No segments parsed.");
3818  return 1;
3819  }
3820 }
3821 
3822 
3823 
3824 
3825 
3826 
3827 
3828 
3830  unsigned int size,
3831  const char *description,
3832  GWEN_MSGENGINE_TRUSTLEVEL trustLevel)
3833 {
3835 
3836  assert(data);
3837  assert(size);
3839  td->data=(char *)malloc(size);
3840  assert(td->data);
3841  memmove(td->data, data, size);
3842  if (description)
3843  td->description=strdup(description);
3844  td->trustLevel=trustLevel;
3845  td->size=size;
3846  return td;
3847 }
3848 
3849 
3850 
3852 {
3853  if (td) {
3854  free(td->data);
3855  free(td->description);
3856  free(td->replacement);
3857  GWEN_FREE_OBJECT(td);
3858  }
3859 }
3860 
3861 
3862 
3864 {
3865  assert(td);
3866  return td->next;
3867 }
3868 
3869 
3870 
3872 {
3873  assert(td);
3874  return td->data;
3875 }
3876 
3877 
3878 
3880 {
3881  assert(td);
3882  return td->size;
3883 }
3884 
3885 
3886 
3888 {
3889  assert(td);
3890  return td->description;
3891 }
3892 
3893 
3894 
3896 {
3897  assert(td);
3898  return td->trustLevel;
3899 }
3900 
3901 
3902 
3904 {
3905  assert(td);
3906  return td->replacement;
3907 }
3908 
3909 
3910 
3912  unsigned int pos)
3913 {
3914  assert(td);
3915  if (td->posCount>=GWEN_MSGENGINE_TRUSTEDDATA_MAXPOS)
3916  return -1;
3917  td->positions[td->posCount++]=pos;
3918  return 0;
3919 }
3920 
3921 
3922 
3924 {
3925  assert(td);
3926  td->posPointer=0;
3928 }
3929 
3930 
3931 
3933 {
3934  assert(td);
3935  if (td->posPointer>=td->posCount)
3936  return -1;
3937  return td->positions[td->posPointer++];
3938 }
3939 
3940 
3941 
3943  *td)
3944 {
3945  unsigned int nextNr;
3947  unsigned int count;
3948 
3949  assert(td);
3950  count=0;
3951  ntd=td;
3952  while (ntd) {
3953  count++;
3954  ntd=ntd->next;
3955  }
3956 
3957  if (count<0x10)
3958  nextNr=0x01;
3959  else
3960  nextNr=0x11;
3961 
3962  ntd=td;
3963  while (ntd) {
3964  unsigned int i;
3965  char numbuffer[32];
3966  char *rp;
3968  int match;
3969 
3970  /* check whether the same data already exists */
3971  std=td;
3972  match=0;
3973  while (std && std!=ntd) {
3974 
3975  match=1;
3976  if (std->size==ntd->size) {
3977  for (i=0; i<td->size; i++) {
3978  if (std->data[i]!=ntd->data[i]) {
3979  match=0;
3980  break;
3981  }
3982  } /* for */
3983  }
3984  else
3985  match=0;
3986 
3987  if (match)
3988  break;
3989  std=std->next;
3990  } /* while */
3991 
3992  if (match) {
3993  /* copy the found match */
3994  rp=strdup(std->replacement);
3995  }
3996  else {
3997  /* this is a new one */
3998  rp=(char *)malloc(ntd->size+1);
3999  assert(rp);
4000 
4001  if (ntd->size==1) {
4002  if (count>=0x10)
4003  nextNr+=0x10;
4004  }
4005  sprintf(numbuffer, "%02X", nextNr++);
4006  for (i=0; i<ntd->size; i++) {
4007  if (count<0x10)
4008  rp[i]=numbuffer[1];
4009  else
4010  rp[i]=numbuffer[1-(i&1)];
4011  } /* for */
4012  rp[i]=0;
4013  }
4014  /*
4015  DBG_DEBUG(GWEN_LOGDOMAIN, "Replacement: \"%s\" for \"%s\" (%d)", rp,
4016  ntd->description,
4017  ntd->size);
4018  */
4019  free(ntd->replacement);
4020  ntd->replacement=rp;
4021 
4022  ntd=ntd->next;
4023  } /* while */
4024  return 0;
4025 }
4026 
4027 
4028 
4030 {
4032 
4033  assert(e);
4034  td=e->trustInfos;
4035  e->trustInfos=0;
4036  return td;
4037 }
4038 
4039 
4040 
4041 
4043  const char *data,
4044  unsigned int size,
4045  const char *description,
4046  GWEN_MSGENGINE_TRUSTLEVEL trustLevel,
4047  unsigned int pos)
4048 {
4050  int match;
4051 
4052  assert(e);
4053  assert(data);
4054  assert(size);
4055 
4056  if (!description)
4057  description="";
4058 
4059  td=e->trustInfos;
4060  while (td) {
4061  unsigned int i;
4062 
4063  /* compare data */
4064  if (td->size==size &&
4065  *description &&
4066  *(td->description) &&
4067  trustLevel==td->trustLevel &&
4068  strcasecmp(description, td->description)==0) {
4069  match=1;
4070  for (i=0; i<td->size; i++) {
4071  if (td->data[i]!=data[i]) {
4072  match=0;
4073  break;
4074  }
4075  } /* for */
4076  }
4077  else
4078  match=0;
4079 
4080  if (match)
4081  break;
4082  td=td->next;
4083  } /* while */
4084 
4085  if (!td) {
4086  DBG_INFO(GWEN_LOGDOMAIN, "Creating new trustInfo for \"%s\" (%d)",
4087  description, size);
4089  size,
4090  description,
4091  trustLevel);
4092  GWEN_LIST_ADD(GWEN_MSGENGINE_TRUSTEDDATA, td, &(e->trustInfos));
4093  }
4094  else {
4095  DBG_INFO(GWEN_LOGDOMAIN, "Reusing trustInfo for \"%s\" (%d)",
4096  description, size);
4097  }
4099  return 0;
4100 }
4101 
4102 
4103 
int GWEN_MsgEngine_TrustedData_CreateReplacements(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition: msgengine.c:3942
uint32_t GWEN_Buffer_GetBytesLeft(GWEN_BUFFER *bf)
Definition: buffer.c:606
GWEN_MSGENGINE_BINTYPEWRITE_PTR GWEN_MsgEngine_GetBinTypeWriteFunction(GWEN_MSGENGINE *e)
Definition: msgengine.c:365
int(* GWEN_MSGENGINE_BINTYPEWRITE_PTR)(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, GWEN_DB_NODE *gr, GWEN_BUFFER *dbuf)
Definition: msgengine.h:169
GWEN_DB_NODE * GWEN_MsgEngine__GetGlobalValues(GWEN_MSGENGINE *e)
Definition: msgengine.c:202
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:51
GWEN_MSGENGINE_TYPEWRITE_PTR GWEN_MsgEngine_GetTypeWriteFunction(GWEN_MSGENGINE *e)
Definition: msgengine.c:311
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition: db.h:121
void GWEN_MsgEngine_SetGetGlobalValuesFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_GETGLOBALVALUES_PTR p)
Definition: msgengine.c:268
void GWEN_MsgEngine_TrustedData_free(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition: msgengine.c:3851
void GWEN_DB_Dump(GWEN_DB_NODE *n, int insert)
Definition: db.c:1418
GWEN_MSGENGINE_TRUSTEDDATA * GWEN_MsgEngine_TrustedData_new(const char *data, unsigned int size, const char *description, GWEN_MSGENGINE_TRUSTLEVEL trustLevel)
Definition: msgengine.c:3829
int GWEN_MsgEngine_ReadMessage(GWEN_MSGENGINE *e, const char *gtype, GWEN_BUFFER *mbuf, GWEN_DB_NODE *gr, uint32_t flags)
Definition: msgengine.c:3649
int GWEN_MsgEngine_SetIntValue(GWEN_MSGENGINE *e, const char *path, int value)
Definition: msgengine.c:3524
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
Definition: buffer.c:290
#define GWEN_INHERIT_FINI(t, element)
Definition: inherit.h:238
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition: db.c:419
int GWEN_MsgEngine__GetInline(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, GWEN_BUFFER *mbuf)
Definition: msgengine.c:694
void GWEN_MsgEngine_SetBinTypeWriteFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_BINTYPEWRITE_PTR p)
Definition: msgengine.c:356
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:282
GWEN_MSGENGINE_TRUSTEDDATA * GWEN_MsgEngine_TrustedData_GetNext(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition: msgengine.c:3863
const char * GWEN_XMLNode_GetProperty(const GWEN_XMLNODE *n, const char *name, const char *defaultValue)
Definition: xml.c:239
int(* GWEN_MSGENGINE_GETINTVALUE_PTR)(GWEN_MSGENGINE *e, const char *name, int defValue)
Definition: msgengine.h:180
GWEN_XMLNODE * GWEN_MsgEngine_GetGroup(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, const GWEN_XMLNODE_PATH *nodePath, const char *t, int version, const char *pvalue)
Definition: msgengine.c:1636
GWEN_XMLNODE * GWEN_MsgEngine_FindNodeByPropertyStrictProto(GWEN_MSGENGINE *e, const char *t, const char *pname, int version, const char *pvalue)
Definition: msgengine.c:1065
GWEN_XMLNODE * GWEN_MsgEngine__GetGroup(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, const char *t, int version, const char *pvalue)
Definition: msgengine.c:1556
void GWEN_Text_DumpString(const char *s, unsigned int l, unsigned int insert)
Definition: text.c:1283
GWEN_MSGENGINE_TYPECHECK_PTR GWEN_MsgEngine_GetTypeCheckFunction(GWEN_MSGENGINE *e)
Definition: msgengine.c:328
GWEN_DB_NODE_TYPE(* GWEN_MSGENGINE_TYPECHECK_PTR)(GWEN_MSGENGINE *e, const char *tname)
Definition: msgengine.h:161
#define DBG_NOTICE(dbg_logger, format, args...)
Definition: debug.h:151
GWEN_XMLNODE * GWEN_XMLNode_GetFirstData(const GWEN_XMLNODE *n)
Definition: xml.c:684
void GWEN_Buffer_SetStep(GWEN_BUFFER *bf, uint32_t step)
Definition: buffer.c:786
void GWEN_MsgEngine_SetFreeDataFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_FREEDATA_PTR p)
Definition: msgengine.c:391
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:297
GWEN_XMLNODE * GWEN_MsgEngine_FindNodeByProperty(GWEN_MSGENGINE *e, const char *t, const char *pname, int version, const char *pvalue)
Definition: msgengine.c:974
#define GWEN_PATH_FLAGS_CREATE_GROUP
Definition: path.h:96
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:217
const char * GWEN_MsgEngine_TrustedData_GetReplacement(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition: msgengine.c:3903
void GWEN_XMLNode_SetProperty(GWEN_XMLNODE *n, const char *name, const char *value)
Definition: xml.c:322
void GWEN_MsgEngine_SetCharsToEscape(GWEN_MSGENGINE *e, const char *c)
Definition: msgengine.c:137
static int _groupReadElement(GWEN_MSGENGINE *e, GWEN_BUFFER *msgbuf, GWEN_XMLNODE *n, GWEN_XMLNODE *rnode, GWEN_DB_NODE *gr, char currentDelimiter, char currentTerminator, const char *delimiters, uint32_t flags)
Definition: msgengine.c:3298
const char * GWEN_MsgEngine_TrustedData_GetData(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition: msgengine.c:3871
GWEN_XMLNODE * GWEN_MsgEngine_ListMessage(GWEN_MSGENGINE *e, const char *typ, const char *msgName, int msgVersion, uint32_t flags)
Definition: msgengine.c:2788
STL namespace.
int GWEN_MsgEngine__WriteElement(GWEN_MSGENGINE *e, GWEN_BUFFER *gbuf, GWEN_XMLNODE *node, GWEN_DB_NODE *gr, int loopNr, int isOptional, GWEN_XMLNODE_PATH *nodePath)
Definition: msgengine.c:742
void GWEN_XMLNode_Dump(const GWEN_XMLNODE *n, int ind)
Definition: xml.c:472
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
Definition: buffer.c:538
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:124
int GWEN_MsgEngine_SkipSegment(GWEN_UNUSED GWEN_MSGENGINE *e, GWEN_BUFFER *msgbuf, unsigned char escapeChar, unsigned char delimiter)
Definition: msgengine.c:3572
const char * GWEN_MsgEngine_GetValue(GWEN_MSGENGINE *e, const char *path, const char *defValue)
Definition: msgengine.c:3541
struct GWEN_MSGENGINE_TRUSTEDDATA GWEN_MSGENGINE_TRUSTEDDATA
Definition: msgengine.h:52
void GWEN_XMLNode_RemoveChildren(GWEN_XMLNODE *n)
Definition: xml.c:580
#define GWEN_LOGDOMAIN
Definition: logger.h:35
struct GWEN_XMLNODE_PATH GWEN_XMLNODE_PATH
Definition: xml.h:847
GWEN_MSGENGINE_GETGLOBALVALUES_PTR GWEN_MsgEngine_GetGetGlobalValuesFunction(GWEN_MSGENGINE *e)
Definition: msgengine.c:277
int GWEN_MsgEngine_TrustedData_AddPos(GWEN_MSGENGINE_TRUSTEDDATA *td, unsigned int pos)
Definition: msgengine.c:3911
int GWEN_DB_ValueExists(GWEN_DB_NODE *n, const char *path, unsigned int i)
Definition: db.c:1584
void(* GWEN_MSGENGINE_FREEDATA_PTR)(GWEN_MSGENGINE *e)
Definition: msgengine.h:187
uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf)
Definition: buffer.c:253
void GWEN_MsgEngine_SetEscapeChar(GWEN_MSGENGINE *e, char c)
Definition: msgengine.c:121
GWEN_MSGENGINE_TRUSTEDDATA * GWEN_MsgEngine_TakeTrustInfo(GWEN_MSGENGINE *e)
Definition: msgengine.c:4029
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:38
void GWEN_XMLNode_CopyProperties(GWEN_XMLNODE *tn, const GWEN_XMLNODE *sn, int overwrite)
Definition: xml.c:588
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
Definition: buffer.c:618
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:366
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:382
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:519
void GWEN_MsgEngine_Attach(GWEN_MSGENGINE *e)
Definition: msgengine.c:114
int GWEN_MsgEngine_CreateMessage(GWEN_MSGENGINE *e, const char *msgName, int msgVersion, GWEN_BUFFER *gbuf, GWEN_DB_NODE *msgData)
Definition: msgengine.c:2105
GWEN_XMLNODE * GWEN_XMLNode_GetChild(const GWEN_XMLNODE *n)
Definition: xml.c:409
int(* GWEN_MSGENGINE_BINTYPEREAD_PTR)(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, GWEN_DB_NODE *gr, GWEN_BUFFER *vbuf)
Definition: msgengine.h:164
const char * GWEN_MsgEngine__SearchForValue(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, GWEN_XMLNODE_PATH *nodePath, const char *name, unsigned int *datasize)
Definition: msgengine.c:1402
int GWEN_Buffer_PeekByte(GWEN_BUFFER *bf)
Definition: buffer.c:481
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition: stringlist.c:58
GWEN_XMLNODE * GWEN_XMLNode_FindFirstTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:736
GWEN_DB_NODE_TYPE GWEN_DB_GetVariableType(GWEN_DB_NODE *n, const char *p)
Definition: db.c:1593
unsigned int GWEN_MsgEngine_TrustedData_GetSize(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition: msgengine.c:3879
int GWEN_DB_SetBinValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const void *val, unsigned int valSize)
Definition: db.c:1267
GWEN_MSGENGINE_TRUSTLEVEL GWEN_MsgEngine_TrustedData_GetTrustLevel(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition: msgengine.c:3895
GWEN_XMLNODE * GWEN_MsgEngine_GetDefinitions(GWEN_MSGENGINE *e)
Definition: msgengine.c:248
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
GWEN_XMLNODE_TYPE GWEN_XMLNode_GetType(const GWEN_XMLNODE *n)
Definition: xml.c:458
GWEN_XMLNODE_PATH * GWEN_XMLNode_Path_new(void)
Definition: xml.c:1863
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition: stringlist.c:241
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:209
int GWEN_Buffer_AppendBuffer(GWEN_BUFFER *bf, GWEN_BUFFER *sf)
Definition: buffer.c:576
GWEN_XMLNODE * GWEN_XMLNode_GetNextTag(const GWEN_XMLNODE *n)
Definition: xml.c:672
int GWEN_MsgEngine_TrustedData_GetFirstPos(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition: msgengine.c:3923
GWEN_XMLNODE * GWEN_MsgEngine_FindGroupByProperty(GWEN_MSGENGINE *e, const char *pname, int version, const char *pvalue)
Definition: msgengine.c:964
GWEN_MSGENGINE_BINTYPEREAD_PTR GWEN_MsgEngine_GetBinTypeReadFunction(GWEN_MSGENGINE *e)
Definition: msgengine.c:348
GWEN_DB_NODE *(* GWEN_MSGENGINE_GETGLOBALVALUES_PTR)(GWEN_MSGENGINE *e)
Definition: msgengine.h:185
int GWEN_MsgEngine_ShowMessage(GWEN_MSGENGINE *e, const char *typ, const char *msgName, int msgVersion, uint32_t flags)
Definition: msgengine.c:2481
const void * GWEN_DB_GetBinValue(GWEN_DB_NODE *n, const char *path, int idx, const void *defVal, unsigned int defValSize, unsigned int *returnValueSize)
Definition: db.c:1235
GWEN_XMLNODE * GWEN_XMLNode_Path_Surface(GWEN_XMLNODE_PATH *np)
Definition: xml.c:1916
int(* GWEN_MSGENGINE_TYPEWRITE_PTR)(GWEN_MSGENGINE *e, GWEN_BUFFER *gbuf, GWEN_BUFFER *data, GWEN_XMLNODE *node)
Definition: msgengine.h:153
const char * GWEN_MsgEngine_GetCharsToEscape(GWEN_MSGENGINE *e)
Definition: msgengine.c:146
GWEN_MSGENGINE * GWEN_MsgEngine_new(void)
Definition: msgengine.c:66
GWEN_XMLNODE * GWEN_XMLNode_Next(const GWEN_XMLNODE *n)
Definition: xml.c:465
GWEN_XMLNODE * GWEN_XMLNode_FindNode(const GWEN_XMLNODE *node, GWEN_XMLNODE_TYPE t, const char *data)
Definition: xml.c:543
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:54
int GWEN_MsgEngine__ReadValue(GWEN_MSGENGINE *e, GWEN_BUFFER *msgbuf, GWEN_XMLNODE *node, GWEN_XMLNODE *rnode, GWEN_BUFFER *vbuf, const char *delimiters, uint32_t flags)
Definition: msgengine.c:2831
void GWEN_MsgEngine_SetDelimiters(GWEN_MSGENGINE *e, const char *s)
Definition: msgengine.c:154
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:399
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:969
int GWEN_MsgEngine_TrustedData_GetNextPos(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition: msgengine.c:3932
const char * GWEN_MsgEngine__TransformValue(GWEN_MSGENGINE *e, const char *pvalue, GWEN_XMLNODE *node, GWEN_XMLNODE *dnode, unsigned int *datasize)
Definition: msgengine.c:1156
#define GWEN_INHERIT_INIT(t, element)
Definition: inherit.h:223
int GWEN_DB_VariableExists(GWEN_DB_NODE *n, const char *path)
Definition: db.c:1563
GWEN_DB_NODE * GWEN_DB_GetGroup(GWEN_DB_NODE *n, uint32_t flags, const char *path)
Definition: db.c:1379
const char * GWEN_MsgEngine_GetDelimiters(GWEN_MSGENGINE *e)
Definition: msgengine.c:166
int GWEN_Buffer_DecrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:560
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:85
int GWEN_DB_DeleteVar(GWEN_DB_NODE *n, const char *path)
Definition: db.c:897
void GWEN_XMLNode_free(GWEN_XMLNODE *n)
Definition: xml.c:160
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:41
void GWEN_MsgEngine_SetGetIntValueFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_GETINTVALUE_PTR p)
Definition: msgengine.c:382
int GWEN_MsgEngine_GetHighestTrustLevel(GWEN_XMLNODE *node, GWEN_XMLNODE *refnode)
Definition: msgengine.c:1369
int GWEN_MsgEngine__IsCharTyp(GWEN_MSGENGINE *e, const char *type)
Definition: msgengine.c:637
GWEN_XMLNODE * GWEN_XMLNode_GetParent(const GWEN_XMLNODE *n)
Definition: xml.c:416
int GWEN_MsgEngine__IsBinTyp(GWEN_MSGENGINE *e, const char *type)
Definition: msgengine.c:676
int(* GWEN_MSGENGINE_TYPEREAD_PTR)(GWEN_MSGENGINE *e, GWEN_BUFFER *msgbuf, GWEN_XMLNODE *node, GWEN_BUFFER *vbuf, char escapeChar, const char *delimiters)
Definition: msgengine.h:143
const char * GWEN_MsgEngine__findInValues(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, GWEN_XMLNODE *dnode, const char *name, unsigned int *datasize)
Definition: msgengine.c:1484
void * GWEN_MsgEngine_GetInheritorData(const GWEN_MSGENGINE *e)
Definition: msgengine.c:401
int GWEN_MsgEngine__IsIntTyp(GWEN_MSGENGINE *e, const char *type)
Definition: msgengine.c:658
int GWEN_MsgEngine__ShowGroup(GWEN_MSGENGINE *e, const char *path, GWEN_XMLNODE *node, GWEN_STRINGLIST *sl, uint32_t flags)
Definition: msgengine.c:2271
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
Definition: buffer.c:1020
int GWEN_Text_NumToString(int num, char *buffer, unsigned int bufsize, int fillchar)
Definition: text.c:1243
GWEN_MSGENGINE_TRUSTLEVEL
Definition: msgengine.h:54
int GWEN_MsgEngine_CreateMessageFromNode(GWEN_MSGENGINE *e, GWEN_XMLNODE *node, GWEN_BUFFER *gbuf, GWEN_DB_NODE *msgData)
Definition: msgengine.c:2065
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
GWEN_XMLNODE * GWEN_XMLNode_GetFirstTag(const GWEN_XMLNODE *n)
Definition: xml.c:665
#define GWEN_MSGENGINE_READ_FLAGS_TRUSTINFO
Definition: msgengine.h:121
const char * GWEN_MsgEngine_GetMode(GWEN_MSGENGINE *e)
Definition: msgengine.c:191
const char * GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
Definition: xml.c:370
void GWEN_MsgEngine_SetGetCharValueFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_GETCHARVALUE_PTR p)
Definition: msgengine.c:373
int GWEN_Buffer_SetPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:261
struct GWEN__MSGENGINE GWEN_MSGENGINE
Definition: msgengine.h:131
int GWEN_MsgEngine_AddDefinitions(GWEN_MSGENGINE *e, GWEN_XMLNODE *node)
Definition: msgengine.c:2126
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:995
#define GWEN_MSGENGINE_SHOW_FLAGS_NOSET
Definition: msgengine.h:115
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:374
GWEN_XMLNODE_PATH * GWEN_XMLNode_Path_dup(const GWEN_XMLNODE_PATH *np)
Definition: xml.c:1873
GWEN_MSGENGINE_TYPEREAD_PTR GWEN_MsgEngine_GetTypeReadFunction(GWEN_MSGENGINE *e)
Definition: msgengine.c:294
int GWEN_MsgEngine__ListGroup(GWEN_MSGENGINE *e, const char *path, GWEN_XMLNODE *node, GWEN_STRINGLIST *sl, GWEN_XMLNODE *listNode, uint32_t flags)
Definition: msgengine.c:2604
int GWEN_MsgEngine__WriteGroup(GWEN_MSGENGINE *e, GWEN_BUFFER *gbuf, GWEN_XMLNODE *node, GWEN_XMLNODE *rnode, GWEN_DB_NODE *gr, int groupIsOptional, GWEN_XMLNODE_PATH *nodePath)
Definition: msgengine.c:1709
#define GWEN_MSGENGINE_MAX_VALUE_LEN
Definition: msgengine.h:116
GWEN_DB_NODE_TYPE GWEN_DB_GetValueTypeByPath(GWEN_DB_NODE *n, const char *path, unsigned int i)
Definition: db.c:1610
GWEN_XMLNODE * GWEN_XMLNode_dup(const GWEN_XMLNODE *n)
Definition: xml.c:187
char GWEN_MsgEngine_GetEscapeChar(GWEN_MSGENGINE *e)
Definition: msgengine.c:129
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:178
void GWEN_MsgEngine_SetTypeReadFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_TYPEREAD_PTR p)
Definition: msgengine.c:285
void GWEN_MsgEngine_SetBinTypeReadFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_BINTYPEREAD_PTR p)
Definition: msgengine.c:339
int GWEN_MsgEngine_SetValue(GWEN_MSGENGINE *e, const char *path, const char *value)
Definition: msgengine.c:3507
int GWEN_MsgEngine__WriteValue(GWEN_MSGENGINE *e, GWEN_BUFFER *gbuf, GWEN_BUFFER *data, GWEN_XMLNODE *node)
Definition: msgengine.c:420
GWEN_DB_NODE_TYPE
Definition: db.h:233
int GWEN_XMLNode_Path_Dive(GWEN_XMLNODE_PATH *np, GWEN_XMLNODE *n)
Definition: xml.c:1895
void GWEN_MsgEngine_SetProtocolVersion(GWEN_MSGENGINE *e, unsigned int p)
Definition: msgengine.c:232
int GWEN_Buffer_ReadByte(GWEN_BUFFER *bf)
Definition: buffer.c:500
int GWEN_MsgEngine_AddTrustInfo(GWEN_MSGENGINE *e, const char *data, unsigned int size, const char *description, GWEN_MSGENGINE_TRUSTLEVEL trustLevel, unsigned int pos)
Definition: msgengine.c:4042
const char *(* GWEN_MSGENGINE_GETCHARVALUE_PTR)(GWEN_MSGENGINE *e, const char *name, const char *defValue)
Definition: msgengine.h:177
void GWEN_MsgEngine_SetInheritorData(GWEN_MSGENGINE *e, void *d)
Definition: msgengine.c:409
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, const char *path, int idx, int defVal)
Definition: db.c:1161
int GWEN_Buffer_AppendBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
Definition: buffer.c:366
GWEN_DB_NODE * GWEN_DB_FindFirstGroup(GWEN_DB_NODE *n, const char *name)
Definition: db.c:1838
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition: db.c:171
void GWEN_Buffer_Rewind(GWEN_BUFFER *bf)
Definition: buffer.c:729
void GWEN_XMLNode_Path_free(GWEN_XMLNODE_PATH *np)
Definition: xml.c:1888
#define GWEN_LIST_ADD(typ, sr, head)
Definition: misc.h:82
int GWEN_MsgEngine__ReadGroup(GWEN_MSGENGINE *e, GWEN_BUFFER *msgbuf, GWEN_XMLNODE *node, GWEN_XMLNODE *rnode, GWEN_DB_NODE *gr, const char *delimiters, uint32_t flags)
Definition: msgengine.c:3042
int GWEN_DB_SetIntValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, int val)
Definition: db.c:1200
void GWEN_MsgEngine_SetTypeCheckFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_TYPECHECK_PTR p)
Definition: msgengine.c:319
void GWEN_MsgEngine_SetTypeWriteFunction(GWEN_MSGENGINE *e, GWEN_MSGENGINE_TYPEWRITE_PTR p)
Definition: msgengine.c:302
int GWEN_MsgEngine__ShowElement(GWEN_UNUSED GWEN_MSGENGINE *e, const char *path, GWEN_XMLNODE *node, GWEN_STRINGLIST *sl, uint32_t flags)
Definition: msgengine.c:2174
void GWEN_MsgEngine_SetMode(GWEN_MSGENGINE *e, const char *mode)
Definition: msgengine.c:174
int GWEN_Text_FromHexBuffer(const char *src, GWEN_BUFFER *buf)
Definition: text.c:897
int GWEN_MsgEngine_ParseMessage(GWEN_MSGENGINE *e, GWEN_XMLNODE *group, GWEN_BUFFER *msgbuf, GWEN_DB_NODE *msgData, uint32_t flags)
Definition: msgengine.c:3484
int GWEN_MsgEngine__ListElement(GWEN_UNUSED GWEN_MSGENGINE *e, const char *path, GWEN_XMLNODE *node, GWEN_STRINGLIST *sl, GWEN_XMLNODE *listNode, uint32_t flags)
Definition: msgengine.c:2541
unsigned int GWEN_MsgEngine_GetProtocolVersion(GWEN_MSGENGINE *e)
Definition: msgengine.c:221
void GWEN_MsgEngine_SetDefinitions(GWEN_MSGENGINE *e, GWEN_XMLNODE *n, int take)
Definition: msgengine.c:255
int GWEN_MsgEngine_GetIntValue(GWEN_MSGENGINE *e, const char *path, int defValue)
Definition: msgengine.c:3556
GWEN_STRINGLIST * GWEN_StringList_new(void)
Definition: stringlist.c:46
const char * GWEN_MsgEngine_TrustedData_GetDescription(GWEN_MSGENGINE_TRUSTEDDATA *td)
Definition: msgengine.c:3887
GWEN_DB_NODE * GWEN_DB_FindNextGroup(GWEN_DB_NODE *n, const char *name)
Definition: db.c:1859
#define GWEN_INHERIT_FUNCTIONS(t)
Definition: inherit.h:163
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:149
#define GWEN_UNUSED
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:1062
#define GWEN_DB_FLAGS_DEFAULT
Definition: db.h:168
void GWEN_MsgEngine_free(GWEN_MSGENGINE *e)
Definition: msgengine.c:82
const char * GWEN_MsgEngine_SearchForProperty(GWEN_XMLNODE *node, GWEN_XMLNODE *refnode, const char *name, int topDown)
Definition: msgengine.c:1333
void GWEN_XMLNode_AddChild(GWEN_XMLNODE *n, GWEN_XMLNODE *child)
Definition: xml.c:423