]> cygwin.com Git - cygwin-apps/setup.git/blob - geturl.cc
2002-05-12 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 "io_stream.h"
40 #include "io_stream_memory.h"
41 #include "state.h"
42 #include "diskfull.h"
43 #include "mount.h"
44
45 #include "threebar.h"
46
47 #include "String++.h"
48
49 #include "Exception.h"
50
51 #include "LogSingleton.h"
52
53 extern ThreeBarProgressPage Progress;
54
55 static int max_bytes = 0;
56 static int is_local_install = 0;
57
58 int total_download_bytes = 0;
59 int total_download_bytes_sofar = 0;
60
61 static DWORD start_tics;
62
63 static void
64 init_dialog (String const &url, int length, HWND owner)
65 {
66 if (is_local_install)
67 return;
68
69 char const *temp = url.cstr();
70 char const *sl = temp;
71 char const *cp;
72 for (cp = sl; *cp; cp++)
73 if (*cp == '/' || *cp == '\\' || *cp == ':')
74 sl = cp + 1;
75 max_bytes = length;
76 Progress.SetText1("Downloading...");
77 Progress.SetText2(sl);
78 Progress.SetText3("Connecting...");
79 Progress.SetBar1(0);
80 start_tics = GetTickCount ();
81 delete[] temp;
82 }
83
84
85 static void
86 progress (int bytes)
87 {
88 if (is_local_install)
89 return;
90 static char buf[100];
91 double kbps;
92 static unsigned int last_tics = 0;
93 DWORD tics = GetTickCount ();
94 if (tics == start_tics) // to prevent division by zero
95 return;
96 if (tics < last_tics + 200) // to prevent flickering updates
97 return;
98 last_tics = tics;
99
100 kbps = ((double)bytes) / (double)(tics - start_tics);
101 if (max_bytes > 0)
102 {
103 int perc = (int)(100.0 * ((double)bytes) / (double)max_bytes);
104 Progress.SetBar1(bytes, max_bytes);
105 sprintf (buf, "%d %% (%dk/%dk) %03.1f kb/s\n",
106 perc, bytes / 1000, max_bytes / 1000, kbps);
107 if (total_download_bytes > 0)
108 Progress.SetBar2(total_download_bytes_sofar + bytes,
109 total_download_bytes);
110 }
111 else
112 sprintf (buf, "%d %2.1f kb/s\n", bytes, kbps);
113
114 Progress.SetText3(buf);
115 }
116
117 void
118 getUrlToStream (String const &_url, HWND owner, io_stream *output)
119 {
120 log (LOG_BABBLE) << "getUrlToStream " << _url << endLog;
121 is_local_install = (source == IDC_SOURCE_CWD);
122 init_dialog (_url, 0, owner);
123 NetIO *n = NetIO::open (_url.cstr_oneuse());
124 if (!n || !n->ok ())
125 {
126 delete n;
127 log (LOG_BABBLE) << "getUrlToStream failed!" << endLog;
128 throw new Exception ("__LINE__ __FILE__", "Error opening url", APPERR_IO_ERROR);
129 }
130
131 if (n->file_size)
132 max_bytes = n->file_size;
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 = output->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 if (n)
154 delete (n);
155 /* reseeking is up to the recipient if desired */
156 }
157
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 {
164 log (LOG_BABBLE) << "get_url_to_membuf " << _url << endLog;
165 getUrlToStream (_url, owner, membuf);
166
167 if (membuf->seek (0, IO_SEEK_SET))
168 {
169 if (membuf)
170 delete membuf;
171 log (LOG_BABBLE) << "get_url_to_membuf(): seek (0) failed for membuf!" << endLog;
172 return 0;
173 }
174 return membuf;
175 }
176 catch (Exception *e)
177 {
178 if (e->errNo() != APPERR_IO_ERROR)
179 throw e;
180 log (LOG_BABBLE) << "get_url_to_membuf failed!" << endLog;
181 delete membuf;
182 return 0;
183 }
184 }
185
186 // predicate: url has no '\0''s in it.
187 String
188 get_url_to_string (String const &_url, HWND owner)
189 {
190 io_stream *stream = get_url_to_membuf (_url, owner);
191 if (!stream)
192 return String();
193 size_t bytes = stream->get_size ();
194 if (!bytes)
195 {
196 /* zero length, or error retrieving length */
197 delete stream;
198 log (LOG_BABBLE) << "get_url_to_string(): couldn't retrieve buffer size, or zero length buffer" << endLog;
199 return String();
200 }
201 char temp [bytes + 1];
202 /* membufs are quite safe */
203 stream->read (temp, bytes);
204 temp [bytes] = '\0';
205 delete stream;
206 return String(temp);
207 }
208
209 int
210 get_url_to_file (String const &_url, String const &_filename, int expected_length,
211 HWND owner, BOOL allow_ftp_auth)
212 {
213 log (LOG_BABBLE) << "get_url_to_file " << _url << " " << _filename << endLog;
214 if (total_download_bytes > 0)
215 {
216 int df = diskfull (get_root_dir ().cstr_oneuse());
217 Progress.SetBar3(df);
218 }
219 init_dialog (_url, expected_length, owner);
220
221 remove (_filename.cstr_oneuse()); /* but ignore errors */
222
223 NetIO *n = NetIO::open (_url.cstr_oneuse(), allow_ftp_auth);
224 if (!n || !n->ok ())
225 {
226 delete n;
227 log (LOG_BABBLE) << "get_url_to_file failed!" << endLog;
228 return 1;
229 }
230
231 FILE *f = fopen (_filename.cstr_oneuse(), "wb");
232 if (!f)
233 {
234 const char *err = strerror (errno);
235 if (!err)
236 err = "(unknown error)";
237 fatal (owner, IDS_ERR_OPEN_WRITE, _filename.cstr_oneuse(), err);
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 {
247 char buf[8192];
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
257 total_download_bytes_sofar += total_bytes;
258
259 fclose (f);
260 if (n)
261 delete n;
262
263 if (total_download_bytes > 0)
264 {
265 int df = diskfull (get_root_dir ().cstr_oneuse());
266 Progress.SetBar3(df);
267 }
268
269 return 0;
270 }
271
This page took 0.044895 seconds and 5 git commands to generate.