📄 connection.c
字号:
/*-*-linux-c-*-*//* * gnewtellium - Newtella for Unix * Copyright (C) 2001 Elias Athanasopoulos * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* These includes are needed in the specified order by the BSD family. It maybe better to add an #ifdef BSD or something here...*/#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <stdlib.h>#include <sys/ioctl.h>#include <unistd.h>#include <fcntl.h>#include <time.h>#include <errno.h>#include <string.h>#include "global.h"#include "gui.h"#include "newtella.h"#include "connection.h"#include "hosts.h"#ifdef SOLARIS#include <sys/filio.h>#endifextern struct newtella_options *gl_options;extern int gl_server;extern struct host_info *gl_my_host_info;int bytes_avail(int s){ int ret; ioctl(s, FIONREAD, &ret); return ret;}int con_recv_packet(struct newtella_connection *con, int len){ int rval = recv(con->s, con->b, len, 0); if (rval == 0 || (rval < 0 && errno != EAGAIN)) return 0; else return rval;}void con_send_packet(struct newtella_connection *con, gchar *buf, gint len, gint maydrop){ struct gpacket *packet; gint qlen; g_return_if_fail(con->s); if (con->state == GS_FAILED || con->state == GS_TIMEOUT) return; /* we don't drop our packets */ if (!maydrop) goto real_send; qlen = g_list_length(con->queue); /* drop packet if our queue is full */ if (qlen >= QUEUE_FULL && ((con->type == CT_OUTGOING) || (con->type == CT_INCOMING))) { con->total_dropped_to_send++; goto skip; } real_send: packet = newtella_malloc(sizeof(struct gpacket)); packet->_time = time((time_t) NULL); packet->len = len; packet->data = newtella_malloc(len); memcpy(packet->data, buf, len); con->queue = g_list_prepend(con->queue, packet); skip: if (!con->write_tag) con->write_tag = gdk_input_add(con->s, GDK_INPUT_WRITE | GDK_INPUT_EXCEPTION, (GdkInputFunction) newtella_write, (gpointer) con); return; }int con_send_to_all(gchar *buf, gint len, gint maydrop){ GList *iter; struct newtella_connection *con; gint fwd = 0; /* forward a packet to every alive con */ iter = g_list_first(gl_con); while (iter) { con = iter->data; if (con->state == GS_CONNECTED) { con_send_packet(con, buf, len, maydrop); fwd++; } iter = g_list_next(iter); } return fwd;}int con_send_ex_one(struct newtella_connection *excon, gchar *buf, gint len, gint maydrop){ GList *iter; struct newtella_connection *con; if (!excon) { con_send_to_all(buf, len, maydrop); return 1; } /* forward a packet to every alive except con */ iter = g_list_first(gl_con); while (iter) { con = iter->data; if (con->state == GS_CONNECTED && con->s != excon->s) con_send_packet(con, buf, len, maydrop); iter = iter->next; } return 1;}void con_zero_stats(struct newtella_connection *con){ /* sent data */ con->total_sent = 0; con->total_dropped_to_send = 0; /* received data */ con->total_handled = 0; con->total_received_dropped = 0; con->total_bad_received = 0;} void con_init_queue(struct newtella_connection *con){ /* init queue */ con->queue = NULL;}int con_add(guint32 ip, guint16 port){ /* add a new gnutella connection */ struct newtella_connection *new_con = newtella_malloc(sizeof(struct newtella_connection)); new_con->ip = ip; new_con->port = port; con_zero_stats(new_con); con_init_queue(new_con); new_con->state = GS_WAITINGCONNECT; new_con->type = CT_OUTGOING; gl_con = g_list_append(gl_con, new_con); gui_add_con_to_list(new_con); new_con->s = newtella_force_connect(ip, port); new_con->read_tag = gdk_input_add(new_con->s, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, (GdkInputFunction) newtella_read, (gpointer)new_con); new_con->write_tag = gdk_input_add(new_con->s, GDK_INPUT_WRITE | GDK_INPUT_EXCEPTION, (GdkInputFunction) newtella_connect, (gpointer)new_con); /* update time */ new_con->last_time = time((time_t)NULL); return 1;}int con_remove(struct newtella_connection *con){ GList *l; struct gpacket *packet; /* remove gdk i/o tags */ if (con->read_tag) gdk_input_remove(con->read_tag); if (con->write_tag) gdk_input_remove(con->write_tag); /* close socket */ close(con->s); /* empty queue */ l = g_list_first(con->queue); while (l) { packet = l->data; newtella_free(packet->data); newtella_free(packet); l = l->next; } g_list_free(con->queue); /* remove it from GUI */ gui_remove_con_from_list(con); /* remove it from the connection's list */ gl_con = g_list_remove(gl_con, con); /* remove host */ host_remove(con->ip, con->port); newtella_free(con); return 1;}int con_mark(struct newtella_connection *con, con_state state){ switch (state) { case GS_HOSTFEED: con->state = GS_HOSTFEED; gl_options->connected++; break; case GS_FAILED: if (con->state == GS_FAILED || con->state == GS_TIMEOUT) break; if (con->state == GS_CONNECTED || con->state == GS_HOSTFEED) gl_options->connected--; con->state = GS_FAILED; //if (con->type == CT_INCOMING || con->type == CT_OUTGOING) // gl_options->cons--; if (con->type == CT_UPLOAD) gl_options->ucons--; else if (con->type == CT_DOWNLOAD) gl_options->dcons--; break; case GS_TIMEOUT: if (con->state == GS_TIMEOUT || con->state == GS_FAILED) break; if (con->state == GS_CONNECTED || con->state == GS_HOSTFEED) gl_options->connected--; con->state = GS_TIMEOUT; //if (con->type == CT_INCOMING || con->type == CT_OUTGOING) // gl_options->cons--; if (con->type == CT_UPLOAD) gl_options->ucons--; else if (con->type == CT_DOWNLOAD) gl_options->dcons--; break; case GS_CONNECTED: con->state = GS_CONNECTED; gl_options->connected++; break; default: break; } con->last_time = time((time_t)NULL); gui_update_con_status(con); return 1;}int con_reset_buffer(struct newtella_connection *con){ /* init buffer */ con->buffer_len = 0;// con->b = NULL; return 1;}int con_activate(void){ GList *iter; struct host_info *host; iter = g_list_first(gl_hosts_in_cache); while (iter) { host = iter->data; if (!host->used) { host->used = 1; con_add(host->ip, host->port); if (gl_options->cons >= gl_options->min_con) break; } iter = g_list_next(iter); } return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -