]> cygwin.com Git - cygwin-apps/setup.git/blame - install.cc
Change concat to cygpath throughout. Change map_filename to cygpath
[cygwin-apps/setup.git] / install.cc
CommitLineData
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 intall all the packages selected in
17 the install list (in ini.h). Note that we use a separate thread to
18 maintain the progress dialog, so we avoid the complexity of
19 handling two tasks in one thread. We also create or update all the
20 files in /etc/setup/* and create the mount points. */
21
8507f105
DD
22static char *cvsid = "\n%%% $Id$\n";
23
23c9e63c
DD
24#include "win32.h"
25#include "commctrl.h"
26
27#include <stdio.h>
904d24fe 28#include <stdlib.h>
4a83b7b0 29#include <unistd.h>
23c9e63c
DD
30#include <sys/types.h>
31#include <sys/stat.h>
32#include <errno.h>
33#include "zlib/zlib.h"
34
35#include "resource.h"
36#include "ini.h"
37#include "dialog.h"
38#include "concat.h"
39#include "geturl.h"
40#include "mkdir.h"
41#include "state.h"
42#include "tar.h"
43#include "diskfull.h"
44#include "msg.h"
45#include "mount.h"
89b1a15b 46#include "log.h"
4a83b7b0 47#include "hash.h"
a351e48c 48#include "mount.h"
4a83b7b0
DD
49
50#include "port.h"
23c9e63c
DD
51
52static HWND ins_dialog = 0;
4a83b7b0 53static HWND ins_action = 0;
23c9e63c
DD
54static HWND ins_pkgname = 0;
55static HWND ins_filename = 0;
56static HWND ins_pprogress = 0;
57static HWND ins_iprogress = 0;
58static HWND ins_diskfull = 0;
59static HANDLE init_event;
60
61static int total_bytes = 0;
62static int total_bytes_sofar = 0;
63static int package_bytes = 0;
64
65static BOOL
66dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
67{
68 switch (id)
69 {
70 case IDCANCEL:
89b1a15b 71 exit_setup (1);
23c9e63c
DD
72 }
73}
74
75static BOOL CALLBACK
76dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
77{
78 int i, j;
79 HWND listbox;
80 switch (message)
81 {
82 case WM_INITDIALOG:
83 ins_dialog = h;
4a83b7b0 84 ins_action = GetDlgItem (h, IDC_INS_ACTION);
23c9e63c
DD
85 ins_pkgname = GetDlgItem (h, IDC_INS_PKG);
86 ins_filename = GetDlgItem (h, IDC_INS_FILE);
87 ins_pprogress = GetDlgItem (h, IDC_INS_PPROGRESS);
88 ins_iprogress = GetDlgItem (h, IDC_INS_IPROGRESS);
89 ins_diskfull = GetDlgItem (h, IDC_INS_DISKFULL);
90 SetEvent (init_event);
91 return FALSE;
92 case WM_COMMAND:
1fd6d0a2 93 return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
23c9e63c
DD
94 }
95 return FALSE;
96}
97
98static WINAPI DWORD
99dialog (void *)
100{
101 int rv = 0;
102 MSG m;
ed96c6da 103 HWND ins_dialog = CreateDialog (hinstance, MAKEINTRESOURCE (IDD_INSTATUS),
23c9e63c
DD
104 0, dialog_proc);
105 if (ins_dialog == 0)
106 fatal ("create dialog");
107 ShowWindow (ins_dialog, SW_SHOWNORMAL);
108 UpdateWindow (ins_dialog);
109 while (GetMessage (&m, 0, 0, 0) > 0) {
110 TranslateMessage (&m);
111 DispatchMessage (&m);
112 }
113}
114
115static DWORD start_tics;
116
117static void
118init_dialog ()
119{
120 if (ins_dialog == 0)
121 {
122 DWORD tid;
123 HANDLE thread;
124 init_event = CreateEvent (0, 0, 0, 0);
125 thread = CreateThread (0, 0, dialog, 0, 0, &tid);
126 WaitForSingleObject (init_event, 10000);
127 CloseHandle (init_event);
128 SendMessage (ins_pprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
129 SendMessage (ins_iprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
130 SendMessage (ins_diskfull, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
131 }
132
133 SetWindowText (ins_pkgname, "");
134 SetWindowText (ins_filename, "");
135 SendMessage (ins_pprogress, PBM_SETPOS, (WPARAM) 0, 0);
136 SendMessage (ins_iprogress, PBM_SETPOS, (WPARAM) 0, 0);
137 SendMessage (ins_diskfull, PBM_SETPOS, (WPARAM) 0, 0);
138 ShowWindow (ins_dialog, SW_SHOWNORMAL);
139 SetForegroundWindow (ins_dialog);
140}
141
142static void
143progress (int bytes)
144{
145 int perc;
146
bf1d5889 147 if (package_bytes > 100)
23c9e63c 148 {
bf1d5889 149 perc = bytes / (package_bytes / 100);
23c9e63c
DD
150 SendMessage (ins_pprogress, PBM_SETPOS, (WPARAM) perc, 0);
151 }
152
bf1d5889 153 if (total_bytes > 100)
23c9e63c 154 {
bf1d5889 155 perc = (total_bytes_sofar + bytes) / (total_bytes / 100);
23c9e63c
DD
156 SendMessage (ins_iprogress, PBM_SETPOS, (WPARAM) perc, 0);
157 }
23c9e63c
DD
158}
159
160static void
161badrename (char *o, char *n)
162{
163 char buf[1000];
164 char *err = strerror (errno);
165 if (!err)
166 err = "(unknown error)";
167 note (IDS_ERR_RENAME, o, n, err);
168}
169
904d24fe 170static char *standard_dirs[] = {
1a18aed7 171 "/bin",
904d24fe 172 "/etc",
1a18aed7 173 "/lib",
904d24fe 174 "/tmp",
4a83b7b0 175 "/usr",
1a18aed7
DD
176 "/usr/bin",
177 "/usr/lib",
ef45c299 178 "/usr/src",
4a83b7b0 179 "/usr/local",
1a18aed7
DD
180 "/usr/local/bin",
181 "/usr/local/etc",
182 "/usr/local/lib",
904d24fe 183 "/usr/tmp",
1a18aed7 184 "/var/run",
904d24fe
DD
185 "/var/tmp",
186 0
187};
188
4a83b7b0
DD
189void
190hash::add_subdirs (char *path)
191{
192 char *nonp, *pp;
193 for (nonp = path; *nonp == '\\' || *nonp == '/'; nonp++);
194 for (pp = path + strlen(path) - 1; pp>nonp; pp--)
195 if (*pp == '/' || *pp == '\\')
196 {
197 int i, s=0;
198 char c = *pp;
199 *pp = 0;
200 for (i=0; standard_dirs[i]; i++)
201 if (strcmp (standard_dirs[i]+1, path) == 0)
202 {
203 s = 1;
204 break;
205 }
206 if (s == 0)
207 add (path);
208 *pp = c;
209 }
210}
211
40aef45e
DD
212static int
213exists (char *file)
214{
215 if (_access (file, 0) == 0)
216 return 1;
217 return 0;
218}
219
3b9077d4
DD
220static int num_installs, num_uninstalls;
221
222static void
223uninstall_one (char *name, int action)
224{
225 hash dirs;
226 char line[_MAX_PATH];
227
a351e48c 228 gzFile lst = gzopen (cygpath ("/etc/setup/",
3b9077d4
DD
229 name, ".lst.gz", 0),
230 "rb");
231 if (lst)
232 {
233 SetWindowText (ins_pkgname, name);
234 SetWindowText (ins_action, "Uninstalling...");
42bf5b92 235 if (action == ACTION_UPGRADE || action == ACTION_REDO)
3b9077d4
DD
236 log (0, "Uninstalling old %s", name);
237 else
238 log (0, "Uninstalling %s", name);
239
240 while (gzgets (lst, line, sizeof (line)))
241 {
242 if (line[strlen(line)-1] == '\n')
243 line[strlen(line)-1] = 0;
244
245 dirs.add_subdirs (line);
246
a351e48c 247 char *d = cygpath ("/", line, NULL);
3b9077d4
DD
248 DWORD dw = GetFileAttributes (d);
249 if (dw != 0xffffffff && !(dw & FILE_ATTRIBUTE_DIRECTORY))
250 {
251 log (LOG_BABBLE, "unlink %s", d);
252 DeleteFile (d);
253 }
254 }
255 gzclose (lst);
256
a351e48c 257 remove (cygpath ("/etc/setup/", name, ".lst.gz", 0));
3b9077d4
DD
258
259 dirs.reverse_sort ();
260 char *subdir = 0;
261 while ((subdir = dirs.enumerate (subdir)) != 0)
262 {
a351e48c 263 char *d = cygpath ("/", subdir, NULL);
3b9077d4
DD
264 if (RemoveDirectory (d))
265 log (LOG_BABBLE, "rmdir %s", d);
266 }
fb087b80 267 num_uninstalls++;
3b9077d4
DD
268 }
269}
270
42bf5b92 271
3b9077d4 272static int
ef45c299 273install_one (char *name, char *file, int file_size, int action, BOOL isSrc)
3b9077d4
DD
274{
275 int errors = 0;
276 char *local = file, *cp, *fn, *base;
277
278 base = local;
279 for (cp=local; *cp; cp++)
280 if (*cp == '/' || *cp == '\\' || *cp == ':')
281 base = cp+1;
282 SetWindowText (ins_pkgname, base);
283
284 if (!exists (local) && exists (base))
285 local = base;
286 if (!exists (local))
287 {
288 note (IDS_ERR_OPEN_READ, local, "No such file");
289 return 1;
290 }
291
a351e48c 292 gzFile lst = gzopen (cygpath ("/etc/setup/",
3b9077d4
DD
293 name, ".lst.gz", 0),
294 "wb9");
295
296 package_bytes = file_size;
297
298 switch (action)
299 {
300 case ACTION_NEW:
301 SetWindowText (ins_action, "Installing...");
302 break;
303 case ACTION_UPGRADE:
304 SetWindowText (ins_action, "Upgrading...");
305 break;
42bf5b92
CF
306 case ACTION_REDO:
307 SetWindowText (ins_action, "ReInstalling...");
308 break;
3b9077d4
DD
309 }
310
311 log (0, "Installing %s", local);
312 tar_open (local);
313 while (fn = tar_next_file ())
314 {
315 char *dest_file;
316
317 if (lst)
318 gzprintf (lst, "%s\n", fn);
319
a351e48c 320 dest_file = cygpath (isSrc ? "/usr/src/" : "/", fn, NULL);
3b9077d4
DD
321
322 SetWindowText (ins_filename, dest_file);
323 log (LOG_BABBLE, "Installing file %s", dest_file);
324 if (tar_read_file (dest_file) != 0)
325 {
326 log (0, "Unable to install file %s", dest_file);
fb087b80 327 errors++;
3b9077d4
DD
328 }
329
330 progress (tar_ftell ());
a351e48c 331 free (dest_file);
fb087b80 332 num_installs++;
3b9077d4
DD
333 }
334 tar_close ();
335
336 total_bytes_sofar += file_size;
337 progress (0);
338
339 int df = diskfull (root_dir);
340 SendMessage (ins_diskfull, PBM_SETPOS, (WPARAM) df, 0);
341
342 if (lst)
343 gzclose (lst);
344
345 return errors;
346}
347
23c9e63c
DD
348void
349do_install (HINSTANCE h)
350{
3b9077d4 351 int i;
2a1a01e0
DD
352 int errors = 0;
353
3b9077d4
DD
354 num_installs = 0, num_uninstalls = 0;
355
50225eae 356 next_dialog = IDD_DESKTOP;
23c9e63c 357
904d24fe
DD
358 mkdir_p (1, root_dir);
359
360 for (i=0; standard_dirs[i]; i++)
361 {
a351e48c 362 char *p = cygpath (standard_dirs[i], 0);
904d24fe
DD
363 mkdir_p (1, p);
364 free (p);
365 }
366
1a18aed7 367 /* Create /var/run/utmp */
a351e48c 368 char *utmp = cygpath ("/var/run/utmp", 0);
1a18aed7
DD
369 FILE *ufp = fopen (utmp, "wb");
370 if (ufp)
371 fclose (ufp);
372 free (utmp);
373
23c9e63c
DD
374 dismiss_url_status_dialog ();
375
376 init_dialog ();
377
378 total_bytes = 0;
379 total_bytes_sofar = 0;
380
d07591a3
DD
381 int df = diskfull (root_dir);
382 SendMessage (ins_diskfull, PBM_SETPOS, (WPARAM) df, 0);
383
23c9e63c
DD
384 LOOP_PACKAGES
385 {
42bf5b92
CF
386 if (package[i].action != ACTION_SRC_ONLY)
387 total_bytes += pi.install_size;
ef45c299 388 if (package[i].srcaction == SRCACTION_YES)
42bf5b92 389 total_bytes += pi.source_size;
23c9e63c
DD
390 }
391
4a83b7b0 392 for (i=0; i<npackages; i++)
23c9e63c 393 {
4a83b7b0 394 if (package[i].action == ACTION_UNINSTALL
42bf5b92
CF
395 || ((package[i].action == ACTION_UPGRADE
396 || package[i].action == ACTION_REDO) && pi.install))
4a83b7b0 397 {
3b9077d4
DD
398 uninstall_one (package[i].name, package[i].action);
399 uninstall_one (concat (package[i].name, "-src", 0), package[i].action);
4a83b7b0 400 }
23c9e63c 401
4a83b7b0 402 if ((package[i].action == ACTION_NEW
42bf5b92
CF
403 || package[i].action == ACTION_UPGRADE
404 || package[i].action == ACTION_REDO
405 || package[i].action == ACTION_SRC_ONLY)
4a83b7b0 406 && pi.install)
23c9e63c 407 {
42bf5b92
CF
408 int e = 0;
409 if (package[i].action != ACTION_SRC_ONLY)
410 e += install_one (package[i].name, pi.install, pi.install_size, package[i].action, FALSE);
3b9077d4
DD
411 if (package[i].srcaction == SRCACTION_YES && pi.source)
412 e += install_one (concat (package[i].name, "-src", 0), pi.source, pi.source_size,
ef45c299 413 package[i].action, TRUE);
3b9077d4 414 if (e)
40aef45e
DD
415 {
416 package[i].action = ACTION_ERROR;
3b9077d4 417 errors++;
40aef45e 418 }
4a83b7b0
DD
419 }
420 } // end of big package loop
421
422 ShowWindow (ins_dialog, SW_HIDE);
23c9e63c 423
a351e48c
CF
424 char *odbn = cygpath ("/etc/setup/installed.db", 0);
425 char *ndbn = cygpath ("/etc/setup/installed.db.new", 0);
426 char *sdbn = cygpath ("/etc/setup/installed.db.old", 0);
23c9e63c
DD
427
428 mkdir_p (0, ndbn);
429
430 FILE *odb = fopen (odbn, "rt");
431 FILE *ndb = fopen (ndbn, "wb");
432
433 if (!ndb)
434 {
435 char *err = strerror (errno);
436 if (!err)
437 err = "(unknown error)";
438 fatal (IDS_ERR_OPEN_WRITE, ndb, err);
439 }
440
441 if (odb)
442 {
443 char line[1000], pkg[1000];
444 int printit;
445 while (fgets (line, 1000, odb))
446 {
447 printit = 1;
1fd6d0a2 448 sscanf (line, "%s", pkg);
4a83b7b0 449 for (i=0; i<npackages; i++)
23c9e63c
DD
450 {
451 if (strcmp (pkg, package[i].name) == 0)
4a83b7b0
DD
452 switch (package[i].action)
453 {
454 case ACTION_NEW:
455 case ACTION_UPGRADE:
456 case ACTION_UNINSTALL:
42bf5b92
CF
457 case ACTION_REDO:
458 case ACTION_SRC_ONLY:
4a83b7b0
DD
459 printit = 0;
460 break;
461 }
23c9e63c
DD
462 }
463 if (printit)
464 fputs (line, ndb);
465 }
42bf5b92 466
23c9e63c 467 }
4a83b7b0 468
23c9e63c
DD
469 LOOP_PACKAGES
470 {
3b9077d4
DD
471 if (package[i].srcaction == SRCACTION_YES)
472 fprintf (ndb, "%s %s %d %s %d\n", package[i].name,
473 pi.install, pi.install_size,
474 pi.source, pi.source_size);
475 else
476 fprintf (ndb, "%s %s %d\n", package[i].name,
477 pi.install, pi.install_size);
23c9e63c
DD
478 }
479
480 if (odb)
481 fclose (odb);
482 fclose (ndb);
483
484 remove (sdbn);
485 if (odb && rename (odbn, sdbn))
486 badrename (odbn, sdbn);
487
488 remove (odbn);
489 if (rename (ndbn, odbn))
490 badrename (ndbn, odbn);
491
4a83b7b0
DD
492 if (num_installs == 0 && num_uninstalls == 0)
493 {
494 exit_msg = IDS_NOTHING_INSTALLED;
495 return;
496 }
497 if (num_installs == 0)
498 {
499 exit_msg = IDS_UNINSTALL_COMPLETE;
500 return;
501 }
502
24e259bb 503 remove_mount ("/");
23c9e63c 504 remove_mount ("/usr");
24e259bb
DD
505 remove_mount ("/usr/bin");
506 remove_mount ("/usr/lib");
23c9e63c
DD
507 remove_mount ("/var");
508 remove_mount ("/lib");
509 remove_mount ("/bin");
510 remove_mount ("/etc");
511
512 int istext = (root_text == IDC_ROOT_TEXT) ? 1 : 0;
24e259bb 513 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
23c9e63c 514
24e259bb 515 create_mount ("/", root_dir, istext, issystem);
a351e48c
CF
516 create_mount ("/usr/bin", cygpath ("/bin", 0), istext, issystem);
517 create_mount ("/usr/lib", cygpath ("/lib", 0), istext, issystem);
f8a6415f 518 set_cygdrive_flags (istext, issystem);
23c9e63c 519
2a1a01e0
DD
520 if (errors)
521 exit_msg = IDS_INSTALL_INCOMPLETE;
522 else
523 exit_msg = IDS_INSTALL_COMPLETE;
23c9e63c 524}
This page took 0.078163 seconds and 5 git commands to generate.