* Fixed an error in the template that was causing the 'c_rbl_at_greeting' field to...
[citadel.git] / ctdlphp / sessionproxy.php
blob22f4d4a0eddc1272e5e210b17088de6b85c2bc6e
1 #!/usr/bin/php -q
3 <?php
4 include "config_ctdlclient.php";
5 // $Id$
6 //
7 // This is the session proxy that binds a unix domain socket to a Citadel
8 // server connection. We need one of these for each session because PHP does
9 // not have a way to bind a session to a persistent socket.
11 // Web designers: don't touch this module. It's not included in your web pages
12 // and therefore you don't need to be here.
14 // Copyright (c) 2003 by Art Cancro <ajc@uncensored.citadel.org>
15 // This program is released under the terms of the GNU General Public License.
17 global $msgsock;
19 // sock_gets() -- reads one line of text from a socket
20 //
21 if (CITADEL_DEBUG_PROXY)
23 define_syslog_variables();
24 openlog("sessionproxylog", LOG_PID | LOG_PERROR, LOG_LOCAL0);
26 function sock_gets($sock) {
27 global $msgsock;
28 socket_clear_error($msgsock);
29 $buf = socket_read($sock, 4096, PHP_NORMAL_READ);
30 if (CITADEL_DEBUG_PROXY)
32 syslog(LOG_DEBUG, "gets Read: ".$buf);
34 if (socket_last_error($sock)) return false;
36 if (preg_match("'\n$'s", $buf)) {
37 $buf = substr($buf, 0, strpos($buf, "\n"));
40 return $buf;
46 // *** Start of main program ***
48 error_reporting(E_ALL);
50 /* Allow the script to hang around waiting for connections. */
51 set_time_limit(0);
53 /* Turn on implicit output flushing so we see what we're getting
54 * as it comes in.
56 ob_implicit_flush();
58 if ($argc != 2) {
59 echo "usage: ", $argv[0], " sockname\n";
60 exit(1);
63 $sockname = $argv[1];
65 if ($sockname == "/tmp/") {
66 echo "Invalid socket name.\n";
67 exit(1);
70 // If there's a dead socket already there, remove it.
71 system("/bin/rm -f " . $sockname);
73 $sock = socket_create(AF_UNIX, SOCK_STREAM, 0);
74 if (!$sock) {
75 echo "socket_create() failed: ", socket_strerror($sock), "\n";
76 system("/bin/rm -f " . $sockname);
77 exit(2);
80 $ret = socket_bind($sock, $sockname);
81 if (!$ret) {
82 echo "socket_bind() failed: ", socket_strerror($ret), "\n";
83 system("/bin/rm -f " . $sockname);
84 exit(3);
87 $ret = socket_listen($sock, 5);
88 if (!$ret) {
89 echo "socket_listen() failed: ", socket_strerror($ret), "\n";
90 system("/bin/rm -f " . $sockname);
91 exit(4);
94 // Set the permissions so someone else doesn't jump into our connection.
95 chmod($sockname, 0600);
97 // We need to get a connection to the Citadel server going now.
99 $ctdlsock = fsockopen(CITADEL_HOSTNAME, CITADEL_TCP_PORTNO, $errno, $errstr, 30);
100 if (!$ctdlsock) {
101 socket_close ($sock);
102 system("/bin/rm -f " . $sockname);
103 exit(5);
106 // Read the greeting from the Citadel server.
107 if (!$buf = fgets($ctdlsock, 4096)) {
108 socket_close ($sock);
109 system("/bin/rm -f " . $sockname);
110 exit(6);
113 // Make sure the server is allowing logins.
114 if (substr($buf, 0, 1) != "2") {
115 socket_close ($sock);
116 system("/bin/rm -f " . $sockname);
117 exit(7);
120 do {
121 // Wait for connections, but time out after 15 minutes.
122 // socket_select() is completely b0rken in PHP 4.1, which is why
123 // this program requires PHP 4.3 or newer.
125 if (socket_select($readsock = array($sock),
126 $writesock = NULL,
127 $exceptsock = NULL,
128 900, 0
129 ) == 0) {
130 // Timing out.
131 socket_close ($sock);
132 system("/bin/rm -f " . $sockname);
133 exit(8);
136 // Ok, there's a valid connection coming in. Accept it.
137 $msgsock = socket_accept($sock);
138 if ($msgsock >= 0) do {
139 $buf = sock_gets($msgsock);
140 if ($buf !== false) {
141 // fwrite($logfd, ">>");
142 // fwride($logfd, $buf);
143 if (!fwrite($ctdlsock, $buf . "\n")) {
144 fclose($ctdlsock);
145 socket_close($sock);
146 system("/bin/rm -f " . $sockname);
147 exit(9);
149 $talkback = fgets($ctdlsock, 4096);
150 if (CITADEL_DEBUG_PROXY)
152 syslog(LOG_DEBUG, "talkback: ".$talkback);
154 if (!$talkback) {
155 if (CITADEL_DEBUG_PROXY)
157 syslog(LOG_ERROR, "closing socket.");
159 fclose($ctdlsock);
160 socket_close($sock);
161 system("/bin/rm -f " . $sockname);
162 exit(10);
164 socket_write($msgsock, $talkback, strlen($talkback));
166 // BINARY_FOLLOWS mode
167 if (substr($talkback, 0, 1) == "6") {
168 $bytes = intval(substr($talkback, 4));
169 if (CITADEL_DEBUG_PROXY)
171 syslog(LOG_DEBUG, "reading ".$bytes." bytes from server");
173 $buf = fread($ctdlsock, $bytes);
174 if (CITADEL_DEBUG_PROXY)
176 syslog(LOG_DEBUG, "Read: ".$buf);
178 socket_write($msgsock, $buf, $bytes);
181 // LISTING_FOLLOWS mode
182 if (substr($talkback, 0, 1) == "1") do {
183 $buf = fgets($ctdlsock, 4096);
184 if (!$buf) {
185 $buf = "000\n" ;
187 else {
188 socket_write($msgsock, $buf,
189 strlen($buf));
191 } while ($buf != "000\n");
193 // SEND_LISTING mode
194 if (substr($talkback, 0, 1) == "4") do {
195 socket_clear_error($msgsock);
196 $buf = sock_gets($msgsock);
197 if (socket_last_error($msgsock)) {
198 $buf = "000" ;
200 if (!fwrite($ctdlsock, $buf . "\n")) {
201 fclose($ctdlsock);
202 socket_close($sock);
203 system("/bin/rm -f " . $sockname);
204 exit(11);
206 } while ($buf != "000");
209 } while($buf !== false);
211 socket_close ($msgsock);
213 } while (true);
215 socket_close($sock);
216 fclose($ctdlsock);
217 system("/bin/rm -f " . $sockname);
218 exit(0);