]>
cygwin.com Git - cygwin-apps/setup.git/blob - install.cc
2 * Copyright (c) 2000, Red Hat, Inc.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by DJ Delorie <dj@cygnus.com>
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. */
22 static char *cvsid
= "\n%%% $Id$\n";
30 #include <sys/types.h>
33 #include "zlib/zlib.h"
51 static HWND ins_dialog
= 0;
52 static HWND ins_action
= 0;
53 static HWND ins_pkgname
= 0;
54 static HWND ins_filename
= 0;
55 static HWND ins_pprogress
= 0;
56 static HWND ins_iprogress
= 0;
57 static HWND ins_diskfull
= 0;
58 static HANDLE init_event
;
60 static int total_bytes
= 0;
61 static int total_bytes_sofar
= 0;
62 static int package_bytes
= 0;
65 dialog_cmd (HWND h
, int id
, HWND hwndctl
, UINT code
)
75 dialog_proc (HWND h
, UINT message
, WPARAM wParam
, LPARAM lParam
)
83 ins_action
= GetDlgItem (h
, IDC_INS_ACTION
);
84 ins_pkgname
= GetDlgItem (h
, IDC_INS_PKG
);
85 ins_filename
= GetDlgItem (h
, IDC_INS_FILE
);
86 ins_pprogress
= GetDlgItem (h
, IDC_INS_PPROGRESS
);
87 ins_iprogress
= GetDlgItem (h
, IDC_INS_IPROGRESS
);
88 ins_diskfull
= GetDlgItem (h
, IDC_INS_DISKFULL
);
89 SetEvent (init_event
);
92 return HANDLE_WM_COMMAND (h
, wParam
, lParam
, dialog_cmd
);
102 HANDLE ins_dialog
= CreateDialog (hinstance
, MAKEINTRESOURCE (IDD_INSTATUS
),
105 fatal ("create dialog");
106 ShowWindow (ins_dialog
, SW_SHOWNORMAL
);
107 UpdateWindow (ins_dialog
);
108 while (GetMessage (&m
, 0, 0, 0) > 0) {
109 TranslateMessage (&m
);
110 DispatchMessage (&m
);
114 static DWORD start_tics
;
123 init_event
= CreateEvent (0, 0, 0, 0);
124 thread
= CreateThread (0, 0, dialog
, 0, 0, &tid
);
125 WaitForSingleObject (init_event
, 10000);
126 CloseHandle (init_event
);
127 SendMessage (ins_pprogress
, PBM_SETRANGE
, 0, MAKELPARAM (0, 100));
128 SendMessage (ins_iprogress
, PBM_SETRANGE
, 0, MAKELPARAM (0, 100));
129 SendMessage (ins_diskfull
, PBM_SETRANGE
, 0, MAKELPARAM (0, 100));
132 SetWindowText (ins_pkgname
, "");
133 SetWindowText (ins_filename
, "");
134 SendMessage (ins_pprogress
, PBM_SETPOS
, (WPARAM
) 0, 0);
135 SendMessage (ins_iprogress
, PBM_SETPOS
, (WPARAM
) 0, 0);
136 SendMessage (ins_diskfull
, PBM_SETPOS
, (WPARAM
) 0, 0);
137 ShowWindow (ins_dialog
, SW_SHOWNORMAL
);
138 SetForegroundWindow (ins_dialog
);
146 if (package_bytes
> 100)
148 perc
= bytes
/ (package_bytes
/ 100);
149 SendMessage (ins_pprogress
, PBM_SETPOS
, (WPARAM
) perc
, 0);
152 if (total_bytes
> 100)
154 perc
= (total_bytes_sofar
+ bytes
) / (total_bytes
/ 100);
155 SendMessage (ins_iprogress
, PBM_SETPOS
, (WPARAM
) perc
, 0);
160 badrename (char *o
, char *n
)
163 char *err
= strerror (errno
);
165 err
= "(unknown error)";
166 note (IDS_ERR_RENAME
, o
, n
, err
);
169 static char *standard_dirs
[] = {
188 hash::add_subdirs (char *path
)
191 for (nonp
= path
; *nonp
== '\\' || *nonp
== '/'; nonp
++);
192 for (pp
= path
+ strlen(path
) - 1; pp
>nonp
; pp
--)
193 if (*pp
== '/' || *pp
== '\\')
198 for (i
=0; standard_dirs
[i
]; i
++)
199 if (strcmp (standard_dirs
[i
]+1, path
) == 0)
211 map_filename (char *fn
)
214 while (*fn
== '/' || *fn
== '\\')
216 if (strncmp (fn
, "usr/bin/", 8) == 0)
217 dest_file
= concat (root_dir
, "/bin/", fn
+8, 0);
218 else if (strncmp (fn
, "usr/lib/", 8) == 0)
219 dest_file
= concat (root_dir
, "/lib/", fn
+8, 0);
221 dest_file
= concat (root_dir
, "/", fn
, 0);
225 #define pi (package[i].info[package[i].trust])
227 #define LOOP_PACKAGES \
228 for (i=0; i<npackages; i++) \
229 if ((package[i].action == ACTION_NEW \
230 || package[i].action == ACTION_UPGRADE) \
236 if (_access (file
, 0) == 0)
242 static int num_installs
, num_uninstalls
;
245 uninstall_one (char *name
, int action
)
248 char line
[_MAX_PATH
];
250 gzFile lst
= gzopen (concat (root_dir
, "/etc/setup/",
255 SetWindowText (ins_pkgname
, name
);
256 SetWindowText (ins_action
, "Uninstalling...");
257 if (action
== ACTION_UPGRADE
)
258 log (0, "Uninstalling old %s", name
);
260 log (0, "Uninstalling %s", name
);
262 while (gzgets (lst
, line
, sizeof (line
)))
264 if (line
[strlen(line
)-1] == '\n')
265 line
[strlen(line
)-1] = 0;
267 dirs
.add_subdirs (line
);
269 char *d
= map_filename (line
);
270 DWORD dw
= GetFileAttributes (d
);
271 if (dw
!= 0xffffffff && !(dw
& FILE_ATTRIBUTE_DIRECTORY
))
273 log (LOG_BABBLE
, "unlink %s", d
);
279 remove (concat (root_dir
, "/etc/setup/", name
, ".lst.gz", 0));
281 dirs
.reverse_sort ();
283 while ((subdir
= dirs
.enumerate (subdir
)) != 0)
285 char *d
= map_filename (subdir
);
286 if (RemoveDirectory (d
))
287 log (LOG_BABBLE
, "rmdir %s", d
);
295 install_one (char *name
, char *file
, int file_size
, int action
)
298 char *local
= file
, *cp
, *fn
, *base
;
301 for (cp
=local
; *cp
; cp
++)
302 if (*cp
== '/' || *cp
== '\\' || *cp
== ':')
304 SetWindowText (ins_pkgname
, base
);
306 if (!exists (local
) && exists (base
))
310 note (IDS_ERR_OPEN_READ
, local
, "No such file");
314 gzFile lst
= gzopen (concat (root_dir
, "/etc/setup/",
318 package_bytes
= file_size
;
323 SetWindowText (ins_action
, "Installing...");
326 SetWindowText (ins_action
, "Upgrading...");
330 log (0, "Installing %s", local
);
332 while (fn
= tar_next_file ())
337 gzprintf (lst
, "%s\n", fn
);
339 dest_file
= map_filename (fn
);
341 SetWindowText (ins_filename
, dest_file
);
342 log (LOG_BABBLE
, "Installing file %s", dest_file
);
343 if (tar_read_file (dest_file
) != 0)
345 log (0, "Unable to install file %s", dest_file
);
349 progress (tar_ftell ());
354 total_bytes_sofar
+= file_size
;
357 int df
= diskfull (root_dir
);
358 SendMessage (ins_diskfull
, PBM_SETPOS
, (WPARAM
) df
, 0);
367 do_install (HINSTANCE h
)
372 num_installs
= 0, num_uninstalls
= 0;
374 next_dialog
= IDD_DESKTOP
;
376 mkdir_p (1, root_dir
);
378 for (i
=0; standard_dirs
[i
]; i
++)
380 char *p
= concat (root_dir
, standard_dirs
[i
], 0);
385 /* Create /var/run/utmp */
386 char *utmp
= concat (root_dir
, "/var/run/utmp", 0);
387 FILE *ufp
= fopen (utmp
, "wb");
392 dismiss_url_status_dialog ();
397 total_bytes_sofar
= 0;
399 int df
= diskfull (root_dir
);
400 SendMessage (ins_diskfull
, PBM_SETPOS
, (WPARAM
) df
, 0);
404 total_bytes
+= pi
.install_size
;
407 for (i
=0; i
<npackages
; i
++)
409 if (package
[i
].action
== ACTION_UNINSTALL
410 || (package
[i
].action
== ACTION_UPGRADE
&& pi
.install
))
412 uninstall_one (package
[i
].name
, package
[i
].action
);
413 uninstall_one (concat (package
[i
].name
, "-src", 0), package
[i
].action
);
416 if ((package
[i
].action
== ACTION_NEW
417 || package
[i
].action
== ACTION_UPGRADE
)
420 int e
= install_one (package
[i
].name
, pi
.install
, pi
.install_size
, package
[i
].action
);
421 if (package
[i
].srcaction
== SRCACTION_YES
&& pi
.source
)
422 e
+= install_one (concat (package
[i
].name
, "-src", 0), pi
.source
, pi
.source_size
,
426 package
[i
].action
= ACTION_ERROR
;
430 } // end of big package loop
432 ShowWindow (ins_dialog
, SW_HIDE
);
434 char *odbn
= concat (root_dir
, "/etc/setup/installed.db", 0);
435 char *ndbn
= concat (root_dir
, "/etc/setup/installed.db.new", 0);
436 char *sdbn
= concat (root_dir
, "/etc/setup/installed.db.old", 0);
440 FILE *odb
= fopen (odbn
, "rt");
441 FILE *ndb
= fopen (ndbn
, "wb");
445 char *err
= strerror (errno
);
447 err
= "(unknown error)";
448 fatal (IDS_ERR_OPEN_WRITE
, ndb
, err
);
453 char line
[1000], pkg
[1000];
455 while (fgets (line
, 1000, odb
))
458 sscanf (line
, "%s", pkg
);
459 for (i
=0; i
<npackages
; i
++)
461 if (strcmp (pkg
, package
[i
].name
) == 0)
462 switch (package
[i
].action
)
466 case ACTION_UNINSTALL
:
479 if (package
[i
].srcaction
== SRCACTION_YES
)
480 fprintf (ndb
, "%s %s %d %s %d\n", package
[i
].name
,
481 pi
.install
, pi
.install_size
,
482 pi
.source
, pi
.source_size
);
484 fprintf (ndb
, "%s %s %d\n", package
[i
].name
,
485 pi
.install
, pi
.install_size
);
493 if (odb
&& rename (odbn
, sdbn
))
494 badrename (odbn
, sdbn
);
497 if (rename (ndbn
, odbn
))
498 badrename (ndbn
, odbn
);
500 if (num_installs
== 0 && num_uninstalls
== 0)
502 exit_msg
= IDS_NOTHING_INSTALLED
;
505 if (num_installs
== 0)
507 exit_msg
= IDS_UNINSTALL_COMPLETE
;
512 remove_mount ("/usr");
513 remove_mount ("/usr/bin");
514 remove_mount ("/usr/lib");
515 remove_mount ("/var");
516 remove_mount ("/lib");
517 remove_mount ("/bin");
518 remove_mount ("/etc");
520 int istext
= (root_text
== IDC_ROOT_TEXT
) ? 1 : 0;
521 int issystem
= (root_scope
== IDC_ROOT_SYSTEM
) ? 1 : 0;
523 create_mount ("/", root_dir
, istext
, issystem
);
524 create_mount ("/usr/bin", concat (root_dir
, "/bin", 0), istext
, issystem
);
525 create_mount ("/usr/lib", concat (root_dir
, "/lib", 0), istext
, issystem
);
528 exit_msg
= IDS_INSTALL_INCOMPLETE
;
530 exit_msg
= IDS_INSTALL_COMPLETE
;
This page took 0.060464 seconds and 6 git commands to generate.