-int write_socket(struct ClientSocket *client, char* msg, int len) {
- if(!(client->flags & SOCKET_FLAG_CONNECTED)) return 0;
- printf("[send %d] %s", len, msg);
- #ifdef WIN32
- send(client->sock, msg, len, 0);
+int disconnect_socket(struct ClientSocket *client) {
+ if(client == NULL) return 0;
+ if((client->flags & SOCKET_FLAG_CONNECTED)) {
+ char quitbuf[MAXLEN];
+ int quitlen = sprintf(quitbuf, "QUIT :[NeonServ %s.%d] disconnect requested.\n", NEONSERV_VERSION, patchlevel);
+ write_socket_force(client, quitbuf, quitlen);
+ }
+ client->flags &= ~(SOCKET_FLAG_READY | SOCKET_FLAG_RECONNECT);
+ client->flags |= SOCKET_FLAG_QUITTED;
+ return 1;
+}
+
+static void destroy_socket(struct ClientSocket *client, int free_socket) {
+ SYNCHRONIZE(synchronized);
+ if((client->flags & SOCKET_FLAG_CONNECTED)) {
+ close(client->sock);
+ 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);