OSDN Git Service

3.15 taka-san version
[nucleus-jp/nucleus-jp-ancient.git] / utf8 / nucleus / libs / xmlrpcs.inc.php
1 <?php\r
2 // by Edd Dumbill (C) 1999-2001\r
3 // <edd@usefulinc.com>\r
4 // $Id: xmlrpcs.inc.php,v 1.2 2005-03-04 08:09:34 kimitake Exp $\r
5 \r
6 // Copyright (c) 1999,2000,2001 Edd Dumbill.\r
7 // All rights reserved.\r
8 //\r
9 // Redistribution and use in source and binary forms, with or without\r
10 // modification, are permitted provided that the following conditions\r
11 // are met:\r
12 //\r
13 //    * Redistributions of source code must retain the above copyright\r
14 //      notice, this list of conditions and the following disclaimer.\r
15 //\r
16 //    * Redistributions in binary form must reproduce the above\r
17 //      copyright notice, this list of conditions and the following\r
18 //      disclaimer in the documentation and/or other materials provided\r
19 //      with the distribution.\r
20 //\r
21 //    * Neither the name of the "XML-RPC for PHP" nor the names of its\r
22 //      contributors may be used to endorse or promote products derived\r
23 //      from this software without specific prior written permission.\r
24 //\r
25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
26 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
27 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
28 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
29 // REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
30 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
31 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
32 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
33 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
34 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
35 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
36 // OF THE POSSIBILITY OF SUCH DAMAGE.\r
37 \r
38 // XML RPC Server class\r
39 // requires: xmlrpc.inc\r
40 \r
41 // listMethods: either a string, or nothing\r
42 $_xmlrpcs_listMethods_sig=array(array($xmlrpcArray, $xmlrpcString), \r
43                                                                                                                                 array($xmlrpcArray));\r
44 $_xmlrpcs_listMethods_doc='This method lists all the methods that the XML-RPC server knows how to dispatch';\r
45 function _xmlrpcs_listMethods($server, $m) {\r
46         global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;\r
47         $v=new xmlrpcval();\r
48         $dmap=$server->dmap;\r
49         $outAr=array();\r
50         for(reset($dmap); list($key, $val)=each($dmap); ) {\r
51                 $outAr[]=new xmlrpcval($key, "string");\r
52         }\r
53         $dmap=$_xmlrpcs_dmap;\r
54         for(reset($dmap); list($key, $val)=each($dmap); ) {\r
55                 $outAr[]=new xmlrpcval($key, "string");\r
56         }\r
57         $v->addArray($outAr);\r
58         return new xmlrpcresp($v);\r
59 }\r
60 \r
61 $_xmlrpcs_methodSignature_sig=array(array($xmlrpcArray, $xmlrpcString));\r
62 $_xmlrpcs_methodSignature_doc='Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)';\r
63 function _xmlrpcs_methodSignature($server, $m) {\r
64         global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;\r
65 \r
66         $methName=$m->getParam(0);\r
67         $methName=$methName->scalarval();\r
68         if (ereg("^system\.", $methName)) {\r
69                 $dmap=$_xmlrpcs_dmap; $sysCall=1;\r
70         } else {\r
71                 $dmap=$server->dmap; $sysCall=0;\r
72         }\r
73         //      print "<!-- ${methName} -->\n";\r
74         if (isset($dmap[$methName])) {\r
75                 if ($dmap[$methName]["signature"]) {\r
76                         $sigs=array();\r
77                         $thesigs=$dmap[$methName]["signature"];\r
78                         for($i=0; $i<sizeof($thesigs); $i++) {\r
79                                 $cursig=array();\r
80                                 $inSig=$thesigs[$i];\r
81                                 for($j=0; $j<sizeof($inSig); $j++) {\r
82                                         $cursig[]=new xmlrpcval($inSig[$j], "string");\r
83                                 }\r
84                                 $sigs[]=new xmlrpcval($cursig, "array");\r
85                         }\r
86                         $r=new xmlrpcresp(new xmlrpcval($sigs, "array"));\r
87                 } else {\r
88                         $r=new xmlrpcresp(new xmlrpcval("undef", "string"));\r
89                 }\r
90         } else {\r
91                         $r=new xmlrpcresp(0,\r
92                                                   $xmlrpcerr["introspect_unknown"],\r
93                                                   $xmlrpcstr["introspect_unknown"]);\r
94         }\r
95         return $r;\r
96 }\r
97 \r
98 $_xmlrpcs_methodHelp_sig=array(array($xmlrpcString, $xmlrpcString));\r
99 $_xmlrpcs_methodHelp_doc='Returns help text if defined for the method passed, otherwise returns an empty string';\r
100 function _xmlrpcs_methodHelp($server, $m) {\r
101         global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap;\r
102 \r
103         $methName=$m->getParam(0);\r
104         $methName=$methName->scalarval();\r
105         if (ereg("^system\.", $methName)) {\r
106                 $dmap=$_xmlrpcs_dmap; $sysCall=1;\r
107         } else {\r
108                 $dmap=$server->dmap; $sysCall=0;\r
109         }\r
110         //      print "<!-- ${methName} -->\n";\r
111         if (isset($dmap[$methName])) {\r
112                 if ($dmap[$methName]["docstring"]) {\r
113                         $r=new xmlrpcresp(new xmlrpcval($dmap[$methName]["docstring"]),\r
114                                                                                                 "string");\r
115                 } else {\r
116                         $r=new xmlrpcresp(new xmlrpcval("", "string"));\r
117                 }\r
118         } else {\r
119                         $r=new xmlrpcresp(0,\r
120                                                   $xmlrpcerr["introspect_unknown"],\r
121                                                   $xmlrpcstr["introspect_unknown"]);\r
122         }\r
123         return $r;\r
124 }\r
125 \r
126 $_xmlrpcs_dmap=array(\r
127                                                                                  "system.listMethods" =>\r
128                                                                                  array("function" => "_xmlrpcs_listMethods",\r
129                                                                                                          "signature" => $_xmlrpcs_listMethods_sig,\r
130                                                                                                          "docstring" => $_xmlrpcs_listMethods_doc),\r
131                                                                                  "system.methodHelp" =>\r
132                                                                                  array("function" => "_xmlrpcs_methodHelp",\r
133                                                                                                          "signature" => $_xmlrpcs_methodHelp_sig,\r
134                                                                                                          "docstring" => $_xmlrpcs_methodHelp_doc),\r
135                                                                                  "system.methodSignature" =>\r
136                                                                                  array("function" => "_xmlrpcs_methodSignature",\r
137                                                                                                          "signature" => $_xmlrpcs_methodSignature_sig,\r
138                                                                                                          "docstring" => $_xmlrpcs_methodSignature_doc)\r
139                                                                                  );\r
140 \r
141 $_xmlrpc_debuginfo="";\r
142 function xmlrpc_debugmsg($m) {\r
143         global $_xmlrpc_debuginfo;\r
144         $_xmlrpc_debuginfo=$_xmlrpc_debuginfo . $m . "\n";\r
145 }\r
146 \r
147 class xmlrpc_server {\r
148   var $dmap=array();\r
149 \r
150   function xmlrpc_server($dispMap, $serviceNow=1) {\r
151                 global $HTTP_RAW_POST_DATA;\r
152                 // dispMap is a despatch array of methods\r
153                 // mapped to function names and signatures\r
154                 // if a method\r
155                 // doesn't appear in the map then an unknown\r
156                 // method error is generated\r
157                 $this->dmap=$dispMap;\r
158                 if ($serviceNow) {\r
159                         $this->service();\r
160                 }\r
161   }\r
162 \r
163         function serializeDebug() {\r
164                 global $_xmlrpc_debuginfo;\r
165                 if ($_xmlrpc_debuginfo!="") \r
166                         return "<!-- DEBUG INFO:\n\n" .\r
167                                 $_xmlrpc_debuginfo . "\n-->\n";\r
168                 else\r
169                         return "";\r
170         }\r
171 \r
172         function service() {\r
173                 $r=$this->parseRequest();\r
174                 $payload="<" . "?xml version=\"1.0\"?" . ">\n" . \r
175                         $this->serializeDebug() .\r
176                         $r->serialize();\r
177                 Header("Content-type: text/xml\r\nContent-length: " . \r
178                                          strlen($payload));\r
179                 print $payload;\r
180         }\r
181 \r
182         function verifySignature($in, $sig) {\r
183                 for($i=0; $i<sizeof($sig); $i++) {\r
184                         // check each possible signature in turn\r
185                         $cursig=$sig[$i];\r
186                         if (sizeof($cursig)==$in->getNumParams()+1) {\r
187                                 $itsOK=1;\r
188                                 for($n=0; $n<$in->getNumParams(); $n++) {\r
189                                         $p=$in->getParam($n);\r
190                                         // print "<!-- $p -->\n";\r
191                                         if ($p->kindOf() == "scalar") {\r
192                                                 $pt=$p->scalartyp();\r
193                                         } else {\r
194                                                 $pt=$p->kindOf();\r
195                                         }\r
196                                         // $n+1 as first type of sig is return type\r
197                                         if ($pt != $cursig[$n+1]) {\r
198                                                 $itsOK=0;\r
199                                                 $pno=$n+1; $wanted=$cursig[$n+1]; $got=$pt;\r
200                                                 break;\r
201                                         }\r
202                                 }\r
203                         if ($itsOK) \r
204                                 return array(1);\r
205                         }\r
206                 }\r
207                 return array(0, "Wanted ${wanted}, got ${got} at param ${pno})");\r
208         }\r
209 \r
210   function parseRequest($data="") {\r
211         global $_xh,$HTTP_RAW_POST_DATA;\r
212         global $xmlrpcerr, $xmlrpcstr, $xmlrpcerrxml, $xmlrpc_defencoding,\r
213                 $_xmlrpcs_dmap;\r
214 \r
215         \r
216 \r
217         if ($data=="") {\r
218           $data=$HTTP_RAW_POST_DATA;\r
219         }\r
220         $parser = xml_parser_create($xmlrpc_defencoding);\r
221 \r
222         $_xh[$parser]=array();\r
223         $_xh[$parser]['st']="";\r
224         $_xh[$parser]['cm']=0; \r
225         $_xh[$parser]['isf']=0; \r
226         $_xh[$parser]['params']=array();\r
227         $_xh[$parser]['method']="";\r
228 \r
229         // decompose incoming XML into request structure\r
230 \r
231         xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);\r
232         xml_set_element_handler($parser, "xmlrpc_se", "xmlrpc_ee");\r
233         xml_set_character_data_handler($parser, "xmlrpc_cd");\r
234         xml_set_default_handler($parser, "xmlrpc_dh");\r
235         if (!xml_parse($parser, $data, 1)) {\r
236           // return XML error as a faultCode\r
237           $r=new xmlrpcresp(0,\r
238                                                 $xmlrpcerrxml+xml_get_error_code($parser),\r
239                                                 sprintf("XML error: %s at line %d",\r
240                                         xml_error_string(xml_get_error_code($parser)),\r
241                                   xml_get_current_line_number($parser)));\r
242           xml_parser_free($parser);\r
243         } else {\r
244           xml_parser_free($parser);\r
245           $m=new xmlrpcmsg($_xh[$parser]['method']);\r
246           // now add parameters in\r
247           $plist="";\r
248           for($i=0; $i<sizeof($_xh[$parser]['params']); $i++) {\r
249                         //print "<!-- " . $_xh[$parser]['params'][$i]. "-->\n";\r
250                         $plist.="$i - " .  $_xh[$parser]['params'][$i]. " \n";\r
251                         eval('$m->addParam(' . $_xh[$parser]['params'][$i]. ");");\r
252           }\r
253                 // uncomment this to really see what the server's getting!\r
254                 // xmlrpc_debugmsg($plist);\r
255           // now to deal with the method\r
256                 $methName=$_xh[$parser]['method'];\r
257                 if (ereg("^system\.", $methName)) {\r
258                         $dmap=$_xmlrpcs_dmap; $sysCall=1;\r
259                 } else {\r
260                         $dmap=$this->dmap; $sysCall=0;\r
261                 }\r
262           if (isset($dmap[$methName]['function'])) {\r
263                         // dispatch if exists\r
264                         if (isset($dmap[$methName]['signature'])) {\r
265                                 $sr=$this->verifySignature($m, \r
266                                                                                                                                         $dmap[$methName]['signature'] );\r
267                         }\r
268                         if ( (!isset($dmap[$methName]['signature']))\r
269                                          || $sr[0]) {\r
270                                 // if no signature or correct signature\r
271                                 if ($sysCall) { \r
272                                         eval('$r=' . $dmap[$methName]['function'] . \r
273                                                          '($this, $m);');\r
274                                 } else {\r
275                                         eval('$r=' . $dmap[$methName]['function'] . \r
276                                                          '($m);');\r
277                                 }\r
278                         } else {\r
279                                 $r=new xmlrpcresp(0,\r
280                                                   $xmlrpcerr["incorrect_params"],\r
281                                                   $xmlrpcstr["incorrect_params"].": ". $sr[1]);\r
282                         }\r
283           } else {\r
284                 // else prepare error response\r
285                 $r=new xmlrpcresp(0,\r
286                                                   $xmlrpcerr["unknown_method"],\r
287                                                   $xmlrpcstr["unknown_method"]);\r
288           }\r
289         }\r
290         return $r;\r
291   }\r
292 \r
293   function echoInput() {\r
294         global $HTTP_RAW_POST_DATA;\r
295 \r
296         // a debugging routine: just echos back the input\r
297         // packet as a string value\r
298 \r
299         $r=new xmlrpcresp;\r
300         $r->xv=new xmlrpcval( "'Aha said I: '" . $HTTP_RAW_POST_DATA, "string");\r
301         print $r->serialize();\r
302   }\r
303 }\r
304 \r
305 ?>\r