Home | History | Annotate | Download | only in src
      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <stdarg.h>
      4 #include <dlfcn.h>
      5 #include <sys/time.h>
      6 #include <stdio.h>
      7 #include <string.h>
      8 #include "dmt.hpp"
      9 //#include "dm_security.h"
     10 #include "dmVersion.h"
     11 #include "xpl_dm_Manager.h"
     12 
     13 extern "C" int MultiProcessTest( void );
     14 
     15 using namespace std;
     16 static const char* c_szErrorText = "\033[31mError!\033[0m";
     17 
     18 static DmtPrincipal principal("localhost");
     19 static PDmtTree ptrTree;
     20 static PDmtErrorDescription e;
     21 static DMString s_strRootPath = "";
     22 
     23 static DMString s_strCurLine;
     24 static bool s_bDone = false;
     25 static bool s_bAtomic = false;
     26 static bool s_bShowTimestamp = false;
     27 static bool s_bAutoReleaseTree = true;
     28 static bool s_bShowProfileTime = false;
     29 static int counter = 0;
     30 static bool countTestCase = false;
     31 
     32 //helper class for profiling
     33 struct TestProfile
     34 {
     35   TestProfile( const char* sHeader )
     36   {
     37     gettimeofday( &m_tvStart, NULL );
     38     m_szHeader = sHeader;
     39 
     40   }
     41   ~TestProfile()
     42   {
     43     struct timeval  tv2;
     44     gettimeofday( &tv2, NULL );
     45     long long n1 = m_tvStart.tv_usec + (m_tvStart.tv_sec * 1000000 );
     46     long long n2 = tv2.tv_usec + (tv2.tv_sec * 1000000 );
     47     long long elapsed = n2 - n1;
     48 
     49     if ( s_bShowProfileTime )
     50       printf( "DMProfile: %s, time is %d.%d ms\n", m_szHeader.c_str(), (int)(elapsed/1000), (int)(elapsed%1000/100)  );
     51   }
     52 
     53   DMString m_szHeader;
     54   struct timeval  m_tvStart;
     55 };
     56 
     57 static void Error(char *fmt, ...)
     58 {
     59     va_list argp;
     60     va_start(argp, fmt);
     61     if ( e.GetErrorCode() == SYNCML_DM_SUCCESS)
     62       return;
     63     printf("%s ", c_szErrorText);
     64     vprintf(fmt, argp);
     65     printf(", DmtException: %d\n", e->GetErrorCode() );
     66 }
     67 
     68 static DMString GetLine()
     69 {
     70     DMString s = "";
     71     int nC;
     72     while ( (nC = getchar() ) != EOF )
     73     {
     74         if ( nC == '\r' || nC == '\n') {
     75             return s;
     76         }
     77         char sz[2] = {nC, 0};
     78         s += sz;
     79     }
     80 
     81     s_bDone = true;
     82     return s;
     83 }
     84 
     85 static BOOLEAN StrToBin(DMString &binStr, INT32 *len)
     86 {
     87 	char *pivot_w;
     88 	char *pivot_r;
     89 	char digits[4];
     90 	UINT8 vbin;
     91 	INT32 i;
     92 
     93 	*len = binStr.length();
     94 	if (*len  & 1 )
     95 	{
     96 		printf("Error Input: Uneven string length.\n");
     97 		return FALSE;
     98 	}
     99 	*len >>= 1;
    100 	pivot_w = binStr.GetBuffer();
    101 
    102 
    103 	pivot_r = pivot_w;
    104 	digits[3] = '\0';
    105 	for (i=0; i<*len; i++)
    106 	{
    107 		strncpy(digits, pivot_r, 2);
    108 		sscanf(digits, "%x", &vbin);
    109 		pivot_w[i] = vbin;
    110 		pivot_r += 2;
    111 	}
    112 
    113 	return TRUE;
    114 }
    115 
    116 static DMString ConvertEscape(DMString strInput)
    117 {
    118     DMString s;
    119     const char* szBuf = strInput.c_str();
    120     char ch;
    121     unsigned int code;
    122 
    123     while (true) {
    124         ch = szBuf[0];
    125         if (ch == '\\') {
    126             szBuf++;
    127             ch = szBuf[0];
    128             if (ch == 't') {
    129                 code = '\t';
    130             } else if (ch == 'r') {
    131                 code = '\r';
    132             } else if (ch == 'n') {
    133                 code = '\n';
    134             } else if (ch == 'f') {
    135                 code = '\f';
    136             } else if (ch == 'x') {
    137                 code = 0;
    138                 for (int i = 0; i < 2; i++) {
    139                     szBuf++;
    140                     ch = szBuf[0];
    141                     switch (ch) {
    142                         case '0': case '1': case '2': case '3':
    143                         case '4': case '5': case '6': case '7':
    144                         case '8': case '9':
    145                             code = (code << 4) + (ch - '0');
    146                             break;
    147                         case 'a': case 'b': case 'c': case 'd':
    148                         case 'e': case 'f':
    149                             code = (code << 4) + (ch - 'a' + 10);
    150                             break;
    151                         case 'A': case 'B': case 'C': case 'D':
    152                         case 'E': case 'F':
    153                             code = (code << 4) + (ch - 'A' + 10);
    154                             break;
    155                         default:
    156                             printf("%s malformed \\xXX encoding.\n", c_szErrorText);
    157                             return "";
    158                     }
    159                 }
    160             } else {
    161                 code = ch;
    162             }
    163         } else {
    164             code = ch;
    165         }
    166 
    167         if (code <= 0) {
    168             break;
    169         } else if (code > 0 && code <= 0xFF) {
    170             char sz[2] = { (char)code, 0 };
    171             s += sz;
    172         } else {
    173             printf("%s in input string: %x.\n", c_szErrorText, code);
    174             return "";
    175         }
    176         szBuf++;
    177     }
    178     return s;
    179 }
    180 
    181 static DMString GetParam()
    182 {
    183   DMString s;
    184 
    185   const char* szBuf = s_strCurLine.c_str();
    186 
    187   while ( szBuf[0] == ' ' )
    188     szBuf++;
    189 
    190   bool bEscaped = false;
    191   char ch;
    192   while ( true ) {
    193     ch = szBuf[0];
    194     if ( ch == 0 || (!bEscaped && ch == ' ')) {
    195         break;
    196     }
    197     if ( !bEscaped && ch == '\\') {
    198         bEscaped = true;
    199     } else {
    200         bEscaped = false;
    201     }
    202 
    203     char sz[2] = {ch, 0};
    204     s += sz;
    205     szBuf++;
    206   }
    207 
    208   DMString strTmp = szBuf;
    209   s_strCurLine = strTmp;
    210 
    211   return ConvertEscape(s);
    212 }
    213 
    214 static DMString GetCmd()
    215 {
    216     if (s_bDone) {
    217         return "quit";
    218     }
    219 
    220     if (countTestCase) {
    221       counter++;
    222     }
    223 
    224     s_strCurLine = GetLine();
    225     return GetParam();
    226 }
    227 
    228 static void startCounter()
    229 {
    230   printf("Counter started!\n");
    231   countTestCase = true;
    232 }
    233 
    234 static void endCounter()
    235 {
    236   if (counter > 0)
    237   {
    238     counter--;
    239   }
    240   printf("Counter ended!\n");
    241   countTestCase = false;
    242 }
    243 
    244 static void displayCountStatus()
    245 {
    246   if (counter > 0)
    247   {
    248     counter--;
    249   }
    250   printf("Count is ");
    251   if (countTestCase) {
    252     printf("ON\n");
    253   } else {
    254     printf("OFF\n");
    255   }
    256 }
    257 
    258 static void resetCounter()
    259 {
    260   printf("Counter has reseted!\n");
    261   counter = 0;
    262 }
    263 
    264 static void getCounter()
    265 {
    266   if (counter > 0)
    267   {
    268     counter--;
    269   }
    270   printf("Number of tested cases: %d\n", counter);
    271   return;
    272 }
    273 
    274 
    275 static DMString GetInputString(const char * szPrompt, const char * szDefault)
    276 {
    277     printf("%s (default=%s): ", szPrompt, szDefault);
    278     DMString strIn = GetLine();
    279     printf("get: %s\n", strIn.c_str());
    280     if (strIn == "") {
    281         strIn = szDefault;
    282     }
    283     return ConvertEscape(strIn);
    284 }
    285 
    286 
    287 /**
    288  * Get DM tree to global tree variable (ptrTree)
    289  */
    290 static PDmtTree GetTree()
    291 {
    292   if (ptrTree != NULL) return ptrTree;
    293   if ( (e=DmtTreeFactory::GetSubtree(principal, s_strRootPath.c_str(), ptrTree)) != NULL ) {
    294       Error("can't get tree");
    295   }
    296   return ptrTree;
    297 }
    298 
    299 static  PDmtNode GetNode( const char*  szNodeName )
    300 {
    301   PDmtNode ptrNode;
    302   GetTree();
    303 
    304   if ( ptrTree != NULL ){
    305     if ( (e=ptrTree->GetNode( szNodeName, ptrNode)) != NULL ) {
    306         Error("can't get node %s", szNodeName);
    307 
    308     }
    309   }
    310   return ptrNode;
    311 }
    312 static void printESNChunk(const char * buffer, int size )
    313 {
    314   int offset=0;
    315   int line =0;
    316   while(offset < size)
    317   {
    318   	putchar(buffer[offset++]);
    319 	line++;
    320 	if(line>64)
    321 	{ line =0;
    322 	   printf( "\n");
    323 	}
    324   }
    325    printf( "\n");
    326 }
    327 
    328 static void displayESN(PDmtNode ptrNode)
    329 {
    330    SYNCML_DM_RET_STATUS_T retStatus;
    331    if (ptrNode->IsExternalStorageNode())
    332    {
    333 	   DmtDataChunk chunkData;
    334 	   UINT32 getLen;
    335 	   UINT8 *bufp;
    336 	   retStatus = ptrNode->GetFirstChunk(chunkData);
    337 	   if( retStatus != SYNCML_DM_SUCCESS)
    338 		   return;
    339 	   chunkData.GetReturnLen(getLen);
    340 	   chunkData.GetChunkData(&bufp);  // the chunk data is available
    341 	   while (true)
    342 	   {
    343 		   printESNChunk((const char*)bufp, getLen);
    344 		   if (getLen == 0)
    345 				   break;
    346 		   else
    347 		   {
    348 			   //  save or process the data in *bufp
    349 			   retStatus = ptrNode->GetNextChunk(chunkData);
    350 			   if( retStatus != SYNCML_DM_SUCCESS)
    351 				   return;
    352 			   chunkData.GetReturnLen(getLen);
    353 			   chunkData.GetChunkData(&bufp);
    354 		   }
    355 			}
    356 
    357 	} else {
    358 	   DMString path;
    359 	   ptrNode->GetPath(path);
    360 
    361 	   Error("It's not a External Storage Node \n", path.c_str());
    362     }
    363 }
    364 
    365 static void PrintNode( PDmtNode ptrNode )
    366 {
    367     DmtAttributes oAttr;
    368     DMString path;
    369 
    370     if( (e=ptrNode->GetPath(path)) != NULL )
    371     {
    372       Error("can't get attributes of node %d",  e.GetErrorCode());
    373     }
    374 
    375     if ( (e=ptrNode->GetAttributes( oAttr )) != NULL) {
    376       Error("can't get attributes of node %s",  path.c_str());
    377       return;
    378     }
    379 
    380     DmtData oData;
    381     if (!ptrNode->IsExternalStorageNode())
    382     {
    383     	if ( (e=ptrNode->GetValue( oData )) != NULL ) {
    384 	        Error("can't get value of node %s", path.c_str());
    385       	  return;
    386     	}
    387     }
    388     printf("path=%s\n", (const char*)path.c_str());
    389     printf("isLeaf=%s\n", (ptrNode->IsLeaf()?"true":"false") );
    390     printf("name=%s\n", (const char*)oAttr.GetName().c_str() );
    391     printf("format=%s\n", (const char*)oAttr.GetFormat().c_str() );
    392     printf("type=%s\n", (const char*)oAttr.GetType().c_str() );
    393     printf("title=%s\n", (const char*)oAttr.GetTitle().c_str() );
    394     printf("acl=%s\n", (const char*)oAttr.GetAcl().toString().c_str() );
    395     printf("size=%d\n", (const char*)oAttr.GetSize() );
    396     if ( s_bShowTimestamp ) {
    397         if ( oAttr.GetTimestamp() == 0 ) {
    398             printf("timestamp=(Unknown)\n");
    399         } else {
    400             // convert msec to sec
    401             time_t timestamp = (time_t)(oAttr.GetTimestamp()/1000L);
    402             printf("timestamp=%s", ctime(&timestamp) );
    403         }
    404     }
    405     printf("version=%d\n", oAttr.GetVersion() );
    406     if ( !ptrNode->IsLeaf() ) {
    407       DMStringVector aChildren;
    408       oData.GetNodeValue( aChildren );
    409       printf("children:");
    410       if ( aChildren.size() == 0 ) {
    411           printf("null");
    412       }
    413       for (int i=0; i < aChildren.size(); i++) {
    414           printf("%s/", aChildren[i].c_str());
    415       }
    416       printf("\n");
    417     } else {
    418       if (ptrNode->IsExternalStorageNode())
    419         {
    420           printf("value=\n");
    421           displayESN(ptrNode);
    422         }
    423       else {
    424         if ( strcasecmp(oAttr.GetFormat(), "bin") == 0 ) {
    425           printf("Binary value: [");
    426           for ( int i = 0 ; i < oData.GetBinaryValue().size(); i++ ){
    427             printf( "%02x ", oData.GetBinaryValue().get_data()[i]);
    428           }
    429           printf( "]\n" );
    430         }
    431 	else
    432 	{
    433 		DMString s;
    434 		oData.GetString(s);
    435 		printf("value=%s\n", s.c_str());
    436 	}
    437 
    438 
    439     }
    440 }
    441 }
    442 
    443 static void Get( const char* szNodeName )
    444 {
    445   PDmtNode ptrNode = GetNode( szNodeName );
    446 
    447   if ( ptrNode == NULL )
    448     return;
    449 
    450   PrintNode(ptrNode);
    451 }
    452 
    453 static void CreateInterior( const char * szNode )
    454 {
    455   PDmtNode ptrNode;
    456   GetTree();
    457 
    458   if ( ptrTree == NULL ) {
    459     return;
    460   }
    461 
    462   if ( (e=ptrTree->CreateInteriorNode( szNode, ptrNode )) == NULL ) {
    463     printf( "node %s created successfully\n", szNode );
    464   } else {
    465     Error("can't create a node %s", szNode);
    466   }
    467 }
    468 
    469 static void CreateLeaf( const char * szNode, const char* szData )
    470 {
    471   PDmtNode ptrNode;
    472   GetTree();
    473 
    474   if ( ptrTree == NULL ) {
    475     return;
    476   }
    477 
    478   if ( (e=ptrTree->CreateLeafNode( szNode, ptrNode, DmtData( szData ) )) == NULL ) {
    479     printf( "node %s (%s) created successfully\n", szNode, szData );
    480   } else {
    481     Error("can't create a node %s", szNode);
    482   }
    483 }
    484 
    485 static void CreateLeafInteger( const char * szNode, const char* szData )
    486 {
    487   PDmtNode ptrNode;
    488   GetTree();
    489 
    490   if ( ptrTree == NULL ) {
    491     return;
    492   }
    493 
    494   int intValue = atoi(szData);
    495 
    496   if ( (e=ptrTree->CreateLeafNode( szNode, ptrNode, DmtData( intValue ) )) == NULL ) {
    497     printf( "node %s (%d) created successfully\n", szNode, intValue );
    498   } else {
    499     Error("can't create a node %s", szNode);
    500   }
    501 }
    502 
    503 static void CreateLeafBoolean( const char * szNode, const char* szData )
    504 {
    505   PDmtNode ptrNode;
    506   GetTree();
    507 
    508   if ( ptrTree == NULL ) {
    509     return;
    510   }
    511 
    512   bool bValue = ((strcasecmp(szData, "true") == 0) ? true : false);
    513 
    514   if ( (e=ptrTree->CreateLeafNode( szNode, ptrNode, DmtData( bValue ) )) == NULL ) {
    515     printf( "node %s (%s) created successfully\n",
    516                 szNode, (bValue?"true":"false") );
    517   } else {
    518     Error("can't create a node %s", szNode);
    519   }
    520 }
    521 
    522 
    523 
    524 static void CreateLeafBinary( const char * szNode, const char* szData )
    525 {
    526 	INT32 len;
    527 	DMString binStr = szData;
    528 
    529 	if ( StrToBin( binStr, &len) == FALSE)
    530 		return;
    531 
    532   PDmtNode ptrNode;
    533   GetTree();
    534 
    535   if ( ptrTree == NULL ) {
    536     return;
    537   }
    538 
    539   if ( (e=ptrTree->CreateLeafNode( szNode, ptrNode, DmtData( (const byte*)binStr.c_str(), len ) )) == NULL ) {
    540     printf( "node %s (%s) created successfully\n", szNode, szData );
    541   } else {
    542     Error("can't create a node %s", szNode);
    543   }
    544 }
    545 
    546 static void CreateLeafBinaryE( const char * szNode )
    547 {
    548   PDmtNode ptrNode;
    549   GetTree();
    550 
    551   if ( ptrTree == NULL ) {
    552     return;
    553   }
    554 
    555   if ( (e=ptrTree->CreateLeafNode( szNode, ptrNode, DmtData( ) )) == NULL ) {
    556     printf( "node %s () created successfully\n", szNode );
    557   } else {
    558     Error("can't create a node %s", szNode);
    559   }
    560 }
    561 
    562 
    563 static void CreateLeafFloat( const char * szNode, const char* szData )
    564 {
    565   PDmtNode ptrNode;
    566   GetTree();
    567 
    568   if ( ptrTree == NULL ) {
    569     return;
    570   }
    571 
    572   if ( (e=ptrTree->CreateLeafNode( szNode, ptrNode, DmtData( szData, SYNCML_DM_DATAFORMAT_FLOAT) ) )  == NULL ) {
    573     printf( "node %s (%s) created successfully\n", szNode, szData );
    574   } else {
    575     Error("can't create a node %s", szNode);
    576   }
    577 }
    578 
    579 static void CreateLeafDate( const char * szNode, const char* szData )
    580 {
    581   PDmtNode ptrNode;
    582   GetTree();
    583 
    584   if ( ptrTree == NULL ) {
    585     return;
    586   }
    587 
    588   if ( (e=ptrTree->CreateLeafNode( szNode, ptrNode, DmtData( szData, SYNCML_DM_DATAFORMAT_DATE) ) )  == NULL ) {
    589     printf( "node %s (%s) created successfully\n", szNode, szData );
    590   } else {
    591     Error("can't create a node %s", szNode);
    592   }
    593 }
    594 
    595 static void CreateLeafTime( const char * szNode, const char* szData )
    596 {
    597   PDmtNode ptrNode;
    598   GetTree();
    599 
    600   if ( ptrTree == NULL ) {
    601     return;
    602   }
    603 
    604   if ( (e=ptrTree->CreateLeafNode( szNode, ptrNode, DmtData( szData, SYNCML_DM_DATAFORMAT_TIME) ) )  == NULL ) {
    605     printf( "node %s (%s) created successfully\n", szNode, szData );
    606   } else {
    607     Error("can't create a node %s", szNode);
    608   }
    609 }
    610 
    611 static void Delete(const char* szNode )
    612 {
    613   GetTree();
    614   if ( ptrTree == NULL ) {
    615     return;
    616   }
    617 
    618   if ( (e=ptrTree->DeleteNode( szNode )) == NULL ) {
    619     printf( "node %s deleted successfully\n", szNode );
    620   } else {
    621     Error("can't delete node %s", szNode);
    622   }
    623 }
    624 
    625 static void Rename(const char* szNode, const char* szNewName)
    626 {
    627   GetTree();
    628   if ( ptrTree == NULL ) {
    629       return;
    630   }
    631 
    632   if ( (e=ptrTree->RenameNode( szNode, szNewName )) == NULL ) {
    633     printf( "node %s renamed to %s successfully\n", szNode, szNewName);
    634   } else {
    635     Error("can't rename node %s to %s", szNode, szNewName);
    636   }
    637 }
    638 
    639 static void setESN(const char * szNode, const char * szFile)
    640 {
    641   FILE* f = fopen( szFile, "r" );
    642   if ( !f ) {
    643     printf("%s can't open file %s\n",c_szErrorText, szFile);
    644     return;
    645   }
    646 
    647   // assume 100k is enough
    648   const int c_nSize = 100 * 1024;
    649   char* szBuf = new char [c_nSize];
    650 
    651   int n = fread(szBuf, 1, c_nSize, f );
    652 
    653   printf("read %d bytes\n", n);
    654   if ( n > 0 ) {
    655    SYNCML_DM_RET_STATUS_T retStatus;
    656   PDmtNode ptrNode = GetNode(szNode);
    657   if ( ptrNode == NULL ) {
    658     return;
    659   }
    660 
    661     szBuf[n] = 0;
    662 
    663  if (ptrNode->IsExternalStorageNode())
    664  {
    665 	DmtDataChunk chunkData;
    666 	int setLen = 0;
    667 	int offset = 0;
    668 	bool isFirstChunk = true;
    669 	bool isLastChunk = false;
    670 	int chunksize = chunkData.GetChunkSize();
    671 
    672 	while(!isLastChunk)
    673 	{	setLen =  n - offset;
    674 		if(setLen > 0)
    675 		{
    676 			if(setLen > chunksize)
    677 				setLen = chunksize;
    678 		}
    679 		else
    680 			isLastChunk = true;
    681 
    682 		printESNChunk(&szBuf[offset], setLen);
    683 		chunkData.SetChunkData((const UINT8 *)&szBuf[offset], setLen);
    684 		if(isFirstChunk)
    685 		{
    686 			retStatus = ptrNode->SetFirstChunk(chunkData);
    687 			isFirstChunk = false;
    688 		}
    689 		else
    690 		{	if(!isLastChunk)
    691 				retStatus = ptrNode->SetNextChunk(chunkData);
    692 			else
    693 				retStatus = ptrNode->SetLastChunk(chunkData);
    694 		}
    695 
    696 		offset += setLen;
    697 	}
    698 
    699   } else {
    700     Error("It's not a External Storage Node \n", szNode);
    701   }
    702   }
    703 
    704   delete [] szBuf;
    705   fclose( f );
    706 }
    707 static void SetTitle(const char * szNode, const char * szTitle)
    708 {
    709   PDmtNode ptrNode = GetNode(szNode);
    710   if ( ptrNode == NULL ) {
    711     return;
    712   }
    713 
    714   if ( (e=ptrNode->SetTitle(szTitle)) == NULL ) {
    715     printf("set title of node %s to %s successfully\n",
    716              szNode, szTitle);
    717     PrintNode(ptrNode);
    718   } else {
    719     Error("can't set title of node %s to %s", szNode, szTitle);
    720   }
    721 }
    722 
    723 static void SetAcl(const char * szNode, const char * szAcl)
    724 {
    725   PDmtNode ptrNode = GetNode(szNode);
    726   if (ptrNode == NULL) {
    727       return;
    728   }
    729 
    730   DmtAcl oAcl(szAcl);
    731   if ( (e=ptrNode->SetAcl(oAcl)) == NULL ) {
    732     printf("set acl of node %s to %s successfully\n",
    733              szNode, szAcl);
    734     PrintNode(ptrNode);
    735   } else {
    736     Error("can't set acl of node %s to %s", szNode, szAcl);
    737   }
    738 }
    739 
    740 static void ReplaceString( const char * szNode, const char * szValue)
    741 {
    742     PDmtNode ptrNode = GetNode(szNode);
    743     if (ptrNode == NULL) {
    744         return;
    745     }
    746 
    747     if ( (e=ptrNode->SetStringValue(szValue)) == NULL ) {
    748         printf("set value of node %s to %s successfully\n", szNode, szValue);
    749         PrintNode(ptrNode);
    750     } else {
    751         Error("can't set value of node %s to %s", szNode, szValue);
    752     }
    753 }
    754 
    755 static void ReplaceInteger( const char * szNode, const char * szValue)
    756 {
    757     PDmtNode ptrNode = GetNode(szNode);
    758     if (ptrNode == NULL) {
    759         return;
    760     }
    761     //int intValue = atoi(szValue);
    762     int intValue = 0;
    763     //store the sscanf result;
    764     int int_item_converted = 0;
    765     int_item_converted = sscanf(szValue, "%d", &intValue);
    766     //printf("data is %s \n", szValue);
    767     printf("INT_ITEM_CONVERTED is %d \n", int_item_converted);
    768     if(int_item_converted==0) {
    769         printf("The input %s is not an integer\n", szValue);
    770 	 return;
    771      }
    772     if ( (e=ptrNode->SetIntValue( intValue )) == NULL ) {
    773         printf("set value of node %s to %d successfully\n", szNode, intValue);
    774         PrintNode(ptrNode);
    775     } else {
    776         Error("can't set value of node %s to %d", szNode, intValue);
    777     }
    778 }
    779 
    780 static void ReplaceBoolean( const char * szNode, const char * szValue)
    781 {
    782     PDmtNode ptrNode = GetNode(szNode);
    783     if (ptrNode == NULL) {
    784         return;
    785     }
    786     bool boolValue = ((strcasecmp(szValue, "true") == 0) ? true : false);
    787     if ( (e=ptrNode->SetBooleanValue( boolValue )) == NULL ) {
    788         printf("set value of node %s to %s successfully\n",
    789                 szNode, (boolValue?"true":"false"));
    790         PrintNode(ptrNode);
    791     } else {
    792         Error("can't set value of node %s to %s",
    793                 szNode, (boolValue?"true":"false"));
    794     }
    795 }
    796 
    797 static void ReplaceFloat( const char * szNode, const char * szValue)
    798 {
    799     PDmtNode ptrNode = GetNode(szNode);
    800     if (ptrNode == NULL) {
    801         return;
    802     }
    803 
    804     if ( (e=ptrNode->SetFloatValue( szValue )) == NULL ) {
    805         printf("set value of node %s to %s successfully\n", szNode, szValue);
    806         PrintNode(ptrNode);
    807     } else {
    808         Error("can't set value of node %s to %s", szNode, szValue);
    809     }
    810 }
    811 
    812 static void ReplaceDate( const char * szNode, const char * szValue)
    813 {
    814     PDmtNode ptrNode = GetNode(szNode);
    815     if (ptrNode == NULL) {
    816         return;
    817     }
    818     if ( (e=ptrNode->SetDateValue( szValue )) == NULL ) {
    819         printf("set value of node %s to %s successfully\n", szNode, szValue);
    820         PrintNode(ptrNode);
    821     } else {
    822         Error("can't set value of node %s to %s", szNode, szValue);
    823     }
    824 }
    825 
    826 static void ReplaceTime( const char * szNode, const char * szValue)
    827 {
    828     PDmtNode ptrNode = GetNode(szNode);
    829     if (ptrNode == NULL) {
    830         return;
    831     }
    832 
    833     if ( (e=ptrNode->SetTimeValue( szValue )) == NULL ) {
    834         printf("set value of node %s to %s successfully\n", szNode, szValue);
    835         PrintNode(ptrNode);
    836     } else {
    837         Error("can't set value of node %s to %s", szNode, szValue);
    838     }
    839 }
    840 
    841 static void ReplaceBytes( const char * szNode, const char * szValue)
    842 {
    843 	INT32 len;
    844 	DMString binStr = szValue;
    845 
    846 	if ( StrToBin(binStr, &len) == FALSE)
    847 		return;
    848 
    849     PDmtNode ptrNode = GetNode(szNode);
    850     if (ptrNode == NULL) {
    851         return;
    852     }
    853 
    854     if ( (e=ptrNode->SetBinaryValue( (const byte*)binStr.c_str(), len )) == NULL ) {
    855         printf("set value of node %s to %s successfully\n", szNode, szValue);
    856         PrintNode(ptrNode);
    857     } else {
    858         Error("can't set value of node %s to %s", szNode, szValue);
    859     }
    860 }
    861 
    862 static void DumpSubTree( PDmtNode ptrNode )
    863 {
    864     PrintNode(ptrNode);
    865     printf("\n");
    866     if ( e != NULL ) return;
    867 
    868     if ( !ptrNode->IsLeaf() ) {
    869       DMVector<PDmtNode> aChildren;
    870       if ( (e=ptrNode->GetChildNodes( aChildren )) != NULL ) {
    871         DMString path;
    872         ptrNode->GetPath(path);
    873         Error("can't get child nodes of %s", path.c_str());
    874         return;
    875       }
    876       for (int i=0; i < aChildren.size(); i++) {
    877           DumpSubTree( aChildren[i] );
    878       }
    879     }
    880 }
    881 
    882 static void DumpTree( const char * szNode )
    883 {
    884     PDmtNode ptrNode = GetNode( szNode );
    885     if ( ptrNode == NULL  ) {
    886         return;
    887     }
    888 
    889     DumpSubTree( ptrNode );
    890 }
    891 
    892 static void Execute( const char * szNode, const char * szData )
    893 {
    894     PDmtNode ptrNode = GetNode(szNode);
    895     if (ptrNode == NULL) {
    896         return;
    897     }
    898     DMString strResult;
    899     if ( (e=ptrNode->Execute(szData, strResult)) == NULL ) {
    900         printf("execute node %s successfully, result=%s\n",
    901                 szNode, strResult.c_str() );
    902     } else {
    903         Error("can't execute node %s", szNode);
    904     }
    905 }
    906 
    907 static void Open( const char * szNode)
    908 {
    909     if ( strcmp(szNode, ".") == 0) {
    910         s_strRootPath = "";
    911     } else {
    912         s_strRootPath = szNode;
    913     }
    914     s_bAtomic = false;
    915     ptrTree = NULL;
    916     printf("Open tree: %s\n", s_strRootPath.c_str());
    917 }
    918 
    919 static void GetExclusiveTree( const char * szNode)
    920 {
    921     if ( strcmp(szNode, ".") == 0) {
    922         s_strRootPath = "";
    923     } else {
    924         s_strRootPath = szNode;
    925     }
    926     s_bAtomic = false;
    927     ptrTree = NULL;
    928 
    929   if ( (e=DmtTreeFactory::GetSubtreeEx(principal, s_strRootPath.c_str(), DmtTreeFactory::LOCK_TYPE_EXCLUSIVE, ptrTree)) != NULL ) {
    930       Error("can't get tree");
    931   }
    932 
    933     printf("GetExclusiveTree: %s\n", s_strRootPath.c_str());
    934 }
    935 
    936 static void Release()
    937 {
    938     s_bAtomic = false;
    939     ptrTree = NULL;
    940     s_strRootPath = "";
    941     printf("release tree successfully\n");
    942 }
    943 
    944 static void Flush()
    945 {
    946     if (ptrTree != NULL) {
    947         if ((e=ptrTree->Flush()) == NULL) {
    948             printf("flush tree successfully\n");
    949         } else {
    950             Error("can't flush tree");
    951         }
    952     } else {
    953         printf("tree is already released\n");
    954     }
    955     s_bAtomic = false;
    956 }
    957 
    958 static void Begin()
    959 {
    960     GetTree();
    961     if (ptrTree == NULL) {
    962         return;
    963     }
    964     if ( (e=ptrTree->Begin()) == NULL ) {
    965         s_bAtomic = true;
    966         printf("begin an atomic operation successfully\n");
    967     } else {
    968         Error("can't begin an atomic operation");
    969     }
    970 }
    971 
    972 static void Commit()
    973 {
    974     if (!s_bAtomic || ptrTree == NULL) {
    975         printf("not in the middle of atomic operations\n");
    976     } else if ( (e=ptrTree->Commit()) == NULL) {
    977         printf("commit atomic operations successfully\n");
    978     } else {
    979         Error("can't commit atomic operations");
    980     }
    981     s_bAtomic = false;
    982 }
    983 
    984 static void Rollback()
    985 {
    986     if ( !s_bAtomic || ptrTree == NULL) {
    987         printf("not in the middle of the atomic operations\n");
    988     } else if ( (e=ptrTree->Rollback()) == NULL) {
    989         printf("rollback atomic operations successfully\n");
    990     } else {
    991         Error("can't rollback atomic oeprations");
    992     }
    993     s_bAtomic = false;
    994 }
    995 
    996 static void Clone(const char * szNode, const char * szNewNode)
    997 {
    998     GetTree();
    999     if (ptrTree == NULL) {
   1000         return;
   1001     }
   1002 
   1003     if ( (e=ptrTree->Clone(szNode, szNewNode)) == NULL) {
   1004         printf("clone %s to %s successfully\n", szNode, szNewNode);
   1005     } else {
   1006         Error("can't clone %s to %s", szNode, szNewNode);
   1007     }
   1008 }
   1009 
   1010 static void GetMap( const char * szNode)
   1011 {
   1012     GetTree();
   1013     if (ptrTree == NULL) {
   1014         return;
   1015     }
   1016 
   1017     DMMap<DMString, DmtData> oMap;
   1018     if ( (e=ptrTree->GetChildValuesMap(szNode, oMap)) == NULL) {
   1019         printf("map table size=%d\n", oMap.size());
   1020         for (DMMap<DMString, DmtData>::POS it = oMap.begin(); it != oMap.end(); it++) {
   1021             DMString strKey = oMap.get_key(it);
   1022             DmtData oData = oMap.get_value(it);
   1023             DMString strData;
   1024             if ( (e=oData.GetString(strData)) == NULL) {
   1025                 printf("%s=%s\n", strKey.c_str(), strData.c_str());
   1026             } else {
   1027                 Error("can't get value of node %s", strKey.c_str() );
   1028             }
   1029         }
   1030     } else {
   1031         Error("can't get map of node %s", szNode);
   1032     }
   1033 }
   1034 
   1035 static void SetMap( const char * szNode )
   1036 {
   1037     GetTree();
   1038     if (ptrTree == NULL) {
   1039         return;
   1040     }
   1041 
   1042     DMMap<DMString, DmtData> oMap;
   1043     while (true) {
   1044         DMString strKey = GetParam();
   1045         DMString strData = GetParam();
   1046 
   1047         if (strKey == "" || strData == "") {
   1048             break;
   1049         }
   1050         DmtData oData(strData);
   1051         oMap.put(strKey, oData);
   1052     }
   1053     if ( (e=ptrTree->SetChildValuesMap(szNode, oMap)) == NULL ) {
   1054         printf("set map for %s succesfully, size = %d\n",
   1055                 szNode, oMap.size());
   1056     } else {
   1057         Error("can't set map of node %s", szNode);
   1058     }
   1059 }
   1060 
   1061 
   1062 static void Dump( const char* buf, int size )
   1063 {
   1064   int nOffset = 0;
   1065 
   1066   while ( size > 0){
   1067     int nLine = size > 16 ? 16: size;
   1068 
   1069     char s[250];
   1070     int pos = 0;
   1071 
   1072     pos += sprintf( s+pos, "%04x:", nOffset );
   1073 
   1074     for ( int i = 0; i < nLine; i++ ){
   1075       pos += sprintf( s+pos, " %02x", (unsigned int)((unsigned char)buf[i]) );
   1076     }
   1077     for ( int i = nLine; i < 16; i++ ){
   1078       pos += sprintf( s+pos, "   " );
   1079     }
   1080 
   1081     pos += sprintf( s+pos, "  " );
   1082     for ( int i = 0; i < nLine; i++ ){
   1083       pos += sprintf( s+pos, "%c", (buf[i] > 31 ? buf[i] : '.') );
   1084     }
   1085 
   1086     printf( "%s\n", s );
   1087     buf += nLine;
   1088     size -= nLine;
   1089     nOffset += nLine;
   1090   }
   1091 }
   1092 
   1093 static void ProcessScript( const char* szFile, const char* isBinary )
   1094 {
   1095   FILE* f = fopen( szFile, "r" );
   1096   if ( !f ) {
   1097     printf("%s can't open file %s\n",c_szErrorText, szFile);
   1098     return;
   1099   }
   1100 
   1101   bool bBinary = (isBinary[0] == '1');
   1102 
   1103   printf("Process WBXML script: %s\n", bBinary? "true" : "false");
   1104 
   1105   // assume 100k is enough
   1106   const int c_nSize = 100 * 1024;
   1107   char* szBuf = new char [c_nSize];
   1108 
   1109   int n = fread(szBuf, 1, c_nSize, f );
   1110 
   1111 
   1112   printf("Read %d bytes\n", n);
   1113   if ( n > 0 ) {
   1114     szBuf[n] = 0;
   1115 
   1116     DMString oResult;
   1117     DMVector<UINT8> bResult;
   1118     DmtPrincipal p("localhost");
   1119     SYNCML_DM_RET_STATUS_T res = DmtTreeFactory::ProcessScript( p, (const byte*)szBuf, n, bBinary, bResult);
   1120 
   1121     if (bBinary == true)
   1122     {
   1123       printf( "\nPrint result in HEX mode: \n\n" );
   1124       //  Dump(oResult.c_str(), oResult.length());
   1125 
   1126       printf( "Result Size: %d\n", bResult.size());
   1127 
   1128       int resultSize = bResult.size();
   1129       char* resultBuf = new char [resultSize];
   1130 
   1131       for (int i = 0; i < bResult.size(); i++) {
   1132         resultBuf[i] = (char)bResult[i];
   1133       }
   1134 
   1135       Dump(resultBuf, resultSize);
   1136 
   1137     } else
   1138     {
   1139 
   1140       int resultSize = bResult.size();
   1141       char* resultBuf = new char [resultSize+1];
   1142 
   1143       for (int i = 0; i < bResult.size(); i++) {
   1144         resultBuf[i] = (char)bResult[i];
   1145       }
   1146       resultBuf[resultSize] = '\0';
   1147 
   1148       printf( "The test Script error code %d; text:\n\n%s\n\n",
   1149 	      (int)res,
   1150 	      (const char*)resultBuf );
   1151     }
   1152   }
   1153 
   1154   delete [] szBuf;
   1155   fclose( f );
   1156 }
   1157 
   1158 static void StartServerSession( const char* szServerID, const char* szParam2 )
   1159 {
   1160     bool bBinary = (szParam2[0] == '1');
   1161 
   1162     printf("start server session, %s, bin = %s\n",
   1163                 szServerID, bBinary? "true" : "false");
   1164 	e = DmtTreeFactory::StartServerSession( szServerID, bBinary );
   1165 
   1166 	if ( e != NULL ) {
   1167       Error("can't start server session");
   1168     }
   1169 }
   1170 
   1171 static void StartServerSessionEx( const char* szServerID, const char* szBin, const char* szCorrelator1, const char* szCorrelator2 )
   1172 {
   1173     bool bBinary = (szBin[0] == '1');
   1174 
   1175     printf("start server session, %s, bin = %s, correlator(s) %s, %s\n",
   1176                 szServerID, bBinary? "true" : "false",
   1177                szCorrelator1, szCorrelator2 );
   1178 
   1179     DmtSessionProp oProps( DmtFirmAlert( "./DevDetail", "200",
   1180       "org.openmobilealliance.firmwareupdate.download", "int",
   1181       "critical", szCorrelator1 ), bBinary );
   1182 
   1183     if ( szCorrelator2 && *szCorrelator2 ){
   1184       oProps.addFirmAlert(DmtFirmAlert("./DevInfo", "402",
   1185       NULL, NULL, NULL, szCorrelator2) );
   1186 
   1187       oProps.addFirmAlert(DmtFirmAlert("./DevInfo/somewhere", NULL,
   1188         NULL, NULL, "NULL", NULL) );
   1189 
   1190       oProps.addFirmAlert(DmtFirmAlert("./DevInfo/somewhere", "data",
   1191         NULL, NULL, "NULL", NULL) );
   1192     }
   1193 
   1194 	e = DmtTreeFactory::StartServerSession( szServerID, oProps );
   1195 
   1196 	if ( e.GetErrorCode() != SYNCML_DM_SUCCESS ) {
   1197       Error("can't start server session");
   1198     }
   1199 }
   1200 
   1201 
   1202 //typedef SYNCMLDM_SEC_CREDENTIALS_T * (* hmac_callback)
   1203 //       (const SYNCMLDM_HMAC_SEC_INFO_T *ps_hmac_sec_info);
   1204 
   1205 static void BuildCredHMAC(const char * server_Id)
   1206 {
   1207   /***
   1208     SYNCMLDM_SEC_CREDENTIALS_T    *pHmacCreds = NULL;
   1209     SYNCMLDM_HMAC_SEC_INFO_T       hmacSecInfo;
   1210 
   1211     printf("Build the credentials for HMAC authentication scheme.\n");
   1212 
   1213    void *dllhandle=dlopen("libdmssession.so", RTLD_NOW);
   1214    if (dllhandle==NULL)
   1215    {
   1216       dlclose( dllhandle );
   1217       return;
   1218    }
   1219     hmacSecInfo.pb_syncml_document = NULL;
   1220     hmac_callback pFunc=(hmac_callback)dlsym(dllhandle, "syncmldm_sec_build_hmac_cred");
   1221     pHmacCreds = pFunc((const SYNCMLDM_HMAC_SEC_INFO_T *)&hmacSecInfo);
   1222    if ( dllhandle != NULL)
   1223 	 dlclose(dllhandle);
   1224     printf("credhmac end.\n");
   1225     */
   1226 }
   1227 
   1228 
   1229 static DMString CreateServerId(const char * szServerIP)
   1230 {
   1231     DMString strServerID = "";
   1232     DMString strPath = "./SyncML/DMAcc/";
   1233     DMString strPath2;
   1234     DMString strInput;
   1235     PDmtNode ptrNode;
   1236 
   1237     if (s_bAtomic) {
   1238         s_bAtomic = false;
   1239         ptrTree = NULL;
   1240     }
   1241 
   1242     if ( (e=DmtTreeFactory::GetTree(principal, ptrTree)) != NULL) {
   1243         Error("can't get tree");
   1244         return "";
   1245     }
   1246 
   1247  //   if ( (e=ptrTree->Begin()) != NULL) {
   1248 //       Error("can't begin atomic operations");
   1249 //        ptrTree = NULL;
   1250 //        return "";
   1251  //   }
   1252 
   1253 //    strInput = GetInputString("Enter account/profile name:", "test");
   1254     strPath += "SampleServer";
   1255 
   1256     if ( ptrTree->IsValidNode( strPath.c_str() ) ) {
   1257         if ( (e=ptrTree->DeleteNode(strPath.c_str())) != NULL) {
   1258             Error("can't delete existing node %s", strPath.c_str());
   1259  //           ptrTree->Rollback();
   1260             ptrTree = NULL;
   1261             return "";
   1262         }
   1263     }
   1264 
   1265     // Interior node
   1266     if ( (e=ptrTree->CreateInteriorNode(strPath.c_str(), ptrNode)) != NULL) {
   1267         Error("can't create node %s", strPath.c_str());
   1268    //     ptrTree->Rollback();
   1269         ptrTree = NULL;
   1270         return "";
   1271     }
   1272 
   1273     // PortNbr
   1274     //strInput = GetInputString("Enter port no:", "80");
   1275     strPath2 = strPath;
   1276     strPath2 += "/PortNbr";
   1277     if ( (e=ptrTree->CreateLeafNode(strPath2.c_str(), ptrNode, DmtData("80")) ) != NULL) {
   1278         Error("can't create node %s", strPath2.c_str() );
   1279    //     ptrTree->Rollback();
   1280         ptrTree = NULL;
   1281         return "";
   1282     }
   1283 
   1284     // AddrType
   1285     strPath2 = strPath;
   1286     strPath2 += "/Name";
   1287     if ( (e=ptrTree->CreateLeafNode(strPath2.c_str(), ptrNode, DmtData("SampleServer")) ) == NULL) {
   1288         printf("Stored name=SampleServer\n");
   1289     } else {
   1290         Error("can't create node %s", strPath2.c_str());
   1291      //   ptrTree->Rollback();
   1292         ptrTree = NULL;
   1293         return "";
   1294     }
   1295 
   1296     // AddrType
   1297     strPath2 = strPath;
   1298     strPath2 += "/AddrType";
   1299     if ( (e=ptrTree->CreateLeafNode(strPath2.c_str(), ptrNode, DmtData("1")) ) == NULL) {
   1300         printf("Stored AddrType=1\n");
   1301     } else {
   1302         Error("can't create node %s", strPath2.c_str());
   1303      //   ptrTree->Rollback();
   1304         ptrTree = NULL;
   1305         return "";
   1306     }
   1307 
   1308     // Address
   1309     //DMString strAddr = "http://";
   1310     //strAddr += szServerIP;
   1311     //strAddr += "/Manage";
   1312 
   1313     //strInput = GetInputString("Enter Addr:", strAddr.c_str());
   1314     strPath2 = strPath;
   1315     strPath2 += "/Addr";
   1316     if ( (e=ptrTree->CreateLeafNode(strPath2.c_str(), ptrNode, DmtData("http://10.72.34.36/Manage")) ) != NULL) {
   1317         Error("can't create node %s", strPath2.c_str());
   1318     //    ptrTree->Rollback();
   1319         ptrTree = NULL;
   1320         return "";
   1321     }
   1322 
   1323     // AuthPref
   1324 //    strInput = GetInputString("Enter AuthPref:", "syncml:auth-Basic");
   1325     strPath2 = strPath;
   1326     strPath2 += "/AuthPref";
   1327     if ( (e=ptrTree->CreateLeafNode(strPath2.c_str(), ptrNode, DmtData("syncml:auth-Basic")) ) != NULL) {
   1328         Error("can't create node %s", strPath2.c_str());
   1329     //    ptrTree->Rollback();
   1330         ptrTree = NULL;
   1331         return "";
   1332     }
   1333 
   1334     // User name
   1335 /////    strInput = GetInputString("Enter UserName:", "SampleServer");
   1336     strPath2 = strPath;
   1337     strPath2 += "/UserName";
   1338     if ( (e=ptrTree->CreateLeafNode(strPath2.c_str(), ptrNode, DmtData((CPCHAR)"")) ) != NULL) {
   1339         Error("can't create node %s", strPath2.c_str());
   1340    //     ptrTree->Rollback();
   1341         ptrTree = NULL;
   1342         return "";
   1343     }
   1344 
   1345     // Client Password
   1346  //   strInput = GetInputString("Enter ClientPW:", "SampleServer");
   1347     strPath2 = strPath;
   1348     strPath2 += "/ClientPW";
   1349     if ( (e=ptrTree->CreateLeafNode(strPath2.c_str(), ptrNode, DmtData((CPCHAR)"")) ) != NULL) {
   1350         Error("can't create node %s", strPath2.c_str());
   1351     //    ptrTree->Rollback();
   1352         ptrTree = NULL;
   1353         return "";
   1354     }
   1355 
   1356     // Client Nonce
   1357 //    strInput = GetInputString("Enter ClientNonce:", "MTIzNDU=");
   1358     strPath2 = strPath;
   1359     strPath2 += "/ClientNonce";
   1360     if ( (e=ptrTree->CreateLeafNode(strPath2.c_str(), ptrNode, DmtData("123abc")) ) != NULL) {
   1361         Error("can't create node %s", strPath2.c_str());
   1362    //     ptrTree->Rollback();
   1363         ptrTree = NULL;
   1364         return "";
   1365     }
   1366 
   1367     // ServerID
   1368 //    strInput = GetInputString("Enter ServerId:", "sid");
   1369     strPath2 = strPath;
   1370     strPath2 += "/ServerId";
   1371     if ( (e=ptrTree->CreateLeafNode(strPath2.c_str(), ptrNode, DmtData("Scts")) ) == NULL) {
   1372         strServerID = strInput;
   1373     } else {
   1374         Error("can't create node %s", strPath2.c_str());
   1375    //     ptrTree->Rollback();
   1376         ptrTree = NULL;
   1377         return "";
   1378     }
   1379 
   1380     // Server Password
   1381    // strInput = GetInputString("Enter ServerPW:", "SampleClient");
   1382     strPath2 = strPath;
   1383     strPath2 += "/ServerPW";
   1384     if ( (e=ptrTree->CreateLeafNode(strPath2.c_str(), ptrNode, DmtData((CPCHAR)"")) ) != NULL) {
   1385         Error("can't create node %s", strPath2.c_str());
   1386    //     ptrTree->Rollback();
   1387         ptrTree = NULL;
   1388         return "";
   1389     }
   1390 
   1391     // Server Nonce
   1392   //  strInput = GetInputString("Enter ServerNonce:", "MTIzNDU=");
   1393     strPath2 = strPath;
   1394     strPath2 += "/ServerNonce";
   1395     if ( (e=ptrTree->CreateLeafNode(strPath2.c_str(), ptrNode, DmtData("MTIzNDEyMzQxMjM0MTIzNA==")) ) != NULL) {
   1396         Error("can't create node %s", strPath2.c_str());
   1397    //     ptrTree->Rollback();
   1398         ptrTree = NULL;
   1399         return "";
   1400     }
   1401 
   1402     // ConRef
   1403     //strPath2 = strPath;
   1404     //strPath2 += "/ConRef";
   1405    // if ( (e=ptrTree->CreateLeafNode(strPath2.c_str(), ptrNode, DmtData("1")) ) == NULL) {
   1406     //    printf("Stored ConRef=1\n");
   1407     //} else {
   1408     //    Error("can't create node %s", strPath2.c_str());
   1409     //    ptrTree->Rollback();
   1410   //      ptrTree = NULL;
   1411    //     return "";
   1412    // }
   1413 
   1414 //    ptrTree->Commit();
   1415     ptrTree = NULL;
   1416     return strServerID;
   1417 }
   1418 
   1419 static void CreateAndStartServerSession(const char * szAddr, const char * szParam2)
   1420 {
   1421     printf("Create Server ID\n");
   1422     DMString strServerID = CreateServerId(szAddr);
   1423     if (strServerID="") {
   1424         printf("Failed to create server id\n");
   1425     } else {
   1426         StartServerSession(strServerID.c_str(), szParam2);
   1427     }
   1428 }
   1429 
   1430 static void ShowTimestamp(const char * sParam)
   1431 {
   1432     s_bShowTimestamp = (sParam[0] == '1');
   1433     if (s_bShowTimestamp) {
   1434         printf("now show timestamp of nodes\n");
   1435     } else {
   1436         printf("now don't show timestamp of nodes\n");
   1437     }
   1438 }
   1439 
   1440 static void ShowProfileTime(const char * sParam)
   1441 {
   1442     s_bShowProfileTime = (sParam[0] == '1');
   1443     if (s_bShowProfileTime) {
   1444         printf("now show profile time\n");
   1445     } else {
   1446         printf("now don't show profile time\n");
   1447     }
   1448 }
   1449 
   1450 static void DMVersion()
   1451 {
   1452 
   1453   unsigned long libVersion = 0;
   1454   const char *version = GetDMSyncMLVersion(&libVersion);
   1455   CPCHAR dm_ver = XPL_DM_GetEnv(SYNCML_DM_VERSION);
   1456   printf("DM Version: %s\n", dm_ver);
   1457   printf("LIB Version = 0x%06x    \nDMSyncMLVersion = %s\n", libVersion, version);
   1458 
   1459 }
   1460 
   1461 static void SuperAgent()
   1462 {
   1463 
   1464   CPCHAR dm_ver = XPL_DM_GetEnv(SYNCML_DM_VERSION);
   1465   PDmtNode ptrNode;
   1466   if (strcmp(dm_ver, "1.1.2") == 0) {
   1467     CreateInterior("./SyncML/DMAcc/SuperAgent");
   1468     CreateLeaf("./SyncML/DMAcc/SuperAgent/ServerId", "LJAgent");
   1469     if (e != NULL) {
   1470       return;
   1471     }
   1472     ptrNode = GetNode("./SyncML/DMAcc/SuperAgent/ServerId");
   1473   } else if (strcmp(dm_ver, "1.2") == 0) {
   1474     CreateInterior("./DMAcc/SuperAgent");
   1475     CreateLeaf("./DMAcc/SuperAgent/ServerID", "LJAgent");
   1476     if (e != NULL) {
   1477       return;
   1478     }
   1479     ptrNode = GetNode("./DMAcc/SuperAgent/ServerID");
   1480   } else {
   1481     Error("DM Version not supported!\n");
   1482     return;
   1483   }
   1484 
   1485   if ( ptrNode == NULL ) {
   1486     if (strcmp(dm_ver, "1.1.2") == 0) {
   1487       Error("can't get Node ./SyncML/DMAcc/SuperAgent/ServerId");
   1488       return;
   1489     } else if (strcmp(dm_ver, "1.2") == 0) {
   1490       Error("can't get Node ./DMAcc/SuperAgent/ServerID");
   1491       return;
   1492     }
   1493   }
   1494 
   1495 
   1496     DmtAcl oAcl( "Replace=*");
   1497     if ( (e=ptrNode->SetAcl(oAcl)) != NULL )
   1498     {
   1499       if (strcmp(dm_ver, "1.1.2") == 0) {
   1500         Error("can't set acl of node ./SyncML/DMAcc/SuperAgent/ServerId to Replace=*");
   1501 	return;
   1502       } else if (strcmp(dm_ver, "1.2") == 0) {
   1503 	Error("can't set acl of node ./DMAcc/SuperAgent/ServerID to Replace=*");
   1504 	return;
   1505       }
   1506     }
   1507 
   1508 	DmtData dmData;
   1509 	if( (e=ptrNode->GetValue(dmData)) == NULL )
   1510 	{
   1511 		Error("Get node value even if don't have get permission");
   1512 		return;
   1513 	}
   1514 	ptrNode = NULL;
   1515 	ptrTree = NULL;
   1516 
   1517 
   1518 	DmtPrincipal lj("LJAgent");
   1519 
   1520 	PDmtTree tree;
   1521 	if ( (e=DmtTreeFactory::GetSubtree(lj, s_strRootPath.c_str(), tree)) != NULL )
   1522 	{
   1523 		Error("can't get tree for LJAgent");
   1524 		return;
   1525 	}
   1526 
   1527 	if( tree != NULL )
   1528 	{
   1529 	  if (strcmp(dm_ver, "1.1.2") == 0) {
   1530 		if( (e=tree->GetNode("./SyncML/DMAcc/SuperAgent/ServerId", ptrNode)) != NULL )
   1531 		{
   1532 			Error("can't get node for LJAgent");
   1533 		}
   1534 
   1535 	  } else if (strcmp(dm_ver, "1.2") == 0) {
   1536 	    if( (e=tree->GetNode("./DMAcc/SuperAgent/ServerID", ptrNode)) != NULL )
   1537 		{
   1538 			Error("can't get node for LJAgent");
   1539 		}
   1540 	  }
   1541 
   1542 	  if( ptrNode != NULL )
   1543 	  {
   1544 	    PrintNode(ptrNode);
   1545 	    if (strcmp(dm_ver, "1.1.2") == 0) {
   1546 	      if( (e=tree->DeleteNode("./SyncML/DMAcc/SuperAgent")) != NULL )
   1547 	      {
   1548 		Error("can't delete ./SyncML/DMAcc/SuperAgent by LJAgent");
   1549 	      }
   1550 	    } else if (strcmp(dm_ver, "1.2") == 0) {
   1551 	      if( (e=tree->DeleteNode("./DMAcc/SuperAgent")) != NULL )
   1552 	      {
   1553 		Error("can't delete ./DMAcc/SuperAgent by LJAgent");
   1554 	      }
   1555 	    }
   1556 	  }
   1557 	}
   1558 }
   1559 
   1560 
   1561 static void SubTreeStruct(PDmtNode ptrNode, int depth)
   1562 {
   1563    for (int i=0; i < depth; i++) {
   1564        if (i == (depth-1)) {
   1565            printf("^---");
   1566        } else {
   1567            printf("    ");
   1568        }
   1569    }
   1570 
   1571    DMString strName;
   1572    ptrNode->GetNodeName(strName);
   1573    if (ptrNode->IsLeaf() ) {
   1574        DMString strValue;
   1575        DMString strName;
   1576        ptrNode->GetStringValue(strValue);
   1577        printf("%s: %s\n", strName.c_str(), strValue.c_str());
   1578    } else {
   1579        printf("%s(node)\n", strName.c_str());
   1580        DMVector<PDmtNode> aChildren;
   1581        if ( (e=ptrNode->GetChildNodes( aChildren )) != NULL ) {
   1582             DMString strPath;
   1583             ptrNode->GetPath(strPath);
   1584             Error("can't get child nodes of %s\n", strPath.c_str());
   1585            return;
   1586        }
   1587        for (int i=0; i < aChildren.size(); i++) {
   1588            SubTreeStruct(aChildren[i], depth+1);
   1589        }
   1590    }
   1591 }
   1592 
   1593 static void TreeStruct(const char * sParam)
   1594 {
   1595     PDmtNode ptrNode = GetNode( sParam );
   1596     if ( ptrNode == NULL  ) {
   1597         return;
   1598     }
   1599     SubTreeStruct( ptrNode, 0 );
   1600 }
   1601 
   1602 
   1603 static void SubscribeOnEvents()
   1604 {
   1605     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
   1606 
   1607 
   1608     DmtEventSubscription oEvent;
   1609     DmtEventSubscription oEvent1;
   1610 
   1611     UINT8 event =  SYNCML_DM_EVENT_ADD | SYNCML_DM_EVENT_REPLACE |
   1612                           SYNCML_DM_EVENT_DELETE | SYNCML_DM_EVENT_INDIRECT;
   1613 
   1614 
   1615     oEvent.Set(event,SYNCML_DM_EVENT_DETAIL);
   1616 
   1617     dm_stat = DmtTreeFactory::SubscribeEvent("./UnitTest", oEvent);
   1618     if ( dm_stat != SYNCML_DM_SUCCESS )
   1619        return;
   1620 
   1621     dm_stat = DmtTreeFactory::SubscribeEvent("./TEST", oEvent);
   1622     if ( dm_stat != SYNCML_DM_SUCCESS )
   1623         return;
   1624 
   1625     dm_stat = DmtTreeFactory::SubscribeEvent("./CLONE", oEvent);
   1626     if ( dm_stat != SYNCML_DM_SUCCESS )
   1627         return;
   1628 
   1629     dm_stat = DmtTreeFactory::SubscribeEvent("./TestRWPluginNode", oEvent);
   1630     if ( dm_stat != SYNCML_DM_SUCCESS )
   1631         return;
   1632 
   1633     GetTree();
   1634 
   1635     PDmtNode ptrNode;
   1636     DmtData oData("server");
   1637 
   1638 
   1639     ptrTree->DeleteNode("./DMAcc/Test");
   1640     ptrTree->DeleteNode("./DMAcc/Test1");
   1641     ptrTree->DeleteNode("./DMAcc/Test2");
   1642     ptrTree->DeleteNode("./DMAcc/Test3");
   1643     ptrTree->CreateInteriorNode( "./DMAcc/Test", ptrNode );
   1644     ptrTree->CreateInteriorNode( "./DMAcc/Test1", ptrNode );
   1645     ptrTree->CreateInteriorNode( "./DMAcc/Test2", ptrNode );
   1646     ptrTree->CreateLeafNode( "./DMAcc/Test/ServerID", ptrNode, oData );
   1647     ptrTree->CreateLeafNode( "./DMAcc/Test1/ServerID", ptrNode, oData );
   1648     ptrTree->CreateLeafNode( "./DMAcc/Test2/ServerID", ptrNode, oData );
   1649     if ( ptrNode )
   1650     {
   1651         ptrNode->SetValue(oData);
   1652         ptrNode->SetValue(oData);
   1653         ptrNode->SetValue(oData);
   1654     }
   1655     ptrTree->RenameNode("./DMAcc/Test", "Test3");
   1656     ptrTree->DeleteNode(  "./DMAcc/Test3" );
   1657     ptrTree->DeleteNode("./DMAcc/Test1");
   1658     ptrTree->DeleteNode("./DMAcc/Test2");
   1659 
   1660 }
   1661 
   1662 
   1663 static void Usage()
   1664 {
   1665   printf( "Supported commands:\n"
   1666     "exit, quit, q - exit\n"
   1667     "? - help screen\n"
   1668     "get <node> - print node info\n"
   1669     "createi <node> - create interior node\n"
   1670     "createl <node> <string> - create string leaf node\n"
   1671     "createli <node> <integer> - create integer leaf node\n"
   1672     "createlz <node> true|false - create boolean leaf node\n"
   1673     "createlb <node> <binary> - create binary leaf node\n"
   1674     "createlbe <node> - create binary leaf node with default value\n"
   1675     "createlf <node> <float> - create float leaf node\n"
   1676     "createld <node> <date> - create date leaf node\n"
   1677     "createlt <node> <time> - create time leaf node\n"
   1678     "delete <node> - delete node\n"
   1679     "rename <node> <new name> - rename node name\n"
   1680     "setESN <node> <file> - set External Storage Node data\n"
   1681     "settitle <node> <title> - set node title\n"
   1682     "setacl <node> <acl> - set node acl\n"
   1683     "set|replace <node> <string>- set string value\n"
   1684     "seti <node> <integer> - set integer value\n"
   1685     "setz <node> true|false - set boolean value\n"
   1686     "setf <node> <float> - set float value\n"
   1687     "setd <node> <date> - set date value\n"
   1688     "sett <node> <time> - set time value\n"
   1689     "setb <node> <bytes> - set bytes value\n"
   1690     "dump <node> - dump the subtree from the node\n"
   1691     "exec <node> - execute node\n"
   1692     "getmap <node> - \n"
   1693     "hmaccred <string> - build the credentials for HMAC \n"
   1694 /*    "setmap <node> - \n" */
   1695     "ProcessScript <file> | <using binary xml [0/1]> - reads file and calls ProcessScript\n"
   1696     "tree|open <node> - open subtree\n"
   1697     "GetExclusiveTree <node> - get exclusive subtree subtree\n"
   1698     "release - release the tree\n"
   1699     "flush - flush the tree\n"
   1700 /*    "reset <mode> - reset tree\n" */
   1701     "begin - begin atomic operations\n"
   1702     "rollback - rollback atomic operations\n"
   1703     "commit - commit atmoic operations\n"
   1704 /*  "alert - \n" */
   1705     "clone <node> <new node> - clone a new node\n"
   1706     "StartServerSession|connectsid <server ID> <using binary xml [0/1]> - starts server session\n"
   1707     "sss <server ID> <using binary xml [0/1]> <correlator 1> <correlator 2> - starts server session\n"
   1708     "connect <server_ip> <using binary xml [0/1]> - create new server ID and start server session\n"
   1709     "createsid <server ip> - create new server ID\n"
   1710     "showtimestamp [0/1] - toggle showing timestamp\n"
   1711     "showprofiletime [0/1] - toggle showing profiling time\n"
   1712     "version - show version of DM engine\n"
   1713     "superagent - test SuperAgent function\n"
   1714     "SetAutoRelease on|off - turn on/off autorelease of the tree\n"
   1715     "struct - Show tree struct\n"
   1716     "startCounter - Start counter for executed command\n"
   1717     "endCounter - End counter for command\n"
   1718     "displayCountStatus - Display count status ON/OFF\n"
   1719     "resetCounter - Reset the counter back to zero\n"
   1720     "getCounter - Get the number of executed command\n"
   1721     );
   1722 }
   1723 
   1724 int InteractiveMode(int argc, char** argv)
   1725 {
   1726 	if ( !DmtTreeFactory::Initialize() ) {
   1727 		printf("Fail to init DM tree\n");
   1728 		return 1;
   1729 	}
   1730 
   1731     if ( GetTree() == NULL ) {
   1732         return 1;
   1733     }
   1734 	ptrTree = NULL;
   1735 
   1736     SubscribeOnEvents();
   1737 
   1738     printf( "Interaction mode, type \"exit\" to exit, ? for help\n");
   1739 
   1740     while ( true ) {
   1741         printf("\n] ");
   1742 
   1743         DMString sOperation = GetCmd();
   1744         const char* szOperation = sOperation.c_str();
   1745 
   1746         if ( strcasecmp(szOperation, "") == 0 || szOperation[0] == '#') {
   1747             continue;
   1748         }
   1749 
   1750         printf("Cmd: %s%s\n", szOperation, s_strCurLine.c_str());
   1751 
   1752         DMString sParam1 = GetParam();
   1753         if ( strcasecmp( szOperation, "setmap" ) == 0 ) {
   1754             SetMap(sParam1);
   1755             if ( !s_bAtomic ) {
   1756                 //ptrTree = NULL;
   1757             }
   1758             continue;
   1759         }
   1760         DMString sParam2 = GetParam();
   1761         DMString sParam3 = GetParam();
   1762         DMString sParam4 = GetParam();
   1763 
   1764   TestProfile  oProf( szOperation );
   1765 
   1766 
   1767         if ( strcasecmp( szOperation, "exit" ) == 0 ||
   1768             strcasecmp( szOperation, "quit" ) == 0 ||
   1769             strcasecmp( szOperation, "q" ) == 0) {
   1770             break;
   1771         } else if ( strcasecmp( szOperation, "get" ) == 0 ) {
   1772             Get( sParam1 );
   1773         } else if ( strcasecmp( szOperation, "delete" ) == 0 ) {
   1774             Delete( sParam1 );
   1775         } else if ( strcasecmp( szOperation, "createi" ) == 0 ) {
   1776            CreateInterior( sParam1 );
   1777         } else if ( strcasecmp( szOperation, "createl" ) == 0 ) {
   1778            CreateLeaf( sParam1, sParam2 );
   1779         } else if ( strcasecmp( szOperation, "createli" ) == 0 ) {
   1780            CreateLeafInteger( sParam1, sParam2 );
   1781         } else if ( strcasecmp( szOperation, "createlz" ) == 0 ) {
   1782            CreateLeafBoolean( sParam1, sParam2 );
   1783         } else if ( strcasecmp( szOperation, "createlb" ) == 0 ) {
   1784            CreateLeafBinary( sParam1, sParam2 );
   1785         } else if ( strcasecmp( szOperation, "createlbe" ) == 0 ) {
   1786            CreateLeafBinaryE( sParam1 );
   1787         } else if ( strcasecmp( szOperation, "createlf" ) == 0 ) {
   1788            CreateLeafFloat( sParam1, sParam2 );
   1789         } else if ( strcasecmp( szOperation, "createld" ) == 0 ) {
   1790            CreateLeafDate( sParam1, sParam2 );
   1791         } else if ( strcasecmp( szOperation, "createlt" ) == 0 ) {
   1792            CreateLeafTime( sParam1, sParam2 );
   1793         } else if ( strcasecmp( szOperation, "rename") == 0 ) {
   1794             Rename( sParam1, sParam2);
   1795         } else if ( strcasecmp( szOperation, "settitle") == 0 ) {
   1796             SetTitle( sParam1, sParam2 );
   1797         } else if ( strcasecmp( szOperation, "setESN") == 0 ) {
   1798 		setESN( sParam1, sParam2 );
   1799         } else if ( strcasecmp( szOperation, "setacl" ) == 0 ) {
   1800             SetAcl( sParam1, sParam2 );
   1801         } else if ( strcasecmp( szOperation, "set") == 0 ||
   1802                 strcasecmp( szOperation, "replace" ) == 0 ) {
   1803             ReplaceString( sParam1, sParam2 );
   1804         } else if ( strcasecmp( szOperation, "seti" ) == 0 ) {
   1805             ReplaceInteger( sParam1, sParam2 );
   1806         } else if ( strcasecmp( szOperation, "setz" ) == 0 ) {
   1807             ReplaceBoolean( sParam1, sParam2 );
   1808         } else if ( strcasecmp( szOperation, "setb" ) == 0 ) {
   1809             ReplaceBytes( sParam1, sParam2 );
   1810         } else if ( strcasecmp( szOperation, "setf" ) == 0 ) {
   1811             ReplaceFloat( sParam1, sParam2 );
   1812         } else if ( strcasecmp( szOperation, "setd" ) == 0 ) {
   1813             ReplaceDate( sParam1, sParam2 );
   1814         } else if ( strcasecmp( szOperation, "sett" ) == 0 ) {
   1815             ReplaceTime( sParam1, sParam2 );
   1816         } else if ( strcasecmp( szOperation, "hmaccred" ) == 0 ) {
   1817            BuildCredHMAC( sParam1 );
   1818         } else if ( strcasecmp( szOperation, "dump" ) == 0 ) {
   1819             DumpTree( sParam1 );
   1820         } else if (strcasecmp( szOperation, "exec") == 0 ||
   1821                 strcasecmp(szOperation, "execute") == 0 ) {
   1822             Execute( sParam1, sParam2 );
   1823         } else if (strcasecmp( szOperation, "getmap") == 0) {
   1824             GetMap(sParam1);
   1825         } else if (strcasecmp( szOperation, "open") == 0 ||
   1826                 strcasecmp(szOperation, "tree") == 0 ) {
   1827             Open( sParam1 );
   1828         }        else if (strcasecmp(szOperation, "GetExclusiveTree") == 0 ) {
   1829             GetExclusiveTree( sParam1 );
   1830         } else if (strcasecmp( szOperation, "release") == 0) {
   1831             Release();
   1832         } else if (strcasecmp( szOperation, "flush") == 0) {
   1833             Flush();
   1834         } else if (strcasecmp( szOperation, "begin") == 0) {
   1835             Begin();
   1836         } else if (strcasecmp( szOperation, "commit") == 0) {
   1837             Commit();
   1838         } else if (strcasecmp( szOperation, "rollback") == 0) {
   1839             Rollback();
   1840         } else if (strcasecmp( szOperation, "clone") == 0) {
   1841             Clone( sParam1, sParam2 );
   1842         } else if ( strcasecmp( szOperation, "ProcessScript" ) == 0 ) {
   1843 	  ProcessScript( sParam1 , sParam2);
   1844         } else if ( strcasecmp( szOperation, "connectsid" ) == 0 ||
   1845                 strcasecmp(szOperation, "StartServerSession") == 0 ) {
   1846            StartServerSession( sParam1, sParam2 );
   1847         } else if ( strcasecmp( szOperation, "sss" ) == 0 ) {
   1848             StartServerSessionEx( sParam1, sParam2, sParam3, sParam4 );
   1849         } else if ( strcasecmp( szOperation, "createsid" ) == 0 ) {
   1850             CreateServerId( sParam1 );
   1851         } else if ( strcasecmp( szOperation, "connect") == 0) {
   1852             CreateAndStartServerSession( sParam1, sParam2 );
   1853         } else if ( strcasecmp( szOperation, "showtimestamp") == 0) {
   1854             ShowTimestamp( sParam1 );
   1855         }        else if ( strcasecmp( szOperation, "showprofiletime") == 0) {
   1856             ShowProfileTime( sParam1 );
   1857         } else if ( strcasecmp( szOperation, "version") == 0) {
   1858             DMVersion();
   1859 	 } else if ( strcasecmp( szOperation, "superagent") == 0) {
   1860             SuperAgent();
   1861 	 } else if ( strcasecmp( szOperation, "SetAutoRelease" ) == 0 ) {
   1862 			s_bAutoReleaseTree =
   1863 					(strcasecmp(sParam1, "on") == 0 ||
   1864 					strcasecmp(sParam1, "yes") == 0 ||
   1865 					strcasecmp(sParam1, "true") == 0 ||
   1866 					strcasecmp(sParam1, "1") == 0);
   1867 					printf("Autorelease is now %s\n", s_bAutoReleaseTree ? "ON" : "OFF");
   1868         } else if ( strcasecmp( szOperation, "struct") == 0) {
   1869             TreeStruct( sParam1 );
   1870 
   1871        } else if ( strcasecmp( szOperation, "startCounter") == 0) {
   1872             startCounter();
   1873        } else if ( strcasecmp( szOperation, "endCounter") == 0) {
   1874             endCounter();
   1875        } else if ( strcasecmp( szOperation, "displayCountStatus") == 0) {
   1876             displayCountStatus();
   1877         } else if ( strcasecmp( szOperation, "resetCounter") == 0) {
   1878             resetCounter();
   1879         } else if ( strcasecmp( szOperation, "getCounter") == 0) {
   1880             getCounter();
   1881         } else if ( strcasecmp( szOperation, "?" ) == 0 ||
   1882                 strcasecmp( szOperation, "help" ) == 0) {
   1883            Usage();
   1884         } else {
   1885            printf( "Unknown option %s.\n", szOperation );
   1886            Usage();
   1887         }
   1888         if (!s_bAtomic && s_bAutoReleaseTree) {
   1889             ptrTree = NULL;
   1890         }
   1891     }
   1892 
   1893     DmtTreeFactory::Uninitialize();
   1894     return 0;
   1895 }
   1896 
   1897 int defaultFunction()
   1898 {
   1899     if ( !DmtTreeFactory::Initialize() ) {
   1900         printf("Fail to init DM tree\n");
   1901         return 1;
   1902     }
   1903 
   1904     if ( (e=DmtTreeFactory::GetTree(principal, ptrTree)) != NULL ) {
   1905         printf( "%s can't get tree, %d\n", c_szErrorText, e->GetErrorCode() );
   1906         return 1;
   1907     }
   1908 
   1909     PDmtNode ptrNode;
   1910 	DMString strNode = "./DevDetail/Bearer/GSM";
   1911 
   1912 	if ( (e=ptrTree->GetNode( strNode, ptrNode )) != NULL )
   1913 	  printf( "can't get node %s, error %s\n", strNode.c_str(), (const char*)e->GetErrorText().c_str() );
   1914 	else {
   1915 	  e = ptrNode->SetValue( DmtData("123"));
   1916 	  if ( e != NULL )
   1917 		printf( "can't set node value [%s], error %s\n", strNode.c_str(), (const char*)e->GetErrorText().c_str() );
   1918 
   1919 	}
   1920 
   1921 	ptrNode = NULL;
   1922 	ptrTree = NULL;
   1923 
   1924 	printf(" start server session\n");
   1925 	e = DmtTreeFactory::StartServerSession( "Scts", false );
   1926 
   1927 	if ( e != NULL ) {
   1928 	  printf( "error %d\n", e->GetErrorCode());
   1929     }
   1930 
   1931     DmtTreeFactory::Uninitialize();
   1932 
   1933     printf("Done.\n");
   1934     return 0;
   1935 }
   1936 
   1937 static void isVersionOn(int argc, char** argv)
   1938 {
   1939   for(int i=1; i<argc; i++)
   1940   {
   1941     if(strcmp(argv[i], "-version") == 0 )
   1942     {
   1943         DMVersion();
   1944         break;
   1945     }
   1946   }
   1947 }
   1948 
   1949 int main(int argc, char** argv)
   1950 {
   1951   isVersionOn(argc, argv);
   1952   const char* szParam1 = argc > 1 ? argv[1] : "";
   1953   if ( strcmp( szParam1, "unittest" ) == 0 ) {
   1954 	return defaultFunction();
   1955   }
   1956   else if ( strcmp( szParam1, "mt" ) == 0 ) {
   1957 	return MultiProcessTest();
   1958   }
   1959 
   1960   return InteractiveMode(argc, argv);
   1961 }
   1962