00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef HAVE_CONFIG_H
00026 # include <config.h>
00027 #endif
00028
00029 #define DISABLE_DEBUGLOG
00030
00031 #include <gwenhywfar/gwenhywfarapi.h>
00032 #include <msgengine_p.h>
00033 #include <gwenhywfar/xml.h>
00034 #include <gwenhywfar/text.h>
00035 #include <gwenhywfar/misc.h>
00036 #include <gwenhywfar/path.h>
00037 #include <gwenhywfar/debug.h>
00038 #include <gwenhywfar/buffer.h>
00039 #include <stdlib.h>
00040 #include <assert.h>
00041 #include <string.h>
00042 #include <ctype.h>
00043
00044
00045 GWEN_INHERIT_FUNCTIONS(GWEN_MSGENGINE)
00046
00047
00048 GWEN_MSGENGINE *GWEN_MsgEngine_new(void){
00049 GWEN_MSGENGINE *e;
00050
00051 GWEN_NEW_OBJECT(GWEN_MSGENGINE, e);
00052 GWEN_INHERIT_INIT(GWEN_MSGENGINE, e);
00053 e->charsToEscape=strdup(GWEN_MSGENGINE_CHARSTOESCAPE);
00054 e->delimiters=strdup(GWEN_MSGENGINE_DEFAULT_DELIMITERS);
00055 e->globalValues=GWEN_DB_Group_new("globalvalues");
00056 e->escapeChar='\\';
00057
00058 e->usage=1;
00059 return e;
00060 }
00061
00062
00063 void GWEN_MsgEngine_free(GWEN_MSGENGINE *e){
00064 if (e) {
00065 assert(e->usage);
00066 if (--(e->usage)==0) {
00067 GWEN_INHERIT_FINI(GWEN_MSGENGINE, e);
00068
00069 if (e->inheritorData && e->freeDataPtr)
00070 e->freeDataPtr(e);
00071 if (e->ownDefs)
00072 GWEN_XMLNode_free(e->defs);
00073 free(e->charsToEscape);
00074 free(e->delimiters);
00075 GWEN_DB_Group_free(e->globalValues);
00076 if (e->trustInfos) {
00077
00078 GWEN_MSGENGINE_TRUSTEDDATA *td, *tdn;
00079
00080 td=e->trustInfos;
00081 while(td) {
00082 tdn=td->next;
00083 GWEN_MsgEngine_TrustedData_free(td);
00084 td=tdn;
00085 }
00086 }
00087 GWEN_FREE_OBJECT(e);
00088 }
00089 }
00090 }
00091
00092
00093
00094 void GWEN_MsgEngine_Attach(GWEN_MSGENGINE *e){
00095 assert(e);
00096 e->usage++;
00097 }
00098
00099
00100 void GWEN_MsgEngine_SetEscapeChar(GWEN_MSGENGINE *e, char c){
00101 assert(e);
00102 e->escapeChar=c;
00103 }
00104
00105
00106
00107 char GWEN_MsgEngine_GetEscapeChar(GWEN_MSGENGINE *e){
00108 assert(e);
00109 return e->escapeChar;
00110 }
00111
00112
00113
00114 void GWEN_MsgEngine_SetCharsToEscape(GWEN_MSGENGINE *e, const char *c){
00115 assert(e);
00116 free(e->charsToEscape);
00117 e->charsToEscape=strdup(c);
00118 }
00119
00120
00121
00122 const char *GWEN_MsgEngine_GetCharsToEscape(GWEN_MSGENGINE *e){
00123 assert(e);
00124 return e->charsToEscape;
00125 }
00126
00127
00128
00129 void GWEN_MsgEngine_SetDelimiters(GWEN_MSGENGINE *e, const char *s){
00130 assert(e);
00131 free(e->delimiters);
00132 if (s)
00133 e->delimiters=strdup(s);
00134 else
00135 e->delimiters=strdup(GWEN_MSGENGINE_DEFAULT_DELIMITERS);
00136 }
00137
00138
00139
00140 const char *GWEN_MsgEngine_GetDelimiters(GWEN_MSGENGINE *e){
00141 assert(e);
00142 return e->delimiters;
00143 }
00144
00145
00146
00147 void GWEN_MsgEngine_SetMode(GWEN_MSGENGINE *e, const char *mode){
00148 GWEN_DB_NODE *db;
00149
00150 assert(e);
00151 db=GWEN_MsgEngine__GetGlobalValues(e);
00152
00153 if (mode)
00154 GWEN_DB_SetCharValue(db,
00155 GWEN_DB_FLAGS_OVERWRITE_VARS,
00156 "engine/secmode",
00157 mode);
00158 else
00159 GWEN_DB_DeleteVar(db, "engine/secmode");
00160 }
00161
00162
00163 const char *GWEN_MsgEngine_GetMode(GWEN_MSGENGINE *e){
00164 GWEN_DB_NODE *db;
00165
00166 assert(e);
00167 db=GWEN_MsgEngine__GetGlobalValues(e);
00168 return GWEN_DB_GetCharValue(db, "engine/secmode", 0, 0);
00169 }
00170
00171
00172
00173 GWEN_DB_NODE *GWEN_MsgEngine__GetGlobalValues(GWEN_MSGENGINE *e){
00174 GWEN_DB_NODE *globalValues;
00175
00176 assert(e);
00177 if (e->getGlobalValuesPtr) {
00178 globalValues=e->getGlobalValuesPtr(e);
00179 if (!globalValues)
00180 globalValues=e->globalValues;
00181 }
00182 else {
00183 globalValues=e->globalValues;
00184 }
00185 assert(globalValues);
00186 return globalValues;
00187 }
00188
00189
00190
00191 unsigned int GWEN_MsgEngine_GetProtocolVersion(GWEN_MSGENGINE *e){
00192 GWEN_DB_NODE *db;
00193
00194 assert(e);
00195 db=GWEN_MsgEngine__GetGlobalValues(e);
00196 return GWEN_DB_GetIntValue(db, "engine/pversion", 0, 0);
00197 }
00198
00199
00200
00201 void GWEN_MsgEngine_SetProtocolVersion(GWEN_MSGENGINE *e,
00202 unsigned int p){
00203 GWEN_DB_NODE *db;
00204
00205 assert(e);
00206 db=GWEN_MsgEngine__GetGlobalValues(e);
00207
00208 GWEN_DB_SetIntValue(db,
00209 GWEN_DB_FLAGS_OVERWRITE_VARS,
00210 "engine/pversion",
00211 p);
00212 }
00213
00214
00215
00216 GWEN_XMLNODE *GWEN_MsgEngine_GetDefinitions(GWEN_MSGENGINE *e){
00217 assert(e);
00218 return e->defs;
00219 }
00220
00221
00222 void GWEN_MsgEngine_SetDefinitions(GWEN_MSGENGINE *e,
00223 GWEN_XMLNODE *n,
00224 int take){
00225 assert(e);
00226 if (e->ownDefs)
00227 GWEN_XMLNode_free(e->defs);
00228 e->defs=n;
00229 e->ownDefs=take;
00230 }
00231
00232
00233
00234 void
00235 GWEN_MsgEngine_SetGetGlobalValuesFunction(GWEN_MSGENGINE *e,
00236 GWEN_MSGENGINE_GETGLOBALVALUES_PTR p){
00237 assert(e);
00238 e->getGlobalValuesPtr=p;
00239 }
00240
00241
00242
00243 GWEN_MSGENGINE_GETGLOBALVALUES_PTR
00244 GWEN_MsgEngine_GetGetGlobalValuesFunction(GWEN_MSGENGINE *e){
00245 assert(e);
00246 return e->getGlobalValuesPtr;
00247 }
00248
00249
00250
00251 void GWEN_MsgEngine_SetTypeReadFunction(GWEN_MSGENGINE *e,
00252 GWEN_MSGENGINE_TYPEREAD_PTR p){
00253 assert(e);
00254 e->typeReadPtr=p;
00255 }
00256
00257
00258
00259 GWEN_MSGENGINE_TYPEREAD_PTR
00260 GWEN_MsgEngine_GetTypeReadFunction(GWEN_MSGENGINE *e){
00261 assert(e);
00262 return e->typeReadPtr;
00263 }
00264
00265
00266
00267 void GWEN_MsgEngine_SetTypeWriteFunction(GWEN_MSGENGINE *e,
00268 GWEN_MSGENGINE_TYPEWRITE_PTR p){
00269 assert(e);
00270 e->typeWritePtr=p;
00271 }
00272
00273
00274
00275 GWEN_MSGENGINE_TYPEWRITE_PTR
00276 GWEN_MsgEngine_GetTypeWriteFunction(GWEN_MSGENGINE *e){
00277 assert(e);
00278 return e->typeWritePtr;
00279 }
00280
00281
00282
00283 void GWEN_MsgEngine_SetTypeCheckFunction(GWEN_MSGENGINE *e,
00284 GWEN_MSGENGINE_TYPECHECK_PTR p){
00285 assert(e);
00286 e->typeCheckPtr=p;
00287 }
00288
00289
00290
00291 GWEN_MSGENGINE_TYPECHECK_PTR
00292 GWEN_MsgEngine_GetTypeCheckFunction(GWEN_MSGENGINE *e){
00293 assert(e);
00294 return e->typeCheckPtr;
00295 }
00296
00297
00298
00299
00300
00301
00302 void GWEN_MsgEngine_SetBinTypeReadFunction(GWEN_MSGENGINE *e,
00303 GWEN_MSGENGINE_BINTYPEREAD_PTR p){
00304 assert(e);
00305 e->binTypeReadPtr=p;
00306 }
00307
00308
00309
00310 GWEN_MSGENGINE_BINTYPEREAD_PTR
00311 GWEN_MsgEngine_GetBinTypeReadFunction(GWEN_MSGENGINE *e){
00312 assert(e);
00313 return e->binTypeReadPtr;
00314 }
00315
00316
00317
00318 void
00319 GWEN_MsgEngine_SetBinTypeWriteFunction(GWEN_MSGENGINE *e,
00320 GWEN_MSGENGINE_BINTYPEWRITE_PTR p){
00321 assert(e);
00322 e->binTypeWritePtr=p;
00323 }
00324
00325
00326
00327 GWEN_MSGENGINE_BINTYPEWRITE_PTR
00328 GWEN_MsgEngine_GetBinTypeWriteFunction(GWEN_MSGENGINE *e){
00329 assert(e);
00330 return e->binTypeWritePtr;
00331 }
00332
00333
00334
00335 void
00336 GWEN_MsgEngine_SetGetCharValueFunction(GWEN_MSGENGINE *e,
00337 GWEN_MSGENGINE_GETCHARVALUE_PTR p){
00338 assert(e);
00339 e->getCharValuePtr=p;
00340 }
00341
00342
00343
00344 void
00345 GWEN_MsgEngine_SetGetIntValueFunction(GWEN_MSGENGINE *e,
00346 GWEN_MSGENGINE_GETINTVALUE_PTR p){
00347 assert(e);
00348 e->getIntValuePtr=p;
00349 }
00350
00351
00352
00353 void
00354 GWEN_MsgEngine_SetFreeDataFunction(GWEN_MSGENGINE *e,
00355 GWEN_MSGENGINE_FREEDATA_PTR p){
00356 assert(e);
00357 DBG_WARN(GWEN_LOGDOMAIN, "GWEN_MsgEngine_SetFreeDataFunction: Deprecated");
00358 e->freeDataPtr=p;
00359 }
00360
00361
00362
00363 void *GWEN_MsgEngine_GetInheritorData(const GWEN_MSGENGINE *e){
00364 assert(e);
00365 return e->inheritorData;
00366 }
00367
00368
00369
00370 void GWEN_MsgEngine_SetInheritorData(GWEN_MSGENGINE *e, void *d){
00371 assert(e);
00372 DBG_WARN(GWEN_LOGDOMAIN, "GWEN_MsgEngine_SetInheritorData: Deprecated");
00373 if (e->inheritorData && e->freeDataPtr)
00374 e->freeDataPtr(e);
00375 e->inheritorData=d;
00376 }
00377
00378
00379
00380 int GWEN_MsgEngine__WriteValue(GWEN_MSGENGINE *e,
00381 GWEN_BUFFER *gbuf,
00382 GWEN_BUFFER *data,
00383 GWEN_XMLNODE *node) {
00384 unsigned int minsize;
00385 unsigned int maxsize;
00386 unsigned int fixSize;
00387 unsigned int startPos;
00388 int filler;
00389 const char *type;
00390 const char *name;
00391 int rv;
00392
00393
00394 minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize","0"));
00395 maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize","0"));
00396 fixSize=atoi(GWEN_XMLNode_GetProperty(node, "size","0"));
00397 filler=atoi(GWEN_XMLNode_GetProperty(node, "filler","0"));
00398 type=GWEN_XMLNode_GetProperty(node, "type","ASCII");
00399 name=GWEN_XMLNode_GetProperty(node, "name","<unnamed>");
00400 startPos=GWEN_Buffer_GetPos(gbuf);
00401
00402
00403 if (minsize && GWEN_Buffer_GetUsedBytes(data)<minsize) {
00404 DBG_ERROR(GWEN_LOGDOMAIN, "Data too short (minsize is %d)", minsize);
00405 return -1;
00406 }
00407 if (maxsize && GWEN_Buffer_GetUsedBytes(data)>maxsize) {
00408 DBG_ERROR(GWEN_LOGDOMAIN, "Data too long (maxsize is %d)", maxsize);
00409 return -1;
00410 }
00411
00412 rv=1;
00413 if (e->typeWritePtr) {
00414 rv=e->typeWritePtr(e,
00415 gbuf,
00416 data,
00417 node);
00418 }
00419 if (rv==-1) {
00420 DBG_INFO(GWEN_LOGDOMAIN, "External type writing failed");
00421 return -1;
00422 }
00423 else if (rv==1) {
00424 int i;
00425
00426
00427 if (strcasecmp(type, "bin")==0) {
00428 DBG_DEBUG(GWEN_LOGDOMAIN, "Writing binary data (%d bytes added to %d bytes)",
00429 GWEN_Buffer_GetUsedBytes(data),
00430 GWEN_Buffer_GetUsedBytes(gbuf));
00431 if (GWEN_Buffer_AllocRoom(gbuf, 10+GWEN_Buffer_GetUsedBytes(data))) {
00432 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
00433 return -1;
00434 }
00435 sprintf(GWEN_Buffer_GetPosPointer(gbuf),
00436 "@%d@",
00437 GWEN_Buffer_GetUsedBytes(data));
00438
00439
00440 i=strlen(GWEN_Buffer_GetPosPointer(gbuf));
00441 GWEN_Buffer_IncrementPos(gbuf, i);
00442 GWEN_Buffer_AdjustUsedBytes(gbuf);
00443 GWEN_Buffer_AppendBuffer(gbuf, data);
00444 }
00445 else if (strcasecmp(type, "num")==0) {
00446 int num;
00447 unsigned int len;
00448 unsigned int lj;
00449
00450 num=atoi(GWEN_Buffer_GetPosPointer(data));
00451 len=strlen(GWEN_Buffer_GetPosPointer(data));
00452
00453 if (atoi(GWEN_XMLNode_GetProperty(node, "leftfill","0"))) {
00454 if (GWEN_Buffer_AllocRoom(gbuf, maxsize+1)) {
00455 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
00456 return -1;
00457 }
00458
00459
00460 for (lj=0; lj<(maxsize-len); lj++)
00461 GWEN_Buffer_AppendByte(gbuf, '0');
00462
00463
00464 for (lj=0; lj<len; lj++)
00465 GWEN_Buffer_AppendByte(gbuf, GWEN_Buffer_ReadByte(data));
00466 }
00467 else if (atoi(GWEN_XMLNode_GetProperty(node, "rightfill","0"))) {
00468 if (GWEN_Buffer_AllocRoom(gbuf, maxsize+1)) {
00469 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
00470 return -1;
00471 }
00472
00473
00474 for (lj=0; lj<len; lj++)
00475 GWEN_Buffer_AppendByte(gbuf, GWEN_Buffer_ReadByte(data));
00476
00477
00478 for (lj=0; lj<(maxsize-len); lj++)
00479 GWEN_Buffer_AppendByte(gbuf, '0');
00480 }
00481 else {
00482 if (GWEN_Buffer_AllocRoom(gbuf, maxsize+1)) {
00483 DBG_ERROR(GWEN_LOGDOMAIN, "Maxsize in XML file is higher than the buffer size");
00484 return -1;
00485 }
00486 for (lj=0; lj<len; lj++)
00487 GWEN_Buffer_AppendByte(gbuf, GWEN_Buffer_ReadByte(data));
00488 }
00489 }
00490 else {
00491
00492 const char *p;
00493 int lastWasEscape;
00494 unsigned int pcount;
00495
00496 p=GWEN_Buffer_GetPosPointer(data);
00497 pcount=0;
00498 lastWasEscape=0;
00499 while(*p && pcount<GWEN_Buffer_GetUsedBytes(data)) {
00500 int c;
00501
00502 c=(unsigned char)*p;
00503 if (lastWasEscape) {
00504 lastWasEscape=0;
00505 switch(c) {
00506 case 'r': c='\r'; break;
00507 case 'n': c='\n'; break;
00508 case 'f': c='\f'; break;
00509 case 't': c='\t'; break;
00510 default: c=(unsigned char)*p;
00511 }
00512 }
00513 else {
00514 if (*p=='\\') {
00515 lastWasEscape=1;
00516 c=-1;
00517 }
00518 else
00519 c=(unsigned char)*p;
00520 }
00521 if (c!=-1) {
00522 int needsEscape;
00523
00524 needsEscape=0;
00525 if (c==e->escapeChar)
00526 needsEscape=1;
00527 else {
00528 if (e->charsToEscape)
00529 if (strchr(e->charsToEscape, c))
00530 needsEscape=1;
00531 }
00532 if (needsEscape) {
00533
00534 if (GWEN_Buffer_AppendByte(gbuf,
00535 e->escapeChar)) {
00536 return -1;
00537 }
00538 }
00539 if (GWEN_Buffer_AppendByte(gbuf, c)) {
00540 return -1;
00541 }
00542 }
00543 p++;
00544 pcount++;
00545 }
00546 if (pcount<GWEN_Buffer_GetUsedBytes(data)) {
00547 DBG_WARN(GWEN_LOGDOMAIN, "Premature end of string (%d<%d)",
00548 pcount, GWEN_Buffer_GetUsedBytes(data));
00549 }
00550 if (*p) {
00551 DBG_WARN(GWEN_LOGDOMAIN,
00552 "String for \"%s\" (type %s) is longer than expected "
00553 "(no #0 at pos=%d)",
00554 name, type,
00555 GWEN_Buffer_GetUsedBytes(data)-1);
00556 }
00557 }
00558 }
00559 else {
00560 DBG_INFO(GWEN_LOGDOMAIN, "Type \"%s\" (for %s) is external (write)",
00561 type, name);
00562
00563 }
00564
00565
00566 if (fixSize) {
00567 uint32_t bs;
00568 unsigned int j;
00569
00570 bs=GWEN_Buffer_GetPos(gbuf)-startPos;
00571 if (bs>fixSize) {
00572 DBG_ERROR(GWEN_LOGDOMAIN,
00573 "Data too long (size is %d, fixed size is %d)",
00574 bs, fixSize);
00575 return -1;
00576 }
00577
00578 for (j=bs; j<fixSize; j++)
00579 GWEN_Buffer_AppendByte(gbuf, (unsigned char)filler);
00580 }
00581
00582 return 0;
00583 }
00584
00585
00586
00587 int GWEN_MsgEngine__IsCharTyp(GWEN_MSGENGINE *e,
00588 const char *type) {
00589 if (e->typeCheckPtr) {
00590 GWEN_DB_NODE_TYPE vt;
00591
00592 vt=e->typeCheckPtr(e, type);
00593 if (vt!=GWEN_DB_NodeType_Unknown) {
00594 if (vt==GWEN_DB_NodeType_ValueChar)
00595 return 1;
00596 }
00597 }
00598 return
00599 (strcasecmp(type, "alpha")==0) ||
00600 (strcasecmp(type, "ascii")==0) ||
00601 (strcasecmp(type, "an")==0) ||
00602 (strcasecmp(type, "float")==0);
00603 }
00604
00605
00606
00607 int GWEN_MsgEngine__IsIntTyp(GWEN_MSGENGINE *e,
00608 const char *type) {
00609 if (e->typeCheckPtr) {
00610 GWEN_DB_NODE_TYPE vt;
00611
00612 vt=e->typeCheckPtr(e, type);
00613 if (vt!=GWEN_DB_NodeType_Unknown) {
00614 if (vt==GWEN_DB_NodeType_ValueInt)
00615 return 1;
00616 }
00617 }
00618 return
00619 (strcasecmp(type, "num")==0);
00620 }
00621
00622
00623
00624 int GWEN_MsgEngine__IsBinTyp(GWEN_MSGENGINE *e,
00625 const char *type) {
00626 if (e->typeCheckPtr) {
00627 GWEN_DB_NODE_TYPE vt;
00628
00629 vt=e->typeCheckPtr(e, type);
00630 if (vt!=GWEN_DB_NodeType_Unknown) {
00631 if (vt==GWEN_DB_NodeType_ValueBin)
00632 return 1;
00633 }
00634 }
00635 return
00636 (strcasecmp(type, "bin")==0);
00637 }
00638
00639
00640
00641 int GWEN_MsgEngine__GetInline(GWEN_MSGENGINE *e,
00642 GWEN_XMLNODE *node,
00643 GWEN_BUFFER *mbuf) {
00644
00645 GWEN_XMLNODE *n;
00646 const char *type;
00647
00648
00649 type=GWEN_XMLNode_GetProperty(node, "type", "ascii");
00650 DBG_DEBUG(GWEN_LOGDOMAIN,
00651 "Getting data of type \"%s\" from within XML file", type);
00652 n=GWEN_XMLNode_GetFirstData(node);
00653 if (!n) {
00654 DBG_DEBUG(GWEN_LOGDOMAIN, "No child");
00655 return 1;
00656 }
00657
00658 if (GWEN_MsgEngine__IsBinTyp(e, type)) {
00659 const char *dp;
00660 unsigned int dplen;
00661 const char *stype;
00662
00663 stype=GWEN_XMLNode_GetProperty(node, "storedAs", type);
00664 if (GWEN_MsgEngine__IsBinTyp(e, stype)) {
00665 dp=GWEN_XMLNode_GetData(n);
00666 dplen=strlen(dp);
00667 if (GWEN_Text_FromHexBuffer(dp, mbuf)) {
00668 DBG_INFO(GWEN_LOGDOMAIN, "here");
00669 return -1;
00670 }
00671 }
00672 else {
00673
00674 GWEN_Buffer_AppendString(mbuf, GWEN_XMLNode_GetData(n));
00675 }
00676 }
00677 else {
00678 GWEN_Buffer_AppendString(mbuf, GWEN_XMLNode_GetData(n));
00679 }
00680
00681 return 0;
00682 }
00683
00684
00685
00686
00687
00688 int GWEN_MsgEngine__WriteElement(GWEN_MSGENGINE *e,
00689 GWEN_BUFFER *gbuf,
00690 GWEN_XMLNODE *node,
00691 GWEN_XMLNODE *rnode,
00692 GWEN_DB_NODE *gr,
00693 int loopNr,
00694 int isOptional,
00695 GWEN_XMLNODE_PATH *nodePath) {
00696 const char *name;
00697 const char *type;
00698 unsigned int minsize;
00699 unsigned int maxsize;
00700 char numbuffer[256];
00701 const char *pdata;
00702 unsigned int datasize;
00703 GWEN_BUFFER *data;
00704 GWEN_BUFFER *tdata;
00705 int handled;
00706
00707 pdata=0;
00708 handled=0;
00709 data=0;
00710 tdata=0;
00711
00712
00713 type=GWEN_XMLNode_GetProperty(node, "type","ASCII");
00714 DBG_DEBUG(GWEN_LOGDOMAIN, "Type is \"%s\"", type);
00715
00716 minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize","0"));
00717 maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize","0"));
00718
00719 if (e->binTypeWritePtr &&
00720 GWEN_MsgEngine__IsBinTyp(e, type) &&
00721 atoi(GWEN_XMLNode_GetProperty(node, "writebin", "1"))) {
00722 int rv;
00723
00724 data=GWEN_Buffer_new(0,
00725 64,
00726 0,
00727 1);
00728
00729 rv=e->binTypeWritePtr(e, node, gr, data);
00730 if (rv==-1) {
00731
00732 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
00733 return -1;
00734 }
00735 else if (rv==0) {
00736 handled=1;
00737 }
00738 else if (rv==1) {
00739 GWEN_Buffer_free(data);
00740 data=0;
00741 }
00742 }
00743
00744 if (!handled) {
00745
00746 name=GWEN_XMLNode_GetProperty(node, "name", 0);
00747 if (!name) {
00748 int rv;
00749
00750
00751 tdata=GWEN_Buffer_new(0, 32, 0, 1);
00752 GWEN_Buffer_SetStep(tdata, 256);
00753 rv=GWEN_MsgEngine__GetInline(e, node, tdata);
00754 if (rv==0) {
00755 pdata=GWEN_Buffer_GetStart(tdata);
00756 datasize=GWEN_Buffer_GetUsedBytes(tdata);
00757 }
00758 else {
00759 GWEN_Buffer_free(tdata);
00760 tdata=0;
00761 pdata="";
00762 datasize=0;
00763 }
00764 }
00765 else {
00766 const char *nptr;
00767
00768 DBG_DEBUG(GWEN_LOGDOMAIN, "Name provided (%s), loop is %d", name, loopNr);
00769 nptr=name;
00770
00771 if (gr) {
00772 GWEN_DB_NODE_TYPE vt;
00773 int idata;
00774
00775
00776
00777 vt=GWEN_DB_GetValueTypeByPath(gr, nptr, loopNr);
00778 if (vt==GWEN_DB_NodeType_Unknown) {
00779 if (GWEN_MsgEngine__IsCharTyp(e, type))
00780 vt=GWEN_DB_NodeType_ValueChar;
00781 else if (GWEN_MsgEngine__IsIntTyp(e, type))
00782 vt=GWEN_DB_NodeType_ValueInt;
00783 else if (GWEN_MsgEngine__IsBinTyp(e, type))
00784 vt=GWEN_DB_NodeType_ValueBin;
00785 else {
00786 DBG_INFO(GWEN_LOGDOMAIN,
00787 "Unable to determine parameter "
00788 "type (%s), assuming \"char\" for this matter", type);
00789 vt=GWEN_DB_NodeType_ValueChar;
00790 }
00791 }
00792
00793
00794 switch(vt) {
00795 case GWEN_DB_NodeType_ValueChar:
00796 DBG_DEBUG(GWEN_LOGDOMAIN, "Type of \"%s\" is char", name);
00797 pdata=GWEN_DB_GetCharValue(gr, nptr, loopNr, 0);
00798 if (pdata) {
00799 DBG_DEBUG(GWEN_LOGDOMAIN, "Value of \"%s\" is %s", nptr, pdata);
00800 datasize=strlen(pdata);
00801 }
00802 else
00803 datasize=0;
00804 break;
00805
00806 case GWEN_DB_NodeType_ValueInt:
00807 DBG_DEBUG(GWEN_LOGDOMAIN, "Type of \"%s\" is int", name);
00808 if (GWEN_DB_ValueExists(gr, nptr, loopNr)) {
00809 idata=GWEN_DB_GetIntValue(gr, nptr, loopNr, 0);
00810 if (-1==GWEN_Text_NumToString(idata, numbuffer,
00811 sizeof(numbuffer),0)) {
00812 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
00813 GWEN_Buffer_free(data);
00814 return -1;
00815 }
00816 DBG_DEBUG(GWEN_LOGDOMAIN, "Value of \"%s\" is %d", nptr, idata);
00817 pdata=numbuffer;
00818 datasize=strlen(numbuffer);
00819 }
00820 break;
00821
00822 case GWEN_DB_NodeType_ValueBin:
00823 DBG_DEBUG(GWEN_LOGDOMAIN, "Type of \"%s\" is bin", name);
00824 pdata=GWEN_DB_GetBinValue(gr, nptr, loopNr, 0, 0, &datasize);
00825 break;
00826
00827 default:
00828 DBG_WARN(GWEN_LOGDOMAIN, "Unsupported parameter type (%d)", vt);
00829 break;
00830 }
00831 }
00832
00833 if (!pdata) {
00834 GWEN_XMLNODE_PATH *copyOfNodePath;
00835
00836 copyOfNodePath=GWEN_XMLNode_Path_dup(nodePath);
00837
00838
00839 DBG_DEBUG(GWEN_LOGDOMAIN, "Searching for value of \"%s\"", name);
00840 pdata=GWEN_MsgEngine__SearchForValue(e,
00841 node, copyOfNodePath, nptr,
00842 &datasize);
00843 GWEN_XMLNode_Path_free(copyOfNodePath);
00844 if (pdata) {
00845 DBG_DEBUG(GWEN_LOGDOMAIN, "Found value of \"%s\"", name);
00846 }
00847 }
00848
00849 if (!pdata) {
00850 int rv;
00851
00852
00853 tdata=GWEN_Buffer_new(0, 32, 0, 1);
00854 GWEN_Buffer_SetStep(tdata, 256);
00855 rv=GWEN_MsgEngine__GetInline(e, node, tdata);
00856 if (rv==0) {
00857 pdata=GWEN_Buffer_GetStart(tdata);
00858 datasize=GWEN_Buffer_GetUsedBytes(tdata);
00859 }
00860 else {
00861 GWEN_Buffer_free(tdata);
00862 tdata=0;
00863 }
00864 }
00865
00866 if (pdata==0) {
00867 if (isOptional) {
00868 DBG_INFO(GWEN_LOGDOMAIN, "Value not found, omitting element \"%s[%d]\"",
00869 name, loopNr);
00870 GWEN_Buffer_free(data);
00871 return 1;
00872 }
00873 else {
00874 DBG_ERROR(GWEN_LOGDOMAIN,
00875 "Value for element \"%s[%d]\" (mode \"%s\") not found",
00876 name, loopNr,
00877 GWEN_MsgEngine_GetMode(e));
00878 GWEN_DB_Dump(gr, 4);
00879 GWEN_Buffer_free(data);
00880 return -1;
00881 }
00882 }
00883 }
00884
00885 if (!data)
00886 data=GWEN_Buffer_new((char*)pdata,
00887 datasize,
00888 datasize,
00889 0 );
00890 }
00891
00892
00893 if (GWEN_MsgEngine__WriteValue(e,
00894 gbuf,
00895 data,
00896 node)!=0) {
00897 DBG_INFO(GWEN_LOGDOMAIN, "Could not write value");
00898 GWEN_Buffer_free(data);
00899 GWEN_Buffer_free(tdata);
00900 return -1;
00901 }
00902 GWEN_Buffer_free(data);
00903 GWEN_Buffer_free(tdata);
00904
00905 return 0;
00906 }
00907
00908
00909
00910 GWEN_XMLNODE *GWEN_MsgEngine_FindGroupByProperty(GWEN_MSGENGINE *e,
00911 const char *pname,
00912 int version,
00913 const char *pvalue) {
00914 return GWEN_MsgEngine_FindNodeByProperty(e, "GROUP", pname, version, pvalue);
00915 }
00916
00917
00918
00919 GWEN_XMLNODE *GWEN_MsgEngine_FindNodeByProperty(GWEN_MSGENGINE *e,
00920 const char *t,
00921 const char *pname,
00922 int version,
00923 const char *pvalue) {
00924 GWEN_XMLNODE *n;
00925 const char *p;
00926 int i;
00927 const char *mode;
00928 unsigned int proto;
00929 char buffer[256];
00930
00931 if ((strlen(t)+4)>sizeof(buffer)) {
00932 DBG_ERROR(GWEN_LOGDOMAIN, "Type name too long.");
00933 return 0;
00934 }
00935
00936 mode=GWEN_MsgEngine_GetMode(e);
00937 proto=GWEN_MsgEngine_GetProtocolVersion(e);
00938 if (!e->defs) {
00939 DBG_INFO(GWEN_LOGDOMAIN, "No definitions available");
00940 return 0;
00941 }
00942 n=e->defs;
00943 n=GWEN_XMLNode_GetChild(n);
00944
00945
00946 strcpy(buffer, t);
00947 strcat(buffer,"S");
00948 while(n) {
00949 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
00950 p=GWEN_XMLNode_GetData(n);
00951 assert(p);
00952 if (strcasecmp(p, buffer)==0)
00953 break;
00954 }
00955 n=GWEN_XMLNode_Next(n);
00956 }
00957
00958 if (!n) {
00959 DBG_INFO(GWEN_LOGDOMAIN, "No definitions available for type \"%s\"", t);
00960 return 0;
00961 }
00962
00963
00964 if (!mode)
00965 mode="";
00966 n=GWEN_XMLNode_GetChild(n);
00967 if (!n) {
00968 DBG_INFO(GWEN_LOGDOMAIN, "No definitions inside \"%s\"", buffer);
00969 return 0;
00970 }
00971
00972
00973 strcpy(buffer, t);
00974 strcat(buffer,"def");
00975 while(n) {
00976 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
00977 p=GWEN_XMLNode_GetData(n);
00978 assert(p);
00979 if (strcasecmp(p, buffer)==0) {
00980 p=GWEN_XMLNode_GetProperty(n, pname,"");
00981 if (strcasecmp(p, pvalue)==0) {
00982 i=atoi(GWEN_XMLNode_GetProperty(n, "pversion" ,"0"));
00983 if (proto==0 || (int)proto==i || i==0) {
00984 i=atoi(GWEN_XMLNode_GetProperty(n, "version" ,"0"));
00985 if (version==0 || version==i) {
00986 p=GWEN_XMLNode_GetProperty(n, "mode","");
00987 if (strcasecmp(p, mode)==0 || !*p) {
00988 DBG_DEBUG(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\" found",
00989 pname, pvalue);
00990 return n;
00991 }
00992 }
00993 }
00994 }
00995 }
00996 }
00997 n=GWEN_XMLNode_Next(n);
00998 }
00999
01000 DBG_INFO(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\"(%d) not found",
01001 pname,
01002 pvalue,
01003 version);
01004 return 0;
01005 }
01006
01007
01008
01009 GWEN_XMLNODE *GWEN_MsgEngine_FindNodeByPropertyStrictProto(GWEN_MSGENGINE *e,
01010 const char *t,
01011 const char *pname,
01012 int version,
01013 const char *pvalue) {
01014 GWEN_XMLNODE *n;
01015 const char *p;
01016 int i;
01017 const char *mode;
01018 unsigned int proto;
01019 char buffer[256];
01020
01021 if ((strlen(t)+4)>sizeof(buffer)) {
01022 DBG_ERROR(GWEN_LOGDOMAIN, "Type name too long.");
01023 return 0;
01024 }
01025
01026 mode=GWEN_MsgEngine_GetMode(e);
01027 proto=GWEN_MsgEngine_GetProtocolVersion(e);
01028 if (!e->defs) {
01029 DBG_INFO(GWEN_LOGDOMAIN, "No definitions available");
01030 return 0;
01031 }
01032 n=e->defs;
01033 n=GWEN_XMLNode_GetChild(n);
01034
01035
01036 strcpy(buffer, t);
01037 strcat(buffer,"S");
01038 while(n) {
01039 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
01040 p=GWEN_XMLNode_GetData(n);
01041 assert(p);
01042 if (strcasecmp(p, buffer)==0)
01043 break;
01044 }
01045 n=GWEN_XMLNode_Next(n);
01046 }
01047
01048 if (!n) {
01049 DBG_INFO(GWEN_LOGDOMAIN, "No definitions available for type \"%s\"", t);
01050 return 0;
01051 }
01052
01053
01054 if (!mode)
01055 mode="";
01056 n=GWEN_XMLNode_GetChild(n);
01057 if (!n) {
01058 DBG_INFO(GWEN_LOGDOMAIN, "No definitions inside \"%s\"", buffer);
01059 return 0;
01060 }
01061
01062
01063 strcpy(buffer, t);
01064 strcat(buffer,"def");
01065 while(n) {
01066 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
01067 p=GWEN_XMLNode_GetData(n);
01068 assert(p);
01069 if (strcasecmp(p, buffer)==0) {
01070 p=GWEN_XMLNode_GetProperty(n, pname,"");
01071 if (strcasecmp(p, pvalue)==0) {
01072 i=atoi(GWEN_XMLNode_GetProperty(n, "pversion" ,"0"));
01073 if (proto==0 || (int)proto==i) {
01074 i=atoi(GWEN_XMLNode_GetProperty(n, "version" ,"0"));
01075 if (version==0 || version==i) {
01076 p=GWEN_XMLNode_GetProperty(n, "mode","");
01077 if (strcasecmp(p, mode)==0 || !*p) {
01078 DBG_DEBUG(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\" found",
01079 pname, pvalue);
01080 return n;
01081 }
01082 }
01083 }
01084 }
01085 }
01086 }
01087 n=GWEN_XMLNode_Next(n);
01088 }
01089
01090 DBG_INFO(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\"(%d) not found",
01091 pname,
01092 pvalue,
01093 version);
01094 return 0;
01095 }
01096
01097
01098
01099 const char *GWEN_MsgEngine__TransformValue(GWEN_MSGENGINE *e,
01100 const char *pvalue,
01101 GWEN_XMLNODE *node,
01102 GWEN_XMLNODE *dnode,
01103 unsigned int *datasize) {
01104 const char *p;
01105 static char pbuffer[256];
01106 GWEN_DB_NODE *globalValues;
01107
01108 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
01109 assert(globalValues);
01110
01111 if (pvalue) {
01112 DBG_DEBUG(GWEN_LOGDOMAIN, "Transforming value \"%s\"", pvalue);
01113
01114 p=pvalue;
01115 while (*p && isspace((int)*p))
01116 p++;
01117 if (*p=='$' || *p=='+') {
01118
01119 int incr;
01120
01121 incr=(*p=='+');
01122 p++;
01123
01124 DBG_DEBUG(GWEN_LOGDOMAIN, "Getting global property \"%s\"", p);
01125 if (incr) {
01126 int z;
01127
01128 z=GWEN_DB_GetIntValue(globalValues, p, 0, 0);
01129 DBG_DEBUG(GWEN_LOGDOMAIN, "Incrementing global property \"%s\" (%d)",
01130 p, z);
01131 if (GWEN_Text_NumToString(z, pbuffer, sizeof(pbuffer),0)<1) {
01132 DBG_ERROR(GWEN_LOGDOMAIN, "Error converting num to string");
01133 return 0;
01134 }
01135
01136 z++;
01137 DBG_DEBUG(GWEN_LOGDOMAIN, "Setting global property \"%s\"=%d", p, z);
01138 GWEN_DB_SetIntValue(globalValues,
01139 GWEN_DB_FLAGS_DEFAULT |
01140 GWEN_DB_FLAGS_OVERWRITE_VARS,
01141 p, z);
01142 pvalue=pbuffer;
01143 *datasize=strlen(pvalue);
01144 }
01145 else {
01146 int z;
01147 GWEN_DB_NODE_TYPE vt;
01148 const char *type = "should_be_known";
01149
01150
01151 DBG_DEBUG(GWEN_LOGDOMAIN, "Getting global property \"%s\"", p);
01152 vt=GWEN_DB_GetVariableType(globalValues, p);
01153 if (vt==GWEN_DB_NodeType_Unknown) {
01154 if (!GWEN_DB_VariableExists(globalValues, p)) {
01155 DBG_ERROR(GWEN_LOGDOMAIN, "Unable to determine type of \"%s\"", p);
01156 return 0;
01157 }
01158 type=GWEN_XMLNode_GetProperty(dnode, "type", "ascii");
01159 if (GWEN_MsgEngine__IsCharTyp(e, type))
01160 vt=GWEN_DB_NodeType_ValueChar;
01161 else if (GWEN_MsgEngine__IsIntTyp(e, type))
01162 vt=GWEN_DB_NodeType_ValueInt;
01163 else if (GWEN_MsgEngine__IsBinTyp(e, type))
01164 vt=GWEN_DB_NodeType_ValueBin;
01165 else {
01166 DBG_ERROR(GWEN_LOGDOMAIN,
01167 "Unable to determine type of \"%s\" (xml)", p);
01168 return 0;
01169 }
01170 }
01171
01172 switch(vt) {
01173 case GWEN_DB_NodeType_ValueChar:
01174 pvalue=GWEN_DB_GetCharValue(globalValues, p, 0, "");
01175 *datasize=strlen(pvalue);
01176 break;
01177
01178 case GWEN_DB_NodeType_ValueInt:
01179 z=GWEN_DB_GetIntValue(globalValues, p, 0, 0);
01180 if (GWEN_Text_NumToString(z, pbuffer, sizeof(pbuffer),0)<1) {
01181 DBG_ERROR(GWEN_LOGDOMAIN, "Error converting num to string");
01182 return 0;
01183 }
01184 pvalue=pbuffer;
01185 *datasize=strlen(pvalue);
01186 break;
01187
01188 case GWEN_DB_NodeType_ValueBin:
01189 pvalue=GWEN_DB_GetBinValue(globalValues, p, 0,
01190 0,0,
01191 datasize);
01192 break;
01193
01194 default:
01195 DBG_ERROR(GWEN_LOGDOMAIN,"Unknown type %s", type);
01196 return 0;
01197 }
01198 }
01199 DBG_DEBUG(GWEN_LOGDOMAIN, "Value transformed");
01200 }
01201 else if (*p=='%') {
01202
01203 p++;
01204
01205 DBG_DEBUG(GWEN_LOGDOMAIN, "Getting property \"%s\"", p);
01206 pvalue=GWEN_XMLNode_GetProperty(node, p, 0);
01207 if (pvalue) {
01208 *datasize=strlen(pvalue);
01209 DBG_DEBUG(GWEN_LOGDOMAIN, "Transformed value \"%s\"", pvalue);
01210 }
01211 else
01212 *datasize=0;
01213 }
01214 else if (*p=='?') {
01215 GWEN_DB_NODE_TYPE vt;
01216 int z;
01217 const char *dtype;
01218
01219
01220 dtype=GWEN_XMLNode_GetProperty(dnode, "type","ASCII");
01221
01222
01223 p++;
01224 DBG_DEBUG(GWEN_LOGDOMAIN, "Getting program variable \"%s\"", p);
01225
01226 pvalue=0;
01227 if (GWEN_MsgEngine__IsCharTyp(e, dtype))
01228 vt=GWEN_DB_NodeType_ValueChar;
01229 else if (GWEN_MsgEngine__IsIntTyp(e, dtype))
01230 vt=GWEN_DB_NodeType_ValueInt;
01231 else {
01232 vt=GWEN_DB_NodeType_ValueChar;
01233 }
01234
01235 switch(vt) {
01236 case GWEN_DB_NodeType_ValueChar:
01237 if (e->getCharValuePtr) {
01238 pvalue=e->getCharValuePtr(e, p, 0);
01239 if (pvalue)
01240 *datasize=strlen(pvalue);
01241 }
01242 break;
01243
01244 case GWEN_DB_NodeType_ValueInt:
01245 if (e->getIntValuePtr) {
01246 z=e->getIntValuePtr(e, p, 0);
01247 if (GWEN_Text_NumToString(z, pbuffer, sizeof(pbuffer),0)<1) {
01248 DBG_ERROR(GWEN_LOGDOMAIN, "Error converting num to string");
01249 return 0;
01250 }
01251 pvalue=pbuffer;
01252 *datasize=strlen(pvalue);
01253 }
01254 else {
01255 DBG_NOTICE(GWEN_LOGDOMAIN, "Callback for getIntValue not set");
01256 }
01257 break;
01258
01259 default:
01260 DBG_ERROR(GWEN_LOGDOMAIN,"Unhandled type %s", dtype);
01261 return 0;
01262 }
01263
01264 DBG_DEBUG(GWEN_LOGDOMAIN, "Value transformed");
01265 }
01266 else {
01267 *datasize=strlen(pvalue);
01268 }
01269 }
01270 return pvalue;
01271 }
01272
01273
01274
01275 const char *GWEN_MsgEngine_SearchForProperty(GWEN_XMLNODE *node,
01276 GWEN_XMLNODE *refnode,
01277 const char *name,
01278 int topDown) {
01279 const char *pvalue;
01280 GWEN_XMLNODE *pn;
01281 const char *lastValue;
01282
01283 DBG_DEBUG(GWEN_LOGDOMAIN, "Searching for value of \"%s\" in properties", name);
01284 lastValue=0;
01285
01286 pvalue=GWEN_XMLNode_GetProperty(node, name,0);
01287 if (pvalue) {
01288 if (!topDown)
01289 return pvalue;
01290 DBG_DEBUG(GWEN_LOGDOMAIN, "Found a value (%s), but will look further", pvalue);
01291 lastValue=pvalue;
01292 }
01293
01294 pn=refnode;
01295 while(pn) {
01296 pvalue=GWEN_XMLNode_GetProperty(pn, name,0);
01297 if (pvalue) {
01298 if (!topDown)
01299 return pvalue;
01300 DBG_DEBUG(GWEN_LOGDOMAIN, "Found a value (%s), but will look further", pvalue);
01301 lastValue=pvalue;
01302 }
01303 pn=GWEN_XMLNode_GetParent(pn);
01304 }
01305 return lastValue;
01306 }
01307
01308
01309
01310 int GWEN_MsgEngine_GetHighestTrustLevel(GWEN_XMLNODE *node,
01311 GWEN_XMLNODE *refnode) {
01312 int value;
01313 GWEN_XMLNODE *pn;
01314 int highestTrust;
01315
01316 highestTrust=0;
01317
01318 value=atoi(GWEN_XMLNode_GetProperty(node, "trustlevel","0"));
01319 if (value>highestTrust)
01320 highestTrust=value;
01321
01322 pn=node;
01323 while(pn) {
01324 value=atoi(GWEN_XMLNode_GetProperty(pn, "trustlevel","0"));
01325 if (value>highestTrust)
01326 highestTrust=value;
01327 pn=GWEN_XMLNode_GetParent(pn);
01328 }
01329
01330 pn=refnode;
01331 while(pn) {
01332 value=atoi(GWEN_XMLNode_GetProperty(pn, "trustlevel","0"));
01333 if (value>highestTrust)
01334 highestTrust=value;
01335 pn=GWEN_XMLNode_GetParent(pn);
01336 }
01337 return highestTrust;
01338 }
01339
01340
01341
01342 const char *GWEN_MsgEngine__SearchForValue(GWEN_MSGENGINE *e,
01343 GWEN_XMLNODE *node,
01344 GWEN_XMLNODE_PATH *nodePath,
01345 const char *name,
01346 unsigned int *datasize) {
01347 const char *pvalue;
01348 GWEN_XMLNODE *pn;
01349 char *bufferPtr;
01350 int topDown;
01351 const char *lastValue;
01352 unsigned int lastDataSize;
01353 unsigned int ldatasize;
01354
01355 DBG_DEBUG(GWEN_LOGDOMAIN, "Searching for value of \"%s\" in <VALUES>",
01356 name);
01357 if (!node) {
01358 DBG_WARN(GWEN_LOGDOMAIN, "No node !");
01359 }
01360 topDown=atoi(GWEN_XMLNode_GetProperty(node, "topdown", "0"));
01361 lastValue=0;
01362 lastDataSize=0;
01363
01364 bufferPtr=0;
01365
01366
01367 pn=GWEN_XMLNode_Path_Surface(nodePath);
01368 while(pn) {
01369 const char *ppath;
01370
01371
01372
01373
01374
01375 pvalue=GWEN_MsgEngine__findInValues(e, pn, node, name, &ldatasize);
01376 if (pvalue) {
01377 if (!topDown) {
01378 free(bufferPtr);
01379 *datasize=ldatasize;
01380 return pvalue;
01381 }
01382 DBG_DEBUG(GWEN_LOGDOMAIN, "Found a value, but will look further");
01383 lastValue=pvalue;
01384 lastDataSize=ldatasize;
01385 }
01386
01387 ppath=GWEN_XMLNode_GetProperty(pn, "name", "");
01388
01389 if (*ppath) {
01390 int i;
01391 char *tmpptr;
01392
01393 if (bufferPtr) {
01394 i=strlen(bufferPtr)+strlen(ppath)+2;
01395 tmpptr=(char*)malloc(i);
01396 assert(tmpptr);
01397 sprintf(tmpptr, "%s/%s", ppath, bufferPtr);
01398 free(bufferPtr);
01399 bufferPtr=tmpptr;
01400 }
01401 else {
01402 i=strlen(ppath)+strlen(name)+2;
01403 tmpptr=(char*)malloc(i);
01404 assert(tmpptr);
01405 sprintf(tmpptr, "%s/%s", ppath, name);
01406 bufferPtr=tmpptr;
01407 }
01408 name=bufferPtr;
01409 }
01410 pn=GWEN_XMLNode_Path_Surface(nodePath);
01411 }
01412
01413 free(bufferPtr);
01414 if (!lastValue)
01415 *datasize=0;
01416 else
01417 *datasize=lastDataSize;
01418 return lastValue;
01419 }
01420
01421
01422
01423 const char *GWEN_MsgEngine__findInValues(GWEN_MSGENGINE *e,
01424 GWEN_XMLNODE *node,
01425 GWEN_XMLNODE *dnode,
01426 const char *name,
01427 unsigned int *datasize) {
01428 GWEN_XMLNODE *pn;
01429
01430 DBG_VERBOUS(GWEN_LOGDOMAIN, "Looking for value of \"%s\" in <VALUES>", name);
01431 pn=GWEN_XMLNode_GetChild(node);
01432
01433 while(pn) {
01434 if (GWEN_XMLNode_GetType(pn)==GWEN_XMLNodeTypeTag) {
01435 GWEN_XMLNODE *n;
01436 const char *p;
01437
01438 p=GWEN_XMLNode_GetData(pn);
01439 assert(p);
01440 DBG_DEBUG(GWEN_LOGDOMAIN, "Checking %s", p);
01441 if (strcasecmp(p, "VALUES")==0) {
01442 DBG_DEBUG(GWEN_LOGDOMAIN, "<values> found");
01443
01444 n=GWEN_XMLNode_GetChild(pn);
01445 while(n) {
01446 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
01447 p=GWEN_XMLNode_GetData(n);
01448 assert(p);
01449 if (strcasecmp(p, "VALUE")==0) {
01450 const char *pname;
01451 const char *pvalue;
01452
01453 pname=GWEN_XMLNode_GetProperty(n, "path", 0);
01454 if (pname) {
01455 DBG_DEBUG(GWEN_LOGDOMAIN, "Comparing against \"%s\"", pname);
01456 if (strcasecmp(name, pname)==0) {
01457 GWEN_XMLNODE *dn;
01458
01459 dn=GWEN_XMLNode_GetChild(n);
01460 while (dn) {
01461 if (GWEN_XMLNode_GetType(dn)==GWEN_XMLNodeTypeData) {
01462 pvalue=GWEN_XMLNode_GetData(dn);
01463 if (pvalue) {
01464 DBG_DEBUG(GWEN_LOGDOMAIN, "Transforming \"%s\"", pvalue);
01465 pvalue=GWEN_MsgEngine__TransformValue(e,
01466 pvalue,
01467 node,
01468 dnode,
01469 datasize);
01470 }
01471 if (pvalue)
01472 return pvalue;
01473 }
01474 dn=GWEN_XMLNode_Next(dn);
01475 }
01476 }
01477 }
01478 }
01479 }
01480 n=GWEN_XMLNode_Next(n);
01481 }
01482 break;
01483 }
01484 }
01485 pn=GWEN_XMLNode_Next(pn);
01486 }
01487
01488 DBG_DEBUG(GWEN_LOGDOMAIN, "No value found for \"%s\" in <VALUES>", name);
01489 return 0;
01490 }
01491
01492
01493
01494 GWEN_XMLNODE *GWEN_MsgEngine__GetGroup(GWEN_MSGENGINE *e,
01495 GWEN_XMLNODE *node,
01496 const char *t,
01497 int version,
01498 const char *pvalue) {
01499 GWEN_XMLNODE *n;
01500 const char *p;
01501 int i;
01502 const char *mode;
01503 unsigned int proto;
01504 char buffer[256];
01505
01506 if ((strlen(t)+4)>sizeof(buffer)) {
01507 DBG_ERROR(GWEN_LOGDOMAIN, "Type name too long.");
01508 return 0;
01509 }
01510
01511 mode=GWEN_MsgEngine_GetMode(e);
01512 proto=GWEN_MsgEngine_GetProtocolVersion(e);
01513
01514
01515 strcpy(buffer, t);
01516 strcat(buffer,"S");
01517 n=GWEN_XMLNode_FindFirstTag(node, buffer, 0, 0);
01518 if (!n) {
01519 DBG_DEBUG(GWEN_LOGDOMAIN,
01520 "No definitions here for type \"%s\"", t);
01521 return 0;
01522 }
01523
01524
01525 if (!mode)
01526 mode="";
01527 n=GWEN_XMLNode_GetFirstTag(n);
01528 if (!n) {
01529 DBG_INFO(GWEN_LOGDOMAIN, "No definitions inside \"%s\"", buffer);
01530 return 0;
01531 }
01532
01533
01534 strcpy(buffer, t);
01535 strcat(buffer, "def");
01536 while(n) {
01537 p=GWEN_XMLNode_GetData(n);
01538 assert(p);
01539 if (strcasecmp(p, buffer)==0 ||
01540 strcasecmp(p, t)==0) {
01541 p=GWEN_XMLNode_GetProperty(n, "id", "");
01542 if (strcasecmp(p, pvalue)!=0)
01543 p=GWEN_XMLNode_GetProperty(n, "name", "");
01544 if (strcasecmp(p, pvalue)==0) {
01545 i=atoi(GWEN_XMLNode_GetProperty(n, "pversion" ,"0"));
01546 if (proto==0 || (int)proto==i || i==0) {
01547 i=atoi(GWEN_XMLNode_GetProperty(n, "version" ,"0"));
01548 if (version==0 || version==i) {
01549 p=GWEN_XMLNode_GetProperty(n, "mode","");
01550 if (strcasecmp(p, mode)==0 || !*p) {
01551 DBG_DEBUG(GWEN_LOGDOMAIN,
01552 "Group definition for \"%s=%s\" found",
01553 t, pvalue);
01554 return n;
01555 }
01556 }
01557 }
01558 }
01559 }
01560 n=GWEN_XMLNode_GetNextTag(n);
01561 }
01562
01563 DBG_DEBUG(GWEN_LOGDOMAIN,
01564 "Group definition for \"%s=%s\"(%d) not found here",
01565 t,
01566 pvalue,
01567 version);
01568 return 0;
01569 }
01570
01571
01572
01573 GWEN_XMLNODE *GWEN_MsgEngine_GetGroup(GWEN_MSGENGINE *e,
01574 GWEN_XMLNODE *node,
01575 const GWEN_XMLNODE_PATH *nodePath,
01576 const char *t,
01577 int version,
01578 const char *pvalue) {
01579 GWEN_XMLNODE *n;
01580 GWEN_XMLNODE *nLast = 0;
01581 GWEN_XMLNODE *nRes = 0;
01582 GWEN_XMLNODE_PATH *pathCopy;
01583
01584 assert(node);
01585 assert(nodePath);
01586 assert(t);
01587 assert(pvalue);
01588
01589 pathCopy=GWEN_XMLNode_Path_dup(nodePath);
01590 n=GWEN_XMLNode_Path_Surface(pathCopy);
01591
01592 while(n) {
01593 nLast=n;
01594 nRes=GWEN_MsgEngine__GetGroup(e, n, t, version, pvalue);
01595 if (nRes)
01596 break;
01597 n=GWEN_XMLNode_Path_Surface(pathCopy);
01598 }
01599 GWEN_XMLNode_Path_free(pathCopy);
01600 if (nRes) {
01601
01602 if (nRes==node) {
01603 DBG_ERROR(GWEN_LOGDOMAIN, "Loop detected.");
01604 return 0;
01605 }
01606 return nRes;
01607 }
01608
01609 if (nLast)
01610 n=nLast;
01611 else
01612 n=node;
01613
01614 if (n) {
01615 n=GWEN_XMLNode_GetParent(n);
01616 while(n) {
01617 nRes=GWEN_MsgEngine__GetGroup(e, n, t, version, pvalue);
01618 if (nRes)
01619 break;
01620 n=GWEN_XMLNode_GetParent(n);
01621 }
01622 }
01623
01624
01625 if (!nRes && e->defs)
01626 nRes=GWEN_MsgEngine__GetGroup(e, e->defs, t, version, pvalue);
01627
01628 if (!nRes) {
01629 DBG_DEBUG(GWEN_LOGDOMAIN,
01630 "Group definition for \"%s=%s\"(%d) not found",
01631 t,
01632 pvalue,
01633 version);
01634 return 0;
01635 }
01636 if (nRes==node) {
01637 DBG_ERROR(GWEN_LOGDOMAIN, "Loop detected.");
01638 return 0;
01639 }
01640 return nRes;
01641 }
01642
01643
01644
01645 int GWEN_MsgEngine__WriteGroup(GWEN_MSGENGINE *e,
01646 GWEN_BUFFER *gbuf,
01647 GWEN_XMLNODE *node,
01648 GWEN_XMLNODE *rnode,
01649 GWEN_DB_NODE *gr,
01650 int groupIsOptional,
01651 GWEN_XMLNODE_PATH *nodePath) {
01652 GWEN_XMLNODE *n;
01653 const char *p;
01654 char delimiter;
01655 char terminator;
01656 int isFirstElement;
01657 int omittedElements;
01658 int hasEntries;
01659
01660
01661
01662 if (rnode) {
01663
01664 p=GWEN_XMLNode_GetProperty(rnode,
01665 "delimiter",
01666 GWEN_XMLNode_GetProperty(node,
01667 "delimiter",
01668 ""));
01669 delimiter=*p;
01670
01671
01672 p=GWEN_XMLNode_GetProperty(rnode,
01673 "terminator",
01674 GWEN_XMLNode_GetProperty(node,
01675 "terminator",
01676 ""));
01677 terminator=*p;
01678 }
01679 else {
01680
01681 p=GWEN_XMLNode_GetProperty(node,
01682 "delimiter",
01683 "");
01684 delimiter=*p;
01685
01686
01687 p=GWEN_XMLNode_GetProperty(node, "terminator","");
01688 terminator=*p;
01689 }
01690
01691
01692 n=GWEN_XMLNode_GetChild(node);
01693 isFirstElement=1;
01694 omittedElements=0;
01695 hasEntries=0;
01696 if (!n) {
01697 DBG_INFO(GWEN_LOGDOMAIN, "No subnodes !");
01698 }
01699 while(n) {
01700 int t;
01701 unsigned int minnum;
01702 unsigned int maxnum;
01703 int gversion;
01704 const char *addEmptyMode;
01705 unsigned int loopNr;
01706
01707 minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum","1"));
01708 maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum","1"));
01709 gversion=atoi(GWEN_XMLNode_GetProperty(n, "version","0"));
01710 addEmptyMode=GWEN_XMLNode_GetProperty(n, "addemptymode","one");
01711
01712 DBG_DEBUG(GWEN_LOGDOMAIN, "Omitted elements: %d", omittedElements);
01713 t=GWEN_XMLNode_GetType(n);
01714 if (t==GWEN_XMLNodeTypeTag) {
01715 const char *typ;
01716
01717 typ=GWEN_XMLNode_GetData(n);
01718 if (typ==0) {
01719 DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed tag found (internal error?)");
01720 return -1;
01721 }
01722 if (strcasecmp(typ, "ELEM")==0) {
01723
01724 int j;
01725 int rv;
01726
01727 DBG_VERBOUS(GWEN_LOGDOMAIN, "Found an element");
01728
01729 for (loopNr=0; loopNr<maxnum; loopNr++) {
01730 unsigned int posBeforeElement;
01731
01732 posBeforeElement=GWEN_Buffer_GetPos(gbuf);
01733
01734
01735 if (delimiter) {
01736 DBG_VERBOUS(GWEN_LOGDOMAIN, "Appending %d delimiters",
01737 omittedElements);
01738 for (j=0; j<omittedElements; j++) {
01739 if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
01740 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
01741 return -1;
01742 }
01743 }
01744 if (!isFirstElement)
01745 if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
01746 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
01747 return -1;
01748 }
01749 }
01750
01751 rv=GWEN_MsgEngine__WriteElement(e,
01752 gbuf,
01753 n,
01754 rnode,
01755 gr,
01756 loopNr,
01757 loopNr>=minnum ||
01758 (groupIsOptional && !hasEntries),
01759 nodePath);
01760 if (rv==-1) {
01761 DBG_INFO(GWEN_LOGDOMAIN, "Error writing element");
01762 DBG_INFO(GWEN_LOGDOMAIN, "Node is:");
01763 GWEN_XMLNode_Dump(n, 1);
01764 if (gr) {
01765 DBG_INFO(GWEN_LOGDOMAIN, "Data is:");
01766 GWEN_DB_Dump(gr, 1);
01767 }
01768 return -1;
01769 }
01770 else if (rv==0) {
01771 isFirstElement=0;
01772 omittedElements=0;
01773 hasEntries=1;
01774 DBG_DEBUG(GWEN_LOGDOMAIN, "Element written");
01775 }
01776 else {
01777
01778
01779 GWEN_Buffer_SetPos(gbuf, posBeforeElement);
01780 GWEN_Buffer_Crop(gbuf, 0, posBeforeElement);
01781
01782 if (strcasecmp(addEmptyMode, "max")==0) {
01783 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding max empty");
01784 omittedElements+=(maxnum-loopNr);
01785 }
01786 else if (strcasecmp(addEmptyMode, "min")==0) {
01787 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding min empty");
01788 if (loopNr<minnum)
01789 omittedElements+=(minnum-loopNr);
01790 }
01791 else if (strcasecmp(addEmptyMode, "one")==0) {
01792 if (loopNr==0)
01793 omittedElements++;
01794 }
01795 else if (strcasecmp(addEmptyMode, "none")==0) {
01796 }
01797 else {
01798 DBG_ERROR(GWEN_LOGDOMAIN, "Unknown addemptymode \"%s\"",
01799 addEmptyMode);
01800 return -1;
01801 }
01802 break;
01803 }
01804 }
01805 }
01806 else if (strcasecmp(typ, "VALUES")==0) {
01807 }
01808 else if (strcasecmp(typ, "DESCR")==0) {
01809 }
01810 else {
01811
01812 GWEN_XMLNODE *gn;
01813 GWEN_DB_NODE *gcfg;
01814 const char *gname;
01815 const char *gtype;
01816 unsigned int posBeforeGroup;
01817
01818 DBG_VERBOUS(GWEN_LOGDOMAIN, "Found a group");
01819
01820 gcfg=0;
01821 gtype=GWEN_XMLNode_GetProperty(n, "type",0);
01822 if (!gtype) {
01823
01824 DBG_INFO(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", typ);
01825 gtype="";
01826 gn=n;
01827 }
01828 else {
01829 DBG_VERBOUS(GWEN_LOGDOMAIN, "<%s> tag is of type \"%s\"", typ, gtype);
01830 gn=GWEN_MsgEngine_GetGroup(e, n, nodePath, typ,
01831 gversion, gtype);
01832 if (!gn) {
01833 DBG_INFO(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", typ);
01834 return -1;
01835 }
01836 }
01837
01838 gname=NULL;
01839 gcfg=NULL;
01840 if (gr) {
01841 gname=GWEN_XMLNode_GetProperty(n, "name",0);
01842 if (gname) {
01843 DBG_VERBOUS(GWEN_LOGDOMAIN, "Group \"%s\" using special data", gname);
01844 gcfg=GWEN_DB_FindFirstGroup(gr, gname);
01845 }
01846 else {
01847 DBG_DEBUG(GWEN_LOGDOMAIN, "Unnamed group, using basic data");
01848
01849 gcfg=gr;
01850 }
01851 }
01852
01853
01854 for (loopNr=0; loopNr<maxnum; loopNr++) {
01855 int rv;
01856 int groupIsEmpty;
01857
01858 groupIsEmpty=0;
01859 posBeforeGroup=GWEN_Buffer_GetPos(gbuf);
01860
01861
01862 if (delimiter) {
01863 int j;
01864
01865 DBG_VERBOUS(GWEN_LOGDOMAIN, "Appending %d delimiters",
01866 omittedElements);
01867 for (j=0; j<omittedElements; j++) {
01868 if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
01869 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
01870 return -1;
01871 }
01872 }
01873 if (!isFirstElement)
01874 if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
01875 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
01876 return -1;
01877 }
01878 }
01879
01880
01881 if (gcfg==0) {
01882 DBG_DEBUG(GWEN_LOGDOMAIN, "No group found");
01883 if (loopNr>=minnum)
01884 groupIsEmpty=1;
01885 }
01886
01887 if (groupIsEmpty) {
01888
01889 rv=1;
01890 }
01891 else {
01892 int dive;
01893
01894
01895 if (GWEN_XMLNode_Path_Dive(nodePath, n)) {
01896 DBG_INFO(GWEN_LOGDOMAIN, "Called from here");
01897 return -1;
01898 }
01899 if (n==gn)
01900 dive=1;
01901 else {
01902 if (GWEN_XMLNode_Path_Dive(nodePath, gn)) {
01903 DBG_INFO(GWEN_LOGDOMAIN, "Called from here");
01904 return -1;
01905 }
01906 dive=2;
01907 }
01908 rv=GWEN_MsgEngine__WriteGroup(e,
01909 gbuf,
01910 gn,
01911 n,
01912 gcfg,
01913 loopNr>=minnum || groupIsOptional,
01914 nodePath);
01915 GWEN_XMLNode_Path_Surface(nodePath);
01916 if (dive==2)
01917 GWEN_XMLNode_Path_Surface(nodePath);
01918 }
01919
01920 if (rv==-1) {
01921 DBG_INFO(GWEN_LOGDOMAIN, "Could not write group \"%s\"", gtype);
01922 if (gn) {
01923 DBG_INFO(GWEN_LOGDOMAIN, "Node is:");
01924 GWEN_XMLNode_Dump(gn, 1);
01925 }
01926 if (n) {
01927 DBG_INFO(GWEN_LOGDOMAIN, "Referring node is:");
01928 GWEN_XMLNode_Dump(n, 1);
01929 }
01930 if (gr) {
01931 DBG_INFO(GWEN_LOGDOMAIN, "Data is:");
01932 GWEN_DB_Dump(gr, 1);
01933 }
01934 return -1;
01935 }
01936 else if (rv==0) {
01937 isFirstElement=0;
01938 omittedElements=0;
01939 hasEntries=1;
01940 DBG_DEBUG(GWEN_LOGDOMAIN, "Element written");
01941 }
01942 else {
01943
01944
01945 GWEN_Buffer_SetPos(gbuf, posBeforeGroup);
01946 GWEN_Buffer_Crop(gbuf, 0, posBeforeGroup);
01947
01948 if (strcasecmp(addEmptyMode, "max")==0) {
01949 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding max empty");
01950 omittedElements+=(maxnum-loopNr);
01951 }
01952 else if (strcasecmp(addEmptyMode, "min")==0) {
01953 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding min empty");
01954 if (loopNr<minnum)
01955 omittedElements+=(minnum-loopNr);
01956 }
01957 else if (strcasecmp(addEmptyMode, "one")==0) {
01958 if (loopNr==0)
01959 omittedElements++;
01960 }
01961 else if (strcasecmp(addEmptyMode, "none")==0) {
01962 }
01963 else {
01964 DBG_ERROR(GWEN_LOGDOMAIN, "Unknown addemptymode \"%s\"",
01965 addEmptyMode);
01966 return -1;
01967 }
01968 break;
01969 }
01970
01971
01972 if (gcfg && gname)
01973 gcfg=GWEN_DB_FindNextGroup(gcfg, gname);
01974 }
01975 }
01976 }
01977 else if (t==GWEN_XMLNodeTypeData) {
01978 }
01979 else {
01980 DBG_DEBUG(GWEN_LOGDOMAIN, "Unhandled node type %d", t);
01981 }
01982 n=GWEN_XMLNode_Next(n);
01983 }
01984
01985
01986 if (terminator) {
01987 if (GWEN_Buffer_AppendByte(gbuf, terminator)) {
01988 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
01989 return -1;
01990 }
01991 }
01992
01993 if (!hasEntries) {
01994 DBG_INFO(GWEN_LOGDOMAIN, "No entries in node");
01995 }
01996 return hasEntries?0:1;
01997 }
01998
01999
02000
02001 int GWEN_MsgEngine_CreateMessageFromNode(GWEN_MSGENGINE *e,
02002 GWEN_XMLNODE *node,
02003 GWEN_BUFFER *gbuf,
02004 GWEN_DB_NODE *msgData){
02005 GWEN_XMLNODE_PATH *np;
02006 int rv;
02007
02008 assert(e);
02009 assert(node);
02010 assert(msgData);
02011
02012 np=GWEN_XMLNode_Path_new();
02013 GWEN_XMLNode_Path_Dive(np, node);
02014 rv=GWEN_MsgEngine__WriteGroup(e,
02015 gbuf,
02016 node,
02017 0,
02018 msgData,
02019 0,
02020 np);
02021 GWEN_XMLNode_Path_free(np);
02022 if (rv){
02023 const char *p;
02024
02025 p=GWEN_XMLNode_GetData(node);
02026 if (p) {
02027 DBG_INFO(GWEN_LOGDOMAIN, "Error writing group \"%s\"", p);
02028 }
02029 else {
02030 DBG_INFO(GWEN_LOGDOMAIN, "Error writing group");
02031 }
02032 return -1;
02033 }
02034
02035 return 0;
02036 }
02037
02038
02039
02040 int GWEN_MsgEngine_CreateMessage(GWEN_MSGENGINE *e,
02041 const char *msgName,
02042 int msgVersion,
02043 GWEN_BUFFER *gbuf,
02044 GWEN_DB_NODE *msgData) {
02045 GWEN_XMLNODE *group;
02046
02047 group=GWEN_MsgEngine_FindGroupByProperty(e, "id", msgVersion, msgName);
02048 if (!group) {
02049 DBG_ERROR(GWEN_LOGDOMAIN, "Group \"%s\" not found\n", msgName);
02050 return -1;
02051 }
02052 return GWEN_MsgEngine_CreateMessageFromNode(e,
02053 group,
02054 gbuf,
02055 msgData);
02056 }
02057
02058
02059
02060 int GWEN_MsgEngine_AddDefinitions(GWEN_MSGENGINE *e,
02061 GWEN_XMLNODE *node) {
02062 GWEN_XMLNODE *nsrc, *ndst;
02063
02064 assert(e);
02065 assert(node);
02066
02067 if (!e->defs) {
02068 e->defs=GWEN_XMLNode_dup(node);
02069 e->ownDefs=1;
02070 return 0;
02071 }
02072
02073 nsrc=GWEN_XMLNode_GetChild(node);
02074 while(nsrc) {
02075 if (GWEN_XMLNode_GetType(nsrc)==GWEN_XMLNodeTypeTag) {
02076 ndst=GWEN_XMLNode_FindNode(e->defs, GWEN_XMLNodeTypeTag,
02077 GWEN_XMLNode_GetData(nsrc));
02078 if (ndst) {
02079 GWEN_XMLNODE *n;
02080
02081 n=GWEN_XMLNode_GetChild(nsrc);
02082 while (n) {
02083 GWEN_XMLNODE *newNode;
02084
02085 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding node \"%s\"", GWEN_XMLNode_GetData(n));
02086 newNode=GWEN_XMLNode_dup(n);
02087 GWEN_XMLNode_AddChild(ndst, newNode);
02088 n=GWEN_XMLNode_Next(n);
02089 }
02090 }
02091 else {
02092 GWEN_XMLNODE *newNode;
02093
02094 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding branch \"%s\"", GWEN_XMLNode_GetData(nsrc));
02095 newNode=GWEN_XMLNode_dup(nsrc);
02096 GWEN_XMLNode_AddChild(e->defs, newNode);
02097 }
02098 }
02099 nsrc=GWEN_XMLNode_Next(nsrc);
02100 }
02101
02102 return 0;
02103 }
02104
02105
02106
02107 int GWEN_MsgEngine__ShowElement(GWEN_UNUSED GWEN_MSGENGINE *e,
02108 const char *path,
02109 GWEN_XMLNODE *node,
02110 GWEN_STRINGLIST *sl,
02111 uint32_t flags) {
02112 const char *name;
02113 const char *type;
02114 const char *npath;
02115 unsigned int minsize;
02116 unsigned int maxsize;
02117 unsigned int minnum;
02118 unsigned int maxnum;
02119 int j;
02120 int isSet;
02121 char nbuffer[256];
02122 GWEN_STRINGLISTENTRY *en;
02123
02124
02125 type=GWEN_XMLNode_GetProperty(node, "type","ASCII");
02126
02127
02128 minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize","0"));
02129 maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize","0"));
02130 minnum=atoi(GWEN_XMLNode_GetProperty(node, "minnum","1"));
02131 maxnum=atoi(GWEN_XMLNode_GetProperty(node, "maxnum","1"));
02132
02133 npath="";
02134 isSet=0;
02135
02136
02137 name=GWEN_XMLNode_GetProperty(node, "name", 0);
02138 if (path==0)
02139 path="";
02140
02141 if (name) {
02142
02143 if (strlen(path)+strlen(name)+10>=sizeof(nbuffer)) {
02144 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02145 return -1;
02146 }
02147 if (*path)
02148 sprintf(nbuffer, "%s/%s", path, name);
02149 else
02150 sprintf(nbuffer, "%s", name);
02151 npath=nbuffer;
02152 }
02153
02154 en=GWEN_StringList_FirstEntry(sl);
02155 while(en) {
02156 if (GWEN_StringListEntry_Data(en))
02157 if (strcasecmp(GWEN_StringListEntry_Data(en), npath)==0) {
02158 isSet=1;
02159 break;
02160 }
02161 en=GWEN_StringListEntry_Next(en);
02162 }
02163
02164 if (isSet && (flags & GWEN_MSGENGINE_SHOW_FLAGS_NOSET))
02165 return 0;
02166
02167 fprintf(stdout, " %s",
02168 npath);
02169 j=GWEN_MSGENGINE_VARNAME_WIDTH-strlen(npath);
02170 if (j>0) {
02171 int i;
02172
02173 for (i=0; i<j; i++)
02174 fprintf(stdout, " ");
02175 }
02176 fprintf(stdout, "| %s", type);
02177 j=GWEN_MSGENGINE_TYPENAME_WIDTH-strlen(type);
02178 if (j>0) {
02179 int i;
02180
02181 for (i=0; i<j; i++)
02182 fprintf(stdout, " ");
02183 }
02184 fprintf(stdout, "| %4d-%4d", minsize, maxsize);
02185 fprintf(stdout," | %3d ", maxnum);
02186 fprintf(stdout," |");
02187 if (minnum==0)
02188 fprintf(stdout," optvar");
02189 if (flags & GWEN_MSGENGINE_SHOW_FLAGS_OPTIONAL)
02190 fprintf(stdout," optgrp");
02191
02192 if (isSet) {
02193 fprintf(stdout," set");
02194 }
02195
02196 fprintf(stdout,"\n");
02197
02198 return 0;
02199 }
02200
02201
02202
02203 int GWEN_MsgEngine__ShowGroup(GWEN_MSGENGINE *e,
02204 const char *path,
02205 GWEN_XMLNODE *node,
02206 GWEN_XMLNODE *rnode,
02207 GWEN_STRINGLIST *sl,
02208 uint32_t flags) {
02209 GWEN_XMLNODE *n;
02210 int isFirstElement;
02211 int omittedElements;
02212 int rv;
02213
02214
02215 n=GWEN_XMLNode_GetChild(node);
02216
02217 if (path==0)
02218 path="";
02219 if (*path=='/')
02220 path++;
02221
02222 while(n) {
02223 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
02224 const char *p;
02225
02226 p=GWEN_XMLNode_GetData(n);
02227 assert(p);
02228 DBG_DEBUG(GWEN_LOGDOMAIN, "Checking %s",p);
02229 if (strcasecmp(p, "VALUES")==0)
02230 break;
02231 }
02232 n=GWEN_XMLNode_Next(n);
02233 }
02234
02235 if (n) {
02236 DBG_DEBUG(GWEN_LOGDOMAIN, "<preset> found");
02237
02238 n=GWEN_XMLNode_GetChild(n);
02239 while(n) {
02240 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
02241 const char *p;
02242
02243 p=GWEN_XMLNode_GetData(n);
02244 assert(p);
02245 if (strcasecmp(p, "VALUE")==0) {
02246 const char *pname;
02247 const char *pvalue;
02248
02249 pname=GWEN_XMLNode_GetProperty(n, "path", 0);
02250 if (pname) {
02251 GWEN_XMLNODE *dn;
02252
02253
02254 dn=GWEN_XMLNode_GetChild(n);
02255 while (dn) {
02256 if (GWEN_XMLNode_GetType(dn)==GWEN_XMLNodeTypeData) {
02257 pvalue=GWEN_XMLNode_GetData(dn);
02258 if (pvalue) {
02259 char pbuffer[256];
02260
02261
02262 p=pvalue;
02263 while (*p && isspace((int)*p))
02264 p++;
02265 if (strlen(path)+strlen(pname)+2>sizeof(pbuffer)) {
02266 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02267 return -1;
02268 }
02269 if (*path)
02270 sprintf(pbuffer, "%s/%s", path, pname);
02271 else
02272 sprintf(pbuffer, "%s", pname);
02273 GWEN_StringList_AppendString(sl,
02274 pbuffer,
02275 0,
02276 1);
02277 }
02278 break;
02279 }
02280 dn=GWEN_XMLNode_Next(dn);
02281 }
02282 }
02283 }
02284 }
02285 n=GWEN_XMLNode_Next(n);
02286 }
02287 }
02288
02289
02290 n=GWEN_XMLNode_GetChild(node);
02291 isFirstElement=1;
02292 omittedElements=0;
02293 while(n) {
02294 int t;
02295 unsigned int minnum;
02296 unsigned int maxnum;
02297 int gversion;
02298 const char *addEmptyMode;
02299 unsigned int loopNr;
02300 unsigned int lflags;
02301
02302 minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum","1"));
02303 maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum","1"));
02304 gversion=atoi(GWEN_XMLNode_GetProperty(n, "version","0"));
02305 addEmptyMode=GWEN_XMLNode_GetProperty(n, "addemptymode","one");
02306
02307 lflags=flags;
02308
02309 DBG_DEBUG(GWEN_LOGDOMAIN, "Omitted elements: %d", omittedElements);
02310 t=GWEN_XMLNode_GetType(n);
02311 if (t==GWEN_XMLNodeTypeTag) {
02312 const char *typ;
02313
02314 typ=GWEN_XMLNode_GetData(n);
02315 if (typ==0) {
02316 DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed tag found (internal error?)");
02317 return -1;
02318 }
02319 if (strcasecmp(typ, "ELEM")==0) {
02320
02321
02322
02323 rv=GWEN_MsgEngine__ShowElement(e,
02324 path,
02325 n,
02326 sl,
02327 lflags);
02328 if (rv==-1)
02329 return -1;
02330 else {
02331 isFirstElement=0;
02332 omittedElements=0;
02333 }
02334 }
02335 else if (strcasecmp(typ, "VALUES")==0) {
02336 }
02337 else if (strcasecmp(typ, "DESCR")==0) {
02338 }
02339 else {
02340
02341 GWEN_XMLNODE *gn;
02342 const char *gname;
02343 const char *gtype;
02344
02345 if (minnum==0)
02346 lflags|=GWEN_MSGENGINE_SHOW_FLAGS_OPTIONAL;
02347
02348 gtype=GWEN_XMLNode_GetProperty(n, "type",0);
02349 if (!gtype) {
02350
02351 DBG_DEBUG(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", typ);
02352 gtype="";
02353 gn=n;
02354 }
02355 else {
02356 gn=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", gversion, gtype);
02357 if (!gn) {
02358 DBG_DEBUG(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", typ);
02359 return -1;
02360 }
02361 }
02362
02363
02364 for (loopNr=0; loopNr<maxnum; loopNr++) {
02365
02366 char pbuffer[256];
02367 const char *npath;
02368
02369
02370 gname=GWEN_XMLNode_GetProperty(n, "name",0);
02371 if (gname) {
02372 if (loopNr==0) {
02373 if (strlen(path)+strlen(gname)+1>sizeof(pbuffer)) {
02374 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02375 return -1;
02376 }
02377 sprintf(pbuffer, "%s/%s", path, gname);
02378 npath=pbuffer;
02379 }
02380 else {
02381
02382 if (strlen(path)+strlen(gname)+10>sizeof(pbuffer)) {
02383 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02384 return -1;
02385 }
02386 if (*path)
02387 sprintf(pbuffer, "%s/%s%d", path, gname, loopNr);
02388 else
02389 sprintf(pbuffer, "%s%d", gname, loopNr);
02390
02391 npath=pbuffer;
02392 }
02393 }
02394 else
02395 npath=path;
02396
02397
02398 if (GWEN_MsgEngine__ShowGroup(e,
02399 npath,
02400 gn,
02401 n,
02402 sl,
02403 lflags)) {
02404 DBG_INFO(GWEN_LOGDOMAIN, "Could not show group \"%s\"", gtype);
02405 return -1;
02406 }
02407 }
02408 }
02409 }
02410 n=GWEN_XMLNode_Next(n);
02411 }
02412
02413 return 0;
02414 }
02415
02416
02417
02418 int GWEN_MsgEngine_ShowMessage(GWEN_MSGENGINE *e,
02419 const char *typ,
02420 const char *msgName,
02421 int msgVersion,
02422 uint32_t flags) {
02423 GWEN_XMLNODE *group;
02424 GWEN_STRINGLIST *sl;
02425 int i, j;
02426 const char *p;
02427
02428 sl=GWEN_StringList_new();
02429
02430 fprintf(stdout, "Message \"%s\" version %d\n",
02431 msgName, msgVersion);
02432 for (i=0; i<76; i++)
02433 fprintf(stdout, "=");
02434 fprintf(stdout, "\n");
02435 p=" Variable";
02436 fprintf(stdout, "%s", p);
02437 i=GWEN_MSGENGINE_VARNAME_WIDTH-strlen(p);
02438 for (j=0; j<i; j++)
02439 fprintf(stdout," ");
02440
02441 fprintf(stdout," |");
02442 p=" Type";
02443 fprintf(stdout, "%s", p);
02444 i=GWEN_MSGENGINE_TYPENAME_WIDTH-strlen(p);
02445 for (j=0; j<i; j++)
02446 fprintf(stdout," ");
02447
02448 fprintf(stdout," | Size | Num | Flags\n");
02449 for (i=0; i<76; i++)
02450 fprintf(stdout, "-");
02451 fprintf(stdout, "\n");
02452
02453 group=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", msgVersion, msgName);
02454 if (!group) {
02455 DBG_ERROR(GWEN_LOGDOMAIN, "Group \"%s\" not found\n", msgName);
02456 GWEN_StringList_free(sl);
02457 return -1;
02458 }
02459
02460 if (GWEN_MsgEngine__ShowGroup(e,
02461 "",
02462 group,
02463 0,
02464 sl,
02465 flags)) {
02466 DBG_INFO(GWEN_LOGDOMAIN, "Error showing group \"%s\"", msgName);
02467 GWEN_StringList_free(sl);
02468 return -1;
02469 }
02470
02471 GWEN_StringList_free(sl);
02472
02473 return 0;
02474 }
02475
02476
02477
02478 int GWEN_MsgEngine__ListElement(GWEN_UNUSED GWEN_MSGENGINE *e,
02479 const char *path,
02480 GWEN_XMLNODE *node,
02481 GWEN_STRINGLIST *sl,
02482 GWEN_XMLNODE *listNode,
02483 uint32_t flags) {
02484 const char *name;
02485 const char *type;
02486 const char *npath;
02487 int isSet;
02488 char nbuffer[256];
02489 GWEN_STRINGLISTENTRY *en;
02490 GWEN_XMLNODE *nn;
02491
02492
02493 type=GWEN_XMLNode_GetProperty(node, "type","ASCII");
02494
02495 npath="";
02496 isSet=0;
02497
02498
02499 name=GWEN_XMLNode_GetProperty(node, "name", 0);
02500 if (path==0)
02501 path="";
02502
02503 if (name) {
02504
02505 if (strlen(path)+strlen(name)+10>=sizeof(nbuffer)) {
02506 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02507 return -1;
02508 }
02509 if (*path)
02510 sprintf(nbuffer, "%s/%s", path, name);
02511 else
02512 sprintf(nbuffer, "%s", name);
02513 npath=nbuffer;
02514 }
02515
02516 en=GWEN_StringList_FirstEntry(sl);
02517 while(en) {
02518 if (GWEN_StringListEntry_Data(en))
02519 if (strcasecmp(GWEN_StringListEntry_Data(en), npath)==0) {
02520 isSet=1;
02521 break;
02522 }
02523 en=GWEN_StringListEntry_Next(en);
02524 }
02525
02526 if (isSet && (flags & GWEN_MSGENGINE_SHOW_FLAGS_NOSET))
02527 return 0;
02528
02529 nn=GWEN_XMLNode_dup(node);
02530 if (isSet)
02531 GWEN_XMLNode_SetProperty(nn, "GWEN_set", "1");
02532 GWEN_XMLNode_SetProperty(nn, "GWEN_path", npath);
02533 GWEN_XMLNode_AddChild(listNode, nn);
02534
02535 return 0;
02536 }
02537
02538
02539
02540 int GWEN_MsgEngine__ListGroup(GWEN_MSGENGINE *e,
02541 const char *path,
02542 GWEN_XMLNODE *node,
02543 GWEN_XMLNODE *rnode,
02544 GWEN_STRINGLIST *sl,
02545 GWEN_XMLNODE *listNode,
02546 uint32_t flags) {
02547 GWEN_XMLNODE *n;
02548 int rv;
02549
02550
02551 n=GWEN_XMLNode_GetChild(node);
02552
02553 if (path==0)
02554 path="";
02555 if (*path=='/')
02556 path++;
02557
02558 while(n) {
02559 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
02560 const char *p;
02561
02562 p=GWEN_XMLNode_GetData(n);
02563 assert(p);
02564 DBG_DEBUG(GWEN_LOGDOMAIN, "Checking %s",p);
02565 if (strcasecmp(p, "VALUES")==0)
02566 break;
02567 }
02568 n=GWEN_XMLNode_Next(n);
02569 }
02570
02571 if (n) {
02572 DBG_DEBUG(GWEN_LOGDOMAIN, "<values> found");
02573
02574 n=GWEN_XMLNode_GetChild(n);
02575 while(n) {
02576 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
02577 const char *p;
02578
02579 p=GWEN_XMLNode_GetData(n);
02580 assert(p);
02581 if (strcasecmp(p, "VALUE")==0) {
02582 const char *pname;
02583 const char *pvalue;
02584
02585 pname=GWEN_XMLNode_GetProperty(n, "path", 0);
02586 if (pname) {
02587 GWEN_XMLNODE *dn;
02588
02589
02590 dn=GWEN_XMLNode_GetChild(n);
02591 while (dn) {
02592 if (GWEN_XMLNode_GetType(dn)==GWEN_XMLNodeTypeData) {
02593 pvalue=GWEN_XMLNode_GetData(dn);
02594 if (pvalue) {
02595 char pbuffer[256];
02596
02597
02598 p=pvalue;
02599 while (*p && isspace((int)*p))
02600 p++;
02601 if (strlen(path)+strlen(pname)+2>sizeof(pbuffer)) {
02602 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02603 return -1;
02604 }
02605 if (*path)
02606 sprintf(pbuffer, "%s/%s", path, pname);
02607 else
02608 sprintf(pbuffer, "%s", pname);
02609 DBG_INFO(GWEN_LOGDOMAIN, "Found preset value for %s", pbuffer);
02610 GWEN_StringList_AppendString(sl,
02611 pbuffer,
02612 0,
02613 1);
02614 }
02615 break;
02616 }
02617 dn=GWEN_XMLNode_Next(dn);
02618 }
02619 }
02620 }
02621 }
02622 n=GWEN_XMLNode_Next(n);
02623 }
02624 }
02625
02626
02627 n=GWEN_XMLNode_GetChild(node);
02628 while(n) {
02629 int t;
02630 int gversion;
02631 unsigned int lflags;
02632
02633 gversion=atoi(GWEN_XMLNode_GetProperty(n, "version","0"));
02634 lflags=flags;
02635
02636 t=GWEN_XMLNode_GetType(n);
02637 if (t==GWEN_XMLNodeTypeTag) {
02638 const char *typ;
02639
02640 typ=GWEN_XMLNode_GetData(n);
02641 if (typ==0) {
02642 DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed tag found (internal error?)");
02643 return -1;
02644 }
02645 if (strcasecmp(typ, "ELEM")==0) {
02646
02647
02648
02649 rv=GWEN_MsgEngine__ListElement(e,
02650 path,
02651 n,
02652 sl,
02653 listNode,
02654 lflags);
02655 if (rv==-1)
02656 return -1;
02657 }
02658 else if (strcasecmp(typ, "VALUES")==0) {
02659 }
02660 else if (strcasecmp(typ, "DESCR")==0) {
02661 }
02662 else {
02663
02664 GWEN_XMLNODE *gn;
02665 GWEN_XMLNODE *nn;
02666 const char *gname;
02667 const char *gtype;
02668 char pbuffer[256];
02669 const char *npath;
02670
02671 gtype=GWEN_XMLNode_GetProperty(n, "type",0);
02672 if (!gtype) {
02673
02674 DBG_DEBUG(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", typ);
02675 gtype="";
02676 gn=n;
02677 }
02678 else {
02679 gn=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", gversion, gtype);
02680 if (!gn) {
02681 DBG_DEBUG(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", typ);
02682 return -1;
02683 }
02684 }
02685
02686
02687 gname=GWEN_XMLNode_GetProperty(n, "name",0);
02688 if (gname) {
02689 if (strlen(path)+strlen(gname)+1>sizeof(pbuffer)) {
02690 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02691 return -1;
02692 }
02693
02694 if (*path)
02695 sprintf(pbuffer, "%s/%s", path, gname);
02696 else
02697 sprintf(pbuffer, "%s", gname);
02698 npath=pbuffer;
02699 }
02700 else
02701 npath=path;
02702
02703 nn=GWEN_XMLNode_dup(n);
02704 if (gn!=n)
02705 GWEN_XMLNode_CopyProperties(nn, gn, 0);
02706 GWEN_XMLNode_SetProperty(nn, "GWEN_path", npath);
02707 GWEN_XMLNode_AddChild(listNode, nn);
02708
02709
02710 if (GWEN_MsgEngine__ListGroup(e,
02711 npath,
02712 gn,
02713 n,
02714 sl,
02715 nn,
02716 lflags)) {
02717 DBG_INFO(GWEN_LOGDOMAIN, "Could not list group \"%s\"", gtype);
02718 return -1;
02719 }
02720 }
02721 }
02722 n=GWEN_XMLNode_Next(n);
02723 }
02724
02725 return 0;
02726 }
02727
02728
02729
02730 GWEN_XMLNODE *GWEN_MsgEngine_ListMessage(GWEN_MSGENGINE *e,
02731 const char *typ,
02732 const char *msgName,
02733 int msgVersion,
02734 uint32_t flags) {
02735 GWEN_XMLNODE *group;
02736 GWEN_STRINGLIST *sl;
02737 GWEN_XMLNODE *listNode;
02738
02739 group=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", msgVersion, msgName);
02740 if (!group)
02741 group=GWEN_MsgEngine_FindNodeByProperty(e, typ, "code",
02742 msgVersion, msgName);
02743 if (!group) {
02744 DBG_ERROR(GWEN_LOGDOMAIN, "Group \"%s\" (version %d) not found\n",
02745 msgName, msgVersion);
02746 return 0;
02747 }
02748
02749 sl=GWEN_StringList_new();
02750
02751 listNode=GWEN_XMLNode_dup(group);
02752 GWEN_XMLNode_RemoveChildren(listNode);
02753
02754 if (GWEN_MsgEngine__ListGroup(e,
02755 "",
02756 group,
02757 0,
02758 sl,
02759 listNode,
02760 flags)) {
02761 DBG_INFO(GWEN_LOGDOMAIN, "Error showing group \"%s\"", msgName);
02762 GWEN_StringList_free(sl);
02763 GWEN_XMLNode_free(listNode);
02764 return 0;
02765 }
02766
02767 GWEN_StringList_free(sl);
02768
02769 return listNode;
02770 }
02771
02772
02773
02774
02775
02776
02777
02778 int GWEN_MsgEngine__ReadValue(GWEN_MSGENGINE *e,
02779 GWEN_BUFFER *msgbuf,
02780 GWEN_XMLNODE *node,
02781 GWEN_XMLNODE *rnode,
02782 GWEN_BUFFER *vbuf,
02783 const char *delimiters,
02784 uint32_t flags) {
02785 unsigned int minsize;
02786 unsigned int maxsize;
02787 unsigned int size;
02788 unsigned int minnum;
02789 GWEN_MSGENGINE_TRUSTLEVEL trustLevel;
02790 unsigned int posInMsg;
02791 const char *type;
02792 int rv;
02793 unsigned int realSize;
02794
02795
02796 posInMsg=GWEN_Buffer_GetPos(msgbuf);
02797 realSize=0;
02798 size=atoi(GWEN_XMLNode_GetProperty(node, "size","0"));
02799 minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize","0"));
02800 maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize","0"));
02801 minnum=atoi(GWEN_XMLNode_GetProperty(node, "minnum","1"));
02802 type=GWEN_XMLNode_GetProperty(node, "type","ASCII");
02803
02804 rv=1;
02805 if (e->typeReadPtr) {
02806 rv=e->typeReadPtr(e,
02807 msgbuf,
02808 node,
02809 vbuf,
02810 e->escapeChar,
02811 delimiters);
02812 }
02813 if (rv==-1) {
02814 DBG_INFO(GWEN_LOGDOMAIN, "External type reading failed on type \"%s\"", type);
02815 return -1;
02816 }
02817 else if (rv==1) {
02818 if (strcasecmp(type, "bin")==0) {
02819 if (GWEN_Buffer_GetBytesLeft(msgbuf)==0) {
02820 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (@num@ expected)");
02821 return -1;
02822 }
02823 else {
02824 char lbuffer[16];
02825 int c;
02826 char *p;
02827 int l;
02828
02829 p=lbuffer;
02830 c=GWEN_Buffer_ReadByte(msgbuf);
02831 if (c!='@') {
02832 DBG_ERROR(GWEN_LOGDOMAIN, "\"@num@\" expected");
02833 return -1;
02834 }
02835
02836 c=0;
02837 while(GWEN_Buffer_GetBytesLeft(msgbuf)>0) {
02838 c=GWEN_Buffer_ReadByte(msgbuf);
02839 if (c==-1) {
02840 DBG_ERROR(GWEN_LOGDOMAIN, "\"@\" expected");
02841 return -1;
02842 }
02843 if (c=='@')
02844 break;
02845 *p=(char)c;
02846 p++;
02847 }
02848 *p=0;
02849 if (c!='@') {
02850 DBG_ERROR(GWEN_LOGDOMAIN, "\"@num@\" expected");
02851 return -1;
02852 }
02853 if (sscanf(lbuffer, "%d", &l)!=1) {
02854 DBG_ERROR(GWEN_LOGDOMAIN, "Bad number format");
02855 return -1;
02856 }
02857 DBG_DEBUG(GWEN_LOGDOMAIN, "Reading binary: %d bytes from pos %d (msgsize=%d)",
02858 l,
02859 GWEN_Buffer_GetPos(msgbuf),
02860 GWEN_Buffer_GetUsedBytes(msgbuf));
02861 if (GWEN_Buffer_GetBytesLeft(msgbuf) < (unsigned) l) {
02862 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (binary beyond end)");
02863 return -1;
02864 }
02865 if (GWEN_Buffer_AppendBytes(vbuf,
02866 GWEN_Buffer_GetPosPointer(msgbuf),
02867 l)) {
02868 DBG_DEBUG(GWEN_LOGDOMAIN, "Called from here");
02869 return -1;
02870 }
02871 GWEN_Buffer_IncrementPos(msgbuf,l);
02872 }
02873 }
02874 else {
02875
02876 int lastWasEscape;
02877 int isEscaped;
02878 int br;
02879
02880 isEscaped=0;
02881 lastWasEscape=0;
02882
02883 br=0;
02884 while(GWEN_Buffer_GetBytesLeft(msgbuf) &&
02885 (size==0 || br<size)) {
02886 int c;
02887
02888 c=GWEN_Buffer_ReadByte(msgbuf);
02889 if (lastWasEscape) {
02890 lastWasEscape=0;
02891 isEscaped=1;
02892 }
02893 else {
02894 isEscaped=0;
02895 if (c==e->escapeChar) {
02896 lastWasEscape=1;
02897 c=-1;
02898 }
02899 }
02900 if (c!=-1) {
02901 if (!isEscaped && (c && strchr(delimiters, c)!=0)) {
02902
02903 GWEN_Buffer_DecrementPos(msgbuf,1);
02904 break;
02905 }
02906 else {
02907 if (c=='\\' || iscntrl(c)) {
02908 DBG_WARN(GWEN_LOGDOMAIN,
02909 "Found a bad character (%02x) in type \"%s\", "
02910 "converting to SPACE",
02911 (unsigned int)c,
02912 type);
02913 c=' ';
02914 }
02915 if (GWEN_Buffer_AppendByte(vbuf, c)) {
02916 DBG_DEBUG(GWEN_LOGDOMAIN, "Called from here");
02917 return -1;
02918 }
02919 br++;
02920 }
02921 }
02922 }
02923 }
02924 }
02925 else {
02926 DBG_DEBUG(GWEN_LOGDOMAIN, "Type \"%s\" is external (read)", type);
02927 }
02928
02929 realSize=GWEN_Buffer_GetUsedBytes(vbuf);
02930
02931
02932 if (realSize==0) {
02933 DBG_DEBUG(GWEN_LOGDOMAIN, "Datasize is 0");
02934 if (minnum==0) {
02935 DBG_DEBUG(GWEN_LOGDOMAIN, "... but thats ok");
02936
02937 return 1;
02938 }
02939 else {
02940 DBG_ERROR(GWEN_LOGDOMAIN, "Value missing");
02941 GWEN_XMLNode_Dump(node, 1);
02942 return -1;
02943 }
02944 }
02945
02946
02947 if (minsize!=0 && realSize<minsize) {
02948 DBG_INFO(GWEN_LOGDOMAIN, "Value too short (%d<%d).",
02949 realSize,
02950 minsize);
02951 return -1;
02952 }
02953
02954
02955 if (maxsize!=0 && realSize>maxsize) {
02956 DBG_INFO(GWEN_LOGDOMAIN, "Value too long (%d>%d).",
02957 realSize, maxsize);
02958 return -1;
02959 }
02960
02961 if (flags & GWEN_MSGENGINE_READ_FLAGS_TRUSTINFO) {
02962
02963 const char *descr;
02964
02965 trustLevel=GWEN_MsgEngine_GetHighestTrustLevel(node, rnode);
02966 if (trustLevel) {
02967 unsigned int ustart;
02968
02969 ustart=GWEN_Buffer_GetPos(msgbuf)-realSize;
02970 descr=GWEN_XMLNode_GetProperty(node, "name",0);
02971 if (GWEN_MsgEngine_AddTrustInfo(e,
02972 GWEN_Buffer_GetStart(vbuf),
02973 realSize,
02974 descr,
02975 trustLevel,
02976 ustart)) {
02977 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
02978 return -1;
02979 }
02980 }
02981 }
02982
02983 return 0;
02984 }
02985
02986
02987
02988 int GWEN_MsgEngine__ReadGroup(GWEN_MSGENGINE *e,
02989 GWEN_BUFFER *msgbuf,
02990 GWEN_XMLNODE *node,
02991 GWEN_XMLNODE *rnode,
02992 GWEN_DB_NODE *gr,
02993 const char *delimiters,
02994 uint32_t flags) {
02995 unsigned int minsize;
02996 unsigned int maxsize;
02997 unsigned int minnum;
02998 unsigned int maxnum;
02999 const char *name;
03000 const char *p;
03001 char delimiter;
03002 char terminator;
03003 GWEN_XMLNODE *n;
03004 int abortLoop;
03005 GWEN_BUFFER *delimBuffer=0;
03006
03007
03008 if (rnode) {
03009
03010 p=GWEN_XMLNode_GetProperty(rnode,
03011 "delimiter",
03012 GWEN_XMLNode_GetProperty(node,
03013 "delimiter",
03014 ""));
03015 delimiter=*p;
03016
03017
03018 p=GWEN_XMLNode_GetProperty(rnode,
03019 "terminator",
03020 GWEN_XMLNode_GetProperty(node,
03021 "terminator",
03022 ""));
03023 terminator=*p;
03024 }
03025 else {
03026
03027 p=GWEN_XMLNode_GetProperty(node,
03028 "delimiter",
03029 "");
03030 delimiter=*p;
03031
03032
03033 p=GWEN_XMLNode_GetProperty(node, "terminator","");
03034 terminator=*p;
03035 }
03036
03037 delimBuffer=GWEN_Buffer_new(0, strlen(delimiters)+2, 0, 1);
03038 GWEN_Buffer_AppendString(delimBuffer, delimiters);
03039 if (delimiter)
03040 GWEN_Buffer_AppendByte(delimBuffer, delimiter);
03041 if (terminator)
03042 GWEN_Buffer_AppendByte(delimBuffer, terminator);
03043
03044 DBG_DEBUG(GWEN_LOGDOMAIN, "Delimiters are \"%s\" and \"%c\"",
03045 delimiters, delimiter);
03046
03047 n=GWEN_XMLNode_GetChild(node);
03048 while (n) {
03049 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
03050 const char *type;
03051
03052 if (GWEN_Buffer_GetBytesLeft(msgbuf)==0)
03053 break;
03054
03055 type=GWEN_XMLNode_GetData(n);
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065 if (strcasecmp(type, "ELEM")==0) {
03066 unsigned int loopNr;
03067
03068
03069 minsize=atoi(GWEN_XMLNode_GetProperty(n, "minsize","0"));
03070 maxsize=atoi(GWEN_XMLNode_GetProperty(n, "maxsize","0"));
03071 minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum","1"));
03072 maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum","1"));
03073 name=GWEN_XMLNode_GetProperty(n, "name", 0);
03074
03075 loopNr=0;
03076 abortLoop=0;
03077 while((maxnum==0 || loopNr<maxnum) && !abortLoop) {
03078 int c;
03079
03080 DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading %s", name);
03081 if (GWEN_Buffer_GetBytesLeft(msgbuf)==0)
03082 break;
03083 c=GWEN_Buffer_PeekByte(msgbuf);
03084 if (c==-1) {
03085 DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
03086 GWEN_Buffer_free(delimBuffer);
03087 return -1;
03088 }
03089
03090 DBG_VERBOUS(GWEN_LOGDOMAIN,
03091 "Checking delimiter at pos %x "
03092 "(whether \"%c\" is in \"%s\")",
03093 GWEN_Buffer_GetPos(msgbuf),
03094 c, GWEN_Buffer_GetStart(delimBuffer));
03095 if (c && strchr(GWEN_Buffer_GetStart(delimBuffer), c)) {
03096 abortLoop=1;
03097 DBG_VERBOUS(GWEN_LOGDOMAIN,
03098 "Found delimiter (\"%c\" is in \"%s\")",
03099 c, GWEN_Buffer_GetStart(delimBuffer));
03100 }
03101 else {
03102
03103 if (name==0) {
03104 DBG_VERBOUS(GWEN_LOGDOMAIN, "no name");
03105 }
03106 else {
03107
03108 int rv;
03109 const char *dtype;
03110 GWEN_BUFFER *vbuf;
03111
03112 DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading value from pos %x",
03113 GWEN_Buffer_GetPos(msgbuf));
03114 vbuf=GWEN_Buffer_new(0,
03115 GWEN_MSGENGINE_MAX_VALUE_LEN,
03116 0,0);
03117
03118
03119
03120
03121
03122
03123 rv=GWEN_MsgEngine__ReadValue(e,
03124 msgbuf,
03125 n,
03126 rnode,
03127 vbuf,
03128 GWEN_Buffer_GetStart(delimBuffer),
03129
03130 flags);
03131 if (rv==1) {
03132 DBG_INFO(GWEN_LOGDOMAIN, "Empty value");
03133 }
03134 else if (rv==-1) {
03135 DBG_INFO(GWEN_LOGDOMAIN, "Error parsing node \"%s\" (%s)",
03136 name,
03137 type);
03138 GWEN_Buffer_free(vbuf);
03139 GWEN_Buffer_free(delimBuffer);
03140 return -1;
03141 }
03142
03143 GWEN_Buffer_Rewind(vbuf);
03144
03145
03146 dtype=GWEN_XMLNode_GetProperty(n, "type", "");
03147 if (GWEN_MsgEngine__IsBinTyp(e, dtype)) {
03148 if (atoi(GWEN_XMLNode_GetProperty(n, "readbin", "1")) &&
03149 e->binTypeReadPtr) {
03150 rv=e->binTypeReadPtr(e, n, gr, vbuf);
03151 }
03152 else
03153 rv=1;
03154 if (rv==-1) {
03155 DBG_INFO(GWEN_LOGDOMAIN, "Called from here");
03156 GWEN_Buffer_free(vbuf);
03157 GWEN_Buffer_free(delimBuffer);
03158 return -1;
03159 }
03160 else if (rv==1) {
03161
03162 if (GWEN_DB_SetBinValue(gr,
03163 GWEN_DB_FLAGS_DEFAULT,
03164 name,
03165 GWEN_Buffer_GetStart(vbuf),
03166 GWEN_Buffer_GetUsedBytes(vbuf))) {
03167 DBG_INFO(GWEN_LOGDOMAIN, "Could not set value for \"%s\"", name);
03168 GWEN_Buffer_free(vbuf);
03169 GWEN_Buffer_free(delimBuffer);
03170 return -1;
03171 }
03172 }
03173 }
03174 else if (GWEN_MsgEngine__IsIntTyp(e, dtype)) {
03175 int z;
03176
03177 if (1!=sscanf(GWEN_Buffer_GetStart(vbuf), "%d", &z)) {
03178 DBG_INFO(GWEN_LOGDOMAIN, "Value for \"%s\" is not an integer",
03179 name);
03180 GWEN_Buffer_free(delimBuffer);
03181 return -1;
03182 }
03183 if (GWEN_DB_SetIntValue(gr,
03184 GWEN_DB_FLAGS_DEFAULT,
03185 name, z)) {
03186 DBG_INFO(GWEN_LOGDOMAIN, "Could not set int value for \"%s\"", name);
03187 GWEN_Buffer_free(delimBuffer);
03188 return -1;
03189 }
03190 }
03191 else {
03192 DBG_DEBUG(GWEN_LOGDOMAIN, "Value is \"%s\"",
03193 GWEN_Buffer_GetStart(vbuf));
03194 if (GWEN_DB_SetCharValue(gr,
03195 GWEN_DB_FLAGS_DEFAULT,
03196 name,
03197 GWEN_Buffer_GetStart(vbuf))){
03198 DBG_INFO(GWEN_LOGDOMAIN, "Could not set value for \"%s\"", name);
03199 GWEN_Buffer_free(delimBuffer);
03200 return -1;
03201 }
03202 }
03203
03204 GWEN_Buffer_free(vbuf);
03205 }
03206 }
03207
03208 if (GWEN_Buffer_GetBytesLeft(msgbuf)) {
03209 if (delimiter) {
03210 if (GWEN_Buffer_PeekByte(msgbuf)==delimiter) {
03211 GWEN_Buffer_IncrementPos(msgbuf,1);
03212 }
03213 }
03214 }
03215 loopNr++;
03216 }
03217 if (loopNr<minnum) {
03218 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (too few ELEM repeats)");
03219 GWEN_XMLNode_Dump(n, 2);
03220 GWEN_Buffer_free(delimBuffer);
03221 return -1;
03222 }
03223 n=GWEN_XMLNode_Next(n);
03224 }
03225 else if (strcasecmp(type, "VALUES")==0) {
03226 n=GWEN_XMLNode_Next(n);
03227 }
03228 else if (strcasecmp(type, "DESCR")==0) {
03229 n=GWEN_XMLNode_Next(n);
03230 }
03231 else {
03232
03233 GWEN_XMLNODE *gn;
03234 GWEN_DB_NODE *gcfg;
03235 const char *gname;
03236 const char *gtype;
03237 unsigned int gversion;
03238 unsigned int loopNr;
03239
03240 minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum","1"));
03241 maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum","1"));
03242 gversion=atoi(GWEN_XMLNode_GetProperty(n, "version","0"));
03243 gtype=GWEN_XMLNode_GetProperty(n, "type",0);
03244 if (!gtype) {
03245
03246 DBG_INFO(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", type);
03247 gtype="";
03248 gn=n;
03249 }
03250 else {
03251 gn=GWEN_MsgEngine_FindNodeByProperty(e, type, "id",
03252 gversion, gtype);
03253 if (!gn) {
03254 DBG_INFO(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", type);
03255 GWEN_Buffer_free(delimBuffer);
03256 return -1;
03257 }
03258 }
03259
03260
03261 loopNr=0;
03262 abortLoop=0;
03263 while((maxnum==0 || loopNr<maxnum) && !abortLoop) {
03264 int c;
03265
03266 DBG_DEBUG(GWEN_LOGDOMAIN, "Reading group type %s", gtype);
03267 if (GWEN_Buffer_GetBytesLeft(msgbuf)==0)
03268 break;
03269 c=GWEN_Buffer_PeekByte(msgbuf);
03270 if (c && strchr(GWEN_Buffer_GetStart(delimBuffer), c)) {
03271 abortLoop=1;
03272 }
03273 else {
03274 gname=GWEN_XMLNode_GetProperty(n, "name",0);
03275 if (gname) {
03276 DBG_DEBUG(GWEN_LOGDOMAIN, "Creating group \"%s\"", gname);
03277 gcfg=GWEN_DB_GetGroup(gr,
03278 GWEN_PATH_FLAGS_CREATE_GROUP,
03279 gname);
03280 if (!gcfg) {
03281 DBG_ERROR(GWEN_LOGDOMAIN, "Could not select group \"%s\"",
03282 gname);
03283 GWEN_Buffer_free(delimBuffer);
03284 return -1;
03285 }
03286 DBG_DEBUG(GWEN_LOGDOMAIN, "Created group \"%s\"", gname);
03287 }
03288 else
03289 gcfg=gr;
03290
03291
03292 DBG_DEBUG(GWEN_LOGDOMAIN, "Reading group \"%s\"", gname);
03293 if (GWEN_MsgEngine__ReadGroup(e,
03294 msgbuf,
03295 gn,
03296 n,
03297 gcfg,
03298 GWEN_Buffer_GetStart(delimBuffer),
03299 flags)) {
03300 DBG_INFO(GWEN_LOGDOMAIN, "Could not read group \"%s\"", gtype);
03301 GWEN_Buffer_free(delimBuffer);
03302 return -1;
03303 }
03304 }
03305 if (GWEN_Buffer_GetBytesLeft(msgbuf)) {
03306 if (delimiter) {
03307 if (GWEN_Buffer_PeekByte(msgbuf)==delimiter) {
03308 GWEN_Buffer_IncrementPos(msgbuf, 1);
03309 }
03310 }
03311 }
03312 loopNr++;
03313 }
03314 if (loopNr<minnum) {
03315 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (too few group repeats)");
03316 GWEN_Buffer_free(delimBuffer);
03317 return -1;
03318 }
03319 n=GWEN_XMLNode_Next(n);
03320 }
03321 }
03322 else {
03323 n=GWEN_XMLNode_Next(n);
03324 }
03325 }
03326
03327
03328 while(n) {
03329 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
03330 if (strcasecmp(GWEN_XMLNode_GetData(n), "ELEM")==0 ||
03331 strcasecmp(GWEN_XMLNode_GetData(n), "GROUP")==0) {
03332 unsigned int i;
03333
03334 i=atoi(GWEN_XMLNode_GetProperty(n, "minnum", "1"));
03335 if (i) {
03336 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (still tags to parse)");
03337 GWEN_XMLNode_Dump(n, 2);
03338 GWEN_Buffer_free(delimBuffer);
03339 return -1;
03340 }
03341 }
03342 }
03343 n=GWEN_XMLNode_Next(n);
03344 }
03345
03346
03347 if (terminator) {
03348
03349 if (GWEN_Buffer_GetBytesLeft(msgbuf)) {
03350 if (GWEN_Buffer_PeekByte(msgbuf)==terminator) {
03351 GWEN_Buffer_IncrementPos(msgbuf, 1);
03352 }
03353 else {
03354 DBG_ERROR(GWEN_LOGDOMAIN,
03355 "Terminating character missing (pos=%d [%x]) "
03356 "expecting \"%c\", got \"%c\")",
03357 GWEN_Buffer_GetPos(msgbuf),
03358 GWEN_Buffer_GetPos(msgbuf),
03359 terminator,
03360 GWEN_Buffer_PeekByte(msgbuf));
03361 GWEN_XMLNode_Dump(node, 1);
03362 GWEN_Buffer_free(delimBuffer);
03363 return -1;
03364 }
03365 }
03366 else {
03367 DBG_ERROR(GWEN_LOGDOMAIN, "Terminating character missing");
03368 GWEN_Buffer_free(delimBuffer);
03369 return -1;
03370 }
03371 }
03372
03373 GWEN_Buffer_free(delimBuffer);
03374 return 0;
03375 }
03376
03377
03378
03379 int GWEN_MsgEngine_ParseMessage(GWEN_MSGENGINE *e,
03380 GWEN_XMLNODE *group,
03381 GWEN_BUFFER *msgbuf,
03382 GWEN_DB_NODE *msgData,
03383 uint32_t flags){
03384
03385 if (GWEN_MsgEngine__ReadGroup(e,
03386 msgbuf,
03387 group,
03388 0,
03389 msgData,
03390 e->delimiters,
03391 flags)) {
03392 DBG_INFO(GWEN_LOGDOMAIN, "Error reading group");
03393 return -1;
03394 }
03395
03396 return 0;
03397 }
03398
03399
03400
03401 int GWEN_MsgEngine_SetValue(GWEN_MSGENGINE *e,
03402 const char *path,
03403 const char *value){
03404 GWEN_DB_NODE *globalValues;
03405
03406 assert(e);
03407 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
03408 assert(globalValues);
03409 return GWEN_DB_SetCharValue(globalValues,
03410 GWEN_DB_FLAGS_DEFAULT |
03411 GWEN_DB_FLAGS_OVERWRITE_VARS,
03412 path, value);
03413 }
03414
03415
03416
03417 int GWEN_MsgEngine_SetIntValue(GWEN_MSGENGINE *e,
03418 const char *path,
03419 int value){
03420 GWEN_DB_NODE *globalValues;
03421
03422 assert(e);
03423 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
03424 assert(globalValues);
03425 return GWEN_DB_SetIntValue(globalValues,
03426 GWEN_DB_FLAGS_DEFAULT |
03427 GWEN_DB_FLAGS_OVERWRITE_VARS,
03428 path, value);
03429 }
03430
03431
03432
03433 const char *GWEN_MsgEngine_GetValue(GWEN_MSGENGINE *e,
03434 const char *path,
03435 const char *defValue){
03436 GWEN_DB_NODE *globalValues;
03437
03438 assert(e);
03439 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
03440 assert(globalValues);
03441 return GWEN_DB_GetCharValue(globalValues,
03442 path, 0, defValue);
03443 }
03444
03445
03446
03447 int GWEN_MsgEngine_GetIntValue(GWEN_MSGENGINE *e,
03448 const char *path,
03449 int defValue){
03450 GWEN_DB_NODE *globalValues;
03451
03452 assert(e);
03453 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
03454 assert(globalValues);
03455 return GWEN_DB_GetIntValue(globalValues,
03456 path, 0, defValue);
03457 }
03458
03459
03460
03461
03462 int GWEN_MsgEngine_SkipSegment(GWEN_UNUSED GWEN_MSGENGINE *e,
03463 GWEN_BUFFER *msgbuf,
03464 unsigned char escapeChar,
03465 unsigned char delimiter) {
03466 int esc;
03467
03468 esc=0;
03469 while(GWEN_Buffer_GetBytesLeft(msgbuf)) {
03470 if (esc) {
03471 esc=0;
03472 }
03473 else {
03474 int i;
03475 unsigned char c;
03476
03477 i=GWEN_Buffer_ReadByte(msgbuf);
03478 if (i==-1) {
03479 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
03480 return 0;
03481 }
03482 c=(unsigned int)i;
03483 if (c==escapeChar) {
03484 esc=1;
03485 }
03486 else if (c=='@') {
03487
03488 char lbuffer[16];
03489 char *p;
03490 int l;
03491 int nc;
03492
03493 p=lbuffer;
03494 while(1) {
03495 nc=GWEN_Buffer_ReadByte(msgbuf);
03496 if (nc==-1) {
03497 DBG_ERROR(GWEN_LOGDOMAIN, "\"@num@\" expected");
03498 return -1;
03499 }
03500 if (nc=='@')
03501 break;
03502 *p=nc;
03503 p++;
03504 }
03505 *p=0;
03506 if (sscanf(lbuffer, "%d", &l)!=1) {
03507 DBG_ERROR(GWEN_LOGDOMAIN, "Bad number format");
03508 return -1;
03509 }
03510 if (GWEN_Buffer_GetUsedBytes(msgbuf)-GWEN_Buffer_GetPos(msgbuf)
03511 < (unsigned) l) {
03512 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (binary beyond end)");
03513 return -1;
03514 }
03515 GWEN_Buffer_IncrementPos(msgbuf, l);
03516 }
03517 else if (c==delimiter) {
03518 return 0;
03519 break;
03520 }
03521 }
03522 }
03523
03524 DBG_ERROR(GWEN_LOGDOMAIN, "End of segment not found");
03525 return -1;
03526 }
03527
03528
03529
03530
03531 int GWEN_MsgEngine_ReadMessage(GWEN_MSGENGINE *e,
03532 const char *gtype,
03533 GWEN_BUFFER *mbuf,
03534 GWEN_DB_NODE *gr,
03535 uint32_t flags) {
03536 unsigned int segments;
03537
03538 segments=0;
03539
03540 while(GWEN_Buffer_GetBytesLeft(mbuf)) {
03541 GWEN_XMLNODE *node;
03542 unsigned int posBak;
03543 const char *p;
03544 GWEN_DB_NODE *tmpdb;
03545 int segVer;
03546
03547
03548 tmpdb=GWEN_DB_Group_new("tmpdb");
03549 node=GWEN_MsgEngine_FindGroupByProperty(e,
03550 "id",
03551 0,
03552 "SegHead");
03553 if (node==0) {
03554 DBG_ERROR(GWEN_LOGDOMAIN, "Segment description not found");
03555 GWEN_DB_Group_free(tmpdb);
03556 return -1;
03557 }
03558
03559
03560 posBak=GWEN_Buffer_GetPos(mbuf);
03561 if (GWEN_MsgEngine_ParseMessage(e,
03562 node,
03563 mbuf,
03564 tmpdb,
03565 flags)) {
03566 DBG_ERROR(GWEN_LOGDOMAIN, "Error parsing segment head");
03567 GWEN_DB_Group_free(tmpdb);
03568 return -1;
03569 }
03570
03571
03572 segVer=GWEN_DB_GetIntValue(tmpdb,
03573 "version",
03574 0,
03575 0);
03576 p=GWEN_DB_GetCharValue(tmpdb,
03577 "code",
03578 0,
03579 0);
03580 if (!p) {
03581 DBG_ERROR(GWEN_LOGDOMAIN, "No segment code for %s ? This seems to be a bad msg...",
03582 gtype);
03583 GWEN_Buffer_SetPos(mbuf, posBak);
03584 DBG_ERROR(GWEN_LOGDOMAIN, "Full message (pos=%04x)", posBak);
03585 GWEN_Text_DumpString(GWEN_Buffer_GetStart(mbuf),
03586 GWEN_Buffer_GetUsedBytes(mbuf),
03587 1);
03588 GWEN_DB_Dump(tmpdb, 1);
03589 GWEN_DB_Group_free(tmpdb);
03590 return -1;
03591 }
03592
03593
03594 node=GWEN_MsgEngine_FindNodeByProperty(e,
03595 gtype,
03596 "code",
03597 segVer,
03598 p);
03599 if (node==0) {
03600 unsigned int ustart;
03601
03602 ustart=GWEN_Buffer_GetPos(mbuf);
03603 ustart++;
03604
03605
03606 DBG_NOTICE(GWEN_LOGDOMAIN,
03607 "Unknown segment \"%s\" (Segnum=%d, version=%d, ref=%d)",
03608 p,
03609 GWEN_DB_GetIntValue(tmpdb, "seq", 0, -1),
03610 GWEN_DB_GetIntValue(tmpdb, "version", 0, -1),
03611 GWEN_DB_GetIntValue(tmpdb, "ref", 0, -1));
03612 if (GWEN_MsgEngine_SkipSegment(e, mbuf, '?', '\'')) {
03613 DBG_ERROR(GWEN_LOGDOMAIN, "Error skipping segment \"%s\"", p);
03614 GWEN_DB_Group_free(tmpdb);
03615 return -1;
03616 }
03617 if (flags & GWEN_MSGENGINE_READ_FLAGS_TRUSTINFO) {
03618 unsigned int usize;
03619
03620 usize=GWEN_Buffer_GetPos(mbuf)-ustart-1;
03621 #if 0
03622 GWEN_Text_DumpString(GWEN_Buffer_GetStart(mbuf)+ustart,
03623 usize,
03624 stderr, 1);
03625 #endif
03626 if (GWEN_MsgEngine_AddTrustInfo(e,
03627 GWEN_Buffer_GetStart(mbuf)+ustart,
03628 usize,
03629 p,
03630 GWEN_MsgEngineTrustLevelHigh,
03631 ustart)) {
03632 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
03633 GWEN_DB_Group_free(tmpdb);
03634 return -1;
03635 }
03636 }
03637 }
03638 else {
03639
03640
03641 const char *id;
03642 GWEN_DB_NODE *storegrp;
03643 unsigned int startPos;
03644
03645
03646
03647 GWEN_Buffer_SetPos(mbuf, posBak);
03648
03649
03650 id=GWEN_XMLNode_GetProperty(node, "id", p);
03651 storegrp=GWEN_DB_GetGroup(gr,
03652 GWEN_PATH_FLAGS_CREATE_GROUP,
03653 id);
03654 assert(storegrp);
03655
03656
03657 startPos=GWEN_Buffer_GetPos(mbuf);
03658 GWEN_DB_SetIntValue(storegrp,
03659 GWEN_DB_FLAGS_OVERWRITE_VARS,
03660 "segment/pos",
03661 startPos);
03662
03663
03664 if (GWEN_MsgEngine_ParseMessage(e,
03665 node,
03666 mbuf,
03667 storegrp,
03668 flags)) {
03669 DBG_ERROR(GWEN_LOGDOMAIN, "Error parsing segment \"%s\" at %d (%x)",
03670 p,
03671 GWEN_Buffer_GetPos(mbuf)-startPos,
03672 GWEN_Buffer_GetPos(mbuf)-startPos);
03673 GWEN_Text_DumpString(GWEN_Buffer_GetStart(mbuf)+startPos,
03674 GWEN_Buffer_GetUsedBytes(mbuf)-startPos,
03675 1);
03676 DBG_ERROR(GWEN_LOGDOMAIN, "Stored data so far:");
03677 GWEN_DB_Dump(storegrp, 2);
03678 GWEN_DB_Group_free(tmpdb);
03679 return -1;
03680 }
03681
03682
03683 GWEN_DB_SetIntValue(storegrp,
03684 GWEN_DB_FLAGS_OVERWRITE_VARS,
03685 "segment/length",
03686 GWEN_Buffer_GetPos(mbuf)-startPos);
03687 segments++;
03688 }
03689 GWEN_DB_Group_free(tmpdb);
03690 }
03691
03692
03693 if (segments) {
03694 DBG_DEBUG(GWEN_LOGDOMAIN, "Parsed %d segments", segments);
03695 return 0;
03696 }
03697 else {
03698 DBG_INFO(GWEN_LOGDOMAIN, "No segments parsed.");
03699 return 1;
03700 }
03701 }
03702
03703
03704
03705
03706
03707
03708
03709
03710 GWEN_MSGENGINE_TRUSTEDDATA*
03711 GWEN_MsgEngine_TrustedData_new(const char *data,
03712 unsigned int size,
03713 const char *description,
03714 GWEN_MSGENGINE_TRUSTLEVEL trustLevel){
03715 GWEN_MSGENGINE_TRUSTEDDATA *td;
03716
03717 assert(data);
03718 assert(size);
03719 GWEN_NEW_OBJECT(GWEN_MSGENGINE_TRUSTEDDATA, td);
03720 td->data=(char*)malloc(size);
03721 assert(td->data);
03722 memmove(td->data, data, size);
03723 if (description)
03724 td->description=strdup(description);
03725 td->trustLevel=trustLevel;
03726 td->size=size;
03727 return td;
03728 }
03729
03730
03731
03732 void GWEN_MsgEngine_TrustedData_free(GWEN_MSGENGINE_TRUSTEDDATA *td){
03733 if (td) {
03734 free(td->data);
03735 free(td->description);
03736 free(td->replacement);
03737 GWEN_FREE_OBJECT(td);
03738 }
03739 }
03740
03741
03742
03743 GWEN_MSGENGINE_TRUSTEDDATA*
03744 GWEN_MsgEngine_TrustedData_GetNext(GWEN_MSGENGINE_TRUSTEDDATA *td){
03745 assert(td);
03746 return td->next;
03747 }
03748
03749
03750
03751 const char*
03752 GWEN_MsgEngine_TrustedData_GetData(GWEN_MSGENGINE_TRUSTEDDATA *td){
03753 assert(td);
03754 return td->data;
03755 }
03756
03757
03758
03759 unsigned int
03760 GWEN_MsgEngine_TrustedData_GetSize(GWEN_MSGENGINE_TRUSTEDDATA *td){
03761 assert(td);
03762 return td->size;
03763 }
03764
03765
03766
03767 const char*
03768 GWEN_MsgEngine_TrustedData_GetDescription(GWEN_MSGENGINE_TRUSTEDDATA *td){
03769 assert(td);
03770 return td->description;
03771 }
03772
03773
03774
03775 GWEN_MSGENGINE_TRUSTLEVEL
03776 GWEN_MsgEngine_TrustedData_GetTrustLevel(GWEN_MSGENGINE_TRUSTEDDATA *td){
03777 assert(td);
03778 return td->trustLevel;
03779 }
03780
03781
03782
03783 const char*
03784 GWEN_MsgEngine_TrustedData_GetReplacement(GWEN_MSGENGINE_TRUSTEDDATA *td){
03785 assert(td);
03786 return td->replacement;
03787 }
03788
03789
03790
03791 int GWEN_MsgEngine_TrustedData_AddPos(GWEN_MSGENGINE_TRUSTEDDATA *td,
03792 unsigned int pos){
03793 assert(td);
03794 if (td->posCount>=GWEN_MSGENGINE_TRUSTEDDATA_MAXPOS)
03795 return -1;
03796 td->positions[td->posCount++]=pos;
03797 return 0;
03798 }
03799
03800
03801
03802 int GWEN_MsgEngine_TrustedData_GetFirstPos(GWEN_MSGENGINE_TRUSTEDDATA *td){
03803 assert(td);
03804 td->posPointer=0;
03805 return GWEN_MsgEngine_TrustedData_GetNextPos(td);
03806 }
03807
03808
03809
03810 int GWEN_MsgEngine_TrustedData_GetNextPos(GWEN_MSGENGINE_TRUSTEDDATA *td){
03811 assert(td);
03812 if (td->posPointer>=td->posCount)
03813 return -1;
03814 return td->positions[td->posPointer++];
03815 }
03816
03817
03818
03819 int
03820 GWEN_MsgEngine_TrustedData_CreateReplacements(GWEN_MSGENGINE_TRUSTEDDATA
03821 *td){
03822 unsigned int nextNr;
03823 GWEN_MSGENGINE_TRUSTEDDATA *ntd;
03824 unsigned int count;
03825
03826 assert(td);
03827 count=0;
03828 ntd=td;
03829 while(ntd) {
03830 count++;
03831 ntd=ntd->next;
03832 }
03833
03834 if (count<0x10)
03835 nextNr=0x01;
03836 else
03837 nextNr=0x11;
03838
03839 ntd=td;
03840 while(ntd) {
03841 unsigned int i;
03842 char numbuffer[32];
03843 char *rp;
03844 GWEN_MSGENGINE_TRUSTEDDATA *std;
03845 int match;
03846
03847
03848 std=td;
03849 match=0;
03850 while(std && std!=ntd) {
03851
03852 match=1;
03853 if (std->size==ntd->size) {
03854 for (i=0; i<td->size; i++) {
03855 if (std->data[i]!=ntd->data[i]) {
03856 match=0;
03857 break;
03858 }
03859 }
03860 }
03861 else
03862 match=0;
03863
03864 if (match)
03865 break;
03866 std=std->next;
03867 }
03868
03869 if (match) {
03870
03871 rp=strdup(std->replacement);
03872 }
03873 else {
03874
03875 rp=(char*)malloc(ntd->size+1);
03876 assert(rp);
03877
03878 if (ntd->size==1) {
03879 if (count>=0x10)
03880 nextNr+=0x10;
03881 }
03882 sprintf(numbuffer, "%02X", nextNr++);
03883 for (i=0; i<ntd->size; i++) {
03884 if (count<0x10)
03885 rp[i]=numbuffer[1];
03886 else
03887 rp[i]=numbuffer[1-(i&1)];
03888 }
03889 rp[i]=0;
03890 }
03891
03892
03893
03894
03895
03896 free(ntd->replacement);
03897 ntd->replacement=rp;
03898
03899 ntd=ntd->next;
03900 }
03901 return 0;
03902 }
03903
03904
03905
03906 GWEN_MSGENGINE_TRUSTEDDATA *GWEN_MsgEngine_TakeTrustInfo(GWEN_MSGENGINE *e){
03907 GWEN_MSGENGINE_TRUSTEDDATA *td;
03908
03909 assert(e);
03910 td=e->trustInfos;
03911 e->trustInfos=0;
03912 return td;
03913 }
03914
03915
03916
03917
03918 int GWEN_MsgEngine_AddTrustInfo(GWEN_MSGENGINE *e,
03919 const char *data,
03920 unsigned int size,
03921 const char *description,
03922 GWEN_MSGENGINE_TRUSTLEVEL trustLevel,
03923 unsigned int pos) {
03924 GWEN_MSGENGINE_TRUSTEDDATA *td;
03925 int match;
03926
03927 assert(e);
03928 assert(data);
03929 assert(size);
03930
03931 if (!description)
03932 description="";
03933
03934 td=e->trustInfos;
03935 while(td) {
03936 unsigned int i;
03937
03938
03939 if (td->size==size &&
03940 *description &&
03941 *(td->description) &&
03942 trustLevel==td->trustLevel &&
03943 strcasecmp(description, td->description)==0) {
03944 match=1;
03945 for (i=0; i<td->size; i++) {
03946 if (td->data[i]!=data[i]) {
03947 match=0;
03948 break;
03949 }
03950 }
03951 }
03952 else
03953 match=0;
03954
03955 if (match)
03956 break;
03957 td=td->next;
03958 }
03959
03960 if (!td) {
03961 DBG_INFO(GWEN_LOGDOMAIN, "Creating new trustInfo for \"%s\" (%d)",
03962 description, size);
03963 td=GWEN_MsgEngine_TrustedData_new(data,
03964 size,
03965 description,
03966 trustLevel);
03967 GWEN_LIST_ADD(GWEN_MSGENGINE_TRUSTEDDATA, td, &(e->trustInfos));
03968 }
03969 else {
03970 DBG_INFO(GWEN_LOGDOMAIN, "Reusing trustInfo for \"%s\" (%d)",
03971 description, size);
03972 }
03973 GWEN_MsgEngine_TrustedData_AddPos(td, pos);
03974 return 0;
03975 }
03976
03977
03978