]> cygwin.com Git - cygwin-apps/setup.git/blame - install.cc
* ini.cc (do_ini): don't worry about timestamps if we're not
[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
22#include "win32.h"
23#include "commctrl.h"
24
25#include <stdio.h>
26#include <sys/types.h>
27#include <sys/stat.h>
28#include <errno.h>
29#include "zlib/zlib.h"
30
31#include "resource.h"
32#include "ini.h"
33#include "dialog.h"
34#include "concat.h"
35#include "geturl.h"
36#include "mkdir.h"
37#include "state.h"
38#include "tar.h"
39#include "diskfull.h"
40#include "msg.h"
41#include "mount.h"
42
43static HWND ins_dialog = 0;
44static HWND ins_pkgname = 0;
45static HWND ins_filename = 0;
46static HWND ins_pprogress = 0;
47static HWND ins_iprogress = 0;
48static HWND ins_diskfull = 0;
49static HANDLE init_event;
50
51static int total_bytes = 0;
52static int total_bytes_sofar = 0;
53static int package_bytes = 0;
54
55static BOOL
56dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
57{
58 switch (id)
59 {
60 case IDCANCEL:
61 ExitProcess(0);
62 }
63}
64
65static BOOL CALLBACK
66dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
67{
68 int i, j;
69 HWND listbox;
70 switch (message)
71 {
72 case WM_INITDIALOG:
73 ins_dialog = h;
74 ins_pkgname = GetDlgItem (h, IDC_INS_PKG);
75 ins_filename = GetDlgItem (h, IDC_INS_FILE);
76 ins_pprogress = GetDlgItem (h, IDC_INS_PPROGRESS);
77 ins_iprogress = GetDlgItem (h, IDC_INS_IPROGRESS);
78 ins_diskfull = GetDlgItem (h, IDC_INS_DISKFULL);
79 SetEvent (init_event);
80 return FALSE;
81 case WM_COMMAND:
82 return HANDLE_WM_COMMAND(h, wParam, lParam, dialog_cmd);
83 }
84 return FALSE;
85}
86
87static WINAPI DWORD
88dialog (void *)
89{
90 int rv = 0;
91 MSG m;
92 HANDLE ins_dialog = CreateDialog (hinstance, MAKEINTRESOURCE (IDD_INSTATUS),
93 0, dialog_proc);
94 if (ins_dialog == 0)
95 fatal ("create dialog");
96 ShowWindow (ins_dialog, SW_SHOWNORMAL);
97 UpdateWindow (ins_dialog);
98 while (GetMessage (&m, 0, 0, 0) > 0) {
99 TranslateMessage (&m);
100 DispatchMessage (&m);
101 }
102}
103
104static DWORD start_tics;
105
106static void
107init_dialog ()
108{
109 if (ins_dialog == 0)
110 {
111 DWORD tid;
112 HANDLE thread;
113 init_event = CreateEvent (0, 0, 0, 0);
114 thread = CreateThread (0, 0, dialog, 0, 0, &tid);
115 WaitForSingleObject (init_event, 10000);
116 CloseHandle (init_event);
117 SendMessage (ins_pprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
118 SendMessage (ins_iprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
119 SendMessage (ins_diskfull, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
120 }
121
122 SetWindowText (ins_pkgname, "");
123 SetWindowText (ins_filename, "");
124 SendMessage (ins_pprogress, PBM_SETPOS, (WPARAM) 0, 0);
125 SendMessage (ins_iprogress, PBM_SETPOS, (WPARAM) 0, 0);
126 SendMessage (ins_diskfull, PBM_SETPOS, (WPARAM) 0, 0);
127 ShowWindow (ins_dialog, SW_SHOWNORMAL);
128 SetForegroundWindow (ins_dialog);
129}
130
131static void
132progress (int bytes)
133{
134 int perc;
135
136 if (package_bytes > 0)
137 {
138 perc = bytes * 100 / package_bytes;
139 SendMessage (ins_pprogress, PBM_SETPOS, (WPARAM) perc, 0);
140 }
141
142 if (total_bytes > 0)
143 {
144 perc = (total_bytes_sofar + bytes) * 100 / total_bytes;
145 SendMessage (ins_iprogress, PBM_SETPOS, (WPARAM) perc, 0);
146 }
147
148 int df = diskfull (root_dir);
149 SendMessage (ins_diskfull, PBM_SETPOS, (WPARAM) df, 0);
150}
151
152static void
153badrename (char *o, char *n)
154{
155 char buf[1000];
156 char *err = strerror (errno);
157 if (!err)
158 err = "(unknown error)";
159 note (IDS_ERR_RENAME, o, n, err);
160}
161
162#define pi (package[i].info[package[i].trust])
163
164#define LOOP_PACKAGES \
165 for (i=0; i<npackages; i++) \
166 if (package[i].action == ACTION_NEW \
167 || package[i].action == ACTION_UPGRADE)
168
169void
170do_install (HINSTANCE h)
171{
172 int i, num_installs = 0;
173 next_dialog = 0;
174
175 dismiss_url_status_dialog ();
176
177 init_dialog ();
178
179 total_bytes = 0;
180 total_bytes_sofar = 0;
181
182 LOOP_PACKAGES
183 {
184 total_bytes += pi.install_size;
185 }
186
187 LOOP_PACKAGES
188 {
189 char *local = pi.install, *cp, *fn, *base;
190
191 base = local;
192 for (cp=pi.install; *cp; cp++)
193 if (*cp == '/' || *cp == '\\' || *cp == ':')
194 base = cp+1;
195 SetWindowText (ins_pkgname, base);
196
197 gzFile lst = gzopen (concat (root_dir, "/etc/setup/",
198 package[i].name, ".lst.gz", 0),
199 "wb9");
200
201 package_bytes = pi.install_size;
202
203 tar_open (local);
204 while (fn = tar_next_file ())
205 {
206 char *dest_file;
207
208 while (*fn == '/' || *fn == '\\')
209 fn++;
210
211 if (lst)
212 gzprintf(lst, "%s\n", fn);
213
214 if (strncmp (fn, "usr/bin/", 8) == 0)
215 dest_file = concat(root_dir, "/bin/", fn+8, 0);
216 else if (strncmp (fn, "usr/lib/", 8) == 0)
217 dest_file = concat(root_dir, "/lib/", fn+8, 0);
218 else
219 dest_file = concat(root_dir, "/", fn, 0);
220
221 SetWindowText (ins_filename, dest_file);
222 tar_read_file (dest_file);
223
224 progress (tar_ftell ());
225 num_installs ++;
226 }
227 tar_close ();
228
229 total_bytes_sofar += pi.install_size;
230 progress (0);
231
232 if (lst)
233 gzclose (lst);
234 }
235
236 ShowWindow (ins_dialog, SW_HIDE);
237
238 if (num_installs == 0)
239 {
240 note (IDS_NOTHING_INSTALLED);
241 return;
242 }
243
244 char *odbn = concat (root_dir, "/etc/setup/installed.db", 0);
245 char *ndbn = concat (root_dir, "/etc/setup/installed.db.new", 0);
246 char *sdbn = concat (root_dir, "/etc/setup/installed.db.old", 0);
247
248 mkdir_p (0, ndbn);
249
250 FILE *odb = fopen (odbn, "rt");
251 FILE *ndb = fopen (ndbn, "wb");
252
253 if (!ndb)
254 {
255 char *err = strerror (errno);
256 if (!err)
257 err = "(unknown error)";
258 fatal (IDS_ERR_OPEN_WRITE, ndb, err);
259 }
260
261 if (odb)
262 {
263 char line[1000], pkg[1000];
264 int printit;
265 while (fgets (line, 1000, odb))
266 {
267 printit = 1;
268 sscanf(line, "%s", pkg);
269 LOOP_PACKAGES
270 {
271 if (strcmp (pkg, package[i].name) == 0)
272 {
273 printit = 0;
274 break;
275 }
276 }
277 if (printit)
278 fputs (line, ndb);
279 }
280
281 }
282 LOOP_PACKAGES
283 {
284 fprintf (ndb, "%s %s %d\n", package[i].name,
285 pi.install, pi.install_size);
286 }
287
288 if (odb)
289 fclose (odb);
290 fclose (ndb);
291
292 remove (sdbn);
293 if (odb && rename (odbn, sdbn))
294 badrename (odbn, sdbn);
295
296 remove (odbn);
297 if (rename (ndbn, odbn))
298 badrename (ndbn, odbn);
299
300 remove_mount ("/usr");
301 remove_mount ("/var");
302 remove_mount ("/lib");
303 remove_mount ("/bin");
304 remove_mount ("/etc");
305
306 int istext = (root_text == IDC_ROOT_TEXT) ? 1 : 0;
307
308 create_mount ("/", root_dir, istext);
309 create_mount ("/usr/bin", concat (root_dir, "/bin", 0), istext);
310 create_mount ("/usr/lib", concat (root_dir, "/lib", 0), istext);
311
312 note (IDS_INSTALL_COMPLETE);
313}
This page took 0.049273 seconds and 5 git commands to generate.