0ace0b57e037e02f074f9d4ee2475962e135e847
[citadel.git] / ctdlphp / sessionproxy.php
1 #!/usr/bin/php -q
2
3 <?php
4
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.
10 //
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.
13 //
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.
16
17
18 // sock_gets() -- reads one line of text from a socket
19 // 
20 function sock_gets($sock) {
21         $buf = socket_read($sock, 4096, PHP_NORMAL_READ);
22         if ($buf == false) return false;
23
24         if (preg_match("'\n$'s", $buf)) {
25                 $buf = substr($buf, 0, strpos($buf, "\n"));
26         }
27
28         return $buf;
29 }
30
31
32
33
34
35 // *** Start of main program ***
36
37 error_reporting(E_ALL);
38
39 /* Allow the script to hang around waiting for connections. */
40 set_time_limit(0);
41
42 /* Turn on implicit output flushing so we see what we're getting
43  * as it comes in.
44  */
45 ob_implicit_flush();
46
47 if ($argc != 2) {
48         echo "usage: ", $argv[0], " sockname\n";
49         exit(1);
50 }
51
52 $sockname = $argv[1];
53
54 if ($sockname == "/tmp/") {
55         echo "Invalid socket name.\n";
56         exit(1);
57 }
58
59 // If there's a dead socket already there, remove it.
60 system("/bin/rm -f " . $sockname);
61
62 $sock = socket_create(AF_UNIX, SOCK_STREAM, 0);
63 if (!$sock) {
64         echo "socket_create() failed: ", socket_strerror($sock), "\n";
65         system("/bin/rm -f " . $sockname);
66         exit(2);
67 }
68
69 $ret = socket_bind($sock, $sockname);
70 if (!$ret) {
71         echo "socket_bind() failed: ", socket_strerror($ret), "\n";
72         system("/bin/rm -f " . $sockname);
73         exit(3);
74 }
75
76 $ret = socket_listen($sock, 5);
77 if (!$ret) {
78         echo "socket_listen() failed: ", socket_strerror($ret), "\n";
79         system("/bin/rm -f " . $sockname);
80         exit(4);
81 }
82
83 // Set the permissions so someone else doesn't jump into our connection.
84 chmod($sockname, 0600);
85
86 // We need to get a connection to the Citadel server going now.
87
88 $ctdlsock = fsockopen("uncensored.citadel.org", 504, $errno, $errstr, 30);
89 //$ctdlsock = fsockopen("/appl/citadel/citadel.socket", 0, $errno, $errstr, 30);
90 if (!$ctdlsock) {
91         socket_close ($sock);
92         system("/bin/rm -f " . $sockname);
93         exit(5);
94 }
95
96 // Read the greeting from the Citadel server.
97 if (!$buf = fgets($ctdlsock, 4096)) {
98         socket_close ($sock);
99         system("/bin/rm -f " . $sockname);
100         exit(6);
101 }
102
103 // Make sure the server is allowing logins.
104 if (substr($buf, 0, 1) != "2") {
105         socket_close ($sock);
106         system("/bin/rm -f " . $sockname);
107         exit(7);
108 }
109
110 do {
111         // Wait for connections, but time out after 15 minutes.
112         // socket_select() is completely b0rken in PHP 4.1, which is why
113         // this program requires PHP 4.3 or newer.
114         //
115         if (socket_select($readsock = array($sock),
116                         $writesock = NULL,
117                         $exceptsock = NULL,
118                         900, 0
119         ) == 0) {
120                 // Timing out.
121                 socket_close ($sock);
122                 system("/bin/rm -f " . $sockname);
123                 exit(8);
124         }
125
126         // Ok, there's a valid connection coming in.  Accept it.
127         $msgsock = socket_accept($sock);
128         if ($msgsock >= 0) do {
129                 $buf = sock_gets($msgsock);
130                 if ($buf !== false) {
131                         if (!fwrite($ctdlsock, $buf . "\n")) {
132                                 fclose($ctdlsock);
133                                 socket_close($sock);
134                                 system("/bin/rm -f " . $sockname);
135                                 exit(9);
136                         }
137                         $talkback = fgets($ctdlsock, 4096);
138                         if (!$talkback) {
139                                 fclose($ctdlsock);
140                                 socket_close($sock);
141                                 system("/bin/rm -f " . $sockname);
142                                 exit(10);
143                         }
144                         socket_write($msgsock, $talkback, strlen($talkback));
145
146                         // LISTING_FOLLOWS mode
147                         if (substr($talkback, 0, 1) == "1") do {
148                                 $buf = fgets($ctdlsock, 4096);
149                                 if (!$buf) {
150                                         $buf = "000\n" ;
151                                 }
152                                 else {
153                                         socket_write($msgsock, $buf,
154                                                 strlen($buf));
155                                 }
156                         } while ($buf != "000\n");
157
158                         // SEND_LISTING mode
159                         if (substr($talkback, 0, 1) == "4") do {
160                                 $buf = sock_gets($msgsock);
161                                 if (!$buf) {
162                                         $buf = "000" ;
163                                 }
164                                 if (!fwrite($ctdlsock, $buf . "\n")) {
165                                         fclose($ctdlsock);
166                                         socket_close($sock);
167                                         system("/bin/rm -f " . $sockname);
168                                         exit(11);
169                                 }
170                         } while ($buf != "000");
171
172                 }
173         } while($buf !== false);
174
175         socket_close ($msgsock);
176
177 } while (true);
178
179 socket_close($sock);
180 fclose($ctdlsock);
181 system("/bin/rm -f " . $sockname);
182 exit(0);
183
184 ?>