]> cygwin.com Git - cygwin-apps/setup.git/blob - geturl.cc
2001-11-13 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / geturl.cc
1 /*
2 * Copyright (c) 2000, 2001, Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by DJ Delorie <dj@cygnus.com>
13 *
14 */
15
16 /* The purpose of this file is to act as a pretty interface to
17 netio.cc. We add a progress dialog and some convenience functions
18 (like collect to string or file */
19
20 #if 0
21 static const char *cvsid =
22 "\n%%% $Id$\n";
23 #endif
24
25 #include "win32.h"
26 #include "commctrl.h"
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <errno.h>
31
32 #include "dialog.h"
33 #include "geturl.h"
34 #include "resource.h"
35 #include "netio.h"
36 #include "msg.h"
37 #include "log.h"
38 #include "state.h"
39 #include "diskfull.h"
40 #include "mount.h"
41
42 static HWND gw_dialog = 0;
43 static HWND gw_url = 0;
44 static HWND gw_rate = 0;
45 static HWND gw_progress = 0;
46 static HWND gw_pprogress = 0;
47 static HWND gw_iprogress = 0;
48 static HWND gw_progress_text = 0;
49 static HWND gw_pprogress_text = 0;
50 static HWND gw_iprogress_text = 0;
51 static HANDLE init_event;
52 static int max_bytes = 0;
53 static int is_local_install = 0;
54
55 int total_download_bytes = 0;
56 int total_download_bytes_sofar = 0;
57
58 static BOOL
59 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
60 {
61 switch (id)
62 {
63 case IDCANCEL:
64 exit_setup (0);
65 }
66 return 0;
67 }
68
69 static BOOL CALLBACK
70 dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
71 {
72 switch (message)
73 {
74 case WM_INITDIALOG:
75 gw_dialog = h;
76 gw_url = GetDlgItem (h, IDC_DLS_URL);
77 gw_rate = GetDlgItem (h, IDC_DLS_RATE);
78 gw_progress = GetDlgItem (h, IDC_DLS_PROGRESS);
79 gw_pprogress = GetDlgItem (h, IDC_DLS_PPROGRESS);
80 gw_iprogress = GetDlgItem (h, IDC_DLS_IPROGRESS);
81 gw_progress_text = GetDlgItem (h, IDC_DLS_PROGRESS_TEXT);
82 gw_pprogress_text = GetDlgItem (h, IDC_DLS_PPROGRESS_TEXT);
83 gw_iprogress_text = GetDlgItem (h, IDC_DLS_IPROGRESS_TEXT);
84 SetEvent (init_event);
85 return TRUE;
86 case WM_COMMAND:
87 return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
88 }
89 return FALSE;
90 }
91
92 static WINAPI DWORD
93 dialog (void *)
94 {
95 MSG m;
96 HWND local_gw_dialog =
97 CreateDialog (hinstance, MAKEINTRESOURCE (IDD_DLSTATUS),
98 0, dialog_proc);
99 ShowWindow (local_gw_dialog, SW_SHOWNORMAL);
100 UpdateWindow (local_gw_dialog);
101 while (GetMessage (&m, 0, 0, 0) > 0)
102 {
103 TranslateMessage (&m);
104 DispatchMessage (&m);
105 }
106 return 0;
107 }
108
109 static DWORD start_tics;
110
111 static void
112 init_dialog (char *url, int length)
113 {
114 if (is_local_install)
115 return;
116 if (gw_dialog == 0)
117 {
118 DWORD tid;
119 HANDLE thread;
120 init_event = CreateEvent (0, 0, 0, 0);
121 thread = CreateThread (0, 0, dialog, 0, 0, &tid);
122 WaitForSingleObject (init_event, 1000);
123 CloseHandle (init_event);
124 SendMessage (gw_progress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
125 SendMessage (gw_pprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
126 SendMessage (gw_iprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
127 }
128 char *sl = url, *cp;
129 for (cp = url; *cp; cp++)
130 if (*cp == '/' || *cp == '\\' || *cp == ':')
131 sl = cp + 1;
132 max_bytes = length;
133 SetWindowText (gw_url, sl);
134 SetWindowText (gw_rate, "Connecting...");
135 SendMessage (gw_progress, PBM_SETPOS, (WPARAM) 0, 0);
136 ShowWindow (gw_progress, (length > 0) ? SW_SHOW : SW_HIDE);
137 if (length > 0)
138 SetWindowText (gw_progress_text, "Package");
139 else
140 SetWindowText (gw_progress_text, " ");
141 ShowWindow (gw_pprogress, (total_download_bytes > 0) ? SW_SHOW : SW_HIDE);
142 if (total_download_bytes > 0)
143 {
144 SetWindowText (gw_pprogress_text, "Total");
145 SetWindowText (gw_iprogress_text, "Disk");
146 }
147 else
148 {
149 SetWindowText (gw_pprogress_text, " ");
150 SetWindowText (gw_iprogress_text, " ");
151 }
152 ShowWindow (gw_iprogress, (total_download_bytes > 0) ? SW_SHOW : SW_HIDE);
153 ShowWindow (gw_dialog, SW_SHOWNORMAL);
154 start_tics = GetTickCount ();
155 }
156
157
158 static void
159 progress (int bytes)
160 {
161 if (is_local_install)
162 return;
163 static char buf[100];
164 int kbps;
165 static unsigned int last_tics = 0;
166 DWORD tics = GetTickCount ();
167 if (tics == start_tics) // to prevent division by zero
168 return;
169 if (tics < last_tics + 200) // to prevent flickering updates
170 return;
171 last_tics = tics;
172
173 kbps = bytes / (tics - start_tics);
174 ShowWindow (gw_progress, (max_bytes > 0) ? SW_SHOW : SW_HIDE);
175 ShowWindow (gw_pprogress, (total_download_bytes > 0) ? SW_SHOW : SW_HIDE);
176 ShowWindow (gw_iprogress, (total_download_bytes > 0) ? SW_SHOW : SW_HIDE);
177 if (max_bytes > 100)
178 {
179 int perc = bytes / (max_bytes / 100);
180 SendMessage (gw_progress, PBM_SETPOS, (WPARAM) perc, 0);
181 sprintf (buf, "%3d %% (%dk/%dk) %d kb/s\n",
182 perc, bytes / 1000, max_bytes / 1000, kbps);
183 if (total_download_bytes > 0)
184 {
185 int totalperc =
186 (total_download_bytes_sofar +
187 bytes) / (total_download_bytes / 100);
188 SendMessage (gw_pprogress, PBM_SETPOS, (WPARAM) totalperc, 0);
189 }
190 }
191 else
192 sprintf (buf, "%d %d kb/s\n", bytes, kbps);
193
194 SetWindowText (gw_rate, buf);
195 }
196
197 struct GUBuf
198 {
199 GUBuf *next;
200 int count;
201 char buf[2000];
202 };
203
204 char *
205 get_url_to_string (char *_url)
206 {
207 log (LOG_BABBLE, "get_url_to_string %s", _url);
208 is_local_install = (source == IDC_SOURCE_CWD);
209 init_dialog (_url, 0);
210 NetIO *n = NetIO::open (_url);
211 if (!n || !n->ok ())
212 {
213 delete n;
214 log (LOG_BABBLE, "get_url_to_string failed!");
215 return 0;
216 }
217
218 if (n->file_size)
219 max_bytes = n->file_size;
220
221 GUBuf *bufs = 0;
222 GUBuf **nextp = &bufs;
223 int total_bytes = 1; /* for the NUL */
224 progress (0);
225 while (1)
226 {
227 GUBuf *b = new GUBuf;
228 *nextp = b;
229 b->next = 0;
230 nextp = &(b->next);
231
232 b->count = n->read (b->buf, sizeof (b->buf));
233 if (b->count <= 0)
234 break;
235 total_bytes += b->count;
236 progress (total_bytes);
237 }
238
239 char *rv = (char *) malloc (total_bytes);
240 if (NULL == rv)
241 {
242 if (n)
243 delete n;
244 log (LOG_BABBLE, "get_url_to_string(): malloc failed for rv!");
245 return 0;
246 }
247 char *rvp = rv;
248 while (bufs && bufs->count > 0)
249 {
250 GUBuf *tmp = bufs->next;
251 memcpy (rvp, bufs->buf, bufs->count);
252 rvp += bufs->count;
253 delete bufs;
254 bufs = tmp;
255 }
256 *rvp = 0;
257 if (n)
258 delete n;
259 return rv;
260 }
261
262 int
263 get_url_to_file (char *_url, char *_filename, int expected_length,
264 BOOL allow_ftp_auth)
265 {
266 log (LOG_BABBLE, "get_url_to_file %s %s", _url, _filename);
267 if (total_download_bytes > 0)
268 {
269 int df = diskfull (get_root_dir ());
270 SendMessage (gw_iprogress, PBM_SETPOS, (WPARAM) df, 0);
271 }
272 init_dialog (_url, expected_length);
273
274 remove (_filename); /* but ignore errors */
275
276 NetIO *n = NetIO::open (_url, allow_ftp_auth);
277 if (!n || !n->ok ())
278 {
279 delete n;
280 log (LOG_BABBLE, "get_url_to_file failed!");
281 return 1;
282 }
283
284 FILE *f = fopen (_filename, "wb");
285 if (!f)
286 {
287 const char *err = strerror (errno);
288 if (!err)
289 err = "(unknown error)";
290 fatal (IDS_ERR_OPEN_WRITE, _filename, err);
291 }
292
293 if (n->file_size)
294 max_bytes = n->file_size;
295
296 int total_bytes = 0;
297 progress (0);
298 while (1)
299 {
300 char buf[8192];
301 int count;
302 count = n->read (buf, sizeof (buf));
303 if (count <= 0)
304 break;
305 fwrite (buf, 1, count, f);
306 total_bytes += count;
307 progress (total_bytes);
308 }
309
310 total_download_bytes_sofar += total_bytes;
311
312 fclose (f);
313 if (n)
314 delete n;
315
316 if (total_download_bytes > 0)
317 {
318 int df = diskfull (get_root_dir ());
319 SendMessage (gw_iprogress, PBM_SETPOS, (WPARAM) df, 0);
320 }
321
322 return 0;
323 }
324
325 void
326 dismiss_url_status_dialog ()
327 {
328 if (!is_local_install)
329 ShowWindow (gw_dialog, SW_HIDE);
330 }
This page took 0.113039 seconds and 6 git commands to generate.