Commit 4a9caffb authored by Eskil Heyn Olsen's avatar Eskil Heyn Olsen
Browse files

Doing a lot of slashing in the uninstall part.

	* components/services/install/command-line/Makefile.am:
	* components/services/install/command-line/eazel-uninstall.c:
	(set_parameters_from_command_line), (progress_signal),
	(uninstall_failed), (dep_check), (create_package), (done), (main):
	* components/services/install/lib/Makefile.am:
	* components/services/install/lib/eazel-install-object.c:
	(eazel_install_uninstall_packages):
	* components/services/install/lib/eazel-install-rpm-glue.c:
	(uninstall_packages), (uninstall_a_package), (do_rpm_uninstall),
	(eazel_install_prepare_rpm_system), (eazel_install_add_to_rpm_set),
	(eazel_install_add_to_set), (eazel_install_fetch_rpm_dependencies),
	(eazel_install_do_dependency_check), (eazel_install_ensure_deps),
	(eazel_uninstall_upward_traverse),
	(eazel_uninstall_downward_traverse), (eazel_uninstall_globber):
	Doing a lot of slashing in the uninstall part.

	* nautilus-installer/src/Makefile:
	This is still checked in, as the installer isn't part of the build
	tree.
parent e5c61a01
2000-06-29 Eskil Heyn Olsen <eskil@eazel.com>
* components/services/install/command-line/Makefile.am:
* components/services/install/command-line/eazel-uninstall.c:
(set_parameters_from_command_line), (progress_signal),
(uninstall_failed), (dep_check), (create_package), (done), (main):
* components/services/install/lib/Makefile.am:
* components/services/install/lib/eazel-install-object.c:
(eazel_install_uninstall_packages):
* components/services/install/lib/eazel-install-rpm-glue.c:
(uninstall_packages), (uninstall_a_package), (do_rpm_uninstall),
(eazel_install_prepare_rpm_system), (eazel_install_add_to_rpm_set),
(eazel_install_add_to_set), (eazel_install_fetch_rpm_dependencies),
(eazel_install_do_dependency_check), (eazel_install_ensure_deps),
(eazel_uninstall_upward_traverse),
(eazel_uninstall_downward_traverse), (eazel_uninstall_globber):
Doing a lot of slashing in the uninstall part.
* nautilus-installer/src/Makefile:
This is still checked in, as the installer isn't part of the build
tree.
2000-06-29 Pavel Cisler <pavel@eazel.com>
Fixed some memory leaks.
......
......@@ -4,9 +4,6 @@ CPPFLAGS = \
-DPREFIX=\"$(prefix)\" \
-DG_LOG_DOMAIN=\"Nautilus-Services\"
## CFLAGS = -O -g
## LDFLAGS = -static
INCLUDES = \
-I$(top_srcdir) \
-I$(top_builddir) \
......@@ -30,9 +27,13 @@ LDADD = \
$(RPM_LIBS) \
$(NULL)
bin_PROGRAMS = eazel-install
bin_PROGRAMS = eazel-install eazel-uninstall
eazel_install_SOURCES = \
eazel-alt-install-corba.c \
$(NULL)
eazel_uninstall_SOURCES = \
eazel-uninstall.c \
$(NULL)
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
* Copyright (C) 2000 Eazel, 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors: Eskil Heyn Olsen <eskil@eazel.com>
*
*/
#include <config.h>
#include <gnome.h>
#include <liboaf/liboaf.h>
#include <bonobo.h>
#include <eazel-install-types.h>
#include <eazel-install-corba-types.h>
#include <eazel-install-corba-callback.h>
#include <trilobite-eazel-install.h>
#include <libtrilobite/libtrilobite.h>
#define PACKAGE_FILE_NAME "package-list.xml"
#define DEFAULT_CONFIG_FILE "/var/eazel/services/eazel-services-config.xml"
#define DEFAULT_HOSTNAME "testmachine.eazel.com"
#define DEFAULT_PORT_NUMBER 80
#define DEFAULT_PROTOCOL PROTOCOL_HTTP
#define DEFAULT_TMP_DIR "/tmp/eazel-install"
#define DEFAULT_RPMRC "/usr/lib/rpm/rpmrc"
#define DEFAULT_REMOTE_PACKAGE_LIST "/package-list.xml"
#define DEFAULT_REMOTE_RPM_DIR "/RPMS"
#define DEFAULT_LOG_FILE "/tmp/eazel-install/ulog"
#define OAF_ID "OAFIID:trilobite_eazel_install_service:8ff6e815-1992-437c-9771-d932db3b4a17"
/* Popt stuff */
int arg_dry_run,
arg_http,
arg_ftp,
arg_local,
arg_debug,
arg_port,
arg_delay;
char *arg_server,
*arg_config_file,
*arg_local_list,
*arg_tmp_dir,
*arg_input_list;
CORBA_ORB orb;
CORBA_Environment ev;
static const struct poptOption options[] = {
{"debug", '\0', POPT_ARG_NONE, &arg_debug, 0 , N_("Show debug output"), NULL},
{"test", 't', POPT_ARG_NONE, &arg_dry_run, 0, N_("Test run"), NULL},
{"delay", '\0', POPT_ARG_NONE, &arg_delay, 0 , N_("10 sec delay after starting service"), NULL},
{"config", '\0', POPT_ARG_STRING, &arg_config_file, 0, N_("Specify config file (/var/eazel/services/eazel-services-config.xml)"), NULL},
{NULL, '\0', 0, NULL, 0}
};
#define check_ev(s) if (ev._major!=CORBA_NO_EXCEPTION) { g_warning ("%s: Caught exception %s", s, CORBA_exception_id (&ev)); }
static void
set_parameters_from_command_line (Trilobite_Eazel_Install service)
{
if (!arg_debug) {
Trilobite_Eazel_Install__set_log_file (service, DEFAULT_LOG_FILE, &ev);
check_ev ("set_log_file");
}
if (arg_tmp_dir == NULL) {
arg_tmp_dir = g_strdup (DEFAULT_TMP_DIR);
}
if (arg_dry_run) {
Trilobite_Eazel_Install__set_test_mode (service, TRUE, &ev);
check_ev ("set_test_mode");
}
Trilobite_Eazel_Install__set_tmp_dir (service, arg_tmp_dir, &ev);
check_ev ("set_tmp_dir");
}
static void
progress_signal (EazelInstallCallback *service,
const PackageData *pack,
int amount,
int total,
char *title)
{
fprintf (stdout, "%s - %s %% %f\r", title, pack->name,
(total ? ((float)
((((float) amount) / total) * 100))
: 100.0));
fflush (stdout);
if (amount == total && total!=0) {
fprintf (stdout, "\n");
}
}
/*
This dumps the entire tree for the failed package.
*/
static void
uninstall_failed (EazelInstallCallback *service,
const PackageData *pd,
gchar *indent)
{
GList *iterator;
if (pd->toplevel) {
fprintf (stdout, "\n***The package %s failed. Here's the dep tree\n", pd->name);
}
switch (pd->status) {
case PACKAGE_DEPENDENCY_FAIL:
fprintf (stdout, "%s-%s FAILED\n", indent, rpmfilename_from_packagedata (pd));
break;
case PACKAGE_CANNOT_OPEN:
fprintf (stdout, "%s-%s NOT FOUND\n", indent, rpmfilename_from_packagedata (pd));
break;
case PACKAGE_SOURCE_NOT_SUPPORTED:
fprintf (stdout, "%s-%s is a source package\n", indent, rpmfilename_from_packagedata (pd));
break;
case PACKAGE_BREAKS_DEPENDENCY:
fprintf (stdout, "%s-%s breaks\n", indent, rpmfilename_from_packagedata (pd));
break;
default:
fprintf (stdout, "%s-%s\n", indent, rpmfilename_from_packagedata (pd));
break;
}
for (iterator = pd->soft_depends; iterator; iterator = iterator->next) {
PackageData *pack;
char *indent2;
indent2 = g_strconcat (indent, iterator->next ? " |" : " " , NULL);
pack = (PackageData*)iterator->data;
uninstall_failed (service, pack, indent2);
g_free (indent2);
}
for (iterator = pd->breaks; iterator; iterator = iterator->next) {
PackageData *pack;
char *indent2;
indent2 = g_strconcat (indent, iterator->next ? " |" : " " , NULL);
pack = (PackageData*)iterator->data;
uninstall_failed (service, pack, indent2);
g_free (indent2);
}
}
static void
dep_check (EazelInstallCallback *service,
const PackageData *package,
const PackageData *needs,
gpointer unused)
{
fprintf (stdout, "Doing dependency check for %s - need %s\n", package->name, needs->name);
}
static PackageData*
create_package (char *name)
{
PackageData *pack;
pack = packagedata_new ();
pack->name = g_strdup (name);
pack->toplevel = TRUE;
return pack;
}
static void
done (EazelInstallCallback *service,
gpointer unused)
{
fprintf (stderr, "\nDone\n");
eazel_install_callback_destroy (GTK_OBJECT (service));
gtk_main_quit ();
}
int main(int argc, char *argv[]) {
poptContext ctxt;
GList *packages;
GList *categories;
char *str;
EazelInstallCallback *cb;
CORBA_exception_init (&ev);
/* Seems that bonobo_main doens't like
not having gnome_init called, dies in a
X call, yech */
#if 1
gnome_init_with_popt_table ("Eazel Uninstall", "1.0", argc, argv, options, 0, &ctxt);
#else
gtk_type_init ();
gnomelib_init ("Eazel Uninstall", "1.0");
gnomelib_register_popt_table (options, "Eazel Uninstall");
ctxt = gnomelib_parse_args (argc, argv, 0);
#endif
packages = NULL;
categories = NULL;
/* If there are more args, get them and parse them as packages */
while ((str = poptGetArg (ctxt)) != NULL) {
packages = g_list_prepend (packages, create_package (str));
}
if (packages) {
CategoryData *category;
category = g_new0 (CategoryData, 1);
category->packages = packages;
categories = g_list_prepend (NULL, category);
} else {
g_message ("Using remote list ");
}
/* Chech that we're root and on a redhat system */
if (check_for_root_user() == FALSE) {
fprintf (stderr, "*** This tool requires root access.\n");
}
if (check_for_redhat () == FALSE) {
fprintf (stderr, "*** This tool can only be used on RedHat.\n");
}
orb = oaf_init (argc, argv);
if (bonobo_init (NULL, NULL, NULL) == FALSE) {
g_error ("Could not init bonobo");
}
bonobo_activate ();
cb = eazel_install_callback_new ();
if (arg_delay) {
sleep (10);
}
set_parameters_from_command_line (eazel_install_callback_corba_objref (cb));
gtk_signal_connect (GTK_OBJECT (cb), "uninstall_progress", progress_signal, "Unnstall progress");
gtk_signal_connect (GTK_OBJECT (cb), "uninstall_failed", uninstall_failed, "");
gtk_signal_connect (GTK_OBJECT (cb), "dependency_check", dep_check, NULL);
gtk_signal_connect (GTK_OBJECT (cb), "done", done, NULL);
eazel_install_callback_uninstall_packages (cb, categories, &ev);
fprintf (stdout, "\nEntering main loop...\n");
bonobo_main ();
/* Corba cleanup */
CORBA_exception_free (&ev);
return 0;
};
......@@ -5,6 +5,8 @@ CPPFLAGS = \
-DG_LOG_DOMAIN=\"eazel-install\" \
$(NULL)
CFLAGS=-g -O
INCLUDES = \
-I$(top_srcdir) \
-I$(top_builddir) \
......@@ -36,7 +38,7 @@ noinst_HEADERS = \
libeazelinstallincludedir=$(includedir)/eazel-install
libeazelinstall_HEADERS = \
libeazelinstallinclude_HEADERS = \
eazel-install-public.h \
$(NULL)
......@@ -68,17 +70,20 @@ CORBA_GENERATED = \
trilobite-eazel-install-common.c \
trilobite-eazel-install-skels.c \
trilobite-eazel-install-stubs.c \
trilobite-eazel-install.h \
$(NULL)
IDLDIR = $(top_srcdir)/components/services/install/idl
IDL = $(IDLDIR)/trilobite-eazel-install.idl
$(libinstall_base_a_SOURCES) $(CORBA_GENERATED): trilobite-eazel-install.h
trilobite-eazel-install.h: $(IDL)
$(CORBA_GENERATED): idl_stamp
idl_stamp: $(IDL)
$(ORBIT_IDL) $(IDL_CFLAGS) -I$(IDLDIR) $(IDL)
touch idl_stamp
CLEANFILES+=$(CORBA_GENERATED) trilobite-eazel-install.h lessevil.c evil.c moreevil.c
CLEANFILES+=$(CORBA_GENERATED) idl_stamp
BUILT_SOURCES = \
$(CORBA_GENERATED)
##
......@@ -585,7 +585,7 @@ void
eazel_install_uninstall_packages (EazelInstall *service, GList *categories)
{
SANITY (service);
eazel_install_set_uninstall (service, TRUE);
if (categories == NULL && eazel_install_get_package_list (service) == NULL) {
eazel_install_set_package_list (service, "/var/eazel/services/package-list.xml");
switch (service->private->iopts->protocol) {
......
......@@ -96,6 +96,10 @@ static int eazel_install_package_name_compare (PackageData *pack,
static int eazel_install_package_conflict_compare (PackageData *pack,
struct rpmDependencyConflict *conflict);
static void eazel_uninstall_globber (EazelInstall *service,
GList **packages,
GList **failed);
gboolean
install_new_packages (EazelInstall *service, GList *categories) {
......@@ -245,6 +249,7 @@ uninstall_packages (EazelInstall *service,
problem_filters = 0;
if (eazel_install_get_test (service) == TRUE) {
g_message (_("Dry Run Mode Activated. Packages will not actually be installed ..."));
uninstall_flags |= RPMTRANS_FLAG_TEST;
}
......@@ -258,11 +263,23 @@ uninstall_packages (EazelInstall *service,
rpmReadConfigFiles (eazel_install_get_rpmrc_file (service), NULL);
eazel_install_set_install_flags (service, uninstall_flags);
eazel_install_set_interface_flags (service, interface_flags);
eazel_install_set_problem_filters (service, problem_filters);
rv = TRUE;
while (categories) {
CategoryData* cat = categories->data;
GList* pkgs = cat->packages;
GList *pkgs;
GList *failed;
g_message (_("Category = %s"), cat->name);
failed = NULL;
eazel_uninstall_globber (service, &cat->packages, &failed);
exit (1);
g_message ("g_list_length (failed) = %d", g_list_length (failed));
pkgs = cat->packages;
while (pkgs) {
PackageData* package = pkgs->data;
......@@ -273,7 +290,6 @@ uninstall_packages (EazelInstall *service,
interface_flags) == FALSE) {
g_warning ("Uninstall failed for %s",package->name);
eazel_install_emit_uninstall_failed (service, package);
} else {
rv = FALSE;
}
pkgs = pkgs->next;
......@@ -298,6 +314,7 @@ uninstall_a_package (EazelInstall *service,
retval = 0;
rv = TRUE;
g_message (_("Uninstalling %s"), package->name);
retval = rpm_uninstall (service,
"/",
......@@ -307,7 +324,6 @@ uninstall_a_package (EazelInstall *service,
interface_flags);
if (retval == 0) {
g_message ("Package uninstall successful!");
rv = TRUE;
} else {
g_message (_("Package uninstall failed !"));
rv = FALSE;
......@@ -667,10 +683,19 @@ do_rpm_uninstall (EazelInstall *service,
}
if (!stop_uninstall && conflicts) {
int i;
g_message (_("Dependency check failed."));
printDepProblems (stderr, conflicts,
num_conflicts);
for (i=0; i<num_conflicts; i++) {
switch (conflicts[i].sense) {
case RPMDEP_SENSE_REQUIRES:
g_message ("%s deps on %s and must also be uninstalled", conflicts[i].byName, conflicts[i].needsName);
break;
default:
break;
}
}
num_failed += num_packages;
stop_uninstall = 1;
rpmdepFreeConflicts (conflicts, num_conflicts);
......@@ -956,6 +981,7 @@ eazel_install_prepare_rpm_system(EazelInstall *service)
}
return FALSE;
}
if (set) {
(*set) = rpmtransCreateSet (*db, root_dir);
if (set == NULL) {
......@@ -993,36 +1019,91 @@ eazel_install_free_package_system (EazelInstall *service)
}
static void
eazel_install_add_headers_to_rpm_set (EazelInstall *service,
GList *packages)
eazel_install_add_to_rpm_set (EazelInstall *service,
GList **packages,
GList **failed)
{
GList *iterator;
GList *tmp_failed;
int interface_flags;
g_assert (packages!=NULL);
g_assert (*packages!=NULL);
tmp_failed = NULL;
if (eazel_install_get_update (service) == TRUE) {
interface_flags |= INSTALL_UPGRADE;
}
for (iterator = packages; iterator; iterator = iterator->next) {
for (iterator = *packages; iterator; iterator = iterator->next) {
PackageData *pack;
int err;
pack = (PackageData*)iterator->data;
err = rpmtransAddPackage (service->private->packsys.rpm.set,
*((Header*)pack->packsys_struc),
NULL,
NULL,
interface_flags,
NULL);
if (!eazel_install_get_uninstall (service)) {
err = rpmtransAddPackage (service->private->packsys.rpm.set,
*((Header*)pack->packsys_struc),
NULL,
NULL,
interface_flags,
NULL);
if (err!=0) {
g_warning ("rpmtransAddPackage (..., %s, ...) = %d", pack->name, err);
/* We cannot remove the thing immediately from packages, as
we're iterating it, so add to a tmp list and nuke later */
tmp_failed = g_list_prepend (tmp_failed, pack);
}
} else {
dbiIndexSet matches;
int rc;
rc = rpmdbFindByLabel (service->private->packsys.rpm.db, pack->name, &matches);
if (rc!=0) {
g_warning ("%s not installed, not doing rpmtransRemovePackage", pack->name);
tmp_failed = g_list_prepend (tmp_failed, pack);
} else {
int i;
for (i=0; i< dbiIndexSetCount (matches); i++) {
unsigned int offset;
offset = dbiIndexRecordOffset (matches, i);
if (offset) {
rpmtransRemovePackage (service->private->packsys.rpm.set,
offset);
} else {
tmp_failed = g_list_prepend (tmp_failed, pack);
}
}
}
}
} /* end for loop */
/* Remove all failed from packages, and add them to failed */
if (tmp_failed) {
for (iterator = tmp_failed; iterator; iterator = iterator->next) {
if (failed) {
(*failed) = g_list_prepend (*failed, iterator->data);
}
(*packages) = g_list_remove (*packages, iterator->data);
}
g_list_free (tmp_failed);
}
}
/*
Adds the headers to the package system set
*/
static void
eazel_install_add_headers_to_set (EazelInstall *service,
GList *packages)
eazel_install_add_to_set (EazelInstall *service,
GList **packages,
GList **failed)
{
switch (eazel_install_get_package_system (service)) {
case EAZEL_INSTALL_USE_RPM:
eazel_install_add_headers_to_rpm_set (service, packages);
eazel_install_add_to_rpm_set (service, packages, failed);
break;
}
}
......@@ -1067,6 +1148,10 @@ eazel_install_fetch_rpm_dependencies (EazelInstall *service,
to_remove = NULL;
extras = g_hash_table_new (g_str_hash, g_str_equal);
/* FIXME: bugzilla.eazel.com 1512
This piece of code is rpm specific. It has some generic algorithm
for doing the dep stuff, but it's rpm entangled */
for (iterator = 0; iterator < service->private->packsys.rpm.num_conflicts; iterator++) {
GList *pack_entry;
PackageData *pack;
......@@ -1106,6 +1191,16 @@ eazel_install_fetch_rpm_dependencies (EazelInstall *service,
Here, it'd be cool to compare dep->name to pack->name to see if
dep is pack's devel package. And if so, replace dep->version with
pack->version and not fail pack, but continue */
{
char *tmp;
tmp = g_strdup_printf ("%s-devel", pack->name);
if (strcmp (tmp, dep->name)==0) {
g_message ("breakage is the devel package");
}
g_free (tmp);
}
if (!eazel_install_get_force (service)) {
pack->breaks = g_list_prepend (pack->breaks, dep);
if (g_list_find (*failedpackages, pack) == NULL) {
......@@ -1117,7 +1212,7 @@ eazel_install_fetch_rpm_dependencies (EazelInstall *service,
break;
case RPMDEP_SENSE_CONFLICTS:
/* If we end here, it's a conflict is going to break something */
/* FIXME: bugzilla.eazel.com
/* FIXME: bugzilla.eazel.com 1514
Need to handle this more intelligently */
g_warning (_("%s conflicts %s-%s"), conflict.byName, conflict.needsName, conflict.needsVersion);
continue;
......@@ -1263,6 +1358,30 @@ print_package_list (char *str, GList *packages, gboolean show_deps)
}
}