#!/usr/local/bin/php $data"); } /* client has joined */ function on_join($sock) { global $cdata; $nick = $cdata[$sock]['nick']; $addr = $cdata[$sock]['addr']; send_all("*** Joins: $nick ($addr)"); } /* client has quit */ function on_quit($sock) { global $cdata; $nick = $cdata[$sock]['nick']; $addr = $cdata[$sock]['addr']; send_all_butone($sock, "*** Quits: $nick ($addr)"); } /* who command */ function do_who($sock) { global $s_clients, $cdata; foreach ($s_clients as $mysock) { $state = $cdata[$mysock]['state']; if ($state == STATE_NICKNAME) send_single($sock, sprintf('[nickname] (%s)', $cdata[$mysock]['addr'])); else send_single($sock, sprintf('[chatting] %10s (%s)', $cdata[$mysock]['nick'], $cdata[$mysock]['addr'])); } } /* assign listening socket */ if (!($s_listen = socket_create(AF_INET, SOCK_STREAM, 0))) myerror_d(); /* reuse listening socket address */ if (!socket_set_option($s_listen, SOL_SOCKET, SO_REUSEADDR, 1)) myerror_d(); /* set socket to non-blocking */ if (!socket_set_nonblock($s_listen)) myerror_d(); /* bind listening socket to specific address/port */ if (!socket_bind($s_listen, $listen_addr, $listen_port)) myerror_d(); /* listen on listening socket */ if (!socket_listen($s_listen)) myerror_d(); /* set initial vars and loop until $abort is set to true */ $s_clients = Array(); $abort = false; while (!$abort) { /* sockets we want to pay attention to */ $set = array_merge($s_listen, $s_clients); if (socket_select($set, $set_w = NULL, $set_e = NULL, 1, 0) > 0) { /* loop through sockets */ foreach ($set as $sock) { /* listening socket has a connection, deal with it */ if ($sock == $s_listen) { if (!($this = socket_accept($s_listen))) myerror(); else { /* add socket to client list and announce connection */ $s_clients[$this] = $this; socket_getpeername($this, $addr); $cdata[$this]['addr'] = $addr; $cdata[$this]['buf'] = ''; $cdata[$this]['state'] = STATE_NICKNAME; echo "[connection]: $addr\n"; send_single($this, 'Enter a nickname:'); } } else { /* client socket has incoming data */ if (($read = socket_read($sock, 1024)) === false || $read == '') { if ($read != '') myerror(); else /* no error, but connection was closed, so tell everyone */ on_quit($sock); /* remove client from arrays */ unset($s_clients[$sock]); unset($cdata[$sock]); } else { /* only want data with a newline */ if (strchr($read, "\n") === false) $cdata[$sock]['buf'] .= $read; else handle_data($sock, $read); } } } } } echo "[end]\n"; ?>