mirror of
https://github.com/nmap/nmap.git
synced 2025-12-15 20:29:03 +00:00
Add an uninstall option to ndiff's setup.py
This commit is contained in:
@@ -83,6 +83,7 @@ INSTALLZENMAP=@INSTALLZENMAP@
|
|||||||
INSTALLNDIFF=@INSTALLNDIFF@
|
INSTALLNDIFF=@INSTALLNDIFF@
|
||||||
INSTALLNPING=@INSTALLNPING@
|
INSTALLNPING=@INSTALLNPING@
|
||||||
UNINSTALLZENMAP=@UNINSTALLZENMAP@
|
UNINSTALLZENMAP=@UNINSTALLZENMAP@
|
||||||
|
UNINSTALLNDIFF=@UNINSTALLNDIFF@
|
||||||
UNINSTALLNPING=@UNINSTALLNPING@
|
UNINSTALLNPING=@UNINSTALLNPING@
|
||||||
|
|
||||||
ifneq (@LIBLUA_LIBS@,)
|
ifneq (@LIBLUA_LIBS@,)
|
||||||
@@ -365,7 +366,7 @@ install-nping: $(NPINGDIR)/nping
|
|||||||
install: install-nmap $(INSTALLNSE) $(INSTALLZENMAP) @NCAT_INSTALL@ @NMAP_UPDATE_INSTALL@ $(INSTALLNDIFF) $(INSTALLNPING)
|
install: install-nmap $(INSTALLNSE) $(INSTALLZENMAP) @NCAT_INSTALL@ @NMAP_UPDATE_INSTALL@ $(INSTALLNDIFF) $(INSTALLNPING)
|
||||||
@echo "NMAP SUCCESSFULLY INSTALLED"
|
@echo "NMAP SUCCESSFULLY INSTALLED"
|
||||||
|
|
||||||
uninstall: uninstall-nmap $(UNINSTALLZENMAP) @NCAT_UNINSTALL@ @NMAP_UPDATE_UNINSTALL@ $(UNINSTALLNPING)
|
uninstall: uninstall-nmap $(UNINSTALLZENMAP) @NCAT_UNINSTALL@ @NMAP_UPDATE_UNINSTALL@ $(UNINSTALLNDIFF) $(UNINSTALLNPING)
|
||||||
|
|
||||||
uninstall-nmap:
|
uninstall-nmap:
|
||||||
rm -f $(DESTDIR)$(bindir)/$(TARGET)
|
rm -f $(DESTDIR)$(bindir)/$(TARGET)
|
||||||
@@ -382,6 +383,9 @@ uninstall-zenmap:
|
|||||||
fi
|
fi
|
||||||
rm -f $(DESTDIR)$(bindir)/xnmap
|
rm -f $(DESTDIR)$(bindir)/xnmap
|
||||||
|
|
||||||
|
uninstall-ndiff:
|
||||||
|
cd $(NDIFFDIR) && $(PYTHON) setup.py uninstall
|
||||||
|
|
||||||
uninstall-ncat:
|
uninstall-ncat:
|
||||||
@cd $(NCATDIR) && $(MAKE) uninstall
|
@cd $(NCATDIR) && $(MAKE) uninstall
|
||||||
|
|
||||||
|
|||||||
4
configure
vendored
4
configure
vendored
@@ -690,6 +690,7 @@ ZENMAPDIR
|
|||||||
NDIFF_DIST_CLEAN
|
NDIFF_DIST_CLEAN
|
||||||
NDIFF_CLEAN
|
NDIFF_CLEAN
|
||||||
NDIFF_CHECK
|
NDIFF_CHECK
|
||||||
|
UNINSTALLNDIFF
|
||||||
INSTALLNDIFF
|
INSTALLNDIFF
|
||||||
BUILDNDIFF
|
BUILDNDIFF
|
||||||
NDIFFDIR
|
NDIFFDIR
|
||||||
@@ -5711,12 +5712,14 @@ fi
|
|||||||
if test "$with_ndiff" = "no"; then
|
if test "$with_ndiff" = "no"; then
|
||||||
BUILDNDIFF=""
|
BUILDNDIFF=""
|
||||||
INSTALLNDIFF=""
|
INSTALLNDIFF=""
|
||||||
|
UNINSTALLNDIFF=""
|
||||||
NDIFF_CHECK=""
|
NDIFF_CHECK=""
|
||||||
NDIFF_CLEAN=""
|
NDIFF_CLEAN=""
|
||||||
NDIFF_DIST_CLEAN=""
|
NDIFF_DIST_CLEAN=""
|
||||||
else
|
else
|
||||||
BUILDNDIFF=build-ndiff
|
BUILDNDIFF=build-ndiff
|
||||||
INSTALLNDIFF=install-ndiff
|
INSTALLNDIFF=install-ndiff
|
||||||
|
UNINSTALLNDIFF=uninstall-ndiff
|
||||||
NDIFF_CHECK="ndiff_check"
|
NDIFF_CHECK="ndiff_check"
|
||||||
NDIFF_CLEAN=ndiff_clean
|
NDIFF_CLEAN=ndiff_clean
|
||||||
NDIFF_DIST_CLEAN=ndiff_dist_clean
|
NDIFF_DIST_CLEAN=ndiff_dist_clean
|
||||||
@@ -5728,6 +5731,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ZENMAPDIR=zenmap
|
ZENMAPDIR=zenmap
|
||||||
|
|
||||||
# Do they want Zenmap?
|
# Do they want Zenmap?
|
||||||
|
|||||||
@@ -232,12 +232,14 @@ fi
|
|||||||
if test "$with_ndiff" = "no"; then
|
if test "$with_ndiff" = "no"; then
|
||||||
BUILDNDIFF=""
|
BUILDNDIFF=""
|
||||||
INSTALLNDIFF=""
|
INSTALLNDIFF=""
|
||||||
|
UNINSTALLNDIFF=""
|
||||||
NDIFF_CHECK=""
|
NDIFF_CHECK=""
|
||||||
NDIFF_CLEAN=""
|
NDIFF_CLEAN=""
|
||||||
NDIFF_DIST_CLEAN=""
|
NDIFF_DIST_CLEAN=""
|
||||||
else
|
else
|
||||||
BUILDNDIFF=build-ndiff
|
BUILDNDIFF=build-ndiff
|
||||||
INSTALLNDIFF=install-ndiff
|
INSTALLNDIFF=install-ndiff
|
||||||
|
UNINSTALLNDIFF=uninstall-ndiff
|
||||||
NDIFF_CHECK="ndiff_check"
|
NDIFF_CHECK="ndiff_check"
|
||||||
NDIFF_CLEAN=ndiff_clean
|
NDIFF_CLEAN=ndiff_clean
|
||||||
NDIFF_DIST_CLEAN=ndiff_dist_clean
|
NDIFF_DIST_CLEAN=ndiff_dist_clean
|
||||||
@@ -245,6 +247,7 @@ fi
|
|||||||
AC_SUBST(NDIFFDIR)
|
AC_SUBST(NDIFFDIR)
|
||||||
AC_SUBST(BUILDNDIFF)
|
AC_SUBST(BUILDNDIFF)
|
||||||
AC_SUBST(INSTALLNDIFF)
|
AC_SUBST(INSTALLNDIFF)
|
||||||
|
AC_SUBST(UNINSTALLNDIFF)
|
||||||
AC_SUBST(NDIFF_CHECK)
|
AC_SUBST(NDIFF_CHECK)
|
||||||
AC_SUBST(NDIFF_CLEAN)
|
AC_SUBST(NDIFF_CLEAN)
|
||||||
AC_SUBST(NDIFF_DIST_CLEAN)
|
AC_SUBST(NDIFF_DIST_CLEAN)
|
||||||
|
|||||||
246
ndiff/setup.py
246
ndiff/setup.py
@@ -6,14 +6,32 @@ import os
|
|||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from stat import *
|
||||||
|
|
||||||
import distutils.command
|
import distutils.command
|
||||||
import distutils.command.install
|
import distutils.command.install
|
||||||
import distutils.core
|
import distutils.core
|
||||||
import distutils.cmd
|
import distutils.cmd
|
||||||
import distutils.errors
|
import distutils.errors
|
||||||
|
from distutils import log
|
||||||
from distutils.command.install import install
|
from distutils.command.install import install
|
||||||
|
|
||||||
APP_NAME = "ndiff"
|
APP_NAME = "ndiff"
|
||||||
|
# The name of the file used to record the list of installed files, so that the
|
||||||
|
# uninstall command can remove them.
|
||||||
|
INSTALLED_FILES_NAME = "INSTALLED_FILES"
|
||||||
|
|
||||||
|
|
||||||
|
# path_startswith and path_strip_prefix are used to deal with the installation
|
||||||
|
# root (--root option, also known as DESTDIR).
|
||||||
|
def path_startswith(path, prefix):
|
||||||
|
"""Returns True if path starts with prefix. It's a little more intelligent
|
||||||
|
than str.startswith because it normalizes the paths to remove multiple
|
||||||
|
directory separators and down-up traversals."""
|
||||||
|
path = os.path.normpath(path)
|
||||||
|
prefix = os.path.normpath(prefix)
|
||||||
|
return path.startswith(prefix)
|
||||||
|
|
||||||
|
|
||||||
def path_strip_prefix(path, prefix):
|
def path_strip_prefix(path, prefix):
|
||||||
"""Return path stripped of its directory prefix if it starts with prefix,
|
"""Return path stripped of its directory prefix if it starts with prefix,
|
||||||
@@ -42,10 +60,9 @@ def path_strip_prefix(path, prefix):
|
|||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Distutils subclasses
|
# Distutils subclasses
|
||||||
|
|
||||||
class null_command(distutils.cmd.Command):
|
class null_command(distutils.cmd.Command):
|
||||||
"""This is a dummy distutils command that does nothing. We use it to
|
"""This is a dummy distutils command that does nothing. We use it to
|
||||||
replace the install_egg_info and avoid installing a .egg-info file, because
|
replace the install_egg_info and avoid installing a .egg-info file, because
|
||||||
@@ -56,6 +73,9 @@ class null_command(distutils.cmd.Command):
|
|||||||
def finalize_options(self):
|
def finalize_options(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_outputs(self):
|
||||||
|
return ()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -67,6 +87,11 @@ class checked_install(distutils.command.install.install):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def finalize_options(self):
|
def finalize_options(self):
|
||||||
|
# Ubuntu's python2.6-2.6.4-0ubuntu3 package changes sys.prefix in
|
||||||
|
# install.finalize_options when sys.prefix is "/usr/local" (our
|
||||||
|
# default). Because we need the unchanged value later, remember it
|
||||||
|
# here.
|
||||||
|
self.saved_prefix = sys.prefix
|
||||||
try:
|
try:
|
||||||
distutils.command.install.install.finalize_options(self)
|
distutils.command.install.install.finalize_options(self)
|
||||||
except distutils.errors.DistutilsPlatformError, e:
|
except distutils.errors.DistutilsPlatformError, e:
|
||||||
@@ -85,32 +110,233 @@ Installing your distribution's python-dev package may solve this problem.""")
|
|||||||
app_file = open(app_file_name, "r")
|
app_file = open(app_file_name, "r")
|
||||||
lines = app_file.readlines()
|
lines = app_file.readlines()
|
||||||
app_file.close()
|
app_file.close()
|
||||||
|
|
||||||
for i in range(len(lines)):
|
for i in range(len(lines)):
|
||||||
if re.match(r'^INSTALL_LIB =', lines[i]):
|
if re.match(r'^INSTALL_LIB =', lines[i]):
|
||||||
lines[i] = "INSTALL_LIB = %s\n" % repr(modules_dir)
|
lines[i] = "INSTALL_LIB = %s\n" % repr(modules_dir)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"INSTALL_LIB replacement not found in %s" % app_file_name)
|
"INSTALL_LIB replacement not found in %s" % app_file_name)
|
||||||
|
|
||||||
app_file = open(app_file_name, "w")
|
app_file = open(app_file_name, "w")
|
||||||
app_file.writelines(lines)
|
app_file.writelines(lines)
|
||||||
app_file.close()
|
app_file.close()
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
install.run(self)
|
install.run(self)
|
||||||
|
|
||||||
# These below are from Zenmap. We're only using set_modules_path right now, but we might consider whether the others would be useful (or, if not, whether we should remove them from Zenmap).
|
# These below are from Zenmap. We're only using set_modules_path right now, but
|
||||||
|
# we might consider whether the others would be useful (or, if not, whether we
|
||||||
|
# should remove them from Zenmap).
|
||||||
# self.set_perms()
|
# self.set_perms()
|
||||||
self.set_modules_path()
|
self.set_modules_path()
|
||||||
# self.fix_paths()
|
# self.fix_paths()
|
||||||
# self.create_uninstaller()
|
self.create_uninstaller()
|
||||||
# self.write_installed_files()
|
self.write_installed_files()
|
||||||
|
|
||||||
|
def get_installed_files(self):
|
||||||
|
"""Return a list of installed files and directories, each prefixed with
|
||||||
|
the installation root if given. The list of installed directories
|
||||||
|
doesn't come from distutils so it may be incomplete."""
|
||||||
|
installed_files = self.get_outputs()
|
||||||
|
for package in self.distribution.py_modules:
|
||||||
|
dir = package.replace(".", "/")
|
||||||
|
installed_files.append(os.path.join(self.install_lib, dir))
|
||||||
|
installed_files.append(
|
||||||
|
os.path.join(self.install_scripts, "uninstall_" + APP_NAME))
|
||||||
|
return installed_files
|
||||||
|
|
||||||
|
def create_uninstaller(self):
|
||||||
|
uninstaller_filename = os.path.join(
|
||||||
|
self.install_scripts, "uninstall_" + APP_NAME)
|
||||||
|
|
||||||
|
uninstaller = """\
|
||||||
|
#!/usr/bin/env python
|
||||||
|
import errno, os, os.path, sys
|
||||||
|
|
||||||
|
print 'Uninstall %(name)s'
|
||||||
|
|
||||||
|
answer = raw_input('Are you sure that you want to uninstall '
|
||||||
|
'%(name)s (yes/no) ')
|
||||||
|
|
||||||
|
if answer != 'yes' and answer != 'y':
|
||||||
|
print 'Not uninstalling.'
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
""" % {'name': APP_NAME}
|
||||||
|
|
||||||
|
installed_files = []
|
||||||
|
for output in self.get_installed_files():
|
||||||
|
if self.root is not None:
|
||||||
|
# If we have a root (DESTDIR), we need to strip it off the
|
||||||
|
# front of paths so the uninstaller runs on the target host.
|
||||||
|
# The path manipulations are tricky, but made easier because
|
||||||
|
# the uninstaller only has to run on Unix.
|
||||||
|
if not path_startswith(output, self.root):
|
||||||
|
# This should never happen (everything gets installed
|
||||||
|
# inside the root), but if it does, be safe and don't
|
||||||
|
# delete anything.
|
||||||
|
uninstaller += ("print '%s was not installed inside "
|
||||||
|
"the root %s; skipping.'\n" % (output, self.root))
|
||||||
|
continue
|
||||||
|
output = path_strip_prefix(output, self.root)
|
||||||
|
assert os.path.isabs(output)
|
||||||
|
installed_files.append(output)
|
||||||
|
|
||||||
|
uninstaller += """\
|
||||||
|
INSTALLED_FILES = (
|
||||||
|
"""
|
||||||
|
for file in installed_files:
|
||||||
|
uninstaller += " %s,\n" % repr(file)
|
||||||
|
uninstaller += """\
|
||||||
|
)
|
||||||
|
|
||||||
|
# Split the list into lists of files and directories.
|
||||||
|
files = []
|
||||||
|
dirs = []
|
||||||
|
for path in INSTALLED_FILES:
|
||||||
|
if os.path.isfile(path) or os.path.islink(path):
|
||||||
|
files.append(path)
|
||||||
|
elif os.path.isdir(path):
|
||||||
|
dirs.append(path)
|
||||||
|
# Delete the files.
|
||||||
|
for file in files:
|
||||||
|
print "Removing '%s'." % file
|
||||||
|
try:
|
||||||
|
os.remove(file)
|
||||||
|
except OSError, e:
|
||||||
|
print >> sys.stderr, ' Error: %s.' % str(e)
|
||||||
|
# Delete the directories. First reverse-sort the normalized paths by
|
||||||
|
# length so that child directories are deleted before their parents.
|
||||||
|
dirs = [os.path.normpath(dir) for dir in dirs]
|
||||||
|
dirs.sort(key = len, reverse = True)
|
||||||
|
for dir in dirs:
|
||||||
|
try:
|
||||||
|
print "Removing the directory '%s'." % dir
|
||||||
|
os.rmdir(dir)
|
||||||
|
except OSError, e:
|
||||||
|
if e.errno == errno.ENOTEMPTY:
|
||||||
|
print "Directory '%s' not empty; not removing." % dir
|
||||||
|
else:
|
||||||
|
print >> sys.stderr, str(e)
|
||||||
|
"""
|
||||||
|
|
||||||
|
uninstaller_file = open(uninstaller_filename, 'w')
|
||||||
|
uninstaller_file.write(uninstaller)
|
||||||
|
uninstaller_file.close()
|
||||||
|
|
||||||
|
# Set exec bit for uninstaller
|
||||||
|
mode = ((os.stat(uninstaller_filename)[ST_MODE]) | 0555) & 07777
|
||||||
|
os.chmod(uninstaller_filename, mode)
|
||||||
|
|
||||||
|
def set_modules_path(self):
|
||||||
|
app_file_name = os.path.join(self.install_scripts, APP_NAME)
|
||||||
|
# Find where the modules are installed. distutils will put them in
|
||||||
|
# self.install_lib, but that path can contain the root (DESTDIR), so we
|
||||||
|
# must strip it off if necessary.
|
||||||
|
modules_dir = self.install_lib
|
||||||
|
if self.root is not None:
|
||||||
|
modules_dir = path_strip_prefix(modules_dir, self.root)
|
||||||
|
|
||||||
|
app_file = open(app_file_name, "r")
|
||||||
|
lines = app_file.readlines()
|
||||||
|
app_file.close()
|
||||||
|
|
||||||
|
for i in range(len(lines)):
|
||||||
|
if re.match(r'^INSTALL_LIB =', lines[i]):
|
||||||
|
lines[i] = "INSTALL_LIB = %s\n" % repr(modules_dir)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
"INSTALL_LIB replacement not found in %s" % app_file_name)
|
||||||
|
|
||||||
|
app_file = open(app_file_name, "w")
|
||||||
|
app_file.writelines(lines)
|
||||||
|
app_file.close()
|
||||||
|
|
||||||
|
def write_installed_files(self):
|
||||||
|
"""Write a list of installed files for use by the uninstall command.
|
||||||
|
This is similar to what happens with the --record option except that it
|
||||||
|
doesn't strip off the installation root, if any. File names containing
|
||||||
|
newline characters are not handled."""
|
||||||
|
if INSTALLED_FILES_NAME == self.record:
|
||||||
|
distutils.log.warn("warning: installation record is overwriting "
|
||||||
|
"--record file '%s'." % self.record)
|
||||||
|
f = open(INSTALLED_FILES_NAME, "w")
|
||||||
|
try:
|
||||||
|
for output in self.get_installed_files():
|
||||||
|
assert "\n" not in output
|
||||||
|
print >> f, output
|
||||||
|
finally:
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
class my_uninstall(distutils.cmd.Command):
|
||||||
|
"""A distutils command that performs uninstallation. It reads the list of
|
||||||
|
installed files written by the install command."""
|
||||||
|
|
||||||
|
command_name = "uninstall"
|
||||||
|
description = "uninstall installed files recorded in '%s'" % (
|
||||||
|
INSTALLED_FILES_NAME)
|
||||||
|
user_options = []
|
||||||
|
|
||||||
|
def initialize_options(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def finalize_options(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
# Read the list of installed files.
|
||||||
|
try:
|
||||||
|
f = open(INSTALLED_FILES_NAME, "r")
|
||||||
|
except IOError, e:
|
||||||
|
if e.errno == errno.ENOENT:
|
||||||
|
log.error("Couldn't open the installation record '%s'. "
|
||||||
|
"Have you installed yet?" % INSTALLED_FILES_NAME)
|
||||||
|
return
|
||||||
|
installed_files = [file.rstrip("\n") for file in f.readlines()]
|
||||||
|
f.close()
|
||||||
|
# Delete the installation record too.
|
||||||
|
installed_files.append(INSTALLED_FILES_NAME)
|
||||||
|
# Split the list into lists of files and directories.
|
||||||
|
files = []
|
||||||
|
dirs = []
|
||||||
|
for path in installed_files:
|
||||||
|
if os.path.isfile(path) or os.path.islink(path):
|
||||||
|
files.append(path)
|
||||||
|
elif os.path.isdir(path):
|
||||||
|
dirs.append(path)
|
||||||
|
# Delete the files.
|
||||||
|
for file in files:
|
||||||
|
log.info("Removing '%s'." % file)
|
||||||
|
try:
|
||||||
|
if not self.dry_run:
|
||||||
|
os.remove(file)
|
||||||
|
except OSError, e:
|
||||||
|
log.error(str(e))
|
||||||
|
# Delete the directories. First reverse-sort the normalized paths by
|
||||||
|
# length so that child directories are deleted before their parents.
|
||||||
|
dirs = [os.path.normpath(dir) for dir in dirs]
|
||||||
|
dirs.sort(key=len, reverse=True)
|
||||||
|
for dir in dirs:
|
||||||
|
try:
|
||||||
|
log.info("Removing the directory '%s'." % dir)
|
||||||
|
if not self.dry_run:
|
||||||
|
os.rmdir(dir)
|
||||||
|
except OSError, e:
|
||||||
|
if e.errno == errno.ENOTEMPTY:
|
||||||
|
log.info("Directory '%s' not empty; not removing." % dir)
|
||||||
|
else:
|
||||||
|
log.error(str(e))
|
||||||
|
|
||||||
|
|
||||||
distutils.core.setup(name=u"ndiff", scripts=[u"scripts/ndiff"],
|
distutils.core.setup(name=u"ndiff", scripts=[u"scripts/ndiff"],
|
||||||
py_modules=[u"ndiff"],
|
py_modules=[u"ndiff"],
|
||||||
data_files=[(u"share/man/man1", [u"docs/ndiff.1"])],
|
data_files=[(u"share/man/man1", [u"docs/ndiff.1"])],
|
||||||
cmdclass={"install_egg_info": null_command, "install": checked_install})
|
cmdclass={
|
||||||
|
"install_egg_info": null_command,
|
||||||
|
"install": checked_install,
|
||||||
|
"uninstall": my_uninstall
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user