Back to index

php5  5.3.10
system_methods.c
Go to the documentation of this file.
00001 /*
00002   This file is part of libXMLRPC - a C library for xml-encoded function calls.
00003 
00004   Author: Dan Libby (dan@libby.com)
00005   Epinions.com may be contacted at feedback@epinions-inc.com
00006 */
00007 
00008 /*  
00009   Copyright 2001 Epinions, Inc. 
00010 
00011   Subject to the following 3 conditions, Epinions, Inc.  permits you, free 
00012   of charge, to (a) use, copy, distribute, modify, perform and display this 
00013   software and associated documentation files (the "Software"), and (b) 
00014   permit others to whom the Software is furnished to do so as well.  
00015 
00016   1) The above copyright notice and this permission notice shall be included 
00017   without modification in all copies or substantial portions of the 
00018   Software.  
00019 
00020   2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 
00021   ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 
00022   IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 
00023   PURPOSE OR NONINFRINGEMENT.  
00024 
00025   3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 
00026   SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 
00027   OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 
00028   NEGLIGENCE), EVEN IF EPINIONS, INC.  IS AWARE OF THE POSSIBILITY OF SUCH 
00029   DAMAGES.    
00030 
00031 */
00032 
00033 
00034 /****h* ABOUT/system_methods
00035  * AUTHOR
00036  *   Dan Libby, aka danda  (dan@libby.com)
00037  * HISTORY
00038  *   $Log$
00039  *   Revision 1.7  2001/09/29 21:58:05  danda
00040  *   adding cvs log to history section
00041  *
00042  *   4/28/2001 -- danda -- adding system.multicall and separating out system methods.
00043  * TODO
00044  * NOTES
00045  *******/
00046 
00047 
00048 #include "queue.h"
00049 #include "xmlrpc.h"
00050 #include "xmlrpc_private.h"
00051 #include "xmlrpc_introspection_private.h"
00052 #include "system_methods_private.h"
00053 #include <string.h>
00054 #include <stdlib.h>
00055 #include <stdarg.h>
00056 
00057 
00058 static const char* xsm_introspection_xml =
00059 "<?xml version='1.0' ?>"
00060 
00061 "<introspection version='1.0'>"
00062  "<typeList>"
00063 
00064  "<typeDescription name='system.value' basetype='struct' desc='description of a value'>"
00065    "<value type='string' name='name' optional='yes'>value identifier</value>"
00066    "<value type='string' name='type'>value&apos;s xmlrpc or user-defined type</value>"
00067    "<value type='string' name='description'>value&apos;s textual description</value> "
00068    "<value type='boolean' name='optional'>true if value is optional, else it is required</value> "
00069    "<value type='any' name='member' optional='yes'>a child of this element. n/a for scalar types</value> "
00070  "</typeDescription>"
00071 
00072  "<typeDescription name='system.valueList' basetype='array' desc='list of value descriptions'>"
00073    "<value type='system.value'/>"
00074  "</typeDescription>"
00075 
00076  "<typeDescription name='system.stringList' basetype='array' desc='list of strings'>"
00077    "<value type='string'/>"
00078  "</typeDescription>"
00079 
00080 
00081  "</typeList>"
00082 
00083  "<methodList>"
00084 
00085  "<!-- system.describeMethods -->"
00086  "<methodDescription name='system.describeMethods'>"
00087   "<author>Dan Libby</author>"
00088   "<purpose>fully describes the methods and types implemented by this XML-RPC server.</purpose>"
00089   "<version>1.1</version>"
00090   "<signatures>"
00091    "<signature>"
00092     "<params>"
00093      "<value type='array' name='methodList' optional='yes' desc='a list of methods to be described. if omitted, all are described.'>"
00094       "<value type='string'>a valid method name</value>"
00095      "</value>"
00096     "</params>"
00097     "<returns>"
00098      "<value type='struct' desc='contains methods list and types list'>"
00099       "<value type='array' name='methodList' desc='a list of methods'>"
00100        "<value type='struct' desc='representation of a single method'>"
00101         "<value type='string' name='name'>method name</value>"
00102         "<value type='string' name='version' optional='yes'>method version</value>"
00103         "<value type='string' name='author' optional='yes'>method author</value>"
00104         "<value type='string' name='purpose' optional='yes'>method purpose</value>"
00105         "<value type='array' name='signatures' desc='list of method signatures'>"
00106          "<value type='struct' desc='representation of a single signature'>"
00107           "<value type='system.valueList' name='params' optional='yes'>parameter list</value>"
00108           "<value type='system.valueList' name='returns' optional='yes'>return value list</value>"
00109          "</value>"
00110         "</value>"
00111         "<value type='system.stringList' name='bugs' optional='yes'>list of known bugs</value>"
00112         "<value type='system.stringList' name='errors' optional='yes'>list of possible errors and error codes</value>"
00113         "<value type='system.stringList' name='examples' optional='yes'>list of examples</value>"
00114         "<value type='system.stringList' name='history' optional='yes'>list of modifications</value>"
00115         "<value type='system.stringList' name='notes' optional='yes'>list of notes</value>"
00116         "<value type='system.stringList' name='see' optional='yes'>see also.  list of related methods</value>"
00117         "<value type='system.stringList' name='todo' optional='yes'>list of unimplemented features</value>"
00118        "</value>"
00119       "</value>"
00120       "<value type='array' name='typeList' desc='a list of type descriptions. Typically used for referencing complex types'>"
00121        "<value type='system.value'>a type description</value>"
00122       "</value>"
00123      "</value>"
00124     "</returns>"
00125    "</signature>"
00126   "</signatures>"
00127   "<see>"
00128    "<item name='system.listMethods' />"
00129    "<item name='system.methodSignature' />"
00130    "<item name='system.methodHelp' />"
00131   "</see>"
00132   "<example/>"
00133   "<error/>"
00134   "<note/>"
00135   "<bug/>"
00136   "<todo/>"
00137  "</methodDescription>"
00138 
00139  "<!-- system.listMethods -->"
00140  "<methodDescription name='system.listMethods'>"
00141   "<author>Dan Libby</author>"
00142   "<purpose>enumerates the methods implemented by this XML-RPC server.</purpose>"
00143   "<version>1.0</version>"
00144   "<signatures>"
00145    "<signature>"
00146     "<returns>"
00147      "<value type='array' desc='an array of strings'>"
00148       "<value type='string'>name of a method implemented by the server.</value>"
00149      "</value>"
00150     "</returns>"
00151    "</signature>"
00152   "</signatures>"
00153   "<see>"
00154    "<item name='system.describeMethods' />"
00155    "<item name='system.methodSignature' />"
00156    "<item name='system.methodHelp' />"
00157   "</see>"
00158   "<example/>"
00159   "<error/>"
00160   "<note/>"
00161   "<bug/>"
00162   "<todo/>"
00163  "</methodDescription>"
00164 
00165  "<!-- system.methodHelp -->"
00166  "<methodDescription name='system.methodHelp'>"
00167   "<author>Dan Libby</author>"
00168   "<purpose>provides documentation string for a single method</purpose>"
00169   "<version>1.0</version>"
00170   "<signatures>"
00171    "<signature>"
00172     "<params>"
00173      "<value type='string' name='methodName'>name of the method for which documentation is desired</value>"
00174     "</params>"
00175     "<returns>"
00176      "<value type='string'>help text if defined for the method passed, otherwise an empty string</value>"
00177     "</returns>"
00178    "</signature>"
00179   "</signatures>"
00180   "<see>"
00181    "<item name='system.listMethods' />"
00182    "<item name='system.methodSignature' />"
00183    "<item name='system.methodHelp' />"
00184   "</see>"
00185   "<example/>"
00186   "<error/>"
00187   "<note/>"
00188   "<bug/>"
00189   "<todo/>"
00190  "</methodDescription>"
00191 
00192  "<!-- system.methodSignature -->"
00193  "<methodDescription name='system.methodSignature'>"
00194   "<author>Dan Libby</author>"
00195   "<purpose>provides 1 or more signatures for a single method</purpose>"
00196   "<version>1.0</version>"
00197   "<signatures>"
00198    "<signature>"
00199     "<params>"
00200      "<value type='string' name='methodName'>name of the method for which documentation is desired</value>"
00201     "</params>"
00202     "<returns>"
00203      "<value type='array' desc='a list of arrays, each representing a signature'>"
00204       "<value type='array' desc='a list of strings. the first element represents the method return value. subsequent elements represent parameters.'>"
00205        "<value type='string'>a string indicating the xmlrpc type of a value. one of: string, int, double, base64, datetime, array, struct</value>"
00206       "</value>"
00207      "</value>"
00208     "</returns>"
00209    "</signature>"
00210   "</signatures>"
00211   "<see>"
00212    "<item name='system.listMethods' />"
00213    "<item name='system.methodHelp' />"
00214    "<item name='system.describeMethods' />"
00215   "</see>"
00216   "<example/>"
00217   "<error/>"
00218   "<note/>"
00219   "<bug/>"
00220   "<todo/>"
00221  "</methodDescription>"
00222 
00223  "<!-- system.multiCall -->"
00224  "<methodDescription name='system.multiCall'>"
00225   "<author>Dan Libby</author>"
00226   "<purpose>executes multiple methods in sequence and returns the results</purpose>"
00227   "<version>1.0</version>"
00228   "<signatures>"
00229    "<signature>"
00230     "<params>"
00231      "<value type='array' name='methodList' desc='an array of method call structs'>"
00232       "<value type='struct' desc='a struct representing a single method call'>"
00233        "<value type='string' name='methodName' desc='name of the method to be executed'/>"
00234        "<value type='array' name='params' desc='an array representing the params to a method. sub-elements should match method signature'/>"
00235       "</value>"
00236      "</value>"
00237     "</params>"
00238     "<returns>"
00239      "<value type='array' desc='an array of method responses'>"
00240       "<value type='array' desc='an array containing a single value, which is the method&apos;s response'/>"
00241      "</value>"
00242     "</returns>"
00243    "</signature>"
00244   "</signatures>"
00245   "<see>"
00246    "<item name='system.listMethods' />"
00247    "<item name='system.methodHelp' />"
00248    "<item name='system.describeMethods' />"
00249   "</see>"
00250   "<example/>"
00251   "<error/>"
00252   "<note/>"
00253   "<bug/>"
00254   "<todo/>"
00255  "</methodDescription>"
00256 
00257  "<!-- system.getCapabilities -->"
00258  "<methodDescription name='system.getCapabilities'>"
00259   "<author>Dan Libby</author>"
00260   "<purpose>returns a list of capabilities supported by this server</purpose>"
00261   "<version>1.0</version>"
00262   "<notes><item>spec url: http://groups.yahoo.com/group/xml-rpc/message/2897</item></notes>"
00263   "<signatures>"
00264    "<signature>"
00265     "<returns>"
00266      "<value type='struct' desc='list of capabilities, each with a unique key defined by the capability&apos;s spec'>"
00267       "<value type='struct' desc='definition of a single capability'>"
00268        "<value type='string' name='specURL'>www address of the specification defining this capability</value>"
00269        "<value type='int' name='specVersion'>version of the spec that this server's implementation conforms to</value>"
00270       "</value>"
00271      "</value>"
00272     "</returns>"
00273    "</signature>"
00274   "</signatures>"
00275   "<see>"
00276    "<item name='system.listMethods' />"
00277    "<item name='system.methodHelp' />"
00278    "<item name='system.describeMethods' />"
00279   "</see>"
00280   "<example/>"
00281   "<error/>"
00282   "<note/>"
00283   "<bug/>"
00284   "<todo/>"
00285  "</methodDescription>"
00286 
00287  "</methodList>"
00288 "</introspection>";
00289 
00290 
00291 /* forward declarations for static (non public, non api) funcs */
00292 static XMLRPC_VALUE xsm_system_multicall_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData);
00293 static XMLRPC_VALUE xsm_system_get_capabilities_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData);
00294 
00295 /*-*******************
00296 * System Methods API *
00297 *********************/
00298 
00299 static void xsm_lazy_doc_methods_cb(XMLRPC_SERVER server, void* userData) {
00300    XMLRPC_VALUE xDesc = XMLRPC_IntrospectionCreateDescription(xsm_introspection_xml, NULL);
00301    XMLRPC_ServerAddIntrospectionData(server, xDesc);
00302    XMLRPC_CleanupValue(xDesc);
00303 }
00304 
00305 void xsm_register(XMLRPC_SERVER server) {
00306    xi_register_system_methods(server);
00307 
00308    XMLRPC_ServerRegisterMethod(server, xsm_token_system_multicall, xsm_system_multicall_cb);
00309    XMLRPC_ServerRegisterMethod(server, xsm_token_system_get_capabilities, xsm_system_get_capabilities_cb);
00310 
00311    /* callback for documentation generation should it be requested */
00312    XMLRPC_ServerRegisterIntrospectionCallback(server, xsm_lazy_doc_methods_cb);
00313 }
00314 
00315 XMLRPC_VALUE xsm_system_multicall_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) {
00316    XMLRPC_VALUE xArray = XMLRPC_VectorRewind(XMLRPC_RequestGetData(input));
00317    XMLRPC_VALUE xReturn = XMLRPC_CreateVector(0, xmlrpc_vector_array);
00318 
00319    if (xArray) {
00320       XMLRPC_VALUE xMethodIter = XMLRPC_VectorRewind(xArray);
00321 
00322       while (xMethodIter) {
00323          XMLRPC_REQUEST request = XMLRPC_RequestNew();
00324          if(request) {
00325             const char* methodName = XMLRPC_VectorGetStringWithID(xMethodIter, "methodName");
00326             XMLRPC_VALUE params = XMLRPC_VectorGetValueWithID(xMethodIter, "params");
00327 
00328             if(methodName && params) {
00329                XMLRPC_VALUE xRandomArray = XMLRPC_CreateVector(0, xmlrpc_vector_array);
00330                XMLRPC_RequestSetMethodName(request, methodName);
00331                XMLRPC_RequestSetData(request, params);
00332                XMLRPC_RequestSetRequestType(request, xmlrpc_request_call);
00333 
00334                XMLRPC_AddValueToVector(xRandomArray, 
00335                                        XMLRPC_ServerCallMethod(server, request, userData));
00336 
00337                XMLRPC_AddValueToVector(xReturn, xRandomArray);
00338             }
00339             XMLRPC_RequestFree(request, 1);
00340          }
00341          xMethodIter = XMLRPC_VectorNext(xArray);
00342       }
00343    }
00344    return xReturn;
00345 }
00346 
00347 
00348 XMLRPC_VALUE xsm_system_get_capabilities_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) {
00349    XMLRPC_VALUE xReturn = XMLRPC_CreateVector(0, xmlrpc_vector_struct);
00350    XMLRPC_VALUE xFaults = XMLRPC_CreateVector("faults_interop", xmlrpc_vector_struct);
00351    XMLRPC_VALUE xIntro = XMLRPC_CreateVector("introspection", xmlrpc_vector_struct);
00352 
00353    /* support for fault spec */
00354    XMLRPC_VectorAppendString(xFaults, "specURL", "http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php", 0);
00355    XMLRPC_VectorAppendInt(xFaults, "specVersion", 20010516);
00356 
00357    /* support for introspection spec */
00358    XMLRPC_VectorAppendString(xIntro, "specURL", "http://xmlrpc-epi.sourceforge.net/specs/rfc.introspection.php", 0);
00359    XMLRPC_VectorAppendInt(xIntro, "specVersion", 20010516);
00360 
00361    XMLRPC_AddValuesToVector(xReturn,
00362                             xFaults,
00363                             xIntro,
00364                             NULL);
00365 
00366    return xReturn;
00367                             
00368 }
00369 
00370 /*-***********************
00371 * End System Methods API *
00372 *************************/
00373 
00374 
00375