lsb 3.0-2 Debian release.
authorChris Lawrence <lawrencc@debian.org>
Tue, 2 Aug 2005 03:45:41 +0000 (22:45 -0500)
committerDidier Raboud <odyx@debian.org>
Tue, 2 Aug 2005 03:45:41 +0000 (22:45 -0500)
debian/README.Debian
debian/changelog
debian/control
debian/dirs
debian/po/de.po
debian/po/vi.po [new file with mode: 0644]
debian/rules
init-functions
initdutils.py
lsbinstall [new file with mode: 0755]

index 64d3dea29a3d55aae53bc4535be279c14e825fb7..fda828252bb8147005f79217aead3dc242da5a65 100644 (file)
@@ -79,7 +79,7 @@ construed as a statement that Debian is LSB-compliant.
 
 The specification is available at http://www.linuxbase.org/spec/
 
-DEVIATIONS FROM LSB 2.0
+DEVIATIONS FROM LSB
 
 The package and its dependencies implement all of LSB on Debian, with
 these exceptions:
@@ -131,9 +131,15 @@ these exceptions:
   (This is a known deficiency in debianutils, and is required for
   backwards compatibility with expected behavior on earlier systems.)
 
-- The results of running the LSB test suite against Debian with the
-  LSB package and its dependencies installed are available at
-  http://people.debian.org/~joeyh/lsbtest/current/, courtesy of Joey Hess.
+- /etc/profile.d scripts aren't executed on shell startup by default
+  on Debian systems (see Debian Policy section 9.9 for an explanation).
+  LSB 3.0 is ambiguous on this requirement; /bin/sh is *not* required
+  to execute these scripts, according to its description, but the
+  lsbinstall documentation says that it is.
+
+  Debian policy forbids the use of /etc/profile.d by Debian packages,
+  so it is unlikely this will change (as it might be seen as
+  encouragement for Debian developers to do use it.)
 
 There may be other deviations from the spec; they are bugs in this
 package and should be reported as such using Debian's bug tracking
@@ -164,26 +170,14 @@ DESIGN DECISIONS
   are upgrading from the 1.2 series, you will need to manually reinstall
   all of your LSB packages.)
 
+- As of 3.0-2, a third registry of files installed by lsbinstall is
+  retained in /var/lib/lsb/lsbinstall.  Unlike the other two registries,
+  it is not designed to be human-readable.
+
 - The facility handling scripts are written in Python.  I am not
   particularly attached to them being written in Python, but at the
   same time I do not forsee rewriting them in $language_of_choice.
 
-BACKPORTING TO DEBIAN 3.0 (WOODY)
-
-The scripts install_initd and remove_initd are written in Python and
-require Python 2.2 or later to operate correctly.  Woody (Debian 3.0)
-included the python2.2 package, but the default version of Python in
-woody was Python 2.1.  To backport to woody:
-
-- Change the python dependency to depend on python2.2 rather than python
-- Change the #! lines of install_initd and remove_initd to point to
-  /usr/bin/python2.2
-
-For proper LSB conformance in woody, you will also need to backport
-other Debian packages, including alien.
-
-The default version of Python in Debian 3.1 (sarge) is Python 2.3.5.
-
 COMPLIANCE TESTING
 
 I have been unable to locate any LSB package that tests the init
@@ -194,6 +188,6 @@ any reports of its success or failure.
 An example init script that tests some of these features is provided
 as /usr/share/doc/lsb/examples/init-skeleton.
 
- -- Chris Lawrence <lawrencc@debian.org>, Fri Mar  4 17:41:50 2005
+ -- Chris Lawrence <lawrencc@debian.org>, Mon Jul 11 18:55:39 2005
 
  LocalWords:  LSB
index 1c9722cc35696e5116c70822b23591f25a103ea0..4db404044becea8a5399a817e4a5971983d4fef2 100644 (file)
@@ -1,3 +1,26 @@
+lsb (3.0-2) experimental; urgency=low
+
+  * Uploaded to experimental since glibc 2.3.5 is not in sid yet.
+  * Add /usr/lib/lsb/lsbinstall.  
+    Note: the inetd stuff isn't implemented yet.
+  * Require glibc >> 2.3.5, since some interfaces in LSB 3.0 were
+    introduced by glibc 2.3.5.
+  * Require Python 2.3 or later, so we can use optparse.
+  * Fix test in pidofproc in /lib/lsb/init-functions.  (Closes: #315067)
+  * Document /etc/profile.d lossage in README.Debian.
+  * Remove stale link in README.Debian.  (Closes: #316064)
+  * Update German translation.  (Closes: #313979)
+  * Add Vietnamese translation.  (Closes: #312606)
+  * Updated description.  (Closes: #318224)
+  * Use DEB_BUILD_ARCH_CPU instead of DEB_BUILD_ARCH.
+  * Call /bin/echo when using -e.  (Closes: #320709)
+  * Kludge log_*_msg into being more policy-compliant and (in the case of
+    the LSB functions) more Debian-like.
+  * Add log_progress_msg.  See spiffy example adapted from the Policy
+    Manual in init-functions.  (Closes: #319739)
+
+ -- Chris Lawrence <lawrencc@debian.org>  Mon,  1 Aug 2005 22:45:41 -0500
+
 lsb (3.0-1) unstable; urgency=low
 
   * lsb-cxx now depends on libstdc++6 as well as libstdc++5, necessitated
index f3d8eb80259202555daa8c7e9b28df0cf7f85231..7784109a56d71bafbe0f289a9170b75cf3d8d2ac 100644 (file)
@@ -2,21 +2,21 @@ Source: lsb
 Section: misc
 Priority: extra
 Maintainer: Chris Lawrence <lawrencc@debian.org>
-Build-Depends: debhelper (>= 4.1.13), po-debconf (>= 0.5.0)
-Standards-Version: 3.6.1
+Build-Depends: debhelper (>= 4.1.13), po-debconf (>= 0.5.0), dpkg-dev (>= 1.13.2)
+Standards-Version: 3.6.2
 
 Package: lsb-core
 Architecture: any
-Depends: lsb-release, libz1, exim4 | mail-transport-agent, at, bc, binutils, bsdmainutils, cpio, cron, file, libc6-dev | libc-dev, locales, lpr, m4, make, man-db, mawk | gawk, ncurses-term, passwd, patch, pax, procps, psmisc, rsync, alien (>= 8.36), python (>> 2.2.2), ${misc:Depends}, ${depends}, lsb-base
+Depends: lsb-release, ${glibc}, libz1, exim4 | mail-transport-agent, at, bc, binutils, bsdmainutils, cpio, cron, file, libc6-dev | libc-dev, locales, lpr, m4, make, man-db, mawk | gawk, ncurses-term, passwd, patch, pax, procps, psmisc, rsync, alien (>= 8.36), python (>> 2.3), ${misc:Depends}, ${depends}, lsb-base
 Provides: lsb-core-noarch, ${provides}
-Conflicts: python (>> 2.5), libutahglx1, lsb (<< 2.0-2)
+Conflicts: python (>> 2.5), lsb (<< 2.0-2)
 Replaces: lsb (<< 2.0-2)
-Description: Linux Standard Base 2.0 core support package
+Description: Linux Standard Base 3.0 core support package
  The Linux Standard Base (http://www.linuxbase.org/) is a standard
  core system that third-party applications written for Linux can
  depend upon.
  .
- This package provides an implementation of the core of version 2.0 of
+ This package provides an implementation of the core of version 3.0 of
  the Linux Standard Base for Debian on the Intel x86, Intel ia64
  (Itanium), IBM S390, and PowerPC 32-bit architectures with the Linux
  kernel.  Future revisions of the specification and this package may
@@ -31,13 +31,14 @@ Description: Linux Standard Base 2.0 core support package
 Package: lsb-graphics
 Architecture: any
 Depends: lsb-core, xlibmesa3-gl | libgl1, xlibs, ${misc:Depends}
+Conflicts: libutahglx1
 Provides: lsb-graphics-noarch, ${provides}
-Description: Linux Standard Base 2.0 graphics support package
+Description: Linux Standard Base 3.0 graphics support package
  The Linux Standard Base (http://www.linuxbase.org/) is a standard
  core system that third-party applications written for Linux can
  depend upon.
  .
- This package provides an implementation of version 2.0 of the Linux
+ This package provides an implementation of version 3.0 of the Linux
  Standard Base graphics specification for Debian on the Intel x86,
  Intel ia64 (Itanium), IBM S390, and PowerPC 32-bit architectures with
  the Linux kernel.  Future revisions of the specification and this
@@ -53,12 +54,12 @@ Package: lsb-cxx
 Architecture: any
 Depends: lsb-core, libstdc++5, libstdc++6, ${misc:Depends}
 Provides: lsb-cxx-noarch, ${provides}
-Description: Linux Standard Base 2.0 C++ support package
+Description: Linux Standard Base 3.0 C++ support package
  The Linux Standard Base (http://www.linuxbase.org/) is a standard
  core system that third-party applications written for Linux can
  depend upon.
  .
- This package provides an implementation of version 2.0 of the Linux
+ This package provides an implementation of version 3.0 of the Linux
  Standard Base C++ (CXX) specification for Debian on the Intel x86,
  Intel ia64 (Itanium), IBM S390, and PowerPC 32-bit architectures with
  the Linux kernel.  Future revisions of the specification and this
@@ -73,12 +74,12 @@ Description: Linux Standard Base 2.0 C++ support package
 Package: lsb
 Architecture: all
 Depends: lsb-core, lsb-graphics, lsb-cxx
-Description: Linux Standard Base 2.0 support package
+Description: Linux Standard Base 3.0 support package
  The Linux Standard Base (http://www.linuxbase.org/) is a standard
  core system that third-party applications written for Linux can
  depend upon.
  .
- This package provides an implementation of all modules of version 2.0
+ This package provides an implementation of all modules of version 3.0
  of the Linux Standard Base for Debian on the Intel x86, Intel ia64
  (Itanium), IBM S390, and PowerPC 32-bit architectures with the Linux
  kernel.  Future revisions of the specification and this package may
@@ -95,7 +96,7 @@ Architecture: all
 Depends: sed, ncurses-bin
 Replaces: lsb (<< 2.0-6)
 Conflicts: lsb (<< 2.0-6)
-Description: Linux Standard Base 2.0 init script functionality
+Description: Linux Standard Base 3.0 init script functionality
  The Linux Standard Base (http://www.linuxbase.org/) is a standard
  core system that third-party applications written for Linux can
  depend upon.
index 6cf4eec4e7d8b6fa85b5dc5bc00c3b308d5db595..df1721dccfe23b41832e1aaf078bc1af97c5d70c 100644 (file)
@@ -1,3 +1,4 @@
 usr/lib/lsb
 var/lib/lsb
 usr/X11R6/bin
+etc/profile.d
index 600440f062dc435d521b4bc3a45598379a336d3f..980f53bfe95eb028eff673558bb0ab18aac0e0d1 100644 (file)
@@ -30,7 +30,7 @@ msgstr "Sollen Schatten-Passworte [/etc/shadow] benutzt werden?"
 #. Description
 #: ../templates:4
 msgid "The Linux Standard Base requires that certain features of adduser(8) be available to conforming applications (such as password aging). Debian only provides these features when shadow passwords are enabled; however, your system currently has shadow passwords disabled."
-msgstr "Die LSB (\"Linux Standard Base\") verlangt, daß bestimmte Funktionen von adduser(8) für LSB-konforme Anwendungen verfügbar sind (z.Bsp. Passwort-Alterung). Debian stellt diese Funktionen nur zur Verfügung, falls Schatten-Passworte benutzt werden; jedoch werden in Ihrem System Schatten-Passworte z.Zt. nicht benutzt."
+msgstr "Die LSB (\"Linux Standard Base\") verlangt, daß bestimmte Funktionen von adduser(8) für LSB-konforme Anwendungen verfügbar sind (z.B. Passwort-Alterung). Debian stellt diese Funktionen nur zur Verfügung, falls Schatten-Passworte benutzt werden; jedoch werden in Ihrem System Schatten-Passworte z.Zt. nicht benutzt."
 
 #. Description
 #: ../templates:4
diff --git a/debian/po/vi.po b/debian/po/vi.po
new file mode 100644 (file)
index 0000000..2933400
--- /dev/null
@@ -0,0 +1,53 @@
+# Vietnamese Translation for lsb.
+# Copyright © 2005 Free Software Foundation, Inc.
+# Clytie Siddall <clytie@riverland.net.au>, 2005.
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: lsb 3.0-1\n"
+"POT-Creation-Date: 2003-03-30 12:40-0300\n"
+"PO-Revision-Date: 2005-06-09 15:53+0930\n"
+"Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n"
+"Language-Team: Vietnamese <gnomevi-list@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#.Description
+#:../templates:4
+msgid "Should shadow passwords be enabled?"
+msgstr "Bạn có muốn hiệu lực mật khẩu bóng không?"
+
+#.Description
+#:../templates:4
+msgid ""
+"The Linux Standard Base requires that certain features of adduser(8) be "
+"available to conforming applications (such as password aging). Debian only "
+"provides these features when shadow passwords are enabled; however, your "
+"system currently has shadow passwords disabled."
+msgstr "Cơ bản chuẩn Linux (Linux Standard Base: lsb) cần đến một số tính năng của «adduser(8)» có sẵn sàng cho những ứng dụng thích hợp (như cách làm cho mật khẩu cũ hơn). Debian cung cấp những tính năng này chỉ khi có bật mật khẩu bóng; tuy nhiên, hệ thống bạn hiện thời có mật khẩu bóng bị tắt."
+
+#.Description
+#:../templates:4
+#,no-c-format
+msgid ""
+"Most LSB applications will work fine with either setting, but 100% "
+"conformance requires shadow passwords to be enabled."
+msgstr "Phần lớn ứng dụng LSB sẽ hoạt động được với cả hai thiết lập, nhưng mà độ phù hợp 100% cần đến có bật mật khẩu bóng."
+
+#.Description
+#:../templates:4
+msgid ""
+"Generally speaking, it is considered good practice to enable shadow "
+"passwords.  However, there are some situations in which shadow passwords may "
+"not work properly (most notably, if non-root users need to authenticate "
+"passwords against /etc/passwd)."
+msgstr "Thường, tốt để hiệu lực mật khẩu bóng. Tuy nhiên, có một số trường hợp không có mật khẩu bóng hoạt động được (phổ biến nhất là nếu người dùng không phải là người chủ có cần xác thực mật khẩu với «/etc/passwd»)."
+
+#.Description
+#:../templates:4
+msgid ""
+"If you answer in the affirmative, the command 'shadowconfig on' will be run "
+"to enable shadow passwords."
+msgstr "Nếu bạn trả lời «Có» thì sẽ chạy lệnh «shadowconfig on» (bật cấu hình bóng) để hiệu lực mật khẩu bóng."
index b2d492e1a23392fe712391517e6a3fe8cd5b5503..d807d841f64608aed5cf274a2422ed61e06e52a2 100755 (executable)
@@ -9,7 +9,7 @@
 # from having to guess our platform (since we know it already)
 DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
 DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
-DEB_BUILD_ARCH      ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH)
+DEB_BUILD_ARCH_CPU  ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH_CPU)
 
 ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
        CFLAGS += -g
@@ -19,12 +19,20 @@ ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
 endif
 
 # Map Debian architectures to LSB architectures
-lsbarch=${DEB_BUILD_ARCH}
+lsbarch=${DEB_BUILD_ARCH_CPU}
 ifeq (${lsbarch}, i386)
-       lsbarch=ia32
+lsbarch=ia32
 endif
 ifeq (${lsbarch}, powerpc)
-       lsbarch=ppc32
+lsbarch=ppc32
+endif
+
+LIBC=glibc (>> 2.3.5)
+ifeq (${lsbarch}, hurd-i386)
+LIBC=libc0.3 (>> 2.3.5)
+endif
+ifeq (${lsbarch}, ia64)
+LIBC=libc6.1 (>> 2.3.5)
 endif
 
 configure: configure-stamp
@@ -63,7 +71,7 @@ install: build
 
        # Add here commands to install the package into debian/lsb.
        #$(MAKE) install DESTDIR=$(CURDIR)/debian/lsb
-       cp initdutils.py install_initd remove_initd debian/lsb-core/usr/lib/lsb
+       cp initdutils.py install_initd remove_initd lsbinstall debian/lsb-core/usr/lib/lsb
        cp init-functions debian/lsb-base/lib/lsb
 
 # Build architecture-independent files here.
@@ -112,6 +120,10 @@ binary-arch: build install
        dh_installinfo -a
 #      dh_undocumented
        dh_installchangelogs -a
+       @echo >> debian/lsb-core.substvars "glibc=${LIBC}"
+       @echo >> debian/lsb-core.substvars "provides=lsb-core-${lsbarch}"
+       @echo >> debian/lsb-cxx.substvars "provides=lsb-cxx-${lsbarch}"
+       @echo >> debian/lsb-graphics.substvars "provides=lsb-graphics-${lsbarch}"
        @[ ${DEB_BUILD_ARCH} = 'amd64' ] && echo >> debian/lsb-core.substvars "depends=ia32-libs" || true
        dh_link -a
        dh_strip -a
@@ -121,9 +133,6 @@ binary-arch: build install
        dh_installdeb -a
 #      dh_perl
        dh_shlibdeps -a
-       @echo >> debian/lsb-core.substvars "provides=lsb-core-${lsbarch}"
-       @echo >> debian/lsb-cxx.substvars "provides=lsb-cxx-${lsbarch}"
-       @echo >> debian/lsb-graphics.substvars "provides=lsb-graphics-${lsbarch}"
        dh_gencontrol -a
        dh_md5sums -a
        dh_builddeb -a
index 8e91ca0f0db1b19862de7b02bebc0315a1d946bf..8644298af4d5aba8251eaa4ceeee7b0a873f070d 100644 (file)
@@ -73,7 +73,7 @@ pidofproc () {
     if [ -f "$pidfile" ]; then
         read -d "" line < "$pidfile"
         for i in $line; do
-            if [ -z "$(echo $p | sed 's/[0-9]//g')" -a -d "/proc/$i" ]; then 
+            if [ -z "$(echo $i | sed 's/[0-9]//g')" -a -d "/proc/$i" ]; then 
                 pids="$i $pids"
             fi
         done
@@ -122,29 +122,35 @@ killproc () {
     fi
 }
 
+TPUT=/usr/bin/tput
+EXPR=/usr/bin/expr
+if [ -x $TPUT ] && [ -x $EXPR ] && $TPUT hpa 60 >/dev/null 2>&1; then
+    FANCYTTY=1
+else
+    FANCYTTY=0
+fi
+
 log_success_msg () {
-    echo " * $@"
+    echo "$@"
 }
 
 log_failure_msg () {
-    TPUT=/usr/bin/tput
-    if [ -x $TPUT ] && $TPUT hpa 60 >/dev/null 2>&1; then
+    if $FANCYTTY; then
         RED=`$TPUT setaf 1`
         NORMAL=`$TPUT op`
-        echo " $RED*$NORMAL $@"
+        echo "$RED*$NORMAL $@"
     else
-        echo " * $@"
+        echo "$@"
     fi
 }
 
 log_warning_msg () {
-    TPUT=/usr/bin/tput
-    if [ -x $TPUT ] && $TPUT hpa 60 >/dev/null 2>&1; then
+    if $FANCYTTY; then
         YELLOW=`$TPUT setaf 3`
         NORMAL=`$TPUT op`
-        echo " $YELLOW*$NORMAL $@"
+        echo "$YELLOW*$NORMAL $@"
     else
-        echo " * $@"
+        echo "$@"
     fi
 }
 
@@ -163,12 +169,35 @@ get_lsb_header_val () {
 
 # int log_begin_message (char *message)
 log_begin_msg () {
-        if [ -z "$1" ]; then
-                return 1
-        fi
-        echo " * $@"
+    if [ -z "$1" ]; then
+        return 1
+    fi
+    echo -n "$@"
 }
 
+
+# #319739
+#
+# Per policy docs:
+#
+#     log_begin_msg "Starting remote file system services:"
+#     log_progress_msg "nfsd"; start-stop-daemon --start --quiet nfsd
+#     log_progress_msg "mountd"; start-stop-daemon --start --quiet mountd
+#     log_progress_msg "ugidd"; start-stop-daemon --start --quiet ugidd
+#     log_end_msg 0
+#
+# You could also do something fancy with log_end_msg here based on the
+# return values of start-stop-daemon; this is left as an exercise for
+# the reader...
+
+log_progress_msg () {
+    if [ -z "$1" ]; then
+        return 1
+    fi
+    /bin/echo -n " $@"
+}
+
+
 # int log_end_message (int exitstatus)
 log_end_msg () {
 
@@ -177,30 +206,19 @@ log_end_msg () {
 
     # Only do the fancy stuff if we have an appropriate terminal
     # and if /usr is already mounted
-    TPUT=/usr/bin/tput
-    EXPR=/usr/bin/expr
-    if [ -x $TPUT ] && [ -x $EXPR ] && $TPUT hpa 60 >/dev/null 2>&1; then
-        COLS=`$TPUT cols`
-        if [ -n "$COLS" ]; then
-            COL=`$EXPR $COLS - 7`
-        else
-            COL=73
-        fi
-        UP=`$TPUT cuu1`
-        END=`$TPUT hpa $COL`
-        START=`$TPUT hpa 0`
+    if $FANCYTTY; then
         RED=`$TPUT setaf 1`
         NORMAL=`$TPUT op`
         if [ $1 -eq 0 ]; then
-            echo "$UP$END[ ok ]"
+            echo "."
         else
-            echo -e "$UP$START $RED*$NORMAL$END[${RED}fail${NORMAL}]"
+            /bin/echo -e " ${RED}failed!${NORMAL}"
         fi
     else
        if [ $1 -eq 0 ]; then
-            echo "   ...done."
+            echo "."
         else
-            echo "   ...fail!"
+            echo " failed!"
         fi
     fi
     return $1
index c7ed1d0157505336d0d6dc7ea485e2fd9ad0951f..cd373699403ad6d88e0aa42320146c727ce96121 100644 (file)
@@ -1,6 +1,7 @@
 # Support for scanning init scripts for LSB info
 
 import re, sys, os, cStringIO
+import cPickle
 
 try:
     assert True
@@ -50,6 +51,7 @@ class RFC822Parser(dict):
 LSBLIB = '/var/lib/lsb'
 FACILITIES = os.path.join(LSBLIB, 'facilities')
 DEPENDS = os.path.join(LSBLIB, 'depends')
+LSBINSTALL = os.path.join(LSBLIB, 'lsbinstall')
 
 beginre = re.compile(re.escape('### BEGIN INIT INFO'))
 endre = re.compile(re.escape('### END INIT INFO'))
@@ -144,5 +146,32 @@ def save_depends(depends):
         print >> fh, '%s: %s' % (initfile, ' '.join(facilities))
     fh.close()
 
+# filemap entries are mappings, { (package, filename) : instloc }
+def load_lsbinstall_info():
+    if not os.path.exists(LSBINSTALL):
+        return {}
+    
+    fh = open(LSBINSTALL, 'rb')
+    filemap = cPickle.load(fh)
+    fh.close()
+
+    # Just in case it's corrupted somehow
+    if not isinstance(filemap, dict):
+        return {}
+
+    return filemap
+
+def save_lsbinstall_info(filemap):
+    if not filemap:
+        try:
+            os.unlink(LSBINSTALL)
+        except OSError:
+            pass
+        return
+    
+    fh = open(LSBINSTALL, 'wb')
+    cPickle.dump(fh, filemap)
+    fh.close()
+
 if __name__ == '__main__':
     print scan_initfile('init-fragment')
diff --git a/lsbinstall b/lsbinstall
new file mode 100755 (executable)
index 0000000..60aaa17
--- /dev/null
@@ -0,0 +1,248 @@
+#!/usr/bin/python
+
+import sys
+import os
+import shutil
+import socket
+from tempfile import NamedTemporaryFile
+from initdutils import load_lsbinstall_info, save_lsbinstall_info
+
+# These keep getting revised... *sigh*
+objecttypes = (
+    #'init',
+    'profile',
+    'service',
+    'inet',
+    #'crontab',
+    #'man'
+    )
+
+def installed_message(objectname):
+    print objectname, 'is installed'
+
+def handle_generic_install(options, args, location, showinstloc=False):
+    filename = args[0]
+    basename = os.path.basename(filename)
+    instloc = os.path.join(location, basename)
+    package = args.package
+
+    filemap = load_lsbinstall_info()
+    fileinfo = filemap.get((package, filename))
+    
+    if options.check:
+        if fileinfo and os.path.exists(fileinfo):
+            installed_message(fileinfo)
+            return
+        else:
+            sys.exit(1)
+    elif options.remove:
+        if os.path.exists(fileinfo):
+            try:
+                os.unlink(fileinfo)
+            except (IOError, OSError, os.error), why:
+                print >> sys.stderr, 'Removal of %s failed: %s' % (
+                    instloc, str(why))
+                sys.exit(1)
+
+        # Remove it from the database, even if it was previously removed
+        del filemap[(package, filename)]
+        save_lsbinstall_info(filemap)
+        return
+
+    if os.path.exists(instloc) and options.package:
+        instloc = os.path.join(location, '%s.%s' % (options.package, basename))
+
+    if os.path.exists(instloc):
+        print >> sys.stderr, 'Unable to install %s: %s exists' % (
+            filename, instloc)
+        sys.exit(1)
+
+    if not os.path.exists(location):
+        try:
+            os.makedirs(location)
+        except (IOError, OSError, os.error), why:
+            print >> sys.stderr, 'Unable to create %s to install %s: %s' % (
+                location, filename, str(why))
+            sys.exit(1)
+        
+    try:
+        shutil.copy2(filename, instloc)
+    except (IOError, os.error), why:
+        print >> sys.stderr, 'Installation of %s as %s failed: %s' % (
+            filename, instloc, str(why))
+        sys.exit(1)
+        
+    if showinstloc:
+        print instloc
+
+    filemap[(package, filename)] = instloc
+    save_lsbinstall_info(filemap)
+
+def handle_service(options, args):
+    # LSB says we don't actually have to remove these things...
+    if options.remove:
+        sys.exit(0)
+
+    pkg = options.package or '<unknown package>'
+
+    try:
+        pproto = args[0]
+        port, proto = pproto.split('/', 1)
+        port = int(port)
+    except:
+        print >> sys.stderr, 'You must specify a port/protocol pair as the first argument.'
+        sys.exit(2)
+
+    if options.check:
+        try:
+            serv = socket.getservbyport(port, proto)
+        except socket.error:
+            sys.exit(1)
+
+        print '%d/%s corresponds to service %s' % (port, proto, serv)
+        return
+
+    sname = args[1]
+    saliases = args[2:]
+
+    try:
+        serv = socket.getservbyport(port, proto)
+    except socket.error:
+        serv = None
+
+    if serv:
+        # Editing existing service
+        fpin = open('/etc/services')
+        fpout = NamedTemporaryFile('w', prefix='services-', dir='/etc')
+        newfname = fpout.name
+
+        for line in fpin:
+            line = line.rstrip()
+            if not line.startswith('#'):
+                lcomment = ''
+                if '#' in line:
+                    line, lcomment = line.split('#', 1)
+                
+                bits = line.split(None, 2)
+                lname, lpproto = bits[:2]
+                laliases = []
+                if len(bits) > 2:
+                    laliases = bits[2].split()
+
+                lport, lproto = lpproto.split('/')
+                lport = int(lport)
+
+                if lport == port and lproto == proto:
+                    # We've found the right line
+                    if name != lname:
+                        aliases += [name]
+
+                    for a in aliases:
+                        if a != lname and a not in laliases:
+                            laliases += [a]
+                elif name == lname or name in laliases:
+                    # name shows up, but in wrong protocol/port
+                    print >> sys.stderr, 'Conflict between specified addition and /etc/services; aborting.'
+                    fpout.close()
+                    os.unlink(newfname)
+                    sys.exit(1)
+
+                endbits = ''
+                if laliases:
+                    endbits = ' '.join(laliases) + ' '
+                if lcomment:
+                    endbits += '#'+lcomment
+                    
+                line = '%15s %15s %s' % lname, lpproto, endbits
+                line = line.rstrip()
+
+            print >> fpout, line
+        
+        fpin.close()
+        fpout.close()
+        # Make sure /etc/services is always available
+        shutil.copy2('/etc/services', '/etc/services~')
+        os.rename(newfname, '/etc/services')
+        return
+
+    fp = open('/etc/services', 'a')
+    print >> fp, '%15s %15s %s # Added by lsbinstall for %s' % (
+        sname, pproto, ' '.join(saliases), pkg)
+    fp.close()
+
+def handle_inet(options, args):
+    # call update-inetd
+    pass
+
+def handle_man(options, args):
+    # Try to figure out the man page section
+    section = 1
+    
+    location = '/usr/local/share/man/man%d/' % section
+
+    handle_generic_install(options, args, location)
+
+
+def main():
+    from optparse import OptionParser
+
+    parser = OptionParser('usage: %prog [-r|-c] -t TYPE arguments...')
+    parser.add_option('-c', '--check', dest="check", default=False,
+                      action="store_true", help='check whether or not an '
+                      'object of this type is already installed')
+    parser.add_option('-r', '--remove', action="store_true",
+                      dest="remove", default=False,
+                      help='remove the named object')
+    parser.add_option('-t', '--type', dest="type", type='choice',
+                      default=None, choices=objecttypes,
+                      help='type of object to be '
+                      'installed: one of %s' % ', '.join(objecttypes) )
+    parser.add_option('-p', '--package', dest="package", default=None,
+                      help='LSB package to operate on')
+
+    (options, args) = parser.parse_args()
+
+    if len(args) < 1:
+        parser.error('You must specify at least one argument.')
+    elif (options.remove or options.check) and len(args) > 1:
+        parser.error('You may only specify one argument with --check or '
+                     '--remove.')
+
+    if not options.type:
+        parser.error('You must specify an object type.')
+
+    if not options.package and options.type not in ['service']:
+        parser.error('You must specify a package with %s objects.' %
+                     options.type)
+
+    if options.type == 'init':
+        if len(args) > 1:
+            parser.error('Only one argument supported for %s' % options.type)
+        handle_generic_install(options, args, '/etc/init.d', showinstloc=True)
+    elif options.type == 'profile':
+        if len(args) > 1:
+            parser.error('Only one argument supported for %s' % options.type)
+        # profile.d does nothing on Debian... sigh
+        handle_generic_install(options, args, '/etc/profile.d')
+    elif options.type == 'service':
+        if len(args) < 2 and not (options.remove or options.check):
+            parser.error('You must specify at least two arguments when adding a service entry.')
+        elif len(args) != 1 and (options.remove or options.check):
+            parser.error('You must specify one argument when removing or checking a service entry.')
+        handle_service(options, args)
+    elif options.type == 'inet':
+        handle_inet(options, args)
+    elif options.type == 'crontab':
+        if len(args) > 1:
+            parser.error('Only one argument supported for %s' % options.type)
+        handle_generic_install(options, args, '/etc/cron.d')
+    elif options.type == 'man':
+        if len(args) > 1:
+            parser.error('Only one argument supported for %s' % options.type)
+        handle_man(options, args)
+    else:
+        print >> sys.stderr, 'Unsupported type %s' % options.type
+        sys.exit(1)
+
+if __name__ == '__main__':
+    main()