2005-01-20 23:22:22 +00:00
|
|
|
// Berkeley Open Infrastructure for Network Computing
|
|
|
|
// http://boinc.berkeley.edu
|
|
|
|
// Copyright (C) 2005 University of California
|
2003-07-02 02:02:18 +00:00
|
|
|
//
|
2005-01-20 23:22:22 +00:00
|
|
|
// This is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation;
|
|
|
|
// either version 2.1 of the License, or (at your option) any later version.
|
2003-07-02 02:02:18 +00:00
|
|
|
//
|
2005-01-20 23:22:22 +00:00
|
|
|
// This software 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 Lesser General Public License for more details.
|
2002-04-30 22:22:54 +00:00
|
|
|
//
|
2005-01-20 23:22:22 +00:00
|
|
|
// To view the GNU Lesser General Public License visit
|
|
|
|
// http://www.gnu.org/copyleft/lesser.html
|
|
|
|
// or write to the Free Software Foundation, Inc.,
|
|
|
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
2002-04-30 22:22:54 +00:00
|
|
|
|
2003-10-16 19:03:49 +00:00
|
|
|
#include "cpp.h"
|
2002-06-06 18:42:01 +00:00
|
|
|
|
2004-03-05 04:37:53 +00:00
|
|
|
#ifdef _WIN32
|
2004-06-16 23:16:08 +00:00
|
|
|
#include "boinc_win.h"
|
2005-11-21 18:34:44 +00:00
|
|
|
#else
|
|
|
|
#include "config.h"
|
2004-03-05 04:37:53 +00:00
|
|
|
#endif
|
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
#include "util.h"
|
2002-07-05 05:33:40 +00:00
|
|
|
#include "file_names.h"
|
2003-06-03 22:47:15 +00:00
|
|
|
#include "client_state.h"
|
2002-08-12 21:54:19 +00:00
|
|
|
#include "filesys.h"
|
2004-04-08 08:15:23 +00:00
|
|
|
#include "client_msgs.h"
|
2002-04-30 22:22:54 +00:00
|
|
|
#include "file_xfer.h"
|
2002-08-21 19:12:42 +00:00
|
|
|
#include "parse.h"
|
2002-07-11 01:09:53 +00:00
|
|
|
#include "error_numbers.h"
|
2002-04-30 22:22:54 +00:00
|
|
|
|
2004-06-30 18:17:21 +00:00
|
|
|
using std::vector;
|
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
FILE_XFER::FILE_XFER() {
|
|
|
|
file_xfer_done = false;
|
|
|
|
file_xfer_retval = 0;
|
2002-07-15 23:21:20 +00:00
|
|
|
fip = NULL;
|
2003-03-19 01:15:46 +00:00
|
|
|
strcpy(pathname, "");
|
|
|
|
strcpy(header, "");
|
2002-08-21 19:12:42 +00:00
|
|
|
file_size_query = false;
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
FILE_XFER::~FILE_XFER() {
|
2003-07-23 22:24:28 +00:00
|
|
|
if (fip && fip->pers_file_xfer) {
|
|
|
|
fip->pers_file_xfer->fxp = NULL;
|
|
|
|
}
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
|
|
|
|
2002-07-05 05:33:40 +00:00
|
|
|
int FILE_XFER::init_download(FILE_INFO& file_info) {
|
2003-05-10 00:52:36 +00:00
|
|
|
is_upload = false;
|
2002-07-05 05:33:40 +00:00
|
|
|
fip = &file_info;
|
2007-03-13 19:33:27 +00:00
|
|
|
get_pathname(fip, pathname, sizeof(pathname));
|
2007-01-17 23:52:39 +00:00
|
|
|
|
|
|
|
// if file is already as large or larger than it's supposed to be,
|
|
|
|
// something's screwy; start reading it from the beginning.
|
|
|
|
//
|
|
|
|
if (file_size(pathname, starting_size) || starting_size >= fip->nbytes) {
|
2006-01-18 21:07:04 +00:00
|
|
|
starting_size = 0;
|
2002-08-12 21:54:19 +00:00
|
|
|
}
|
2006-01-18 21:07:04 +00:00
|
|
|
bytes_xferred = starting_size;
|
2003-06-09 22:33:23 +00:00
|
|
|
|
2006-02-28 23:28:07 +00:00
|
|
|
const char* url = fip->get_current_url(is_upload);
|
|
|
|
if (!url) return ERR_INVALID_URL;
|
2006-01-18 21:07:04 +00:00
|
|
|
return HTTP_OP::init_get(
|
2006-02-28 23:28:07 +00:00
|
|
|
url, pathname, false, (int)starting_size
|
2006-01-18 21:07:04 +00:00
|
|
|
);
|
2002-07-05 05:33:40 +00:00
|
|
|
}
|
|
|
|
|
2002-07-07 20:39:24 +00:00
|
|
|
// for uploads, we need to build a header with xml_signature etc.
|
2007-03-05 18:34:30 +00:00
|
|
|
// (see doc/upload.php)
|
2002-07-05 05:33:40 +00:00
|
|
|
// Do this in memory.
|
|
|
|
//
|
2004-07-13 10:36:18 +00:00
|
|
|
int FILE_XFER::init_upload(FILE_INFO& file_info) {
|
2002-08-12 21:54:19 +00:00
|
|
|
// If upload_offset < 0, we need to query the upload handler
|
|
|
|
// for the offset information
|
2003-03-13 21:49:52 +00:00
|
|
|
// TODO: give priority to unfinished upload if there are multiple choices
|
2002-08-12 21:54:19 +00:00
|
|
|
//
|
2002-07-05 05:33:40 +00:00
|
|
|
fip = &file_info;
|
2007-03-13 19:33:27 +00:00
|
|
|
get_pathname(fip, pathname, sizeof(pathname));
|
2002-08-12 21:54:19 +00:00
|
|
|
|
2003-05-10 00:52:36 +00:00
|
|
|
is_upload = true;
|
2005-12-13 08:04:57 +00:00
|
|
|
|
|
|
|
if (file_info.upload_offset < 0) {
|
2003-02-27 09:21:22 +00:00
|
|
|
bytes_xferred = 0;
|
2002-08-12 21:54:19 +00:00
|
|
|
sprintf(header,
|
2002-12-02 04:29:40 +00:00
|
|
|
"<data_server_request>\n"
|
|
|
|
" <core_client_major_version>%d</core_client_major_version>\n"
|
|
|
|
" <core_client_minor_version>%d</core_client_minor_version>\n"
|
2005-08-31 00:18:36 +00:00
|
|
|
" <core_client_release>%d</core_client_release>\n"
|
2002-12-02 04:29:40 +00:00
|
|
|
" <get_file_size>%s</get_file_size>\n"
|
|
|
|
"</data_server_request>\n",
|
2005-08-31 00:18:36 +00:00
|
|
|
BOINC_MAJOR_VERSION, BOINC_MINOR_VERSION, BOINC_RELEASE,
|
2002-08-12 21:54:19 +00:00
|
|
|
file_info.name
|
|
|
|
);
|
2002-08-21 19:12:42 +00:00
|
|
|
file_size_query = true;
|
2006-02-28 23:28:07 +00:00
|
|
|
const char* url = fip->get_current_url(is_upload);
|
|
|
|
if (!url) return ERR_INVALID_URL;
|
|
|
|
return HTTP_OP::init_post2(url, header, NULL, 0);
|
2002-08-12 21:54:19 +00:00
|
|
|
} else {
|
2003-02-27 09:21:22 +00:00
|
|
|
bytes_xferred = file_info.upload_offset;
|
2002-08-12 21:54:19 +00:00
|
|
|
sprintf(header,
|
2002-12-02 04:29:40 +00:00
|
|
|
"<data_server_request>\n"
|
|
|
|
" <core_client_major_version>%d</core_client_major_version>\n"
|
|
|
|
" <core_client_minor_version>%d</core_client_minor_version>\n"
|
2007-03-29 18:41:41 +00:00
|
|
|
" <core_client_release>%d</core_client_release>\n"
|
2002-12-02 04:29:40 +00:00
|
|
|
"<file_upload>\n"
|
2002-08-12 21:54:19 +00:00
|
|
|
"<file_info>\n"
|
|
|
|
"%s"
|
|
|
|
"<xml_signature>\n"
|
|
|
|
"%s"
|
|
|
|
"</xml_signature>\n"
|
|
|
|
"</file_info>\n"
|
2002-12-02 04:29:40 +00:00
|
|
|
"<nbytes>%.0f</nbytes>\n"
|
2007-03-29 18:41:41 +00:00
|
|
|
"<md5_cksum>%s</md5_cksum>\n"
|
2002-08-12 21:54:19 +00:00
|
|
|
"<offset>%.0f</offset>\n"
|
|
|
|
"<data>\n",
|
2007-03-29 18:41:41 +00:00
|
|
|
BOINC_MAJOR_VERSION, BOINC_MINOR_VERSION, BOINC_RELEASE,
|
2002-08-12 21:54:19 +00:00
|
|
|
file_info.signed_xml,
|
|
|
|
file_info.xml_signature,
|
|
|
|
file_info.nbytes,
|
2007-03-29 18:41:41 +00:00
|
|
|
file_info.md5_cksum,
|
2002-08-12 21:54:19 +00:00
|
|
|
file_info.upload_offset
|
|
|
|
);
|
2002-08-21 19:12:42 +00:00
|
|
|
file_size_query = false;
|
2006-02-28 23:28:07 +00:00
|
|
|
const char* url = fip->get_current_url(is_upload);
|
|
|
|
if (!url) return ERR_INVALID_URL;
|
2002-08-26 22:57:17 +00:00
|
|
|
return HTTP_OP::init_post2(
|
2006-02-28 23:28:07 +00:00
|
|
|
url , header, pathname, fip->upload_offset
|
2002-12-02 04:29:40 +00:00
|
|
|
);
|
2002-08-12 21:54:19 +00:00
|
|
|
}
|
2002-07-05 05:33:40 +00:00
|
|
|
}
|
2002-04-30 22:22:54 +00:00
|
|
|
|
2003-09-30 18:09:58 +00:00
|
|
|
// Parse the file upload handler response in req1
|
2002-08-21 19:12:42 +00:00
|
|
|
//
|
2003-09-30 18:09:58 +00:00
|
|
|
int FILE_XFER::parse_upload_response(double &nbytes) {
|
2003-05-06 21:43:26 +00:00
|
|
|
int status = ERR_UPLOAD_TRANSIENT, x;
|
2003-06-03 22:47:15 +00:00
|
|
|
char buf[256];
|
2002-12-02 04:29:40 +00:00
|
|
|
|
2003-05-06 21:43:26 +00:00
|
|
|
nbytes = -1;
|
2002-12-02 04:29:40 +00:00
|
|
|
parse_double(req1, "<file_size>", nbytes);
|
2003-05-06 21:43:26 +00:00
|
|
|
if (parse_int(req1, "<status>", x)) {
|
|
|
|
switch (x) {
|
|
|
|
case -1: status = ERR_UPLOAD_PERMANENT; break;
|
|
|
|
case 0: status = 0; break;
|
|
|
|
case 1: status = ERR_UPLOAD_TRANSIENT; break;
|
|
|
|
default: status = ERR_UPLOAD_TRANSIENT; break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
status = ERR_UPLOAD_TRANSIENT;
|
|
|
|
}
|
2003-07-02 02:02:18 +00:00
|
|
|
|
2002-12-02 04:29:40 +00:00
|
|
|
if (parse_str(req1, "<message>", buf, sizeof(buf))) {
|
2007-01-25 23:39:06 +00:00
|
|
|
msg_printf(fip->project, MSG_INTERNAL_ERROR, "Error on file upload: %s", buf);
|
2002-12-02 04:29:40 +00:00
|
|
|
}
|
|
|
|
|
2002-08-21 19:12:42 +00:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2002-07-15 23:21:20 +00:00
|
|
|
// Create a new empty FILE_XFER_SET
|
|
|
|
//
|
2002-04-30 22:22:54 +00:00
|
|
|
FILE_XFER_SET::FILE_XFER_SET(HTTP_OP_SET* p) {
|
|
|
|
http_ops = p;
|
2005-11-25 18:17:09 +00:00
|
|
|
up_active = false;
|
|
|
|
down_active = false;
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
|
|
|
|
2004-02-19 16:43:28 +00:00
|
|
|
// start a FILE_XFER going (connect to server etc.)
|
|
|
|
// If successful, add to the set
|
2002-07-15 23:21:20 +00:00
|
|
|
//
|
2002-04-30 22:22:54 +00:00
|
|
|
int FILE_XFER_SET::insert(FILE_XFER* fxp) {
|
|
|
|
int retval;
|
2002-08-15 22:03:41 +00:00
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
retval = http_ops->insert(fxp);
|
|
|
|
if (retval) return retval;
|
2004-02-19 16:43:28 +00:00
|
|
|
file_xfers.push_back(fxp);
|
2006-10-02 16:13:08 +00:00
|
|
|
set_bandwidth_limits(fxp->is_upload);
|
2002-04-30 22:22:54 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-07-15 23:21:20 +00:00
|
|
|
// Remove a FILE_XFER object from the set
|
|
|
|
//
|
2002-04-30 22:22:54 +00:00
|
|
|
int FILE_XFER_SET::remove(FILE_XFER* fxp) {
|
|
|
|
vector<FILE_XFER*>::iterator iter;
|
2002-08-15 22:03:41 +00:00
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
http_ops->remove(fxp);
|
|
|
|
|
|
|
|
iter = file_xfers.begin();
|
|
|
|
while (iter != file_xfers.end()) {
|
|
|
|
if (*iter == fxp) {
|
2006-10-02 17:44:27 +00:00
|
|
|
iter = file_xfers.erase(iter);
|
|
|
|
set_bandwidth_limits(fxp->is_upload);
|
2002-04-30 22:22:54 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
iter++;
|
|
|
|
}
|
2007-01-25 23:39:06 +00:00
|
|
|
msg_printf(NULL, MSG_INTERNAL_ERROR,
|
2006-01-17 22:48:09 +00:00
|
|
|
"File transfer for %s not found", fxp->fip->name
|
|
|
|
);
|
2004-01-30 22:19:19 +00:00
|
|
|
return ERR_NOT_FOUND;
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
|
|
|
|
2002-07-15 23:21:20 +00:00
|
|
|
// Run through the FILE_XFER_SET and determine if any of the file
|
|
|
|
// transfers are complete or had an error
|
|
|
|
//
|
2005-06-07 19:22:50 +00:00
|
|
|
bool FILE_XFER_SET::poll() {
|
2002-04-30 22:22:54 +00:00
|
|
|
unsigned int i;
|
|
|
|
FILE_XFER* fxp;
|
|
|
|
bool action = false;
|
2004-10-14 22:01:05 +00:00
|
|
|
static double last_time=0;
|
2006-02-16 21:35:34 +00:00
|
|
|
char pathname[256];
|
|
|
|
double size;
|
2004-10-14 22:01:05 +00:00
|
|
|
|
2005-06-07 19:22:50 +00:00
|
|
|
if (gstate.now - last_time < 1.0) return false;
|
|
|
|
last_time = gstate.now;
|
2002-04-30 22:22:54 +00:00
|
|
|
|
|
|
|
for (i=0; i<file_xfers.size(); i++) {
|
|
|
|
fxp = file_xfers[i];
|
2006-01-18 22:12:55 +00:00
|
|
|
if (!fxp->http_op_done()) continue;
|
2003-02-26 00:47:57 +00:00
|
|
|
|
2006-01-18 22:12:55 +00:00
|
|
|
action = true;
|
|
|
|
fxp->file_xfer_done = true;
|
2006-06-22 19:40:30 +00:00
|
|
|
if (log_flags.file_xfer_debug) {
|
|
|
|
msg_printf(0, MSG_INFO,
|
2006-09-07 20:39:25 +00:00
|
|
|
"[file_xfer_debug] FILE_XFER_SET::poll(): http op done; retval %d\n",
|
2006-06-22 19:40:30 +00:00
|
|
|
fxp->http_op_retval
|
|
|
|
);
|
|
|
|
}
|
2006-01-18 22:12:55 +00:00
|
|
|
fxp->file_xfer_retval = fxp->http_op_retval;
|
|
|
|
if (fxp->file_xfer_retval == 0) {
|
|
|
|
if (fxp->is_upload) {
|
|
|
|
fxp->file_xfer_retval = fxp->parse_upload_response(
|
|
|
|
fxp->fip->upload_offset
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If this was a file size query, restart the transfer
|
|
|
|
// using the remote file size information
|
|
|
|
//
|
|
|
|
if (fxp->file_size_query) {
|
|
|
|
if (fxp->file_xfer_retval) {
|
|
|
|
fxp->fip->upload_offset = -1;
|
|
|
|
} else {
|
2002-10-15 18:09:16 +00:00
|
|
|
|
2006-01-18 22:12:55 +00:00
|
|
|
// if the server's file size is bigger than ours,
|
|
|
|
// something bad has happened
|
|
|
|
// (like a result got sent to multiple users).
|
|
|
|
// Pretend the file was successfully uploaded
|
|
|
|
//
|
|
|
|
if (fxp->fip->upload_offset >= fxp->fip->nbytes) {
|
|
|
|
fxp->file_xfer_done = true;
|
|
|
|
fxp->file_xfer_retval = 0;
|
|
|
|
} else {
|
|
|
|
// Restart the upload, using the newly obtained
|
|
|
|
// upload_offset
|
2004-01-21 07:07:16 +00:00
|
|
|
//
|
2006-01-18 22:12:55 +00:00
|
|
|
fxp->close_socket();
|
|
|
|
fxp->file_xfer_retval = fxp->init_upload(*fxp->fip);
|
2002-08-21 23:01:12 +00:00
|
|
|
|
2006-01-18 22:12:55 +00:00
|
|
|
if (!fxp->file_xfer_retval) {
|
|
|
|
remove(fxp);
|
|
|
|
i--;
|
|
|
|
fxp->file_xfer_retval = insert(fxp);
|
2003-05-06 21:43:26 +00:00
|
|
|
if (!fxp->file_xfer_retval) {
|
2006-01-18 22:12:55 +00:00
|
|
|
fxp->file_xfer_done = false;
|
|
|
|
fxp->file_xfer_retval = 0;
|
|
|
|
fxp->http_op_retval = 0;
|
2002-08-21 23:01:12 +00:00
|
|
|
}
|
|
|
|
}
|
2002-08-21 19:12:42 +00:00
|
|
|
}
|
|
|
|
}
|
2006-01-18 22:12:55 +00:00
|
|
|
}
|
|
|
|
} else if (fxp->file_xfer_retval == HTTP_STATUS_RANGE_REQUEST_ERROR) {
|
|
|
|
fxp->fip->error_msg = "Local copy is at least as large as server copy";
|
|
|
|
}
|
|
|
|
|
2006-06-27 17:31:43 +00:00
|
|
|
// deal with various error cases for downloads
|
2006-01-18 22:12:55 +00:00
|
|
|
//
|
2006-06-27 17:31:43 +00:00
|
|
|
if (!fxp->is_upload) {
|
2007-03-13 19:33:27 +00:00
|
|
|
get_pathname(fxp->fip, pathname, sizeof(pathname));
|
2006-10-23 21:00:36 +00:00
|
|
|
if (file_size(pathname, size)) continue;
|
|
|
|
double diff = size - fxp->starting_size;
|
2006-07-25 16:45:21 +00:00
|
|
|
if (fxp->http_op_retval == 0) {
|
2006-06-27 17:31:43 +00:00
|
|
|
// If no HTTP error,
|
|
|
|
// see if we read less than 5 KB and file is incomplete.
|
|
|
|
// If so truncate the amount read,
|
|
|
|
// since it may be a proxy error message
|
|
|
|
//
|
|
|
|
if (fxp->fip->nbytes) {
|
|
|
|
if (size == fxp->fip->nbytes) continue;
|
|
|
|
if (diff>0 && diff<MIN_DOWNLOAD_INCREMENT) {
|
|
|
|
msg_printf(fxp->fip->project, MSG_INFO,
|
|
|
|
"Incomplete read of %f < 5KB for %s - truncating",
|
|
|
|
diff, fxp->fip->name
|
|
|
|
);
|
|
|
|
boinc_truncate(pathname, fxp->starting_size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2006-10-23 21:00:36 +00:00
|
|
|
// got HTTP error; truncate last 5KB of file, since some
|
2006-06-27 17:31:43 +00:00
|
|
|
// error-reporting HTML may have been appended
|
|
|
|
//
|
2006-10-23 21:00:36 +00:00
|
|
|
if (diff < MIN_DOWNLOAD_INCREMENT) {
|
|
|
|
diff = 0;
|
|
|
|
} else {
|
|
|
|
diff -= MIN_DOWNLOAD_INCREMENT;
|
|
|
|
}
|
|
|
|
boinc_truncate(pathname, fxp->starting_size + diff);
|
2005-03-10 00:43:22 +00:00
|
|
|
}
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
2006-02-16 21:35:34 +00:00
|
|
|
|
|
|
|
// for downloads: if we requested a partial transfer,
|
|
|
|
// and the HTTP response is 200,
|
|
|
|
// and the file is larger than it should be,
|
|
|
|
// the server or proxy must have sent us the entire file
|
|
|
|
// (i.e. it doesn't understand Range: requests).
|
|
|
|
// In this case, trim off the initial part of the file
|
|
|
|
//
|
|
|
|
if (!fxp->is_upload && fxp->starting_size
|
|
|
|
&& fxp->response==HTTP_STATUS_OK
|
|
|
|
) {
|
2007-03-13 19:33:27 +00:00
|
|
|
get_pathname(fxp->fip, pathname, sizeof(pathname));
|
2006-02-16 21:35:34 +00:00
|
|
|
if (file_size(pathname, size)) continue;
|
|
|
|
if (size > fxp->fip->nbytes) {
|
|
|
|
FILE* f1 = boinc_fopen(pathname, "rb");
|
|
|
|
FILE* f2 = boinc_fopen(TEMP_FILE_NAME, "wb");
|
|
|
|
if (f1 && f2) {
|
|
|
|
fseek(f1, (long)fxp->starting_size, SEEK_SET);
|
|
|
|
copy_stream(f1, f2);
|
|
|
|
fclose(f1);
|
|
|
|
fclose(f2);
|
|
|
|
f1 = boinc_fopen(TEMP_FILE_NAME, "rb");
|
|
|
|
f2 = boinc_fopen(pathname, "wb");
|
|
|
|
copy_stream(f1, f2);
|
|
|
|
fclose(f1);
|
|
|
|
fclose(f2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-04-30 22:22:54 +00:00
|
|
|
}
|
|
|
|
return action;
|
|
|
|
}
|
2006-10-02 16:13:08 +00:00
|
|
|
|
2005-11-25 18:17:09 +00:00
|
|
|
// return true if an upload is currently in progress
|
|
|
|
// or has been since the last call to this.
|
|
|
|
// Similar for download.
|
|
|
|
//
|
|
|
|
void FILE_XFER_SET::check_active(bool& up, bool& down) {
|
|
|
|
unsigned int i;
|
|
|
|
FILE_XFER* fxp;
|
|
|
|
|
|
|
|
up = up_active;
|
|
|
|
down = down_active;
|
|
|
|
for (i=0; i<file_xfers.size(); i++) {
|
|
|
|
fxp = file_xfers[i];
|
|
|
|
fxp->is_upload?up=true:down=true;
|
|
|
|
}
|
|
|
|
up_active = false;
|
|
|
|
down_active = false;
|
|
|
|
}
|
2004-12-08 00:40:19 +00:00
|
|
|
|
2006-10-02 16:13:08 +00:00
|
|
|
// adjust bandwidth limits
|
|
|
|
//
|
|
|
|
void FILE_XFER_SET::set_bandwidth_limits(bool is_upload) {
|
|
|
|
double max_bytes_sec;
|
|
|
|
unsigned int i;
|
|
|
|
FILE_XFER* fxp;
|
|
|
|
|
|
|
|
if (is_upload) {
|
|
|
|
max_bytes_sec = gstate.global_prefs.max_bytes_sec_up;
|
|
|
|
} else {
|
|
|
|
max_bytes_sec = gstate.global_prefs.max_bytes_sec_down;
|
|
|
|
}
|
|
|
|
if (!max_bytes_sec) return;
|
|
|
|
int n = 0;
|
|
|
|
for (i=0; i<file_xfers.size(); i++) {
|
|
|
|
fxp = file_xfers[i];
|
2006-10-03 20:13:15 +00:00
|
|
|
if (!fxp->is_active()) continue;
|
2006-10-02 16:13:08 +00:00
|
|
|
if (is_upload) {
|
|
|
|
if (!fxp->is_upload) continue;
|
|
|
|
} else {
|
|
|
|
if (fxp->is_upload) continue;
|
|
|
|
}
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
if (!n) return;
|
|
|
|
max_bytes_sec /= n;
|
|
|
|
for (i=0; i<file_xfers.size(); i++) {
|
|
|
|
fxp = file_xfers[i];
|
2006-10-03 20:13:15 +00:00
|
|
|
if (!fxp->is_active()) continue;
|
2006-10-02 16:13:08 +00:00
|
|
|
if (is_upload) {
|
|
|
|
if (!fxp->is_upload) continue;
|
|
|
|
fxp->set_speed_limit(true, max_bytes_sec);
|
|
|
|
} else {
|
|
|
|
if (fxp->is_upload) continue;
|
|
|
|
fxp->set_speed_limit(false, max_bytes_sec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-02 18:29:53 +00:00
|
|
|
const char *BOINC_RCSID_31ba21bea3 = "$Id$";
|