My dad was watching internet connected television, while I decided to check fixes for Arch. There were new kernel, some libreoffice stuff, and so on making the download to be more than few megabytes. When I downloaded the packages television sound track was affected annoying way. Obviosly my download was affecting a stream that had greater service quality expectancy. This patch will allow an user to polite and throttle down bandwidth usage in benefit for others. Signed-off-by: Sami Kerola <kerolasa@iki.fi> --- doc/pacman.8.txt | 5 +++++ lib/libalpm/alpm.h | 5 +++++ lib/libalpm/dload.c | 4 ++++ lib/libalpm/handle.c | 13 +++++++++++++ lib/libalpm/handle.h | 1 + src/pacman/conf.c | 1 + src/pacman/conf.h | 2 ++ src/pacman/pacman.c | 6 ++++++ 8 files changed, 37 insertions(+) diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index 574995c..da8fa1b 100644 --- a/doc/pacman.8.txt +++ b/doc/pacman.8.txt @@ -362,6 +362,11 @@ Sync Options[[SO]] packages that are no longer installed; use two to remove all files from the cache. In both cases, you will have a yes or no option to remove packages and/or unused downloaded databases. + +*\--max-recv-speed* <bits>:: + Define maximum transfer rate in bits per seconds. This option is + useful when network bandwidth is scarce resource, and other users + of the network has greater service expecations. + If you use a network shared cache, see the 'CleanMethod' option in linkman:pacman.conf[5]. diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index b049007..bc77641 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -533,6 +533,11 @@ int alpm_option_get_usesyslog(alpm_handle_t *handle); /** Sets whether to use syslog (0 is FALSE, TRUE otherwise). */ int alpm_option_set_usesyslog(alpm_handle_t *handle, int usesyslog); +/** Returns maximum download receive speed. */ +int alpm_option_get_max_recv_speed(alpm_handle_t *handle); +/** Sets maximum download receive speed. */ +int alpm_option_set_max_recv_speed(alpm_handle_t *handle, int rate); + /** @name Accessors to the list of no-upgrade files. * These functions modify the list of files which should * not be updated by package installation. diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 8537b3d..25f2423 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -331,6 +331,10 @@ static void curl_set_handle_opts(struct dload_payload *payload, (intmax_t)st.st_size); payload->initial_size = st.st_size; } + + if(payload->handle->max_recv_speed) { + curl_easy_setopt(curl, CURLOPT_MAX_RECV_SPEED_LARGE, payload->handle->max_recv_speed); + } } static void mask_signal(int signum, void (*handler)(int), diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index 53c86c5..b061efd 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -181,6 +181,12 @@ alpm_cb_progress SYMEXPORT alpm_option_get_progresscb(alpm_handle_t *handle) return handle->progresscb; } +int SYMEXPORT alpm_option_get_max_recv_speed(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return -1); + return handle->max_recv_speed; +} + const char SYMEXPORT *alpm_option_get_root(alpm_handle_t *handle) { CHECK_HANDLE(handle, return NULL); @@ -314,6 +320,13 @@ int SYMEXPORT alpm_option_set_progresscb(alpm_handle_t *handle, alpm_cb_progress return 0; } +int SYMEXPORT alpm_option_set_max_recv_speed(alpm_handle_t *handle, int rate) +{ + CHECK_HANDLE(handle, return -1); + handle->max_recv_speed = rate; + return 0; +} + static char *canonicalize_path(const char *path) { char *new_path; diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 5e84d58..f5b4baf 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -90,6 +90,7 @@ struct __alpm_handle_t { char *arch; /* Architecture of packages we should allow */ double deltaratio; /* Download deltas if possible; a ratio value */ int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */ + int max_recv_speed; /* Maximum download receive speed. */ int checkspace; /* Check disk space before installing */ alpm_siglevel_t siglevel; /* Default signature verification level */ alpm_siglevel_t localfilesiglevel; /* Signature verification level for local file diff --git a/src/pacman/conf.c b/src/pacman/conf.c index cd357ab..e6112f1 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -682,6 +682,7 @@ static int setup_libalpm(void) alpm_option_set_eventcb(handle, cb_event); alpm_option_set_questioncb(handle, cb_question); alpm_option_set_progresscb(handle, cb_progress); + alpm_option_set_max_recv_speed(handle, config->max_recv_speed); config->logfile = config->logfile ? config->logfile : strdup(LOGFILE); ret = alpm_option_set_logfile(handle, config->logfile); diff --git a/src/pacman/conf.h b/src/pacman/conf.h index dcd3204..30ccd60 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -47,6 +47,7 @@ typedef struct __config_t { unsigned short checkspace; unsigned short usesyslog; unsigned short color; + unsigned int max_recv_speed; double deltaratio; char *arch; char *print_format; @@ -143,6 +144,7 @@ enum { OP_ASEXPLICIT, OP_ARCH, OP_PRINTFORMAT, + OP_MAXRECVSPEED, OP_GPGDIR, OP_DBONLY, OP_FORCE, diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 24fd57f..c1c6705 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -177,6 +177,7 @@ static void usage(int op, const char * const myname) addlist(_(" --force force install, overwrite conflicting files\n")); addlist(_(" --asdeps install packages as non-explicitly installed\n")); addlist(_(" --asexplicit install packages as explicitly installed\n")); + addlist(_(" --max-recv-speed <bits> limit download speed to bits per second (libcurl)\n")); addlist(_(" --ignore <pkg> ignore a package upgrade (can be used more than once)\n")); addlist(_(" --ignoregroup <grp>\n" " ignore a group upgrade (can be used more than once)\n")); @@ -510,6 +511,10 @@ static int parsearg_trans(int opt) check_optarg(); config->print_format = strdup(optarg); break; + case OP_MAXRECVSPEED: + check_optarg(); + config->max_recv_speed = (unsigned int)atoi(optarg); + break; default: return 1; } return 0; @@ -645,6 +650,7 @@ static int parseargs(int argc, char *argv[]) {"asexplicit", no_argument, 0, OP_ASEXPLICIT}, {"arch", required_argument, 0, OP_ARCH}, {"print-format", required_argument, 0, OP_PRINTFORMAT}, + {"max-recv-speed", required_argument, 0, OP_MAXRECVSPEED}, {"gpgdir", required_argument, 0, OP_GPGDIR}, {"dbonly", no_argument, 0, OP_DBONLY}, {"color", required_argument, 0, OP_COLOR}, -- 1.8.4