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