]> cygwin.com Git - cygwin-apps/setup.git/blob - geturl.cc
Added dpiAwareness element to manifest
[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 #include "win32.h"
23 #include "commctrl.h"
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <errno.h>
28
29 #include "dialog.h"
30 #include "geturl.h"
31 #include "resource.h"
32 #include "netio.h"
33 #include "msg.h"
34 #include "io_stream.h"
35 #include "io_stream_memory.h"
36 #include "state.h"
37 #include "diskfull.h"
38 #include "mount.h"
39 #include "filemanip.h"
40
41 #include "threebar.h"
42
43 #include "Exception.h"
44
45 #include "LogSingleton.h"
46
47 extern ThreeBarProgressPage Progress;
48
49 static int max_bytes = 0;
50 static int is_local_install = 0;
51
52 long long int total_download_bytes = 0;
53 long long int total_download_bytes_sofar = 0;
54
55 static DWORD start_tics;
56
57 static void
58 init_dialog (const std::string &url, int length)
59 {
60 if (is_local_install)
61 return;
62
63 std::string::size_type divide = url.find_last_of('/');
64 max_bytes = length;
65 Progress.SetText1(IDS_PROGRESS_DOWNLOADING);
66 std::wstring fmt = LoadStringW(IDS_PROGRESS_DOWNLOADING_FROM);
67 std::wstring s = format(fmt,
68 url.substr(divide + 1).c_str(),
69 url.substr(0, divide).c_str());
70 Progress.SetText2(s.c_str());
71 Progress.SetText3(IDS_PROGRESS_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",
98 perc, bytes / 1000, max_bytes / 1000, kbps);
99 if (total_download_bytes > 0)
100 Progress.SetBar2(total_download_bytes_sofar + bytes,
101 total_download_bytes);
102 }
103 else
104 sprintf (buf, "%d %2.1f kB/s", bytes, kbps);
105
106 Progress.SetText3(buf);
107 }
108
109 static void
110 getUrlToStream (const std::string &_url, io_stream *output)
111 {
112 is_local_install = (source == IDC_SOURCE_LOCALDIR);
113 init_dialog (_url, 0);
114 NetIO *n = NetIO::open (_url.c_str(), true);
115 if (!n || !n->ok ())
116 {
117 delete n;
118 throw new Exception (TOSTRING(__LINE__) " " __FILE__, "Error opening url", APPERR_IO_ERROR);
119 }
120
121 if (n->file_size)
122 max_bytes = n->file_size;
123
124 int total_bytes = 0;
125 progress (0);
126 while (1)
127 {
128 char buf[2048];
129 ssize_t rlen, wlen;
130 rlen = n->read (buf, 2048);
131 if (rlen > 0)
132 {
133 wlen = output->write (buf, rlen);
134 if (wlen != rlen)
135 /* FIXME: Show an error message */
136 break;
137 total_bytes += rlen;
138 progress (total_bytes);
139 }
140 else
141 break;
142 }
143 if (n)
144 delete (n);
145 /* reseeking is up to the recipient if desired */
146
147 Log (LOG_BABBLE) << "Fetched URL: " << _url << endLog;
148 }
149
150 io_stream *
151 get_url_to_membuf (const std::string &_url, HWND owner)
152 {
153 io_stream_memory *membuf = new io_stream_memory ();
154 try
155 {
156 getUrlToStream (_url, membuf);
157
158 if (membuf->seek (0, IO_SEEK_SET))
159 {
160 if (membuf)
161 delete membuf;
162 Log (LOG_BABBLE) << "get_url_to_membuf(): seek (0) failed for membuf!" << endLog;
163 return 0;
164 }
165 return membuf;
166 }
167 catch (Exception *e)
168 {
169 if (e->errNo() != APPERR_IO_ERROR)
170 throw e;
171 delete membuf;
172 return 0;
173 }
174 }
175
176 // predicate: url has no '\0''s in it.
177 std::string
178 get_url_to_string (const std::string &_url, HWND owner)
179 {
180 io_stream *stream = get_url_to_membuf (_url, owner);
181 if (!stream)
182 return std::string();
183 size_t bytes = stream->get_size ();
184 if (!bytes)
185 {
186 /* zero length, or error retrieving length */
187 delete stream;
188 Log (LOG_BABBLE) << "get_url_to_string(): couldn't retrieve buffer size, or zero length buffer" << endLog;
189 return std::string();
190 }
191 char temp [bytes + 1];
192 /* membufs are quite safe */
193 stream->read (temp, bytes);
194 temp [bytes] = '\0';
195 delete stream;
196 return std::string(temp);
197 }
198
199 int
200 get_url_to_file (const std::string &_url,
201 const std::string &_filename,
202 int expected_length,
203 HWND owner)
204 {
205 Log (LOG_BABBLE) << "get_url_to_file " << _url << " " << _filename << endLog;
206 if (total_download_bytes > 0)
207 {
208 int df = diskfull (get_root_dir ().c_str());
209 Progress.SetBar3(df);
210 }
211 init_dialog (_url, expected_length);
212
213 remove (_filename.c_str()); /* but ignore errors */
214
215 NetIO *n = NetIO::open (_url.c_str(), false);
216 if (!n || !n->ok ())
217 {
218 delete n;
219 return 1;
220 }
221
222 FILE *f = nt_fopen (_filename.c_str(), "wb");
223 if (!f)
224 {
225 const char *err = strerror (errno);
226 if (!err)
227 err = "(unknown error)";
228 fatal (owner, IDS_ERR_OPEN_WRITE, _filename.c_str(), err);
229 }
230
231 if (n->file_size)
232 max_bytes = n->file_size;
233
234 int total_bytes = 0;
235 progress (0);
236 while (1)
237 {
238 char buf[8192];
239 int count;
240 count = n->read (buf, sizeof (buf));
241 if (count <= 0)
242 break;
243 fwrite (buf, 1, count, f);
244 total_bytes += count;
245 progress (total_bytes);
246 }
247
248 total_download_bytes_sofar += total_bytes;
249
250 fclose (f);
251 if (n)
252 delete n;
253
254 if (total_download_bytes > 0)
255 {
256 int df = diskfull (get_root_dir ().c_str());
257 Progress.SetBar3(df);
258 }
259 Progress.SetText3("");
260
261 return 0;
262 }
263
This page took 0.045297 seconds and 6 git commands to generate.