+ Log( LOG_ALERT, "String too long to send (connection %d)!", Idx );
+ Conn_Close( Idx, "Server error: String too long to send!" );
+ return FALSE;
+ }
+
+#ifdef SNIFFER
+ Log( LOG_DEBUG, " -> connection %d: '%s'.", Idx, buffer );
+#endif
+
+ strcat( buffer, "\r\n" );
+ ok = Conn_Write( Idx, buffer, strlen( buffer ));
+
+ va_end( ap );
+ return ok;
+} /* Conn_WriteStr */
+
+
+GLOBAL BOOLEAN Conn_Write( CONN_ID Idx, CHAR *Data, INT Len )
+{
+ /* Daten in Socket schreiben. Bei "fatalen" Fehlern wird
+ * der Client disconnectiert und FALSE geliefert. */
+
+ assert( Idx >= 0 );
+ assert( My_Connections[Idx].sock >= 0 );
+ assert( Data != NULL );
+ assert( Len > 0 );
+
+ /* pruefen, ob Daten im Schreibpuffer sind. Wenn ja, zunaechst
+ * pruefen, ob diese gesendet werden koennen */
+ if( My_Connections[Idx].wdatalen > 0 )
+ {
+ if( ! Try_Write( Idx )) return FALSE;
+ }
+
+ /* pruefen, ob im Schreibpuffer genuegend Platz ist */
+ if( WRITEBUFFER_LEN - My_Connections[Idx].wdatalen - Len <= 0 )
+ {
+ /* der Puffer ist dummerweise voll ... */
+ Log( LOG_NOTICE, "Write buffer overflow (connection %d)!", Idx );
+ Conn_Close( Idx, NULL );
+ return FALSE;
+ }
+
+ /* Daten in Puffer kopieren */
+ memcpy( My_Connections[Idx].wbuf + My_Connections[Idx].wdatalen, Data, Len );
+ My_Connections[Idx].wdatalen += Len;
+
+ /* pruefen, on Daten vorhanden sind und geschrieben werden koennen */
+ if( My_Connections[Idx].wdatalen > 0 )
+ {
+ if( ! Try_Write( Idx )) return FALSE;
+ }
+
+ return TRUE;
+} /* Conn_Write */
+
+
+GLOBAL VOID Conn_Close( CONN_ID Idx, CHAR *Msg )
+{
+ /* Verbindung schliessen */
+
+ assert( Idx >= 0 );
+ assert( My_Connections[Idx].sock >= 0 );
+
+ if( Msg ) Conn_WriteStr( Idx, "ERROR :%s", Msg );
+
+ if( close( My_Connections[Idx].sock ) != 0 )
+ {
+ Log( LOG_ERR, "Error closing connection %d with %s:%d - %s!", Idx, inet_ntoa( My_Connections[Idx].addr.sin_addr ), ntohs( My_Connections[Idx].addr.sin_port), strerror( errno ));