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