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