]>
Commit | Line | Data |
---|---|---|
23c9e63c DD |
1 | /* |
2 | * Copyright (c) 2000, Red Hat, Inc. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * A copy of the GNU General Public License can be found at | |
10 | * http://www.gnu.org/ | |
11 | * | |
12 | * Written by DJ Delorie <dj@cygnus.com> | |
13 | * | |
14 | */ | |
15 | ||
16 | /* The purpose of this file is to get the list of mirror sites and ask | |
17 | the user which mirror site they want to download from. */ | |
18 | ||
b24c88b3 RC |
19 | #if 0 |
20 | static const char *cvsid = | |
21 | "\n%%% $Id$\n"; | |
22 | #endif | |
8507f105 | 23 | |
23c9e63c DD |
24 | #include "win32.h" |
25 | #include <stdio.h> | |
26 | #include <stdlib.h> | |
27 | #include <string.h> | |
28 | ||
29 | #include "dialog.h" | |
30 | #include "resource.h" | |
31 | #include "state.h" | |
32 | #include "geturl.h" | |
33 | #include "msg.h" | |
ed3e8b9b | 34 | #include "concat.h" |
89b1a15b | 35 | #include "log.h" |
b24c88b3 | 36 | #include "io_stream.h" |
de6a1a64 | 37 | #include "site.h" |
23c9e63c DD |
38 | |
39 | #include "port.h" | |
40 | ||
41 | #define NO_IDX (-1) | |
42 | #define OTHER_IDX (-2) | |
b5b282c4 | 43 | |
de6a1a64 RC |
44 | list < site_list_type, const char *, strcasecmp > site_list; |
45 | list < site_list_type, const char *, strcasecmp > all_site_list; | |
23c9e63c DD |
46 | static int mirror_idx = NO_IDX; |
47 | ||
de6a1a64 RC |
48 | void |
49 | site_list_type::init (char const *newurl) | |
50 | { | |
51 | url = _strdup (newurl); | |
52 | displayed_url = _strdup (newurl); | |
53 | char *dot = strchr (displayed_url, '.'); | |
54 | if (dot) | |
55 | { | |
56 | dot = strchr (dot, '/'); | |
57 | if (dot) | |
58 | *dot = 0; | |
59 | } | |
60 | key = (char *) malloc (2 * strlen (newurl) + 3); | |
61 | ||
62 | dot = displayed_url; | |
63 | dot += strlen (dot); | |
64 | char *dp = key; | |
65 | while (dot != displayed_url) | |
66 | { | |
67 | if (*dot == '.' || *dot == '/') | |
68 | { | |
69 | char *sp; | |
70 | if (dot[3] == 0) | |
71 | *dp++ = '~'; /* sort .com/.edu/.org together */ | |
72 | for (sp = dot + 1; *sp && *sp != '.' && *sp != '/';) | |
73 | *dp++ = *sp++; | |
74 | *dp++ = ' '; | |
75 | } | |
76 | dot--; | |
77 | } | |
78 | *dp++ = ' '; | |
79 | strcpy (dp, displayed_url); | |
80 | } | |
81 | ||
82 | site_list_type::site_list_type (char const *newurl) | |
83 | { | |
84 | init (newurl); | |
85 | } | |
86 | ||
23c9e63c DD |
87 | static void |
88 | check_if_enable_next (HWND h) | |
89 | { | |
de6a1a64 RC |
90 | EnableWindow (GetDlgItem (h, IDOK), |
91 | SendMessage (GetDlgItem (h, IDC_URL_LIST), LB_GETSELCOUNT, 0, | |
92 | 0) > 0 ? 1 : 0); | |
23c9e63c DD |
93 | } |
94 | ||
95 | static void | |
96 | load_dialog (HWND h) | |
97 | { | |
98 | HWND listbox = GetDlgItem (h, IDC_URL_LIST); | |
de6a1a64 RC |
99 | for (size_t n = 1; n <= site_list.number (); n++) |
100 | { | |
101 | int index = SendMessage (listbox, LB_FINDSTRING, (WPARAM) - 1, | |
102 | (LPARAM) site_list[n]->displayed_url); | |
103 | if (index != LB_ERR) | |
104 | SendMessage (listbox, LB_SELITEMRANGE, TRUE, (index << 16) | index); | |
105 | } | |
23c9e63c DD |
106 | check_if_enable_next (h); |
107 | } | |
108 | ||
109 | static void | |
110 | save_dialog (HWND h) | |
111 | { | |
112 | HWND listbox = GetDlgItem (h, IDC_URL_LIST); | |
de6a1a64 RC |
113 | mirror_idx = 0; |
114 | while (site_list.number () > 0) | |
115 | /* we don't delete the object because it's stored in the all_site_list. */ | |
116 | site_list.removebyindex (1); | |
117 | int sel_count = SendMessage (listbox, LB_GETSELCOUNT, 0, 0); | |
118 | if (sel_count > 0) | |
23c9e63c | 119 | { |
de6a1a64 RC |
120 | int sel_buffer[sel_count]; |
121 | int sel_count2 = SendMessage (listbox, LB_GETSELITEMS, sel_count, | |
122 | (LPARAM) sel_buffer); | |
123 | if (sel_count != sel_count2) | |
124 | { | |
125 | NEXT (IDD_SITE); | |
126 | } | |
127 | for (int n = 0; n < sel_count; n++) | |
128 | { | |
129 | int mirror = | |
130 | SendMessage (listbox, LB_GETITEMDATA, sel_buffer[n], 0); | |
131 | if (mirror == OTHER_IDX) | |
132 | mirror_idx = OTHER_IDX; | |
133 | else | |
134 | site_list.registerbyobject (*all_site_list[mirror]); | |
135 | } | |
23c9e63c DD |
136 | } |
137 | else | |
138 | { | |
de6a1a64 | 139 | NEXT (IDD_SITE); |
23c9e63c DD |
140 | } |
141 | } | |
142 | ||
ed3e8b9b DD |
143 | void |
144 | save_site_url () | |
145 | { | |
b24c88b3 | 146 | io_stream *f = io_stream::open ("cygfile:///etc/setup/last-mirror", "wb"); |
de6a1a64 | 147 | for (size_t n = 1; n <= site_list.number (); n++) |
b24c88b3 | 148 | { |
de6a1a64 RC |
149 | if (f) |
150 | { | |
151 | char temp[_MAX_PATH]; | |
152 | /* TODO: potential buffer overflow. we need snprintf asap. */ | |
153 | // FIXME: write all selected sites | |
154 | sprintf (temp, "%s\n", site_list[n]->url); | |
155 | f->write (temp, strlen (temp)); | |
156 | } | |
b24c88b3 | 157 | } |
de6a1a64 | 158 | delete f; |
ed3e8b9b DD |
159 | } |
160 | ||
23c9e63c DD |
161 | static BOOL |
162 | dialog_cmd (HWND h, int id, HWND hwndctl, UINT code) | |
163 | { | |
164 | switch (id) | |
165 | { | |
166 | ||
167 | case IDC_URL_LIST: | |
23c9e63c DD |
168 | check_if_enable_next (h); |
169 | break; | |
170 | ||
171 | case IDOK: | |
ed3e8b9b | 172 | save_dialog (h); |
23c9e63c | 173 | if (mirror_idx == OTHER_IDX) |
1fd6d0a2 | 174 | NEXT (IDD_OTHER_URL); |
23c9e63c | 175 | else |
ed3e8b9b | 176 | { |
ed3e8b9b | 177 | save_site_url (); |
1fd6d0a2 | 178 | NEXT (IDD_S_LOAD_INI); |
ed3e8b9b | 179 | } |
23c9e63c DD |
180 | break; |
181 | ||
182 | case IDC_BACK: | |
ed3e8b9b | 183 | save_dialog (h); |
1fd6d0a2 | 184 | NEXT (IDD_NET); |
23c9e63c DD |
185 | break; |
186 | ||
187 | case IDCANCEL: | |
1fd6d0a2 | 188 | NEXT (0); |
23c9e63c DD |
189 | break; |
190 | } | |
b24c88b3 | 191 | return 0; |
23c9e63c DD |
192 | } |
193 | ||
194 | static BOOL CALLBACK | |
195 | dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) | |
196 | { | |
de6a1a64 | 197 | int j; |
23c9e63c DD |
198 | HWND listbox; |
199 | switch (message) | |
200 | { | |
201 | case WM_INITDIALOG: | |
202 | listbox = GetDlgItem (h, IDC_URL_LIST); | |
de6a1a64 | 203 | for (size_t i = 1; i <= all_site_list.number (); i++) |
23c9e63c | 204 | { |
b24c88b3 RC |
205 | j = |
206 | SendMessage (listbox, LB_ADDSTRING, 0, | |
de6a1a64 | 207 | (LPARAM) all_site_list[i]->displayed_url); |
23c9e63c DD |
208 | SendMessage (listbox, LB_SETITEMDATA, j, i); |
209 | } | |
b24c88b3 | 210 | j = SendMessage (listbox, LB_ADDSTRING, 0, (LPARAM) "Other URL"); |
23c9e63c | 211 | SendMessage (listbox, LB_SETITEMDATA, j, OTHER_IDX); |
ed3e8b9b | 212 | load_dialog (h); |
23c9e63c DD |
213 | return FALSE; |
214 | case WM_COMMAND: | |
1fd6d0a2 | 215 | return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd); |
23c9e63c DD |
216 | } |
217 | return FALSE; | |
218 | } | |
219 | ||
220 | static int | |
221 | get_site_list (HINSTANCE h) | |
222 | { | |
223 | char mirror_url[1000]; | |
ed3e8b9b | 224 | if (LoadString (h, IDS_MIRROR_LST, mirror_url, sizeof (mirror_url)) <= 0) |
23c9e63c DD |
225 | return 1; |
226 | char *mirrors = get_url_to_string (mirror_url); | |
227 | dismiss_url_status_dialog (); | |
228 | if (!mirrors) | |
229 | return 1; | |
230 | ||
231 | char *bol, *eol, *nl; | |
232 | ||
23c9e63c DD |
233 | nl = mirrors; |
234 | while (*nl) | |
235 | { | |
236 | bol = nl; | |
b24c88b3 | 237 | for (eol = bol; *eol && *eol != '\n'; eol++); |
23c9e63c | 238 | if (*eol) |
b24c88b3 | 239 | nl = eol + 1; |
23c9e63c DD |
240 | else |
241 | nl = eol; | |
242 | while (eol > bol && eol[-1] == '\r') | |
243 | eol--; | |
244 | *eol = 0; | |
245 | if (bol[0] != '#' && bol[0] > ' ') | |
246 | { | |
b5b282c4 | 247 | char *semi = strchr (bol, ';'); |
23c9e63c DD |
248 | if (semi) |
249 | *semi = 0; | |
de6a1a64 RC |
250 | site_list_type *newsite = new site_list_type (bol); |
251 | site_list_type & listobj = | |
252 | all_site_list.registerbyobject (*newsite); | |
253 | if (&listobj != newsite) | |
254 | /* That site was already registered */ | |
255 | delete newsite; | |
23c9e63c DD |
256 | } |
257 | } | |
de6a1a64 | 258 | delete[]mirrors; |
b5b282c4 | 259 | |
23c9e63c DD |
260 | return 0; |
261 | } | |
262 | ||
6fbc690d CF |
263 | /* List of machines that should not be used by default when saved |
264 | in "last-mirror". */ | |
265 | #define NOSAVE1 "ftp://sources.redhat.com/" | |
266 | #define NOSAVE1_LEN (sizeof ("ftp://sources.redhat.com/") - 1) | |
267 | #define NOSAVE2 "ftp://sourceware.cygnus.com/" | |
268 | #define NOSAVE2_LEN (sizeof ("ftp://sourceware.cygnus.com/") - 1) | |
269 | #define NOSAVE3 "ftp://gcc.gnu.org/" | |
270 | #define NOSAVE3_LEN (sizeof ("ftp://gcc.gnu.org/") - 1) | |
271 | ||
ed3e8b9b | 272 | static void |
de6a1a64 | 273 | get_saved_sites () |
ed3e8b9b | 274 | { |
b24c88b3 | 275 | io_stream *f = io_stream::open ("cygfile:///etc/setup/last-mirror", "rt"); |
ed3e8b9b DD |
276 | if (!f) |
277 | return; | |
278 | ||
279 | char site[1000]; | |
de6a1a64 RC |
280 | char *fg_ret; |
281 | while ((fg_ret = f->gets (site, 1000))) | |
282 | { | |
ed3e8b9b | 283 | |
de6a1a64 RC |
284 | char *eos = site + strlen (site) - 1; |
285 | while (eos >= site && (*eos == '\n' || *eos == '\r')) | |
286 | *eos-- = '\0'; | |
ed3e8b9b | 287 | |
de6a1a64 RC |
288 | if (eos < site) |
289 | continue; | |
ed3e8b9b | 290 | |
de6a1a64 RC |
291 | bool found = false; |
292 | for (size_t i = 1; !found && i <= all_site_list.number (); i++) | |
293 | if (!strcasecmp (site, all_site_list[i]->url)) | |
294 | found = true; | |
ed3e8b9b | 295 | |
de6a1a64 RC |
296 | if (!found) |
297 | { | |
298 | /* Don't default to certain machines ever since they suffer | |
299 | from bandwidth limitations. */ | |
300 | if (strnicmp (site, NOSAVE1, NOSAVE1_LEN) == 0 | |
301 | || strnicmp (site, NOSAVE2, NOSAVE2_LEN) == 0 | |
302 | || strnicmp (site, NOSAVE3, NOSAVE3_LEN) == 0) | |
303 | return; | |
304 | site_list_type *newsite = new site_list_type (site); | |
305 | site_list_type & listobj = | |
306 | all_site_list.registerbyobject (*newsite); | |
307 | if (&listobj != newsite) | |
308 | /* That site was already registered - shouldn't happen, but safety first */ | |
309 | delete newsite; | |
310 | } | |
311 | /* TODO: make a site_type method to create a serach key on-the-fly from a | |
312 | URL | |
313 | */ | |
314 | found = false; | |
315 | for (size_t i = 1; !found && i <= all_site_list.number (); i++) | |
316 | if (!strcasecmp (site, all_site_list[i]->url)) | |
317 | site_list.registerbyobject (*all_site_list[i]); | |
ed3e8b9b | 318 | } |
de6a1a64 | 319 | delete f; |
ed3e8b9b | 320 | |
ed3e8b9b DD |
321 | } |
322 | ||
23c9e63c DD |
323 | void |
324 | do_site (HINSTANCE h) | |
325 | { | |
326 | int rv = 0; | |
327 | ||
de6a1a64 | 328 | if (all_site_list.number () == 0) |
23c9e63c DD |
329 | if (get_site_list (h)) |
330 | { | |
4a83b7b0 | 331 | NEXT (IDD_NET); |
23c9e63c DD |
332 | return; |
333 | } | |
334 | ||
de6a1a64 | 335 | get_saved_sites (); |
ed3e8b9b | 336 | |
23c9e63c DD |
337 | rv = DialogBox (h, MAKEINTRESOURCE (IDD_SITE), 0, dialog_proc); |
338 | if (rv == -1) | |
339 | fatal (IDS_DIALOG_FAILED); | |
89b1a15b | 340 | |
de6a1a64 RC |
341 | for (size_t n = 1; n <= site_list.number (); n++) |
342 | log (0, "site: %s", site_list[n]->url); | |
23c9e63c | 343 | } |