]> cygwin.com Git - cygwin-apps/setup.git/blame - geturl.cc
Support xz and lzma decompression via liblzma
[cygwin-apps/setup.git] / geturl.cc
CommitLineData
23c9e63c 1/*
ca9506cc
RC
2
3
85553593 4 * Copyright (c) 2000, 2001, Red Hat, Inc.
23c9e63c
DD
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
b24c88b3
RC
22#if 0
23static const char *cvsid =
24 "\n%%% $Id$\n";
25#endif
8507f105 26
23c9e63c
DD
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"
ca9506cc
RC
39#include "io_stream.h"
40#include "io_stream_memory.h"
2f9645a1
CV
41#include "state.h"
42#include "diskfull.h"
85b43844 43#include "mount.h"
23c9e63c 44
ab57ceaa 45#include "threebar.h"
3c054baf 46
fc687221
RC
47#include "Exception.h"
48
74617327
RC
49#include "LogSingleton.h"
50
966a9815
MB
51using namespace std;
52
ab57ceaa
RC
53extern ThreeBarProgressPage Progress;
54
23c9e63c 55static int max_bytes = 0;
7cefe128 56static int is_local_install = 0;
23c9e63c 57
2f9645a1
CV
58int total_download_bytes = 0;
59int total_download_bytes_sofar = 0;
60
23c9e63c
DD
61static DWORD start_tics;
62
63static void
966a9815 64init_dialog (const string &url, int length)
23c9e63c 65{
7cefe128
RC
66 if (is_local_install)
67 return;
ab57ceaa 68
966a9815 69 string::size_type divide = url.find_last_of('/');
23c9e63c 70 max_bytes = length;
ab57ceaa 71 Progress.SetText1("Downloading...");
966a9815
MB
72 Progress.SetText2((url.substr(divide + 1) + " from "
73 + url.substr(0, divide)).c_str());
ab57ceaa
RC
74 Progress.SetText3("Connecting...");
75 Progress.SetBar1(0);
1fd6d0a2 76 start_tics = GetTickCount ();
23c9e63c
DD
77}
78
79
80static void
81progress (int bytes)
82{
7cefe128
RC
83 if (is_local_install)
84 return;
23c9e63c 85 static char buf[100];
ab57ceaa 86 double kbps;
c168185f 87 static unsigned int last_tics = 0;
1fd6d0a2 88 DWORD tics = GetTickCount ();
b24c88b3 89 if (tics == start_tics) // to prevent division by zero
23c9e63c 90 return;
b24c88b3 91 if (tics < last_tics + 200) // to prevent flickering updates
23c9e63c
DD
92 return;
93 last_tics = tics;
94
ab57ceaa
RC
95 kbps = ((double)bytes) / (double)(tics - start_tics);
96 if (max_bytes > 0)
23c9e63c 97 {
ab57ceaa
RC
98 int perc = (int)(100.0 * ((double)bytes) / (double)max_bytes);
99 Progress.SetBar1(bytes, max_bytes);
22ade75c 100 sprintf (buf, "%d %% (%dk/%dk) %03.1f kB/s",
b24c88b3 101 perc, bytes / 1000, max_bytes / 1000, kbps);
2f9645a1 102 if (total_download_bytes > 0)
fc687221
RC
103 Progress.SetBar2(total_download_bytes_sofar + bytes,
104 total_download_bytes);
23c9e63c
DD
105 }
106 else
22ade75c 107 sprintf (buf, "%d %2.1f kB/s", bytes, kbps);
23c9e63c 108
ab57ceaa 109 Progress.SetText3(buf);
23c9e63c
DD
110}
111
f5d45c3b 112static void
966a9815 113getUrlToStream (const string &_url, io_stream *output)
23c9e63c 114{
74617327 115 log (LOG_BABBLE) << "getUrlToStream " << _url << endLog;
7cefe128 116 is_local_install = (source == IDC_SOURCE_CWD);
966a9815 117 init_dialog (_url, 0);
d2a3615c 118 NetIO *n = NetIO::open (_url.c_str());
23c9e63c
DD
119 if (!n || !n->ok ())
120 {
121 delete n;
74617327 122 log (LOG_BABBLE) << "getUrlToStream failed!" << endLog;
346627e7 123 throw new Exception (TOSTRING(__LINE__) " " __FILE__, "Error opening url", APPERR_IO_ERROR);
23c9e63c
DD
124 }
125
126 if (n->file_size)
127 max_bytes = n->file_size;
128
341988b9 129 int total_bytes = 0;
23c9e63c
DD
130 progress (0);
131 while (1)
132 {
ca9506cc 133 char buf[2048];
4fe323f9 134 ssize_t rlen, wlen;
ca9506cc
RC
135 rlen = n->read (buf, 2048);
136 if (rlen > 0)
4fe323f9 137 {
fc687221 138 wlen = output->write (buf, rlen);
4fe323f9
RC
139 if (wlen != rlen)
140 /* FIXME: Show an error message */
141 break;
142 total_bytes += rlen;
143 progress (total_bytes);
144 }
ca9506cc
RC
145 else
146 break;
23c9e63c 147 }
fc687221
RC
148 if (n)
149 delete (n);
150 /* reseeking is up to the recipient if desired */
151}
23c9e63c 152
fc687221 153io_stream *
966a9815 154get_url_to_membuf (const string &_url, HWND owner)
fc687221
RC
155{
156 io_stream_memory *membuf = new io_stream_memory ();
157 try
158 {
74617327 159 log (LOG_BABBLE) << "get_url_to_membuf " << _url << endLog;
966a9815 160 getUrlToStream (_url, membuf);
fc687221
RC
161
162 if (membuf->seek (0, IO_SEEK_SET))
163 {
164 if (membuf)
165 delete membuf;
74617327 166 log (LOG_BABBLE) << "get_url_to_membuf(): seek (0) failed for membuf!" << endLog;
fc687221
RC
167 return 0;
168 }
169 return membuf;
170 }
171 catch (Exception *e)
c168185f 172 {
fc687221
RC
173 if (e->errNo() != APPERR_IO_ERROR)
174 throw e;
74617327 175 log (LOG_BABBLE) << "get_url_to_membuf failed!" << endLog;
fc687221 176 delete membuf;
c168185f
RC
177 return 0;
178 }
341988b9
RC
179}
180
3c054baf 181// predicate: url has no '\0''s in it.
966a9815
MB
182string
183get_url_to_string (const string &_url, HWND owner)
341988b9 184{
ab57ceaa 185 io_stream *stream = get_url_to_membuf (_url, owner);
341988b9 186 if (!stream)
966a9815 187 return string();
341988b9
RC
188 size_t bytes = stream->get_size ();
189 if (!bytes)
190 {
191 /* zero length, or error retrieving length */
192 delete stream;
74617327 193 log (LOG_BABBLE) << "get_url_to_string(): couldn't retrieve buffer size, or zero length buffer" << endLog;
966a9815 194 return string();
341988b9 195 }
3c054baf 196 char temp [bytes + 1];
341988b9 197 /* membufs are quite safe */
3c054baf
RC
198 stream->read (temp, bytes);
199 temp [bytes] = '\0';
341988b9 200 delete stream;
966a9815 201 return string(temp);
23c9e63c
DD
202}
203
204int
966a9815
MB
205get_url_to_file (const string &_url,
206 const string &_filename,
f5d45c3b
MB
207 int expected_length,
208 HWND owner)
23c9e63c 209{
74617327 210 log (LOG_BABBLE) << "get_url_to_file " << _url << " " << _filename << endLog;
2f9645a1
CV
211 if (total_download_bytes > 0)
212 {
d2a3615c 213 int df = diskfull (get_root_dir ().c_str());
3c054baf 214 Progress.SetBar3(df);
2f9645a1 215 }
966a9815 216 init_dialog (_url, expected_length);
23c9e63c 217
d2a3615c 218 remove (_filename.c_str()); /* but ignore errors */
23c9e63c 219
d2a3615c 220 NetIO *n = NetIO::open (_url.c_str());
23c9e63c
DD
221 if (!n || !n->ok ())
222 {
223 delete n;
74617327 224 log (LOG_BABBLE) << "get_url_to_file failed!" << endLog;
23c9e63c
DD
225 return 1;
226 }
227
d2a3615c 228 FILE *f = fopen (_filename.c_str(), "wb");
23c9e63c
DD
229 if (!f)
230 {
b24c88b3 231 const char *err = strerror (errno);
23c9e63c
DD
232 if (!err)
233 err = "(unknown error)";
d2a3615c 234 fatal (owner, IDS_ERR_OPEN_WRITE, _filename.c_str(), err);
23c9e63c
DD
235 }
236
237 if (n->file_size)
238 max_bytes = n->file_size;
239
240 int total_bytes = 0;
241 progress (0);
242 while (1)
243 {
4a83b7b0 244 char buf[8192];
23c9e63c
DD
245 int count;
246 count = n->read (buf, sizeof (buf));
247 if (count <= 0)
248 break;
249 fwrite (buf, 1, count, f);
250 total_bytes += count;
251 progress (total_bytes);
252 }
253
2f9645a1
CV
254 total_download_bytes_sofar += total_bytes;
255
23c9e63c 256 fclose (f);
8e58f8fd
RC
257 if (n)
258 delete n;
23c9e63c 259
2f9645a1
CV
260 if (total_download_bytes > 0)
261 {
d2a3615c 262 int df = diskfull (get_root_dir ().c_str());
ab57ceaa 263 Progress.SetBar3(df);
2f9645a1
CV
264 }
265
23c9e63c
DD
266 return 0;
267}
268
This page took 0.077437 seconds and 5 git commands to generate.