+GLOBAL BOOLEAN Conn_WriteStr( CONN_ID Idx, CHAR *Data )
+{
+ /* String in Socket schreiben. CR+LF wird von dieser Funktion
+ * automatisch angehaengt. */
+
+ CHAR buffer[MAX_CMDLEN];
+
+ if( strlen( Data ) > MAX_CMDLEN - 2 )
+ {
+ Log( LOG_ALERT, "String too long to send (connection %d)!", Idx );
+ Close_Connection( Idx, "Server error: String too long to send!" );
+ return FALSE;
+ }
+
+ sprintf( buffer, "%s\r\n", Data );
+ return Conn_Write( Idx, buffer, strlen( buffer ));
+} /* 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 );
+ Close_Connection( 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 */
+
+
+LOCAL BOOLEAN Try_Write( CONN_ID Idx )
+{
+ /* Versuchen, Daten aus dem Schreib-Puffer in den
+ * Socket zu schreiben. */
+
+ fd_set write_socket;
+
+ assert( Idx >= 0 );
+ assert( My_Connections[Idx].sock >= 0 );
+ assert( My_Connections[Idx].wdatalen > 0 );
+
+ FD_ZERO( &write_socket );
+ FD_SET( My_Connections[Idx].sock, &write_socket );
+ if( select( My_Connections[Idx].sock + 1, NULL, &write_socket, NULL, 0 ) == -1 )
+ {
+ /* Fehler! */
+ if( errno != EINTR )
+ {
+ Log( LOG_ALERT, "select(): %s", strerror( errno ));
+ Close_Connection( Idx, NULL );
+ return FALSE;
+ }
+ }
+
+ if( FD_ISSET( My_Connections[Idx].sock, &write_socket )) return Handle_Write( Idx );
+ else return TRUE;
+} /* Try_Write */
+
+
+LOCAL VOID Handle_Read( INT Sock )