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 install 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. */
23 static const char *cvsid
=
33 #include <sys/types.h>
38 #include "zlib/zlib.h"
52 #include "filemanip.h"
53 #include "io_stream.h"
55 #include "compress_gz.h"
57 #include "archive_tar.h"
60 #include "package_db.h"
61 #include "package_meta.h"
62 #include "package_version.h"
63 #include "package_source.h"
68 extern ThreeBarProgressPage Progress
;
70 static int total_bytes
= 0;
71 static int total_bytes_sofar
= 0;
72 static int package_bytes
= 0;
77 Progress
.SetText2 ("");
78 Progress
.SetText3 ("");
84 if (package_bytes
> 0)
86 Progress
.SetBar1 (bytes
, package_bytes
);
91 Progress
.SetBar2 (total_bytes_sofar
+ bytes
, total_bytes
);
95 static const char *standard_dirs
[] = {
114 static int num_installs
, num_uninstalls
;
116 /* FIXME: upgrades should be a method too */
118 uninstall_one (packagemeta
& pkgm
)
120 Progress
.SetText1 ("Uninstalling...");
121 Progress
.SetText2 (pkgm
.name
);
122 log (0, "Uninstalling %s", pkgm
.name
);
129 /* install one source at a given prefix. */
131 install_one_source (packagemeta
& pkgm
, packagesource
& source
,
132 char const *prefix
, package_type_t type
)
135 Progress
.SetText2 (source
.Base ());
136 if (!io_stream::exists (source
.Cached ()))
138 note (NULL
, IDS_ERR_OPEN_READ
, source
.Cached (), "No such file");
142 if (type
== package_binary
)
146 open (concat ("cygfile:///etc/setup/", pkgm
.name
, ".lst.gz", 0),
148 lst
= new compress_gz (tmp
, "w9");
156 package_bytes
= source
.size
;
159 strcpy (msg
, "Installing");
160 Progress
.SetText1 (msg
);
161 log (0, "%s%s", msg
, source
.Cached ());
162 io_stream
*tmp
= io_stream::open (source
.Cached (), "rb");
163 archive
*thefile
= 0;
166 io_stream
*tmp2
= compress::decompress (tmp
);
168 thefile
= archive::extract (tmp2
);
170 thefile
= archive::extract (tmp
);
172 /* FIXME: potential leak of either *tmp or *tmp2 */
176 while ((fn
= thefile
->next_file_name ()))
179 lst
->write (concat (fn
, "\n", 0), strlen (fn
) + 1);
181 /* FIXME: concat leaks memory */
182 Progress
.SetText3 (concat (prefix
, fn
, 0));
183 log (LOG_BABBLE
, "Installing file %s%s", prefix
, fn
);
184 if (archive::extract_file (thefile
, prefix
) != 0)
186 log (0, "Unable to install file %s%s", prefix
, fn
);
190 progress (tmp
->tell ());
195 total_bytes_sofar
+= package_bytes
;
201 int df
= diskfull (get_root_dir ());
202 Progress
.SetBar3 (df
);
210 /* install a package, install both the binary and source aspects if needed */
212 install_one (packagemeta
& pkg
)
216 if (pkg
.desired
->binpicked
)
219 install_one_source (pkg
, pkg
.desired
->bin
, "cygfile:///",
222 pkg
.installed
= pkg
.desired
;
224 if (pkg
.desired
->srcpicked
)
226 install_one_source (pkg
, pkg
.desired
->src
, "cygfile:///usr/src",
229 /* FIXME: make a upgrade method and reinstate this */
233 strcpy (msg
, "Installing");
236 int n
= strcmp (pi
->version
, pkg
->installed
->version
);
238 strcpy (msg
, "Reverting");
240 strcpy (msg
, "Reinstalling");
242 strcpy (msg
, "Upgrading");
248 strcat (msg
, " previous version...");
254 strcat (msg
, " test version...");
257 /* FIXME: log this somehow */
260 SetWindowText (ins_action
, msg
);
261 log (0, "%s%s", msg
, file
);
268 check_for_old_cygwin ()
270 char buf
[_MAX_PATH
+ sizeof ("\\cygwin1.dll")];
271 if (!GetSystemDirectory (buf
, sizeof (buf
)))
273 strcat (buf
, "\\cygwin1.dll");
274 if (_access (buf
, 0) != 0)
277 char msg
[sizeof (buf
) + 132];
279 "An old version of cygwin1.dll was found here:\r\n%s\r\nDelete?",
282 (NULL
, msg
, "What's that doing there?",
283 MB_YESNO
| MB_ICONQUESTION
| MB_TASKMODAL
))
286 if (!DeleteFile (buf
))
288 sprintf (msg
, "Couldn't delete file %s.\r\n"
289 "Is the DLL in use by another application?\r\n"
290 "You should delete the old version of cygwin1.dll\r\n"
291 "at your earliest convenience.", buf
);
292 MessageBox (NULL
, buf
, "Couldn't delete file",
293 MB_OK
| MB_ICONEXCLAMATION
| MB_TASKMODAL
);
304 do_install_thread (HINSTANCE h
, HWND owner
)
309 num_installs
= 0, num_uninstalls
= 0;
311 next_dialog
= IDD_DESKTOP
;
313 mkdir_p (1, get_root_dir ());
315 for (i
= 0; standard_dirs
[i
]; i
++)
317 char *p
= cygpath (standard_dirs
[i
], 0);
322 /* Create /var/run/utmp */
323 io_stream
*utmp
= io_stream::open ("cygfile:///var/run/utmp", "wb");
329 total_bytes_sofar
= 0;
331 int df
= diskfull (get_root_dir ());
332 Progress
.SetBar3 (df
);
334 int istext
= (root_text
== IDC_ROOT_TEXT
) ? 1 : 0;
335 int issystem
= (root_scope
== IDC_ROOT_SYSTEM
) ? 1 : 0;
337 create_mount ("/", get_root_dir (), istext
, issystem
);
338 create_mount ("/usr/bin", cygpath ("/bin", 0), istext
, issystem
);
339 create_mount ("/usr/lib", cygpath ("/lib", 0), istext
, issystem
);
340 set_cygdrive_flags (istext
, issystem
);
342 /* Let's hope people won't uninstall packages before installing [b]ash */
346 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
348 packagemeta
& pkg
= *db
.packages
[n
];
350 if (pkg
.desired
&& (pkg
.desired
->srcpicked
|| pkg
.desired
->binpicked
))
352 if (pkg
.desired
->srcpicked
)
353 total_bytes
+= pkg
.desired
->src
.size
;
354 if (pkg
.desired
->binpicked
)
355 total_bytes
+= pkg
.desired
->bin
.size
;
359 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
361 packagemeta
& pkg
= *db
.packages
[n
];
362 if (pkg
.installed
&& (!pkg
.desired
|| pkg
.desired
!= pkg
.installed
))
367 if (pkg
.desired
&& (pkg
.desired
->srcpicked
|| pkg
.desired
->binpicked
))
370 e
+= install_one (pkg
);
376 } // end of big package loop
379 if ((temperr
= db
.flush ()))
381 const char *err
= strerror (temperr
);
383 err
= "(unknown error)";
384 fatal (owner
, IDS_ERR_OPEN_WRITE
, err
);
388 check_for_old_cygwin ();
389 if (num_installs
== 0 && num_uninstalls
== 0)
391 exit_msg
= IDS_NOTHING_INSTALLED
;
394 if (num_installs
== 0)
396 exit_msg
= IDS_UNINSTALL_COMPLETE
;
401 exit_msg
= IDS_INSTALL_INCOMPLETE
;
403 exit_msg
= IDS_INSTALL_COMPLETE
;
407 do_install_reflector (void *p
)
410 context
= (HANDLE
*) p
;
412 do_install_thread ((HINSTANCE
) context
[0], (HWND
) context
[1]);
414 // Tell the progress page that we're done downloading
415 Progress
.PostMessage (WM_APP_INSTALL_THREAD_COMPLETE
);
420 static HANDLE context
[2];
423 do_install (HINSTANCE h
, HWND owner
)
428 _beginthread (do_install_reflector
, 0, context
);