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