Rediff patches.
[packages/irssi.git] / irssi-dcc-send-limit.patch
CommitLineData
20ce40f7
AM
1diff -urNp -x '*.orig' irssi-1.2.2.org/src/irc/dcc/dcc-rec.h irssi-1.2.2/src/irc/dcc/dcc-rec.h
2--- irssi-1.2.2.org/src/irc/dcc/dcc-rec.h 2019-08-29 15:48:43.000000000 +0200
3+++ irssi-1.2.2/src/irc/dcc/dcc-rec.h 2021-05-04 21:22:16.382408355 +0200
4@@ -22,6 +22,12 @@ uoff_t transfd; /* bytes transferred */
5
6 int pasv_id; /* DCC Id for passive DCCs. <0 means a passive DCC, >=0 means a standard DCC */
cdc4109b
JR
7
8+int timeout_tag;
9+
10+unsigned long skip_bytes;
11+unsigned long limit_starttime;
12+unsigned long max_speed;
13+
14 unsigned int destroyed:1; /* We're about to destroy this DCC recond */
15
16 GHashTable *module_data;
20ce40f7
AM
17diff -urNp -x '*.orig' irssi-1.2.2.org/src/irc/dcc/dcc-send.c irssi-1.2.2/src/irc/dcc/dcc-send.c
18--- irssi-1.2.2.org/src/irc/dcc/dcc-send.c 2019-08-29 15:48:46.000000000 +0200
19+++ irssi-1.2.2/src/irc/dcc/dcc-send.c 2021-05-04 21:22:16.382408355 +0200
20@@ -250,17 +250,87 @@ static void sig_dcc_destroyed(SEND_DCC_R
cdc4109b
JR
21 {
22 if (!IS_DCC_SEND(dcc)) return;
23
24+ if (dcc->timeout_tag != -1)
25+ g_source_remove(dcc->timeout_tag);
26+
f25af77f
JR
27 if (dcc->fhandle != -1)
28 close(dcc->fhandle);
29
30 dcc_queue_send_next(dcc->queue);
cdc4109b
JR
31 }
32
33+static int sent_too_much(SEND_DCC_REC *dcc)
34+{
35+ GTimeVal gtv;
36+ gulong timediff, curtime;
37+ gulong transfd, speed;
38+
39+ /* 0 == unlimited speed */
40+ if (dcc->max_speed == 0) return 0;
41+
42+ /* get time difference in milliseconds */
43+ g_get_current_time(&gtv);
44+ curtime = (gtv.tv_sec * 1000) + (gtv.tv_usec / 1000);
45+
46+ transfd = (dcc->transfd - dcc->skip_bytes);
47+ timediff = curtime - dcc->limit_starttime + 1;
48+ speed = ((transfd * 1000) / timediff);
49+
50+ /* reset speed counter every 30 seconds */
51+ if (timediff >= 30000) {
52+ dcc->limit_starttime = curtime;
53+ dcc->skip_bytes = dcc->transfd;
54+ }
55+
56+ return (speed > (dcc->max_speed * 1024));
57+}
58+
59+static void dcc_send_data(SEND_DCC_REC *dcc);
60+
61+static void reset_dcc_send(SEND_DCC_REC *dcc)
62+{
63+ if (g_slist_find(dcc_conns, dcc) == NULL) {
64+ /* the DCC was closed during the wait */
65+ return;
66+ }
67+
68+ if (dcc->timeout_tag != -1)
69+ g_source_remove(dcc->timeout_tag);
70+ dcc->timeout_tag = -1;
71+
72+ dcc->tagwrite = g_input_add(dcc->handle, G_INPUT_WRITE,
73+ (GInputFunction) dcc_send_data, dcc);
74+
75+ return;
76+}
77+
78 /* input function: DCC SEND - we're ready to send more data */
79 static void dcc_send_data(SEND_DCC_REC *dcc)
80 {
81 char buffer[512];
82- int ret;
83+ int ret, max_speed;
84+ GTimeVal gtv;
85+
86+ max_speed = settings_get_int("dcc_send_top_speed");
87+ if (max_speed != dcc->max_speed) {
88+ /* speed setting has changed, calculate speed from current position
89+ instead of from the start to eliminate speed boosts/slowdowns */
90+
91+ dcc->max_speed = max_speed;
92+ dcc->skip_bytes = dcc->transfd;
93+
94+ g_get_current_time(&gtv);
95+ dcc->limit_starttime = (gtv.tv_sec * 1000) + (gtv.tv_usec / 1000);
96+ }
97+
98+ if (sent_too_much(dcc)) {
99+ /* disable calling this function for 1/10th of a second. */
100+ g_source_remove(dcc->tagwrite);
101+ dcc->tagwrite = -1;
102+ dcc->timeout_tag = g_timeout_add(100, (GSourceFunc)
103+ reset_dcc_send, dcc);
104+ return;
105+ }
106
107 ret = read(dcc->fhandle, buffer, sizeof(buffer));
108 if (ret <= 0) {
20ce40f7 109@@ -316,6 +386,7 @@ static void dcc_send_connected(SEND_DCC_
cdc4109b
JR
110 GIOChannel *handle;
111 IPADDR addr;
112 int port;
113+ GTimeVal gtv;
114
115 /* accept connection */
116 handle = net_accept(dcc->handle, &addr, &port);
20ce40f7 117@@ -330,6 +401,13 @@ static void dcc_send_connected(SEND_DCC_
cdc4109b 118 g_source_remove(dcc->tagconn);
2eed8244 119 dcc->tagconn = -1;
cdc4109b 120
cdc4109b
JR
121+ dcc->skip_bytes = 0;
122+ dcc->max_speed = settings_get_int("dcc_send_top_speed");
123+
124+ /* get starttime in milliseconds */
125+ g_get_current_time(&gtv);
126+ dcc->limit_starttime = (gtv.tv_sec * 1000) + (gtv.tv_usec / 1000);
127+
128 dcc->starttime = time(NULL);
129 dcc->handle = handle;
130 memcpy(&dcc->addr, &addr, sizeof(IPADDR));
20ce40f7 131@@ -434,6 +512,7 @@ static int dcc_send_one_file(int queue,
f7abf479 132 dcc->size = st.st_size;
2eed8244 133 dcc->fhandle = hfile;
f25af77f 134 dcc->queue = queue;
2eed8244 135+ dcc->timeout_tag = -1;
f7abf479 136 dcc->file_quoted = strchr(fname, ' ') != NULL;
137 if (!passive) {
138 dcc->tagconn = g_input_add(handle, G_INPUT_READ,
20ce40f7 139@@ -473,6 +552,7 @@ void dcc_send_init(void)
cdc4109b
JR
140 dcc_register_type("SEND");
141 settings_add_str("dcc", "dcc_upload_path", "~");
f25af77f 142 settings_add_bool("dcc", "dcc_send_replace_space_with_underscore", FALSE);
cdc4109b 143+ settings_add_int("dcc", "dcc_send_top_speed", 0);
cdc4109b 144 signal_add("dcc destroyed", (SIGNAL_FUNC) sig_dcc_destroyed);
20ce40f7 145 signal_add("dcc reply send pasv", (SIGNAL_FUNC) dcc_send_connect);
cdc4109b 146 command_bind("dcc send", NULL, (SIGNAL_FUNC) cmd_dcc_send);
This page took 0.221593 seconds and 4 git commands to generate.