view netinstall/uninstall.cc @ 1330:4542b72c005e

[xemacs-hg @ 2003-03-01 07:25:26 by ben] build patch Makefile.in.in: Move src deletions to src/Makefile.in.in. dump-paths.el, dumped-lisp.el: Delete. Combine stuff into setup-paths.el. find-paths.el: Removed. Make this file contain generic routines only. Move stuff to compute Emacs roots to setup-paths.el. startup.el: Removed. Move these variables into setup-paths.el. setup-paths.el, startup.el: Removed. Combine all high-level code for computing the paths into setup-paths.el. Create new function startup-find-load-path to encapsulate all logic for computing `load-path'. Eliminate invocation-directory and invocation-name parameters since there is no point (false generality) -- the code references other globals, which cannot be specified. Eliminate some code duplicated between setup-paths.el and startup.el. Clean up the debug-paths code and output load-path in addition. Add logic to paths-emacs-root-p to support separated source and build trees. loadup.el, make-docfile.el, update-elc-2.el, update-elc.el: Rewrite to allow for separated source and build trees, as may occur in MS Windows. NOTE TO BUILD HACKERS: loadup.el, make-docfile.el, update-elc.el and update-elc-2.el made two assumptions that are no longer correct: (1) The source and build trees are in the same place. (2) They can make assumptions about where `.' is. These files now compute the locations of the source and build roots at the top of the file. *ALL* constant file names or path snippets must now be made absolute using expand-file-name and one of these roots. dumped-lisp.el, packages.el: Removed. Remove some unused lists of Lisp files. packages-hardcoded-lisp (empty, in any case) moved to dumped-lisp.el. startup.el: When a compiled init file is out-of-date wrt the uncompiled version, load the uncompiled version and issue a nasty warning. update-elc-2.el: Force touching of auto-autoloads files when REBUILD_AUTOLOADS was set. update-elc.el: Fix code that checks whether dumping is necessary to check against xemacs.dmp, not xemacs.exe, when Unix and pdump. lwlib-Xm.c: Fix compile warning. README, config.inc.samp, xemacs.mak: -- Major reorganization and cleanup. -- Add support for separated build tree and source tree. -- Delete all support for X Windows building, since it's totally bit-rotten and will never be fixed up. Instruct people to use Cygwin if they want such support. make-build-dir: New script to create a skeleton build tree for use with separated build and source tree compilation. m/acorn.h, m/alliant-2800.h, m/alliant.h, m/altos.h, m/amdahl.h, m/arm.h, m/att3b.h, m/aviion.h, m/clipper.h, m/cnvrgnt.h, m/convex.h, m/cydra5.h, m/delta.h, m/delta88k.h, m/dpx2.h, m/elxsi.h, m/ews4800r.h, m/gould.h, m/hp800.h, m/hp9000s300.h, m/i860.h, m/ibmps2-aix.h, m/ibmrs6000.h, m/ibmrt-aix.h, m/ibmrt.h, m/intel386.h, m/iris4d.h, m/iris5d.h, m/iris6d.h, m/irist.h, m/m68k.h, m/masscomp.h, m/mg1.h, m/mips-nec.h, m/mips-siemens.h, m/mips.h, m/nh3000.h, m/nh4000.h, m/ns32000.h, m/plexus.h, m/powerpc.h, m/sequent-ptx.h, m/sequent.h, m/sgi-challenge.h, m/stride.h, m/tad68k.h, m/targon31.h, m/tekxd88.h, m/template.h, m/tower32.h, m/tower32v3.h, m/ustation.h, m/wicat.h, m/xps100.h, data.c, doc.c, editfns.c, emacs.c, lrecord.h, ntheap.c, process-unix.c, sysdep.c, unexec.c: Delete all support for bit-rotten CANNOT_DUMP. Just use pdump. Makefile.in.in: Lots o' cleanup. Use names like LISP, SRC instead of lispdir, srcdir, for consistency with xemacs.mak and the conventions in the rest of the file. Eliminate use of ${...} in favor of $(...), to make it easier to move code between this file and xemacs.mak. Fix dependency handling wrt NEEDTODUMP to eliminate problems some people (e.g. Vin) have been seeing with non-GNU makes. Write a long section about the subtle but oh-so-important differences in dependency processing between nmake, make, and GNU make. Add unicode-encapsulate target, from xemacs.mak. chartab.c, lrecord.h: Fix crash due to attempt to free objects across dump/undump.
author ben
date Sat, 01 Mar 2003 07:25:56 +0000
parents a307f9a2021d
children
line wrap: on
line source

/*
 * Copyright (c) 2000, Red Hat, Inc.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by DJ Delorie <dj@cygnus.com>
 *
 */

/* The purpose of this file is to intall all the packages selected in
   the install list (in ini.h).  Note that we use a separate thread to
   maintain the progress dialog, so we avoid the complexity of
   handling two tasks in one thread.  We also create or update all the
   files in /etc/setup and create the mount points. */

#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#ifndef WIN32_NATIVE
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <zlib.h>

#include "win32.h"
#include "commctrl.h"

#include "resource.h"
#include "ini.h"
#include "dialog.h"
#include "concat.h"
#include "geturl.h"
#include "mkdir.h"
#include "state.h"
#include "tar.h"
#include "diskfull.h"
#include "msg.h"
#include "regedit.h"
#include "reginfo.h"
#include "log.h"
#include "hash.h"
#include "desktop.h"

#include "port.h"

#define XM_DONE (WM_USER + 101)

static HWND unins_dialog = 0;
static HWND unins_action = 0;
static HWND unins_pkgname = 0;
static HWND unins_filename = 0;
static HWND unins_pprogress = 0;
static HWND unins_iprogress = 0;
static HWND unins_diskfull = 0;
static HANDLE init_event;

static int package_bytes = 0;
static int uninstall_started = 0;

extern char * map_filename (char *fn, int type);
static void start_uninstall ();

char *
base (char *s);

static BOOL
dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
{
  switch (id)
    {
    case IDCANCEL:
      exit_setup (1);
    case IDOK:
      if (uninstall_started == 0) {
	uninstall_started = 1;
	start_uninstall();
      }
      else
	exit_setup(0);
      break;
    }
  return FALSE;
}

static BOOL CALLBACK
dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message)
    {
    case WM_INITDIALOG:
      unins_dialog = h;
      unins_action = GetDlgItem (h, IDC_UNINS_ACTION);
      unins_pkgname = GetDlgItem (h, IDC_UNINS_PKG);
      unins_filename = GetDlgItem (h, IDC_UNINS_FILE);
      unins_pprogress = GetDlgItem (h, IDC_UNINS_PPROGRESS);
      unins_iprogress = GetDlgItem (h, IDC_UNINS_IPROGRESS);
      unins_diskfull = GetDlgItem (h, IDC_UNINS_DISKFULL);
      SendMessage (unins_pprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
      SendMessage (unins_iprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
      SendMessage (unins_diskfull, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
      SetWindowText (unins_pkgname, "");
      SetWindowText (unins_filename, "");
      SendMessage (unins_pprogress, PBM_SETPOS, (WPARAM) 0, 0);
      SendMessage (unins_iprogress, PBM_SETPOS, (WPARAM) 0, 0);
      SendMessage (unins_diskfull, PBM_SETPOS, (WPARAM) 0, 0);
      return FALSE;

    case XM_DONE:
      {
	SetWindowText (GetDlgItem (h, IDOK), "Ok");
	LONG style = GetWindowLong (GetDlgItem (h, IDCANCEL),
				    GWL_STYLE);
	SetWindowLong (GetDlgItem (h, IDCANCEL),
		       GWL_STYLE, style & WS_DISABLED);
      }
      return FALSE;
      
    case WM_COMMAND:
      return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
    }
  return DefWindowProc (h, message, wParam, lParam);
}

static DWORD WINAPI uninstall_all (void *);

static void
start_uninstall ()
{
  DWORD tid;
  HANDLE thread;
  init_event = CreateEvent (0, 0, 0, 0);
  thread = CreateThread (0, 0, uninstall_all, 0, 0, &tid);
  WaitForSingleObject (init_event, 10000);
  CloseHandle (init_event);
}

static void
progress (int bytes, int num)
{
  int perc;
  log (0, "%d bytes", bytes);
  if (package_bytes > 100)
    {
      perc = (bytes * 100) / package_bytes;
      SendMessage (unins_pprogress, PBM_SETPOS, (WPARAM) perc, 0);
    }

  if (npackages > 0)
    {
      perc = (num * 100) / npackages;
      SendMessage (unins_iprogress, PBM_SETPOS, (WPARAM) perc, 0);
    }
}

static int num_installs, num_uninstalls;

static void
uninstall_one (char *name, int type, int num)
{
  hash dirs;
  char line[_MAX_PATH];
  char* fname = (type == TY_GENERIC ? 
		 concat (root_dir, XEMACS_PACKAGE_DIR, "pkginfo/MANIFEST.",
			 name,  0) :
		 concat (root_dir, XEMACS_SETUP_DIR, "MANIFEST.", name,  0));

  FILE* lst = fopen (fname, "rb");
  int pos = 0;

  if (lst)
    {
      fseek (lst, 0, SEEK_END);
      package_bytes = ftell (lst);
      fseek (lst, 0, SEEK_SET);
  
      SetWindowText (unins_pkgname, name);
      SetWindowText (unins_action, "Uninstalling...");
      log (0, "uninstalling %s", name);

      while (fgets (line, sizeof (line), lst))
	{
	  progress (pos, num);
	  pos += strlen(line);
	  if (line[strlen(line)-1] == '\n')
	    line[strlen(line)-1] = 0;

	  dirs.add_subdirs (line);

	  char *d = map_filename (line, type);
	  DWORD dw = GetFileAttributes (d);
	  if (dw != 0xffffffff && !(dw & FILE_ATTRIBUTE_DIRECTORY))
	    {
	      log (LOG_BABBLE, "unlink %s", d);
	      DeleteFile (d);
	    }
	}
      fclose (lst);
      remove (fname);

      dirs.reverse_sort ();
      char *subdir = 0;
      while ((subdir = dirs.enumerate (subdir)) != 0)
	{
	  char *d = map_filename (subdir, type);
	  if (RemoveDirectory (d))
	    log (LOG_BABBLE, "rmdir %s", d);
	}
      num_uninstalls ++;
    }
}

void
do_uninstall (HINSTANCE h)
{
  num_installs = 0, num_uninstalls = 0;

  next_dialog = 0;		// we're done after this

  if (!root_dir)
    fatal ("no installation found");

  int rv = DialogBox (h, MAKEINTRESOURCE (IDD_UNINSTALL), 0, dialog_proc);
  if (rv == -1)
    fatal (IDS_DIALOG_FAILED);
}

static void
read_installed_db ()
{
  if (!root_dir)
    return;

  char line[1000], pkg[1000], inst[1000], src[1000];
  int instsz, srcsz;

  FILE *db = fopen (concat (root_dir, XEMACS_SETUP_DIR, "installed.db", 0), "rt");
  if (!db)
    return;

  while (fgets (line, 1000, db))
    {
      src[0] = 0;
      srcsz = 0;
      sscanf (line, "%s %s %d %s %d", pkg, inst, &instsz, src, &srcsz);

      log (0, "read %s", pkg);
      Package* np = new_package(strdup(pkg));
      pinfo(*np).install = inst;
      pinfo(*np).install_size = instsz;
      // pick up versoin
      char *v, *d;
      for (v=base (inst); *v; v++)
	if (*v == '-' && isdigit(v[1]))
	  {
	    v++;
	    break;
	  }
      if (!v)
	v = inst;
      for (d=v; *d; d++)
	if (strncmp (d, ".tar", 4) == 0
	    || strncmp (d, "-pkg", 4) == 0)
	  {
	    *d = 0;
	    break;
	  }
      if (v[0])
	pinfo(*np).version = strdup (v);
      else
	pinfo(*np).version = "0";
      // Crude but effective
      if (pkg != 0)
	if (strncmp ("xemacs-i686", pkg, 11) == 0
	    || (strncmp ("xemacs-i586", pkg, 11) == 0))
	  {
	    np->type = install_type;
	    xemacs_package = np;
	  }
    }
  fclose (db);
}

static DWORD WINAPI
uninstall_all (void *)
{
  int i;
  SetEvent (init_event);

  int df = diskfull (root_dir);
  SendMessage (unins_diskfull, PBM_SETPOS, (WPARAM) df, 0);

  read_installed_db();

  log (0, "There are %d packages\n", npackages);
  for (i=0; i<npackages; i++)
    {
      log (0, "uninstalling %s\n", package[i].name);
      uninstall_one (package[i].name, package[i].type, i);
    }

  PostMessage (unins_dialog, XM_DONE, 0, 0);

  remove (concat (root_dir, XEMACS_SETUP_DIR, "installed.db.old", 0));
  remove (concat (root_dir, XEMACS_SETUP_DIR, "installed.db", 0));

  remove_desktop_setup();
  remove_xemacs_root();
  remove_uninstall_path();

  if (num_installs == 0)
    {
      //      exit_msg = IDS_UNINSTALL_COMPLETE;
      return FALSE;
    }

  return FALSE;
}