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