]> cygwin.com Git - cygwin-apps/setup.git/blob - geturl.cc
2001-01-04 Gary R. Van Sickle <g.r.vansickle@worldnet.att.net>
[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 extern ThreeBarProgressPage Progress;
48
49 static int max_bytes = 0;
50 static int is_local_install = 0;
51
52 int total_download_bytes = 0;
53 int total_download_bytes_sofar = 0;
54
55 static DWORD start_tics;
56
57 static void
58 init_dialog (char const *url, int length, HWND owner)
59 {
60 if (is_local_install)
61 return;
62
63 char const *sl = url;
64 char const *cp;
65 for (cp = url; *cp; cp++)
66 if (*cp == '/' || *cp == '\\' || *cp == ':')
67 sl = cp + 1;
68 max_bytes = length;
69 Progress.SetText1("Downloading...");
70 Progress.SetText2(sl);
71 Progress.SetText3("Connecting...");
72 Progress.SetBar1(0);
73 start_tics = GetTickCount ();
74 }
75
76
77 static void
78 progress (int bytes)
79 {
80 if (is_local_install)
81 return;
82 static char buf[100];
83 double kbps;
84 static unsigned int last_tics = 0;
85 DWORD tics = GetTickCount ();
86 if (tics == start_tics) // to prevent division by zero
87 return;
88 if (tics < last_tics + 200) // to prevent flickering updates
89 return;
90 last_tics = tics;
91
92 kbps = ((double)bytes) / (double)(tics - start_tics);
93 if (max_bytes > 0)
94 {
95 int perc = (int)(100.0 * ((double)bytes) / (double)max_bytes);
96 Progress.SetBar1(bytes, max_bytes);
97 sprintf (buf, "%d %% (%dk/%dk) %03.1f kb/s\n",
98 perc, bytes / 1000, max_bytes / 1000, kbps);
99 if (total_download_bytes > 0)
100 {
101 Progress.SetBar2(total_download_bytes_sofar + bytes, total_download_bytes);
102 }
103 }
104 else
105 sprintf (buf, "%d %2.1f kb/s\n", bytes, kbps);
106
107 Progress.SetText3(buf);
108 }
109
110 io_stream *
111 get_url_to_membuf (char const *_url, HWND owner)
112 {
113 log (LOG_BABBLE, "get_url_to_membuf %s", _url);
114 is_local_install = (source == IDC_SOURCE_CWD);
115 init_dialog (_url, 0, owner);
116 NetIO *n = NetIO::open (_url);
117 if (!n || !n->ok ())
118 {
119 delete n;
120 log (LOG_BABBLE, "get_url_to_membuf failed!");
121 return 0;
122 }
123
124 if (n->file_size)
125 max_bytes = n->file_size;
126
127 io_stream_memory *membuf = new io_stream_memory ();
128
129 int total_bytes = 0;
130 progress (0);
131 while (1)
132 {
133 char buf[2048];
134 ssize_t rlen, wlen;
135 rlen = n->read (buf, 2048);
136 if (rlen > 0)
137 {
138 wlen = membuf->write (buf, rlen);
139 if (wlen != rlen)
140 /* FIXME: Show an error message */
141 break;
142 total_bytes += rlen;
143 progress (total_bytes);
144 }
145 else
146 break;
147 }
148
149 if (membuf->seek (0, IO_SEEK_SET))
150 {
151 if (n)
152 delete n;
153 if (membuf)
154 delete membuf;
155 log (LOG_BABBLE, "get_url_to_membuf(): seek (0) failed for membuf!");
156 return 0;
157 }
158
159 if (n)
160 delete n;
161 return membuf;
162 }
163
164 char *
165 get_url_to_string (char const *_url, HWND owner)
166 {
167 io_stream *stream = get_url_to_membuf (_url, owner);
168 if (!stream)
169 return 0;
170 size_t bytes = stream->get_size ();
171 if (!bytes)
172 {
173 /* zero length, or error retrieving length */
174 delete stream;
175 log (LOG_BABBLE, "get_url_to_string(): couldn't retrieve buffer size, or zero length buffer");
176 return 0;
177 }
178 char *rv = new char [bytes + 1];
179 if (!rv)
180 {
181 delete stream;
182 log (LOG_BABBLE, "get_url_to_string(): new failed for rv!");
183 return 0;
184 }
185 /* membufs are quite safe */
186 stream->read (rv, bytes);
187 rv [bytes] = '\0';
188 delete stream;
189 return rv;
190 }
191
192 int
193 get_url_to_file (char *_url, char *_filename, int expected_length,
194 HWND owner, BOOL allow_ftp_auth)
195 {
196 log (LOG_BABBLE, "get_url_to_file %s %s", _url, _filename);
197 if (total_download_bytes > 0)
198 {
199 int df = diskfull (get_root_dir ());
200 Progress.SetBar3(df);
201 }
202 init_dialog (_url, expected_length, owner);
203
204 remove (_filename); /* but ignore errors */
205
206 NetIO *n = NetIO::open (_url, 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, "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, 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 ());
249 Progress.SetBar3(df);
250 }
251
252 return 0;
253 }
254
This page took 0.043179 seconds and 5 git commands to generate.