[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Transition from dpkg to GNU install-info



On Fri, 13 Mar 2009, Norbert Preining wrote:
> > The Breaks: added to dpkg ensures that info browsers have the right
> > dependency on install-info. That's enough, there's no reason to die.
> 
> Ok, who is going to write the dpkg install-info wrapper?

I just wrote it. I had to do it in C otherwise I couldn't do the check
on how it's called.

Patch attached and test package at:
http://people.debian.org/~hertzog/packages/dpkg_1.15.1~testii_i386.changes

Branch pu/install-info at:
http://git.debian.org/?p=users/hertzog/dpkg.git;a=shortlog;h=refs/heads/pu/install-info
git://git.debian.org/users/hertzog/dpkg.git

> > If the official upstream name is install-info, then we should rather keep
> > that intermediary wrapper.
> 
> Right. We keep the intermediate wrapper, and after squeeze or so we drop
> all of the wrappers and ship only install-info as GNU.

Yes.

> > But we have to handle the info browsers first before we can upload dpkg.
> > Which in turn means that the new install info must be available in sid.
> 
> Why? What would change? info-browsers (see below) should depend on
> install-info, but if they don't well, then we file a bug to fix that.
> But we should have install-info first in sid.

When we upload dpkg to sid, if it contains the Breaks dep,
it will effectively break all info-browsers that have not been updated
yet. It's best to avoid that if possible by doing the dpkg upload after
the info-browsers update.

> Anyway, does that mean with the ok of more people here that after
> testing dpkg (hopefully after the weekend with your patch) I should
> upload to sid?

I guess so. Asking for review/test on -devel is certainly a good idea at
this point.

> Apropos info browsers, that would be:
> 	info (me)
> 	pinfo
> 	tkinfo
> plus several others that ship as "info-browser"
> 	emacs (why does each and every emacs package provide info-browser)
> 	(x)jed (why please does jed-extra provide info-browser?)
> 	konqueror
> 	xemacs* (same)

That will give a somewhat bloated Breaks line but it's better than
allowing broken combinations.

Cheers,
-- 
Raphaël Hertzog

Contribuez à Debian et gagnez un cahier de l'admin Debian Lenny :
http://www.ouaza.com/wp/2009/03/02/contribuer-a-debian-gagner-un-livre/
>From 3c9d26c5d5c21ad41f4cbc6ed772048352628f76 Mon Sep 17 00:00:00 2001
From: Raphael Hertzog <hertzog@debian.org>
Date: Fri, 13 Mar 2009 15:47:52 +0100
Subject: [PATCH] Replace install-info by a simple wrapper (or no-op command)

In order to properly transition to GNU's install-info, dpkg's install-info
is modified to be a simple wrapper around /usr/bin/install-info. That
wrapper warns when the user explicitely calls /usr/sbin/install-info since
the new install-info is in /usr/bin/.

This wrapper is meant to be removed at some point when all references
to /usr/sbin/install-info have gone (most probably in squeeze+1).

Also remove the manual page since there's nothing to document any more
and add a lintian override until the wrapper is removed.

TODO: Add the breaks on all info browsers.

Reference: http://wiki.debian.org/Transitions/DpkgToGnuInstallInfo
---
 debian/dpkg.install           |    1 -
 debian/dpkg.lintian-overrides |    2 +
 man/Makefile.am               |    1 -
 man/install-info.8            |  295 -----------------------
 man/po/po4a.cfg               |    5 -
 po/POTFILES.in                |    1 -
 scripts/Makefile.am           |   16 +--
 scripts/install-info.pl       |  524 -----------------------------------------
 utils/.gitignore              |    1 +
 utils/Makefile.am             |   14 +-
 utils/install-info.c          |   34 +++
 11 files changed, 51 insertions(+), 843 deletions(-)
 delete mode 100644 man/install-info.8
 delete mode 100755 scripts/install-info.pl
 create mode 100644 utils/install-info.c

diff --git a/debian/dpkg.install b/debian/dpkg.install
index 8e956cd..599c02f 100644
--- a/debian/dpkg.install
+++ b/debian/dpkg.install
@@ -23,7 +23,6 @@ usr/share/man/{*/*,*}/dpkg-statoverride.8
 usr/share/man/{*/*,*}/dpkg-trigger.1
 usr/share/man/{*/*,*}/dpkg.cfg.5
 usr/share/man/{*/*,*}/dpkg.1
-usr/share/man/{*/*,*}/install-info.8
 usr/share/man/{*/*,*}/start-stop-daemon.8
 usr/share/man/{*/*,*}/update-alternatives.8
 usr/share/perl5/Dpkg.pm
diff --git a/debian/dpkg.lintian-overrides b/debian/dpkg.lintian-overrides
index eb946ed..96d2a70 100644
--- a/debian/dpkg.lintian-overrides
+++ b/debian/dpkg.lintian-overrides
@@ -2,3 +2,5 @@ dpkg: redundant-origin-field
 dpkg: redundant-bugs-field
 dpkg: arch-dep-package-has-big-usr-share
 dpkg: package-contains-empty-directory usr/share/dpkg/origins/
+# On purpose, install-info is only a wrapper that will be removed soon
+dpkg: binary-without-manpage usr/sbin/install-info
diff --git a/man/Makefile.am b/man/Makefile.am
index 2c0403a..a35c706 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -98,7 +98,6 @@ dist_man_MANS = \
 	dpkg.cfg.5 \
 	dselect.1 \
 	dselect.cfg.5 \
-	install-info.8 \
 	start-stop-daemon.8 \
 	update-alternatives.8
 
diff --git a/man/install-info.8 b/man/install-info.8
deleted file mode 100644
index 954377e..0000000
--- a/man/install-info.8
+++ /dev/null
@@ -1,295 +0,0 @@
-.\" Install-info and this manpage are Copyright © 1994 by Ian Jackson.
-.\"
-.\" This is free software; see the GNU General Public Licence version 2
-.\" or later for copying conditions.  There is NO warranty.
-.TH install\-info 8 "2008-08-18" "Debian Project" "dpkg utilities"
-.SH NAME
-install\-info \- create or update entry in Info dir file
-.
-.SH SYNOPSIS
-.B install\-info
-.RB [ \-\-version ]
-.RB [ \-\-help ]
-.RB [ \-\-debug ]
-.RB [ \-\-maxwidth=\fInnn\fP ]
-.RB [ "\-\-section \fIregexp\fP \fItitle\fP" ]
-.RB [ \-\-infodir=\fIxxx\fP ]
-.RB [ \-\-align=\fInnn\fP ]
-.RB [ \-\-quiet ]
-.RB [ \-\-menuentry=\fIxxx\fP ]
-.RB [ \-\-description=\fIxxx\fP ]
-.RB [ \-\-remove | \-\-remove\-exactly ]
-.RB [ \-\- ]
-.I filename
-.
-.SH DESCRIPTION
-.B install\-info
-creates, updates or removes entries in the Info
-.B dir
-file. When updating or creating entries, if no description is
-specified on the command line or in the Info file, it attempts to guess
-a description from the contents of the file.
-.PP
-See the description of the
-.B \-\-section
-option for details of where the entry will be placed and a description
-of the expected format of the
-.B dir
-file.
-.SH OPTIONS
-.TP
-.BI "[\-\-] " filename
-Gives the filename of the Info file whose menu entry is to be created,
-updated or removed. If
-.B \-\-remove\-exactly
-is specified, then
-.I filename
-should be the exact entry name to be removed (e.g. "emacs\-20/emacs" or
-"gcc"), otherwise the basename of this filename is used as the
-referent of the menu entry which is created, unless there's an
-overriding START-INFO-DIR entry inside the given file. This file must
-therefore exist (or be about to be installed, or have previously
-existed when removing an entry) in the same directory as the
-.B dir
-file (see the
-.B \-\-infodir
-option).
-
-If
-.I filename
-ends in \fB.gz\fP, it is taken to refer to a file compressed with \fBgzip\fP;
-if it doesn't exist, but a corresponding
-.IB filename .gz
-does, the latter is used instead.
-
-When adding or updating entries, the file must exist at the path
-specified (possibly with an additional
-.B .gz
-extension).
-.TP
-.B \-\-remove
-Specifies that the entry for the file
-.I filename
-is to be removed; by default entries are created or updated.
-
-If the removal results in a section becoming empty, the section heading
-(and the spare blank line) will be removed as well, unless this is the
-last section in the file or
-.B \-\-keep\-old
-is specified. See the
-.B \-\-section
-option for details about the expected format of the
-.B dir
-file.
-
-If there are several suitable entries in the
-.B dir
-file, only those in the first matching contiguous group will be removed
-and the others silently ignored.
-
-It is not an error for no suitable entry to be found, though
-.B install\-info
-will issue a warning unless the
-.B \-\-quiet
-option was specified.
-
-When
-.B \-\-remove
-is specified the
-.BR \-\-maxwidth ", " \-\-align " and " \-\-calign
-formatting options are silently ignored.
-.TP
-.B \-\-remove\-exactly
-This option is essentially the same as
-.B \-\-remove
-except that
-.I filename
-is taken as the exact entry to be removed, rather than as the name
-of an existing file. This can be important when trying to remove
-entries that refer to info files in subdirectories
-(e.g. "emacs\-20/emacs") because
-.B \-\-remove
-will operate on the basename of the given
-.I filename
-rather than the exact name given. (i.e.
-.B \-\-remove
-"emacs\-20/emacs" would cause
-.B install\-info
-to look for "emacs", not "emacs\-20/emacs").
-.TP
-.BI "\-\-section " "regexp title"
-Specifies that if a new entry is to be made, it should be placed in a
-section of the
-.B dir
-file whose title matches
-.IR regexp .
-If no such section exists, one will be created as the second to last
-section in the file (see below) with title
-.IR title .
-A section is a part of the
-.B dir
-menu delimited by blank lines; the first line is assumed to be the
-title.
-
-If a new entry is to be created,
-.B install\-info
-will attempt to insert it within the section in alphabetic order. If
-the entries in the section aren't already sorted, the new location
-within the section will be unpredictable. The order of existing
-entries will not be changed.
-
-If the
-.B \-\-section
-option is not specified,
-.B install\-info
-will look for a title in the Info file itself by looking for an entry
-of the form
-
-.br
-.BI "INFO\-DIR\-SECTION" " title"
-.br
-
-If no section title is found, the default is to append new entries to
-the end of the file. The last section (even if it only consists of the
-title line) should always exist to ensure that new sections are
-created in the right place. The final section should be titled to
-reflect the fact that Info files with no better specified location
-are appended to it.
-
-If there is already an entry for the Info file being installed, it is
-replaced in situ with the new entry.
-
-If a section is specified when removing an entry, the section is
-ignored and a warning is issued.
-
-If a section is requested when adding an entry, but the file contains
-no section headings at all, then
-.B install\-info
-will create both the requested section and a Miscellaneous section at
-the end of the file.
-.TP
-.BI \-\-infodir= infodir
-Specifies that the
-.B dir
-file is, and the installed copy of the new Info file was, is or will
-be located in
-.IR infodir .
-The default is
-.BR /usr/share/info/ .
-.TP
-.BI \-\-align= nnn " [deprecated]"
-Specifies that the first line of the description should be indented at
-least
-.I nnn
-characters; extra spaces will be added as required. If necessary
-because of the length of the
-.B dir
-menu entry details, it may be offset more. The default is 27.
-.TP
-.BI \-\-calign= nnn " [deprecated]"
-Specifies that the second and subsequent lines of the description
-should be indented at least
-.I nnn
-characters. The default is 29.
-.TP
-.BI \-\-maxwidth= nnn " [deprecated]"
-Specifies that the maximum width for the Info file is
-.IR nnn .
-This is used when word-wrapping the descriptive text.
-The default is 79.
-.TP
-.B \-\-quiet
-Prevents the usual display of the new menu entry just before it is
-inserted and of the messages announcing the replacement and removal
-of existing entries and the creation and deletion of sections.
-.TP
-.B \-\-help
-Causes
-.B install\-info
-to display its usage information and exit.
-.TP
-.B \-\-version
-Causes
-.B install\-info
-to display its version and copyright information and exit.
-.TP
-.BI \-\-description= xxx
-Specifies that the description to use after the menu entry in new or
-updated entries be
-.IR xxx .
-The default is to use the the value specified in the Info file itself;
-this is found by searching for a section of the form
-.br
-.B START\-INFO\-DIR\-ENTRY
-.br
-.B * Auto-PGP: (auto-pgp). PGP under GNU Emacs.
-.br
-.B END\-INFO\-DIR\-ENTRY
-
-If the entry found in the Info file itself extends across several
-lines, each giving a menu entry, the text found in the file is used
-verbatim. In this case, the alphabetic ordering scheme is turned off,
-and the entries are inserted at the top of section in question. In
-this case, the
-.BR \-\-menuentry ", " \-\-maxwidth ", " \-\-align ", " \-\-calign
-.RB " and " \-\-menuentry
-options are ignored.
-
-If there is no
-.B dir
-entry in the file, the program will try to find a paragraph early in
-the file starting
-.BR "this file documents" .
-It will capitalise the first character of the remainder, and use that.
-
-It is an error for none of these methods to yield a description.
-
-If a description argument is given when
-.B \-\-remove
-is specified, it is ignored and a warning is issued.
-.TP
-.BI \-\-menuentry= xxx
-Specifies that the entry in the menu should be
-.IR xxx .
-The default is to use the the value specified in the Info file itself.
-If this is not present, the basename of the Info file is used
-.RB "(any " ".info " "is deleted, and the entry is made mixed case)."
-See above for details of the format expected for the menu entry in the
-Info file.
-
-When removing entries, the value of the
-.B \-\-menuentry
-option must match the actual menu entry field in the menu item to be
-removed (case not significant). If
-.B \-\-menuentry
-is omitted, no check on the menu entry is done.
-.TP
-.B \-\-keep\-old
-Inhibits the replacement of existing entries and the removal of empty
-sections.
-
-If the file being installed already has an entry in the Info \fBdir\fP file,
-the old entry will be left alone instead of being replaced; the default is
-to overwrite any old entry found with the newly generated one.
-
-If
-.BR \-\-remove " is specified, " \-\-keep\-old
-will prevent the removal of the section heading which would otherwise
-happen if the section is made empty by the removal.
-.TP
-.B \-\-test
-Enables test mode, which inhibits the update of the Info \fBdir\fP file.
-.TP
-.B \-\-debug
-Enables debugging mode, in which the results of some internal
-processing steps are shown.
-.
-.SH "SEE ALSO"
-.BR emacs (1),
-.BR info (1),
-.BR gzip(1).
-.SH AUTHOR
-Copyright \(co 1994 Ian Jackson
-.sp
-This is free software; see the GNU General Public Licence version 2 or
-later for copying conditions. There is NO WARRANTY.
diff --git a/man/po/po4a.cfg b/man/po/po4a.cfg
index 90b0c8f..46b2b2c 100644
--- a/man/po/po4a.cfg
+++ b/man/po/po4a.cfg
@@ -173,11 +173,6 @@
            add_$lang:$(srcdir)/po/$lang.add
 
 
-[type:man] $(srcdir)/install-info.8             \
-           $lang:$lang/install-info.8           \
-           add_$lang:$(srcdir)/po/$lang.add
-
-
 [type:man] $(srcdir)/start-stop-daemon.8        \
            $lang:$lang/start-stop-daemon.8      \
            add_$lang:$(srcdir)/po/$lang.add
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5cf9e3f..c26b3e3 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -59,5 +59,4 @@ utils/start-stop-daemon.c
 
 scripts/dpkg-divert.pl
 scripts/dpkg-statoverride.pl
-scripts/install-info.pl
 scripts/update-alternatives.pl
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index dae6b44..cb7ef49 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -43,7 +43,6 @@ EXTRA_DIST = \
 	dpkg-source.pl \
 	dpkg-divert.pl \
 	dpkg-statoverride.pl \
-	install-info.pl \
 	update-alternatives.pl \
 	changelog/debian.pl \
 	t/000_pod.t \
@@ -78,8 +77,7 @@ EXTRA_DIST = \
 	t/900_update_alternatives.t
 
 CLEANFILES = \
-	$(bin_SCRIPTS) $(changelog_SCRIPTS) \
-	install-info install-info-stamp
+	$(bin_SCRIPTS) $(changelog_SCRIPTS)
 
 perllibdir = $(PERL_LIBDIR)
 nobase_dist_perllib_DATA = \
@@ -142,18 +140,6 @@ do_shell_subst = sed -e "s:version=\"[^\"]*\":version=\"$(PACKAGE_VERSION)\":"
 	$(do_shell_subst) <$< >$@
 	chmod +x $@
 
-
-# Automake has its own install-info rule, gah
-all-local: install-info-stamp
-install-info-stamp: $(srcdir)/install-info.pl
-	$(do_perl_subst) <$< >install-info
-	chmod +x install-info
-	touch $@
-
-install-exec-local: install-info-stamp
-	$(mkdir_p) $(DESTDIR)$(sbindir)
-	$(INSTALL_SCRIPT) install-info $(DESTDIR)$(sbindir)
-
 install-data-local:
 	$(mkdir_p) $(DESTDIR)$(sysconfdir)/alternatives
 	$(INSTALL_DATA) $(srcdir)/README.alternatives $(DESTDIR)$(sysconfdir)/alternatives/README
diff --git a/scripts/install-info.pl b/scripts/install-info.pl
deleted file mode 100755
index c3552bd..0000000
--- a/scripts/install-info.pl
+++ /dev/null
@@ -1,524 +0,0 @@
-#!/usr/bin/perl --
-
-BEGIN { # Work-around for bug #479711 in perl
-    $ENV{PERL_DL_NONLAZY} = 1;
-}
-
-use Text::Wrap;
-use Dpkg;
-use Dpkg::Gettext;
-
-textdomain("dpkg");
-
-# FIXME: sort entries
-# FIXME: send to FSF ?
-
-sub version {
-    printf _g("Debian %s version %s.\n"), $progname, $version;
-
-    printf _g("
-Copyright (C) 1994,1995 Ian Jackson.");
-
-    printf _g("
-This is free software; see the GNU General Public Licence version 2 or
-later for copying conditions. There is NO warranty.
-");
-}
-
-sub usage {
-    $file = $_[0];
-    printf $file _g(
-"Usage: %s [<options> ...] [--] <filename>
-
-Options:
-  --section <regexp> <title>
-                           put the new entry in the <regex> matched section
-                           or create a new one with <title> if non-existent.
-  --menuentry=<text>       set the menu entry.
-  --description=<text>     set the description to be used in the menu entry.
-  --info-file=<path>       specify info file to install in the directory.
-  --dir-file=<path>        specify file name of info directory file.
-  --infodir=<directory>    same as '--dir-file=<directory>/dir'.
-  --info-dir=<directory>   likewise.
-  --keep-old               do not replace entries nor remove empty ones.
-  --remove                 remove the entry specified by <filename> basename.
-  --remove-exactly         remove the exact <filename> entry.
-  --test                   enables test mode (no actions taken).
-  --debug                  enables debug mode (show more information).
-  --quiet                  do not show output messages.
-  --help                   show this help message.
-  --version                show the version.
-"), $progname;
-}
-
-$dirfile = '/usr/share/info/dir';
-$maxwidth=79;
-$Text::Wrap::columns=$maxwidth;
-$backup='/var/backups/infodir.bak';
-$default='/usr/share/base-files/info.dir';
-
-$menuentry="";
-$description="";
-$sectionre="";
-$sectiontitle="";
-$infoentry="";
-$quiet=0;
-$nowrite=0;
-$keepold=0;
-$debug=0;
-$remove=0;
-
-my $remove_exactly;
-
-$0 =~ m|[^/]+$|; $name= $&;
-
-while ($ARGV[0] =~ m/^--/) {
-    $_= shift(@ARGV);
-    last if $_ eq '--';
-    if ($_ eq '--version') {
-        &version(STDOUT); exit 0;
-    } elsif ($_ eq '--quiet') {
-        $quiet=1;
-    } elsif ($_ eq '--test') {
-        $nowrite=1;
-    } elsif ($_ eq '--keep-old') {
-        $keepold=1;
-    } elsif ($_ eq '--remove') {
-        $remove=1;
-    } elsif ($_ eq '--remove-exactly') {
-        $remove=1;
-        $remove_exactly=1;
-    } elsif ($_ eq '--help') {
-        &usage(STDOUT); exit 0;
-    } elsif ($_ eq '--version') {
-        &version; exit 0;
-    } elsif ($_ eq '--debug') {
-	open(DEBUG,">&STDERR")
-	    || &quit(sprintf(_g("could not open stderr for output! %s"), $!));
-	$debug=1;
-    } elsif ($_ eq '--section') {
-        if (@ARGV < 2) {
-	    printf STDERR _g("%s: --section needs two more args")."\n", $name;
-            &usage(STDERR); exit 1;
-        }
-        $sectionre= shift(@ARGV);
-        $sectiontitle= shift(@ARGV);
-    } elsif (m/^--(c?align|maxwidth)=([0-9]+)$/) {
-	warn(sprintf(_g("%s: option --%s is deprecated (ignored)"), $name, $1)."\n");
-    } elsif (m/^--info-?dir=/) {
-	$dirfile = $' . '/dir';
-    } elsif (m/^--info-file=/) {
-	$filename = $';
-    } elsif (m/^--menuentry=/) {
-	$menuentry = $';
-    } elsif (m/^--description=/) {
-	$description = $';
-    } elsif (m/^--dir-file=/) { # for compatibility with GNU install-info
-	$dirfile = $';
-    } else {
-        printf STDERR _g("%s: unknown option \`%s'")."\n", $name, $_;
-        &usage(STDERR); exit 1;
-    }
-}
-
-if (!@ARGV) { &usage(STDERR); exit 1; }
-
-if ( !$filename ) {
-	$filename= shift(@ARGV);
-	$name = "$name($filename)";
-}
-if (@ARGV) { printf STDERR _g("%s: too many arguments")."\n", $name; &usage(STDERR); exit 1; }
-
-if ($remove) {
-    printf(STDERR _g("%s: --section ignored with --remove")."\n", $name) if length($sectiontitle);
-    printf(STDERR _g("%s: --description ignored with --remove")."\n", $name) if length($description);
-}
-
-printf(STDERR _g("%s: test mode - dir file will not be updated")."\n", $name)
-    if $nowrite && !$quiet;
-
-umask(umask(0777) & ~0444);
-
-if($remove_exactly) {
-    $remove_exactly = $filename;
-}
-
-$filename =~ m|[^/]+$|; $basename= $&; $basename =~ s/(\.info)?(\.gz)?$//;
-
-# The location of the info files from the dir entry, i.e. (emacs-20/emacs).
-my $fileinentry;
-
-&dprint("dirfile='$dirfile' filename='$filename' maxwidth='$maxwidth'");
-&dprint("menuentry='$menuentry' basename='$basename'");
-&dprint("description='$description' remove=$remove");
-
-if (!$remove) {
-
-    if (!-f $filename && -f "$filename.gz" || $filename =~ s/\.gz$//) {
-        $filename= "gzip -cd <$filename.gz |";  $pipeit= 1;
-    } elsif (-f $filename) {
-        $filename= "< $filename";
-    } else {
-        die "$progname: File $filename not found\n";
-    }
-
-    if (!length($description)) {
-        
-        open(IF,"$filename") || &quit(sprintf(_g("unable to read %s: %s"), $filename, $!));
-        $asread='';
-        while(<IF>) {
-	    m/^START-INFO-DIR-ENTRY$/ && last;
-	    m/^INFO-DIR-SECTION (.+)$/ && do {
-		$sectiontitle = $1		unless ($sectiontitle);
-		$sectionre = '^'.quotemeta($1)	unless ($sectionre);
-	    }
-	}
-        while(<IF>) { last if m/^END-INFO-DIR-ENTRY$/; $asread.= $_; }
-	if ($pipeit) {
-	    while (<IF>) {};
-	}
-
-        close(IF); &checkpipe;
-        if ($asread =~ m/(\*\s*[^:]+:\s*\(([^\)]+)\).*\. *.*\n){2}/) {
-            $infoentry= $asread;
-            $multiline= 1;
-            $fileinentry = $2;
-            &dprint("multiline '$asread'");
-        } elsif ($asread =~ m/^\*\s*([^:]+):(\s*\(([^\)]+)\)\.|:)\s*/) {
-            $menuentry= $1;
-            $description = $';
-            $fileinentry = $3;
-            &dprint("infile menuentry '$menuentry' description '$description'");
-        } elsif (length($asread)) {
-            printf STDERR _g("%s: warning, ignoring confusing INFO-DIR-ENTRY in file.")."\n", $name;
-        }
-    }
-
-    if (length($infoentry)) {
-
-        $infoentry =~ m/\n/;
-        print "$`\n" unless $quiet;
-        $infoentry =~ m/^\*\s*([^:]+):\s*\(([^\)]+)\)/ || 
-            &quit(_g("invalid info entry")); # internal error
-        $sortby= $1;
-        $fileinentry= $2;
-
-    } else {
-
-        if (!length($description)) {
-            open(IF,"$filename") || &quit(_g("unable to read %s: %s"), $filename, $!);
-            $asread='';
-            while(<IF>) {
-                if (m/^\s*[Tt]his file documents/) {
-                    $asread = $';
-                    last;
-                }
-            }
-            if (length($asread)) {
-                while(<IF>) { last if m/^\s*$/; $asread.= $_; }
-                $description= $asread;
-            }
-	    if ($pipeit) {
-		while (<IF>) {};
-	    }
-            close(IF); &checkpipe;
-        }
-
-        if (!length($description)) {
-            printf STDERR _g("
-No \`START-INFO-DIR-ENTRY' and no \`This file documents'.
-%s: unable to determine description for \`dir' entry - giving up
-"), $name;
-            exit 1;
-        }
-
-        $description =~ s/^\s*(.)//;  $_=$1;  y/a-z/A-Z/;
-        $description= $_ . $description;
-
-        if (!length($menuentry)) {
-            $menuentry= $basename;  $menuentry =~ s/\Winfo$//;
-            $menuentry =~ s/^.//;  $_=$&;  y/a-z/A-Z/;
-            $menuentry= $_ . $menuentry;
-        }
-
-        &dprint("menuentry='$menuentry'  description='$description'");
-
-        if($fileinentry) {
-            $cprefix= sprintf("* %s: (%s).", $menuentry, $fileinentry);
-        } else {
-            $cprefix= sprintf("* %s: (%s).", $menuentry, $basename);
-        }
-
-        $align--; $calign--;
-        $lprefix= length($cprefix);
-        if ($lprefix < $align) {
-            $cprefix .= ' ' x ($align - $lprefix);
-            $lprefix= $align;
-        }
-        $prefix= "\n". (' 'x $calign);
-        $cwidth= $maxwidth+1;
-
-        for $_ (split(/\s+/,$description)) {
-            $l= length($_);
-            $cwidth++; $cwidth += $l;
-            if ($cwidth > $maxwidth) {
-                $infoentry .= $cprefix;
-                $cwidth= $lprefix+1+$l;
-                $cprefix= $prefix; $lprefix= $calign;
-            }
-            $infoentry.= ' '; $infoentry .= $_;
-        }
-
-        $infoentry.= "\n";
-        print $infoentry unless $quiet;
-        $sortby= $menuentry;  $sortby =~ y/A-Z/a-z/;
-
-    }
-}
-
-if (!$nowrite && ( ! -e $dirfile || ! -s _ )) {
-    if (-r $backup) {
-	printf( STDERR _g("%s: no file %s, retrieving backup file %s.")."\n",
-		$name, $dirfile, "$backup" );
-	if (system ('cp', $backup, $dirfile)) {
-	    printf( STDERR _g("%s: copying %s to %s failed, giving up: %s")."\n",
-		    $name, $backup, $dirfile, $! );
-	    exit 1;
-	}
-    } else {
-        if (-r $default) {
-	    printf( STDERR _g("%s: no backup file %s available, retrieving default file.")."\n",
-		    $name, $backup );
-
-	    if (system('cp', $default, $dirfile)) {
-		printf( STDERR _g("%s: copying %s to %s failed, giving up: %s")."\n",
-			$name, $default, $dirfile, $! );
-		exit 1;
-	    }
-	} else {
-	    printf STDERR _g("%s: no backup file %s available.")."\n", $name, $backup;
-	    printf STDERR _g("%s: no default file %s available, giving up.")."\n", $name, $default;
-	    exit 1;
-	}
-    }
-}
-
-if (!$nowrite && !link($dirfile, "$dirfile.lock")) {
-    printf( STDERR _g("%s: failed to lock dir for editing! %s")."\n",
-	    $name, $! );
-    printf( STDERR _g("try deleting %s?")."\n", "$dirfile.lock")
-	if $!{EEXIST};
-    exit 1;
-}
-
-open(OLD, $dirfile) || &ulquit(sprintf(_g("unable to open %s: %s"), $dirfile, $!));
-@work= <OLD>;
-eof(OLD) || &ulquit(sprintf(_g("unable to read %s: %s"), $dirfile, $!));
-close(OLD) || &ulquit(sprintf(_g("unable to close %s after read: %s"),
-				 $dirfile, $!));
-
-while (($#work >= 0) && ($work[$#work] !~ m/\S/)) { $#work--; }
-
-while (@work) {
-    $_= shift(@work);
-    push(@head,$_);
-    last if (m/^\*\s*Menu:/i);
-}
-
-if (!$remove) {
-
-    my $target_entry;
-
-    if($fileinentry) {
-        $target_entry = $fileinentry;
-    } else {
-        $target_entry = $basename;
-    }
-
-    for ($i=0; $i<=$#work; $i++) {
-        next unless $work[$i] =~ m/^\*\s*[^:]+:\s*\(([^\)]+)\).*\.\s/;
-        last if $1 eq $target_entry || $1 eq "$target_entry.info";
-    }
-    for ($j=$i; $j<=$#work+1; $j++) {
-        next if $work[$j] =~ m/^\s+\S/;
-        last unless $work[$j] =~ m/^\* *[^:]+: *\(([^\)]+)\).*\.\s/;
-        last unless $1 eq $target_entry || $1 eq "$target_entry.info";
-    }
-
-    if ($i < $j) {
-        if ($keepold) {
-            printf(_g("%s: existing entry for \`%s' not replaced")."\n", $name, $target_entry) unless $quiet;
-            $nowrite=1;
-        } else {
-            printf(_g("%s: replacing existing dir entry for \`%s'")."\n", $name, $target_entry) unless $quiet;
-        }
-        $mss= $i;
-        @work= (@work[0..$i-1], @work[$j..$#work]);
-    } elsif (length($sectionre)) {
-        $mss= -1;
-        for ($i=0; $i<=$#work; $i++) {
-            $_= $work[$i];
-            next if m/^(\*|\s)/;
-            next unless m/$sectionre/io;
-            $mss= $i+1; last;
-        }
-        if ($mss < 0) {
-            printf(_g("%s: creating new section \`%s'")."\n", $name, $sectiontitle) unless $quiet;
-            for ($i= $#work; $i>=0 && $work[$i] =~ m/\S/; $i--) { }
-            if ($i <= 0) { # We ran off the top, make this section and Misc.
-                printf(_g("%s: no sections yet, creating Miscellaneous section too.")."\n", $name)
-                    unless $quiet;
-                @work= ("\n", "$sectiontitle\n", "\n", "Miscellaneous:\n", @work);
-                $mss= 1;
-            } else {
-                @work= (@work[0..$i], "$sectiontitle\n", "\n", @work[$i+1..$#work]);
-                $mss= $i+1;
-            }
-        }
-        while ($mss <= $#work) {
-            $work[$mss] =~ m/\S/ || last;
-            $work[$mss] =~ m/^\* *([^:]+):/ || ($mss++, next);
-            last if $multiline;
-            $_=$1;  y/A-Z/a-z/;
-            last if $_ gt $sortby;
-            $mss++;
-        }
-    } else {
-        printf(_g("%s: no section specified for new entry, placing at end")."\n", $name)
-            unless $quiet;
-        $mss= $#work+1;
-    }
-
-    @work= (@work[0..$mss-1], map("$_\n",split(/\n/,$infoentry)), @work[$mss..$#work]);
-    
-} else {
-
-    my $target_entry;
-
-    if($remove_exactly) {
-        $target_entry = $remove_exactly;
-    } else {
-        $target_entry = $basename;
-    }
-
-    for ($i=0; $i<=$#work; $i++) {
-        next unless $work[$i] =~ m/^\* *([^:]+): *\((\w[^\)]*)\)/;
-        $tme= $1; $tfile= $2; $match= $&;
-        next unless $tfile eq $target_entry;
-        last if !length($menuentry);
-        $tme =~ y/A-Z/a-z/;
-        last if $tme eq $menuentry;
-    }
-    for ($j=$i; $j<=$#work+1; $j++) {
-        next if $work[$j] =~ m/^\s+\S/;
-        last unless $work[$j] =~ m/^\* *([^:]+): *\((\w[^\)]*)\)/;
-        $tme= $1; $tfile= $2;
-        last unless $tfile eq $target_entry;
-        next if !length($menuentry);
-        $tme =~ y/A-Z/a-z/;
-        last unless $tme eq $menuentry;
-    }
-
-    if ($i < $j) {
-        &dprint("i=$i \$work[\$i]='$work[$i]' j=$j \$work[\$j]='$work[$j]'");
-        printf(_g("%s: deleting entry \`%s ...'")."\n", $name, $match) unless $quiet;
-        $_= $work[$i-1];
-        unless (m/^\s/ || m/^\*/ || m/^$/ ||
-                $j > $#work || $work[$j] !~ m/^\s*$/) {
-            s/:?\s+$//;
-            if ($keepold) {
-                printf(_g("%s: empty section \`%s' not removed")."\n", $name, $_) unless $quiet;
-            } else {
-                $i--; $j++;
-                printf(_g("%s: deleting empty section \`%s'")."\n", $name, $_) unless $quiet;
-            }
-        }
-        @work= (@work[0..$i-1], @work[$j..$#work]);
-    } else {
-        unless ($quiet) {
-            if (length($menuentry)) {
-                printf _g("%s: no entry for file \`%s' and menu entry \`%s'")."\n", $name, $target_entry, $menuentry;
-            } else {
-                printf _g("%s: no entry for file \`%s'")."\n", $name, $target_entry;
-            }
-        }
-    }
-}
-$length = 0;
-
-$j = -1;
-for ($i=0; $i<=$#work; $i++) {
-	$_ = $work[$i];
-	chomp;
-	if ( m/^(\* *[^:]+: *\(\w[^\)]*\)[^.]*\.)[ \t]*(.*)/ ) {
-		$length = length($1) if ( length($1) > $length );
-		$work[++$j] = $_;
-	} elsif ( m/^[ \t]+(.*)/ ) {
-		$work[$j] = "$work[$j] $1";
-	} else {
-		$work[++$j] = $_;
-	}
-}
-@work = @work[0..$j];
-
-my $descalign=40;
-
-@newwork = ();
-foreach ( @work ) {
-	if ( m/^(\* *[^:]+: *\(\w[^\)]*\)[^.]*\.)[ \t]*(.*)/ ||
-		m/^([ \t]+)(.*)/ ) {
-		if (length $1 >= $descalign) {
-			push @newwork, $1;
-			$_=(" " x $descalign) . $2;
-		}
-		else {
-			$_ = $1 . (" " x ($descalign - length $1)) . $2;
-		}
-		push @newwork, split( "\n", wrap('', " " x $descalign, $_ ) );
-	} else {
-		push @newwork, $_;
-	}
-}
-
-if (!$nowrite) {
-    open(NEW,"> $dirfile.new") || &ulquit(sprintf(_g("unable to create %s: %s"),
-						     "$dirfile.new", $!));
-    print(NEW @head,join("\n",@newwork)) ||
-	&ulquit(sprintf(_g("unable to write %s: %s"), "$dirfile.new", $!));
-    close(NEW) || &ulquit(sprintf(_g("unable to close %s: %s"), "$dirfile.new", $!));
-
-    unlink("$dirfile.old");
-    link($dirfile, "$dirfile.old") ||
-	&ulquit(sprintf(_g("unable to backup old %s, giving up: %s"),
-			   $dirfile, $!));
-    rename("$dirfile.new", $dirfile) ||
-	&ulquit(sprintf(_g("unable to install new %s: %s"), $dirfile, $!));
-
-    unlink("$dirfile.lock") ||
-	&quit(sprintf(_g("unable to unlock %s: %s"), $dirfile, $!));
-    system ('cp', $dirfile, $backup) &&
-	warn sprintf(_g("%s: could not backup %s in %s: %s"), $name, $dirfile, $backup, $!)."\n";
-}
-
-sub quit
-{
-    die "$name: $@\n";
-}
-
-sub ulquit {
-    unlink("$dirfile.lock") ||
-	warn sprintf(_g("%s: warning - unable to unlock %s: %s"),
-		     $name, $dirfile, $!)."\n";
-    &quit($_[0]);
-}
-
-sub checkpipe {
-    return if !$pipeit || !$? || $?==0x8D00 || $?==0x0D;
-    &quit(sprintf(_g("unable to read %s: %d"), $filename, $?));
-}
-
-sub dprint {
-    printf(DEBUG _g("dbg: %s")."\n", $_[0]) if ($debug);
-}
-
-exit 0;
diff --git a/utils/.gitignore b/utils/.gitignore
index bf5714e..ee8689b 100644
--- a/utils/.gitignore
+++ b/utils/.gitignore
@@ -1 +1,2 @@
 start-stop-daemon
+install-info
diff --git a/utils/Makefile.am b/utils/Makefile.am
index cd1e4f1..2de2b0c 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -6,7 +6,6 @@ INCLUDES = \
 	-idirafter $(top_srcdir)/libcompat \
 	-I$(top_srcdir)/lib
 
-
 if WITH_START_STOP_DAEMON
   sbin_PROGRAMS = start-stop-daemon
 
@@ -16,3 +15,16 @@ if WITH_START_STOP_DAEMON
   start_stop_daemon_LDADD = ../libcompat/libcompat.a $(SSD_LIBS)
 endif
 
+EXTRA_DIST = install-info.c
+CLEANFILES = install-info install-info-stamp
+
+# Automake has its own install-info rule, gah
+all-local: install-info-stamp
+install-info-stamp: $(srcdir)/install-info.c
+	$(CC) $(CFLAGS) -o install-info $(srcdir)/install-info.c
+	touch $@
+
+install-exec-local: install-info-stamp
+	$(mkdir_p) $(DESTDIR)$(sbindir)
+	$(INSTALL_PROGRAM) install-info $(DESTDIR)$(sbindir)
+
diff --git a/utils/install-info.c b/utils/install-info.c
new file mode 100644
index 0000000..ee8758b
--- /dev/null
+++ b/utils/install-info.c
@@ -0,0 +1,34 @@
+
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+
+#define WARN "install-info: warning: "
+#define FAIL "install-info: failure: "
+
+int
+main(int argc, char **argv)
+{
+    if (strcmp(argv[0], "/usr/sbin/install-info") == 0) {
+	fprintf(stderr, WARN "/usr/sbin/install-info provided by "
+	                "dpkg is deprecated\n");
+	fprintf(stderr, WARN "its replacement lives in /usr/bin/\n");
+    }
+
+    if (access("/usr/bin/install-info", X_OK) == 0) {
+	execv("/usr/bin/install-info", argv);
+	return 1; /* exec failed */
+    } else {
+	if (errno == ENOENT) {
+	    fprintf(stderr, WARN "nothing done since /usr/bin/install-info "
+	                    "doesn't exist\n");
+	} else {
+	    fprintf(stderr, FAIL "can't execute /usr/bin/install-info: %s\n",
+	            strerror(errno));
+	    return 1;
+	}
+    }
+
+    return 0;
+}
-- 
1.6.2


Reply to: