ECConversion.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. #include <kopano/platform.h>
  18. #include "soapH.h"
  19. #include "SOAPUtils.h"
  20. #include "ECDatabase.h"
  21. #include <kopano/stringutil.h>
  22. #include <sstream>
  23. #include "ECConversion.h"
  24. using namespace std;
  25. namespace KC {
  26. // Convert search criteria from zarafa-5.2x to zarafa-6 format
  27. ECRESULT ConvertSearchCriteria52XTo6XX(ECDatabase *lpDatabase, char* lpData, struct searchCriteria **lppNewSearchCriteria)
  28. {
  29. if (lpDatabase == NULL || lpData == NULL || lppNewSearchCriteria == NULL)
  30. return KCERR_INVALID_PARAMETER;
  31. ECRESULT er = erSuccess;
  32. DB_ROW lpDBRow = NULL;
  33. DB_RESULT lpDBResult;
  34. DB_LENGTHS lpDBLenths = NULL;
  35. std::string strQuery;
  36. unsigned int i;
  37. struct soap xmlsoap;
  38. struct searchCriteria *lpNewSearchCriteria = NULL;
  39. struct searchCriteria52X crit;
  40. std::string xmldata(lpData);
  41. std::istringstream xml(xmldata);
  42. // We use the soap serializer / deserializer to store the data
  43. soap_set_mode(&xmlsoap, SOAP_XML_TREE | SOAP_C_UTFSTRING);
  44. // Workaround for gsoap bug in which it does a set_mode on FD 0 (stdin) which causes soap_begin_recv to hang
  45. // until input is received
  46. xmlsoap.recvfd = -1;
  47. xmlsoap.is = &xml;
  48. soap_default_searchCriteria52X(&xmlsoap, &crit);
  49. if (soap_begin_recv(&xmlsoap) != 0) {
  50. er = KCERR_NETWORK_ERROR;
  51. goto exit;
  52. }
  53. soap_get_searchCriteria52X(&xmlsoap, &crit, "SearchCriteria", NULL);
  54. // We now have the object, allocated by xmlsoap object,
  55. if (soap_end_recv(&xmlsoap) != 0) {
  56. er = KCERR_NETWORK_ERROR;
  57. goto exit;
  58. }
  59. lpNewSearchCriteria = s_alloc<searchCriteria>(nullptr);
  60. memset(lpNewSearchCriteria, 0, sizeof(struct searchCriteria));
  61. // Do backward-compatibility fixup
  62. if (crit.lpRestrict) {
  63. // Copy the restriction
  64. er = CopyRestrictTable(NULL, crit.lpRestrict, &lpNewSearchCriteria->lpRestrict);
  65. if (er != erSuccess)
  66. goto exit;
  67. }
  68. lpNewSearchCriteria->ulFlags = crit.ulFlags;
  69. // EntryidList
  70. if (crit.lpFolders != nullptr && crit.lpFolders->__size > 0 &&
  71. crit.lpFolders->__ptr != nullptr) {
  72. lpNewSearchCriteria->lpFolders = s_alloc<struct entryList>(NULL);
  73. lpNewSearchCriteria->lpFolders->__ptr = s_alloc<entryId>(NULL, crit.lpFolders->__size);
  74. lpNewSearchCriteria->lpFolders->__size = 0;
  75. memset(lpNewSearchCriteria->lpFolders->__ptr, 0, sizeof(entryId) * crit.lpFolders->__size);
  76. // Get them from the database
  77. strQuery = "SELECT val_binary FROM indexedproperties WHERE tag=0x0FFF AND hierarchyid IN ("; //PR_ENTRYID
  78. for (i = 0; i < crit.lpFolders->__size; ++i) {
  79. if (i != 0)strQuery+= ",";
  80. strQuery+= stringify(crit.lpFolders->__ptr[i]);
  81. }
  82. strQuery+= ")";
  83. er = lpDatabase->DoSelect(strQuery, &lpDBResult);
  84. if(er != erSuccess)
  85. goto exit;
  86. while ((lpDBRow = lpDatabase->FetchRow(lpDBResult)))
  87. {
  88. lpDBLenths = lpDatabase->FetchRowLengths(lpDBResult);
  89. if (lpDBRow[0] == NULL)
  90. continue; // Skip row, old folder
  91. i = lpNewSearchCriteria->lpFolders->__size;
  92. lpNewSearchCriteria->lpFolders->__ptr[i].__ptr = s_alloc<unsigned char>(NULL, (unsigned int) lpDBLenths[0]);
  93. memcpy(lpNewSearchCriteria->lpFolders->__ptr[i].__ptr, (unsigned char*) lpDBRow[0], lpDBLenths[0]);
  94. lpNewSearchCriteria->lpFolders->__ptr[i].__size = (unsigned int) lpDBLenths[0];
  95. ++lpNewSearchCriteria->lpFolders->__size;
  96. }
  97. } //if (lpSearchCriteria...)
  98. soap_destroy(&xmlsoap);
  99. soap_end(&xmlsoap);
  100. soap_done(&xmlsoap);
  101. *lppNewSearchCriteria = lpNewSearchCriteria;
  102. exit:
  103. if (er != erSuccess && lpNewSearchCriteria)
  104. FreeSearchCriteria(lpNewSearchCriteria);
  105. return er;
  106. }
  107. } /* namespace */
  108. SOAP_FMAC3 void SOAP_FMAC4 soap_default_searchCriteria52X(struct soap *soap, struct searchCriteria52X *a)
  109. {
  110. (void)soap; (void)a; /* appease -Wall -Werror */
  111. a->lpRestrict = NULL;
  112. a->lpFolders = NULL;
  113. soap_default_unsignedInt(soap, &a->ulFlags);
  114. }
  115. SOAP_FMAC3 struct searchCriteria52X * SOAP_FMAC4 soap_get_searchCriteria52X(struct soap *soap, struct searchCriteria52X *p, const char *tag, const char *type)
  116. {
  117. if ((p = soap_in_searchCriteria52X(soap, tag, p, type)))
  118. soap_getindependent(soap);
  119. return p;
  120. }
  121. SOAP_FMAC3 struct searchCriteria52X * SOAP_FMAC4 soap_in_searchCriteria52X(struct soap *soap, const char *tag, struct searchCriteria52X *a, const char *type)
  122. {
  123. short soap_flag_lpRestrict = 1, soap_flag_lpFolders = 1, soap_flag_ulFlags = 1;
  124. if (soap_element_begin_in(soap, tag, 0, type))
  125. return NULL;
  126. if (*soap->type && soap_match_tag(soap, soap->type, type))
  127. { soap->error = SOAP_TYPE;
  128. return NULL;
  129. }
  130. a = (struct searchCriteria52X *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_searchCriteria, sizeof(struct searchCriteria52X), 0, NULL, NULL, NULL);
  131. if (!a)
  132. return NULL;
  133. soap_default_searchCriteria52X(soap, a);
  134. if (soap->body && !*soap->href)
  135. {
  136. for (;;)
  137. { soap->error = SOAP_TAG_MISMATCH;
  138. if (soap_flag_lpRestrict && soap->error == SOAP_TAG_MISMATCH)
  139. if (soap_in_PointerTorestrictTable(soap, "lpRestrict", &a->lpRestrict, "restrictTable")) {
  140. --soap_flag_lpRestrict;
  141. continue;
  142. }
  143. if (soap_flag_lpFolders && soap->error == SOAP_TAG_MISMATCH)
  144. if (soap_in_PointerToentryList52X(soap, "lpFolders", &a->lpFolders, "entryList")) {
  145. --soap_flag_lpFolders;
  146. continue;
  147. }
  148. if (soap_flag_ulFlags && soap->error == SOAP_TAG_MISMATCH)
  149. if (soap_in_unsignedInt(soap, "ulFlags", &a->ulFlags, "xsd:unsignedInt")) {
  150. --soap_flag_ulFlags;
  151. continue;
  152. }
  153. if (soap->error == SOAP_TAG_MISMATCH)
  154. soap->error = soap_ignore_element(soap);
  155. if (soap->error == SOAP_NO_TAG)
  156. break;
  157. if (soap->error)
  158. return NULL;
  159. }
  160. if ((soap->mode & SOAP_XML_STRICT) && soap_flag_ulFlags > 0)
  161. { soap->error = SOAP_OCCURS;
  162. return NULL;
  163. }
  164. if (soap_element_end_in(soap, tag))
  165. return NULL;
  166. }
  167. else
  168. {
  169. a = static_cast<struct searchCriteria52X *>(soap_id_forward(soap,
  170. soap->href, reinterpret_cast<void **>(a), 0,
  171. SOAP_TYPE_searchCriteria, 0, sizeof(*a), 0, NULL, NULL));
  172. if (soap->body && soap_element_end_in(soap, tag))
  173. return NULL;
  174. }
  175. return a;
  176. }
  177. SOAP_FMAC3 struct entryList52X ** SOAP_FMAC4 soap_in_PointerToentryList52X(struct soap *soap, const char *tag, struct entryList52X **a, const char *type)
  178. {
  179. if (soap_element_begin_in(soap, tag, 1, type))
  180. return NULL;
  181. if (!a)
  182. if (!(a = (struct entryList52X **)soap_malloc(soap, sizeof(struct entryList52X *))))
  183. return NULL;
  184. *a = NULL;
  185. if (!soap->null && *soap->href != '#')
  186. { soap_revert(soap);
  187. if (!(*a = soap_in_entryList52X(soap, tag, *a, type)))
  188. return NULL;
  189. }
  190. else
  191. {
  192. a = static_cast<struct entryList52X **>(soap_id_lookup(soap,
  193. soap->href, reinterpret_cast<void **>(a),
  194. SOAP_TYPE_entryList, sizeof(*a), 0, NULL));
  195. if (soap->body && soap_element_end_in(soap, tag))
  196. return NULL;
  197. }
  198. return a;
  199. }
  200. SOAP_FMAC3 struct entryList52X * SOAP_FMAC4 soap_in_entryList52X(struct soap *soap, const char *tag, struct entryList52X *a, const char *type)
  201. {
  202. short soap_flag___ptr = 1;
  203. if (soap_element_begin_in(soap, tag, 0, type))
  204. return NULL;
  205. if (*soap->type && soap_match_tag(soap, soap->type, type))
  206. { soap->error = SOAP_TYPE;
  207. return NULL;
  208. }
  209. a = (struct entryList52X *)soap_id_enter(soap, soap->id, a, SOAP_TYPE_entryList, sizeof(struct entryList52X), 0, NULL, NULL, NULL);
  210. if (!a)
  211. return NULL;
  212. soap_default_entryList52X(soap, a);
  213. if (soap->body && !*soap->href)
  214. {
  215. for (;;)
  216. { soap->error = SOAP_TAG_MISMATCH;
  217. if (soap_flag___ptr && soap->error == SOAP_TAG_MISMATCH)
  218. { unsigned int *p;
  219. soap_alloc_block(soap);
  220. for (a->__size = 0; !soap_element_begin_in(soap, "item", 1, type); ++a->__size) {
  221. p = (unsigned int *)soap_push_block(soap, NULL, sizeof(unsigned int));
  222. soap_default_unsignedInt(soap, p);
  223. soap_revert(soap);
  224. if (!soap_in_unsignedInt(soap, "item", p, "xsd:unsignedInt"))
  225. break;
  226. soap_flag___ptr = 0;
  227. }
  228. a->__ptr = (unsigned int *)soap_save_block(soap, NULL, NULL, 1);
  229. if (!soap_flag___ptr && soap->error == SOAP_TAG_MISMATCH)
  230. continue;
  231. }
  232. if (soap->error == SOAP_TAG_MISMATCH)
  233. soap->error = soap_ignore_element(soap);
  234. if (soap->error == SOAP_NO_TAG)
  235. break;
  236. if (soap->error)
  237. return NULL;
  238. }
  239. if (soap_element_end_in(soap, tag))
  240. return NULL;
  241. }
  242. else
  243. {
  244. a = static_cast<struct entryList52X *>(soap_id_forward(soap,
  245. soap->href, reinterpret_cast<void **>(a), 0,
  246. SOAP_TYPE_entryList, 0, sizeof(*a), 0, NULL, NULL));
  247. if (soap->body && soap_element_end_in(soap, tag))
  248. return NULL;
  249. }
  250. return a;
  251. }
  252. SOAP_FMAC3 void SOAP_FMAC4 soap_default_entryList52X(struct soap *soap, struct entryList52X *a)
  253. {
  254. (void)soap; (void)a; /* appease -Wall -Werror */
  255. a->__size = 0;
  256. a->__ptr = NULL;
  257. }