📄 uploads.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 + -