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