⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uploads.c

📁 linux下支持P2P的客户端程序,采用了Gnutella的方法,其中有实现Gnutella的具体源码,是一个基于p2p环境下的音乐共享软件,有助于对P2P的研究
💻 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 */#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <time.h>#include "newtella.h"#include "file.h"#include "gui.h"#include "guid.h"#include "http.h"#include "uploads.h"/* General functions for Upload Connections */struct file_entry *upload_find_file(guint32 indx){	/* finds a file in the database	   using its index.	*/	struct file_entry *fe;	GList *iter;	iter = g_list_first(gl_file_db);	while (iter) {		fe = iter->data;		if (fe->index == indx)			return fe;		iter = g_list_next(iter);	} 	/* if we reach uphere then something 	   _really_ bad has happened. :-(	*/	return NULL;}gint upload_write(gpointer gdata, gint s, GdkInputCondition cond){        struct newtella_connection *ucon = (struct newtella_connection *)gdata;	struct gpacket *packet;	gchar data[1024];	gint bytes_readed, r;		        if (cond == GDK_INPUT_EXCEPTION) {		upload_stop(ucon);		ucon->state = GS_FAILED;		gui_update_upload(ucon);		return -1;        }	if (g_list_length(ucon->queue)) {				packet = (struct gpacket *) g_list_last(ucon->queue)->data;		r = send(ucon->s, packet->data, packet->len, 0);		if (r != packet->len) 			upload_stop(ucon);		else			ucon->state = GS_CONNECTED;		ucon->queue = g_list_remove(ucon->queue, packet);		newtella_free(packet->data);		newtella_free(packet);		return 1;	}       		if (!ucon->fi->des)		return 1;	bytes_readed = read(ucon->fi->des, &data, 1024);       	if (bytes_readed && send(ucon->s, data, bytes_readed, 0) > 0) {		ucon->total_sent += bytes_readed;	} else {		if (ucon->total_sent >= ucon->u_file_size)			ucon->state = GS_COMPLETE;		else			ucon->state = GS_FAILED;		upload_stop(ucon);        }	/* gui update */	gui_update_upload(ucon);        return 1;}gint upload_add(guint32 ip, guint16 port, guint32 indx, gchar *guid){	struct http_header *http = newtella_malloc(sizeof(struct http_header));	struct file_entry *fe = upload_find_file(indx);	struct newtella_connection *ucon;	/* file not found */	if (!fe) 		return -1;	ucon = newtella_malloc(sizeof(struct newtella_connection));	ucon->ip = ip;        ucon->port = port;		con_zero_stats(ucon);	con_init_queue(ucon);	ucon->state = GS_HANDSHAKE;	ucon->type  = CT_UPLOAD;	ucon->u_file_size = fe->size;        gl_up_con = g_list_append(gl_up_con, ucon);        ucon->s = newtella_force_connect(ip, port);	ucon->write_tag = gdk_input_add(ucon->s, GDK_INPUT_WRITE | GDK_INPUT_EXCEPTION, 					(GdkInputFunction) newtella_connect, (gpointer)ucon);	/* build the http msg */	http->func = HTTP_GIV;	http->file_index = indx;	http->file_name = fe->name;	guidcpy(http->guid, guid);	con_send_packet(ucon, http_header_build(http), 			strlen(http_header_build(http)), 0);	return 1;}int upload_start(struct newtella_connection *ucon, gchar *buf){	gchar *up_file;	struct http_header *http        = newtella_malloc(sizeof *http);	struct http_header *get_request;	struct file_entry  *fe;	get_request = http_header_parse(buf);	g_print("***Upload\n%s\n", buf);	/* find the requested file */	fe = upload_find_file(get_request->file_index);		ucon->write_tag = gdk_input_add(ucon->s, GDK_INPUT_WRITE | GDK_INPUT_EXCEPTION, 				(GdkInputFunction) upload_write, (gpointer)ucon);        /* file not found */	if (!fe) {		http->func = HTTP_RESPONSE;		http->code = 404; /* Not Found */		http->user_agent = GNEWTELLIUM;		con_send_packet(ucon, http_header_build(http),				strlen(http_header_build(http)), 0);		ucon->state = GS_FAILED;				return -1;	}	/* reject upload */	if (gl_options->current_up_con >= gl_options->max_uploads) {		http->func = HTTP_RESPONSE;		http->code = 503; /* Busy */		http->user_agent = GNEWTELLIUM;		con_send_packet(ucon, http_header_build(http),				strlen(http_header_build(http)), 0);		ucon->state = GS_FAILED;				return -1;	}	if (ucon->state != CT_UPLOAD) {		/* this is a direct upload connection so		   it comes from an ordinary one. We have to		   add it in the upload list and kill the 		   ordinary one.		*/		ucon->state = GS_HANDSHAKE;		ucon->type  = CT_UPLOAD;		ucon->u_file_size = fe->size;		gl_up_con = g_list_append(gl_up_con, ucon);		gl_con = g_list_remove(gl_con, ucon);		gui_remove_con_from_list(ucon);	}       	gui_add_upload(ucon, fe->name); 	       	up_file = newtella_malloc(strlen(fe->path)+strlen(fe->name)+1);	up_file = strcpy(up_file, fe->path);	up_file = strcat(up_file, fe->name);	ucon->fi = newtella_malloc(sizeof(struct file_found));	ucon->fi->des = open(up_file, O_RDONLY);	if (get_request->range_start) {		lseek(ucon->fi->des, get_request->range_start, SEEK_SET);		ucon->total_sent = get_request->range_start;	}        /* approve upload */	http->func = HTTP_RESPONSE;	if (!get_request->range_start) {		http->code = 200; /* OK */		http->content_length = fe->size;	}	else {		http->code = 206; /* Resume */		http->content_length = fe->size - get_request->range_start;	}	http->user_agent = GNEWTELLIUM;	con_send_packet(ucon, http_header_build(http), 			strlen(http_header_build(http)), 0);	return 1;}int upload_stop(struct newtella_connection *ucon){	if (ucon->write_tag)		gdk_input_remove(ucon->write_tag);	close(ucon->s);	ucon->state = GS_STOPPED;	gui_update_upload(ucon);	return 1;}int upload_kill(struct newtella_connection *ucon){	if (ucon->state != GS_STOPPED)		upload_stop(ucon);	gl_up_con = g_list_remove(gl_up_con, ucon);       	gui_remove_upload(ucon);	newtella_free(ucon->fi);	newtella_free(ucon->queue);	newtella_free(ucon);	return 1;}int upload_active_con(void){	struct newtella_connection *ucon;	gint ucons = 0;	GList *iter = g_list_first(gl_up_con);	while (iter) {		ucon = iter->data;		if (ucon->state == GS_CONNECTED)			ucons++;		iter = g_list_next(iter);	}	return ucons;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -