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