ed868620f45caee603f2358247b1768ada01f7f8
[platform/upstream/syncevolution.git] / src / synthesis / src / sysync / remotedatastore.cpp
1 /*
2  *  File:         RemoteDataStore.cpp
3  *
4  *  Author:                       Lukas Zeller (luz@synthesis.ch)
5  *
6  *  TRemoteDataStore
7  *    Abstraction of remote data store for SyncML Server
8  *    Buffers and forwards incoming remote data store commands for
9  *    processing by sync engine.
10  *
11  *  Copyright (c) 2001-2009 by Synthesis AG (www.synthesis.ch)
12  *
13  *  2001-06-12 : luz : created
14  *
15  */
16
17 // includes
18 #include "prefix_file.h"
19 #include "sysync.h"
20 #include "syncagent.h"
21 #include "remotedatastore.h"
22
23
24 using namespace sysync;
25
26
27 /*
28  * Implementation of TRemoteDataStore
29  */
30
31 void TRemoteDataStore::init(void)
32 {
33   // nop so far
34 } // TSyncDataStore::init
35
36
37 void TRemoteDataStore::InternalResetDataStore(void)
38 {
39   // for server, get default GUID size (in case remote devInf does not send one)
40   #ifdef SYSYNC_SERVER
41   if (IS_SERVER) {
42           fMaxGUIDSize = static_cast<TAgentConfig *>(getSession()->getSessionConfig())->fMaxGUIDSizeSent;
43   }
44   #endif
45 } // TRemoteDataStore::InternalResetDataStore
46
47
48 TRemoteDataStore::TRemoteDataStore(TSyncSession *aSessionP) :
49   TSyncDataStore(aSessionP)
50 {
51   // nop so far
52 } // TSyncDataStore::TSyncDataStore
53
54
55 TRemoteDataStore::TRemoteDataStore(
56   TSyncSession *aSessionP, const char *aName,
57   uInt32 aCommonSyncCapMask
58 ) :
59   TSyncDataStore(aSessionP, aName, aCommonSyncCapMask)
60 {
61   // assume full name same as real name, but could be updated at <alert> or <sync>
62   fFullName=aName;
63 } // TSyncDataStore::TSyncDataStore
64
65
66
67 TRemoteDataStore::~TRemoteDataStore()
68 {
69   InternalResetDataStore();
70   // nop so far
71 } // TRemoteDataStore::~TRemoteDataStore
72
73
74 // - return pure relative (item) URI (removes absolute part or ./ prefix)
75 const char *TRemoteDataStore::DatastoreRelativeURI(const char *aURI)
76 {
77   return relativeURI(aURI,fSessionP->getRemoteURI());
78 } // TRemoteDataStore::DatastoreRelativeURI
79
80
81 // check if this remote datastore is accessible with given URI
82 // NOTE: URI might include path elements or CGI params that are
83 // access options to the database.
84 // Remote datastores however only represent devinf, so
85 // it counts as name match if start of specified URI matches
86 // name and then continues with "/" or "?" (subpaths and CGI ignored)
87 uInt16 TRemoteDataStore::isDatastore(const char *aDatastoreURI)
88 {
89   // - make pure relative paths
90   const char *nam=DatastoreRelativeURI(fName.c_str());
91   size_t n=strlen(nam);
92   const char *uri=DatastoreRelativeURI(aDatastoreURI);
93   // - compare up to end of local name
94   if (strucmp(nam,uri,n,n)==0) {
95     // beginnig matches.
96     char c=uri[n]; // terminating char
97     // match if full match, or uri continues with '/' or '?'
98     // Note: return number of chars matched, to allow search for best match
99     return (c==0 || c=='/' || c=='?') ? n : 0;
100   }
101   else
102     return 0; // no match
103 } // TRemoteDataStore::isDatastore
104
105
106
107 // SYNC command bracket start (check credentials if needed)
108 bool TRemoteDataStore::remoteProcessSyncCmd(
109   SmlSyncPtr_t aSyncP,            // the Sync element
110   TStatusCommand &aStatusCommand,     // status that might be modified
111   bool &aQueueForLater // will be set if command must be queued for later (re-)execution
112 )
113 {
114   // adjust name of datastore (may include subpath or CGI)
115   fFullName = smlSrcTargLocURIToCharP(aSyncP->source);
116   // read meta of Sync Command for remote datastore
117   // NOTE: this will overwrite Max values eventually read from DevInf
118   //       as meta is more accurate (actual free bytes/ids, not total)
119   SmlMetInfMetInfPtr_t metaP = smlPCDataToMetInfP(aSyncP->meta);
120   if (metaP) {
121     if (metaP->mem) {
122       // - max free bytes
123       if (metaP->mem->free)
124         if (!StrToLongLong(smlPCDataToCharP(metaP->mem->free),fFreeMemory))
125           return false;
126       // - maximum ID
127       if (metaP->mem->freeid)
128         if (!StrToLongLong(smlPCDataToCharP(metaP->mem->freeid),fFreeID))
129           return false;
130     }
131     PDEBUGPRINTFX(DBG_REMOTEINFO,("Sync Meta provides memory constraints: FreeMem=" PRINTF_LLD ", FreeID=" PRINTF_LLD,PRINTF_LLD_ARG(fFreeMemory),PRINTF_LLD_ARG(fFreeID)));
132   }
133   return true;
134 } // TRemoteDataStore::remoteProcessSyncCmd
135
136
137 // SYNC command bracket end (but another might follow in next message)
138 bool TRemoteDataStore::remoteProcessSyncCmdEnd(void)
139 {
140   // %%% nop for now, %%% eventually obsolete
141   return true;
142 } // TRemoteDataStore::remoteProcessSyncCmdEnd
143
144
145 // end of all sync commands from client
146 bool TRemoteDataStore::endOfClientSyncCmds(void)
147 {
148   // %%% nop for now, %%% eventually obsolete
149   return true;
150 } // TRemoteDataStore::endOfClientSyncCmds
151
152
153 // set description structure of datastore
154 bool TRemoteDataStore::setDatastoreDevInf(
155   SmlDevInfDatastorePtr_t aDataStoreDevInfP,  // the datastore DevInf
156   TSyncItemTypePContainer &aLocalItemTypes,   // list to look up local types (for reference)
157   TSyncItemTypePContainer &aNewItemTypes      // list to add analyzed types if not already there
158 )
159 {
160   // get important info out of the structure
161   SYSYNC_TRY {
162     // - name (sourceRef)
163     fName=smlPCDataToCharP(aDataStoreDevInfP->sourceref);
164     #ifndef MINIMAL_CODE
165     // - displayname
166     fDisplayName=smlPCDataToCharP(aDataStoreDevInfP->displayname);
167     #endif
168     // - MaxGUIDsize
169     if (aDataStoreDevInfP->maxguidsize) {
170       if (!StrToLong(smlPCDataToCharP(aDataStoreDevInfP->maxguidsize),fMaxGUIDSize))
171         return false;
172     }
173     else {
174       PDEBUGPRINTFX(DBG_REMOTEINFO,("Datastore DevInf does not specify MaxGUIDSize -> using default"));
175     }
176     PDEBUGPRINTFX(DBG_REMOTEINFO+DBG_HOT,(
177       "Remote Datastore Name='%s', DisplayName='%s', MaxGUIDSize=%ld",
178       getName(),
179       getDisplayName(),
180       (long)fMaxGUIDSize
181     ));
182     PDEBUGPRINTFX(DBG_REMOTEINFO,(
183       "Preferred Rx='%s' version '%s', preferred Tx='%s' version '%s'",
184       smlPCDataToCharP(aDataStoreDevInfP->rxpref->cttype),
185       smlPCDataToCharP(aDataStoreDevInfP->rxpref->verct),
186       smlPCDataToCharP(aDataStoreDevInfP->txpref->cttype),
187       smlPCDataToCharP(aDataStoreDevInfP->txpref->verct)
188     ));
189     // - analyze DS 1.2 style datastore local CTCap
190     if (getSession()->getSyncMLVersion()>=syncml_vers_1_2) {
191       // analyze CTCaps (content type capabilities)
192       SmlDevInfCtcapListPtr_t ctlP = aDataStoreDevInfP->ctcap;
193       // loop through list
194       PDEBUGBLOCKDESC("RemoteTypes", "Analyzing remote types listed in datastore level CTCap");
195       if (getSession()->fIgnoreCTCap) {
196         // ignore CTCap
197         if (ctlP) {
198           PDEBUGPRINTFX(DBG_REMOTEINFO+DBG_HOT,("Remote rule prevents looking at CTCap"));
199         }
200       }
201       else {
202         while (ctlP) {
203           if (ctlP->data) {
204             // create appropriate remote data itemtypes
205             if (TSyncItemType::analyzeCTCapAndCreateItemTypes(
206               getSession(),
207               this, // this is the DS1.2 style where CTCap is related to this datastore
208               ctlP->data, // CTCap
209               aLocalItemTypes, // look up in local types for specialized classes
210               aNewItemTypes // add new item types here
211             )) {
212               // we have CTCap info of at least one remote type
213               getSession()->fRemoteDataTypesKnown=true;
214             }
215             else
216               return false;
217           }
218           // - go to next item
219           ctlP=ctlP->next;
220         } // while
221       }
222       PDEBUGENDBLOCK("RemoteTypes");
223     } // if >=DS1.2
224     // - analyze supported rx types
225     TSyncDataStore *relDsP = getSession()->getSyncMLVersion()>=syncml_vers_1_2 ? this : NULL;
226     fRxPrefItemTypeP=TSyncItemType::registerType(fSessionP,aDataStoreDevInfP->rxpref,aLocalItemTypes,aNewItemTypes,relDsP);
227     fRxItemTypes.push_back(fRxPrefItemTypeP);
228     registerTypes(fRxItemTypes,aDataStoreDevInfP->rx,aLocalItemTypes,aNewItemTypes,relDsP);
229     // - analyze supported tx types
230     fTxPrefItemTypeP=TSyncItemType::registerType(fSessionP,aDataStoreDevInfP->txpref,aLocalItemTypes,aNewItemTypes,relDsP);
231     fTxItemTypes.push_back(fTxPrefItemTypeP);
232     registerTypes(fTxItemTypes,aDataStoreDevInfP->tx,aLocalItemTypes,aNewItemTypes,relDsP);
233     // - Datastore Memory
234     if (aDataStoreDevInfP->dsmem) {
235       // datastore provides memory information
236       // Note: <Sync> command meta could override these with actual free info
237       // - max free bytes
238       if (aDataStoreDevInfP->dsmem->maxmem) {
239         if (!StrToLongLong(smlPCDataToCharP(aDataStoreDevInfP->dsmem->maxmem),fMaxMemory))
240           return false;
241         else
242           fFreeMemory=fMaxMemory; // default for free = max (sync meta might correct this)
243       }
244       // - maximum free ID
245       if (aDataStoreDevInfP->dsmem->maxid) {
246         if (!StrToLongLong(smlPCDataToCharP(aDataStoreDevInfP->dsmem->maxid),fMaxID))
247           return false;
248         else
249           fFreeID=fMaxID; // default for free = max (sync meta might correct this)
250       }
251       PDEBUGPRINTFX(DBG_REMOTEINFO,("DevInf provides DSMem: MaxMem=" PRINTF_LLD ", MaxID=" PRINTF_LLD,PRINTF_LLD_ARG(fFreeMemory),PRINTF_LLD_ARG(fMaxID)));
252     }
253   }
254   SYSYNC_CATCH (...)
255     DEBUGPRINTFX(DBG_ERROR,("******** setDatastoreDevInf caused exception"));
256     return false;
257   SYSYNC_ENDCATCH
258   return true;
259 } // TRemoteDataStore::setDatastoreDevInf
260
261
262 /* end of TRemoteDataStore implementation */
263
264 // eof