comparison netinstall/geturl.cc @ 448:3078fd1074e8 r21-2-39

Import from CVS: tag r21-2-39
author cvs
date Mon, 13 Aug 2007 11:38:25 +0200
parents
children 42a8626b741e
comparison
equal deleted inserted replaced
447:4fc5f13f3bd3 448:3078fd1074e8
1 /*
2 * Copyright (c) 2000, 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 #include "win32.h"
21 #include "commctrl.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <errno.h>
26
27 #include "dialog.h"
28 #include "geturl.h"
29 #include "resource.h"
30 #include "netio.h"
31 #include "msg.h"
32 #include "log.h"
33
34 static int is_showing = 0;
35 static HWND gw_dialog = 0;
36 static HWND gw_url = 0;
37 static HWND gw_rate = 0;
38 static HWND gw_progress = 0;
39 static HANDLE init_event;
40 static int max_bytes = 0;
41
42 static BOOL
43 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
44 {
45 switch (id)
46 {
47 case IDCANCEL:
48 exit_setup (0);
49 }
50 return FALSE;
51 }
52
53 static BOOL CALLBACK
54 dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
55 {
56 switch (message)
57 {
58 case WM_INITDIALOG:
59 gw_dialog = h;
60 gw_url = GetDlgItem (h, IDC_DLS_URL);
61 gw_rate = GetDlgItem (h, IDC_DLS_RATE);
62 gw_progress = GetDlgItem (h, IDC_DLS_PROGRESS);
63 SetEvent (init_event);
64 return FALSE;
65 case WM_COMMAND:
66 return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
67 }
68 return FALSE;
69 }
70
71 static DWORD WINAPI
72 dialog (void *)
73 {
74 MSG m;
75 HWND gw_dialog = CreateDialog (hinstance, MAKEINTRESOURCE (IDD_DLSTATUS),
76 0, dialog_proc);
77 ShowWindow (gw_dialog, SW_SHOWNORMAL);
78 UpdateWindow (gw_dialog);
79 while (GetMessage (&m, 0, 0, 0) > 0) {
80 TranslateMessage (&m);
81 DispatchMessage (&m);
82 }
83 return FALSE;
84 }
85
86 static DWORD start_tics;
87
88 static void
89 init_dialog (char *url, int length)
90 {
91 if (gw_dialog == 0)
92 {
93 DWORD tid;
94 HANDLE thread;
95 init_event = CreateEvent (0, 0, 0, 0);
96 thread = CreateThread (0, 0, dialog, 0, 0, &tid);
97 WaitForSingleObject (init_event, 1000);
98 CloseHandle (init_event);
99 SendMessage (gw_progress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
100 is_showing = 0;
101 }
102 char *sl=url, *cp;
103 for (cp=url; *cp; cp++)
104 if (*cp == '/' || *cp == '\\' || *cp == ':')
105 sl = cp+1;
106 max_bytes = length;
107 SetWindowText (gw_url, sl);
108 SetWindowText (gw_rate, "Connecting...");
109 SendMessage (gw_progress, PBM_SETPOS, (WPARAM) 0, 0);
110 ShowWindow (gw_progress, (length > 0) ? SW_SHOW : SW_HIDE);
111 ShowWindow (gw_dialog, SW_SHOWNORMAL);
112 if (!is_showing)
113 {
114 SetForegroundWindow (gw_dialog);
115 is_showing = 1;
116 }
117 start_tics = GetTickCount ();
118 }
119
120
121 static void
122 progress (int bytes)
123 {
124 static char buf[100];
125 int kbps;
126 static DWORD last_tics = 0;
127 DWORD tics = GetTickCount ();
128 if (tics == start_tics) // to prevent division by zero
129 return;
130 if (tics < last_tics + 200) // to prevent flickering updates
131 return;
132 last_tics = tics;
133
134 kbps = bytes / (tics - start_tics);
135 ShowWindow (gw_progress, (max_bytes > 0) ? SW_SHOW : SW_HIDE);
136 if (max_bytes > 100)
137 {
138 int perc = bytes / (max_bytes / 100);
139 SendMessage (gw_progress, PBM_SETPOS, (WPARAM) perc, 0);
140 sprintf (buf, "%3d %% (%dk/%dk) %d kb/s\n",
141 perc, bytes/1000, max_bytes/1000, kbps);
142 }
143 else
144 sprintf (buf, "%d %d kb/s\n", bytes, kbps);
145
146 SetWindowText (gw_rate, buf);
147 }
148
149 struct GUBuf {
150 GUBuf *next;
151 int count;
152 char buf[2000];
153 };
154
155 char *
156 get_url_to_string (char *_url)
157 {
158 log (LOG_BABBLE, "get_url_to_string %s", _url);
159 init_dialog (_url, 0);
160 NetIO *n = NetIO::open (_url);
161 if (!n || !n->ok ())
162 {
163 delete n;
164 log (LOG_BABBLE, "get_url_to_string failed!");
165 return 0;
166 }
167
168 if (n->file_size)
169 max_bytes = n->file_size;
170
171 GUBuf *bufs = 0;
172 GUBuf **nextp = &bufs;
173 int total_bytes = 1; /* for the NUL */
174 progress (0);
175 while (1)
176 {
177 GUBuf *b = new GUBuf;
178 *nextp = b;
179 b->next = 0;
180 nextp = &(b->next);
181
182 b->count = n->read (b->buf, sizeof (b->buf));
183 if (b->count <= 0)
184 break;
185 total_bytes += b->count;
186 progress (total_bytes);
187 }
188
189 char *rv = (char *) malloc (total_bytes);
190 char *rvp = rv;
191 while (bufs && bufs->count > 0)
192 {
193 GUBuf *tmp = bufs->next;
194 memcpy (rvp, bufs->buf, bufs->count);
195 rvp += bufs->count;
196 delete bufs;
197 bufs = tmp;
198 }
199 *rvp = 0;
200 return rv;
201 }
202
203 int
204 get_url_to_file (char *_url, char *_filename, int expected_length)
205 {
206 log (LOG_BABBLE, "get_url_to_file %s %s", _url, _filename);
207 init_dialog (_url, expected_length);
208
209 remove (_filename); /* but ignore errors */
210
211 NetIO *n = NetIO::open (_url);
212 if (!n || !n->ok ())
213 {
214 delete n;
215 log (LOG_BABBLE, "get_url_to_file failed!");
216 return 1;
217 }
218
219 FILE *f = fopen (_filename, "wb");
220 if (!f)
221 {
222 char *err = strerror (errno);
223 if (!err)
224 err = "(unknown error)";
225 fatal (IDS_ERR_OPEN_WRITE, _filename, err);
226 }
227
228 if (n->file_size)
229 max_bytes = n->file_size;
230
231 int total_bytes = 0;
232 progress (0);
233 while (1)
234 {
235 char buf[8192];
236 int count;
237 count = n->read (buf, sizeof (buf));
238 if (count <= 0)
239 break;
240 fwrite (buf, 1, count, f);
241 total_bytes += count;
242 progress (total_bytes);
243 }
244
245 fclose (f);
246
247 return 0;
248 }
249
250 void
251 dismiss_url_status_dialog ()
252 {
253 ShowWindow (gw_dialog, SW_HIDE);
254 is_showing = 0;
255 }