OSDN Git Service

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