+ bot_disconnect(client);
+ }
+ if(client->flags & SOCKET_FLAG_HAVE_SSL)
+ ssl_disconnect(client);
+ if(client->queue)
+ queue_destroy(client);
+ if(client->whoqueue_first)
+ clear_whoqueue(client);
+ if(client->handleinfo_first)
+ clear_handleinfoqueue(client);
+ client->flags &= ~(SOCKET_FLAG_CONNECTED | SOCKET_FLAG_READY | SOCKET_FLAG_HAVE_SSL);
+ if(free_socket) {
+ struct ClientSocket *sock, *last_sock = NULL;
+ for (sock = sockets->data; sock; sock = sock->next) {
+ if(sock == client) {
+ if(last_sock)
+ last_sock->next = sock->next;
+ else
+ sockets->data = sock->next;
+ sockets->count--;
+ break;
+ } else
+ last_sock = sock;
+ }
+ free(client->host);
+ if(client->bind)
+ free(client->bind);
+ if(client->pass)
+ free(client->pass);
+ if(client->network_name)
+ free(client->network_name);
+ free(client);
+ } else if(client->flags & SOCKET_FLAG_FAST_JUMP) {
+ client->flags &= ~SOCKET_FLAG_FAST_JUMP;
+ connect_socket(client);
+ }
+ DESYNCHRONIZE(synchronized);
+}
+
+int write_socket_force(struct ClientSocket *client, char* msg, int len) {
+ SYNCHRONIZE(synchronized);
+ #ifdef HAVE_THREADS
+ putlog(LOGLEVEL_RAW, "[%d send %d] %s", getCurrentThreadID(), len, msg);
+ #else
+ putlog(LOGLEVEL_RAW, "[send %d] %s", len, msg);
+ #endif
+ int ret = 1;
+ if(!(client->flags & SOCKET_FLAG_HAVE_SSL) || ssl_write(client, msg, len) == -2) {
+ #ifdef WIN32
+ ret = send(client->sock, msg, len, 0);
+ #else
+ ret = write(client->sock, msg, len);
+ #endif
+ }
+ client->traffic_out += len;
+ DESYNCHRONIZE(synchronized);
+ return ret;
+}
+
+int write_socket(struct ClientSocket *client, char* msg, int len) {
+ if(!(client && (client->flags & SOCKET_FLAG_CONNECTED))) return 0;
+ if(client->flags & SOCKET_FLAG_USE_QUEUE)
+ return queue_add(client, msg, len);
+ else
+ return write_socket_force(client, msg, len);
+}
+
+#if HAVE_THREADS
+static void clientsocket_start_of_recv(unsigned int tid) {
+ SYNCHRONIZE(whohandler_sync);
+ struct ParseOrder *entry, *last;
+ for(last = parse_order; last; last = last->next) {
+ if(last->next == NULL)
+ break;
+ }
+ entry = malloc(sizeof(*entry));
+ entry->tid = tid;
+ entry->next = NULL;
+ if(last)
+ last->next = entry;
+ else
+ parse_order = entry;
+ DESYNCHRONIZE(whohandler_sync);
+}
+
+static void clientsocket_end_of_recv(unsigned int tid) {
+ SYNCHRONIZE(whohandler_sync);
+ struct ParseOrder *entry, *last = NULL;
+ for(entry = parse_order; entry; entry = entry->next) {
+ if(entry->tid == tid) {
+ if(last)
+ last->next = entry->next;