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. */
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"
59 #include "package_db.h"
60 #include "package_meta.h"
61 #include "package_version.h"
62 #include "package_source.h"
67 extern ThreeBarProgressPage Progress
;
69 static int total_bytes
= 0;
70 static int total_bytes_sofar
= 0;
71 static int package_bytes
= 0;
76 Progress
.SetText2 ("");
77 Progress
.SetText3 ("");
83 if (package_bytes
> 0)
85 Progress
.SetBar1 (bytes
, package_bytes
);
90 Progress
.SetBar2 (total_bytes_sofar
+ bytes
, total_bytes
);
94 static const char *standard_dirs
[] = {
113 static int num_installs
, num_uninstalls
;
115 /* FIXME: upgrades should be a method too */
117 uninstall_one (packagemeta
& pkgm
)
119 Progress
.SetText1 ("Uninstalling...");
120 Progress
.SetText2 (pkgm
.name
);
121 log (0, "Uninstalling %s", pkgm
.name
);
128 /* install one source at a given prefix. */
130 install_one_source (packagemeta
& pkgm
, packagesource
& source
,
131 char const *prefix
, package_type_t type
)
134 Progress
.SetText2 (source
.Base ());
135 if (!io_stream::exists (source
.Cached ()))
137 note (NULL
, IDS_ERR_OPEN_READ
, source
.Cached (), "No such file");
141 if (type
== package_binary
)
145 open (concat ("cygfile:///etc/setup/", pkgm
.name
, ".lst.gz", 0),
147 lst
= new compress_gz (tmp
, "w9");
155 package_bytes
= source
.size
;
158 strcpy (msg
, "Installing");
159 Progress
.SetText1 (msg
);
160 log (0, "%s%s", msg
, source
.Cached ());
161 io_stream
*tmp
= io_stream::open (source
.Cached (), "rb");
162 archive
*thefile
= 0;
165 io_stream
*tmp2
= compress::decompress (tmp
);
167 thefile
= archive::extract (tmp2
);
169 thefile
= archive::extract (tmp
);
171 /* FIXME: potential leak of either *tmp or *tmp2 */
175 while ((fn
= thefile
->next_file_name ()))
178 lst
->write (concat (fn
, "\n", 0), strlen (fn
) + 1);
180 /* FIXME: concat leaks memory */
181 Progress
.SetText3 (concat (prefix
, fn
, 0));
182 log (LOG_BABBLE
, "Installing file %s%s", prefix
, fn
);
183 if (archive::extract_file (thefile
, prefix
) != 0)
185 log (0, "Unable to install file %s%s", prefix
, fn
);
189 progress (tmp
->tell ());
194 total_bytes_sofar
+= package_bytes
;
200 int df
= diskfull (get_root_dir ());
201 Progress
.SetBar3 (df
);
209 /* install a package, install both the binary and source aspects if needed */
211 install_one (packagemeta
& pkg
)
215 if (pkg
.desired
->binpicked
)
218 install_one_source (pkg
, pkg
.desired
->bin
, "cygfile:///",
221 pkg
.installed
= pkg
.desired
;
223 if (pkg
.desired
->srcpicked
)
225 install_one_source (pkg
, pkg
.desired
->src
, "cygfile:///usr/src",
228 /* FIXME: make a upgrade method and reinstate this */
232 strcpy (msg
, "Installing");
235 int n
= strcmp (pi
->version
, pkg
->installed
->version
);
237 strcpy (msg
, "Reverting");
239 strcpy (msg
, "Reinstalling");
241 strcpy (msg
, "Upgrading");
247 strcat (msg
, " previous version...");
253 strcat (msg
, " test version...");
256 /* FIXME: log this somehow */
259 SetWindowText (ins_action
, msg
);
260 log (0, "%s%s", msg
, file
);
267 check_for_old_cygwin ()
269 char buf
[_MAX_PATH
+ sizeof ("\\cygwin1.dll")];
270 if (!GetSystemDirectory (buf
, sizeof (buf
)))
272 strcat (buf
, "\\cygwin1.dll");
273 if (_access (buf
, 0) != 0)
276 char msg
[sizeof (buf
) + 132];
278 "An old version of cygwin1.dll was found here:\r\n%s\r\nDelete?",
281 (NULL
, msg
, "What's that doing there?",
282 MB_YESNO
| MB_ICONQUESTION
| MB_TASKMODAL
))
285 if (!DeleteFile (buf
))
287 sprintf (msg
, "Couldn't delete file %s.\r\n"
288 "Is the DLL in use by another application?\r\n"
289 "You should delete the old version of cygwin1.dll\r\n"
290 "at your earliest convenience.", buf
);
291 MessageBox (NULL
, buf
, "Couldn't delete file",
292 MB_OK
| MB_ICONEXCLAMATION
| MB_TASKMODAL
);
303 do_install_thread (HINSTANCE h
, HWND owner
)
308 num_installs
= 0, num_uninstalls
= 0;
310 next_dialog
= IDD_DESKTOP
;
312 mkdir_p (1, get_root_dir ());
314 for (i
= 0; standard_dirs
[i
]; i
++)
316 char *p
= cygpath (standard_dirs
[i
], 0);
321 /* Create /var/run/utmp */
322 io_stream
*utmp
= io_stream::open ("cygfile:///var/run/utmp", "wb");
328 total_bytes_sofar
= 0;
330 int df
= diskfull (get_root_dir ());
331 Progress
.SetBar3 (df
);
333 int istext
= (root_text
== IDC_ROOT_TEXT
) ? 1 : 0;
334 int issystem
= (root_scope
== IDC_ROOT_SYSTEM
) ? 1 : 0;
336 create_mount ("/", get_root_dir (), istext
, issystem
);
337 create_mount ("/usr/bin", cygpath ("/bin", 0), istext
, issystem
);
338 create_mount ("/usr/lib", cygpath ("/lib", 0), istext
, issystem
);
339 set_cygdrive_flags (istext
, issystem
);
342 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
344 packagemeta
& pkg
= *db
.packages
[n
];
346 if (pkg
.desired
&& (pkg
.desired
->srcpicked
|| pkg
.desired
->binpicked
))
348 if (pkg
.desired
->srcpicked
)
349 total_bytes
+= pkg
.desired
->src
.size
;
350 if (pkg
.desired
->binpicked
)
351 total_bytes
+= pkg
.desired
->bin
.size
;
355 for (size_t n
= 1; n
< db
.packages
.number (); n
++)
357 packagemeta
& pkg
= *db
.packages
[n
];
358 if (pkg
.installed
&& (!pkg
.desired
|| pkg
.desired
!= pkg
.installed
))
363 if (pkg
.desired
&& (pkg
.desired
->srcpicked
|| pkg
.desired
->binpicked
))
366 e
+= install_one (pkg
);
372 } // end of big package loop
375 if ((temperr
= db
.flush ()))
377 const char *err
= strerror (temperr
);
379 err
= "(unknown error)";
380 fatal (owner
, IDS_ERR_OPEN_WRITE
, err
);
384 check_for_old_cygwin ();
385 if (num_installs
== 0 && num_uninstalls
== 0)
387 exit_msg
= IDS_NOTHING_INSTALLED
;
390 if (num_installs
== 0)
392 exit_msg
= IDS_UNINSTALL_COMPLETE
;
397 exit_msg
= IDS_INSTALL_INCOMPLETE
;
399 exit_msg
= IDS_INSTALL_COMPLETE
;
403 do_install_reflector (void *p
)
406 context
= (HANDLE
*) p
;
408 do_install_thread ((HINSTANCE
) context
[0], (HWND
) context
[1]);
410 // Tell the progress page that we're done downloading
411 Progress
.PostMessage (WM_APP_INSTALL_THREAD_COMPLETE
);
416 static HANDLE context
[2];
419 do_install (HINSTANCE h
, HWND owner
)
424 _beginthread (do_install_reflector
, 0, context
);