657
|
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 <io.h>
|
|
23 #include <stdio.h>
|
|
24 #include <stdlib.h>
|
|
25 #include <ctype.h>
|
|
26 #ifndef WIN32_NATIVE
|
|
27 #include <unistd.h>
|
|
28 #endif
|
|
29 #include <sys/types.h>
|
|
30 #include <sys/stat.h>
|
|
31 #include <errno.h>
|
|
32 #include <zlib.h>
|
|
33
|
|
34 #include "win32.h"
|
|
35 #include "commctrl.h"
|
|
36
|
|
37 #include "resource.h"
|
|
38 #include "ini.h"
|
|
39 #include "dialog.h"
|
|
40 #include "concat.h"
|
|
41 #include "geturl.h"
|
|
42 #include "mkdir.h"
|
|
43 #include "state.h"
|
|
44 #include "tar.h"
|
|
45 #include "diskfull.h"
|
|
46 #include "msg.h"
|
|
47 #include "regedit.h"
|
|
48 #include "reginfo.h"
|
|
49 #include "log.h"
|
|
50 #include "hash.h"
|
|
51
|
|
52 #include "port.h"
|
|
53
|
|
54 #define XM_DONE (WM_USER + 101)
|
|
55
|
|
56 static HWND unins_dialog = 0;
|
|
57 static HWND unins_action = 0;
|
|
58 static HWND unins_pkgname = 0;
|
|
59 static HWND unins_filename = 0;
|
|
60 static HWND unins_pprogress = 0;
|
|
61 static HWND unins_iprogress = 0;
|
|
62 static HWND unins_diskfull = 0;
|
|
63 static HANDLE init_event;
|
|
64
|
|
65 static int package_bytes = 0;
|
|
66 static int uninstall_started = 0;
|
|
67
|
|
68 extern char * map_filename (char *fn, int type);
|
|
69 void remove_desktop_setup ();
|
|
70 static void start_uninstall ();
|
666
|
71 extern char* find_xemacs_exe_name();
|
657
|
72
|
|
73 char *
|
|
74 base (char *s);
|
|
75
|
|
76 static BOOL
|
|
77 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
|
|
78 {
|
|
79 switch (id)
|
|
80 {
|
|
81 case IDCANCEL:
|
|
82 exit_setup (1);
|
|
83 case IDOK:
|
|
84 if (uninstall_started == 0) {
|
|
85 uninstall_started = 1;
|
|
86 start_uninstall();
|
|
87 }
|
|
88 else
|
|
89 exit_setup(0);
|
|
90 break;
|
|
91 }
|
|
92 return FALSE;
|
|
93 }
|
|
94
|
|
95 static BOOL CALLBACK
|
|
96 dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
|
|
97 {
|
|
98 switch (message)
|
|
99 {
|
|
100 case WM_INITDIALOG:
|
|
101 unins_dialog = h;
|
|
102 unins_action = GetDlgItem (h, IDC_UNINS_ACTION);
|
|
103 unins_pkgname = GetDlgItem (h, IDC_UNINS_PKG);
|
|
104 unins_filename = GetDlgItem (h, IDC_UNINS_FILE);
|
|
105 unins_pprogress = GetDlgItem (h, IDC_UNINS_PPROGRESS);
|
|
106 unins_iprogress = GetDlgItem (h, IDC_UNINS_IPROGRESS);
|
|
107 unins_diskfull = GetDlgItem (h, IDC_UNINS_DISKFULL);
|
|
108 SendMessage (unins_pprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
|
|
109 SendMessage (unins_iprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
|
|
110 SendMessage (unins_diskfull, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
|
|
111 SetWindowText (unins_pkgname, "");
|
|
112 SetWindowText (unins_filename, "");
|
|
113 SendMessage (unins_pprogress, PBM_SETPOS, (WPARAM) 0, 0);
|
|
114 SendMessage (unins_iprogress, PBM_SETPOS, (WPARAM) 0, 0);
|
|
115 SendMessage (unins_diskfull, PBM_SETPOS, (WPARAM) 0, 0);
|
|
116 return FALSE;
|
|
117
|
|
118 case XM_DONE:
|
|
119 {
|
|
120 SetWindowText (GetDlgItem (h, IDOK), "Ok");
|
|
121 LONG style = GetWindowLong (GetDlgItem (h, IDCANCEL),
|
|
122 GWL_STYLE);
|
|
123 SetWindowLong (GetDlgItem (h, IDCANCEL),
|
|
124 GWL_STYLE, style & WS_DISABLED);
|
|
125 }
|
|
126 return FALSE;
|
|
127
|
|
128 case WM_COMMAND:
|
|
129 return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
|
|
130 }
|
|
131 return DefWindowProc (h, message, wParam, lParam);
|
|
132 }
|
|
133
|
|
134 static DWORD WINAPI uninstall_all (void *);
|
|
135
|
|
136 static void
|
|
137 start_uninstall ()
|
|
138 {
|
|
139 DWORD tid;
|
|
140 HANDLE thread;
|
|
141 init_event = CreateEvent (0, 0, 0, 0);
|
|
142 thread = CreateThread (0, 0, uninstall_all, 0, 0, &tid);
|
|
143 WaitForSingleObject (init_event, 10000);
|
|
144 CloseHandle (init_event);
|
|
145 }
|
|
146
|
|
147 static void
|
|
148 progress (int bytes, int num)
|
|
149 {
|
|
150 int perc;
|
|
151 log (0, "%d bytes", bytes);
|
|
152 if (package_bytes > 100)
|
|
153 {
|
|
154 perc = (bytes * 100) / package_bytes;
|
|
155 SendMessage (unins_pprogress, PBM_SETPOS, (WPARAM) perc, 0);
|
|
156 }
|
|
157
|
|
158 if (npackages > 0)
|
|
159 {
|
|
160 perc = (num * 100) / npackages;
|
|
161 SendMessage (unins_iprogress, PBM_SETPOS, (WPARAM) perc, 0);
|
|
162 }
|
|
163 }
|
|
164
|
|
165 static int num_installs, num_uninstalls;
|
|
166
|
|
167 static void
|
|
168 uninstall_one (char *name, int type, int num)
|
|
169 {
|
|
170 hash dirs;
|
|
171 char line[_MAX_PATH];
|
|
172 char* fname = (type == TY_GENERIC ?
|
|
173 concat (root_dir, XEMACS_PACKAGE_DIR, "pkginfo/MANIFEST.",
|
|
174 name, 0) :
|
|
175 concat (root_dir, XEMACS_SETUP_DIR, "MANIFEST.", name, 0));
|
|
176
|
|
177 FILE* lst = fopen (fname, "rb");
|
|
178 int pos = 0;
|
|
179
|
|
180 if (lst)
|
|
181 {
|
|
182 fseek (lst, 0, SEEK_END);
|
|
183 package_bytes = ftell (lst);
|
|
184 fseek (lst, 0, SEEK_SET);
|
|
185
|
|
186 SetWindowText (unins_pkgname, name);
|
|
187 SetWindowText (unins_action, "Uninstalling...");
|
|
188 log (0, "uninstalling %s", name);
|
|
189
|
|
190 while (fgets (line, sizeof (line), lst))
|
|
191 {
|
|
192 progress (pos, num);
|
|
193 pos += strlen(line);
|
|
194 if (line[strlen(line)-1] == '\n')
|
|
195 line[strlen(line)-1] = 0;
|
|
196
|
|
197 dirs.add_subdirs (line);
|
|
198
|
|
199 char *d = map_filename (line, type);
|
|
200 DWORD dw = GetFileAttributes (d);
|
|
201 if (dw != 0xffffffff && !(dw & FILE_ATTRIBUTE_DIRECTORY))
|
|
202 {
|
|
203 log (LOG_BABBLE, "unlink %s", d);
|
|
204 DeleteFile (d);
|
|
205 }
|
|
206 }
|
|
207 fclose (lst);
|
|
208 remove (fname);
|
|
209
|
|
210 dirs.reverse_sort ();
|
|
211 char *subdir = 0;
|
|
212 while ((subdir = dirs.enumerate (subdir)) != 0)
|
|
213 {
|
|
214 char *d = map_filename (subdir, type);
|
|
215 if (RemoveDirectory (d))
|
|
216 log (LOG_BABBLE, "rmdir %s", d);
|
|
217 }
|
|
218 num_uninstalls ++;
|
|
219 }
|
|
220 }
|
|
221
|
|
222 void
|
|
223 do_uninstall (HINSTANCE h)
|
|
224 {
|
|
225 num_installs = 0, num_uninstalls = 0;
|
|
226
|
|
227 next_dialog = 0; // we're done after this
|
|
228
|
|
229 if (!root_dir)
|
|
230 fatal ("no installation found");
|
|
231
|
|
232 int rv = DialogBox (h, MAKEINTRESOURCE (IDD_UNINSTALL), 0, dialog_proc);
|
|
233 if (rv == -1)
|
|
234 fatal (IDS_DIALOG_FAILED);
|
|
235 }
|
|
236
|
|
237 static void
|
|
238 read_installed_db ()
|
|
239 {
|
|
240 if (!root_dir)
|
|
241 return;
|
|
242
|
|
243 char line[1000], pkg[1000], inst[1000], src[1000];
|
|
244 int instsz, srcsz;
|
|
245
|
|
246 FILE *db = fopen (concat (root_dir, XEMACS_SETUP_DIR, "installed.db", 0), "rt");
|
|
247 if (!db)
|
|
248 return;
|
|
249
|
|
250 while (fgets (line, 1000, db))
|
|
251 {
|
|
252 src[0] = 0;
|
|
253 srcsz = 0;
|
|
254 sscanf (line, "%s %s %d %s %d", pkg, inst, &instsz, src, &srcsz);
|
|
255
|
|
256 log (0, "read %s", pkg);
|
|
257 Package* np = new_package(strdup(pkg));
|
|
258 pinfo(*np).install = inst;
|
|
259 pinfo(*np).install_size = instsz;
|
|
260 // pick up versoin
|
|
261 char *v, *d;
|
|
262 for (v=base (inst); *v; v++)
|
|
263 if (*v == '-' && isdigit(v[1]))
|
|
264 {
|
|
265 v++;
|
|
266 break;
|
|
267 }
|
|
268 if (!v)
|
|
269 v = inst;
|
|
270 for (d=v; *d; d++)
|
|
271 if (strncmp (d, ".tar", 4) == 0
|
|
272 || strncmp (d, "-pkg", 4) == 0)
|
|
273 {
|
|
274 *d = 0;
|
|
275 break;
|
|
276 }
|
|
277 if (v[0])
|
|
278 pinfo(*np).version = strdup (v);
|
|
279 else
|
|
280 pinfo(*np).version = "0";
|
|
281 // Crude but effective
|
|
282 if (pkg != 0)
|
|
283 if (strncmp ("xemacs-i686", pkg, 11) == 0
|
|
284 || (strncmp ("xemacs-i586", pkg, 11) == 0))
|
666
|
285 {
|
|
286 np->type = install_type;
|
|
287 xemacs_package = np;
|
|
288 }
|
657
|
289 }
|
|
290 fclose (db);
|
|
291 }
|
|
292
|
|
293 static DWORD WINAPI
|
|
294 uninstall_all (void *)
|
|
295 {
|
|
296 int i;
|
|
297 SetEvent (init_event);
|
|
298
|
|
299 int df = diskfull (root_dir);
|
|
300 SendMessage (unins_diskfull, PBM_SETPOS, (WPARAM) df, 0);
|
|
301
|
|
302 read_installed_db();
|
|
303
|
|
304 log (0, "There are %d packages\n", npackages);
|
|
305 for (i=0; i<npackages; i++)
|
|
306 {
|
|
307 log (0, "uninstalling %s\n", package[i].name);
|
|
308 uninstall_one (package[i].name, package[i].type, i);
|
|
309 }
|
|
310
|
|
311 PostMessage (unins_dialog, XM_DONE, 0, 0);
|
|
312
|
666
|
313 remove (concat (root_dir, XEMACS_SETUP_DIR, "installed.db.old", 0));
|
|
314 remove (concat (root_dir, XEMACS_SETUP_DIR, "installed.db", 0));
|
657
|
315
|
666
|
316 remove_desktop_setup();
|
657
|
317 remove_xemacs_root();
|
|
318 remove_uninstall_path();
|
|
319
|
|
320 if (num_installs == 0)
|
|
321 {
|
|
322 // exit_msg = IDS_UNINSTALL_COMPLETE;
|
|
323 return FALSE;
|
|
324 }
|
|
325
|
|
326 return FALSE;
|
|
327 }
|