PageRenderTime 28ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/soar/1.2/common/php/sample/sock/request_one/server.php

http://arronwork.googlecode.com/
PHP | 440 lines | 402 code | 32 blank | 6 comment | 62 complexity | 132aa3556e93e9a601be786d91ff70f9 MD5 | raw file
  1. #!/usr/bin/env php
  2. <?php
  3. $SOAR_DIR=getenv("SOAR_DIR");
  4. if(empty($SOAR_DIR)) $SOAR_DIR="/opt/soar";
  5. $SOAR_DIR="../../../../..";
  6. include "$SOAR_DIR/common/php/soar/soar.inc";
  7. class stat
  8. {/*{{{*/
  9. public static $client=array(); // ip:port => call_num
  10. public static $client_conn_num=0;
  11. public static $svc=array(); // name => call_num
  12. }/*}}}*/
  13. function load_cnfg()
  14. {/*{{{*/
  15. $cnfg_file=dirname(__FILE__)."/server.cnfg.inc";
  16. include $cnfg_file;
  17. if(empty(cnfg::$access['server_port']) ||
  18. cnfg::$access['server_port'] < 1024)
  19. {
  20. printf("%s: access.server_port invalid\n", __METHOD__);
  21. return false;
  22. }
  23. if(empty(cnfg::$access['monitor_port']) ||
  24. cnfg::$access['monitor_port'] < 1024)
  25. {
  26. printf("%s: access.monitor_port invalid\n", __METHOD__);
  27. return false;
  28. }
  29. return true;
  30. }/*}}}*/
  31. class worker
  32. {/*{{{*/
  33. private static $CONSOLE_IDLE_TIMEOUT=300;
  34. private static $CONN_IDLE_TIMEOUT=120;
  35. public static $listen_slots=array(); // 'server'=> 'monitor'=>
  36. public static $ep=null;
  37. private static $quit=false;
  38. private static $monitor_login=-1;
  39. private static $cmd_map=array(
  40. array('name'=>"printclient", 'ab'=>"pclt",
  41. 'desc'=>"print client ip & port",
  42. 'usage'=>"printclient(pwrk)"),
  43. array('name'=>"printservice", 'ab'=>"psvc",
  44. 'desc'=>"print service status",
  45. 'usage'=>"printservice(psvc)"),
  46. array('name'=>"shutdown", 'ab'=>"shutdown",
  47. 'desc'=>"shutdown server",
  48. 'usage'=>"shutdown"),
  49. array('name'=>"help", 'ab'=>"h",
  50. 'desc'=>"",
  51. 'usage'=>"help(h) [command]")
  52. );
  53. private function CMD_FUNC_PRINTCLIENT($request)
  54. {/*{{{*/
  55. $respond=
  56. "Client Calls\n".
  57. "------------ --------\n";
  58. foreach(stat::$client as $addr=>$call_num)
  59. {
  60. $respond.=sprintf("%-30s %8d\n",
  61. $addr, $call_num);
  62. }
  63. $respond.=
  64. "----------------------------------------\n";
  65. $respond.="Connected: ".stat::$client_conn_num."\n";
  66. return $respond;
  67. }/*}}}*/
  68. private function CMD_FUNC_PRINTSERVICE($request)
  69. {/*{{{*/
  70. $respond=
  71. "Service Calls\n".
  72. "------- ---------\n";
  73. foreach(stat::$svc as $name=>$call_num)
  74. {
  75. $respond.=sprintf("%-30s %9d\n",
  76. $name, $call_num);
  77. }
  78. return $respond;
  79. }/*}}}*/
  80. private function CMD_FUNC_SHUTDOWN($request)
  81. {/*{{{*/
  82. self::$quit=true;
  83. $respond="Shutdown complete\nDisconnect\n";
  84. return $respond;
  85. }/*}}}*/
  86. private function CMD_FUNC_HELP($request)
  87. {/*{{{*/
  88. if(empty($request))
  89. {
  90. $respond="help [command]\ncommands:\n";
  91. foreach(self::$cmd_map as $arr)
  92. {
  93. $respond.=" ".$arr['name']."\n";
  94. }
  95. return $respond;
  96. }
  97. $request=strtolower($request);
  98. foreach(self::$cmd_map as $arr)
  99. {
  100. if($arr['name'] == $request || $arr['ab'] == $request)
  101. {
  102. $respond="Description: ".$arr['desc']."\n".
  103. "Usage: ".$arr['usage']."\n";
  104. return $respond;
  105. }
  106. }
  107. $respond="Command not found, type help\n";
  108. return $respond;
  109. }/*}}}*/
  110. private function callcmd($request)
  111. {/*{{{*/
  112. $request=trim($request);
  113. $pos=strpos($request, " ");
  114. if($pos === false)
  115. {
  116. $cmd=$request;
  117. $body="";
  118. }
  119. else
  120. {
  121. $cmd=substr($request, 0, $pos);
  122. $body=substr($request, $pos);
  123. $body=ltrim($body);
  124. }
  125. $cmd=strtolower($cmd);
  126. //printf("cmd(%s)\n", $cmd);
  127. $cmdsize=strlen($cmd);
  128. if(0 < $cmdsize && $cmdsize <= misc::NAME_SIZE)
  129. {
  130. $found=false;
  131. foreach(self::$cmd_map as $arr)
  132. {
  133. if($arr['name'] == $cmd || $arr['ab'] == $cmd)
  134. {
  135. $found=true;
  136. $cmd=$arr['name'];
  137. break;
  138. }
  139. }
  140. if($found)
  141. {
  142. $func="CMD_FUNC_".strtoupper($cmd);
  143. $respond=self::$func($body);
  144. }
  145. else
  146. {
  147. $respond="command(".$cmd.") not found\n";
  148. }
  149. }
  150. else
  151. {
  152. $respond="command invalid\n";
  153. }
  154. return $respond;
  155. }/*}}}*/
  156. private function callsvc($request)
  157. {/*{{{*/
  158. if(!isset($request['svc']) ||
  159. strlen($request['svc']) > misc::NAME_SIZE)
  160. {
  161. errlog::add("%s: svc(%s) invalid",
  162. __METHOD__,
  163. isset($request['svc'])?$request['svc']:'null');
  164. return array('errcode'=>SOAR_ERR::SVC_INVALID);
  165. }
  166. $svc=strtoupper($request['svc']);
  167. if(class_exists($svc))
  168. {
  169. $ins=new $svc();
  170. $response=$ins->call($request['paras']);
  171. if(array_key_exists($svc, stat::$svc))
  172. ++stat::$svc[$svc];
  173. else
  174. stat::$svc[$svc]=1;
  175. }
  176. else
  177. {
  178. errlog::add("%s: func(%s) not found",
  179. __METHOD__, $svc);
  180. $response=array('errcode'=>SOAR_ERR::SVC_NOT_FOUND);
  181. }
  182. return $response;
  183. }/*}}}*/
  184. private function conn($active)
  185. {/*{{{*/
  186. if($active['slot_id'] == self::$listen_slots['monitor'])
  187. {
  188. if(self::$monitor_login >= 0)
  189. {
  190. errlog::add("%s: monitor has logged in", __METHOD__);
  191. socket_close($active['sock']);
  192. return false;
  193. }
  194. }
  195. $new_slot=self::$ep->add($active['new_sock']);
  196. if($new_slot === false)
  197. {
  198. errlog::add("%s: ep::add fail", __METHOD__);
  199. socket_close($active['new_sock']);
  200. return false;
  201. }
  202. if($active['slot_id'] == self::$listen_slots['monitor'])
  203. {
  204. self::$ep->set_timeout($new_slot,
  205. self::$CONSOLE_IDLE_TIMEOUT);
  206. self::$monitor_login=$new_slot;
  207. errlog::add("%s: monitor log in", __METHOD__);
  208. }
  209. else
  210. {
  211. self::$ep->set_timeout($new_slot,
  212. self::$CONN_IDLE_TIMEOUT);
  213. self::$ep->set_wrap($new_slot);
  214. $slot_info=self::$ep->get_info($new_slot);
  215. $addr=$slot_info['peer_ip'].":".$slot_info['peer_port'];
  216. stat::$client[$addr]=0;
  217. ++stat::$client_conn_num;
  218. //print "conn:$new_slot\n";
  219. }
  220. return true;
  221. }/*}}}*/
  222. private function recv($active)
  223. {/*{{{*/
  224. if($active['slot_id'] == self::$monitor_login)
  225. {
  226. $respond=self::callcmd($active['msg']);
  227. }
  228. else
  229. {
  230. $respond=self::callsvc($active['msg']);
  231. }
  232. $res=self::$ep->send($active['slot_id'], $respond);
  233. if($res == false)
  234. {
  235. errlog::add("%s: send fail", __METHOD__);
  236. }
  237. }/*}}}*/
  238. private function disconn($active)
  239. {/*{{{*/
  240. if($active['slot_id'] == self::$monitor_login)
  241. {
  242. self::$monitor_login=-1;
  243. errlog::add("%s: monitor %s revoke, error:%d",
  244. __METHOD__, $active['addr'], $active['error']);
  245. }
  246. else
  247. {
  248. if(array_key_exists($active['addr'], stat::$client))
  249. unset(stat::$client[$active['addr']]);
  250. errlog::add("%s: client %s %s, error:%d, total:%d, ",
  251. __METHOD__, $active['addr'],
  252. ($active['type']==ep::ABORT)?"abort":"timeout",
  253. $active['error'],
  254. count(stat::$client));
  255. }
  256. return true;
  257. }/*}}}*/
  258. public function start()
  259. {/*{{{*/
  260. $svc_dir="./svc";
  261. include_once "$svc_dir/svr.inc";
  262. $dh=opendir($svc_dir);
  263. while($inc=readdir($dh))
  264. {
  265. if(substr($inc, 0, 1) != "." &&
  266. substr($inc, -4) == ".inc" &&
  267. $inc != "svr.inc")
  268. {
  269. include_once "$svc_dir/$inc";
  270. printf("load $inc\n");
  271. }
  272. }
  273. while(!self::$quit)
  274. {
  275. $active_list=self::$ep->poll();
  276. if($active_list === false)
  277. {
  278. errlog::add("%s: ep::poll fail", __METHOD__);
  279. }
  280. else
  281. {
  282. foreach($active_list as $active)
  283. {
  284. //print_r($active);
  285. switch($active['type'])
  286. {
  287. case ep::CONN:
  288. self::conn($active);
  289. break;
  290. case ep::RECV:
  291. self::recv($active);
  292. break;
  293. case ep::ABORT:
  294. case ep::TIMEOUT:
  295. self::disconn($active);
  296. break;
  297. }
  298. }
  299. }
  300. }
  301. }/*}}}*/
  302. }/*}}}*/
  303. function start($daemon)
  304. {/*{{{*/
  305. if($daemon)
  306. {
  307. $pid=pcntl_fork();
  308. if($pid == -1)
  309. {
  310. printf("%s: daemonize fail", __METHOD__);
  311. return false;
  312. }
  313. if($pid > 0)
  314. {
  315. return true;
  316. }
  317. // errlog
  318. if(errlog::init(basename(__FILE__), cnfg::$errlog['location'])
  319. == false)
  320. {
  321. printf("%s: init errlog fail", __METHOD__);
  322. return false;
  323. }
  324. }
  325. // setuid
  326. if(posix_getuid() == 0)
  327. {
  328. if(!empty(cnfg::$user))
  329. {
  330. $user=posix_getpwnam(cnfg::$user);
  331. if($user)
  332. {
  333. if(posix_setuid($user['uid']) == false)
  334. {
  335. printf("Change to user %s fail\n", cnfg::$user);
  336. return false;
  337. }
  338. printf("Change to user %s\n", cnfg::$user);
  339. }
  340. else
  341. {
  342. printf("User %s not found, keep root\n", cnfg::$user);
  343. }
  344. }
  345. else
  346. {
  347. printf("User empty, keep root\n");
  348. }
  349. }
  350. stat::$client=array();
  351. stat::$client_conn_num=0;
  352. stat::$svc=array();
  353. $ep=new ep();
  354. $sock=sock::listen(cnfg::$access['monitor_port']);
  355. if($sock === false)
  356. {
  357. errlog::add("%s: open monitor_port(%d) fail",
  358. __METHOD__, cnfg::$access['monitor_port']);
  359. return false;
  360. }
  361. $slot_id=$ep->add_listen($sock);
  362. if($slot_id === false)
  363. {
  364. errlog::add("%s: ep::add_listen monitor fail", __METHOD__);
  365. return false;
  366. }
  367. worker::$listen_slots['monitor']=$slot_id;
  368. printf("open monitor port:%d slot:%d\n",
  369. cnfg::$access['monitor_port'], $slot_id);
  370. errlog::add("%s: open monitor port %d",
  371. __METHOD__, cnfg::$access['monitor_port']);
  372. $sock=sock::listen(cnfg::$access['server_port']);
  373. if($sock === false)
  374. {
  375. printf("%s: open server_port(%d) fail",
  376. __METHOD__, cnfg::$access['server_port']);
  377. return false;
  378. }
  379. $slot_id=$ep->add_listen($sock);
  380. if($slot_id === false)
  381. {
  382. errlog::add("%s: ep::add_listen server fail", __METHOD__);
  383. return false;
  384. }
  385. worker::$listen_slots['server']=$slot_id;
  386. printf("open server port:%d slot:%d\n",
  387. cnfg::$access['server_port'], $slot_id);
  388. errlog::add("%s: open server port %d",
  389. __METHOD__, cnfg::$access['server_port']);
  390. worker::$ep=$ep;
  391. return worker::start();
  392. }/*}}}*/
  393. function main($argv)
  394. {/*{{{*/
  395. if(load_cnfg() == false)
  396. return 1;
  397. $daemon=false;
  398. if(isset($argv[1]))
  399. {
  400. if($argv[1] == "-d" || $argv[1] == "--daemon")
  401. $daemon=true;
  402. }
  403. if(start($daemon) == false)
  404. return 1;
  405. return 0;
  406. }/*}}}*/
  407. exit(main($argv));
  408. ?>