]>
Commit | Line | Data |
---|---|---|
23c9e63c | 1 | /* |
ca9506cc RC |
2 | |
3 | ||
85553593 | 4 | * Copyright (c) 2000, 2001, Red Hat, Inc. |
23c9e63c DD |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; either version 2 of the License, or | |
9 | * (at your option) any later version. | |
10 | * | |
11 | * A copy of the GNU General Public License can be found at | |
12 | * http://www.gnu.org/ | |
13 | * | |
14 | * Written by DJ Delorie <dj@cygnus.com> | |
15 | * | |
16 | */ | |
17 | ||
18 | /* The purpose of this file is to act as a pretty interface to | |
19 | netio.cc. We add a progress dialog and some convenience functions | |
20 | (like collect to string or file */ | |
21 | ||
b24c88b3 RC |
22 | #if 0 |
23 | static const char *cvsid = | |
24 | "\n%%% $Id$\n"; | |
25 | #endif | |
8507f105 | 26 | |
23c9e63c DD |
27 | #include "win32.h" |
28 | #include "commctrl.h" | |
29 | ||
30 | #include <stdio.h> | |
31 | #include <stdlib.h> | |
32 | #include <errno.h> | |
33 | ||
34 | #include "dialog.h" | |
35 | #include "geturl.h" | |
36 | #include "resource.h" | |
37 | #include "netio.h" | |
38 | #include "msg.h" | |
ca9506cc RC |
39 | #include "io_stream.h" |
40 | #include "io_stream_memory.h" | |
2f9645a1 CV |
41 | #include "state.h" |
42 | #include "diskfull.h" | |
85b43844 | 43 | #include "mount.h" |
23c9e63c | 44 | |
ab57ceaa | 45 | #include "threebar.h" |
3c054baf RC |
46 | |
47 | #include "String++.h" | |
48 | ||
fc687221 RC |
49 | #include "Exception.h" |
50 | ||
74617327 RC |
51 | #include "LogSingleton.h" |
52 | ||
ab57ceaa RC |
53 | extern ThreeBarProgressPage Progress; |
54 | ||
23c9e63c | 55 | static int max_bytes = 0; |
7cefe128 | 56 | static int is_local_install = 0; |
23c9e63c | 57 | |
2f9645a1 CV |
58 | int total_download_bytes = 0; |
59 | int total_download_bytes_sofar = 0; | |
60 | ||
23c9e63c DD |
61 | static DWORD start_tics; |
62 | ||
63 | static void | |
3c054baf | 64 | init_dialog (String const &url, int length, HWND owner) |
23c9e63c | 65 | { |
7cefe128 RC |
66 | if (is_local_install) |
67 | return; | |
ab57ceaa | 68 | |
3c054baf RC |
69 | char const *temp = url.cstr(); |
70 | char const *sl = temp; | |
341988b9 | 71 | char const *cp; |
3c054baf | 72 | for (cp = sl; *cp; cp++) |
23c9e63c | 73 | if (*cp == '/' || *cp == '\\' || *cp == ':') |
b24c88b3 | 74 | sl = cp + 1; |
23c9e63c | 75 | max_bytes = length; |
ab57ceaa RC |
76 | Progress.SetText1("Downloading..."); |
77 | Progress.SetText2(sl); | |
78 | Progress.SetText3("Connecting..."); | |
79 | Progress.SetBar1(0); | |
1fd6d0a2 | 80 | start_tics = GetTickCount (); |
3c054baf | 81 | delete[] temp; |
23c9e63c DD |
82 | } |
83 | ||
84 | ||
85 | static void | |
86 | progress (int bytes) | |
87 | { | |
7cefe128 RC |
88 | if (is_local_install) |
89 | return; | |
23c9e63c | 90 | static char buf[100]; |
ab57ceaa | 91 | double kbps; |
c168185f | 92 | static unsigned int last_tics = 0; |
1fd6d0a2 | 93 | DWORD tics = GetTickCount (); |
b24c88b3 | 94 | if (tics == start_tics) // to prevent division by zero |
23c9e63c | 95 | return; |
b24c88b3 | 96 | if (tics < last_tics + 200) // to prevent flickering updates |
23c9e63c DD |
97 | return; |
98 | last_tics = tics; | |
99 | ||
ab57ceaa RC |
100 | kbps = ((double)bytes) / (double)(tics - start_tics); |
101 | if (max_bytes > 0) | |
23c9e63c | 102 | { |
ab57ceaa RC |
103 | int perc = (int)(100.0 * ((double)bytes) / (double)max_bytes); |
104 | Progress.SetBar1(bytes, max_bytes); | |
b7301c43 | 105 | sprintf (buf, "%d %% (%dk/%dk) %03.1f kb/s\n", |
b24c88b3 | 106 | perc, bytes / 1000, max_bytes / 1000, kbps); |
2f9645a1 | 107 | if (total_download_bytes > 0) |
fc687221 RC |
108 | Progress.SetBar2(total_download_bytes_sofar + bytes, |
109 | total_download_bytes); | |
23c9e63c DD |
110 | } |
111 | else | |
ab57ceaa | 112 | sprintf (buf, "%d %2.1f kb/s\n", bytes, kbps); |
23c9e63c | 113 | |
ab57ceaa | 114 | Progress.SetText3(buf); |
23c9e63c DD |
115 | } |
116 | ||
fc687221 RC |
117 | void |
118 | getUrlToStream (String const &_url, HWND owner, io_stream *output) | |
23c9e63c | 119 | { |
74617327 | 120 | log (LOG_BABBLE) << "getUrlToStream " << _url << endLog; |
7cefe128 | 121 | is_local_install = (source == IDC_SOURCE_CWD); |
ab57ceaa | 122 | init_dialog (_url, 0, owner); |
3c054baf | 123 | NetIO *n = NetIO::open (_url.cstr_oneuse()); |
23c9e63c DD |
124 | if (!n || !n->ok ()) |
125 | { | |
126 | delete n; | |
74617327 | 127 | log (LOG_BABBLE) << "getUrlToStream failed!" << endLog; |
fc687221 | 128 | throw new Exception ("__LINE__ __FILE__", "Error opening url", APPERR_IO_ERROR); |
23c9e63c DD |
129 | } |
130 | ||
131 | if (n->file_size) | |
132 | max_bytes = n->file_size; | |
133 | ||
341988b9 | 134 | int total_bytes = 0; |
23c9e63c DD |
135 | progress (0); |
136 | while (1) | |
137 | { | |
ca9506cc | 138 | char buf[2048]; |
4fe323f9 | 139 | ssize_t rlen, wlen; |
ca9506cc RC |
140 | rlen = n->read (buf, 2048); |
141 | if (rlen > 0) | |
4fe323f9 | 142 | { |
fc687221 | 143 | wlen = output->write (buf, rlen); |
4fe323f9 RC |
144 | if (wlen != rlen) |
145 | /* FIXME: Show an error message */ | |
146 | break; | |
147 | total_bytes += rlen; | |
148 | progress (total_bytes); | |
149 | } | |
ca9506cc RC |
150 | else |
151 | break; | |
23c9e63c | 152 | } |
fc687221 RC |
153 | if (n) |
154 | delete (n); | |
155 | /* reseeking is up to the recipient if desired */ | |
156 | } | |
23c9e63c | 157 | |
fc687221 RC |
158 | io_stream * |
159 | get_url_to_membuf (String const &_url, HWND owner) | |
160 | { | |
161 | io_stream_memory *membuf = new io_stream_memory (); | |
162 | try | |
163 | { | |
74617327 | 164 | log (LOG_BABBLE) << "get_url_to_membuf " << _url << endLog; |
fc687221 RC |
165 | getUrlToStream (_url, owner, membuf); |
166 | ||
167 | if (membuf->seek (0, IO_SEEK_SET)) | |
168 | { | |
169 | if (membuf) | |
170 | delete membuf; | |
74617327 | 171 | log (LOG_BABBLE) << "get_url_to_membuf(): seek (0) failed for membuf!" << endLog; |
fc687221 RC |
172 | return 0; |
173 | } | |
174 | return membuf; | |
175 | } | |
176 | catch (Exception *e) | |
c168185f | 177 | { |
fc687221 RC |
178 | if (e->errNo() != APPERR_IO_ERROR) |
179 | throw e; | |
74617327 | 180 | log (LOG_BABBLE) << "get_url_to_membuf failed!" << endLog; |
fc687221 | 181 | delete membuf; |
c168185f RC |
182 | return 0; |
183 | } | |
341988b9 RC |
184 | } |
185 | ||
3c054baf RC |
186 | // predicate: url has no '\0''s in it. |
187 | String | |
188 | get_url_to_string (String const &_url, HWND owner) | |
341988b9 | 189 | { |
ab57ceaa | 190 | io_stream *stream = get_url_to_membuf (_url, owner); |
341988b9 | 191 | if (!stream) |
3c054baf | 192 | return String(); |
341988b9 RC |
193 | size_t bytes = stream->get_size (); |
194 | if (!bytes) | |
195 | { | |
196 | /* zero length, or error retrieving length */ | |
197 | delete stream; | |
74617327 | 198 | log (LOG_BABBLE) << "get_url_to_string(): couldn't retrieve buffer size, or zero length buffer" << endLog; |
3c054baf | 199 | return String(); |
341988b9 | 200 | } |
3c054baf | 201 | char temp [bytes + 1]; |
341988b9 | 202 | /* membufs are quite safe */ |
3c054baf RC |
203 | stream->read (temp, bytes); |
204 | temp [bytes] = '\0'; | |
341988b9 | 205 | delete stream; |
3c054baf | 206 | return String(temp); |
23c9e63c DD |
207 | } |
208 | ||
209 | int | |
3c054baf | 210 | get_url_to_file (String const &_url, String const &_filename, int expected_length, |
ab57ceaa | 211 | HWND owner, BOOL allow_ftp_auth) |
23c9e63c | 212 | { |
74617327 | 213 | log (LOG_BABBLE) << "get_url_to_file " << _url << " " << _filename << endLog; |
2f9645a1 CV |
214 | if (total_download_bytes > 0) |
215 | { | |
3c054baf RC |
216 | int df = diskfull (get_root_dir ().cstr_oneuse()); |
217 | Progress.SetBar3(df); | |
2f9645a1 | 218 | } |
ab57ceaa | 219 | init_dialog (_url, expected_length, owner); |
23c9e63c | 220 | |
3c054baf | 221 | remove (_filename.cstr_oneuse()); /* but ignore errors */ |
23c9e63c | 222 | |
3c054baf | 223 | NetIO *n = NetIO::open (_url.cstr_oneuse(), allow_ftp_auth); |
23c9e63c DD |
224 | if (!n || !n->ok ()) |
225 | { | |
226 | delete n; | |
74617327 | 227 | log (LOG_BABBLE) << "get_url_to_file failed!" << endLog; |
23c9e63c DD |
228 | return 1; |
229 | } | |
230 | ||
3c054baf | 231 | FILE *f = fopen (_filename.cstr_oneuse(), "wb"); |
23c9e63c DD |
232 | if (!f) |
233 | { | |
b24c88b3 | 234 | const char *err = strerror (errno); |
23c9e63c DD |
235 | if (!err) |
236 | err = "(unknown error)"; | |
3c054baf | 237 | fatal (owner, IDS_ERR_OPEN_WRITE, _filename.cstr_oneuse(), err); |
23c9e63c DD |
238 | } |
239 | ||
240 | if (n->file_size) | |
241 | max_bytes = n->file_size; | |
242 | ||
243 | int total_bytes = 0; | |
244 | progress (0); | |
245 | while (1) | |
246 | { | |
4a83b7b0 | 247 | char buf[8192]; |
23c9e63c DD |
248 | int count; |
249 | count = n->read (buf, sizeof (buf)); | |
250 | if (count <= 0) | |
251 | break; | |
252 | fwrite (buf, 1, count, f); | |
253 | total_bytes += count; | |
254 | progress (total_bytes); | |
255 | } | |
256 | ||
2f9645a1 CV |
257 | total_download_bytes_sofar += total_bytes; |
258 | ||
23c9e63c | 259 | fclose (f); |
8e58f8fd RC |
260 | if (n) |
261 | delete n; | |
23c9e63c | 262 | |
2f9645a1 CV |
263 | if (total_download_bytes > 0) |
264 | { | |
3c054baf | 265 | int df = diskfull (get_root_dir ().cstr_oneuse()); |
ab57ceaa | 266 | Progress.SetBar3(df); |
2f9645a1 CV |
267 | } |
268 | ||
23c9e63c DD |
269 | return 0; |
270 | } | |
271 |