]> cygwin.com Git - cygwin-apps/setup.git/blob - geturl.cc
2002-02-19 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / geturl.cc
1 /*
2
3
4 * Copyright (c) 2000, 2001, Red Hat, Inc.
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
22 #if 0
23 static const char *cvsid =
24 "\n%%% $Id$\n";
25 #endif
26
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"
39 #include "log.h"
40 #include "io_stream.h"
41 #include "io_stream_memory.h"
42 #include "state.h"
43 #include "diskfull.h"
44 #include "mount.h"
45
46 #include "threebar.h"
47
48 #include "String++.h"
49
50 extern ThreeBarProgressPage Progress;
51
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 DWORD start_tics;
59
60 static void
61 init_dialog (String const &url, int length, HWND owner)
62 {
63 if (is_local_install)
64 return;
65
66 char const *temp = url.cstr();
67 char const *sl = temp;
68 char const *cp;
69 for (cp = sl; *cp; cp++)
70 if (*cp == '/' || *cp == '\\' || *cp == ':')
71 sl = cp + 1;
72 max_bytes = length;
73 Progress.SetText1("Downloading...");
74 Progress.SetText2(sl);
75 Progress.SetText3("Connecting...");
76 Progress.SetBar1(0);
77 start_tics = GetTickCount ();
78 delete[] temp;
79 }
80
81
82 static void
83 progress (int bytes)
84 {
85 if (is_local_install)
86 return;
87 static char buf[100];
88 double kbps;
89 static unsigned int last_tics = 0;
90 DWORD tics = GetTickCount ();
91 if (tics == start_tics) // to prevent division by zero
92 return;
93 if (tics < last_tics + 200) // to prevent flickering updates
94 return;
95 last_tics = tics;
96
97 kbps = ((double)bytes) / (double)(tics - start_tics);
98 if (max_bytes > 0)
99 {
100 int perc = (int)(100.0 * ((double)bytes) / (double)max_bytes);
101 Progress.SetBar1(bytes, max_bytes);
102 sprintf (buf, "%d %% (%dk/%dk) %03.1f kb/s\n",
103 perc, bytes / 1000, max_bytes / 1000, kbps);
104 if (total_download_bytes > 0)
105 {
106 Progress.SetBar2(total_download_bytes_sofar + bytes, total_download_bytes);
107 }
108 }
109 else
110 sprintf (buf, "%d %2.1f kb/s\n", bytes, kbps);
111
112 Progress.SetText3(buf);
113 }
114
115 io_stream *
116 get_url_to_membuf (String const &_url, HWND owner)
117 {
118 log (LOG_BABBLE, String ("get_url_to_membuf ") + _url);
119 is_local_install = (source == IDC_SOURCE_CWD);
120 init_dialog (_url, 0, owner);
121 NetIO *n = NetIO::open (_url.cstr_oneuse());
122 if (!n || !n->ok ())
123 {
124 delete n;
125 log (LOG_BABBLE, "get_url_to_membuf failed!");
126 return 0;
127 }
128
129 if (n->file_size)
130 max_bytes = n->file_size;
131
132 io_stream_memory *membuf = new io_stream_memory ();
133
134 int total_bytes = 0;
135 progress (0);
136 while (1)
137 {
138 char buf[2048];
139 ssize_t rlen, wlen;
140 rlen = n->read (buf, 2048);
141 if (rlen > 0)
142 {
143 wlen = membuf->write (buf, rlen);
144 if (wlen != rlen)
145 /* FIXME: Show an error message */
146 break;
147 total_bytes += rlen;
148 progress (total_bytes);
149 }
150 else
151 break;
152 }
153
154 if (membuf->seek (0, IO_SEEK_SET))
155 {
156 if (n)
157 delete n;
158 if (membuf)
159 delete membuf;
160 log (LOG_BABBLE, "get_url_to_membuf(): seek (0) failed for membuf!");
161 return 0;
162 }
163
164 if (n)
165 delete n;
166 return membuf;
167 }
168
169 // predicate: url has no '\0''s in it.
170 String
171 get_url_to_string (String const &_url, HWND owner)
172 {
173 io_stream *stream = get_url_to_membuf (_url, owner);
174 if (!stream)
175 return String();
176 size_t bytes = stream->get_size ();
177 if (!bytes)
178 {
179 /* zero length, or error retrieving length */
180 delete stream;
181 log (LOG_BABBLE, "get_url_to_string(): couldn't retrieve buffer size, or zero length buffer");
182 return String();
183 }
184 char temp [bytes + 1];
185 /* membufs are quite safe */
186 stream->read (temp, bytes);
187 temp [bytes] = '\0';
188 delete stream;
189 return String(temp);
190 }
191
192 int
193 get_url_to_file (String const &_url, String const &_filename, int expected_length,
194 HWND owner, BOOL allow_ftp_auth)
195 {
196 log (LOG_BABBLE, String ("get_url_to_file ") + _url + " " + _filename);
197 if (total_download_bytes > 0)
198 {
199 int df = diskfull (get_root_dir ().cstr_oneuse());
200 Progress.SetBar3(df);
201 }
202 init_dialog (_url, expected_length, owner);
203
204 remove (_filename.cstr_oneuse()); /* but ignore errors */
205
206 NetIO *n = NetIO::open (_url.cstr_oneuse(), allow_ftp_auth);
207 if (!n || !n->ok ())
208 {
209 delete n;
210 log (LOG_BABBLE, "get_url_to_file failed!");
211 return 1;
212 }
213
214 FILE *f = fopen (_filename.cstr_oneuse(), "wb");
215 if (!f)
216 {
217 const char *err = strerror (errno);
218 if (!err)
219 err = "(unknown error)";
220 fatal (owner, IDS_ERR_OPEN_WRITE, _filename.cstr_oneuse(), err);
221 }
222
223 if (n->file_size)
224 max_bytes = n->file_size;
225
226 int total_bytes = 0;
227 progress (0);
228 while (1)
229 {
230 char buf[8192];
231 int count;
232 count = n->read (buf, sizeof (buf));
233 if (count <= 0)
234 break;
235 fwrite (buf, 1, count, f);
236 total_bytes += count;
237 progress (total_bytes);
238 }
239
240 total_download_bytes_sofar += total_bytes;
241
242 fclose (f);
243 if (n)
244 delete n;
245
246 if (total_download_bytes > 0)
247 {
248 int df = diskfull (get_root_dir ().cstr_oneuse());
249 Progress.SetBar3(df);
250 }
251
252 return 0;
253 }
254
This page took 0.043716 seconds and 5 git commands to generate.