Initial revision
authorArt Cancro <ajc@citadel.org>
Fri, 31 Oct 2003 03:45:35 +0000 (03:45 +0000)
committerArt Cancro <ajc@citadel.org>
Fri, 31 Oct 2003 03:45:35 +0000 (03:45 +0000)
ctdlphp/ctdlheader.php [new file with mode: 0644]
ctdlphp/ctdlprotocol.php [new file with mode: 0644]
ctdlphp/ctdlsession.php [new file with mode: 0644]
ctdlphp/index.php [new file with mode: 0644]
ctdlphp/logout.php [new file with mode: 0644]
ctdlphp/page2.php [new file with mode: 0644]
ctdlphp/page3.php [new file with mode: 0644]
ctdlphp/sessionproxy.c [new file with mode: 0644]
ctdlphp/sessionproxy.php [new file with mode: 0755]

diff --git a/ctdlphp/ctdlheader.php b/ctdlphp/ctdlheader.php
new file mode 100644 (file)
index 0000000..590fc69
--- /dev/null
@@ -0,0 +1,60 @@
+<?PHP
+
+include "ctdlsession.php";
+include "ctdlprotocol.php";
+
+function bbs_page_header() {
+
+       global $session;
+
+       establish_citadel_session();
+
+       echo <<<CITADEL_HEADER_DATA
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+       <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+       <meta name="Description" content="Citadel BBS">
+       <meta name="Keywords" content="citadel,bbs">
+       <meta name="MSSmartTagsPreventParsing" content="TRUE">
+       <title>FIXME NAME BBS</title>
+</head>
+
+<body
+       text="#000000"
+       bgcolor="#FFFFFF"
+       link="#0000FF"
+       vlink="#990066"
+       alink="#DD0000"
+>
+
+Citadel test PHP thing.<BR>
+CITADEL_HEADER_DATA;
+
+echo "Your session ID is ", $session, "<BR>\n";
+echo "Dude, we're in ", `pwd`, "<BR>";
+echo "<A HREF=\"logout.php\">Log out</A><HR>";
+flush();
+
+test_for_echo();
+
+}
+
+
+function bbs_page_footer() {
+       global $clientsocket;
+
+       echo "<HR>";
+
+       if (!fclose($clientsocket)) {
+               echo "Error closing client socket.<BR>\n";
+       }
+
+       echo "Copyright &copy; 2003 by The SCO Group.<BR>\n";
+       echo "</BODY></HTML>\n";
+
+
+}
+
+?>
diff --git a/ctdlphp/ctdlprotocol.php b/ctdlphp/ctdlprotocol.php
new file mode 100644 (file)
index 0000000..50a3e01
--- /dev/null
@@ -0,0 +1,21 @@
+<?PHP
+
+function test_for_echo() {
+
+       global $clientsocket, $session;
+
+       $command = "ECHO Video vertigo ... test for echo.\n";
+
+       echo "Trying echo ... session name is ", $session, "<BR>\n";
+       flush();
+       echo "Writing...<BR>\n";
+       flush();
+       fwrite($clientsocket, $command, strlen($command));
+       echo "Reading...<BR>\n";
+       flush();
+       $response = fgets($clientsocket, 4096);
+       echo $response, "<BR>";
+       flush();
+}
+
+?>
diff --git a/ctdlphp/ctdlsession.php b/ctdlphp/ctdlsession.php
new file mode 100644 (file)
index 0000000..605529b
--- /dev/null
@@ -0,0 +1,85 @@
+<?PHP
+
+//
+// ctdlsession.php
+//
+// This gets called from within the header functions.  It establishes or
+// connects to a PHP session, and then connects to Citadel if necessary.
+//
+
+function establish_citadel_session() {
+
+       global $session, $clientsocket;
+
+       // echo "Calling session_start()<BR>\n";
+       // flush();
+       session_start();
+       $session = "CtdlSession." . session_id();
+
+       // See if there's a Citadel connection proxy open for this session.
+       // The name of the socket is identical to the name of the
+       // session, and it's found in the /tmp directory.
+
+       $sockname = "/tmp/" . $session . ".socket" ;
+
+       // echo "Connecting to ", $sockname, "...<BR>\n";
+       // flush();
+       $clientsocket = fsockopen($sockname, 0, $errno, $errstr, 5);
+       if (!$clientsocket) {
+               //echo "Socket not present.  Firing up a new proxy.<BR>\n";
+               //flush();
+
+               // It ain't there, dude.  Open up the proxy. (C version)
+               //$cmd = "./sessionproxy " . $sockname ;
+               //exec($cmd);
+
+               // It ain't there, dude.  Open up the proxy.  (PHP version)
+               $cmd = "./sessionproxy.php " . $sockname .
+                       " </dev/null >/dev/null 2>&1 " .
+                       " 3>&1 4>&1 5>&1 6>&1 7>&1 8>&1 & " ;
+               exec($cmd);
+               sleep(2);
+
+               // Ok, now try again.
+               // echo "Connecting to ", $sockname, "...<BR>\n";
+               // flush();
+               $clientsocket = fsockopen($sockname, 0, $errno, $errstr, 5);
+       }
+
+       if ($clientsocket) {
+               /*
+               echo "Connected.  Performing echo tests.<BR>\n";
+               flush();
+               $cmd = "ECHO test echo string upon connection\n";
+               fwrite($clientsocket, $cmd, strlen($cmd));
+               $response = fgets($clientsocket, 4096);
+               echo "Response is: ", $response, "<BR>\n";
+               flush();
+
+               $cmd = "ECHO second test for echo\n";
+               fwrite($clientsocket, $cmd, strlen($cmd));
+               $response = fgets($clientsocket, 4096);
+               echo "Response is: ", $response, "<BR>\n";
+               flush();
+               */
+       }
+       else {
+               echo "ERROR: no Citadel socket!<BR>\n";
+               flush();
+       }
+       
+}
+
+
+function ctdl_end_session() {
+       global $clientsocket, $session;
+
+       session_destroy();
+       unset($clientsocket);
+       unset($session); 
+
+       echo "Session destroyed.<BR>\n";
+       
+}
+
+?>
diff --git a/ctdlphp/index.php b/ctdlphp/index.php
new file mode 100644 (file)
index 0000000..9127a44
--- /dev/null
@@ -0,0 +1,26 @@
+<?PHP
+       include "ctdlheader.php";
+
+       bbs_page_header();
+?>
+
+
+<h1>Page One</h1>
+
+<P>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis consectetuer
+varius ipsum. Cras neque tortor, congue in, faucibus id, ornare vitae, est.
+Vivamus erat. Cras vel erat vitae pede convallis porttitor. Vestibulum
+dictum, arcu in tempus vulputate, leo lorem commodo purus, ut fringilla
+augue urna eget mi. Donec laoreet condimentum est. Vestibulum bibendum.
+Curabitur faucibus, risus vitae porta commodo, felis eros fringilla nibh,
+quis varius lectus ante ac pede. Maecenas eu leo. Phasellus orci. Suspendisse
+elementum ultricies quam. Nulla facilisi. Fusce vel purus at nunc ultrices
+tempor. Nullam laoreet massa ut wisi.</p>
+
+<a href="page2.php">Page Two</a><BR>
+<a href="page3.php">Page Three</a><BR>
+
+<?PHP
+       bbs_page_footer();
+?>
+
diff --git a/ctdlphp/logout.php b/ctdlphp/logout.php
new file mode 100644 (file)
index 0000000..14a2c68
--- /dev/null
@@ -0,0 +1,20 @@
+<?PHP
+       include "ctdlheader.php";
+
+       bbs_page_header();
+
+       echo <<<LITERAL
+
+<h1>Goodbye</h1>
+
+You are being logged out.
+
+<a href="index.php">Log in again</a><BR>
+
+LITERAL;
+
+       ctdl_end_session();
+       bbs_page_footer();
+
+?>
+
diff --git a/ctdlphp/page2.php b/ctdlphp/page2.php
new file mode 100644 (file)
index 0000000..411acb1
--- /dev/null
@@ -0,0 +1,36 @@
+<?PHP
+       include "ctdlheader.php";
+
+       bbs_page_header();
+
+       echo "Hi there.  The date is ", `date`, "<BR>";
+
+       echo <<<LITERAL
+
+<h1>Page Two</h1>
+
+<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus nisl
+tortor, ultrices nec, laoreet ac, porta eu, felis. Aenean elit sapien,
+ornare vitae, condimentum ut, feugiat vitae, metus. Curabitur id leo.
+Vivamus semper suscipit justo. Pellentesque interdum rutrum lacus. Fusce
+egestas, tellus ut suscipit semper, dolor metus vestibulum orci, id hendrerit
+diam dolor vel diam. Quisque at mauris. Fusce sollicitudin. Integer ante
+quam, malesuada at, ullamcorper nec, dictum id, nulla. Donec nec arcu sit
+amet justo molestie fermentum. Cras tortor. Fusce est tortor, euismod non,
+rutrum ut, lobortis suscipit, orci. Maecenas venenatis, purus ac volutpat
+euismod, ligula nulla ullamcorper mi, eu fringilla justo wisi quis dolor.
+Morbi vitae enim. Pellentesque tempor, nisl quis euismod tincidunt, tellus
+odio tempor lacus, sit amet viverra enim ante nec nunc. Aliquam vestibulum
+feugiat urna. Cras lectus libero, vestibulum non, pellentesque id, cursus
+sit amet, turpis. Aliquam ipsum magna, vulputate sit amet, iaculis eget,
+molestie rutrum, felis. Curabitur ante metus, rutrum in, vestibulum nec,
+faucibus sit amet, magna. In pretium lacus eget mi.</p>
+
+<a href="index.php">Page One</a><BR>
+<a href="page3.php">Page Three</a><BR>
+
+LITERAL;
+
+       bbs_page_footer();
+?>
+
diff --git a/ctdlphp/page3.php b/ctdlphp/page3.php
new file mode 100644 (file)
index 0000000..3c1bfed
--- /dev/null
@@ -0,0 +1,19 @@
+<?PHP
+       include "ctdlheader.php";
+
+       bbs_page_header();
+
+       echo <<<LITERAL
+
+<h1>Page Three</h1>
+
+<P>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In vel arcu sit amet orci suscipit pellentesque. Cras consequat erat vel libero. Integer dignissim, ipsum at sagittis feugiat, massa nibh placerat erat, in pretium pede purus at est. Nullam suscipit iaculis magna. Sed eleifend wisi ut ipsum. Morbi sed libero quis nunc sagittis venenatis. Sed volutpat neque eu augue. Duis tortor felis, dignissim eget, mattis eget, tempus vel, ipsum. Nam est. Etiam leo. Fusce urna diam, commodo eget, eleifend sit amet, fermentum at, turpis. Nunc luctus. Pellentesque auctor, felis vel venenatis fermentum, tellus nunc faucibus odio, vel mattis dolor nulla vitae purus. Vivamus sagittis mi sit amet nibh.</p>
+
+<a href="index.php">Page One</a><BR>
+<a href="page2.php">Page Two</a><BR>
+
+LITERAL;
+
+       bbs_page_footer();
+?>
+
diff --git a/ctdlphp/sessionproxy.c b/ctdlphp/sessionproxy.c
new file mode 100644 (file)
index 0000000..2dd4af9
--- /dev/null
@@ -0,0 +1,370 @@
+/*
+ * $Id$
+ *
+ * Session proxy for Citadel PHP bindings
+ *
+ * This is an unfinished session proxy ... it is a C version of the
+ * session proxy implemented in sessionproxy.php ... that version is pure PHP
+ * so we should probably stick with it as long as it works.
+ *
+ * Copyright (c) 2003 by Art Cancro <ajc@uncensored.citadel.org>
+ * This program is released under the terms of the GNU General Public License.
+ */
+
+#define SIZ 4096
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/un.h>
+#include <netdb.h>
+#include <string.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
+
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+
+void timeout(int signum)
+{
+       fprintf(stderr, "Connection timed out.\n");
+       exit(3);
+}
+
+
+/*
+ * Connect a unix domain socket
+ */
+int uds_connectsock(char *sockpath)
+{
+       struct sockaddr_un addr;
+       int s;
+
+       memset(&addr, 0, sizeof(addr));
+       addr.sun_family = AF_UNIX;
+       strncpy(addr.sun_path, sockpath, sizeof addr.sun_path);
+
+       s = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (s < 0) {
+               fprintf(stderr, "Can't create socket: %s\n",
+                       strerror(errno));
+               return(-1);
+       }
+
+       if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+               fprintf(stderr, "Can't connect: %s\n",
+                       strerror(errno));
+               close(s);
+               return(-1);
+       }
+
+       return s;
+}
+
+
+/*
+ * Connect a TCP/IP socket
+ */
+int tcp_connectsock(char *host, char *service)
+{
+       struct hostent *phe;
+       struct servent *pse;
+       struct protoent *ppe;
+       struct sockaddr_in sin;
+       int s;
+
+       memset(&sin, 0, sizeof(sin));
+       sin.sin_family = AF_INET;
+
+       pse = getservbyname(service, "tcp");
+       if (pse) {
+               sin.sin_port = pse->s_port;
+       } else if ((sin.sin_port = htons((u_short) atoi(service))) == 0) {
+               fprintf(stderr, "Can't get %s service entry\n", service);
+               return (-1);
+       }
+       phe = gethostbyname(host);
+       if (phe) {
+               memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
+       } else if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
+               fprintf(stderr, "Can't get %s host entry: %s\n",
+                       host, strerror(errno));
+               return (-1);
+       }
+       if ((ppe = getprotobyname("tcp")) == 0) {
+               fprintf(stderr, "Can't get TCP protocol entry: %s\n",
+                       strerror(errno));
+               return (-1);
+       }
+
+       s = socket(PF_INET, SOCK_STREAM, ppe->p_proto);
+       if (s < 0) {
+               fprintf(stderr, "Can't create socket: %s\n", strerror(errno));
+               return (-1);
+       }
+       signal(SIGALRM, timeout);
+       alarm(30);
+
+       if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+               fprintf(stderr, "Can't connect to %s.%s: %s\n",
+                       host, service, strerror(errno));
+               close(s);
+               return (-1);
+       }
+       alarm(0);
+       signal(SIGALRM, SIG_IGN);
+
+       return (s);
+}
+
+
+
+
+/*
+ * Input binary data from socket
+ */
+int sock_read(int sock, char *buf, int bytes)
+{
+       int len, rlen;
+
+       len = 0;
+       while (len < bytes) {
+               rlen = read(sock, &buf[len], bytes - len);
+               if (rlen < 1) {
+                       fprintf(stderr, "Server connection broken: %s\n",
+                               strerror(errno));
+                       return(-1);
+               }
+               len = len + rlen;
+       }
+       return(len);
+}
+
+
+/*
+ * input string from pipe
+ */
+int sock_gets(int sock, char *strbuf)
+{
+       int ch, len;
+       char buf[2];
+
+       len = 0;
+       strcpy(strbuf, "");
+       do {
+               if (sock_read(sock, &buf[0], 1) < 0) return(-1);
+               ch = buf[0];
+               strbuf[len++] = ch;
+       } while ((ch != 10) && (ch != 0) && (len < (SIZ-1)));
+       if (strbuf[len-1] == 10) strbuf[--len] = 0;
+       if (strbuf[len-1] == 13) strbuf[--len] = 0;
+       return(len);
+}
+
+
+
+/*
+ * send binary to server
+ */
+int sock_write(int sock, char *buf, int nbytes)
+{
+       int bytes_written = 0;
+       int retval;
+       while (bytes_written < nbytes) {
+               retval = write(sock, &buf[bytes_written],
+                              nbytes - bytes_written);
+               if (retval < 1) {
+                       fprintf(stderr, "Server connection broken: %s\n",
+                               strerror(errno));
+                       return(-1);
+               }
+               bytes_written = bytes_written + retval;
+       }
+       return(bytes_written);
+}
+
+
+/*
+ * send line to server
+ */
+int sock_puts(int sock, char *string)
+{
+       char buf[SIZ];
+
+       sprintf(buf, "%s\n", string);
+       return sock_write(sock, buf, strlen(buf));
+}
+
+
+/*
+ * Create a Unix domain socket and listen on it
+ */
+int ig_uds_server(char *sockpath, int queue_len)
+{
+       struct sockaddr_un addr;
+       int s;
+       int i;
+       int actual_queue_len;
+
+       actual_queue_len = queue_len;
+       if (actual_queue_len < 5) actual_queue_len = 5;
+
+       i = unlink(sockpath);
+       if (i != 0) if (errno != ENOENT) {
+               fprintf(stderr, "can't unlink %s: %s\n",
+                       sockpath, strerror(errno));
+               return(-1);
+       }
+
+       memset(&addr, 0, sizeof(addr));
+       addr.sun_family = AF_UNIX;
+       strncpy(addr.sun_path, sockpath, sizeof addr.sun_path);
+
+       s = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (s < 0) {
+               fprintf(stderr, "Can't create a socket: %s\n",
+                       strerror(errno));
+               return(-1);
+       }
+
+       if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+               fprintf(stderr, "Can't bind: %s\n",
+                       strerror(errno));
+               return(-1);
+       }
+
+       if (listen(s, actual_queue_len) < 0) {
+               fprintf(stderr, "Can't listen: %s\n", strerror(errno));
+               return(-1);
+       }
+
+       chmod(sockpath, 0700);  /* only me me me can talk to this */
+       return(s);
+}
+
+
+
+/*
+ * main loop
+ */
+int main(int argc, char **argv) {
+
+       char buf[SIZ];
+       char dbuf[SIZ];
+       int i, f;
+       int ctdl_sock;
+       int listen_sock;
+       int cmd_sock;
+
+       /* Fail if we weren't supplied with the right number of arguments
+        */
+       if (argc != 2) {
+               exit(1);
+       }
+
+       /* Fail if we can't connect to Citadel
+        */
+       ctdl_sock = uds_connectsock("/appl/citadel/citadel.socket");
+       if (ctdl_sock < 0) {
+               exit(2);
+       }
+
+       /* Fail if we can't read the server greeting message
+        */
+       if (sock_gets(ctdl_sock, buf) < 0) {
+               exit(3);
+       }
+
+       /* Fail if the server isn't giving us an error-free startup
+        */
+       if (buf[0] != '2') {
+               exit(4);
+       }
+
+       /* Now we're solid with the Citadel server.  Nice.  It's time to
+        * open our proxy socket so PHP can talk to us.  Fail if we can't
+        * set this up.
+        */
+       listen_sock = ig_uds_server(argv[1], 5);
+       if (listen_sock < 0) {
+               close(ctdl_sock);
+               exit(5);
+       }
+
+       /* The socket is ready to listen for connections, so it's time for
+        * this program to go into the background.  Fork, then close all file
+        * descriptors so that the PHP script that called us can continue
+        * its processing.
+        */
+       f = fork();
+       if (f < 0) {
+               close(ctdl_sock);
+               close(listen_sock);
+               unlink(argv[1]);
+               exit(6);
+       }
+       if (f != 0) {
+               exit(0);
+       }
+       if (f == 0) {
+               setpgrp();
+               for (i=0; i<256; ++i) {
+                       /* Close fd's so PHP doesn't get all, like, whatever */
+                       if ( (i != ctdl_sock) && (i != listen_sock) ) {
+                               close(i);
+                       }
+               }
+       }
+
+       /* Listen for connections. */
+
+       signal(SIGPIPE, SIG_IGN);
+       while (cmd_sock = accept(listen_sock, NULL, 0), cmd_sock >= 0) {
+
+               while (sock_gets(cmd_sock, buf) >= 0) {
+                       if (sock_puts(ctdl_sock, buf) < 0) goto CTDL_BAIL;
+                       if (sock_gets(ctdl_sock, buf) < 0) goto CTDL_BAIL;
+                       sock_puts(cmd_sock, buf);
+
+                       if (buf[0] == '1') do {
+                               if (sock_gets(ctdl_sock, dbuf) < 0) {
+                                       goto CTDL_BAIL;
+                               }
+                               sock_puts(cmd_sock, dbuf);
+                       } while (strcmp(dbuf, "000"));
+
+                       else if (buf[0] == '4') do {
+                               sock_gets(cmd_sock, dbuf);
+                               if (sock_puts(ctdl_sock, dbuf) < 0) {
+                                       goto CTDL_BAIL;
+                               }
+                       } while (strcmp(dbuf, "000"));
+
+               }
+               close(cmd_sock);
+       }
+
+CTDL_BAIL:
+       /* Clean up and go away.
+        */
+       close(ctdl_sock);
+       close(listen_sock);
+       unlink(argv[1]);
+       exit(0);
+}
diff --git a/ctdlphp/sessionproxy.php b/ctdlphp/sessionproxy.php
new file mode 100755 (executable)
index 0000000..5c5ee40
--- /dev/null
@@ -0,0 +1,120 @@
+#!/usr/bin/php -q
+
+<?php
+
+// $Id$
+//
+// This is the session proxy that binds a unix domain socket to a Citadel
+// server connection.  We need one of these for each session because PHP does
+// not have a way to bind a session to a persistent socket.
+//
+// Copyright (c) 2003 by Art Cancro <ajc@uncensored.citadel.org>
+// This program is released under the terms of the GNU General Public License.
+//
+
+
+// sock_gets() -- reads one line of text from a socket
+// 
+function sock_gets($sock) {
+       $buf = socket_read($sock, 4096, PHP_NORMAL_READ);
+       if ($buf == false) return false;
+
+       if (preg_match("'\n$'s", $buf)) {
+               $buf = substr($buf, 0, strpos($buf, "\n"));
+       }
+
+       return $buf;
+}
+
+
+
+
+
+// *** Start of main program ***
+
+error_reporting(E_ALL);
+
+/* Allow the script to hang around waiting for connections. */
+set_time_limit(0);
+
+/* Turn on implicit output flushing so we see what we're getting
+ * as it comes in.
+ */
+ob_implicit_flush();
+
+if ($argc != 2) {
+       echo "usage: ", $argv[0], " sockname\n";
+       exit(1);
+}
+
+$sockname = $argv[1];
+
+if ($sockname == "/tmp/") {
+       echo "Invalid socket name.\n";
+       exit(1);
+}
+
+// If there's a dead socket already there, remove it.
+system("/bin/rm -f " . $sockname);
+
+$sock = socket_create(AF_UNIX, SOCK_STREAM, 0);
+if ($sock < 0) {
+       echo "socket_create() failed: ", socket_strerror($sock), "\n";
+       exit(2);
+}
+
+$ret = socket_bind($sock, $sockname);
+if ($ret < 0) {
+       echo "socket_bind() failed: ", socket_strerror($ret), "\n";
+       exit(3);
+}
+
+$ret = socket_listen($sock, 5);
+if ($ret < 0) {
+       echo "socket_listen() failed: ", socket_strerror($ret), "\n";
+       exit(4);
+}
+
+// We need to get a connection to the Citadel server going now.
+
+$ctdlsock = fsockopen("uncensored.citadel.org", 504, $errno, $errstr, 30);
+// $ctdlsock = fsockopen("/appl/citadel/citadel.socket", 0, $errno, $errstr, 30);
+if (!$ctdlsock) {
+       socket_close ($sock);
+       system("/bin/rm -f " . $sockname);
+       exit(5);
+}
+
+echo "Connected to Citadel server.\n";
+$buf = fgets($ctdlsock, 4096);
+echo $buf, "\n";
+
+do {
+       $msgsock = socket_accept($sock);
+       if ($msgsock < 0) {
+               echo "socket_accept() failed: ",
+                       socket_strerror($msgsock), "\n";
+               break;
+       }
+
+       do {
+               echo "Reading a line...\n";
+               $buf = sock_gets($msgsock);
+               if ($buf !== false) {
+                       fwrite($ctdlsock, $buf . "\n", (strlen($buf)+1) );
+                       $talkback = fgets($ctdlsock, 4096);
+                       socket_write($msgsock, $talkback, strlen($talkback));
+               }
+       } while($buf !== false);
+
+       echo "Closing socket.\n";
+
+       socket_close ($msgsock);
+
+} while (true);
+
+socket_close ($sock);
+system("/bin/rm -f " . $sockname);
+exit(0);
+
+?>