fifo_server.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #!/usr/bin/php4 -q
  2. <?php
  3. // $Id$
  4. // fifo_server.php - fifo/internet relay
  5. /*
  6. * Copyright (C) 2004 Juha Heinanen
  7. *
  8. * This file is part of ser, a free SIP server.
  9. *
  10. * ser is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version
  14. *
  15. * For a license to use the ser software under conditions
  16. * other than those described here, or to purchase support for this
  17. * software, please contact iptel.org by e-mail at the following addresses:
  18. * [email protected]
  19. *
  20. * ser is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program; if not, write to the Free Software
  27. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  28. *
  29. * History:
  30. * -------
  31. * 2004-06-11: fifo_server.php introduced as interim solution
  32. * until ser fifo natively supports tcp/ip access
  33. */
  34. error_reporting (E_ALL);
  35. require("/etc/ser/fifo_server.cfg");
  36. /* Check if fifo server is needed */
  37. if ($fifo_server_address == NULL) {
  38. return;
  39. }
  40. /* Allow the script to hang around waiting for connections. */
  41. set_time_limit (0);
  42. /* Turn on implicit output flushing so we see what we're getting
  43. * as it comes in. */
  44. ob_implicit_flush ();
  45. $fifo_clients = "/etc/ser/fifo_server.clients";
  46. global $mtime, $clients;
  47. $mtime = 0;
  48. function fifo_allow($fifo_clients, $addr) {
  49. global $mtime, $clients;
  50. $long_addr = ip2long($addr);
  51. if (!file_exists($fifo_clients)) {
  52. echo "fifo_server.clients file does not exist!\n";
  53. return FALSE;
  54. }
  55. clearstatcache();
  56. $cur_mtime = filemtime($fifo_clients);
  57. if ($cur_mtime > $mtime) {
  58. $fd = fopen($fifo_clients, "r");
  59. if ($fd == FALSE) {
  60. echo "Cannot open fifo.clients file!\n";
  61. return FALSE;
  62. }
  63. $clients = array();
  64. while (!feof ($fd)) {
  65. $client = ip2long(fgets($fd, 4096));
  66. if ($client != -1) {
  67. $clients[] = $client;
  68. }
  69. }
  70. fclose ($fd);
  71. $mtime = $cur_mtime;
  72. }
  73. return in_array($long_addr, $clients, TRUE);
  74. }
  75. if (($sock = socket_create (AF_INET, SOCK_STREAM, 0)) < 0) {
  76. echo "socket_create() failed: " . socket_strerror ($sock) . "\n";
  77. return;
  78. }
  79. if (($ret = socket_bind($sock, $fifo_server_address, $fifo_server_port)) < 0) {
  80. echo "socket_bind() failed: " . socket_strerror ($ret) . "\n";
  81. socket_close($sock);
  82. return;
  83. }
  84. if (($ret = socket_listen ($sock, 5)) < 0) {
  85. echo "socket_listen() failed: " . socket_strerror ($ret) . "\n";
  86. socket_close($sock);
  87. return;
  88. }
  89. do {
  90. if (($msgsock = socket_accept($sock)) < 0) {
  91. echo "socket_accept() failed: ".socket_strerror($msgsock)."\n";
  92. socket_close($msgsock);
  93. continue;
  94. }
  95. socket_getpeername($msgsock, $addr);
  96. if (!fifo_allow($fifo_clients, $addr)) {
  97. $msg = "403 Forbidden\n";
  98. socket_write($msgsock, $msg, strlen($msg));
  99. socket_shutdown($msgsock);
  100. socket_close($msgsock);
  101. continue;
  102. }
  103. if (FALSE === ($fifo_cmd = socket_read ($msgsock, 8192, PHP_BINARY_READ))) {
  104. echo "socket_read() failed: ".socket_strerror(socket_last_error($msgsock))."\n";
  105. socket_shutdown($msgsock);
  106. socket_close($msgsock);
  107. continue;
  108. }
  109. $fifo_reply_file_name = "ser_fifo_reply_".rand();
  110. $fifo_reply_file = "/tmp/".$fifo_reply_file_name;
  111. $fifo_cmd = str_replace("REPLY_FILE_NAME", $fifo_reply_file_name, $fifo_cmd);
  112. /* add command separator */
  113. $fifo_cmd=$fifo_cmd."\n";
  114. $fifo_handle=fopen( "/tmp/ser_fifo", "w" );
  115. if (!$fifo_handle) {
  116. $msg = "sorry -- cannot open write fifo";
  117. socket_write($msgsock, $msg, strlen($msg));
  118. socket_shutdown($msgsock);
  119. socket_close($msgsock);
  120. continue;
  121. }
  122. /* create fifo for replies */
  123. @system("mkfifo -m 666 ".$fifo_reply_file);
  124. /* write fifo command */
  125. if (fwrite( $fifo_handle, $fifo_cmd) == -1) {
  126. @unlink($fifo_reply_file);
  127. @fclose($fifo_handle);
  128. $msg = "sorry -- fifo writing error";
  129. socket_write($msgsock, $msg, strlen($msg));
  130. socket_shutdown($msgsock);
  131. socket_close($msgsock);
  132. continue;
  133. }
  134. @fclose($fifo_handle);
  135. /* read output now */
  136. @$fp = fopen($fifo_reply_file, "r");
  137. if (!$fp) {
  138. @unlink($fifo_reply_file);
  139. $msg = "sorry -- reply fifo opening error";
  140. socket_write($msgsock, $msg, strlen($msg));
  141. socket_shutdown($msgsock);
  142. socket_close($msgsock);
  143. continue;
  144. }
  145. $status = fgetS($fp, 256);
  146. if (!$status) {
  147. @unlink($fifo_reply_file);
  148. $msg = "sorry -- reply fifo reading error";
  149. socket_write($msgsock, $msg, strlen($msg));
  150. socket_shutdown($msgsock);
  151. socket_close($msgsock);
  152. continue;
  153. }
  154. socket_write($msgsock, $status, strlen($status));
  155. $rest = fread($fp, 8192);
  156. @unlink($fifo_reply_file);
  157. socket_write($msgsock, $rest, strlen($rest));
  158. socket_close ($msgsock);
  159. } while (true);
  160. socket_close ($sock);
  161. ?>