- INT sock; /* Socket Handle */
- struct sockaddr_in addr; /* Adresse des Client */
- RES_STAT *res_stat; /* "Resolver-Status", s.o. */
- CHAR host[HOST_LEN]; /* Hostname */
- CHAR rbuf[READBUFFER_LEN]; /* Lesepuffer */
- INT rdatalen; /* Laenge der Daten im Lesepuffer */
- CHAR wbuf[WRITEBUFFER_LEN]; /* Schreibpuffer */
- INT wdatalen; /* Laenge der Daten im Schreibpuffer */
- INT our_server; /* wenn von uns zu connectender Server: ID */
- time_t lastdata; /* Letzte Aktivitaet */
- time_t lastping; /* Letzter PING */
- time_t lastprivmsg; /* Letzte PRIVMSG */
- time_t delaytime; /* Nicht beachten bis ("penalty") */
- LONG bytes_in, bytes_out; /* Counter fuer Statistik */
- INT flag; /* Channel-Flag (vgl. "irc-write"-Modul) */
-} CONNECTION;
-
-
-LOCAL VOID Handle_Read PARAMS(( INT sock ));
-LOCAL BOOLEAN Handle_Write PARAMS(( CONN_ID Idx ));
-LOCAL VOID New_Connection PARAMS(( INT Sock ));
-LOCAL CONN_ID Socket2Index PARAMS(( INT Sock ));
-LOCAL VOID Read_Request PARAMS(( CONN_ID Idx ));
-LOCAL BOOLEAN Try_Write PARAMS(( CONN_ID Idx ));
-LOCAL VOID Handle_Buffer PARAMS(( CONN_ID Idx ));
-LOCAL VOID Check_Connections PARAMS(( VOID ));
-LOCAL VOID Check_Servers PARAMS(( VOID ));
-LOCAL VOID Init_Conn_Struct PARAMS(( LONG Idx ));
-LOCAL BOOLEAN Init_Socket PARAMS(( INT Sock ));
-LOCAL VOID New_Server PARAMS(( INT Server, CONN_ID Idx ));
-LOCAL VOID Read_Resolver_Result PARAMS(( INT r_fd ));
-
-
-LOCAL fd_set My_Listeners;
-LOCAL fd_set My_Sockets;
-LOCAL fd_set My_Connects;
-
-LOCAL CONNECTION *My_Connections;
-LOCAL LONG Pool_Size;
-
-
-GLOBAL VOID
-Conn_Init( VOID )
+ (void) irrelevant;
+ New_Connection( sock );
+}
+
+
+static void
+cb_connserver(int sock, short what)
+{
+ int res, err;
+ socklen_t sock_len;
+ CLIENT *c;
+ CONN_ID idx = Socket2Index( sock );
+ if (idx <= NONE) {
+#ifdef DEBUG
+ Log(LOG_DEBUG, "cb_connserver wants to write on unknown socket?!");
+#endif
+ io_close(sock);
+ return;
+ }
+
+ assert( what & IO_WANTWRITE);
+
+ /* connect() finished, get result. */
+ sock_len = sizeof( err );
+ res = getsockopt( My_Connections[idx].sock, SOL_SOCKET, SO_ERROR, &err, &sock_len );
+ assert( sock_len == sizeof( err ));
+
+ /* Fehler aufgetreten? */
+ if(( res != 0 ) || ( err != 0 )) {
+ if ( res != 0 )
+ Log( LOG_CRIT, "getsockopt (connection %d): %s!", idx, strerror( errno ));
+ else
+ Log( LOG_CRIT, "Can't connect socket to \"%s:%d\" (connection %d): %s!",
+ My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port,
+ idx, strerror( err ));
+
+ /* Clean up socket, connection and client structures */
+ c = Client_GetFromConn( idx );
+ if( c ) Client_DestroyNow( c );
+ io_close( My_Connections[idx].sock );
+ Init_Conn_Struct( idx );
+
+ /* Bei Server-Verbindungen lasttry-Zeitpunkt auf "jetzt" setzen */
+ Conf_Server[Conf_GetServer( idx )].lasttry = time( NULL );
+ Conf_UnsetServer( idx );
+ return;
+ }
+
+ Conn_OPTION_DEL( &My_Connections[idx], CONN_ISCONNECTING );
+
+ Log( LOG_INFO, "Connection %d with \"%s:%d\" established. Now logging in ...", idx,
+ My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port );
+
+ io_event_setcb( My_Connections[idx].sock, cb_clientserver);
+ io_event_add( My_Connections[idx].sock, IO_WANTREAD|IO_WANTWRITE);
+
+ /* Send PASS and SERVER command to peer */
+ Conn_WriteStr( idx, "PASS %s %s", Conf_Server[Conf_GetServer( idx )].pwd_out, NGIRCd_ProtoID );
+ Conn_WriteStr( idx, "SERVER %s :%s", Conf_ServerName, Conf_ServerInfo );
+}
+
+
+static void
+cb_clientserver(int sock, short what)
+{
+ CONN_ID idx = Socket2Index( sock );
+ if (idx <= NONE) {
+#ifdef DEBUG
+ Log(LOG_WARNING, "WTF: cb_clientserver wants to write on unknown socket?!");
+#endif
+ io_close(sock);
+ return;
+ }
+
+ if (what & IO_WANTREAD)
+ Read_Request( idx );
+
+ if (what & IO_WANTWRITE)
+ Handle_Write( idx );
+}
+
+
+LOCAL void
+FreeRes_stat( CONNECTION *c )
+{
+ assert( c != NULL );
+ assert( c->res_stat != NULL );
+
+ if (!c->res_stat) return;
+
+ io_close( c->res_stat->pipe[0] );
+
+ free( c->res_stat );
+ c->res_stat = NULL;
+}
+
+
+GLOBAL void
+Conn_Init( void )