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