PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://arronwork.googlecode.com/
PHP | 428 lines | 391 code | 31 blank | 6 comment | 59 complexity | 6106da250fa5d5aba1dd1c467b10c666 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. $respond="";
  159. $curr=0;
  160. $svc=para::get_item($request, $curr);
  161. if(empty($svc) || strlen($svc) > misc::NAME_SIZE)
  162. {
  163. errlog::add("%s: svc(%s) invalid",
  164. __METHOD__,
  165. empty($svc)?"null":$svc);
  166. para::put_item($respond, SOAR_ERR_SVC_INVALID);
  167. }
  168. @include_once "./svc/${svc}.inc";
  169. $func="SVC_FUNC_$svc";
  170. if(function_exists($func))
  171. {
  172. $respond=$func($request);
  173. if(array_key_exists($svc, stat::$svc))
  174. ++stat::$svc[$svc];
  175. else
  176. stat::$svc[$svc]=1;
  177. }
  178. else
  179. {
  180. errlog::add("%s: func(%s) not found",
  181. __METHOD__, $svc);
  182. para::put_item($respond, SOAR_ERR_SVC_NOT_FOUND);
  183. }
  184. return $respond;
  185. }/*}}}*/
  186. private function conn($active)
  187. {/*{{{*/
  188. if($active['slot_id'] == self::$listen_slots['monitor'])
  189. {
  190. if(self::$monitor_login >= 0)
  191. {
  192. errlog::add("%s: monitor has logged in", __METHOD__);
  193. socket_close($active['sock']);
  194. return false;
  195. }
  196. }
  197. $new_slot=self::$ep->add($active['new_sock']);
  198. if($new_slot === false)
  199. {
  200. errlog::add("%s: ep::add fail", __METHOD__);
  201. socket_close($active['new_sock']);
  202. return false;
  203. }
  204. if($active['slot_id'] == self::$listen_slots['monitor'])
  205. {
  206. self::$ep->set_timeout($new_slot,
  207. self::$CONSOLE_IDLE_TIMEOUT);
  208. self::$monitor_login=$new_slot;
  209. errlog::add("%s: monitor log in", __METHOD__);
  210. }
  211. else
  212. {
  213. self::$ep->set_timeout($new_slot,
  214. self::$CONN_IDLE_TIMEOUT);
  215. self::$ep->set_wrap($new_slot);
  216. $slot_info=self::$ep->get_info($new_slot);
  217. $addr=$slot_info['peer_ip'].":".$slot_info['peer_port'];
  218. stat::$client[$addr]=0;
  219. ++stat::$client_conn_num;
  220. //print "conn:$new_slot\n";
  221. }
  222. return true;
  223. }/*}}}*/
  224. private function recv($active)
  225. {/*{{{*/
  226. if($active['slot_id'] == self::$monitor_login)
  227. {
  228. $respond=self::callcmd($active['msg']);
  229. }
  230. else
  231. {
  232. $respond=self::callsvc($active['msg']);
  233. }
  234. $res=self::$ep->send($active['slot_id'], $respond);
  235. if($res == false)
  236. {
  237. errlog::add("%s: send fail", __METHOD__);
  238. }
  239. }/*}}}*/
  240. private function disconn($active)
  241. {/*{{{*/
  242. if($active['slot_id'] == self::$monitor_login)
  243. {
  244. self::$monitor_login=-1;
  245. errlog::add("%s: monitor %s revoke, error:%d",
  246. __METHOD__, $active['addr'], $active['error']);
  247. }
  248. else
  249. {
  250. if(array_key_exists($active['addr'], stat::$client))
  251. unset(stat::$client[$active['addr']]);
  252. errlog::add("%s: client %s %s, error:%d, total:%d, ",
  253. __METHOD__, $active['addr'],
  254. ($active['type']==ep::ABORT)?"abort":"timeout",
  255. $active['error'],
  256. count(stat::$client));
  257. }
  258. return true;
  259. }/*}}}*/
  260. public function start()
  261. {/*{{{*/
  262. while(!self::$quit)
  263. {
  264. $active_list=self::$ep->poll();
  265. if($active_list === false)
  266. {
  267. errlog::add("%s: ep::poll fail", __METHOD__);
  268. }
  269. else
  270. {
  271. foreach($active_list as $active)
  272. {
  273. //print_r($active);
  274. switch($active['type'])
  275. {
  276. case ep::CONN:
  277. self::conn($active);
  278. break;
  279. case ep::RECV:
  280. self::recv($active);
  281. break;
  282. case ep::ABORT:
  283. case ep::TIMEOUT:
  284. self::disconn($active);
  285. break;
  286. }
  287. }
  288. }
  289. }
  290. }/*}}}*/
  291. }/*}}}*/
  292. function start($daemon)
  293. {/*{{{*/
  294. if($daemon)
  295. {
  296. $pid=pcntl_fork();
  297. if($pid == -1)
  298. {
  299. printf("%s: daemonize fail", __METHOD__);
  300. return false;
  301. }
  302. if($pid > 0)
  303. {
  304. return true;
  305. }
  306. // errlog
  307. if(errlog::init(basename(__FILE__), cnfg::$ERRLOG['LOCATION'])
  308. == false)
  309. {
  310. printf("%s: init errlog fail", __METHOD__);
  311. return false;
  312. }
  313. }
  314. // setuid
  315. if(posix_getuid() == 0)
  316. {
  317. if(!empty(cnfg::$USER))
  318. {
  319. $user=posix_getpwnam(cnfg::$USER);
  320. if($user)
  321. {
  322. if(posix_setuid($user['uid']) == false)
  323. {
  324. printf("Change to user %s fail\n", cnfg::$USER);
  325. return false;
  326. }
  327. printf("Change to user %s\n", cnfg::$USER);
  328. }
  329. else
  330. {
  331. printf("User %s not found, keep root\n", cnfg::$USER);
  332. }
  333. }
  334. else
  335. {
  336. printf("User empty, keep root\n");
  337. }
  338. }
  339. stat::$client=array();
  340. stat::$client_conn_num=0;
  341. stat::$svc=array();
  342. $ep=new ep();
  343. $sock=sock::listen(cnfg::$ACCESS['MONITOR_PORT']);
  344. if($sock === false)
  345. {
  346. errlog::add("%s: open monitor_port(%d) fail",
  347. __METHOD__, cnfg::$ACCESS['MONITOR_PORT']);
  348. return false;
  349. }
  350. $slot_id=$ep->add_listen($sock);
  351. if($slot_id === false)
  352. {
  353. errlog::add("%s: ep::add_listen monitor fail", __METHOD__);
  354. return false;
  355. }
  356. worker::$listen_slots['monitor']=$slot_id;
  357. printf("open monitor port:%d slot:%d\n",
  358. cnfg::$ACCESS['MONITOR_PORT'], $slot_id);
  359. errlog::add("%s: open monitor port %d",
  360. __METHOD__, cnfg::$ACCESS['MONITOR_PORT']);
  361. $sock=sock::listen(cnfg::$ACCESS['SERVER_PORT']);
  362. if($sock === false)
  363. {
  364. printf("%s: open server_port(%d) fail",
  365. __METHOD__, cnfg::$ACCESS['SERVER_PORT']);
  366. return false;
  367. }
  368. $slot_id=$ep->add_listen($sock);
  369. if($slot_id === false)
  370. {
  371. errlog::add("%s: ep::add_listen server fail", __METHOD__);
  372. return false;
  373. }
  374. worker::$listen_slots['server']=$slot_id;
  375. printf("open server port:%d slot:%d\n",
  376. cnfg::$ACCESS['SERVER_PORT'], $slot_id);
  377. errlog::add("%s: open server port %d",
  378. __METHOD__, cnfg::$ACCESS['SERVER_PORT']);
  379. worker::$ep=$ep;
  380. return worker::start();
  381. }/*}}}*/
  382. function main($argv)
  383. {/*{{{*/
  384. if(load_cnfg() == false)
  385. return 1;
  386. $daemon=false;
  387. if(isset($argv[1]))
  388. {
  389. if($argv[1] == "-d" || $argv[1] == "--daemon")
  390. $daemon=true;
  391. }
  392. if(start($daemon) == false)
  393. return 1;
  394. return 0;
  395. }/*}}}*/
  396. exit(main($argv));
  397. ?>