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 GWEN_XMLNODE *GWEN_MsgEngine_FindNodeByPropertyStrictProto(GWEN_MSGENGINE *e,
01013 const char *t,
01014 const char *pname,
01015 int version,
01016 const char *pvalue) {
01017 GWEN_XMLNODE *n;
01018 const char *p;
01019 int i;
01020 const char *mode;
01021 unsigned int proto;
01022 char buffer[256];
01023
01024 if ((strlen(t)+4)>sizeof(buffer)) {
01025 DBG_ERROR(GWEN_LOGDOMAIN, "Type name too long.");
01026 return 0;
01027 }
01028
01029 mode=GWEN_MsgEngine_GetMode(e);
01030 proto=GWEN_MsgEngine_GetProtocolVersion(e);
01031 if (!e->defs) {
01032 DBG_INFO(GWEN_LOGDOMAIN, "No definitions available");
01033 return 0;
01034 }
01035 n=e->defs;
01036 n=GWEN_XMLNode_GetChild(n);
01037
01038
01039 strcpy(buffer, t);
01040 strcat(buffer,"S");
01041 while(n) {
01042 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
01043 p=GWEN_XMLNode_GetData(n);
01044 assert(p);
01045 if (strcasecmp(p, buffer)==0)
01046 break;
01047 }
01048 n=GWEN_XMLNode_Next(n);
01049 }
01050
01051 if (!n) {
01052 DBG_INFO(GWEN_LOGDOMAIN, "No definitions available for type \"%s\"", t);
01053 return 0;
01054 }
01055
01056
01057 if (!mode)
01058 mode="";
01059 n=GWEN_XMLNode_GetChild(n);
01060 if (!n) {
01061 DBG_INFO(GWEN_LOGDOMAIN, "No definitions inside \"%s\"", buffer);
01062 return 0;
01063 }
01064
01065
01066 strcpy(buffer, t);
01067 strcat(buffer,"def");
01068 while(n) {
01069 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
01070 p=GWEN_XMLNode_GetData(n);
01071 assert(p);
01072 if (strcasecmp(p, buffer)==0) {
01073 p=GWEN_XMLNode_GetProperty(n, pname,"");
01074 if (strcasecmp(p, pvalue)==0) {
01075 i=atoi(GWEN_XMLNode_GetProperty(n, "pversion" ,"0"));
01076 if (proto==0 || (int)proto==i) {
01077 i=atoi(GWEN_XMLNode_GetProperty(n, "version" ,"0"));
01078 if (version==0 || version==i) {
01079 p=GWEN_XMLNode_GetProperty(n, "mode","");
01080 if (strcasecmp(p, mode)==0 || !*p) {
01081 DBG_DEBUG(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\" found",
01082 pname, pvalue);
01083 return n;
01084 }
01085 }
01086 }
01087 }
01088 }
01089 }
01090 n=GWEN_XMLNode_Next(n);
01091 }
01092
01093 DBG_INFO(GWEN_LOGDOMAIN, "Group definition for \"%s=%s\"(%d) not found",
01094 pname,
01095 pvalue,
01096 version);
01097 return 0;
01098 }
01099
01100
01101
01102 const char *GWEN_MsgEngine__TransformValue(GWEN_MSGENGINE *e,
01103 const char *pvalue,
01104 GWEN_XMLNODE *node,
01105 GWEN_XMLNODE *dnode,
01106 unsigned int *datasize) {
01107 const char *p;
01108 static char pbuffer[256];
01109 GWEN_DB_NODE *globalValues;
01110
01111 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
01112 assert(globalValues);
01113
01114 if (pvalue) {
01115 DBG_DEBUG(GWEN_LOGDOMAIN, "Transforming value \"%s\"", pvalue);
01116
01117 p=pvalue;
01118 while (*p && isspace((int)*p))
01119 p++;
01120 if (*p=='$' || *p=='+') {
01121
01122 int incr;
01123
01124 incr=(*p=='+');
01125 p++;
01126
01127 DBG_DEBUG(GWEN_LOGDOMAIN, "Getting global property \"%s\"", p);
01128 if (incr) {
01129 int z;
01130
01131 z=GWEN_DB_GetIntValue(globalValues, p, 0, 0);
01132 DBG_DEBUG(GWEN_LOGDOMAIN, "Incrementing global property \"%s\" (%d)",
01133 p, z);
01134 if (GWEN_Text_NumToString(z, pbuffer, sizeof(pbuffer),0)<1) {
01135 DBG_ERROR(GWEN_LOGDOMAIN, "Error converting num to string");
01136 return 0;
01137 }
01138
01139 z++;
01140 DBG_DEBUG(GWEN_LOGDOMAIN, "Setting global property \"%s\"=%d", p, z);
01141 GWEN_DB_SetIntValue(globalValues,
01142 GWEN_DB_FLAGS_DEFAULT |
01143 GWEN_DB_FLAGS_OVERWRITE_VARS,
01144 p, z);
01145 pvalue=pbuffer;
01146 *datasize=strlen(pvalue);
01147 }
01148 else {
01149 int z;
01150 GWEN_DB_NODE_TYPE vt;
01151 const char *type = "should_be_known";
01152
01153
01154 DBG_DEBUG(GWEN_LOGDOMAIN, "Getting global property \"%s\"", p);
01155 vt=GWEN_DB_GetVariableType(globalValues, p);
01156 if (vt==GWEN_DB_NodeType_Unknown) {
01157 if (!GWEN_DB_VariableExists(globalValues, p)) {
01158 DBG_ERROR(GWEN_LOGDOMAIN, "Unable to determine type of \"%s\"", p);
01159 return 0;
01160 }
01161 type=GWEN_XMLNode_GetProperty(dnode, "type", "ascii");
01162 if (GWEN_MsgEngine__IsCharTyp(e, type))
01163 vt=GWEN_DB_NodeType_ValueChar;
01164 else if (GWEN_MsgEngine__IsIntTyp(e, type))
01165 vt=GWEN_DB_NodeType_ValueInt;
01166 else if (GWEN_MsgEngine__IsBinTyp(e, type))
01167 vt=GWEN_DB_NodeType_ValueBin;
01168 else {
01169 DBG_ERROR(GWEN_LOGDOMAIN,
01170 "Unable to determine type of \"%s\" (xml)", p);
01171 return 0;
01172 }
01173 }
01174
01175 switch(vt) {
01176 case GWEN_DB_NodeType_ValueChar:
01177 pvalue=GWEN_DB_GetCharValue(globalValues, p, 0, "");
01178 *datasize=strlen(pvalue);
01179 break;
01180
01181 case GWEN_DB_NodeType_ValueInt:
01182 z=GWEN_DB_GetIntValue(globalValues, p, 0, 0);
01183 if (GWEN_Text_NumToString(z, pbuffer, sizeof(pbuffer),0)<1) {
01184 DBG_ERROR(GWEN_LOGDOMAIN, "Error converting num to string");
01185 return 0;
01186 }
01187 pvalue=pbuffer;
01188 *datasize=strlen(pvalue);
01189 break;
01190
01191 case GWEN_DB_NodeType_ValueBin:
01192 pvalue=GWEN_DB_GetBinValue(globalValues, p, 0,
01193 0,0,
01194 datasize);
01195 break;
01196
01197 default:
01198 DBG_ERROR(GWEN_LOGDOMAIN,"Unknown type %s", type);
01199 return 0;
01200 }
01201 }
01202 DBG_DEBUG(GWEN_LOGDOMAIN, "Value transformed");
01203 }
01204 else if (*p=='%') {
01205
01206 p++;
01207
01208 DBG_DEBUG(GWEN_LOGDOMAIN, "Getting property \"%s\"", p);
01209 pvalue=GWEN_XMLNode_GetProperty(node, p, 0);
01210 if (pvalue) {
01211 *datasize=strlen(pvalue);
01212 DBG_DEBUG(GWEN_LOGDOMAIN, "Transformed value \"%s\"", pvalue);
01213 }
01214 else
01215 *datasize=0;
01216 }
01217 else if (*p=='?') {
01218 GWEN_DB_NODE_TYPE vt;
01219 int z;
01220 const char *dtype;
01221
01222
01223 dtype=GWEN_XMLNode_GetProperty(dnode, "type","ASCII");
01224
01225
01226 p++;
01227 DBG_DEBUG(GWEN_LOGDOMAIN, "Getting program variable \"%s\"", p);
01228
01229 pvalue=0;
01230 if (GWEN_MsgEngine__IsCharTyp(e, dtype))
01231 vt=GWEN_DB_NodeType_ValueChar;
01232 else if (GWEN_MsgEngine__IsIntTyp(e, dtype))
01233 vt=GWEN_DB_NodeType_ValueInt;
01234 else {
01235 vt=GWEN_DB_NodeType_ValueChar;
01236 }
01237
01238 switch(vt) {
01239 case GWEN_DB_NodeType_ValueChar:
01240 if (e->getCharValuePtr) {
01241 pvalue=e->getCharValuePtr(e, p, 0);
01242 if (pvalue)
01243 *datasize=strlen(pvalue);
01244 }
01245 break;
01246
01247 case GWEN_DB_NodeType_ValueInt:
01248 if (e->getIntValuePtr) {
01249 z=e->getIntValuePtr(e, p, 0);
01250 if (GWEN_Text_NumToString(z, pbuffer, sizeof(pbuffer),0)<1) {
01251 DBG_ERROR(GWEN_LOGDOMAIN, "Error converting num to string");
01252 return 0;
01253 }
01254 pvalue=pbuffer;
01255 *datasize=strlen(pvalue);
01256 }
01257 else {
01258 DBG_NOTICE(GWEN_LOGDOMAIN, "Callback for getIntValue not set");
01259 }
01260 break;
01261
01262 default:
01263 DBG_ERROR(GWEN_LOGDOMAIN,"Unhandled type %s", dtype);
01264 return 0;
01265 }
01266
01267 DBG_DEBUG(GWEN_LOGDOMAIN, "Value transformed");
01268 }
01269 else {
01270 *datasize=strlen(pvalue);
01271 }
01272 }
01273 return pvalue;
01274 }
01275
01276
01277
01278 const char *GWEN_MsgEngine_SearchForProperty(GWEN_XMLNODE *node,
01279 GWEN_XMLNODE *refnode,
01280 const char *name,
01281 int topDown) {
01282 const char *pvalue;
01283 GWEN_XMLNODE *pn;
01284 const char *lastValue;
01285
01286 DBG_DEBUG(GWEN_LOGDOMAIN, "Searching for value of \"%s\" in properties", name);
01287 lastValue=0;
01288
01289 pvalue=GWEN_XMLNode_GetProperty(node, name,0);
01290 if (pvalue) {
01291 if (!topDown)
01292 return pvalue;
01293 DBG_DEBUG(GWEN_LOGDOMAIN, "Found a value (%s), but will look further", pvalue);
01294 lastValue=pvalue;
01295 }
01296
01297 pn=refnode;
01298 while(pn) {
01299 pvalue=GWEN_XMLNode_GetProperty(pn, name,0);
01300 if (pvalue) {
01301 if (!topDown)
01302 return pvalue;
01303 DBG_DEBUG(GWEN_LOGDOMAIN, "Found a value (%s), but will look further", pvalue);
01304 lastValue=pvalue;
01305 }
01306 pn=GWEN_XMLNode_GetParent(pn);
01307 }
01308 return lastValue;
01309 }
01310
01311
01312
01313 int GWEN_MsgEngine_GetHighestTrustLevel(GWEN_XMLNODE *node,
01314 GWEN_XMLNODE *refnode) {
01315 int value;
01316 GWEN_XMLNODE *pn;
01317 int highestTrust;
01318
01319 highestTrust=0;
01320
01321 value=atoi(GWEN_XMLNode_GetProperty(node, "trustlevel","0"));
01322 if (value>highestTrust)
01323 highestTrust=value;
01324
01325 pn=node;
01326 while(pn) {
01327 value=atoi(GWEN_XMLNode_GetProperty(pn, "trustlevel","0"));
01328 if (value>highestTrust)
01329 highestTrust=value;
01330 pn=GWEN_XMLNode_GetParent(pn);
01331 }
01332
01333 pn=refnode;
01334 while(pn) {
01335 value=atoi(GWEN_XMLNode_GetProperty(pn, "trustlevel","0"));
01336 if (value>highestTrust)
01337 highestTrust=value;
01338 pn=GWEN_XMLNode_GetParent(pn);
01339 }
01340 return highestTrust;
01341 }
01342
01343
01344
01345 const char *GWEN_MsgEngine__SearchForValue(GWEN_MSGENGINE *e,
01346 GWEN_XMLNODE *node,
01347 GWEN_XMLNODE_PATH *nodePath,
01348 const char *name,
01349 unsigned int *datasize) {
01350 const char *pvalue;
01351 GWEN_XMLNODE *pn;
01352 char *bufferPtr;
01353 int topDown;
01354 const char *lastValue;
01355 unsigned int lastDataSize;
01356 unsigned int ldatasize;
01357
01358 DBG_DEBUG(GWEN_LOGDOMAIN, "Searching for value of \"%s\" in <VALUES>",
01359 name);
01360 if (!node) {
01361 DBG_WARN(GWEN_LOGDOMAIN, "No node !");
01362 }
01363 topDown=atoi(GWEN_XMLNode_GetProperty(node, "topdown", "0"));
01364 lastValue=0;
01365 lastDataSize=0;
01366
01367 bufferPtr=0;
01368
01369
01370 pn=GWEN_XMLNode_Path_Surface(nodePath);
01371 while(pn) {
01372 const char *ppath;
01373
01374
01375
01376
01377
01378 pvalue=GWEN_MsgEngine__findInValues(e, pn, node, name, &ldatasize);
01379 if (pvalue) {
01380 if (!topDown) {
01381 free(bufferPtr);
01382 *datasize=ldatasize;
01383 return pvalue;
01384 }
01385 DBG_DEBUG(GWEN_LOGDOMAIN, "Found a value, but will look further");
01386 lastValue=pvalue;
01387 lastDataSize=ldatasize;
01388 }
01389
01390 ppath=GWEN_XMLNode_GetProperty(pn, "name", "");
01391
01392 if (*ppath) {
01393 int i;
01394 char *tmpptr;
01395
01396 if (bufferPtr) {
01397 i=strlen(bufferPtr)+strlen(ppath)+2;
01398 tmpptr=(char*)malloc(i);
01399 assert(tmpptr);
01400 sprintf(tmpptr, "%s/%s", ppath, bufferPtr);
01401 free(bufferPtr);
01402 bufferPtr=tmpptr;
01403 }
01404 else {
01405 i=strlen(ppath)+strlen(name)+2;
01406 tmpptr=(char*)malloc(i);
01407 assert(tmpptr);
01408 sprintf(tmpptr, "%s/%s", ppath, name);
01409 bufferPtr=tmpptr;
01410 }
01411 name=bufferPtr;
01412 }
01413 pn=GWEN_XMLNode_Path_Surface(nodePath);
01414 }
01415
01416 free(bufferPtr);
01417 if (!lastValue)
01418 *datasize=0;
01419 else
01420 *datasize=lastDataSize;
01421 return lastValue;
01422 }
01423
01424
01425
01426 const char *GWEN_MsgEngine__findInValues(GWEN_MSGENGINE *e,
01427 GWEN_XMLNODE *node,
01428 GWEN_XMLNODE *dnode,
01429 const char *name,
01430 unsigned int *datasize) {
01431 GWEN_XMLNODE *pn;
01432
01433 DBG_VERBOUS(GWEN_LOGDOMAIN, "Looking for value of \"%s\" in <VALUES>", name);
01434 pn=GWEN_XMLNode_GetChild(node);
01435
01436 while(pn) {
01437 if (GWEN_XMLNode_GetType(pn)==GWEN_XMLNodeTypeTag) {
01438 GWEN_XMLNODE *n;
01439 const char *p;
01440
01441 p=GWEN_XMLNode_GetData(pn);
01442 assert(p);
01443 DBG_DEBUG(GWEN_LOGDOMAIN, "Checking %s", p);
01444 if (strcasecmp(p, "VALUES")==0) {
01445 DBG_DEBUG(GWEN_LOGDOMAIN, "<values> found");
01446
01447 n=GWEN_XMLNode_GetChild(pn);
01448 while(n) {
01449 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
01450 const char *p;
01451
01452 p=GWEN_XMLNode_GetData(n);
01453 assert(p);
01454 if (strcasecmp(p, "VALUE")==0) {
01455 const char *pname;
01456 const char *pvalue;
01457
01458 pname=GWEN_XMLNode_GetProperty(n, "path", 0);
01459 if (pname) {
01460 DBG_DEBUG(GWEN_LOGDOMAIN, "Comparing against \"%s\"", pname);
01461 if (strcasecmp(name, pname)==0) {
01462 GWEN_XMLNODE *dn;
01463
01464 dn=GWEN_XMLNode_GetChild(n);
01465 while (dn) {
01466 if (GWEN_XMLNode_GetType(dn)==GWEN_XMLNodeTypeData) {
01467 pvalue=GWEN_XMLNode_GetData(dn);
01468 if (pvalue) {
01469 DBG_DEBUG(GWEN_LOGDOMAIN, "Transforming \"%s\"", pvalue);
01470 pvalue=GWEN_MsgEngine__TransformValue(e,
01471 pvalue,
01472 node,
01473 dnode,
01474 datasize);
01475 }
01476 if (pvalue)
01477 return pvalue;
01478 }
01479 dn=GWEN_XMLNode_Next(dn);
01480 }
01481 }
01482 }
01483 }
01484 }
01485 n=GWEN_XMLNode_Next(n);
01486 }
01487 break;
01488 }
01489 }
01490 pn=GWEN_XMLNode_Next(pn);
01491 }
01492
01493 DBG_DEBUG(GWEN_LOGDOMAIN, "No value found for \"%s\" in <VALUES>", name);
01494 return 0;
01495 }
01496
01497
01498
01499 GWEN_XMLNODE *GWEN_MsgEngine__GetGroup(GWEN_MSGENGINE *e,
01500 GWEN_XMLNODE *node,
01501 const char *t,
01502 int version,
01503 const char *pvalue) {
01504 GWEN_XMLNODE *n;
01505 const char *p;
01506 int i;
01507 const char *mode;
01508 unsigned int proto;
01509 char buffer[256];
01510
01511 if ((strlen(t)+4)>sizeof(buffer)) {
01512 DBG_ERROR(GWEN_LOGDOMAIN, "Type name too long.");
01513 return 0;
01514 }
01515
01516 mode=GWEN_MsgEngine_GetMode(e);
01517 proto=GWEN_MsgEngine_GetProtocolVersion(e);
01518
01519
01520 strcpy(buffer, t);
01521 strcat(buffer,"S");
01522 n=GWEN_XMLNode_FindFirstTag(node, buffer, 0, 0);
01523 if (!n) {
01524 DBG_DEBUG(GWEN_LOGDOMAIN,
01525 "No definitions here for type \"%s\"", t);
01526 return 0;
01527 }
01528
01529
01530 if (!mode)
01531 mode="";
01532 n=GWEN_XMLNode_GetFirstTag(n);
01533 if (!n) {
01534 DBG_INFO(GWEN_LOGDOMAIN, "No definitions inside \"%s\"", buffer);
01535 return 0;
01536 }
01537
01538
01539 strcpy(buffer, t);
01540 strcat(buffer, "def");
01541 while(n) {
01542 p=GWEN_XMLNode_GetData(n);
01543 assert(p);
01544 if (strcasecmp(p, buffer)==0 ||
01545 strcasecmp(p, t)==0) {
01546 p=GWEN_XMLNode_GetProperty(n, "id", "");
01547 if (strcasecmp(p, pvalue)!=0)
01548 p=GWEN_XMLNode_GetProperty(n, "name", "");
01549 if (strcasecmp(p, pvalue)==0) {
01550 i=atoi(GWEN_XMLNode_GetProperty(n, "pversion" ,"0"));
01551 if (proto==0 || (int)proto==i || i==0) {
01552 i=atoi(GWEN_XMLNode_GetProperty(n, "version" ,"0"));
01553 if (version==0 || version==i) {
01554 p=GWEN_XMLNode_GetProperty(n, "mode","");
01555 if (strcasecmp(p, mode)==0 || !*p) {
01556 DBG_DEBUG(GWEN_LOGDOMAIN,
01557 "Group definition for \"%s=%s\" found",
01558 t, pvalue);
01559 return n;
01560 }
01561 }
01562 }
01563 }
01564 }
01565 n=GWEN_XMLNode_GetNextTag(n);
01566 }
01567
01568 DBG_DEBUG(GWEN_LOGDOMAIN,
01569 "Group definition for \"%s=%s\"(%d) not found here",
01570 t,
01571 pvalue,
01572 version);
01573 return 0;
01574 }
01575
01576
01577
01578 GWEN_XMLNODE *GWEN_MsgEngine_GetGroup(GWEN_MSGENGINE *e,
01579 GWEN_XMLNODE *node,
01580 const GWEN_XMLNODE_PATH *nodePath,
01581 const char *t,
01582 int version,
01583 const char *pvalue) {
01584 GWEN_XMLNODE *n;
01585 GWEN_XMLNODE *nLast = 0;
01586 GWEN_XMLNODE *nRes = 0;
01587 GWEN_XMLNODE_PATH *pathCopy;
01588
01589 assert(node);
01590 assert(nodePath);
01591 assert(t);
01592 assert(pvalue);
01593
01594 pathCopy=GWEN_XMLNode_Path_dup(nodePath);
01595 n=GWEN_XMLNode_Path_Surface(pathCopy);
01596
01597 while(n) {
01598 nLast=n;
01599 nRes=GWEN_MsgEngine__GetGroup(e, n, t, version, pvalue);
01600 if (nRes)
01601 break;
01602 n=GWEN_XMLNode_Path_Surface(pathCopy);
01603 }
01604 GWEN_XMLNode_Path_free(pathCopy);
01605 if (nRes) {
01606
01607 if (nRes==node) {
01608 DBG_ERROR(GWEN_LOGDOMAIN, "Loop detected.");
01609 return 0;
01610 }
01611 return nRes;
01612 }
01613
01614 if (nLast)
01615 n=nLast;
01616 else
01617 n=node;
01618
01619 if (n) {
01620 n=GWEN_XMLNode_GetParent(n);
01621 while(n) {
01622 nRes=GWEN_MsgEngine__GetGroup(e, n, t, version, pvalue);
01623 if (nRes)
01624 break;
01625 n=GWEN_XMLNode_GetParent(n);
01626 }
01627 }
01628
01629
01630 if (!nRes && e->defs)
01631 nRes=GWEN_MsgEngine__GetGroup(e, e->defs, t, version, pvalue);
01632
01633 if (!nRes) {
01634 DBG_DEBUG(GWEN_LOGDOMAIN,
01635 "Group definition for \"%s=%s\"(%d) not found",
01636 t,
01637 pvalue,
01638 version);
01639 return 0;
01640 }
01641 if (nRes==node) {
01642 DBG_ERROR(GWEN_LOGDOMAIN, "Loop detected.");
01643 return 0;
01644 }
01645 return nRes;
01646 }
01647
01648
01649
01650 int GWEN_MsgEngine__WriteGroup(GWEN_MSGENGINE *e,
01651 GWEN_BUFFER *gbuf,
01652 GWEN_XMLNODE *node,
01653 GWEN_XMLNODE *rnode,
01654 GWEN_DB_NODE *gr,
01655 int groupIsOptional,
01656 GWEN_XMLNODE_PATH *nodePath) {
01657 GWEN_XMLNODE *n;
01658 const char *p;
01659 char delimiter;
01660 char terminator;
01661 int isFirstElement;
01662 int omittedElements;
01663 int hasEntries;
01664
01665
01666
01667 if (rnode) {
01668
01669 p=GWEN_XMLNode_GetProperty(rnode,
01670 "delimiter",
01671 GWEN_XMLNode_GetProperty(node,
01672 "delimiter",
01673 ""));
01674 delimiter=*p;
01675
01676
01677 p=GWEN_XMLNode_GetProperty(rnode,
01678 "terminator",
01679 GWEN_XMLNode_GetProperty(node,
01680 "terminator",
01681 ""));
01682 terminator=*p;
01683 }
01684 else {
01685
01686 p=GWEN_XMLNode_GetProperty(node,
01687 "delimiter",
01688 "");
01689 delimiter=*p;
01690
01691
01692 p=GWEN_XMLNode_GetProperty(node, "terminator","");
01693 terminator=*p;
01694 }
01695
01696
01697 n=GWEN_XMLNode_GetChild(node);
01698 isFirstElement=1;
01699 omittedElements=0;
01700 hasEntries=0;
01701 if (!n) {
01702 DBG_INFO(GWEN_LOGDOMAIN, "No subnodes !");
01703 }
01704 while(n) {
01705 int t;
01706 unsigned int minnum;
01707 unsigned int maxnum;
01708 int gversion;
01709 const char *addEmptyMode;
01710 unsigned int loopNr;
01711
01712 minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum","1"));
01713 maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum","1"));
01714 gversion=atoi(GWEN_XMLNode_GetProperty(n, "version","0"));
01715 addEmptyMode=GWEN_XMLNode_GetProperty(n, "addemptymode","one");
01716
01717 DBG_DEBUG(GWEN_LOGDOMAIN, "Omitted elements: %d", omittedElements);
01718 t=GWEN_XMLNode_GetType(n);
01719 if (t==GWEN_XMLNodeTypeTag) {
01720 const char *typ;
01721
01722 typ=GWEN_XMLNode_GetData(n);
01723 if (typ==0) {
01724 DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed tag found (internal error?)");
01725 return -1;
01726 }
01727 if (strcasecmp(typ, "ELEM")==0) {
01728
01729 int j;
01730 int rv;
01731
01732 DBG_VERBOUS(GWEN_LOGDOMAIN, "Found an element");
01733
01734 for (loopNr=0; loopNr<maxnum; loopNr++) {
01735 unsigned int posBeforeElement;
01736
01737 posBeforeElement=GWEN_Buffer_GetPos(gbuf);
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755 if (delimiter) {
01756 DBG_VERBOUS(GWEN_LOGDOMAIN, "Appending %d delimiters",
01757 omittedElements);
01758 for (j=0; j<omittedElements; j++) {
01759 if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
01760 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
01761 return -1;
01762 }
01763 }
01764 if (!isFirstElement)
01765 if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
01766 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
01767 return -1;
01768 }
01769 }
01770
01771 rv=GWEN_MsgEngine__WriteElement(e,
01772 gbuf,
01773 n,
01774 rnode,
01775 gr,
01776 loopNr,
01777 loopNr>=minnum ||
01778 (groupIsOptional && !hasEntries),
01779 nodePath);
01780 if (rv==-1) {
01781 DBG_INFO(GWEN_LOGDOMAIN, "Error writing element");
01782 DBG_INFO(GWEN_LOGDOMAIN, "Node is:");
01783 GWEN_XMLNode_Dump(n, stderr, 1);
01784 if (gr) {
01785 DBG_INFO(GWEN_LOGDOMAIN, "Data is:");
01786 GWEN_DB_Dump(gr, stderr, 1);
01787 }
01788 return -1;
01789 }
01790 else if (rv==0) {
01791 isFirstElement=0;
01792 omittedElements=0;
01793 hasEntries=1;
01794 DBG_DEBUG(GWEN_LOGDOMAIN, "Element written");
01795 }
01796 else {
01797
01798
01799 GWEN_Buffer_SetPos(gbuf, posBeforeElement);
01800 GWEN_Buffer_Crop(gbuf, 0, posBeforeElement);
01801
01802 if (strcasecmp(addEmptyMode, "max")==0) {
01803 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding max empty");
01804 omittedElements+=(maxnum-loopNr);
01805 }
01806 else if (strcasecmp(addEmptyMode, "min")==0) {
01807 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding min empty");
01808 if (loopNr<minnum)
01809 omittedElements+=(minnum-loopNr);
01810 }
01811 else if (strcasecmp(addEmptyMode, "one")==0) {
01812 if (loopNr==0)
01813 omittedElements++;
01814 }
01815 else if (strcasecmp(addEmptyMode, "none")==0) {
01816 }
01817 else {
01818 DBG_ERROR(GWEN_LOGDOMAIN, "Unknown addemptymode \"%s\"",
01819 addEmptyMode);
01820 return -1;
01821 }
01822 break;
01823 }
01824 }
01825 }
01826 else if (strcasecmp(typ, "VALUES")==0) {
01827 }
01828 else if (strcasecmp(typ, "DESCR")==0) {
01829 }
01830 else {
01831
01832 GWEN_XMLNODE *gn;
01833 GWEN_DB_NODE *gcfg;
01834 const char *gname;
01835 const char *gtype;
01836 unsigned int posBeforeGroup;
01837
01838 DBG_VERBOUS(GWEN_LOGDOMAIN, "Found a group");
01839
01840 gcfg=0;
01841 gtype=GWEN_XMLNode_GetProperty(n, "type",0);
01842 if (!gtype) {
01843
01844 DBG_INFO(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", typ);
01845 gtype="";
01846 gn=n;
01847 }
01848 else {
01849 DBG_VERBOUS(GWEN_LOGDOMAIN, "<%s> tag is of type \"%s\"", typ, gtype);
01850 gn=GWEN_MsgEngine_GetGroup(e, n, nodePath, typ,
01851 gversion, gtype);
01852 if (!gn) {
01853 DBG_INFO(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", typ);
01854 return -1;
01855 }
01856 }
01857
01858 gname=0;
01859 gcfg=0;
01860 if (gr) {
01861 gname=GWEN_XMLNode_GetProperty(n, "name",0);
01862 if (gname) {
01863 DBG_VERBOUS(GWEN_LOGDOMAIN, "Group \"%s\" using special data", gname);
01864 gcfg=GWEN_DB_GetFirstGroup(gr);
01865 }
01866 else {
01867 DBG_DEBUG(GWEN_LOGDOMAIN, "Unnamed group, using basic data");
01868 gcfg=gr;
01869 }
01870 }
01871
01872
01873 for (loopNr=0; loopNr<maxnum; loopNr++) {
01874 int rv;
01875 int groupIsEmpty;
01876
01877 groupIsEmpty=0;
01878 posBeforeGroup=GWEN_Buffer_GetPos(gbuf);
01879
01880
01881 if (gname) {
01882 DBG_DEBUG(GWEN_LOGDOMAIN, "Finding next group named \"%s\"", gname);
01883 while(gcfg) {
01884 if (strcasecmp(GWEN_DB_GroupName(gcfg), gname)==0)
01885 break;
01886 gcfg=GWEN_DB_GetNextGroup(gcfg);
01887 if (gcfg==0) {
01888 DBG_DEBUG(GWEN_LOGDOMAIN, "No group found");
01889 if (loopNr>=minnum)
01890 groupIsEmpty=1;
01891 }
01892 }
01893 }
01894
01895 if (!groupIsEmpty) {
01896 int dive;
01897
01898
01899 if (!isFirstElement && delimiter) {
01900 int j;
01901
01902 DBG_VERBOUS(GWEN_LOGDOMAIN, "Appending %d delimiters", omittedElements+1);
01903 for (j=0; j<omittedElements+1; j++) {
01904 if (GWEN_Buffer_AppendByte(gbuf, delimiter)) {
01905 return -1;
01906 }
01907 }
01908 omittedElements=0;
01909 }
01910 else
01911 isFirstElement=0;
01912
01913
01914
01915 if (GWEN_XMLNode_Path_Dive(nodePath, n)) {
01916 DBG_INFO(GWEN_LOGDOMAIN, "Called from here");
01917 return -1;
01918 }
01919 if (n==gn)
01920 dive=1;
01921 else {
01922 if (GWEN_XMLNode_Path_Dive(nodePath, gn)) {
01923 DBG_INFO(GWEN_LOGDOMAIN, "Called from here");
01924 return -1;
01925 }
01926 dive=2;
01927 }
01928 rv=GWEN_MsgEngine__WriteGroup(e,
01929 gbuf,
01930 gn,
01931 n,
01932 gcfg,
01933 loopNr>=minnum || groupIsOptional,
01934 nodePath);
01935 GWEN_XMLNode_Path_Surface(nodePath);
01936 if (dive==2)
01937 GWEN_XMLNode_Path_Surface(nodePath);
01938 if (rv==-1){
01939 DBG_INFO(GWEN_LOGDOMAIN, "Could not write group \"%s\"", gtype);
01940 if (gn) {
01941 DBG_INFO(GWEN_LOGDOMAIN, "Node is:");
01942 GWEN_XMLNode_Dump(gn, stderr, 1);
01943 }
01944 if (n) {
01945 DBG_INFO(GWEN_LOGDOMAIN, "Referring node is:");
01946 GWEN_XMLNode_Dump(n, stderr, 1);
01947 }
01948 if (gr) {
01949 DBG_INFO(GWEN_LOGDOMAIN, "Data is:");
01950 GWEN_DB_Dump(gr, stderr, 1);
01951 }
01952 return -1;
01953 }
01954 else if (rv==0) {
01955 hasEntries=1;
01956 }
01957 else
01958 groupIsEmpty=1;
01959 }
01960
01961 if (groupIsEmpty) {
01962 DBG_DEBUG(GWEN_LOGDOMAIN, "Empty Group");
01963 GWEN_Buffer_SetPos(gbuf, posBeforeGroup);
01964 GWEN_Buffer_Crop(gbuf, 0, posBeforeGroup);
01965
01966 if (loopNr>=minnum) {
01967 DBG_DEBUG(GWEN_LOGDOMAIN, "No data for group \"%s[%d]\", omitting",
01968 gname, loopNr);
01969 if (strcasecmp(addEmptyMode, "max")==0) {
01970 DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding max empty");
01971 omittedElements+=(maxnum-loopNr);
01972 }
01973 else if (strcasecmp(addEmptyMode, "min")==0) {
01974 DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding min empty");
01975 if (loopNr<minnum)
01976 omittedElements+=(minnum-loopNr);
01977 }
01978 else if (strcasecmp(addEmptyMode, "one")==0) {
01979 if (loopNr==0)
01980 omittedElements++;
01981 }
01982 else if (strcasecmp(addEmptyMode, "none")==0) {
01983 }
01984 else {
01985 DBG_ERROR(GWEN_LOGDOMAIN, "Unknown addemptymode \"%s\"",
01986 addEmptyMode);
01987 return -1;
01988 }
01989 break;
01990 }
01991 else {
01992 DBG_ERROR(GWEN_LOGDOMAIN, "No data for group \"%s[%d]\"",
01993 gname, loopNr);
01994 return -1;
01995 }
01996 }
01997
01998 if (gcfg)
01999 gcfg=GWEN_DB_GetNextGroup(gcfg);
02000 }
02001 }
02002 }
02003 else if (t==GWEN_XMLNodeTypeData) {
02004 }
02005 else {
02006 DBG_DEBUG(GWEN_LOGDOMAIN, "Unhandled node type %d", t);
02007 }
02008 n=GWEN_XMLNode_Next(n);
02009 }
02010
02011
02012 if (terminator) {
02013 if (GWEN_Buffer_AppendByte(gbuf, terminator)) {
02014 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
02015 return -1;
02016 }
02017 }
02018
02019 if (!hasEntries) {
02020 DBG_INFO(GWEN_LOGDOMAIN, "No entries in node");
02021 }
02022 return hasEntries?0:1;
02023 }
02024
02025
02026
02027 int GWEN_MsgEngine_CreateMessageFromNode(GWEN_MSGENGINE *e,
02028 GWEN_XMLNODE *node,
02029 GWEN_BUFFER *gbuf,
02030 GWEN_DB_NODE *msgData){
02031 GWEN_XMLNODE_PATH *np;
02032 int rv;
02033
02034 assert(e);
02035 assert(node);
02036 assert(msgData);
02037
02038 np=GWEN_XMLNode_Path_new();
02039 GWEN_XMLNode_Path_Dive(np, node);
02040 rv=GWEN_MsgEngine__WriteGroup(e,
02041 gbuf,
02042 node,
02043 0,
02044 msgData,
02045 0,
02046 np);
02047 GWEN_XMLNode_Path_free(np);
02048 if (rv){
02049 const char *p;
02050
02051 p=GWEN_XMLNode_GetData(node);
02052 if (p) {
02053 DBG_INFO(GWEN_LOGDOMAIN, "Error writing group \"%s\"", p);
02054 }
02055 else {
02056 DBG_INFO(GWEN_LOGDOMAIN, "Error writing group");
02057 }
02058 return -1;
02059 }
02060
02061 return 0;
02062 }
02063
02064
02065
02066 int GWEN_MsgEngine_CreateMessage(GWEN_MSGENGINE *e,
02067 const char *msgName,
02068 int msgVersion,
02069 GWEN_BUFFER *gbuf,
02070 GWEN_DB_NODE *msgData) {
02071 GWEN_XMLNODE *group;
02072
02073 group=GWEN_MsgEngine_FindGroupByProperty(e, "id", msgVersion, msgName);
02074 if (!group) {
02075 DBG_ERROR(GWEN_LOGDOMAIN, "Group \"%s\" not found\n", msgName);
02076 return -1;
02077 }
02078 return GWEN_MsgEngine_CreateMessageFromNode(e,
02079 group,
02080 gbuf,
02081 msgData);
02082 }
02083
02084
02085
02086 int GWEN_MsgEngine_AddDefinitions(GWEN_MSGENGINE *e,
02087 GWEN_XMLNODE *node) {
02088 GWEN_XMLNODE *nsrc, *ndst;
02089
02090 assert(e);
02091 assert(node);
02092
02093 if (!e->defs) {
02094 e->defs=GWEN_XMLNode_dup(node);
02095 e->ownDefs=1;
02096 return 0;
02097 }
02098
02099 nsrc=GWEN_XMLNode_GetChild(node);
02100 while(nsrc) {
02101 if (GWEN_XMLNode_GetType(nsrc)==GWEN_XMLNodeTypeTag) {
02102 ndst=GWEN_XMLNode_FindNode(e->defs, GWEN_XMLNodeTypeTag,
02103 GWEN_XMLNode_GetData(nsrc));
02104 if (ndst) {
02105 GWEN_XMLNODE *n;
02106
02107 n=GWEN_XMLNode_GetChild(nsrc);
02108 while (n) {
02109 GWEN_XMLNODE *newNode;
02110
02111 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding node \"%s\"", GWEN_XMLNode_GetData(n));
02112 newNode=GWEN_XMLNode_dup(n);
02113 GWEN_XMLNode_AddChild(ndst, newNode);
02114 n=GWEN_XMLNode_Next(n);
02115 }
02116 }
02117 else {
02118 GWEN_XMLNODE *newNode;
02119
02120 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding branch \"%s\"", GWEN_XMLNode_GetData(nsrc));
02121 newNode=GWEN_XMLNode_dup(nsrc);
02122 GWEN_XMLNode_AddChild(e->defs, newNode);
02123 }
02124 }
02125 nsrc=GWEN_XMLNode_Next(nsrc);
02126 }
02127
02128 return 0;
02129 }
02130
02131
02132
02133 int GWEN_MsgEngine__ShowElement(GWEN_MSGENGINE *e,
02134 const char *path,
02135 GWEN_XMLNODE *node,
02136 GWEN_STRINGLIST *sl,
02137 uint32_t flags) {
02138 const char *name;
02139 const char *type;
02140 const char *npath;
02141 unsigned int minsize;
02142 unsigned int maxsize;
02143 unsigned int minnum;
02144 unsigned int maxnum;
02145 int j;
02146 int isSet;
02147 char nbuffer[256];
02148 GWEN_STRINGLISTENTRY *en;
02149
02150
02151 type=GWEN_XMLNode_GetProperty(node, "type","ASCII");
02152
02153
02154 minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize","0"));
02155 maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize","0"));
02156 minnum=atoi(GWEN_XMLNode_GetProperty(node, "minnum","1"));
02157 maxnum=atoi(GWEN_XMLNode_GetProperty(node, "maxnum","1"));
02158
02159 npath="";
02160 isSet=0;
02161
02162
02163 name=GWEN_XMLNode_GetProperty(node, "name", 0);
02164 if (path==0)
02165 path="";
02166
02167 if (name) {
02168
02169 if (strlen(path)+strlen(name)+10>=sizeof(nbuffer)) {
02170 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02171 return -1;
02172 }
02173 if (*path)
02174 sprintf(nbuffer, "%s/%s", path, name);
02175 else
02176 sprintf(nbuffer, "%s", name);
02177 npath=nbuffer;
02178 }
02179
02180 en=GWEN_StringList_FirstEntry(sl);
02181 while(en) {
02182 if (GWEN_StringListEntry_Data(en))
02183 if (strcasecmp(GWEN_StringListEntry_Data(en), npath)==0) {
02184 isSet=1;
02185 break;
02186 }
02187 en=GWEN_StringListEntry_Next(en);
02188 }
02189
02190 if (isSet && (flags & GWEN_MSGENGINE_SHOW_FLAGS_NOSET))
02191 return 0;
02192
02193 fprintf(stdout, " %s",
02194 npath);
02195 j=GWEN_MSGENGINE_VARNAME_WIDTH-strlen(npath);
02196 if (j>0) {
02197 int i;
02198
02199 for (i=0; i<j; i++)
02200 fprintf(stdout, " ");
02201 }
02202 fprintf(stdout, "| %s", type);
02203 j=GWEN_MSGENGINE_TYPENAME_WIDTH-strlen(type);
02204 if (j>0) {
02205 int i;
02206
02207 for (i=0; i<j; i++)
02208 fprintf(stdout, " ");
02209 }
02210 fprintf(stdout, "| %4d-%4d", minsize, maxsize);
02211 fprintf(stdout," | %3d ", maxnum);
02212 fprintf(stdout," |");
02213 if (minnum==0)
02214 fprintf(stdout," optvar");
02215 if (flags & GWEN_MSGENGINE_SHOW_FLAGS_OPTIONAL)
02216 fprintf(stdout," optgrp");
02217
02218 if (isSet) {
02219 fprintf(stdout," set");
02220 }
02221
02222 fprintf(stdout,"\n");
02223
02224 return 0;
02225 }
02226
02227
02228
02229 int GWEN_MsgEngine__ShowGroup(GWEN_MSGENGINE *e,
02230 const char *path,
02231 GWEN_XMLNODE *node,
02232 GWEN_XMLNODE *rnode,
02233 GWEN_STRINGLIST *sl,
02234 uint32_t flags) {
02235 GWEN_XMLNODE *n;
02236 int isFirstElement;
02237 int omittedElements;
02238 int rv;
02239
02240
02241 n=GWEN_XMLNode_GetChild(node);
02242
02243 if (path==0)
02244 path="";
02245 if (*path=='/')
02246 path++;
02247
02248 while(n) {
02249 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
02250 const char *p;
02251
02252 p=GWEN_XMLNode_GetData(n);
02253 assert(p);
02254 DBG_DEBUG(GWEN_LOGDOMAIN, "Checking %s",p);
02255 if (strcasecmp(p, "VALUES")==0)
02256 break;
02257 }
02258 n=GWEN_XMLNode_Next(n);
02259 }
02260
02261 if (n) {
02262 DBG_DEBUG(GWEN_LOGDOMAIN, "<preset> found");
02263
02264 n=GWEN_XMLNode_GetChild(n);
02265 while(n) {
02266 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
02267 const char *p;
02268
02269 p=GWEN_XMLNode_GetData(n);
02270 assert(p);
02271 if (strcasecmp(p, "VALUE")==0) {
02272 const char *pname;
02273 const char *pvalue;
02274
02275 pname=GWEN_XMLNode_GetProperty(n, "path", 0);
02276 if (pname) {
02277 GWEN_XMLNODE *dn;
02278
02279
02280 dn=GWEN_XMLNode_GetChild(n);
02281 while (dn) {
02282 if (GWEN_XMLNode_GetType(dn)==GWEN_XMLNodeTypeData) {
02283 pvalue=GWEN_XMLNode_GetData(dn);
02284 if (pvalue) {
02285 char pbuffer[256];
02286
02287
02288 p=pvalue;
02289 while (*p && isspace((int)*p))
02290 p++;
02291 if (strlen(path)+strlen(pname)+2>sizeof(pbuffer)) {
02292 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02293 return -1;
02294 }
02295 if (*path)
02296 sprintf(pbuffer, "%s/%s", path, pname);
02297 else
02298 sprintf(pbuffer, "%s", pname);
02299 GWEN_StringList_AppendString(sl,
02300 pbuffer,
02301 0,
02302 1);
02303 }
02304 break;
02305 }
02306 dn=GWEN_XMLNode_Next(dn);
02307 }
02308 }
02309 }
02310 }
02311 n=GWEN_XMLNode_Next(n);
02312 }
02313 }
02314
02315
02316 n=GWEN_XMLNode_GetChild(node);
02317 isFirstElement=1;
02318 omittedElements=0;
02319 while(n) {
02320 int t;
02321 unsigned int minnum;
02322 unsigned int maxnum;
02323 int gversion;
02324 const char *addEmptyMode;
02325 unsigned int loopNr;
02326 unsigned int lflags;
02327
02328 minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum","1"));
02329 maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum","1"));
02330 gversion=atoi(GWEN_XMLNode_GetProperty(n, "version","0"));
02331 addEmptyMode=GWEN_XMLNode_GetProperty(n, "addemptymode","one");
02332
02333 lflags=flags;
02334
02335 DBG_DEBUG(GWEN_LOGDOMAIN, "Omitted elements: %d", omittedElements);
02336 t=GWEN_XMLNode_GetType(n);
02337 if (t==GWEN_XMLNodeTypeTag) {
02338 const char *typ;
02339
02340 typ=GWEN_XMLNode_GetData(n);
02341 if (typ==0) {
02342 DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed tag found (internal error?)");
02343 return -1;
02344 }
02345 if (strcasecmp(typ, "ELEM")==0) {
02346
02347
02348
02349 rv=GWEN_MsgEngine__ShowElement(e,
02350 path,
02351 n,
02352 sl,
02353 lflags);
02354 if (rv==-1)
02355 return -1;
02356 else {
02357 isFirstElement=0;
02358 omittedElements=0;
02359 }
02360 }
02361 else if (strcasecmp(typ, "VALUES")==0) {
02362 }
02363 else if (strcasecmp(typ, "DESCR")==0) {
02364 }
02365 else {
02366
02367 GWEN_XMLNODE *gn;
02368 const char *gname;
02369 const char *gtype;
02370
02371 if (minnum==0)
02372 lflags|=GWEN_MSGENGINE_SHOW_FLAGS_OPTIONAL;
02373
02374 gtype=GWEN_XMLNode_GetProperty(n, "type",0);
02375 if (!gtype) {
02376
02377 DBG_DEBUG(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", typ);
02378 gtype="";
02379 gn=n;
02380 }
02381 else {
02382 gn=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", gversion, gtype);
02383 if (!gn) {
02384 DBG_DEBUG(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", typ);
02385 return -1;
02386 }
02387 }
02388
02389
02390 for (loopNr=0; loopNr<maxnum; loopNr++) {
02391
02392 char pbuffer[256];
02393 const char *npath;
02394
02395
02396 gname=GWEN_XMLNode_GetProperty(n, "name",0);
02397 if (gname) {
02398 if (loopNr==0) {
02399 if (strlen(path)+strlen(gname)+1>sizeof(pbuffer)) {
02400 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02401 return -1;
02402 }
02403 sprintf(pbuffer, "%s/%s", path, gname);
02404 npath=pbuffer;
02405 }
02406 else {
02407
02408 if (strlen(path)+strlen(gname)+10>sizeof(pbuffer)) {
02409 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02410 return -1;
02411 }
02412 if (*path)
02413 sprintf(pbuffer, "%s/%s%d", path, gname, loopNr);
02414 else
02415 sprintf(pbuffer, "%s%d", gname, loopNr);
02416
02417 npath=pbuffer;
02418 }
02419 }
02420 else
02421 npath=path;
02422
02423
02424 if (GWEN_MsgEngine__ShowGroup(e,
02425 npath,
02426 gn,
02427 n,
02428 sl,
02429 lflags)) {
02430 DBG_INFO(GWEN_LOGDOMAIN, "Could not show group \"%s\"", gtype);
02431 return -1;
02432 }
02433 }
02434 }
02435 }
02436 n=GWEN_XMLNode_Next(n);
02437 }
02438
02439 return 0;
02440 }
02441
02442
02443
02444 int GWEN_MsgEngine_ShowMessage(GWEN_MSGENGINE *e,
02445 const char *typ,
02446 const char *msgName,
02447 int msgVersion,
02448 uint32_t flags) {
02449 GWEN_XMLNODE *group;
02450 GWEN_STRINGLIST *sl;
02451 int i, j;
02452 const char *p;
02453
02454 sl=GWEN_StringList_new();
02455
02456 fprintf(stdout, "Message \"%s\" version %d\n",
02457 msgName, msgVersion);
02458 for (i=0; i<76; i++)
02459 fprintf(stdout, "=");
02460 fprintf(stdout, "\n");
02461 p=" Variable";
02462 fprintf(stdout, "%s", p);
02463 i=GWEN_MSGENGINE_VARNAME_WIDTH-strlen(p);
02464 for (j=0; j<i; j++)
02465 fprintf(stdout," ");
02466
02467 fprintf(stdout," |");
02468 p=" Type";
02469 fprintf(stdout, "%s", p);
02470 i=GWEN_MSGENGINE_TYPENAME_WIDTH-strlen(p);
02471 for (j=0; j<i; j++)
02472 fprintf(stdout," ");
02473
02474 fprintf(stdout," | Size | Num | Flags\n");
02475 for (i=0; i<76; i++)
02476 fprintf(stdout, "-");
02477 fprintf(stdout, "\n");
02478
02479 group=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", msgVersion, msgName);
02480 if (!group) {
02481 DBG_ERROR(GWEN_LOGDOMAIN, "Group \"%s\" not found\n", msgName);
02482 GWEN_StringList_free(sl);
02483 return -1;
02484 }
02485
02486 if (GWEN_MsgEngine__ShowGroup(e,
02487 "",
02488 group,
02489 0,
02490 sl,
02491 flags)) {
02492 DBG_INFO(GWEN_LOGDOMAIN, "Error showing group \"%s\"", msgName);
02493 GWEN_StringList_free(sl);
02494 return -1;
02495 }
02496
02497 GWEN_StringList_free(sl);
02498
02499 return 0;
02500 }
02501
02502
02503
02504 int GWEN_MsgEngine__ListElement(GWEN_MSGENGINE *e,
02505 const char *path,
02506 GWEN_XMLNODE *node,
02507 GWEN_STRINGLIST *sl,
02508 GWEN_XMLNODE *listNode,
02509 uint32_t flags) {
02510 const char *name;
02511 const char *type;
02512 const char *npath;
02513 int isSet;
02514 char nbuffer[256];
02515 GWEN_STRINGLISTENTRY *en;
02516 GWEN_XMLNODE *nn;
02517
02518
02519 type=GWEN_XMLNode_GetProperty(node, "type","ASCII");
02520
02521 npath="";
02522 isSet=0;
02523
02524
02525 name=GWEN_XMLNode_GetProperty(node, "name", 0);
02526 if (path==0)
02527 path="";
02528
02529 if (name) {
02530
02531 if (strlen(path)+strlen(name)+10>=sizeof(nbuffer)) {
02532 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02533 return -1;
02534 }
02535 if (*path)
02536 sprintf(nbuffer, "%s/%s", path, name);
02537 else
02538 sprintf(nbuffer, "%s", name);
02539 npath=nbuffer;
02540 }
02541
02542 en=GWEN_StringList_FirstEntry(sl);
02543 while(en) {
02544 if (GWEN_StringListEntry_Data(en))
02545 if (strcasecmp(GWEN_StringListEntry_Data(en), npath)==0) {
02546 isSet=1;
02547 break;
02548 }
02549 en=GWEN_StringListEntry_Next(en);
02550 }
02551
02552 if (isSet && (flags & GWEN_MSGENGINE_SHOW_FLAGS_NOSET))
02553 return 0;
02554
02555 nn=GWEN_XMLNode_dup(node);
02556 if (isSet)
02557 GWEN_XMLNode_SetProperty(nn, "GWEN_set", "1");
02558 GWEN_XMLNode_SetProperty(nn, "GWEN_path", npath);
02559 GWEN_XMLNode_AddChild(listNode, nn);
02560
02561 return 0;
02562 }
02563
02564
02565
02566 int GWEN_MsgEngine__ListGroup(GWEN_MSGENGINE *e,
02567 const char *path,
02568 GWEN_XMLNODE *node,
02569 GWEN_XMLNODE *rnode,
02570 GWEN_STRINGLIST *sl,
02571 GWEN_XMLNODE *listNode,
02572 uint32_t flags) {
02573 GWEN_XMLNODE *n;
02574 int rv;
02575
02576
02577 n=GWEN_XMLNode_GetChild(node);
02578
02579 if (path==0)
02580 path="";
02581 if (*path=='/')
02582 path++;
02583
02584 while(n) {
02585 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
02586 const char *p;
02587
02588 p=GWEN_XMLNode_GetData(n);
02589 assert(p);
02590 DBG_DEBUG(GWEN_LOGDOMAIN, "Checking %s",p);
02591 if (strcasecmp(p, "VALUES")==0)
02592 break;
02593 }
02594 n=GWEN_XMLNode_Next(n);
02595 }
02596
02597 if (n) {
02598 DBG_DEBUG(GWEN_LOGDOMAIN, "<values> found");
02599
02600 n=GWEN_XMLNode_GetChild(n);
02601 while(n) {
02602 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
02603 const char *p;
02604
02605 p=GWEN_XMLNode_GetData(n);
02606 assert(p);
02607 if (strcasecmp(p, "VALUE")==0) {
02608 const char *pname;
02609 const char *pvalue;
02610
02611 pname=GWEN_XMLNode_GetProperty(n, "path", 0);
02612 if (pname) {
02613 GWEN_XMLNODE *dn;
02614
02615
02616 dn=GWEN_XMLNode_GetChild(n);
02617 while (dn) {
02618 if (GWEN_XMLNode_GetType(dn)==GWEN_XMLNodeTypeData) {
02619 pvalue=GWEN_XMLNode_GetData(dn);
02620 if (pvalue) {
02621 char pbuffer[256];
02622
02623
02624 p=pvalue;
02625 while (*p && isspace((int)*p))
02626 p++;
02627 if (strlen(path)+strlen(pname)+2>sizeof(pbuffer)) {
02628 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02629 return -1;
02630 }
02631 if (*path)
02632 sprintf(pbuffer, "%s/%s", path, pname);
02633 else
02634 sprintf(pbuffer, "%s", pname);
02635 DBG_INFO(GWEN_LOGDOMAIN, "Found preset value for %s", pbuffer);
02636 GWEN_StringList_AppendString(sl,
02637 pbuffer,
02638 0,
02639 1);
02640 }
02641 break;
02642 }
02643 dn=GWEN_XMLNode_Next(dn);
02644 }
02645 }
02646 }
02647 }
02648 n=GWEN_XMLNode_Next(n);
02649 }
02650 }
02651
02652
02653 n=GWEN_XMLNode_GetChild(node);
02654 while(n) {
02655 int t;
02656 int gversion;
02657 unsigned int lflags;
02658
02659 gversion=atoi(GWEN_XMLNode_GetProperty(n, "version","0"));
02660 lflags=flags;
02661
02662 t=GWEN_XMLNode_GetType(n);
02663 if (t==GWEN_XMLNodeTypeTag) {
02664 const char *typ;
02665
02666 typ=GWEN_XMLNode_GetData(n);
02667 if (typ==0) {
02668 DBG_ERROR(GWEN_LOGDOMAIN, "Unnamed tag found (internal error?)");
02669 return -1;
02670 }
02671 if (strcasecmp(typ, "ELEM")==0) {
02672
02673
02674
02675 rv=GWEN_MsgEngine__ListElement(e,
02676 path,
02677 n,
02678 sl,
02679 listNode,
02680 lflags);
02681 if (rv==-1)
02682 return -1;
02683 }
02684 else if (strcasecmp(typ, "VALUES")==0) {
02685 }
02686 else if (strcasecmp(typ, "DESCR")==0) {
02687 }
02688 else {
02689
02690 GWEN_XMLNODE *gn;
02691 GWEN_XMLNODE *nn;
02692 const char *gname;
02693 const char *gtype;
02694 char pbuffer[256];
02695 const char *npath;
02696
02697 gtype=GWEN_XMLNode_GetProperty(n, "type",0);
02698 if (!gtype) {
02699
02700 DBG_DEBUG(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", typ);
02701 gtype="";
02702 gn=n;
02703 }
02704 else {
02705 gn=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", gversion, gtype);
02706 if (!gn) {
02707 DBG_DEBUG(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", typ);
02708 return -1;
02709 }
02710 }
02711
02712
02713 gname=GWEN_XMLNode_GetProperty(n, "name",0);
02714 if (gname) {
02715 if (strlen(path)+strlen(gname)+1>sizeof(pbuffer)) {
02716 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
02717 return -1;
02718 }
02719
02720 if (*path)
02721 sprintf(pbuffer, "%s/%s", path, gname);
02722 else
02723 sprintf(pbuffer, "%s", gname);
02724 npath=pbuffer;
02725 }
02726 else
02727 npath=path;
02728
02729 nn=GWEN_XMLNode_dup(n);
02730 if (gn!=n)
02731 GWEN_XMLNode_CopyProperties(nn, gn, 0);
02732 GWEN_XMLNode_SetProperty(nn, "GWEN_path", npath);
02733 GWEN_XMLNode_AddChild(listNode, nn);
02734
02735
02736 if (GWEN_MsgEngine__ListGroup(e,
02737 npath,
02738 gn,
02739 n,
02740 sl,
02741 nn,
02742 lflags)) {
02743 DBG_INFO(GWEN_LOGDOMAIN, "Could not list group \"%s\"", gtype);
02744 return -1;
02745 }
02746 }
02747 }
02748 n=GWEN_XMLNode_Next(n);
02749 }
02750
02751 return 0;
02752 }
02753
02754
02755
02756 GWEN_XMLNODE *GWEN_MsgEngine_ListMessage(GWEN_MSGENGINE *e,
02757 const char *typ,
02758 const char *msgName,
02759 int msgVersion,
02760 uint32_t flags) {
02761 GWEN_XMLNODE *group;
02762 GWEN_STRINGLIST *sl;
02763 GWEN_XMLNODE *listNode;
02764
02765 group=GWEN_MsgEngine_FindNodeByProperty(e, typ, "id", msgVersion, msgName);
02766 if (!group)
02767 group=GWEN_MsgEngine_FindNodeByProperty(e, typ, "code",
02768 msgVersion, msgName);
02769 if (!group) {
02770 DBG_ERROR(GWEN_LOGDOMAIN, "Group \"%s\" (version %d) not found\n",
02771 msgName, msgVersion);
02772 return 0;
02773 }
02774
02775 sl=GWEN_StringList_new();
02776
02777 listNode=GWEN_XMLNode_dup(group);
02778 GWEN_XMLNode_RemoveChildren(listNode);
02779
02780 if (GWEN_MsgEngine__ListGroup(e,
02781 "",
02782 group,
02783 0,
02784 sl,
02785 listNode,
02786 flags)) {
02787 DBG_INFO(GWEN_LOGDOMAIN, "Error showing group \"%s\"", msgName);
02788 GWEN_StringList_free(sl);
02789 GWEN_XMLNode_free(listNode);
02790 return 0;
02791 }
02792
02793 GWEN_StringList_free(sl);
02794
02795 return listNode;
02796 }
02797
02798
02799
02800
02801
02802
02803
02804 int GWEN_MsgEngine__ReadValue(GWEN_MSGENGINE *e,
02805 GWEN_BUFFER *msgbuf,
02806 GWEN_XMLNODE *node,
02807 GWEN_XMLNODE *rnode,
02808 GWEN_BUFFER *vbuf,
02809 const char *delimiters,
02810 uint32_t flags) {
02811 unsigned int minsize;
02812 unsigned int maxsize;
02813 unsigned int size;
02814 unsigned int minnum;
02815 GWEN_MSGENGINE_TRUSTLEVEL trustLevel;
02816 unsigned int posInMsg;
02817 const char *type;
02818 int rv;
02819 unsigned int realSize;
02820
02821
02822 posInMsg=GWEN_Buffer_GetPos(msgbuf);
02823 realSize=0;
02824 size=atoi(GWEN_XMLNode_GetProperty(node, "size","0"));
02825 minsize=atoi(GWEN_XMLNode_GetProperty(node, "minsize","0"));
02826 maxsize=atoi(GWEN_XMLNode_GetProperty(node, "maxsize","0"));
02827 minnum=atoi(GWEN_XMLNode_GetProperty(node, "minnum","1"));
02828 type=GWEN_XMLNode_GetProperty(node, "type","ASCII");
02829
02830 rv=1;
02831 if (e->typeReadPtr) {
02832 rv=e->typeReadPtr(e,
02833 msgbuf,
02834 node,
02835 vbuf,
02836 e->escapeChar,
02837 delimiters);
02838 }
02839 if (rv==-1) {
02840 DBG_INFO(GWEN_LOGDOMAIN, "External type reading failed on type \"%s\"", type);
02841 return -1;
02842 }
02843 else if (rv==1) {
02844 if (strcasecmp(type, "bin")==0) {
02845 if (GWEN_Buffer_GetBytesLeft(msgbuf)==0) {
02846 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (@num@ expected)");
02847 return -1;
02848 }
02849 else {
02850 char lbuffer[16];
02851 int c;
02852 char *p;
02853 int l;
02854
02855 p=lbuffer;
02856 c=GWEN_Buffer_ReadByte(msgbuf);
02857 if (c!='@') {
02858 DBG_ERROR(GWEN_LOGDOMAIN, "\"@num@\" expected");
02859 return -1;
02860 }
02861
02862 c=0;
02863 while(GWEN_Buffer_GetBytesLeft(msgbuf)>0) {
02864 c=GWEN_Buffer_ReadByte(msgbuf);
02865 if (c==-1) {
02866 DBG_ERROR(GWEN_LOGDOMAIN, "\"@\" expected");
02867 return -1;
02868 }
02869 if (c=='@')
02870 break;
02871 *p=(char)c;
02872 p++;
02873 }
02874 *p=0;
02875 if (c!='@') {
02876 DBG_ERROR(GWEN_LOGDOMAIN, "\"@num@\" expected");
02877 return -1;
02878 }
02879 if (sscanf(lbuffer, "%d", &l)!=1) {
02880 DBG_ERROR(GWEN_LOGDOMAIN, "Bad number format");
02881 return -1;
02882 }
02883 DBG_DEBUG(GWEN_LOGDOMAIN, "Reading binary: %d bytes from pos %d (msgsize=%d)",
02884 l,
02885 GWEN_Buffer_GetPos(msgbuf),
02886 GWEN_Buffer_GetUsedBytes(msgbuf));
02887 if (GWEN_Buffer_GetBytesLeft(msgbuf) < (unsigned) l) {
02888 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (binary beyond end)");
02889 return -1;
02890 }
02891 if (GWEN_Buffer_AppendBytes(vbuf,
02892 GWEN_Buffer_GetPosPointer(msgbuf),
02893 l)) {
02894 DBG_DEBUG(GWEN_LOGDOMAIN, "Called from here");
02895 return -1;
02896 }
02897 GWEN_Buffer_IncrementPos(msgbuf,l);
02898 }
02899 }
02900 else {
02901
02902 int lastWasEscape;
02903 int isEscaped;
02904 int br;
02905
02906 isEscaped=0;
02907 lastWasEscape=0;
02908
02909 br=0;
02910 while(GWEN_Buffer_GetBytesLeft(msgbuf) &&
02911 (size==0 || br<size)) {
02912 int c;
02913
02914 c=GWEN_Buffer_ReadByte(msgbuf);
02915 if (lastWasEscape) {
02916 lastWasEscape=0;
02917 isEscaped=1;
02918 }
02919 else {
02920 isEscaped=0;
02921 if (c==e->escapeChar) {
02922 lastWasEscape=1;
02923 c=-1;
02924 }
02925 }
02926 if (c!=-1) {
02927 if (!isEscaped && (c && strchr(delimiters, c)!=0)) {
02928
02929 GWEN_Buffer_DecrementPos(msgbuf,1);
02930 break;
02931 }
02932 else {
02933 if (c=='\\' || iscntrl(c)) {
02934 DBG_WARN(GWEN_LOGDOMAIN,
02935 "Found a bad character (%02x) in type \"%s\", "
02936 "converting to SPACE",
02937 (unsigned int)c,
02938 type);
02939 c=' ';
02940 }
02941 if (GWEN_Buffer_AppendByte(vbuf, c)) {
02942 DBG_DEBUG(GWEN_LOGDOMAIN, "Called from here");
02943 return -1;
02944 }
02945 br++;
02946 }
02947 }
02948 }
02949 }
02950 }
02951 else {
02952 DBG_DEBUG(GWEN_LOGDOMAIN, "Type \"%s\" is external (read)", type);
02953 }
02954
02955 realSize=GWEN_Buffer_GetUsedBytes(vbuf);
02956
02957
02958 if (realSize==0) {
02959 DBG_DEBUG(GWEN_LOGDOMAIN, "Datasize is 0");
02960 if (minnum==0) {
02961 DBG_DEBUG(GWEN_LOGDOMAIN, "... but thats ok");
02962
02963 return 1;
02964 }
02965 else {
02966 DBG_ERROR(GWEN_LOGDOMAIN, "Value missing");
02967 GWEN_XMLNode_Dump(node, stderr, 1);
02968 return -1;
02969 }
02970 }
02971
02972
02973 if (minsize!=0 && realSize<minsize) {
02974 DBG_INFO(GWEN_LOGDOMAIN, "Value too short (%d<%d).",
02975 realSize,
02976 minsize);
02977 return -1;
02978 }
02979
02980
02981 if (maxsize!=0 && realSize>maxsize) {
02982 DBG_INFO(GWEN_LOGDOMAIN, "Value too long (%d>%d).",
02983 realSize, maxsize);
02984 return -1;
02985 }
02986
02987 if (flags & GWEN_MSGENGINE_READ_FLAGS_TRUSTINFO) {
02988
02989 const char *descr;
02990
02991 trustLevel=GWEN_MsgEngine_GetHighestTrustLevel(node, rnode);
02992 if (trustLevel) {
02993 unsigned int ustart;
02994
02995 ustart=GWEN_Buffer_GetPos(msgbuf)-realSize;
02996 descr=GWEN_XMLNode_GetProperty(node, "name",0);
02997 if (GWEN_MsgEngine_AddTrustInfo(e,
02998 GWEN_Buffer_GetStart(vbuf),
02999 realSize,
03000 descr,
03001 trustLevel,
03002 ustart)) {
03003 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
03004 return -1;
03005 }
03006 }
03007 }
03008
03009 return 0;
03010 }
03011
03012
03013
03014 int GWEN_MsgEngine__ReadGroup(GWEN_MSGENGINE *e,
03015 GWEN_BUFFER *msgbuf,
03016 GWEN_XMLNODE *node,
03017 GWEN_XMLNODE *rnode,
03018 GWEN_DB_NODE *gr,
03019 const char *delimiters,
03020 uint32_t flags) {
03021 unsigned int minsize;
03022 unsigned int maxsize;
03023 unsigned int minnum;
03024 unsigned int maxnum;
03025 const char *name;
03026 const char *p;
03027 char delimiter;
03028 char terminator;
03029 GWEN_XMLNODE *n;
03030 int abortLoop;
03031 GWEN_BUFFER *delimBuffer=0;
03032
03033
03034 if (rnode) {
03035
03036 p=GWEN_XMLNode_GetProperty(rnode,
03037 "delimiter",
03038 GWEN_XMLNode_GetProperty(node,
03039 "delimiter",
03040 ""));
03041 delimiter=*p;
03042
03043
03044 p=GWEN_XMLNode_GetProperty(rnode,
03045 "terminator",
03046 GWEN_XMLNode_GetProperty(node,
03047 "terminator",
03048 ""));
03049 terminator=*p;
03050 }
03051 else {
03052
03053 p=GWEN_XMLNode_GetProperty(node,
03054 "delimiter",
03055 "");
03056 delimiter=*p;
03057
03058
03059 p=GWEN_XMLNode_GetProperty(node, "terminator","");
03060 terminator=*p;
03061 }
03062
03063 delimBuffer=GWEN_Buffer_new(0, strlen(delimiters)+2, 0, 1);
03064 GWEN_Buffer_AppendString(delimBuffer, delimiters);
03065 if (delimiter)
03066 GWEN_Buffer_AppendByte(delimBuffer, delimiter);
03067 if (terminator)
03068 GWEN_Buffer_AppendByte(delimBuffer, terminator);
03069
03070 DBG_DEBUG(GWEN_LOGDOMAIN, "Delimiters are \"%s\" and \"%c\"",
03071 delimiters, delimiter);
03072
03073 n=GWEN_XMLNode_GetChild(node);
03074 while (n) {
03075 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
03076 const char *type;
03077
03078 if (GWEN_Buffer_GetBytesLeft(msgbuf)==0)
03079 break;
03080
03081 type=GWEN_XMLNode_GetData(n);
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091 if (strcasecmp(type, "ELEM")==0) {
03092 unsigned int loopNr;
03093
03094
03095 minsize=atoi(GWEN_XMLNode_GetProperty(n, "minsize","0"));
03096 maxsize=atoi(GWEN_XMLNode_GetProperty(n, "maxsize","0"));
03097 minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum","1"));
03098 maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum","1"));
03099 name=GWEN_XMLNode_GetProperty(n, "name", 0);
03100
03101 loopNr=0;
03102 abortLoop=0;
03103 while((maxnum==0 || loopNr<maxnum) && !abortLoop) {
03104 int c;
03105
03106 DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading %s", name);
03107 if (GWEN_Buffer_GetBytesLeft(msgbuf)==0)
03108 break;
03109 c=GWEN_Buffer_PeekByte(msgbuf);
03110 if (c==-1) {
03111 DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
03112 GWEN_Buffer_free(delimBuffer);
03113 return -1;
03114 }
03115
03116 DBG_VERBOUS(GWEN_LOGDOMAIN,
03117 "Checking delimiter at pos %x "
03118 "(whether \"%c\" is in \"%s\")",
03119 GWEN_Buffer_GetPos(msgbuf),
03120 c, GWEN_Buffer_GetStart(delimBuffer));
03121 if (c && strchr(GWEN_Buffer_GetStart(delimBuffer), c)) {
03122 abortLoop=1;
03123 DBG_VERBOUS(GWEN_LOGDOMAIN,
03124 "Found delimiter (\"%c\" is in \"%s\")",
03125 c, GWEN_Buffer_GetStart(delimBuffer));
03126 }
03127 else {
03128
03129 if (name==0) {
03130 DBG_VERBOUS(GWEN_LOGDOMAIN, "no name");
03131 }
03132 else {
03133
03134 int rv;
03135 const char *dtype;
03136 GWEN_BUFFER *vbuf;
03137
03138 DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading value from pos %x",
03139 GWEN_Buffer_GetPos(msgbuf));
03140 vbuf=GWEN_Buffer_new(0,
03141 GWEN_MSGENGINE_MAX_VALUE_LEN,
03142 0,0);
03143
03144
03145
03146
03147
03148
03149 rv=GWEN_MsgEngine__ReadValue(e,
03150 msgbuf,
03151 n,
03152 rnode,
03153 vbuf,
03154 GWEN_Buffer_GetStart(delimBuffer),
03155
03156 flags);
03157 if (rv==1) {
03158 DBG_INFO(GWEN_LOGDOMAIN, "Empty value");
03159 }
03160 else if (rv==-1) {
03161 DBG_INFO(GWEN_LOGDOMAIN, "Error parsing node \"%s\" (%s)",
03162 name,
03163 type);
03164 GWEN_Buffer_free(vbuf);
03165 GWEN_Buffer_free(delimBuffer);
03166 return -1;
03167 }
03168
03169 GWEN_Buffer_Rewind(vbuf);
03170
03171
03172 dtype=GWEN_XMLNode_GetProperty(n, "type", "");
03173 if (GWEN_MsgEngine__IsBinTyp(e, dtype)) {
03174 if (atoi(GWEN_XMLNode_GetProperty(n, "readbin", "1")) &&
03175 e->binTypeReadPtr) {
03176 rv=e->binTypeReadPtr(e, n, gr, vbuf);
03177 }
03178 else
03179 rv=1;
03180 if (rv==-1) {
03181 DBG_INFO(GWEN_LOGDOMAIN, "Called from here");
03182 GWEN_Buffer_free(vbuf);
03183 GWEN_Buffer_free(delimBuffer);
03184 return -1;
03185 }
03186 else if (rv==1) {
03187
03188 if (GWEN_DB_SetBinValue(gr,
03189 GWEN_DB_FLAGS_DEFAULT,
03190 name,
03191 GWEN_Buffer_GetStart(vbuf),
03192 GWEN_Buffer_GetUsedBytes(vbuf))) {
03193 DBG_INFO(GWEN_LOGDOMAIN, "Could not set value for \"%s\"", name);
03194 GWEN_Buffer_free(vbuf);
03195 GWEN_Buffer_free(delimBuffer);
03196 return -1;
03197 }
03198 }
03199 }
03200 else if (GWEN_MsgEngine__IsIntTyp(e, dtype)) {
03201 int z;
03202
03203 if (1!=sscanf(GWEN_Buffer_GetStart(vbuf), "%d", &z)) {
03204 DBG_INFO(GWEN_LOGDOMAIN, "Value for \"%s\" is not an integer",
03205 name);
03206 GWEN_Buffer_free(delimBuffer);
03207 return -1;
03208 }
03209 if (GWEN_DB_SetIntValue(gr,
03210 GWEN_DB_FLAGS_DEFAULT,
03211 name, z)) {
03212 DBG_INFO(GWEN_LOGDOMAIN, "Could not set int value for \"%s\"", name);
03213 GWEN_Buffer_free(delimBuffer);
03214 return -1;
03215 }
03216 }
03217 else {
03218 DBG_DEBUG(GWEN_LOGDOMAIN, "Value is \"%s\"",
03219 GWEN_Buffer_GetStart(vbuf));
03220 if (GWEN_DB_SetCharValue(gr,
03221 GWEN_DB_FLAGS_DEFAULT,
03222 name,
03223 GWEN_Buffer_GetStart(vbuf))){
03224 DBG_INFO(GWEN_LOGDOMAIN, "Could not set value for \"%s\"", name);
03225 GWEN_Buffer_free(delimBuffer);
03226 return -1;
03227 }
03228 }
03229
03230 GWEN_Buffer_free(vbuf);
03231 }
03232 }
03233
03234 if (GWEN_Buffer_GetBytesLeft(msgbuf)) {
03235 if (delimiter) {
03236 if (GWEN_Buffer_PeekByte(msgbuf)==delimiter) {
03237 GWEN_Buffer_IncrementPos(msgbuf,1);
03238 }
03239 }
03240 }
03241 loopNr++;
03242 }
03243 if (loopNr<minnum) {
03244 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (too few ELEM repeats)");
03245 GWEN_XMLNode_Dump(n, stderr, 2);
03246 GWEN_Buffer_free(delimBuffer);
03247 return -1;
03248 }
03249 n=GWEN_XMLNode_Next(n);
03250 }
03251 else if (strcasecmp(type, "VALUES")==0) {
03252 n=GWEN_XMLNode_Next(n);
03253 }
03254 else if (strcasecmp(type, "DESCR")==0) {
03255 n=GWEN_XMLNode_Next(n);
03256 }
03257 else {
03258
03259 GWEN_XMLNODE *gn;
03260 GWEN_DB_NODE *gcfg;
03261 const char *gname;
03262 const char *gtype;
03263 unsigned int gversion;
03264 unsigned int loopNr;
03265
03266 minnum=atoi(GWEN_XMLNode_GetProperty(n, "minnum","1"));
03267 maxnum=atoi(GWEN_XMLNode_GetProperty(n, "maxnum","1"));
03268 gversion=atoi(GWEN_XMLNode_GetProperty(n, "version","0"));
03269 gtype=GWEN_XMLNode_GetProperty(n, "type",0);
03270 if (!gtype) {
03271
03272 DBG_INFO(GWEN_LOGDOMAIN, "<%s> tag has no \"type\" property", type);
03273 gtype="";
03274 gn=n;
03275 }
03276 else {
03277 gn=GWEN_MsgEngine_FindNodeByProperty(e, type, "id",
03278 gversion, gtype);
03279 if (!gn) {
03280 DBG_INFO(GWEN_LOGDOMAIN, "Definition for type \"%s\" not found", type);
03281 GWEN_Buffer_free(delimBuffer);
03282 return -1;
03283 }
03284 }
03285
03286
03287 loopNr=0;
03288 abortLoop=0;
03289 while((maxnum==0 || loopNr<maxnum) && !abortLoop) {
03290 int c;
03291
03292 DBG_DEBUG(GWEN_LOGDOMAIN, "Reading group type %s", gtype);
03293 if (GWEN_Buffer_GetBytesLeft(msgbuf)==0)
03294 break;
03295 c=GWEN_Buffer_PeekByte(msgbuf);
03296 if (c && strchr(GWEN_Buffer_GetStart(delimBuffer), c)) {
03297 abortLoop=1;
03298 }
03299 else {
03300 gname=GWEN_XMLNode_GetProperty(n, "name",0);
03301 if (gname) {
03302 DBG_DEBUG(GWEN_LOGDOMAIN, "Creating group \"%s\"", gname);
03303 gcfg=GWEN_DB_GetGroup(gr,
03304 GWEN_PATH_FLAGS_CREATE_GROUP,
03305 gname);
03306 if (!gcfg) {
03307 DBG_ERROR(GWEN_LOGDOMAIN, "Could not select group \"%s\"",
03308 gname);
03309 GWEN_Buffer_free(delimBuffer);
03310 return -1;
03311 }
03312 DBG_DEBUG(GWEN_LOGDOMAIN, "Created group \"%s\"", gname);
03313 }
03314 else
03315 gcfg=gr;
03316
03317
03318 DBG_DEBUG(GWEN_LOGDOMAIN, "Reading group \"%s\"", gname);
03319 if (GWEN_MsgEngine__ReadGroup(e,
03320 msgbuf,
03321 gn,
03322 n,
03323 gcfg,
03324 GWEN_Buffer_GetStart(delimBuffer),
03325 flags)) {
03326 DBG_INFO(GWEN_LOGDOMAIN, "Could not read group \"%s\"", gtype);
03327 GWEN_Buffer_free(delimBuffer);
03328 return -1;
03329 }
03330 }
03331 if (GWEN_Buffer_GetBytesLeft(msgbuf)) {
03332 if (delimiter) {
03333 if (GWEN_Buffer_PeekByte(msgbuf)==delimiter) {
03334 GWEN_Buffer_IncrementPos(msgbuf, 1);
03335 }
03336 }
03337 }
03338 loopNr++;
03339 }
03340 if (loopNr<minnum) {
03341 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (too few group repeats)");
03342 GWEN_Buffer_free(delimBuffer);
03343 return -1;
03344 }
03345 n=GWEN_XMLNode_Next(n);
03346 }
03347 }
03348 else {
03349 n=GWEN_XMLNode_Next(n);
03350 }
03351 }
03352
03353
03354 while(n) {
03355 if (GWEN_XMLNode_GetType(n)==GWEN_XMLNodeTypeTag) {
03356 if (strcasecmp(GWEN_XMLNode_GetData(n), "ELEM")==0 ||
03357 strcasecmp(GWEN_XMLNode_GetData(n), "GROUP")==0) {
03358 unsigned int i;
03359
03360 i=atoi(GWEN_XMLNode_GetProperty(n, "minnum", "1"));
03361 if (i) {
03362 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (still tags to parse)");
03363 GWEN_XMLNode_Dump(n, stderr, 2);
03364 GWEN_Buffer_free(delimBuffer);
03365 return -1;
03366 }
03367 }
03368 }
03369 n=GWEN_XMLNode_Next(n);
03370 }
03371
03372
03373 if (terminator) {
03374
03375 if (GWEN_Buffer_GetBytesLeft(msgbuf)) {
03376 if (GWEN_Buffer_PeekByte(msgbuf)==terminator) {
03377 GWEN_Buffer_IncrementPos(msgbuf, 1);
03378 }
03379 else {
03380 DBG_ERROR(GWEN_LOGDOMAIN,
03381 "Terminating character missing (pos=%d [%x]) "
03382 "expecting \"%c\", got \"%c\")",
03383 GWEN_Buffer_GetPos(msgbuf),
03384 GWEN_Buffer_GetPos(msgbuf),
03385 terminator,
03386 GWEN_Buffer_PeekByte(msgbuf));
03387 GWEN_XMLNode_Dump(node, stderr, 1);
03388 GWEN_Buffer_free(delimBuffer);
03389 return -1;
03390 }
03391 }
03392 else {
03393 DBG_ERROR(GWEN_LOGDOMAIN, "Terminating character missing");
03394 GWEN_Buffer_free(delimBuffer);
03395 return -1;
03396 }
03397 }
03398
03399 GWEN_Buffer_free(delimBuffer);
03400 return 0;
03401 }
03402
03403
03404
03405 int GWEN_MsgEngine_ParseMessage(GWEN_MSGENGINE *e,
03406 GWEN_XMLNODE *group,
03407 GWEN_BUFFER *msgbuf,
03408 GWEN_DB_NODE *msgData,
03409 uint32_t flags){
03410
03411 if (GWEN_MsgEngine__ReadGroup(e,
03412 msgbuf,
03413 group,
03414 0,
03415 msgData,
03416 e->delimiters,
03417 flags)) {
03418 DBG_INFO(GWEN_LOGDOMAIN, "Error reading group");
03419 return -1;
03420 }
03421
03422 return 0;
03423 }
03424
03425
03426
03427 int GWEN_MsgEngine_SetValue(GWEN_MSGENGINE *e,
03428 const char *path,
03429 const char *value){
03430 GWEN_DB_NODE *globalValues;
03431
03432 assert(e);
03433 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
03434 assert(globalValues);
03435 return GWEN_DB_SetCharValue(globalValues,
03436 GWEN_DB_FLAGS_DEFAULT |
03437 GWEN_DB_FLAGS_OVERWRITE_VARS,
03438 path, value);
03439 }
03440
03441
03442
03443 int GWEN_MsgEngine_SetIntValue(GWEN_MSGENGINE *e,
03444 const char *path,
03445 int value){
03446 GWEN_DB_NODE *globalValues;
03447
03448 assert(e);
03449 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
03450 assert(globalValues);
03451 return GWEN_DB_SetIntValue(globalValues,
03452 GWEN_DB_FLAGS_DEFAULT |
03453 GWEN_DB_FLAGS_OVERWRITE_VARS,
03454 path, value);
03455 }
03456
03457
03458
03459 const char *GWEN_MsgEngine_GetValue(GWEN_MSGENGINE *e,
03460 const char *path,
03461 const char *defValue){
03462 GWEN_DB_NODE *globalValues;
03463
03464 assert(e);
03465 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
03466 assert(globalValues);
03467 return GWEN_DB_GetCharValue(globalValues,
03468 path, 0, defValue);
03469 }
03470
03471
03472
03473 int GWEN_MsgEngine_GetIntValue(GWEN_MSGENGINE *e,
03474 const char *path,
03475 int defValue){
03476 GWEN_DB_NODE *globalValues;
03477
03478 assert(e);
03479 globalValues=GWEN_MsgEngine__GetGlobalValues(e);
03480 assert(globalValues);
03481 return GWEN_DB_GetIntValue(globalValues,
03482 path, 0, defValue);
03483 }
03484
03485
03486
03487
03488 int GWEN_MsgEngine_SkipSegment(GWEN_MSGENGINE *e,
03489 GWEN_BUFFER *msgbuf,
03490 unsigned char escapeChar,
03491 unsigned char delimiter) {
03492 int esc;
03493
03494 esc=0;
03495 while(GWEN_Buffer_GetBytesLeft(msgbuf)) {
03496 if (esc) {
03497 esc=0;
03498 }
03499 else {
03500 int i;
03501 unsigned char c;
03502
03503 i=GWEN_Buffer_ReadByte(msgbuf);
03504 if (i==-1) {
03505 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
03506 return 0;
03507 }
03508 c=(unsigned int)i;
03509 if (c==escapeChar) {
03510 esc=1;
03511 }
03512 else if (c=='@') {
03513
03514 char lbuffer[16];
03515 char *p;
03516 int l;
03517 int nc;
03518
03519 p=lbuffer;
03520 while(1) {
03521 nc=GWEN_Buffer_ReadByte(msgbuf);
03522 if (nc==-1) {
03523 DBG_ERROR(GWEN_LOGDOMAIN, "\"@num@\" expected");
03524 return -1;
03525 }
03526 if (nc=='@')
03527 break;
03528 *p=nc;
03529 p++;
03530 }
03531 *p=0;
03532 if (sscanf(lbuffer, "%d", &l)!=1) {
03533 DBG_ERROR(GWEN_LOGDOMAIN, "Bad number format");
03534 return -1;
03535 }
03536 if (GWEN_Buffer_GetUsedBytes(msgbuf)-GWEN_Buffer_GetPos(msgbuf)
03537 < (unsigned) l) {
03538 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of message (binary beyond end)");
03539 return -1;
03540 }
03541 GWEN_Buffer_IncrementPos(msgbuf, l);
03542 }
03543 else if (c==delimiter) {
03544 return 0;
03545 break;
03546 }
03547 }
03548 }
03549
03550 DBG_ERROR(GWEN_LOGDOMAIN, "End of segment not found");
03551 return -1;
03552 }
03553
03554
03555
03556
03557 int GWEN_MsgEngine_ReadMessage(GWEN_MSGENGINE *e,
03558 const char *gtype,
03559 GWEN_BUFFER *mbuf,
03560 GWEN_DB_NODE *gr,
03561 uint32_t flags) {
03562 unsigned int segments;
03563
03564 segments=0;
03565
03566 while(GWEN_Buffer_GetBytesLeft(mbuf)) {
03567 GWEN_XMLNODE *node;
03568 unsigned int posBak;
03569 const char *p;
03570 GWEN_DB_NODE *tmpdb;
03571 int segVer;
03572
03573
03574 tmpdb=GWEN_DB_Group_new("tmpdb");
03575 node=GWEN_MsgEngine_FindGroupByProperty(e,
03576 "id",
03577 0,
03578 "SegHead");
03579 if (node==0) {
03580 DBG_ERROR(GWEN_LOGDOMAIN, "Segment description not found");
03581 GWEN_DB_Group_free(tmpdb);
03582 return -1;
03583 }
03584
03585
03586 posBak=GWEN_Buffer_GetPos(mbuf);
03587 if (GWEN_MsgEngine_ParseMessage(e,
03588 node,
03589 mbuf,
03590 tmpdb,
03591 flags)) {
03592 DBG_ERROR(GWEN_LOGDOMAIN, "Error parsing segment head");
03593 GWEN_DB_Group_free(tmpdb);
03594 return -1;
03595 }
03596
03597
03598 segVer=GWEN_DB_GetIntValue(tmpdb,
03599 "version",
03600 0,
03601 0);
03602 p=GWEN_DB_GetCharValue(tmpdb,
03603 "code",
03604 0,
03605 0);
03606 if (!p) {
03607 DBG_ERROR(GWEN_LOGDOMAIN, "No segment code for %s ? This seems to be a bad msg...",
03608 gtype);
03609 GWEN_Buffer_SetPos(mbuf, posBak);
03610 DBG_ERROR(GWEN_LOGDOMAIN, "Full message (pos=%04x)", posBak);
03611 GWEN_Text_DumpString(GWEN_Buffer_GetStart(mbuf),
03612 GWEN_Buffer_GetUsedBytes(mbuf),
03613 stderr, 1);
03614 GWEN_DB_Dump(tmpdb, stderr, 1);
03615 GWEN_DB_Group_free(tmpdb);
03616 return -1;
03617 }
03618
03619
03620 node=GWEN_MsgEngine_FindNodeByProperty(e,
03621 gtype,
03622 "code",
03623 segVer,
03624 p);
03625 if (node==0) {
03626 unsigned int ustart;
03627
03628 ustart=GWEN_Buffer_GetPos(mbuf);
03629 ustart++;
03630
03631
03632 DBG_NOTICE(GWEN_LOGDOMAIN,
03633 "Unknown segment \"%s\" (Segnum=%d, version=%d, ref=%d)",
03634 p,
03635 GWEN_DB_GetIntValue(tmpdb, "seq", 0, -1),
03636 GWEN_DB_GetIntValue(tmpdb, "version", 0, -1),
03637 GWEN_DB_GetIntValue(tmpdb, "ref", 0, -1));
03638 if (GWEN_MsgEngine_SkipSegment(e, mbuf, '?', '\'')) {
03639 DBG_ERROR(GWEN_LOGDOMAIN, "Error skipping segment \"%s\"", p);
03640 GWEN_DB_Group_free(tmpdb);
03641 return -1;
03642 }
03643 if (flags & GWEN_MSGENGINE_READ_FLAGS_TRUSTINFO) {
03644 unsigned int usize;
03645
03646 usize=GWEN_Buffer_GetPos(mbuf)-ustart-1;
03647 #if 0
03648 GWEN_Text_DumpString(GWEN_Buffer_GetStart(mbuf)+ustart,
03649 usize,
03650 stderr, 1);
03651 #endif
03652 if (GWEN_MsgEngine_AddTrustInfo(e,
03653 GWEN_Buffer_GetStart(mbuf)+ustart,
03654 usize,
03655 p,
03656 GWEN_MsgEngineTrustLevelHigh,
03657 ustart)) {
03658 DBG_INFO(GWEN_LOGDOMAIN, "called from here");
03659 GWEN_DB_Group_free(tmpdb);
03660 return -1;
03661 }
03662 }
03663 }
03664 else {
03665
03666
03667 const char *id;
03668 GWEN_DB_NODE *storegrp;
03669 unsigned int startPos;
03670
03671
03672
03673 GWEN_Buffer_SetPos(mbuf, posBak);
03674
03675
03676 id=GWEN_XMLNode_GetProperty(node, "id", p);
03677 storegrp=GWEN_DB_GetGroup(gr,
03678 GWEN_PATH_FLAGS_CREATE_GROUP,
03679 id);
03680 assert(storegrp);
03681
03682
03683 startPos=GWEN_Buffer_GetPos(mbuf);
03684 GWEN_DB_SetIntValue(storegrp,
03685 GWEN_DB_FLAGS_OVERWRITE_VARS,
03686 "segment/pos",
03687 startPos);
03688
03689
03690 if (GWEN_MsgEngine_ParseMessage(e,
03691 node,
03692 mbuf,
03693 storegrp,
03694 flags)) {
03695 DBG_ERROR(GWEN_LOGDOMAIN, "Error parsing segment \"%s\" at %d (%x)",
03696 p,
03697 GWEN_Buffer_GetPos(mbuf)-startPos,
03698 GWEN_Buffer_GetPos(mbuf)-startPos);
03699 GWEN_Text_DumpString(GWEN_Buffer_GetStart(mbuf)+startPos,
03700 GWEN_Buffer_GetUsedBytes(mbuf)-startPos,
03701 stderr, 1);
03702 DBG_ERROR(GWEN_LOGDOMAIN, "Stored data so far:");
03703 GWEN_DB_Dump(storegrp, stderr, 2);
03704 GWEN_DB_Group_free(tmpdb);
03705 return -1;
03706 }
03707
03708
03709 GWEN_DB_SetIntValue(storegrp,
03710 GWEN_DB_FLAGS_OVERWRITE_VARS,
03711 "segment/length",
03712 GWEN_Buffer_GetPos(mbuf)-startPos);
03713 segments++;
03714 }
03715 GWEN_DB_Group_free(tmpdb);
03716 }
03717
03718
03719 if (segments) {
03720 DBG_DEBUG(GWEN_LOGDOMAIN, "Parsed %d segments", segments);
03721 return 0;
03722 }
03723 else {
03724 DBG_INFO(GWEN_LOGDOMAIN, "No segments parsed.");
03725 return 1;
03726 }
03727 }
03728
03729
03730
03731
03732
03733
03734
03735
03736 GWEN_MSGENGINE_TRUSTEDDATA*
03737 GWEN_MsgEngine_TrustedData_new(const char *data,
03738 unsigned int size,
03739 const char *description,
03740 GWEN_MSGENGINE_TRUSTLEVEL trustLevel){
03741 GWEN_MSGENGINE_TRUSTEDDATA *td;
03742
03743 assert(data);
03744 assert(size);
03745 GWEN_NEW_OBJECT(GWEN_MSGENGINE_TRUSTEDDATA, td);
03746 td->data=(char*)malloc(size);
03747 assert(td->data);
03748 memmove(td->data, data, size);
03749 if (description)
03750 td->description=strdup(description);
03751 td->trustLevel=trustLevel;
03752 td->size=size;
03753 return td;
03754 }
03755
03756
03757
03758 void GWEN_MsgEngine_TrustedData_free(GWEN_MSGENGINE_TRUSTEDDATA *td){
03759 if (td) {
03760 free(td->data);
03761 free(td->description);
03762 free(td->replacement);
03763 GWEN_FREE_OBJECT(td);
03764 }
03765 }
03766
03767
03768
03769 GWEN_MSGENGINE_TRUSTEDDATA*
03770 GWEN_MsgEngine_TrustedData_GetNext(GWEN_MSGENGINE_TRUSTEDDATA *td){
03771 assert(td);
03772 return td->next;
03773 }
03774
03775
03776
03777 const char*
03778 GWEN_MsgEngine_TrustedData_GetData(GWEN_MSGENGINE_TRUSTEDDATA *td){
03779 assert(td);
03780 return td->data;
03781 }
03782
03783
03784
03785 unsigned int
03786 GWEN_MsgEngine_TrustedData_GetSize(GWEN_MSGENGINE_TRUSTEDDATA *td){
03787 assert(td);
03788 return td->size;
03789 }
03790
03791
03792
03793 const char*
03794 GWEN_MsgEngine_TrustedData_GetDescription(GWEN_MSGENGINE_TRUSTEDDATA *td){
03795 assert(td);
03796 return td->description;
03797 }
03798
03799
03800
03801 GWEN_MSGENGINE_TRUSTLEVEL
03802 GWEN_MsgEngine_TrustedData_GetTrustLevel(GWEN_MSGENGINE_TRUSTEDDATA *td){
03803 assert(td);
03804 return td->trustLevel;
03805 }
03806
03807
03808
03809 const char*
03810 GWEN_MsgEngine_TrustedData_GetReplacement(GWEN_MSGENGINE_TRUSTEDDATA *td){
03811 assert(td);
03812 return td->replacement;
03813 }
03814
03815
03816
03817 int GWEN_MsgEngine_TrustedData_AddPos(GWEN_MSGENGINE_TRUSTEDDATA *td,
03818 unsigned int pos){
03819 assert(td);
03820 if (td->posCount>=GWEN_MSGENGINE_TRUSTEDDATA_MAXPOS)
03821 return -1;
03822 td->positions[td->posCount++]=pos;
03823 return 0;
03824 }
03825
03826
03827
03828 int GWEN_MsgEngine_TrustedData_GetFirstPos(GWEN_MSGENGINE_TRUSTEDDATA *td){
03829 assert(td);
03830 td->posPointer=0;
03831 return GWEN_MsgEngine_TrustedData_GetNextPos(td);
03832 }
03833
03834
03835
03836 int GWEN_MsgEngine_TrustedData_GetNextPos(GWEN_MSGENGINE_TRUSTEDDATA *td){
03837 assert(td);
03838 if (td->posPointer>=td->posCount)
03839 return -1;
03840 return td->positions[td->posPointer++];
03841 }
03842
03843
03844
03845 int
03846 GWEN_MsgEngine_TrustedData_CreateReplacements(GWEN_MSGENGINE_TRUSTEDDATA
03847 *td){
03848 unsigned int nextNr;
03849 GWEN_MSGENGINE_TRUSTEDDATA *ntd;
03850 unsigned int count;
03851
03852 assert(td);
03853 count=0;
03854 ntd=td;
03855 while(ntd) {
03856 count++;
03857 ntd=ntd->next;
03858 }
03859
03860 if (count<0x10)
03861 nextNr=0x01;
03862 else
03863 nextNr=0x11;
03864
03865 ntd=td;
03866 while(ntd) {
03867 unsigned int i;
03868 char numbuffer[32];
03869 char *rp;
03870 GWEN_MSGENGINE_TRUSTEDDATA *std;
03871 int match;
03872
03873
03874 std=td;
03875 match=0;
03876 while(std && std!=ntd) {
03877
03878 match=1;
03879 if (std->size==ntd->size) {
03880 unsigned int i;
03881
03882 for (i=0; i<td->size; i++) {
03883 if (std->data[i]!=ntd->data[i]) {
03884 match=0;
03885 break;
03886 }
03887 }
03888 }
03889 else
03890 match=0;
03891
03892 if (match)
03893 break;
03894 std=std->next;
03895 }
03896
03897 if (match) {
03898
03899 rp=strdup(std->replacement);
03900 }
03901 else {
03902
03903 rp=(char*)malloc(ntd->size+1);
03904 assert(rp);
03905
03906 if (ntd->size==1) {
03907 if (count>=0x10)
03908 nextNr+=0x10;
03909 }
03910 sprintf(numbuffer, "%02X", nextNr++);
03911 for (i=0; i<ntd->size; i++) {
03912 if (count<0x10)
03913 rp[i]=numbuffer[1];
03914 else
03915 rp[i]=numbuffer[1-(i&1)];
03916 }
03917 rp[i]=0;
03918 }
03919
03920
03921
03922
03923
03924 free(ntd->replacement);
03925 ntd->replacement=rp;
03926
03927 ntd=ntd->next;
03928 }
03929 return 0;
03930 }
03931
03932
03933
03934 GWEN_MSGENGINE_TRUSTEDDATA *GWEN_MsgEngine_TakeTrustInfo(GWEN_MSGENGINE *e){
03935 GWEN_MSGENGINE_TRUSTEDDATA *td;
03936
03937 assert(e);
03938 td=e->trustInfos;
03939 e->trustInfos=0;
03940 return td;
03941 }
03942
03943
03944
03945
03946 int GWEN_MsgEngine_AddTrustInfo(GWEN_MSGENGINE *e,
03947 const char *data,
03948 unsigned int size,
03949 const char *description,
03950 GWEN_MSGENGINE_TRUSTLEVEL trustLevel,
03951 unsigned int pos) {
03952 GWEN_MSGENGINE_TRUSTEDDATA *td;
03953 int match;
03954
03955 assert(e);
03956 assert(data);
03957 assert(size);
03958
03959 if (!description)
03960 description="";
03961
03962 td=e->trustInfos;
03963 while(td) {
03964 unsigned int i;
03965
03966
03967 if (td->size==size &&
03968 *description &&
03969 *(td->description) &&
03970 trustLevel==td->trustLevel &&
03971 strcasecmp(description, td->description)==0) {
03972 match=1;
03973 for (i=0; i<td->size; i++) {
03974 if (td->data[i]!=data[i]) {
03975 match=0;
03976 break;
03977 }
03978 }
03979 }
03980 else
03981 match=0;
03982
03983 if (match)
03984 break;
03985 td=td->next;
03986 }
03987
03988 if (!td) {
03989 DBG_INFO(GWEN_LOGDOMAIN, "Creating new trustInfo for \"%s\" (%d)",
03990 description, size);
03991 td=GWEN_MsgEngine_TrustedData_new(data,
03992 size,
03993 description,
03994 trustLevel);
03995 GWEN_LIST_ADD(GWEN_MSGENGINE_TRUSTEDDATA, td, &(e->trustInfos));
03996 }
03997 else {
03998 DBG_INFO(GWEN_LOGDOMAIN, "Reusing trustInfo for \"%s\" (%d)",
03999 description, size);
04000 }
04001 GWEN_MsgEngine_TrustedData_AddPos(td, pos);
04002 return 0;
04003 }
04004
04005
04006