xmlrpc.c 78 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008
  1. /*
  2. This file is part of libXMLRPC - a C library for xml-encoded function calls.
  3. Author: Dan Libby (dan@libby.com)
  4. Epinions.com may be contacted at feedback@epinions-inc.com
  5. */
  6. /*
  7. Copyright 2000 Epinions, Inc.
  8. Subject to the following 3 conditions, Epinions, Inc. permits you, free
  9. of charge, to (a) use, copy, distribute, modify, perform and display this
  10. software and associated documentation files (the "Software"), and (b)
  11. permit others to whom the Software is furnished to do so as well.
  12. 1) The above copyright notice and this permission notice shall be included
  13. without modification in all copies or substantial portions of the
  14. Software.
  15. 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF
  16. ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY
  17. IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR
  18. PURPOSE OR NONINFRINGEMENT.
  19. 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
  21. OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING
  22. NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH
  23. DAMAGES.
  24. */
  25. static const char rcsid[] = "#(@) $Id$";
  26. /****h* ABOUT/xmlrpc
  27. * NAME
  28. * XMLRPC_VALUE
  29. * AUTHOR
  30. * Dan Libby, aka danda (dan@libby.com)
  31. * CREATION DATE
  32. * 9/1999 - 10/2000
  33. * HISTORY
  34. * $Log$
  35. * Revision 1.8.4.3.2.1 2008/09/10 00:07:44 felipe
  36. * MFH:
  37. * - Merged fix from SF project (Import Jeff Lawsons patches for XML datetime bug fixes)
  38. * Fixed bugs:
  39. * #45226 (xmlrpc_set_type() segfaults with valid ISO8601 date string)
  40. * #18916 (xmlrpc_set_type() "not working")
  41. *
  42. * Revision 1.8.4.3 2007/09/18 19:49:53 iliaa
  43. *
  44. * Fixed bug #42189 (xmlrpc_set_type() crashes php on invalid datetime
  45. * values).
  46. *
  47. * Revision 1.8.4.2 2007/06/07 09:07:36 tony2001
  48. * MFH: php_localtime_r() checks
  49. *
  50. * Revision 1.8.4.1 2006/11/30 16:38:37 iliaa
  51. * last set of zts fixes
  52. *
  53. * Revision 1.8 2005/03/28 00:07:24 edink
  54. * Reshufle includes to make it compile on windows
  55. *
  56. * Revision 1.7 2005/03/26 03:13:58 sniper
  57. * - Made it possible to build ext/xmlrpc with libxml2
  58. *
  59. * Revision 1.6 2004/04/27 17:33:59 iliaa
  60. * Removed C++ style comments.
  61. *
  62. * Revision 1.5 2003/12/16 21:00:21 sniper
  63. * Fix some compile warnings (patch by Joe Orton)
  64. *
  65. * Revision 1.4 2002/07/05 04:43:53 danda
  66. * merged in updates from SF project. bring php repository up to date with xmlrpc-epi version 0.51
  67. *
  68. * Revision 1.22 2002/03/09 23:15:44 danda
  69. * add fault interrogation funcs
  70. *
  71. * Revision 1.21 2002/03/09 22:27:41 danda
  72. * win32 build patches contributed by Jeff Lawson
  73. *
  74. * Revision 1.20 2002/02/13 20:58:50 danda
  75. * patch to make source more windows friendly, contributed by Jeff Lawson
  76. *
  77. * Revision 1.19 2001/10/12 23:25:54 danda
  78. * default to writing xmlrpc
  79. *
  80. * Revision 1.18 2001/09/29 21:58:05 danda
  81. * adding cvs log to history section
  82. *
  83. * 10/15/2000 -- danda -- adding robodoc documentation
  84. * 08/2000 -- danda -- PHP C extension that uses XMLRPC
  85. * 08/2000 -- danda -- support for two vocabularies: danda-rpc and xml-rpc
  86. * 09/1999 -- danda -- Initial API, before I even knew of standard XMLRPC vocab. Response only.
  87. * 07/2000 -- danda -- wrote new implementation to be compatible with xmlrpc standard and
  88. * incorporated some ideas from ensor, most notably the separation of
  89. * xml dom from xmlrpc api.
  90. * 06/2000 -- danda -- played with expat-ensor from www.ensor.org. Cool, but some flaws.
  91. * TODO
  92. * PORTABILITY
  93. * Coded on RedHat Linux 6.2. Builds on Solaris x86. Should build on just
  94. * about anything with minor mods.
  95. * NOTES
  96. * Welcome to XMLRPC. For more info on the specification and history, see
  97. * http://www.xmlrpc.org.
  98. *
  99. * This code aims to be a full-featured C implementation of XMLRPC. It does not
  100. * have any networking code. Rather, it is intended to be plugged into apps
  101. * or libraries with existing networking facilities, eg PHP, apache, perl, mozilla,
  102. * home-brew application servers, etc.
  103. *
  104. * Usage Paradigm:
  105. * The user of this library will typically be implementing either an XMLRPC server,
  106. * an XMLRPC client, or both. The client will use the library to build an in-memory
  107. * representation of a request, and then serialize (encode) that request into XML. The
  108. * client will then send the XML to the server via external mechanism. The server will
  109. * de-serialize the XML back into an binary representation, call the appropriate registered
  110. * method -- thereby generating a response. The response will be serialized into XML and
  111. * sent back to the client. The client will de-serialize it into memory, and can
  112. * iterate through the results via API.
  113. *
  114. * Both the request and the response may consist of arbitrarily long, arbitrarily nested
  115. * values. The values may be one of several types, as defined by XMLRPC_VALUE_TYPE.
  116. *
  117. * Features and Architecture:
  118. * - The XML parsing (xml_element.c) is completely independent of the XMLRPC api. In fact,
  119. * it can be used as a standalone dom implementation.
  120. * - Because of this, the same XMLRPC data can be serialized into multiple xml vocabularies.
  121. * It is simply a matter of writing a transport. So far, two transports have been defined.
  122. * The default xmlrpc vocab (xml_to_xmlrpc.c), and simple-rpc (xml_to_dandarpc.c) which is
  123. * proprietary, but imho more readable, and nice for proprietary legacy reasons.
  124. * - Various output options, including: xml escaping via CDATA or entity, case folding,
  125. * vocab version, and character encoding.
  126. * - One to One mapping between C structures and actual values, unlike ensor which forces
  127. * one to understand the arcana of the xmlrpc vocab.
  128. * - support for mixed indexed/keyed vector types, making it more compatible with
  129. * languages such as PHP.
  130. * - quite speedy compared to implementations written in interpreted languages. Also, uses
  131. * intelligent string handling, so not many strlen() calls, etc.
  132. * - comprehensive API for manipulation of values
  133. *******/
  134. #include "ext/xml/expat_compat.h"
  135. #include "main/php_reentrancy.h"
  136. #include <stdio.h>
  137. #include <stdlib.h>
  138. #include <string.h>
  139. #include <stdarg.h>
  140. #include <time.h>
  141. #include <ctype.h>
  142. #include "queue.h"
  143. #include "xmlrpc.h"
  144. #include "base64.h"
  145. #include "xml_to_xmlrpc.h"
  146. #include "xml_to_dandarpc.h"
  147. #include "xml_to_soap.h"
  148. #include "xml_element.h"
  149. #include "xmlrpc_private.h"
  150. #include "xmlrpc_introspection_private.h"
  151. #include "system_methods_private.h"
  152. /*-*********************
  153. * Begin Time Functions *
  154. ***********************/
  155. static time_t mkgmtime(struct tm *tm)
  156. {
  157. static const int mdays[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
  158. return ((((((tm->tm_year - 70) * 365) + mdays[tm->tm_mon] + tm->tm_mday-1 +
  159. (tm->tm_year-68-1+(tm->tm_mon>=2))/4) * 24) + tm->tm_hour) * 60 +
  160. tm->tm_min) * 60 + tm->tm_sec;
  161. }
  162. static int date_from_ISO8601 (const char *text, time_t * value) {
  163. struct tm tm;
  164. int n;
  165. int i;
  166. char buf[30];
  167. if (strchr (text, '-')) {
  168. char *p = (char *) text, *p2 = buf;
  169. while (p && *p) {
  170. if (*p != '-') {
  171. *p2 = *p;
  172. p2++;
  173. if (p2-buf >= sizeof(buf)) {
  174. return -1;
  175. }
  176. }
  177. p++;
  178. }
  179. *p2 = 0;
  180. text = buf;
  181. }
  182. if (strlen(text)<17) {
  183. return -1;
  184. }
  185. tm.tm_isdst = -1;
  186. #define XMLRPC_IS_NUMBER(x) if (x < '0' || x > '9') return -1;
  187. n = 1000;
  188. tm.tm_year = 0;
  189. for(i = 0; i < 4; i++) {
  190. XMLRPC_IS_NUMBER(text[i])
  191. tm.tm_year += (text[i]-'0')*n;
  192. n /= 10;
  193. }
  194. n = 10;
  195. tm.tm_mon = 0;
  196. for(i = 0; i < 2; i++) {
  197. XMLRPC_IS_NUMBER(text[i+4])
  198. tm.tm_mon += (text[i+4]-'0')*n;
  199. n /= 10;
  200. }
  201. tm.tm_mon --;
  202. if(tm.tm_mon < 0 || tm.tm_mon > 11) {
  203. return -1;
  204. }
  205. n = 10;
  206. tm.tm_mday = 0;
  207. for(i = 0; i < 2; i++) {
  208. XMLRPC_IS_NUMBER(text[i+6])
  209. tm.tm_mday += (text[i+6]-'0')*n;
  210. n /= 10;
  211. }
  212. n = 10;
  213. tm.tm_hour = 0;
  214. for(i = 0; i < 2; i++) {
  215. XMLRPC_IS_NUMBER(text[i+9])
  216. tm.tm_hour += (text[i+9]-'0')*n;
  217. n /= 10;
  218. }
  219. n = 10;
  220. tm.tm_min = 0;
  221. for(i = 0; i < 2; i++) {
  222. XMLRPC_IS_NUMBER(text[i+12])
  223. tm.tm_min += (text[i+12]-'0')*n;
  224. n /= 10;
  225. }
  226. n = 10;
  227. tm.tm_sec = 0;
  228. for(i = 0; i < 2; i++) {
  229. XMLRPC_IS_NUMBER(text[i+15])
  230. tm.tm_sec += (text[i+15]-'0')*n;
  231. n /= 10;
  232. }
  233. tm.tm_year -= 1900;
  234. *value = mkgmtime(&tm);
  235. return 0;
  236. }
  237. static int date_to_ISO8601 (time_t value, char *buf, int length) {
  238. struct tm *tm, tmbuf;
  239. tm = php_gmtime_r(&value, &tmbuf);
  240. if (!tm) {
  241. return 0;
  242. }
  243. #if 0 /* TODO: soap seems to favor this method. xmlrpc the latter. */
  244. return strftime (buf, length, "%Y-%m-%dT%H:%M:%SZ", tm);
  245. #else
  246. return strftime(buf, length, "%Y%m%dT%H:%M:%SZ", tm);
  247. #endif
  248. }
  249. /*-*******************
  250. * End Time Functions *
  251. *********************/
  252. /*-***************************
  253. * Begin XMLRPC_REQUEST funcs *
  254. *****************************/
  255. /****f* REQUEST/XMLRPC_RequestNew
  256. * NAME
  257. * XMLRPC_RequestNew
  258. * SYNOPSIS
  259. * XMLRPC_REQUEST XMLRPC_RequestNew()
  260. * FUNCTION
  261. * Creates a new XMLRPC_Request data struct
  262. * INPUTS
  263. * none
  264. * SEE ALSO
  265. * XMLRPC_RequestFree ()
  266. * SOURCE
  267. */
  268. XMLRPC_REQUEST XMLRPC_RequestNew() {
  269. XMLRPC_REQUEST xRequest = ecalloc(1, sizeof(STRUCT_XMLRPC_REQUEST));
  270. if(xRequest) {
  271. simplestring_init(&xRequest->methodName);
  272. }
  273. return xRequest;
  274. }
  275. /*******/
  276. /****f* REQUEST/XMLRPC_RequestFree
  277. * NAME
  278. * XMLRPC_RequestFree
  279. * SYNOPSIS
  280. * void XMLRPC_RequestFree(XMLRPC_REQUEST request, int bFreeIO)
  281. * FUNCTION
  282. * Free XMLRPC Request and all sub-values
  283. * INPUTS
  284. * request -- previously allocated request struct
  285. * bFreeIO -- 1 = also free request value data, if any, 0 = ignore.
  286. * SEE ALSO
  287. * XMLRPC_RequestNew ()
  288. * XMLRPC_CleanupValue ()
  289. * SOURCE
  290. */
  291. void XMLRPC_RequestFree(XMLRPC_REQUEST request, int bFreeIO) {
  292. if(request) {
  293. simplestring_free(&request->methodName);
  294. if(request->io && bFreeIO) {
  295. XMLRPC_CleanupValue(request->io);
  296. }
  297. if(request->error) {
  298. XMLRPC_CleanupValue(request->error);
  299. }
  300. my_free(request);
  301. }
  302. }
  303. /*******/
  304. /* Set Method Name to call */
  305. /****f* REQUEST/XMLRPC_RequestSetMethodName
  306. * NAME
  307. * XMLRPC_RequestSetMethodName
  308. * SYNOPSIS
  309. * const char* XMLRPC_RequestSetMethodName(XMLRPC_REQUEST request, const char* methodName)
  310. * FUNCTION
  311. * Set name of method to call with this request.
  312. * INPUTS
  313. * request -- previously allocated request struct
  314. * methodName -- name of method
  315. * SEE ALSO
  316. * XMLRPC_RequestNew ()
  317. * XMLRPC_RequestGetMethodName ()
  318. * XMLRPC_RequestFree ()
  319. * SOURCE
  320. */
  321. const char* XMLRPC_RequestSetMethodName(XMLRPC_REQUEST request, const char* methodName) {
  322. if(request) {
  323. simplestring_clear(&request->methodName);
  324. simplestring_add(&request->methodName, methodName);
  325. return request->methodName.str;
  326. }
  327. return NULL;
  328. }
  329. /*******/
  330. /****f* REQUEST/XMLRPC_RequestGetMethodName
  331. * NAME
  332. * XMLRPC_RequestGetMethodName
  333. * SYNOPSIS
  334. * const char* XMLRPC_RequestGetMethodName(XMLRPC_REQUEST request)
  335. * FUNCTION
  336. * Get name of method called by this request
  337. * INPUTS
  338. * request -- previously allocated request struct
  339. * SEE ALSO
  340. * XMLRPC_RequestNew ()
  341. * XMLRPC_RequestSetMethodName ()
  342. * XMLRPC_RequestFree ()
  343. * SOURCE
  344. */
  345. const char* XMLRPC_RequestGetMethodName(XMLRPC_REQUEST request) {
  346. return request ? request->methodName.str : NULL;
  347. }
  348. /*******/
  349. /****f* REQUEST/XMLRPC_RequestSetRequestType
  350. * NAME
  351. * XMLRPC_RequestSetRequestType
  352. * SYNOPSIS
  353. * XMLRPC_REQUEST_TYPE XMLRPC_RequestSetRequestType(XMLRPC_REQUEST request, XMLRPC_REQUEST_TYPE type)
  354. * FUNCTION
  355. * A request struct may be allocated by a caller or by xmlrpc
  356. * in response to a request. This allows setting the
  357. * request type.
  358. * INPUTS
  359. * request -- previously allocated request struct
  360. * type -- request type [xmlrpc_method_call | xmlrpc_method_response]
  361. * SEE ALSO
  362. * XMLRPC_RequestNew ()
  363. * XMLRPC_RequestGetRequestType ()
  364. * XMLRPC_RequestFree ()
  365. * XMLRPC_REQUEST_TYPE
  366. * SOURCE
  367. */
  368. XMLRPC_REQUEST_TYPE XMLRPC_RequestSetRequestType (XMLRPC_REQUEST request,
  369. XMLRPC_REQUEST_TYPE type) {
  370. if(request) {
  371. request->request_type = type;
  372. return request->request_type;
  373. }
  374. return xmlrpc_request_none;
  375. }
  376. /*******/
  377. /****f* REQUEST/XMLRPC_RequestGetRequestType
  378. * NAME
  379. * XMLRPC_RequestGetRequestType
  380. * SYNOPSIS
  381. * XMLRPC_REQUEST_TYPE XMLRPC_RequestGetRequestType(XMLRPC_REQUEST request)
  382. * FUNCTION
  383. * A request struct may be allocated by a caller or by xmlrpc
  384. * in response to a request. This allows setting the
  385. * request type.
  386. * INPUTS
  387. * request -- previously allocated request struct
  388. * RESULT
  389. * type -- request type [xmlrpc_method_call | xmlrpc_method_response]
  390. * SEE ALSO
  391. * XMLRPC_RequestNew ()
  392. * XMLRPC_RequestSetRequestType ()
  393. * XMLRPC_RequestFree ()
  394. * XMLRPC_REQUEST_TYPE
  395. * SOURCE
  396. */
  397. XMLRPC_REQUEST_TYPE XMLRPC_RequestGetRequestType(XMLRPC_REQUEST request) {
  398. return request ? request->request_type : xmlrpc_request_none;
  399. }
  400. /*******/
  401. /****f* REQUEST/XMLRPC_RequestSetData
  402. * NAME
  403. * XMLRPC_RequestSetData
  404. * SYNOPSIS
  405. * XMLRPC_VALUE XMLRPC_RequestSetData(XMLRPC_REQUEST request, XMLRPC_VALUE data)
  406. * FUNCTION
  407. * Associates a block of xmlrpc data with the request. The
  408. * data is *not* copied. A pointer is kept. The caller
  409. * should be careful not to doubly free the data value,
  410. * which may optionally be free'd by XMLRPC_RequestFree().
  411. * INPUTS
  412. * request -- previously allocated request struct
  413. * data -- previously allocated data struct
  414. * RESULT
  415. * XMLRPC_VALUE -- pointer to value stored, or NULL
  416. * SEE ALSO
  417. * XMLRPC_RequestNew ()
  418. * XMLRPC_RequestGetData ()
  419. * XMLRPC_RequestFree ()
  420. * XMLRPC_REQUEST
  421. * XMLRPC_VALUE
  422. * SOURCE
  423. */
  424. XMLRPC_VALUE XMLRPC_RequestSetData(XMLRPC_REQUEST request, XMLRPC_VALUE data) {
  425. if(request && data) {
  426. if (request->io) {
  427. XMLRPC_CleanupValue (request->io);
  428. }
  429. request->io = XMLRPC_CopyValue(data);
  430. return request->io;
  431. }
  432. return NULL;
  433. }
  434. /*******/
  435. /****f* REQUEST/XMLRPC_RequestGetData
  436. * NAME
  437. * XMLRPC_RequestGetData
  438. * SYNOPSIS
  439. * XMLRPC_VALUE XMLRPC_RequestGetData(XMLRPC_REQUEST request)
  440. * FUNCTION
  441. * Returns data associated with request, if any.
  442. * INPUTS
  443. * request -- previously allocated request struct
  444. * RESULT
  445. * XMLRPC_VALUE -- pointer to value stored, or NULL
  446. * SEE ALSO
  447. * XMLRPC_RequestNew ()
  448. * XMLRPC_RequestSetData ()
  449. * XMLRPC_RequestFree ()
  450. * XMLRPC_REQUEST
  451. * XMLRPC_VALUE
  452. * SOURCE
  453. */
  454. XMLRPC_VALUE XMLRPC_RequestGetData(XMLRPC_REQUEST request) {
  455. return request ? request->io : NULL;
  456. }
  457. /*******/
  458. /****f* REQUEST/XMLRPC_RequestSetError
  459. * NAME
  460. * XMLRPC_RequestSetError
  461. * SYNOPSIS
  462. * XMLRPC_VALUE XMLRPC_RequestSetError(XMLRPC_REQUEST request, XMLRPC_VALUE error)
  463. * FUNCTION
  464. * Associates a block of xmlrpc data, representing an error
  465. * condition, with the request.
  466. * INPUTS
  467. * request -- previously allocated request struct
  468. * error -- previously allocated error code or struct
  469. * RESULT
  470. * XMLRPC_VALUE -- pointer to value stored, or NULL
  471. * NOTES
  472. * This is a private function for usage by internals only.
  473. * SEE ALSO
  474. * XMLRPC_RequestGetError ()
  475. * SOURCE
  476. */
  477. XMLRPC_VALUE XMLRPC_RequestSetError (XMLRPC_REQUEST request, XMLRPC_VALUE error) {
  478. if (request && error) {
  479. if (request->error) {
  480. XMLRPC_CleanupValue (request->error);
  481. }
  482. request->error = XMLRPC_CopyValue (error);
  483. return request->error;
  484. }
  485. return NULL;
  486. }
  487. /*******/
  488. /****f* REQUEST/XMLRPC_RequestGetError
  489. * NAME
  490. * XMLRPC_RequestGetError
  491. * SYNOPSIS
  492. * XMLRPC_VALUE XMLRPC_RequestGetError(XMLRPC_REQUEST request)
  493. * FUNCTION
  494. * Returns error data associated with request, if any.
  495. * INPUTS
  496. * request -- previously allocated request struct
  497. * RESULT
  498. * XMLRPC_VALUE -- pointer to error value stored, or NULL
  499. * NOTES
  500. * This is a private function for usage by internals only.
  501. * SEE ALSO
  502. * XMLRPC_RequestSetError ()
  503. * XMLRPC_RequestFree ()
  504. * SOURCE
  505. */
  506. XMLRPC_VALUE XMLRPC_RequestGetError (XMLRPC_REQUEST request) {
  507. return request ? request->error : NULL;
  508. }
  509. /*******/
  510. /****f* REQUEST/XMLRPC_RequestSetOutputOptions
  511. * NAME
  512. * XMLRPC_RequestSetOutputOptions
  513. * SYNOPSIS
  514. * XMLRPC_REQUEST_OUTPUT_OPTIONS XMLRPC_RequestSetOutputOptions(XMLRPC_REQUEST request, XMLRPC_REQUEST_OUTPUT_OPTIONS output)
  515. * FUNCTION
  516. * Sets output options used for generating XML. The output struct
  517. * is copied, and may be freed by the caller.
  518. * INPUTS
  519. * request -- previously allocated request struct
  520. * output -- output options struct initialized by caller
  521. * RESULT
  522. * XMLRPC_REQUEST_OUTPUT_OPTIONS -- pointer to value stored, or NULL
  523. * SEE ALSO
  524. * XMLRPC_RequestNew ()
  525. * XMLRPC_RequestGetOutputOptions ()
  526. * XMLRPC_RequestFree ()
  527. * XMLRPC_REQUEST
  528. * XMLRPC_REQUEST_OUTPUT_OPTIONS
  529. * SOURCE
  530. */
  531. XMLRPC_REQUEST_OUTPUT_OPTIONS XMLRPC_RequestSetOutputOptions(XMLRPC_REQUEST request, XMLRPC_REQUEST_OUTPUT_OPTIONS output) {
  532. if(request && output) {
  533. memcpy (&request->output, output,
  534. sizeof (STRUCT_XMLRPC_REQUEST_OUTPUT_OPTIONS));
  535. return &request->output;
  536. }
  537. return NULL;
  538. }
  539. /*******/
  540. /****f* REQUEST/XMLRPC_RequestGetOutputOptions
  541. * NAME
  542. * XMLRPC_RequestGetOutputOptions
  543. * SYNOPSIS
  544. * XMLRPC_REQUEST_OUTPUT_OPTIONS XMLRPC_RequestGetOutputOptions(XMLRPC_REQUEST request)
  545. * FUNCTION
  546. * Gets a pointer to output options used for generating XML.
  547. * INPUTS
  548. * request -- previously allocated request struct
  549. * RESULT
  550. * XMLRPC_REQUEST_OUTPUT_OPTIONS -- pointer to options stored, or NULL
  551. * SEE ALSO
  552. * XMLRPC_RequestNew ()
  553. * XMLRPC_RequestSetOutputOptions ()
  554. * XMLRPC_RequestFree ()
  555. * XMLRPC_REQUEST
  556. * XMLRPC_REQUEST_OUTPUT_OPTIONS
  557. * SOURCE
  558. */
  559. XMLRPC_REQUEST_OUTPUT_OPTIONS XMLRPC_RequestGetOutputOptions(XMLRPC_REQUEST request) {
  560. return request ? &request->output : NULL;
  561. }
  562. /*******/
  563. /*-*************************
  564. * End XMLRPC_REQUEST funcs *
  565. ***************************/
  566. /*-***************************
  567. * Begin Serializiation funcs *
  568. *****************************/
  569. /****f* SERIALIZE/XMLRPC_VALUE_ToXML
  570. * NAME
  571. * XMLRPC_VALUE_ToXML
  572. * SYNOPSIS
  573. * char* XMLRPC_VALUE_ToXML(XMLRPC_VALUE val)
  574. * FUNCTION
  575. * encode XMLRPC_VALUE into XML buffer. Note that the generated
  576. * buffer will not contain a methodCall.
  577. * INPUTS
  578. * val -- previously allocated XMLRPC_VALUE
  579. * buf_len -- length of returned buffer, if not null
  580. * RESULT
  581. * char* -- newly allocated buffer containing XML.
  582. * It is the caller's responsibility to free it.
  583. * SEE ALSO
  584. * XMLRPC_REQUEST_ToXML ()
  585. * XMLRPC_VALUE_FromXML ()
  586. * XMLRPC_Free ()
  587. * XMLRPC_VALUE
  588. * SOURCE
  589. */
  590. char* XMLRPC_VALUE_ToXML(XMLRPC_VALUE val, int* buf_len) {
  591. xml_element *root_elem = XMLRPC_VALUE_to_xml_element(val);
  592. char* pRet = NULL;
  593. if(root_elem) {
  594. pRet = xml_elem_serialize_to_string(root_elem, NULL, buf_len);
  595. xml_elem_free(root_elem);
  596. }
  597. return pRet;
  598. }
  599. /*******/
  600. /****f* SERIALIZE/XMLRPC_REQUEST_ToXML
  601. * NAME
  602. * XMLRPC_REQUEST_ToXML
  603. * SYNOPSIS
  604. * char* XMLRPC_REQUEST_ToXML(XMLRPC_REQUEST request)
  605. * FUNCTION
  606. * encode XMLRPC_REQUEST into XML buffer
  607. * INPUTS
  608. * request -- previously allocated XMLRPC_REQUEST
  609. * buf_len -- size of returned buf, if not null
  610. * RESULT
  611. * char* -- newly allocated buffer containing XML.
  612. * It is the caller's responsibility to free it.
  613. * SEE ALSO
  614. * XMLRPC_REQUEST_ToXML ()
  615. * XMLRPC_REQUEST_FromXML ()
  616. * XMLRPC_Free ()
  617. * XMLRPC_VALUE_ToXML ()
  618. * XMLRPC_REQUEST
  619. * SOURCE
  620. */
  621. char* XMLRPC_REQUEST_ToXML(XMLRPC_REQUEST request, int* buf_len) {
  622. char* pRet = NULL;
  623. if (request) {
  624. xml_element *root_elem = NULL;
  625. if (request->output.version == xmlrpc_version_simple) {
  626. root_elem = DANDARPC_REQUEST_to_xml_element (request);
  627. }
  628. else if (request->output.version == xmlrpc_version_1_0 ||
  629. request->output.version == xmlrpc_version_none) {
  630. root_elem = XMLRPC_REQUEST_to_xml_element (request);
  631. }
  632. else if (request->output.version == xmlrpc_version_soap_1_1) {
  633. root_elem = SOAP_REQUEST_to_xml_element (request);
  634. }
  635. if(root_elem) {
  636. pRet =
  637. xml_elem_serialize_to_string (root_elem,
  638. &request->output.xml_elem_opts,
  639. buf_len);
  640. xml_elem_free(root_elem);
  641. }
  642. }
  643. return pRet;
  644. }
  645. /*******/
  646. /****f* SERIALIZE/XMLRPC_VALUE_FromXML
  647. * NAME
  648. * XMLRPC_VALUE_FromXML
  649. * SYNOPSIS
  650. * XMLRPC_VALUE XMLRPC_VALUE_FromXML(const char* in_buf, int le
  651. * FUNCTION
  652. * Retrieve XMLRPC_VALUE from XML buffer. Note that this will
  653. * ignore any methodCall. See XMLRPC_REQUEST_FromXML
  654. * INPUTS
  655. * in_buf -- character buffer containing XML
  656. * len -- length of buffer
  657. * RESULT
  658. * XMLRPC_VALUE -- newly allocated data, or NULL if error. Should
  659. * be free'd by caller.
  660. * SEE ALSO
  661. * XMLRPC_VALUE_ToXML ()
  662. * XMLRPC_REQUEST_FromXML ()
  663. * XMLRPC_VALUE
  664. * SOURCE
  665. */
  666. XMLRPC_VALUE XMLRPC_VALUE_FromXML (const char *in_buf, int len, XMLRPC_REQUEST_INPUT_OPTIONS in_options) {
  667. XMLRPC_VALUE xResponse = NULL;
  668. XMLRPC_REQUEST req = XMLRPC_REQUEST_FromXML(in_buf, len, in_options);
  669. if(req) {
  670. xResponse = req->io;
  671. XMLRPC_RequestFree(req, 0);
  672. }
  673. return xResponse;
  674. }
  675. /*******/
  676. /* map parser errors to standard xml-rpc errors */
  677. static XMLRPC_VALUE map_expat_errors(XML_ELEM_ERROR error) {
  678. XMLRPC_VALUE xReturn = NULL;
  679. if(error) {
  680. XMLRPC_ERROR_CODE code;
  681. char buf[1024];
  682. snprintf(buf, sizeof(buf),
  683. "error occurred at line %ld, column %ld, byte index %ld",
  684. error->line, error->column, error->byte_index);
  685. /* expat specific errors */
  686. switch(error->parser_code) {
  687. case XML_ERROR_UNKNOWN_ENCODING:
  688. code = xmlrpc_error_parse_unknown_encoding;
  689. break;
  690. case XML_ERROR_INCORRECT_ENCODING:
  691. code = xmlrpc_error_parse_bad_encoding;
  692. break;
  693. default:
  694. code = xmlrpc_error_parse_xml_syntax;
  695. break;
  696. }
  697. xReturn = XMLRPC_UtilityCreateFault(code, buf);
  698. }
  699. return xReturn;
  700. }
  701. /****f* SERIALIZE/XMLRPC_REQUEST_FromXML
  702. * NAME
  703. * XMLRPC_REQUEST_FromXML
  704. * SYNOPSIS
  705. * XMLRPC_REQUEST XMLRPC_REQUEST_FromXML(const char* in_buf, int le
  706. * FUNCTION
  707. * Retrieve XMLRPC_REQUEST from XML buffer
  708. * INPUTS
  709. * in_buf -- character buffer containing XML
  710. * len -- length of buffer
  711. * RESULT
  712. * XMLRPC_REQUEST -- newly allocated data, or NULL if error. Should
  713. * be free'd by caller.
  714. * SEE ALSO
  715. * XMLRPC_REQUEST_ToXML ()
  716. * XMLRPC_VALUE_FromXML ()
  717. * XMLRPC_REQUEST
  718. * SOURCE
  719. */
  720. XMLRPC_REQUEST XMLRPC_REQUEST_FromXML (const char *in_buf, int len,
  721. XMLRPC_REQUEST_INPUT_OPTIONS in_options) {
  722. XMLRPC_REQUEST request = XMLRPC_RequestNew();
  723. STRUCT_XML_ELEM_ERROR error = {0};
  724. if(request) {
  725. xml_element *root_elem =
  726. xml_elem_parse_buf (in_buf, len,
  727. (in_options ? &in_options->xml_elem_opts : NULL),
  728. &error);
  729. if(root_elem) {
  730. if(!strcmp(root_elem->name, "simpleRPC")) {
  731. request->output.version = xmlrpc_version_simple;
  732. xml_element_to_DANDARPC_REQUEST(request, root_elem);
  733. }
  734. else if (!strcmp (root_elem->name, "SOAP-ENV:Envelope")) {
  735. request->output.version = xmlrpc_version_soap_1_1;
  736. xml_element_to_SOAP_REQUEST (request, root_elem);
  737. }
  738. else {
  739. request->output.version = xmlrpc_version_1_0;
  740. xml_element_to_XMLRPC_REQUEST(request, root_elem);
  741. }
  742. xml_elem_free(root_elem);
  743. }
  744. else {
  745. if(error.parser_error) {
  746. XMLRPC_RequestSetError (request, map_expat_errors (&error));
  747. }
  748. }
  749. }
  750. return request;
  751. }
  752. /*******/
  753. /*-************************
  754. * End Serialization Funcs *
  755. **************************/
  756. /****f* VALUE/XMLRPC_CreateValueEmpty
  757. * NAME
  758. * XMLRPC_CreateValueEmpty
  759. * SYNOPSIS
  760. * XMLRPC_VALUE XMLRPC_CreateValueEmpty ()
  761. * FUNCTION
  762. * Create an XML value to be used/modified elsewhere.
  763. * INPUTS
  764. * RESULT
  765. * XMLRPC_VALUE. The new value, or NULL on failure.
  766. * SEE ALSO
  767. * XMLRPC_CleanupValue ()
  768. * XMLRPC_VALUE
  769. * SOURCE
  770. */
  771. XMLRPC_VALUE XMLRPC_CreateValueEmpty() {
  772. XMLRPC_VALUE v = ecalloc(1, sizeof(STRUCT_XMLRPC_VALUE));
  773. if(v) {
  774. #ifdef XMLRPC_DEBUG_REFCOUNT
  775. printf ("calloc'd 0x%x\n", v);
  776. #endif
  777. v->type = xmlrpc_empty;
  778. simplestring_init(&v->id);
  779. simplestring_init(&v->str);
  780. }
  781. return v;
  782. }
  783. /*******/
  784. /****f* VALUE/XMLRPC_SetValueID_Case
  785. * NAME
  786. * XMLRPC_SetValueID_Case
  787. * SYNOPSIS
  788. * const char *XMLRPC_SetValueID_Case(XMLRPC_VALUE value, const char* id, int len, XMLRPC_CASE id_case)
  789. * FUNCTION
  790. * Assign an ID (key) to an XMLRPC value.
  791. * INPUTS
  792. * value The xml value who's ID we will set.
  793. * id The desired new id.
  794. * len length of id string if known, or 0 if unknown.
  795. * id_case one of XMLRPC_CASE
  796. * RESULT
  797. * const char* pointer to the newly allocated id string, or NULL
  798. * SEE ALSO
  799. * XMLRPC_SetValueID ()
  800. * XMLRPC_GetValueID ()
  801. * XMLRPC_VALUE
  802. * XMLRPC_CASE
  803. * SOURCE
  804. */
  805. const char *XMLRPC_SetValueID_Case(XMLRPC_VALUE value, const char* id, int len, XMLRPC_CASE id_case) {
  806. const char* pRetval = NULL;
  807. if(value) {
  808. if(id) {
  809. simplestring_clear(&value->id);
  810. (len > 0) ? simplestring_addn(&value->id, id, len) :
  811. simplestring_add(&value->id, id);
  812. /* upper or lower case string in place if required. could be a separate func. */
  813. if(id_case == xmlrpc_case_lower || id_case == xmlrpc_case_upper) {
  814. int i;
  815. for(i = 0; i < value->id.len; i++) {
  816. value->id.str[i] =
  817. (id_case ==
  818. xmlrpc_case_lower) ? tolower (value->id.
  819. str[i]) : toupper (value->
  820. id.
  821. str[i]);
  822. }
  823. }
  824. pRetval = value->id.str;
  825. #ifdef XMLRPC_DEBUG_REFCOUNT
  826. printf("set value id: %s\n", pRetval);
  827. #endif
  828. }
  829. }
  830. return pRetval;
  831. }
  832. /*******/
  833. /****f* VALUE/XMLRPC_SetValueString
  834. * NAME
  835. * XMLRPC_SetValueString
  836. * SYNOPSIS
  837. * const char *XMLRPC_SetValueString(XMLRPC_VALUE value, const char* val, int len)
  838. * FUNCTION
  839. * Assign a string value to an XMLRPC_VALUE, and set it to type xmlrpc_string
  840. * INPUTS
  841. * value The xml value who's ID we will set.
  842. * val The desired new string val.
  843. * len length of val string if known, or 0 if unknown.
  844. * RESULT
  845. * const char* pointer to the newly allocated value string, or NULL
  846. * SEE ALSO
  847. * XMLRPC_GetValueString ()
  848. * XMLRPC_VALUE
  849. * XMLRPC_VALUE_TYPE
  850. * SOURCE
  851. */
  852. const char *XMLRPC_SetValueString(XMLRPC_VALUE value, const char* val, int len) {
  853. char *pRetval = NULL;
  854. if(value && val) {
  855. simplestring_clear(&value->str);
  856. (len > 0) ? simplestring_addn(&value->str, val, len) :
  857. simplestring_add(&value->str, val);
  858. value->type = xmlrpc_string;
  859. pRetval = (char *)value->str.str;
  860. }
  861. return pRetval;
  862. }
  863. /*******/
  864. /****f* VALUE/XMLRPC_SetValueInt
  865. * NAME
  866. * XMLRPC_SetValueInt
  867. * SYNOPSIS
  868. * void XMLRPC_SetValueInt(XMLRPC_VALUE value, int val)
  869. * FUNCTION
  870. * Assign an int value to an XMLRPC_VALUE, and set it to type xmlrpc_int
  871. * INPUTS
  872. * value The xml value who's ID we will set.
  873. * val The desired new integer value
  874. * RESULT
  875. * SEE ALSO
  876. * XMLRPC_GetValueInt ()
  877. * XMLRPC_VALUE
  878. * XMLRPC_VALUE_TYPE
  879. * SOURCE
  880. */
  881. void XMLRPC_SetValueInt(XMLRPC_VALUE value, int val) {
  882. if(value) {
  883. value->type = xmlrpc_int;
  884. value->i = val;
  885. }
  886. }
  887. /*******/
  888. /****f* VALUE/XMLRPC_SetValueBoolean
  889. * NAME
  890. * XMLRPC_SetValueBoolean
  891. * SYNOPSIS
  892. * void XMLRPC_SetValueBoolean(XMLRPC_VALUE value, int val)
  893. * FUNCTION
  894. * Assign a boolean value to an XMLRPC_VALUE, and set it to type xmlrpc_boolean
  895. * INPUTS
  896. * value The xml value who's value we will set.
  897. * val The desired new boolean value. [0 | 1]
  898. * RESULT
  899. * SEE ALSO
  900. * XMLRPC_GetValueBoolean ()
  901. * XMLRPC_VALUE
  902. * XMLRPC_VALUE_TYPE
  903. * SOURCE
  904. */
  905. void XMLRPC_SetValueBoolean(XMLRPC_VALUE value, int val) {
  906. if(value) {
  907. value->type = xmlrpc_boolean;
  908. value->i = val ? 1 : 0;
  909. }
  910. }
  911. /*******/
  912. /****f* VECTOR/XMLRPC_SetIsVector
  913. * NAME
  914. * XMLRPC_SetIsVector
  915. * SYNOPSIS
  916. * int XMLRPC_SetIsVector(XMLRPC_VALUE value, XMLRPC_VECTOR_TYPE type)
  917. * FUNCTION
  918. * Set the XMLRPC_VALUE to be a vector (list) type. The vector may be one of
  919. * [xmlrpc_array | xmlrpc_struct | xmlrpc_mixed]. An array has only index values.
  920. * A struct has key/val pairs. Mixed allows both index and key/val combinations.
  921. * INPUTS
  922. * value The xml value who's vector type we will set
  923. * type New type of vector as enumerated by XMLRPC_VECTOR_TYPE
  924. * RESULT
  925. * int 1 if successful, 0 otherwise
  926. * SEE ALSO
  927. * XMLRPC_GetValueType ()
  928. * XMLRPC_GetVectorType ()
  929. * XMLRPC_VALUE
  930. * XMLRPC_VECTOR_TYPE
  931. * XMLRPC_VALUE_TYPE
  932. * SOURCE
  933. */
  934. int XMLRPC_SetIsVector(XMLRPC_VALUE value, XMLRPC_VECTOR_TYPE type) {
  935. int bSuccess = 0;
  936. if (value) {
  937. /* we can change the type so long as nothing is currently stored. */
  938. if(value->type == xmlrpc_vector) {
  939. if(value->v) {
  940. if(!Q_Size(value->v->q)) {
  941. value->v->type = type;
  942. }
  943. }
  944. }
  945. else {
  946. value->v = ecalloc(1, sizeof(STRUCT_XMLRPC_VECTOR));
  947. if(value->v) {
  948. value->v->q = (queue*)emalloc(sizeof(queue));
  949. if(value->v->q) {
  950. Q_Init(value->v->q);
  951. value->v->type = type;
  952. value->type = xmlrpc_vector;
  953. bSuccess = 1;
  954. }
  955. }
  956. }
  957. }
  958. return bSuccess;
  959. }
  960. /*******/
  961. /****f* VECTOR/XMLRPC_CreateVector
  962. * NAME
  963. * XMLRPC_CreateVector
  964. * SYNOPSIS
  965. * XMLRPC_VALUE XMLRPC_CreateVector(const char* id, XMLRPC_VECTOR_TYPE type)
  966. * FUNCTION
  967. * Create a new vector and optionally set an id.
  968. * INPUTS
  969. * id The id of the vector, or NULL
  970. * type New type of vector as enumerated by XMLRPC_VECTOR_TYPE
  971. * RESULT
  972. * XMLRPC_VALUE The new vector, or NULL on failure.
  973. * SEE ALSO
  974. * XMLRPC_CreateValueEmpty ()
  975. * XMLRPC_SetIsVector ()
  976. * XMLRPC_GetValueType ()
  977. * XMLRPC_GetVectorType ()
  978. * XMLRPC_VALUE
  979. * XMLRPC_VECTOR_TYPE
  980. * XMLRPC_VALUE_TYPE
  981. * SOURCE
  982. */
  983. XMLRPC_VALUE XMLRPC_CreateVector(const char* id, XMLRPC_VECTOR_TYPE type) {
  984. XMLRPC_VALUE val = NULL;
  985. val = XMLRPC_CreateValueEmpty();
  986. if(val) {
  987. if(XMLRPC_SetIsVector(val, type)) {
  988. if(id) {
  989. const char *pSVI = NULL;
  990. pSVI = XMLRPC_SetValueID(val, id, 0);
  991. if(NULL == pSVI) {
  992. val = NULL;
  993. }
  994. }
  995. }
  996. else {
  997. val = NULL;
  998. }
  999. }
  1000. return val;
  1001. }
  1002. /*******/
  1003. /* Not yet implemented.
  1004. *
  1005. * This should use a hash to determine if a given target id has already
  1006. * been appended.
  1007. *
  1008. * Alternately, it could walk the entire vector, but that could be quite
  1009. * slow for very large lists.
  1010. */
  1011. static int isDuplicateEntry(XMLRPC_VALUE target, XMLRPC_VALUE source) {
  1012. return 0;
  1013. }
  1014. /****f* VECTOR/XMLRPC_AddValueToVector
  1015. * NAME
  1016. * XMLRPC_AddValueToVector
  1017. * SYNOPSIS
  1018. * int XMLRPC_AddValueToVector(XMLRPC_VALUE target, XMLRPC_VALUE source)
  1019. * FUNCTION
  1020. * Add (append) an existing XMLRPC_VALUE to a vector.
  1021. * INPUTS
  1022. * target The target vector
  1023. * source The source value to append
  1024. * RESULT
  1025. * int 1 if successful, else 0
  1026. * SEE ALSO
  1027. * XMLRPC_AddValuesToVector ()
  1028. * XMLRPC_VectorGetValueWithID_Case ()
  1029. * XMLRPC_VALUE
  1030. * NOTES
  1031. * The function will fail and return 0 if an attempt is made to add
  1032. * a value with an ID into a vector of type xmlrpc_vector_array. Such
  1033. * values can only be added to xmlrpc_vector_struct.
  1034. * SOURCE
  1035. */
  1036. int XMLRPC_AddValueToVector(XMLRPC_VALUE target, XMLRPC_VALUE source) {
  1037. if(target && source) {
  1038. if(target->type == xmlrpc_vector && target->v &&
  1039. target->v->q && target->v->type != xmlrpc_vector_none) {
  1040. /* guard against putting value of unknown type into vector */
  1041. switch(source->type) {
  1042. case xmlrpc_empty:
  1043. case xmlrpc_base64:
  1044. case xmlrpc_boolean:
  1045. case xmlrpc_datetime:
  1046. case xmlrpc_double:
  1047. case xmlrpc_int:
  1048. case xmlrpc_string:
  1049. case xmlrpc_vector:
  1050. /* Guard against putting a key/val pair into an array vector */
  1051. if( !(source->id.len && target->v->type == xmlrpc_vector_array) ) {
  1052. if (isDuplicateEntry (target, source)
  1053. || Q_PushTail (target->v->q, XMLRPC_CopyValue (source))) {
  1054. return 1;
  1055. }
  1056. }
  1057. else {
  1058. /* fprintf (stderr,
  1059. "xmlrpc: attempted to add key/val pair to vector of type array\n"); */
  1060. }
  1061. break;
  1062. default:
  1063. /* fprintf (stderr,
  1064. "xmlrpc: attempted to add value of unknown type to vector\n"); */
  1065. break;
  1066. }
  1067. }
  1068. }
  1069. return 0;
  1070. }
  1071. /*******/
  1072. /****f* VECTOR/XMLRPC_AddValuesToVector
  1073. * NAME
  1074. * XMLRPC_AddValuesToVector
  1075. * SYNOPSIS
  1076. * XMLRPC_AddValuesToVector ( target, val1, val2, val3, val(n), 0 )
  1077. * XMLRPC_AddValuesToVector( XMLRPC_VALUE, ... )
  1078. * FUNCTION
  1079. * Add (append) a series of existing XMLRPC_VALUE to a vector.
  1080. * INPUTS
  1081. * target The target vector
  1082. * ... The source value(s) to append. The last item *must* be 0.
  1083. * RESULT
  1084. * int 1 if successful, else 0
  1085. * SEE ALSO
  1086. * XMLRPC_AddValuesToVector ()
  1087. * XMLRPC_VectorGetValueWithID_Case ()
  1088. * XMLRPC_VALUE
  1089. * NOTES
  1090. * This function may actually return failure after it has already modified
  1091. * or added items to target. You can not trust the state of target
  1092. * if this function returns failure.
  1093. * SOURCE
  1094. */
  1095. int XMLRPC_AddValuesToVector(XMLRPC_VALUE target, ...) {
  1096. int iRetval = 0;
  1097. if(target) {
  1098. if(target->type == xmlrpc_vector) {
  1099. XMLRPC_VALUE v = NULL;
  1100. va_list vl;
  1101. va_start(vl, target);
  1102. do {
  1103. v = va_arg(vl, XMLRPC_VALUE);
  1104. if(v) {
  1105. if(!XMLRPC_AddValueToVector(target, v)) {
  1106. iRetval = 0;
  1107. break;
  1108. }
  1109. }
  1110. }
  1111. while (v);
  1112. va_end(vl);
  1113. if(NULL == v) {
  1114. iRetval = 1;
  1115. }
  1116. }
  1117. }
  1118. return iRetval;
  1119. }
  1120. /*******/
  1121. /****f* VECTOR/XMLRPC_VectorGetValueWithID_Case
  1122. * NAME
  1123. * XMLRPC_VectorGetValueWithID_Case
  1124. * SYNOPSIS
  1125. * XMLRPC_VALUE XMLRPC_VectorGetValueWithID_Case(XMLRPC_VALUE vector, const char* id, XMLRPC_CASE_COMPARISON id_case)
  1126. * FUNCTION
  1127. * Get value from vector matching id (key)
  1128. * INPUTS
  1129. * vector The source vector
  1130. * id The key to find
  1131. * id_case Rule for how to match key
  1132. * RESULT
  1133. * int 1 if successful, else 0
  1134. * SEE ALSO
  1135. * XMLRPC_SetValueID_Case ()
  1136. * XMLRPC_VALUE
  1137. * XMLRPC_CASE_COMPARISON
  1138. * SOURCE
  1139. */
  1140. XMLRPC_VALUE XMLRPC_VectorGetValueWithID_Case (XMLRPC_VALUE vector, const char *id,
  1141. XMLRPC_CASE_COMPARISON id_case) {
  1142. if(vector && vector->v && vector->v->q) {
  1143. q_iter qi = Q_Iter_Head_F(vector->v->q);
  1144. while(qi) {
  1145. XMLRPC_VALUE xIter = Q_Iter_Get_F(qi);
  1146. if(xIter && xIter->id.str) {
  1147. if(id_case == xmlrpc_case_sensitive) {
  1148. if(!strcmp(xIter->id.str, id)) {
  1149. return xIter;
  1150. }
  1151. }
  1152. else if(id_case == xmlrpc_case_insensitive) {
  1153. if(!strcasecmp(xIter->id.str, id)) {
  1154. return xIter;
  1155. }
  1156. }
  1157. }
  1158. qi = Q_Iter_Next_F(qi);
  1159. }
  1160. }
  1161. return NULL;
  1162. }
  1163. /*******/
  1164. int XMLRPC_VectorRemoveValue(XMLRPC_VALUE vector, XMLRPC_VALUE value) {
  1165. if(vector && vector->v && vector->v->q && value) {
  1166. q_iter qi = Q_Iter_Head_F(vector->v->q);
  1167. while(qi) {
  1168. XMLRPC_VALUE xIter = Q_Iter_Get_F(qi);
  1169. if(xIter == value) {
  1170. XMLRPC_CleanupValue(xIter);
  1171. Q_Iter_Del(vector->v->q, qi);
  1172. return 1;
  1173. }
  1174. qi = Q_Iter_Next_F(qi);
  1175. }
  1176. }
  1177. return 0;
  1178. }
  1179. /****f* VALUE/XMLRPC_CreateValueString
  1180. * NAME
  1181. * XMLRPC_CreateValueString
  1182. * SYNOPSIS
  1183. * XMLRPC_VALUE XMLRPC_CreateValueString(const char* id, const char* val, int len)
  1184. * FUNCTION
  1185. * Create an XMLRPC_VALUE, and assign a string to it
  1186. * INPUTS
  1187. * id The id of the value, or NULL
  1188. * val The desired new string val.
  1189. * len length of val string if known, or 0 if unknown.
  1190. * RESULT
  1191. * newly allocated XMLRPC_VALUE, or NULL
  1192. * SEE ALSO
  1193. * XMLRPC_GetValueString ()
  1194. * XMLRPC_CreateValueEmpty ()
  1195. * XMLRPC_VALUE
  1196. * XMLRPC_VALUE_TYPE
  1197. * SOURCE
  1198. */
  1199. XMLRPC_VALUE XMLRPC_CreateValueString(const char* id, const char* val, int len) {
  1200. XMLRPC_VALUE value = NULL;
  1201. if(val) {
  1202. value = XMLRPC_CreateValueEmpty();
  1203. if(value) {
  1204. XMLRPC_SetValueString(value, val, len);
  1205. if(id) {
  1206. XMLRPC_SetValueID(value, id, 0);
  1207. }
  1208. }
  1209. }
  1210. return value;
  1211. }
  1212. /*******/
  1213. /****f* VALUE/XMLRPC_CreateValueInt
  1214. * NAME
  1215. * XMLRPC_CreateValueInt
  1216. * SYNOPSIS
  1217. * XMLRPC_VALUE XMLRPC_CreateValueInt(const char* id, int i)
  1218. * FUNCTION
  1219. * Create an XMLRPC_VALUE, and assign an int to it
  1220. * INPUTS
  1221. * id The id of the value, or NULL
  1222. * i The desired new int val.
  1223. * RESULT
  1224. * newly allocated XMLRPC_VALUE, or NULL
  1225. * SEE ALSO
  1226. * XMLRPC_GetValueInt ()
  1227. * XMLRPC_CreateValueEmpty ()
  1228. * XMLRPC_VALUE
  1229. * XMLRPC_VALUE_TYPE
  1230. * SOURCE
  1231. */
  1232. XMLRPC_VALUE XMLRPC_CreateValueInt(const char* id, int i) {
  1233. XMLRPC_VALUE val = XMLRPC_CreateValueEmpty();
  1234. if(val) {
  1235. XMLRPC_SetValueInt(val, i);
  1236. if(id) {
  1237. XMLRPC_SetValueID(val, id, 0);
  1238. }
  1239. }
  1240. return val;
  1241. }
  1242. /*******/
  1243. /****f* VALUE/XMLRPC_CreateValueBoolean
  1244. * NAME
  1245. * XMLRPC_CreateValueBoolean
  1246. * SYNOPSIS
  1247. * XMLRPC_VALUE XMLRPC_CreateValueBoolean(const char* id, int i)
  1248. * FUNCTION
  1249. * Create an XMLRPC_VALUE, and assign an int to it
  1250. * INPUTS
  1251. * id The id of the value, or NULL
  1252. * i The desired new int val.
  1253. * RESULT
  1254. * newly allocated XMLRPC_VALUE, or NULL
  1255. * SEE ALSO
  1256. * XMLRPC_GetValueBoolean ()
  1257. * XMLRPC_CreateValueEmpty ()
  1258. * XMLRPC_VALUE
  1259. * XMLRPC_VALUE_TYPE
  1260. * SOURCE
  1261. */
  1262. XMLRPC_VALUE XMLRPC_CreateValueBoolean(const char* id, int i) {
  1263. XMLRPC_VALUE val = XMLRPC_CreateValueEmpty();
  1264. if(val) {
  1265. XMLRPC_SetValueBoolean(val, i);
  1266. if(id) {
  1267. XMLRPC_SetValueID(val, id, 0);
  1268. }
  1269. }
  1270. return val;
  1271. }
  1272. /*******/
  1273. /****f* VALUE/XMLRPC_CleanupValue
  1274. * NAME
  1275. * XMLRPC_CleanupValue
  1276. * SYNOPSIS
  1277. * void XMLRPC_CleanupValue(XMLRPC_VALUE value)
  1278. * FUNCTION
  1279. * Frees all memory allocated for an XMLRPC_VALUE and any of its children (if a vector)
  1280. * INPUTS
  1281. * value The id of the value to be cleaned up.
  1282. * RESULT
  1283. * void
  1284. * NOTES
  1285. * Normally this function will be called for the topmost vector, thus free-ing
  1286. * all children. If a child of a vector is free'd first, results are undefined.
  1287. * Failure to call this function *will* cause memory leaks.
  1288. *
  1289. * Also, this function is implemented using reference counting. Thus a value
  1290. * may be added and freed from multiple parents so long as a reference is added
  1291. * first using XMLRPC_CopyValue()
  1292. * SEE ALSO
  1293. * XMLRPC_RequestFree ()
  1294. * XMLRPC_CreateValueEmpty ()
  1295. * XMLRPC_CopyValue()
  1296. * XMLRPC_VALUE
  1297. * SOURCE
  1298. */
  1299. void XMLRPC_CleanupValue(XMLRPC_VALUE value) {
  1300. if(value) {
  1301. if(value->iRefCount > 0) {
  1302. value->iRefCount --;
  1303. }
  1304. #ifdef XMLRPC_DEBUG_REFCOUNT
  1305. if(value->id.str) {
  1306. printf ("decremented refcount of %s, now %i\n", value->id.str,
  1307. value->iRefCount);
  1308. }
  1309. else {
  1310. printf ("decremented refcount of 0x%x, now %i\n", value,
  1311. value->iRefCount);
  1312. }
  1313. #endif
  1314. if(value->type == xmlrpc_vector) {
  1315. if(value->v) {
  1316. if(value->iRefCount == 0) {
  1317. XMLRPC_VALUE cur = (XMLRPC_VALUE)Q_Head(value->v->q);
  1318. while( cur ) {
  1319. XMLRPC_CleanupValue(cur);
  1320. /* Make sure some idiot didn't include a vector as a child of itself
  1321. * and thus it would have already free'd these.
  1322. */
  1323. if(value->v && value->v->q) {
  1324. cur = Q_Next(value->v->q);
  1325. }
  1326. else {
  1327. break;
  1328. }
  1329. }
  1330. Q_Destroy(value->v->q);
  1331. my_free(value->v->q);
  1332. my_free(value->v);
  1333. }
  1334. }
  1335. }
  1336. if(value->iRefCount == 0) {
  1337. /* guard against freeing invalid types */
  1338. switch(value->type) {
  1339. case xmlrpc_empty:
  1340. case xmlrpc_base64:
  1341. case xmlrpc_boolean:
  1342. case xmlrpc_datetime:
  1343. case xmlrpc_double:
  1344. case xmlrpc_int:
  1345. case xmlrpc_string:
  1346. case xmlrpc_vector:
  1347. #ifdef XMLRPC_DEBUG_REFCOUNT
  1348. if(value->id.str) {
  1349. printf("free'd %s\n", value->id.str);
  1350. }
  1351. else {
  1352. printf("free'd 0x%x\n", value);
  1353. }
  1354. #endif
  1355. simplestring_free(&value->id);
  1356. simplestring_free(&value->str);
  1357. memset(value, 0, sizeof(STRUCT_XMLRPC_VALUE));
  1358. my_free(value);
  1359. break;
  1360. default:
  1361. /* fprintf (stderr,
  1362. "xmlrpc: attempted to free value of invalid type\n"); */
  1363. break;
  1364. }
  1365. }
  1366. }
  1367. }
  1368. /*******/
  1369. /****f* VALUE/XMLRPC_SetValueDateTime
  1370. * NAME
  1371. * XMLRPC_SetValueDateTime
  1372. * SYNOPSIS
  1373. * void XMLRPC_SetValueDateTime(XMLRPC_VALUE value, time_t time)
  1374. * FUNCTION
  1375. * Assign time value to XMLRPC_VALUE
  1376. * INPUTS
  1377. * value The target XMLRPC_VALUE
  1378. * time The desired new unix time value (time_t)
  1379. * RESULT
  1380. * void
  1381. * SEE ALSO
  1382. * XMLRPC_GetValueDateTime ()
  1383. * XMLRPC_SetValueDateTime_ISO8601 ()
  1384. * XMLRPC_CreateValueDateTime ()
  1385. * XMLRPC_VALUE
  1386. * SOURCE
  1387. */
  1388. void XMLRPC_SetValueDateTime(XMLRPC_VALUE value, time_t time) {
  1389. if(value) {
  1390. char timeBuf[30];
  1391. value->type = xmlrpc_datetime;
  1392. value->i = time;
  1393. timeBuf[0] = 0;
  1394. date_to_ISO8601(time, timeBuf, sizeof(timeBuf));
  1395. if(timeBuf[0]) {
  1396. XMLRPC_SetValueDateTime_ISO8601 (value, timeBuf);
  1397. }
  1398. }
  1399. }
  1400. /*******/
  1401. /****f* VALUE/XMLRPC_CopyValue
  1402. * NAME
  1403. * XMLRPC_CopyValue
  1404. * SYNOPSIS
  1405. * XMLRPC_VALUE XMLRPC_CopyValue(XMLRPC_VALUE value)
  1406. * FUNCTION
  1407. * Make a copy (reference) of an XMLRPC_VALUE
  1408. * INPUTS
  1409. * value The target XMLRPC_VALUE
  1410. * RESULT
  1411. * XMLRPC_VALUE -- address of the copy
  1412. * SEE ALSO
  1413. * XMLRPC_CleanupValue ()
  1414. * XMLRPC_DupValueNew ()
  1415. * NOTES
  1416. * This function is implemented via reference counting, so the
  1417. * returned value is going to be the same as the passed in value.
  1418. * The value must be freed the same number of times it is copied
  1419. * or there will be a memory leak.
  1420. * SOURCE
  1421. */
  1422. XMLRPC_VALUE XMLRPC_CopyValue(XMLRPC_VALUE value) {
  1423. if(value) {
  1424. value->iRefCount ++;
  1425. #ifdef XMLRPC_DEBUG_REFCOUNT
  1426. if(value->id.str) {
  1427. printf ("incremented refcount of %s, now %i\n", value->id.str,
  1428. value->iRefCount);
  1429. }
  1430. else {
  1431. printf ("incremented refcount of 0x%x, now %i\n", value,
  1432. value->iRefCount);
  1433. }
  1434. #endif
  1435. }
  1436. return value;
  1437. }
  1438. /*******/
  1439. /****f* VALUE/XMLRPC_DupValueNew
  1440. * NAME
  1441. * XMLRPC_DupValueNew
  1442. * SYNOPSIS
  1443. * XMLRPC_VALUE XMLRPC_DupValueNew(XMLRPC_VALUE value)
  1444. * FUNCTION
  1445. * Make a duplicate (non reference) of an XMLRPC_VALUE with newly allocated mem.
  1446. * INPUTS
  1447. * value The source XMLRPC_VALUE to duplicate
  1448. * RESULT
  1449. * XMLRPC_VALUE -- address of the duplicate value
  1450. * SEE ALSO
  1451. * XMLRPC_CleanupValue ()
  1452. * XMLRPC_CopyValue ()
  1453. * NOTES
  1454. * Use this when function when you need to modify the contents of
  1455. * the copied value separately from the original.
  1456. *
  1457. * this function is recursive, thus the value and all of its children
  1458. * (if any) will be duplicated.
  1459. * SOURCE
  1460. */
  1461. XMLRPC_VALUE XMLRPC_DupValueNew (XMLRPC_VALUE xSource) {
  1462. XMLRPC_VALUE xReturn = NULL;
  1463. if (xSource) {
  1464. xReturn = XMLRPC_CreateValueEmpty ();
  1465. if (xSource->id.len) {
  1466. XMLRPC_SetValueID (xReturn, xSource->id.str, xSource->id.len);
  1467. }
  1468. switch (xSource->type) {
  1469. case xmlrpc_int:
  1470. case xmlrpc_boolean:
  1471. XMLRPC_SetValueInt (xReturn, xSource->i);
  1472. break;
  1473. case xmlrpc_string:
  1474. case xmlrpc_base64:
  1475. XMLRPC_SetValueString (xReturn, xSource->str.str, xSource->str.len);
  1476. break;
  1477. case xmlrpc_datetime:
  1478. XMLRPC_SetValueDateTime (xReturn, xSource->i);
  1479. break;
  1480. case xmlrpc_double:
  1481. XMLRPC_SetValueDouble (xReturn, xSource->d);
  1482. break;
  1483. case xmlrpc_vector:
  1484. {
  1485. q_iter qi = Q_Iter_Head_F (xSource->v->q);
  1486. XMLRPC_SetIsVector (xReturn, xSource->v->type);
  1487. while (qi) {
  1488. XMLRPC_VALUE xIter = Q_Iter_Get_F (qi);
  1489. XMLRPC_AddValueToVector (xReturn, XMLRPC_DupValueNew (xIter));
  1490. qi = Q_Iter_Next_F (qi);
  1491. }
  1492. }
  1493. break;
  1494. default:
  1495. break;
  1496. }
  1497. }
  1498. return xReturn;
  1499. }
  1500. /*******/
  1501. /****f* VALUE/XMLRPC_CreateValueDateTime
  1502. * NAME
  1503. * XMLRPC_CreateValueDateTime
  1504. * SYNOPSIS
  1505. * XMLRPC_VALUE XMLRPC_CreateValueDateTime(const char* id, time_t time)
  1506. * FUNCTION
  1507. * Create new datetime value from time_t
  1508. * INPUTS
  1509. * id id of the new value, or NULL
  1510. * time The desired unix time value (time_t)
  1511. * RESULT
  1512. * void
  1513. * SEE ALSO
  1514. * XMLRPC_GetValueDateTime ()
  1515. * XMLRPC_SetValueDateTime ()
  1516. * XMLRPC_CreateValueDateTime_ISO8601 ()
  1517. * XMLRPC_VALUE
  1518. * SOURCE
  1519. */
  1520. XMLRPC_VALUE XMLRPC_CreateValueDateTime(const char* id, time_t time) {
  1521. XMLRPC_VALUE val = XMLRPC_CreateValueEmpty();
  1522. if(val) {
  1523. XMLRPC_SetValueDateTime(val, time);
  1524. if(id) {
  1525. XMLRPC_SetValueID(val, id, 0);
  1526. }
  1527. }
  1528. return val;
  1529. }
  1530. /*******/
  1531. /****f* VALUE/XMLRPC_SetValueDateTime_ISO8601
  1532. * NAME
  1533. * XMLRPC_SetValueDateTime_ISO8601
  1534. * SYNOPSIS
  1535. * void XMLRPC_SetValueDateTime_ISO8601(XMLRPC_VALUE value, const char* s)
  1536. * FUNCTION
  1537. * Set datetime value from IS08601 encoded string
  1538. * INPUTS
  1539. * value The target XMLRPC_VALUE
  1540. * s The desired new time value
  1541. * RESULT
  1542. * void
  1543. * BUGS
  1544. * This function currently attempts to convert the time string to a valid unix time
  1545. * value before passing it. Behavior when the string is invalid or out of range
  1546. * is not well defined, but will probably result in Jan 1, 1970 (0) being passed.
  1547. * SEE ALSO
  1548. * XMLRPC_GetValueDateTime_ISO8601 ()
  1549. * XMLRPC_CreateValueDateTime_ISO8601 ()
  1550. * XMLRPC_CreateValueDateTime ()
  1551. * XMLRPC_VALUE
  1552. * SOURCE
  1553. */
  1554. void XMLRPC_SetValueDateTime_ISO8601(XMLRPC_VALUE value, const char* s) {
  1555. if(value) {
  1556. time_t time_val = 0;
  1557. if(s) {
  1558. value->type = xmlrpc_datetime;
  1559. date_from_ISO8601(s, &time_val);
  1560. value->i = time_val;
  1561. simplestring_clear(&value->str);
  1562. simplestring_add(&value->str, s);
  1563. }
  1564. }
  1565. }
  1566. /*******/
  1567. /****f* VALUE/XMLRPC_CreateValueDateTime_ISO8601
  1568. * NAME
  1569. * XMLRPC_CreateValueDateTime_ISO8601
  1570. * SYNOPSIS
  1571. * XMLRPC_VALUE XMLRPC_CreateValueDateTime_ISO8601(const char* id, const char *s)
  1572. * FUNCTION
  1573. * Create datetime value from IS08601 encoded string
  1574. * INPUTS
  1575. * id The id of the new value, or NULL
  1576. * s The desired new time value
  1577. * RESULT
  1578. * newly allocated XMLRPC_VALUE, or NULL if no value created.
  1579. * BUGS
  1580. * See XMLRPC_SetValueDateTime_ISO8601 ()
  1581. * SEE ALSO
  1582. * XMLRPC_GetValueDateTime_ISO8601 ()
  1583. * XMLRPC_SetValueDateTime_ISO8601 ()
  1584. * XMLRPC_CreateValueDateTime ()
  1585. * XMLRPC_VALUE
  1586. * SOURCE
  1587. */
  1588. XMLRPC_VALUE XMLRPC_CreateValueDateTime_ISO8601(const char* id, const char *s) {
  1589. XMLRPC_VALUE val = XMLRPC_CreateValueEmpty();
  1590. if(val) {
  1591. XMLRPC_SetValueDateTime_ISO8601(val, s);
  1592. if(id) {
  1593. XMLRPC_SetValueID(val, id, 0);
  1594. }
  1595. }
  1596. return val;
  1597. }
  1598. /*******/
  1599. /****f* VALUE/XMLRPC_SetValueBase64
  1600. * NAME
  1601. * XMLRPC_SetValueBase64
  1602. * SYNOPSIS
  1603. * void XMLRPC_SetValueBase64(XMLRPC_VALUE value, const char* s, int len)
  1604. * FUNCTION
  1605. * Set base64 value. Base64 is useful for transferring binary data, such as an image.
  1606. * INPUTS
  1607. * value The target XMLRPC_VALUE
  1608. * s The desired new binary value
  1609. * len The length of s, or NULL. If buffer is not null terminated, len *must* be passed.
  1610. * RESULT
  1611. * void
  1612. * NOTES
  1613. * Data is set/stored/retrieved as passed in, but is base64 encoded for XML transfer, and
  1614. * decoded on the other side. This is transparent to the caller.
  1615. * SEE ALSO
  1616. * XMLRPC_GetValueBase64 ()
  1617. * XMLRPC_CreateValueBase64 ()
  1618. * XMLRPC_VALUE
  1619. * SOURCE
  1620. */
  1621. void XMLRPC_SetValueBase64(XMLRPC_VALUE value, const char* s, int len) {
  1622. if(value && s) {
  1623. simplestring_clear(&value->str);
  1624. (len > 0) ? simplestring_addn(&value->str, s, len) :
  1625. simplestring_add(&value->str, s);
  1626. value->type = xmlrpc_base64;
  1627. }
  1628. }
  1629. /*******/
  1630. /****f* VALUE/XMLRPC_CreateValueBase64
  1631. * NAME
  1632. * XMLRPC_CreateValueBase64
  1633. * SYNOPSIS
  1634. * XMLRPC_VALUE XMLRPC_CreateValueBase64(const char* id, const char* s, int len)
  1635. * FUNCTION
  1636. * Create base64 value. Base64 is useful for transferring binary data, such as an image.
  1637. * INPUTS
  1638. * id id of the new value, or NULL
  1639. * s The desired new binary value
  1640. * len The length of s, or NULL. If buffer is not null terminated, len *must* be passed.
  1641. * RESULT
  1642. * newly allocated XMLRPC_VALUE, or NULL if error
  1643. * NOTES
  1644. * See XMLRPC_SetValueBase64 ()
  1645. * SEE ALSO
  1646. * XMLRPC_GetValueBase64 ()
  1647. * XMLRPC_SetValueBase64 ()
  1648. * XMLRPC_VALUE
  1649. * SOURCE
  1650. */
  1651. XMLRPC_VALUE XMLRPC_CreateValueBase64(const char* id, const char* s, int len) {
  1652. XMLRPC_VALUE val = XMLRPC_CreateValueEmpty();
  1653. if(val) {
  1654. XMLRPC_SetValueBase64(val, s, len);
  1655. if(id) {
  1656. XMLRPC_SetValueID(val, id, 0);
  1657. }
  1658. }
  1659. return val;
  1660. }
  1661. /*******/
  1662. /****f* VALUE/XMLRPC_SetValueDouble
  1663. * NAME
  1664. * XMLRPC_SetValueDouble
  1665. * SYNOPSIS
  1666. * void XMLRPC_SetValueDouble(XMLRPC_VALUE value, double val)
  1667. * FUNCTION
  1668. * Set double (floating point) value.
  1669. * INPUTS
  1670. * value The target XMLRPC_VALUE
  1671. * val The desired new double value
  1672. * RESULT
  1673. * void
  1674. * SEE ALSO
  1675. * XMLRPC_GetValueDouble ()
  1676. * XMLRPC_CreateValueDouble ()
  1677. * XMLRPC_VALUE
  1678. * SOURCE
  1679. */
  1680. void XMLRPC_SetValueDouble(XMLRPC_VALUE value, double val) {
  1681. if(value) {
  1682. value->type = xmlrpc_double;
  1683. value->d = val;
  1684. }
  1685. }
  1686. /*******/
  1687. /****f* VALUE/XMLRPC_CreateValueDouble
  1688. * NAME
  1689. * XMLRPC_CreateValueDouble
  1690. * SYNOPSIS
  1691. * XMLRPC_VALUE XMLRPC_CreateValueDouble(const char* id, double d)
  1692. * FUNCTION
  1693. * Create double (floating point) value.
  1694. * INPUTS
  1695. * id id of the newly created value, or NULL
  1696. * d The desired new double value
  1697. * RESULT
  1698. * void
  1699. * SEE ALSO
  1700. * XMLRPC_GetValueDouble ()
  1701. * XMLRPC_CreateValueDouble ()
  1702. * XMLRPC_VALUE
  1703. * SOURCE
  1704. */
  1705. XMLRPC_VALUE XMLRPC_CreateValueDouble(const char* id, double d) {
  1706. XMLRPC_VALUE val = XMLRPC_CreateValueEmpty();
  1707. if(val) {
  1708. XMLRPC_SetValueDouble(val, d);
  1709. if(id) {
  1710. XMLRPC_SetValueID(val, id, 0);
  1711. }
  1712. }
  1713. return val;
  1714. }
  1715. /*******/
  1716. /****f* VALUE/XMLRPC_GetValueString
  1717. * NAME
  1718. * XMLRPC_GetValueString
  1719. * SYNOPSIS
  1720. * const char* XMLRPC_GetValueString(XMLRPC_VALUE value)
  1721. * FUNCTION
  1722. * retrieve string value
  1723. * INPUTS
  1724. * value source XMLRPC_VALUE of type xmlrpc_string
  1725. * RESULT
  1726. * void
  1727. * SEE ALSO
  1728. * XMLRPC_SetValueString ()
  1729. * XMLRPC_GetValueType ()
  1730. * XMLRPC_VALUE
  1731. * SOURCE
  1732. */
  1733. const char* XMLRPC_GetValueString(XMLRPC_VALUE value) {
  1734. return ((value && value->type == xmlrpc_string) ? value->str.str : 0);
  1735. }
  1736. /*******/
  1737. /****f* VALUE/XMLRPC_GetValueStringLen
  1738. * NAME
  1739. * XMLRPC_GetValueStringLen
  1740. * SYNOPSIS
  1741. * int XMLRPC_GetValueStringLen(XMLRPC_VALUE value)
  1742. * FUNCTION
  1743. * determine length of string value
  1744. * INPUTS
  1745. * value XMLRPC_VALUE of type xmlrpc_string
  1746. * RESULT
  1747. * length of string, or 0
  1748. * NOTES
  1749. * SEE ALSO
  1750. * XMLRPC_SetValueString ()
  1751. * XMLRPC_GetValueString ()
  1752. * SOURCE
  1753. */
  1754. int XMLRPC_GetValueStringLen(XMLRPC_VALUE value) {
  1755. return ((value) ? value->str.len : 0);
  1756. }
  1757. /*******/
  1758. /****f* VALUE/XMLRPC_GetValueInt
  1759. * NAME
  1760. * XMLRPC_GetValueInt
  1761. * SYNOPSIS
  1762. * int XMLRPC_GetValueInt(XMLRPC_VALUE value)
  1763. * FUNCTION
  1764. * retrieve integer value.
  1765. * INPUTS
  1766. * value XMLRPC_VALUE of type xmlrpc_int
  1767. * RESULT
  1768. * integer value or 0 if value is not valid int
  1769. * NOTES
  1770. * use XMLRPC_GetValueType () to be sure if 0 is real return value or not
  1771. * SEE ALSO
  1772. * XMLRPC_SetValueInt ()
  1773. * XMLRPC_CreateValueInt ()
  1774. * SOURCE
  1775. */
  1776. int XMLRPC_GetValueInt(XMLRPC_VALUE value) {
  1777. return ((value && value->type == xmlrpc_int) ? value->i : 0);
  1778. }
  1779. /*******/
  1780. /****f* VALUE/XMLRPC_GetValueBoolean
  1781. * NAME
  1782. * XMLRPC_GetValueBoolean
  1783. * SYNOPSIS
  1784. * int XMLRPC_GetValueBoolean(XMLRPC_VALUE value)
  1785. * FUNCTION
  1786. * retrieve boolean value.
  1787. * INPUTS
  1788. * XMLRPC_VALUE of type xmlrpc_boolean
  1789. * RESULT
  1790. * boolean value or 0 if value is not valid boolean
  1791. * NOTES
  1792. * use XMLRPC_GetValueType() to be sure if 0 is real value or not
  1793. * SEE ALSO
  1794. * XMLRPC_SetValueBoolean ()
  1795. * XMLRPC_CreateValueBoolean ()
  1796. * SOURCE
  1797. */
  1798. int XMLRPC_GetValueBoolean(XMLRPC_VALUE value) {
  1799. return ((value && value->type == xmlrpc_boolean) ? value->i : 0);
  1800. }
  1801. /*******/
  1802. /****f* VALUE/XMLRPC_GetValueDouble
  1803. * NAME
  1804. * XMLRPC_GetValueDouble
  1805. * SYNOPSIS
  1806. * double XMLRPC_GetValueDouble(XMLRPC_VALUE value)
  1807. * FUNCTION
  1808. * retrieve double value
  1809. * INPUTS
  1810. * XMLRPC_VALUE of type xmlrpc_double
  1811. * RESULT
  1812. * double value or 0 if value is not valid double.
  1813. * NOTES
  1814. * use XMLRPC_GetValueType() to be sure if 0 is real value or not
  1815. * SEE ALSO
  1816. * XMLRPC_SetValueDouble ()
  1817. * XMLRPC_CreateValueDouble ()
  1818. * SOURCE
  1819. */
  1820. double XMLRPC_GetValueDouble(XMLRPC_VALUE value) {
  1821. return ((value && value->type == xmlrpc_double) ? value->d : 0);
  1822. }
  1823. /*******/
  1824. /****f* VALUE/XMLRPC_GetValueBase64
  1825. * NAME
  1826. * XMLRPC_GetValueBase64
  1827. * SYNOPSIS
  1828. * const char* XMLRPC_GetValueBase64(XMLRPC_VALUE value)
  1829. * FUNCTION
  1830. * retrieve binary value
  1831. * INPUTS
  1832. * XMLRPC_VALUE of type xmlrpc_base64
  1833. * RESULT
  1834. * pointer to binary value or 0 if value is not valid.
  1835. * SEE ALSO
  1836. * XMLRPC_SetValueBase64 ()
  1837. * XMLRPC_CreateValueBase64 ()
  1838. * NOTES
  1839. * Call XMLRPC_GetValueStringLen() to retrieve real length of binary data. strlen()
  1840. * will not be accurate, as returned data may contain embedded nulls.
  1841. * SOURCE
  1842. */
  1843. const char* XMLRPC_GetValueBase64(XMLRPC_VALUE value) {
  1844. return ((value && value->type == xmlrpc_base64) ? value->str.str : 0);
  1845. }
  1846. /*******/
  1847. /****f* VALUE/XMLRPC_GetValueDateTime
  1848. * NAME
  1849. * XMLRPC_GetValueDateTime
  1850. * SYNOPSIS
  1851. * time_t XMLRPC_GetValueDateTime(XMLRPC_VALUE value)
  1852. * FUNCTION
  1853. * retrieve time_t value
  1854. * INPUTS
  1855. * XMLRPC_VALUE of type xmlrpc_datetime
  1856. * RESULT
  1857. * time_t value or 0 if value is not valid datetime.
  1858. * NOTES
  1859. * use XMLRPC_GetValueType() to be sure if 0 is real value or not
  1860. * SEE ALSO
  1861. * XMLRPC_SetValueDateTime ()
  1862. * XMLRPC_GetValueDateTime_ISO8601 ()
  1863. * XMLRPC_CreateValueDateTime ()
  1864. * SOURCE
  1865. */
  1866. time_t XMLRPC_GetValueDateTime(XMLRPC_VALUE value) {
  1867. return (time_t)((value && value->type == xmlrpc_datetime) ? value->i : 0);
  1868. }
  1869. /*******/
  1870. /****f* VALUE/XMLRPC_GetValueDateTime_IOS8601
  1871. * NAME
  1872. * XMLRPC_GetValueDateTime_IOS8601
  1873. * SYNOPSIS
  1874. * const char* XMLRPC_GetValueDateTime_IOS8601(XMLRPC_VALUE value)
  1875. * FUNCTION
  1876. * retrieve ISO8601 formatted time value
  1877. * INPUTS
  1878. * XMLRPC_VALUE of type xmlrpc_datetime
  1879. * RESULT
  1880. * const char* value or 0 if value is not valid datetime.
  1881. * SEE ALSO
  1882. * XMLRPC_SetValueDateTime_IOS8601 ()
  1883. * XMLRPC_GetValueDateTime ()
  1884. * XMLRPC_CreateValueDateTime_IOS8601 ()
  1885. * SOURCE
  1886. */
  1887. const char* XMLRPC_GetValueDateTime_ISO8601(XMLRPC_VALUE value) {
  1888. return ((value && value->type == xmlrpc_datetime) ? value->str.str : 0);
  1889. }
  1890. /*******/
  1891. /* Get ID (key) of value or NULL */
  1892. /****f* VALUE/XMLRPC_GetValueID
  1893. * NAME
  1894. * XMLRPC_GetValueID
  1895. * SYNOPSIS
  1896. * const char* XMLRPC_GetValueID(XMLRPC_VALUE value)
  1897. * FUNCTION
  1898. * retrieve id (key) of value
  1899. * INPUTS
  1900. * XMLRPC_VALUE of any type
  1901. * RESULT
  1902. * const char* pointer to id of value, or NULL
  1903. * NOTES
  1904. * SEE ALSO
  1905. * XMLRPC_SetValueID()
  1906. * XMLRPC_CreateValueEmpty()
  1907. * SOURCE
  1908. */
  1909. const char* XMLRPC_GetValueID(XMLRPC_VALUE value) {
  1910. return (const char*)((value && value->id.len) ? value->id.str : 0);
  1911. }
  1912. /*******/
  1913. /****f* VECTOR/XMLRPC_VectorSize
  1914. * NAME
  1915. * XMLRPC_VectorSize
  1916. * SYNOPSIS
  1917. * int XMLRPC_VectorSize(XMLRPC_VALUE value)
  1918. * FUNCTION
  1919. * retrieve size of vector
  1920. * INPUTS
  1921. * XMLRPC_VALUE of type xmlrpc_vector
  1922. * RESULT
  1923. * count of items in vector
  1924. * NOTES
  1925. * This is a cheap operation even on large vectors. Vector size is
  1926. * maintained by queue during add/remove ops.
  1927. * SEE ALSO
  1928. * XMLRPC_AddValueToVector ()
  1929. * SOURCE
  1930. */
  1931. int XMLRPC_VectorSize(XMLRPC_VALUE value) {
  1932. int size = 0;
  1933. if(value && value->type == xmlrpc_vector && value->v) {
  1934. size = Q_Size(value->v->q);
  1935. }
  1936. return size;
  1937. }
  1938. /*******/
  1939. /****f* VECTOR/XMLRPC_VectorRewind
  1940. * NAME
  1941. * XMLRPC_VectorRewind
  1942. * SYNOPSIS
  1943. * XMLRPC_VALUE XMLRPC_VectorRewind(XMLRPC_VALUE value)
  1944. * FUNCTION
  1945. * reset vector to first item
  1946. * INPUTS
  1947. * XMLRPC_VALUE of type xmlrpc_vector
  1948. * RESULT
  1949. * first XMLRPC_VALUE in list, or NULL if empty or error.
  1950. * NOTES
  1951. * Be careful to rewind any vector passed in to you if you expect to
  1952. * iterate through the entire list.
  1953. * SEE ALSO
  1954. * XMLRPC_VectorNext ()
  1955. * SOURCE
  1956. */
  1957. XMLRPC_VALUE XMLRPC_VectorRewind(XMLRPC_VALUE value) {
  1958. XMLRPC_VALUE xReturn = NULL;
  1959. if(value && value->type == xmlrpc_vector && value->v) {
  1960. xReturn = (XMLRPC_VALUE)Q_Head(value->v->q);
  1961. }
  1962. return xReturn;
  1963. }
  1964. /*******/
  1965. /****f* VECTOR/XMLRPC_VectorNext
  1966. * NAME
  1967. * XMLRPC_VectorNext
  1968. * SYNOPSIS
  1969. * XMLRPC_VALUE XMLRPC_VectorNext(XMLRPC_VALUE value)
  1970. * FUNCTION
  1971. * Iterate vector to next item in list.
  1972. * INPUTS
  1973. * XMLRPC_VALUE of type xmlrpc_vector
  1974. * RESULT
  1975. * Next XMLRPC_VALUE in vector, or NULL if at end.
  1976. * NOTES
  1977. * SEE ALSO
  1978. * XMLRPC_VectorRewind ()
  1979. * SOURCE
  1980. */
  1981. XMLRPC_VALUE XMLRPC_VectorNext(XMLRPC_VALUE value) {
  1982. XMLRPC_VALUE xReturn = NULL;
  1983. if(value && value->type == xmlrpc_vector && value->v) {
  1984. xReturn = (XMLRPC_VALUE)Q_Next(value->v->q);
  1985. }
  1986. return xReturn;
  1987. }
  1988. /*******/
  1989. /****f* VALUE/XMLRPC_GetValueType
  1990. * NAME
  1991. * XMLRPC_GetValueType
  1992. * SYNOPSIS
  1993. * XMLRPC_VALUE_TYPE XMLRPC_GetValueType(XMLRPC_VALUE value)
  1994. * FUNCTION
  1995. * determine data type of the XMLRPC_VALUE
  1996. * INPUTS
  1997. * XMLRPC_VALUE target of query
  1998. * RESULT
  1999. * data type of value as enumerated by XMLRPC_VALUE_TYPE
  2000. * NOTES
  2001. * all values are of type xmlrpc_empty until set.
  2002. * Deprecated for public use. See XMLRPC_GetValueTypeEasy
  2003. * SEE ALSO
  2004. * XMLRPC_SetValue*
  2005. * XMLRPC_CreateValue*
  2006. * XMLRPC_Append*
  2007. * XMLRPC_GetValueTypeEasy ()
  2008. * SOURCE
  2009. */
  2010. XMLRPC_VALUE_TYPE XMLRPC_GetValueType(XMLRPC_VALUE value) {
  2011. return value ? value->type : xmlrpc_empty;
  2012. }
  2013. /*******/
  2014. /* Vector type accessor */
  2015. /****f* VALUE/XMLRPC_GetVectorType
  2016. * NAME
  2017. * XMLRPC_GetVectorType
  2018. * SYNOPSIS
  2019. * XMLRPC_VECTOR_TYPE XMLRPC_GetVectorType(XMLRPC_VALUE value)
  2020. * FUNCTION
  2021. * determine vector type of the XMLRPC_VALUE
  2022. * INPUTS
  2023. * XMLRPC_VALUE of type xmlrpc_vector
  2024. * RESULT
  2025. * vector type of value as enumerated by XMLRPC_VECTOR_TYPE.
  2026. * xmlrpc_none if not a value.
  2027. * NOTES
  2028. * xmlrpc_none is returned if value is not a vector
  2029. * Deprecated for public use. See XMLRPC_GetValueTypeEasy
  2030. * SEE ALSO
  2031. * XMLRPC_SetIsVector ()
  2032. * XMLRPC_GetValueType ()
  2033. * XMLRPC_GetValueTypeEasy ()
  2034. * SOURCE
  2035. */
  2036. XMLRPC_VECTOR_TYPE XMLRPC_GetVectorType(XMLRPC_VALUE value) {
  2037. return(value && value->v) ? value->v->type : xmlrpc_none;
  2038. }
  2039. /*******/
  2040. /****f* VALUE/XMLRPC_GetValueTypeEasy
  2041. * NAME
  2042. * XMLRPC_GetValueTypeEasy
  2043. * SYNOPSIS
  2044. * XMLRPC_VALUE_TYPE_EASY XMLRPC_GetValueTypeEasy(XMLRPC_VALUE value)
  2045. * FUNCTION
  2046. * determine data type of the XMLRPC_VALUE. includes vector types.
  2047. * INPUTS
  2048. * XMLRPC_VALUE target of query
  2049. * RESULT
  2050. * data type of value as enumerated by XMLRPC_VALUE_TYPE_EASY
  2051. * xmlrpc_type_none if not a value.
  2052. * NOTES
  2053. * all values are of type xmlrpc_type_empty until set.
  2054. * SEE ALSO
  2055. * XMLRPC_SetValue*
  2056. * XMLRPC_CreateValue*
  2057. * XMLRPC_Append*
  2058. * SOURCE
  2059. */
  2060. XMLRPC_VALUE_TYPE_EASY XMLRPC_GetValueTypeEasy (XMLRPC_VALUE value) {
  2061. if (value) {
  2062. switch (value->type) {
  2063. case xmlrpc_vector:
  2064. switch (value->v->type) {
  2065. case xmlrpc_vector_none:
  2066. return xmlrpc_type_none;
  2067. case xmlrpc_vector_struct:
  2068. return xmlrpc_type_struct;
  2069. case xmlrpc_vector_mixed:
  2070. return xmlrpc_type_mixed;
  2071. case xmlrpc_vector_array:
  2072. return xmlrpc_type_array;
  2073. }
  2074. default:
  2075. /* evil cast, but we know they are the same */
  2076. return(XMLRPC_VALUE_TYPE_EASY) value->type;
  2077. }
  2078. }
  2079. return xmlrpc_none;
  2080. }
  2081. /*******/
  2082. /*-*******************
  2083. * Begin Server Funcs *
  2084. *********************/
  2085. /****f* VALUE/XMLRPC_ServerCreate
  2086. * NAME
  2087. * XMLRPC_ServerCreate
  2088. * SYNOPSIS
  2089. * XMLRPC_SERVER XMLRPC_ServerCreate()
  2090. * FUNCTION
  2091. * Allocate/Init XMLRPC Server Resources.
  2092. * INPUTS
  2093. * none
  2094. * RESULT
  2095. * newly allocated XMLRPC_SERVER
  2096. * NOTES
  2097. * SEE ALSO
  2098. * XMLRPC_ServerDestroy ()
  2099. * XMLRPC_GetGlobalServer ()
  2100. * SOURCE
  2101. */
  2102. XMLRPC_SERVER XMLRPC_ServerCreate() {
  2103. XMLRPC_SERVER server = ecalloc(1, sizeof(STRUCT_XMLRPC_SERVER));
  2104. if(server) {
  2105. Q_Init(&server->methodlist);
  2106. Q_Init(&server->docslist);
  2107. /* register system methods */
  2108. xsm_register(server);
  2109. }
  2110. return server;
  2111. }
  2112. /*******/
  2113. /* Return global server. Not locking! Not Thread Safe! */
  2114. /****f* VALUE/XMLRPC_GetGlobalServer
  2115. * NAME
  2116. * XMLRPC_GetGlobalServer
  2117. * SYNOPSIS
  2118. * XMLRPC_SERVER XMLRPC_GetGlobalServer()
  2119. * FUNCTION
  2120. * Allocates a global (process-wide) server, or returns pointer if pre-existing.
  2121. * INPUTS
  2122. * none
  2123. * RESULT
  2124. * pointer to global server, or 0 if error.
  2125. * NOTES
  2126. * ***WARNING*** This function is not thread safe. It is included only for the very lazy.
  2127. * Multi-threaded programs that use this may experience problems.
  2128. * BUGS
  2129. * There is currently no way to cleanup the global server gracefully.
  2130. * SEE ALSO
  2131. * XMLRPC_ServerCreate ()
  2132. * SOURCE
  2133. */
  2134. XMLRPC_SERVER XMLRPC_GetGlobalServer() {
  2135. static XMLRPC_SERVER xsServer = 0;
  2136. if(!xsServer) {
  2137. xsServer = XMLRPC_ServerCreate();
  2138. }
  2139. return xsServer;
  2140. }
  2141. /*******/
  2142. /****f* VALUE/XMLRPC_ServerDestroy
  2143. * NAME
  2144. * XMLRPC_ServerDestroy
  2145. * SYNOPSIS
  2146. * void XMLRPC_ServerDestroy(XMLRPC_SERVER server)
  2147. * FUNCTION
  2148. * Free Server Resources
  2149. * INPUTS
  2150. * server The server to be free'd
  2151. * RESULT
  2152. * void
  2153. * NOTES
  2154. * This frees the server struct and any methods that have been added.
  2155. * SEE ALSO
  2156. * XMLRPC_ServerCreate ()
  2157. * SOURCE
  2158. */
  2159. void XMLRPC_ServerDestroy(XMLRPC_SERVER server) {
  2160. if(server) {
  2161. doc_method* dm = Q_Head(&server->docslist);
  2162. server_method* sm = Q_Head(&server->methodlist);
  2163. while( dm ) {
  2164. my_free(dm);
  2165. dm = Q_Next(&server->docslist);
  2166. }
  2167. while( sm ) {
  2168. my_free(sm->name);
  2169. if(sm->desc) {
  2170. XMLRPC_CleanupValue(sm->desc);
  2171. }
  2172. my_free(sm);
  2173. sm = Q_Next(&server->methodlist);
  2174. }
  2175. if (server->xIntrospection) {
  2176. XMLRPC_CleanupValue(server->xIntrospection);
  2177. }
  2178. Q_Destroy(&server->methodlist);
  2179. Q_Destroy(&server->docslist);
  2180. my_free(server);
  2181. }
  2182. }
  2183. /*******/
  2184. /****f* VALUE/XMLRPC_ServerRegisterMethod
  2185. * NAME
  2186. * XMLRPC_ServerRegisterMethod
  2187. * SYNOPSIS
  2188. * void XMLRPC_ServerRegisterMethod(XMLRPC_SERVER server, const char *name, XMLRPC_Callback cb)
  2189. * FUNCTION
  2190. * Register new XMLRPC method with server
  2191. * INPUTS
  2192. * server The XMLRPC_SERVER to register the method with
  2193. * name public name of the method
  2194. * cb C function that implements the method
  2195. * RESULT
  2196. * int - 1 if success, else 0
  2197. * NOTES
  2198. * A C function must be registered for every "method" that the server recognizes. The
  2199. * method name is equivalent to <methodCall><name> method name </name></methodCall> in the
  2200. * XML syntax.
  2201. * SEE ALSO
  2202. * XMLRPC_ServerFindMethod ()
  2203. * XMLRPC_ServerCallMethod ()
  2204. * SOURCE
  2205. */
  2206. int XMLRPC_ServerRegisterMethod(XMLRPC_SERVER server, const char *name, XMLRPC_Callback cb) {
  2207. if(server && name && cb) {
  2208. server_method* sm = emalloc(sizeof(server_method));
  2209. if(sm) {
  2210. sm->name = estrdup(name);
  2211. sm->method = cb;
  2212. sm->desc = NULL;
  2213. return Q_PushTail(&server->methodlist, sm);
  2214. }
  2215. }
  2216. return 0;
  2217. }
  2218. /*******/
  2219. server_method* find_method(XMLRPC_SERVER server, const char* name) {
  2220. server_method* sm;
  2221. q_iter qi = Q_Iter_Head_F(&server->methodlist);
  2222. while( qi ) {
  2223. sm = Q_Iter_Get_F(qi);
  2224. if(sm && !strcmp(sm->name, name)) {
  2225. return sm;
  2226. }
  2227. qi = Q_Iter_Next_F(qi);
  2228. }
  2229. return NULL;
  2230. }
  2231. const char* type_to_str(XMLRPC_VALUE_TYPE type, XMLRPC_VECTOR_TYPE vtype) {
  2232. switch(type) {
  2233. case xmlrpc_none:
  2234. return "none";
  2235. case xmlrpc_empty:
  2236. return "empty";
  2237. case xmlrpc_base64:
  2238. return "base64";
  2239. case xmlrpc_boolean:
  2240. return "boolean";
  2241. case xmlrpc_datetime:
  2242. return "datetime";
  2243. case xmlrpc_double:
  2244. return "double";
  2245. case xmlrpc_int:
  2246. return "int";
  2247. case xmlrpc_string:
  2248. return "string";
  2249. case xmlrpc_vector:
  2250. switch(vtype) {
  2251. case xmlrpc_vector_none:
  2252. return "none";
  2253. case xmlrpc_vector_array:
  2254. return "array";
  2255. case xmlrpc_vector_mixed:
  2256. return "mixed vector (struct)";
  2257. case xmlrpc_vector_struct:
  2258. return "struct";
  2259. }
  2260. }
  2261. return "unknown";
  2262. }
  2263. /****f* VALUE/XMLRPC_ServerFindMethod
  2264. * NAME
  2265. * XMLRPC_ServerFindMethod
  2266. * SYNOPSIS
  2267. * XMLRPC_Callback XMLRPC_ServerFindMethod(XMLRPC_SERVER server, const char* callName)
  2268. * FUNCTION
  2269. * retrieve C callback associated with a given method name.
  2270. * INPUTS
  2271. * server The XMLRPC_SERVER the method is registered with
  2272. * callName the method to find
  2273. * RESULT
  2274. * previously registered XMLRPC_Callback, or NULL
  2275. * NOTES
  2276. * Typically, this is used to determine if a requested method exists, without actually calling it.
  2277. * SEE ALSO
  2278. * XMLRPC_ServerCallMethod ()
  2279. * XMLRPC_ServerRegisterMethod ()
  2280. * SOURCE
  2281. */
  2282. XMLRPC_Callback XMLRPC_ServerFindMethod(XMLRPC_SERVER server, const char* callName) {
  2283. if(server && callName) {
  2284. q_iter qi = Q_Iter_Head_F(&server->methodlist);
  2285. while( qi ) {
  2286. server_method* sm = Q_Iter_Get_F(qi);
  2287. if(sm && !strcmp(sm->name, callName)) {
  2288. return sm->method;
  2289. }
  2290. qi = Q_Iter_Next_F(qi);
  2291. }
  2292. }
  2293. return NULL;
  2294. }
  2295. /*******/
  2296. /* Call method specified in request */
  2297. /****f* VALUE/XMLRPC_ServerCallMethod
  2298. * NAME
  2299. * XMLRPC_ServerCallMethod
  2300. * SYNOPSIS
  2301. * XMLRPC_VALUE XMLRPC_ServerCallMethod(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData)
  2302. * FUNCTION
  2303. *
  2304. * INPUTS
  2305. * server The XMLRPC_SERVER the method is registered with
  2306. * request the request to handle
  2307. * userData any additional data to pass to the C callback, or NULL
  2308. * RESULT
  2309. * XMLRPC_VALUE allocated by the callback, or NULL
  2310. * NOTES
  2311. * It is typically the caller's responsibility to free the returned value.
  2312. *
  2313. * Often the caller will want to serialize the result as XML, via
  2314. * XMLRPC_VALUE_To_XML () or XMLRPC_REQUEST_To_XML ()
  2315. * SEE ALSO
  2316. * XMLRPC_ServerFindMethod ()
  2317. * XMLRPC_ServerRegisterMethod ()
  2318. * XMLRPC_CleanupValue ()
  2319. * SOURCE
  2320. */
  2321. XMLRPC_VALUE XMLRPC_ServerCallMethod(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData) {
  2322. XMLRPC_VALUE xReturn = NULL;
  2323. /* check for error set during request parsing / generation */
  2324. if(request && request->error) {
  2325. xReturn = XMLRPC_CopyValue(request->error);
  2326. }
  2327. else if (server && request) {
  2328. XMLRPC_Callback cb =
  2329. XMLRPC_ServerFindMethod (server, request->methodName.str);
  2330. if(cb) {
  2331. xReturn = cb(server, request, userData);
  2332. }
  2333. else {
  2334. xReturn =
  2335. XMLRPC_UtilityCreateFault (xmlrpc_error_unknown_method,
  2336. request->methodName.str);
  2337. }
  2338. }
  2339. return xReturn;
  2340. }
  2341. /*******/
  2342. /*-*****************
  2343. * End server funcs *
  2344. *******************/
  2345. /*-***********************************
  2346. * Begin XMLRPC General Options funcs *
  2347. *************************************/
  2348. /* For options used by XMLRPC_VALUE funcs that otherwise do not have
  2349. * parameters for options. Kind of gross. :(
  2350. */
  2351. typedef struct _xmlrpc_options {
  2352. XMLRPC_CASE id_case;
  2353. XMLRPC_CASE_COMPARISON id_case_compare;
  2354. }
  2355. STRUCT_XMLRPC_OPTIONS, *XMLRPC_OPTIONS;
  2356. static XMLRPC_OPTIONS XMLRPC_GetDefaultOptions() {
  2357. static STRUCT_XMLRPC_OPTIONS options = {
  2358. xmlrpc_case_exact,
  2359. xmlrpc_case_sensitive
  2360. };
  2361. return &options;
  2362. }
  2363. /****f* VALUE/XMLRPC_GetDefaultIdCase
  2364. * NAME
  2365. * XMLRPC_GetDefaultIdCase
  2366. * SYNOPSIS
  2367. * XMLRPC_CASE XMLRPC_GetDefaultIdCase()
  2368. * FUNCTION
  2369. * Gets default case options used by XMLRPC_VALUE funcs
  2370. * INPUTS
  2371. * none
  2372. * RESULT
  2373. * XMLRPC_CASE
  2374. * BUGS
  2375. * Nasty and gross. Should be server specific, but that requires changing all
  2376. * the XMLRPC_VALUE api's.
  2377. * SEE ALSO
  2378. * XMLRPC_SetDefaultIdCase ()
  2379. * SOURCE
  2380. */
  2381. XMLRPC_CASE XMLRPC_GetDefaultIdCase() {
  2382. XMLRPC_OPTIONS options = XMLRPC_GetDefaultOptions();
  2383. return options->id_case;
  2384. }
  2385. /*******/
  2386. /****f* VALUE/XMLRPC_SetDefaultIdCase
  2387. * NAME
  2388. * XMLRPC_SetDefaultIdCase
  2389. * SYNOPSIS
  2390. * XMLRPC_CASE XMLRPC_SetDefaultIdCase(XMLRPC_CASE id_case)
  2391. * FUNCTION
  2392. * Sets default case options used by XMLRPC_VALUE funcs
  2393. * INPUTS
  2394. * id_case case options as enumerated by XMLRPC_CASE
  2395. * RESULT
  2396. * XMLRPC_CASE -- newly set option
  2397. * BUGS
  2398. * Nasty and gross. Should be server specific, but that requires changing all
  2399. * the XMLRPC_VALUE api's.
  2400. * SEE ALSO
  2401. * XMLRPC_GetDefaultIdCase ()
  2402. * SOURCE
  2403. */
  2404. XMLRPC_CASE XMLRPC_SetDefaultIdCase(XMLRPC_CASE id_case) {
  2405. XMLRPC_OPTIONS options = XMLRPC_GetDefaultOptions();
  2406. options->id_case = id_case;
  2407. return options->id_case;
  2408. }
  2409. /*******/
  2410. /****f* VALUE/XMLRPC_GetDefaultIdCaseComparison
  2411. * NAME
  2412. * XMLRPC_GetDefaultIdCaseComparison
  2413. * SYNOPSIS
  2414. * XMLRPC_CASE XMLRPC_GetDefaultIdCaseComparison( )
  2415. * FUNCTION
  2416. * Gets default case comparison options used by XMLRPC_VALUE funcs
  2417. * INPUTS
  2418. * none
  2419. * RESULT
  2420. * XMLRPC_CASE_COMPARISON default
  2421. * BUGS
  2422. * Nasty and gross. Should be server specific, but that requires changing all
  2423. * the XMLRPC_VALUE api's.
  2424. * SEE ALSO
  2425. * XMLRPC_SetDefaultIdCaseComparison ()
  2426. * SOURCE
  2427. */
  2428. XMLRPC_CASE_COMPARISON XMLRPC_GetDefaultIdCaseComparison() {
  2429. XMLRPC_OPTIONS options = XMLRPC_GetDefaultOptions();
  2430. return options->id_case_compare;
  2431. }
  2432. /*******/
  2433. /****f* VALUE/XMLRPC_SetDefaultIdCaseComparison
  2434. * NAME
  2435. * XMLRPC_SetDefaultIdCaseComparison
  2436. * SYNOPSIS
  2437. * XMLRPC_CASE XMLRPC_SetDefaultIdCaseComparison( XMLRPC_CASE_COMPARISON id_case_compare )
  2438. * FUNCTION
  2439. * Gets default case comparison options used by XMLRPC_VALUE funcs
  2440. * INPUTS
  2441. * id_case_compare case comparison rule to set as default
  2442. * RESULT
  2443. * XMLRPC_CASE_COMPARISON newly set default
  2444. * BUGS
  2445. * Nasty and gross. Should be server specific, but that requires changing all
  2446. * the XMLRPC_VALUE api's.
  2447. * SEE ALSO
  2448. * XMLRPC_GetDefaultIdCaseComparison ()
  2449. * SOURCE
  2450. */
  2451. XMLRPC_CASE_COMPARISON XMLRPC_SetDefaultIdCaseComparison(XMLRPC_CASE_COMPARISON id_case_compare) {
  2452. XMLRPC_OPTIONS options = XMLRPC_GetDefaultOptions();
  2453. options->id_case_compare = id_case_compare;
  2454. return options->id_case_compare;
  2455. }
  2456. /*******/
  2457. /*-*********************************
  2458. * End XMLRPC General Options funcs *
  2459. ***********************************/
  2460. /*-******************
  2461. * Fault API funcs *
  2462. ********************/
  2463. /****f* UTILITY/XMLRPC_UtilityCreateFault
  2464. * NAME
  2465. * XMLRPC_UtilityCreateFault
  2466. * SYNOPSIS
  2467. * XMLRPC_VALUE XMLRPC_UtilityCreateFault( int fault_code, const char* fault_string )
  2468. * FUNCTION
  2469. * generates a struct containing a string member with id "faultString" and an int member
  2470. * with id "faultCode". When using the xmlrpc xml serialization, these will be translated
  2471. * to <fault><value><struct>... format.
  2472. * INPUTS
  2473. * fault_code application specific error code. can be 0.
  2474. * fault_string application specific error string. cannot be null.
  2475. * RESULT
  2476. * XMLRPC_VALUE a newly created struct vector representing the error, or null on error.
  2477. * NOTES
  2478. * This is a utility function. xmlrpc "faults" are not directly represented in this xmlrpc
  2479. * API or data structures. It is the author's view, that this API is intended for simple
  2480. * data types, and a "fault" is a complex data type consisting of multiple simple data
  2481. * types. This function is provided for convenience only, the same result could be
  2482. * achieved directly by the application.
  2483. *
  2484. * This function now supports some "standardized" fault codes, as specified at.
  2485. * http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php.
  2486. * If one of these fault codes is received, the description string will automatically
  2487. * be prefixed with a standard error string and 2 newlines.
  2488. *
  2489. * The actual transformation between this complex type and the xml "<fault>" element takes
  2490. * place in the xmlrpc to xml serialization layer. This step is not performed when using the
  2491. * simplerpc serialization, meaning that there will be no "<fault>" element in that
  2492. * serialization. There will simply be a standard struct with 2 child elements.
  2493. * imho, the "<fault>" element is unnecessary and/or out of place as part of the standard API.
  2494. *
  2495. * SOURCE
  2496. */
  2497. XMLRPC_VALUE XMLRPC_UtilityCreateFault(int fault_code, const char* fault_string) {
  2498. XMLRPC_VALUE xOutput = NULL;
  2499. char* string = NULL;
  2500. simplestring description;
  2501. simplestring_init(&description);
  2502. switch (fault_code) {
  2503. case xmlrpc_error_parse_xml_syntax:
  2504. string = xmlrpc_error_parse_xml_syntax_str;
  2505. break;
  2506. case xmlrpc_error_parse_unknown_encoding:
  2507. string = xmlrpc_error_parse_unknown_encoding_str;
  2508. break;
  2509. case xmlrpc_error_parse_bad_encoding:
  2510. string = xmlrpc_error_parse_bad_encoding_str;
  2511. break;
  2512. case xmlrpc_error_invalid_xmlrpc:
  2513. string = xmlrpc_error_invalid_xmlrpc_str;
  2514. break;
  2515. case xmlrpc_error_unknown_method:
  2516. string = xmlrpc_error_unknown_method_str;
  2517. break;
  2518. case xmlrpc_error_invalid_params:
  2519. string = xmlrpc_error_invalid_params_str;
  2520. break;
  2521. case xmlrpc_error_internal_server:
  2522. string = xmlrpc_error_internal_server_str;
  2523. break;
  2524. case xmlrpc_error_application:
  2525. string = xmlrpc_error_application_str;
  2526. break;
  2527. case xmlrpc_error_system:
  2528. string = xmlrpc_error_system_str;
  2529. break;
  2530. case xmlrpc_error_transport:
  2531. string = xmlrpc_error_transport_str;
  2532. break;
  2533. }
  2534. simplestring_add(&description, string);
  2535. if(string && fault_string) {
  2536. simplestring_add(&description, "\n\n");
  2537. }
  2538. simplestring_add(&description, fault_string);
  2539. if(description.len) {
  2540. xOutput = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct);
  2541. XMLRPC_VectorAppendString (xOutput, "faultString", description.str,
  2542. description.len);
  2543. XMLRPC_VectorAppendInt(xOutput, "faultCode", fault_code);
  2544. }
  2545. simplestring_free(&description);
  2546. return xOutput;
  2547. }
  2548. /*******/
  2549. /****f* FAULT/XMLRPC_ValueIsFault
  2550. * NAME
  2551. * XMLRPC_ValueIsFault
  2552. * SYNOPSIS
  2553. * int XMLRPC_ValueIsFault (XMLRPC_VALUE value)
  2554. * FUNCTION
  2555. * Determines if a value encapsulates a fault "object"
  2556. * INPUTS
  2557. * value any XMLRPC_VALUE
  2558. * RESULT
  2559. * 1 if it is a fault, else 0
  2560. * SEE ALSO
  2561. * XMLRPC_ResponseIsFault ()
  2562. * SOURCE
  2563. */
  2564. int XMLRPC_ValueIsFault (XMLRPC_VALUE value) {
  2565. if( XMLRPC_VectorGetValueWithID(value, "faultCode") &&
  2566. XMLRPC_VectorGetValueWithID(value, "faultString") ) {
  2567. return 1;
  2568. }
  2569. return 0;
  2570. }
  2571. /*******/
  2572. /****f* FAULT/XMLRPC_ResponseIsFault
  2573. * NAME
  2574. * XMLRPC_ResponseIsFault
  2575. * SYNOPSIS
  2576. * int XMLRPC_ResponseIsFault (XMLRPC_REQUEST response)
  2577. * FUNCTION
  2578. * Determines if a response contains an encapsulated fault "object"
  2579. * INPUTS
  2580. * value any XMLRPC_REQUEST. typically of type xmlrpc_request_response
  2581. * RESULT
  2582. * 1 if it contains a fault, else 0
  2583. * SEE ALSO
  2584. * XMLRPC_ValueIsFault ()
  2585. * SOURCE
  2586. */
  2587. int XMLRPC_ResponseIsFault(XMLRPC_REQUEST response) {
  2588. return XMLRPC_ValueIsFault( XMLRPC_RequestGetData(response) );
  2589. }
  2590. /*******/
  2591. /****f* FAULT/XMLRPC_GetValueFaultCode
  2592. * NAME
  2593. * XMLRPC_GetValueFaultCode
  2594. * SYNOPSIS
  2595. * int XMLRPC_GetValueFaultCode (XMLRPC_VALUE value)
  2596. * FUNCTION
  2597. * returns fault code from a struct, if any
  2598. * INPUTS
  2599. * value XMLRPC_VALUE of type xmlrpc_vector_struct.
  2600. * RESULT
  2601. * fault code, else 0.
  2602. * BUGS
  2603. * impossible to distinguish faultCode == 0 from faultCode not present.
  2604. * SEE ALSO
  2605. * XMLRPC_GetResponseFaultCode ()
  2606. * SOURCE
  2607. */
  2608. int XMLRPC_GetValueFaultCode (XMLRPC_VALUE value) {
  2609. return XMLRPC_VectorGetIntWithID(value, "faultCode");
  2610. }
  2611. /*******/
  2612. /****f* FAULT/XMLRPC_GetResponseFaultCode
  2613. * NAME
  2614. * XMLRPC_GetResponseFaultCode
  2615. * SYNOPSIS
  2616. * int XMLRPC_GetResponseFaultCode(XMLRPC_REQUEST response)
  2617. * FUNCTION
  2618. * returns fault code from a response, if any
  2619. * INPUTS
  2620. * response XMLRPC_REQUEST. typically of type xmlrpc_request_response.
  2621. * RESULT
  2622. * fault code, else 0.
  2623. * BUGS
  2624. * impossible to distinguish faultCode == 0 from faultCode not present.
  2625. * SEE ALSO
  2626. * XMLRPC_GetValueFaultCode ()
  2627. * SOURCE
  2628. */
  2629. int XMLRPC_GetResponseFaultCode(XMLRPC_REQUEST response) {
  2630. return XMLRPC_GetValueFaultCode( XMLRPC_RequestGetData(response) );
  2631. }
  2632. /*******/
  2633. /****f* FAULT/XMLRPC_GetValueFaultString
  2634. * NAME
  2635. * XMLRPC_GetValueFaultString
  2636. * SYNOPSIS
  2637. * const char* XMLRPC_GetValueFaultString (XMLRPC_VALUE value)
  2638. * FUNCTION
  2639. * returns fault string from a struct, if any
  2640. * INPUTS
  2641. * value XMLRPC_VALUE of type xmlrpc_vector_struct.
  2642. * RESULT
  2643. * fault string, else 0.
  2644. * SEE ALSO
  2645. * XMLRPC_GetResponseFaultString ()
  2646. * SOURCE
  2647. */
  2648. const char* XMLRPC_GetValueFaultString (XMLRPC_VALUE value) {
  2649. return XMLRPC_VectorGetStringWithID(value, "faultString");
  2650. }
  2651. /*******/
  2652. /****f* FAULT/XMLRPC_GetResponseFaultString
  2653. * NAME
  2654. * XMLRPC_GetResponseFaultString
  2655. * SYNOPSIS
  2656. * const char* XMLRPC_GetResponseFaultString (XMLRPC_REQUEST response)
  2657. * FUNCTION
  2658. * returns fault string from a response, if any
  2659. * INPUTS
  2660. * response XMLRPC_REQUEST. typically of type xmlrpc_request_response.
  2661. * RESULT
  2662. * fault string, else 0.
  2663. * SEE ALSO
  2664. * XMLRPC_GetValueFaultString ()
  2665. * SOURCE
  2666. */
  2667. const char* XMLRPC_GetResponseFaultString (XMLRPC_REQUEST response) {
  2668. return XMLRPC_GetValueFaultString( XMLRPC_RequestGetData(response) );
  2669. }
  2670. /*******/
  2671. /*-******************
  2672. * Utility API funcs *
  2673. ********************/
  2674. /****f* UTILITY/XMLRPC_Free
  2675. * NAME
  2676. * XMLRPC_Free
  2677. * SYNOPSIS
  2678. * void XMLRPC_Free(void* mem)
  2679. * FUNCTION
  2680. * frees a block of memory allocated by xmlrpc.
  2681. * INPUTS
  2682. * mem memory to free
  2683. * RESULT
  2684. * void
  2685. * NOTES
  2686. * Useful for OS's where memory must be free'd
  2687. * in the same library in which it is allocated.
  2688. * SOURCE
  2689. */
  2690. void XMLRPC_Free(void* mem) {
  2691. my_free(mem);
  2692. }
  2693. /*******/
  2694. /****f* UTILITY/XMLRPC_GetVersionString
  2695. * NAME
  2696. * XMLRPC_GetVersionString
  2697. * SYNOPSIS
  2698. * const char* XMLRPC_GetVersionString()
  2699. * FUNCTION
  2700. * returns library version string
  2701. * INPUTS
  2702. *
  2703. * RESULT
  2704. * const char*
  2705. * NOTES
  2706. * SOURCE
  2707. */
  2708. const char* XMLRPC_GetVersionString() {
  2709. return XMLRPC_VERSION_STR;
  2710. }
  2711. /*******/
  2712. /*-**********************
  2713. * End Utility API funcs *
  2714. ************************/