cde39a10e7a0cbfa781d42d2a1ce453e081bf092
[packages/irssi.git] / irssi-dcc-send-limit.patch
1 diff -ur irssi-0.8.4.orig/src/irc/dcc/dcc-rec.h irssi-0.8.4/src/irc/dcc/dcc-rec.h
2 --- irssi-0.8.4.orig/src/irc/dcc/dcc-rec.h      Mon Feb 19 04:40:06 2001
3 +++ irssi-0.8.4/src/irc/dcc/dcc-rec.h   Thu Mar 14 02:20:25 2002
4 @@ -20,6 +20,12 @@
5  time_t starttime; /* transfer start time */
6  uoff_t transfd; /* bytes transferred */
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;
17 diff -ur irssi-0.8.4.orig/src/irc/dcc/dcc-send.c irssi-0.8.4/src/irc/dcc/dcc-send.c
18 --- irssi-0.8.4.orig/src/irc/dcc/dcc-send.c     Sun Jan 20 04:10:27 2002
19 +++ irssi-0.8.4/src/irc/dcc/dcc-send.c  Thu Mar 14 02:21:22 2002
20 @@ -217,17 +217,87 @@
21  {
22         if (!IS_DCC_SEND(dcc)) return;
23  
24 +       if (dcc->timeout_tag != -1)
25 +               g_source_remove(dcc->timeout_tag);
26 +
27         if (dcc->fhandle != -1)
28                 close(dcc->fhandle);
29  
30         dcc_queue_send_next(dcc->queue);
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) {
109 @@ -282,6 +352,7 @@
110          GIOChannel *handle;
111         IPADDR addr;
112         int port;
113 +       GTimeVal gtv;
114  
115         /* accept connection */
116         handle = net_accept(dcc->handle, &addr, &port);
117 @@ -296,6 +366,13 @@
118         g_source_remove(dcc->tagconn);
119          dcc->tagconn = -1;
120  
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));
131 @@ -429,6 +429,7 @@
132         dcc->size = st.st_size;
133         dcc->fhandle = hfile;
134         dcc->queue = queue;
135 +       dcc->timeout_tag = -1;
136          dcc->file_quoted = strchr(fname, ' ') != NULL;
137         if (!passive) {
138                 dcc->tagconn = g_input_add(handle, G_INPUT_READ,
139 @@ -412,6 +490,7 @@
140          dcc_register_type("SEND");
141         settings_add_str("dcc", "dcc_upload_path", "~");
142         settings_add_bool("dcc", "dcc_send_replace_space_with_underscore", FALSE);
143 +       settings_add_int("dcc", "dcc_send_top_speed", 0);
144         signal_add("dcc destroyed", (SIGNAL_FUNC) sig_dcc_destroyed);
145         command_bind("dcc send", NULL, (SIGNAL_FUNC) cmd_dcc_send);
146         command_set_options("dcc send", "append flush prepend rmhead rmtail");
This page took 0.070053 seconds and 2 git commands to generate.