Sfoglia il codice sorgente

dpkg (1.1.6); priority=MEDIUM

  * Check virtual dependencies when removing (ouch! - thanks SDE.)
  * Fixed bug in internal database validity management that could
    make dselect and dpkg dump core.  (Bug#2613.)
  * Fixed two coredumping bugs when using local diversions.  (Bug#2804.)
  * Fixed disappearance of overwritten packages.  (Bug#2696.)
  * install-info won't modify dir file before start of menu.
  * install-info will create Miscellaneous heading if no sections yet.

  * Only alphanums and +-. allowed in package names - enforced by
    dpkg-deb --build and documented in Guidelines.
  * dselect doesn't display packages unless they are installed, selected
    or available.
  * dselect doesn't show spurious section and priority headings.
  * dselect has a few extra keybindings (from Lee Olds).
  * --force message changed to `--force enabled' so that default is OK.

  * dpkg-name now includes architecture component in .deb filename,
    and translates - in package name to _.
  * .deb file has architecture component in filename.

  * Guidelines changed to say Pre-Depends is for experts only.
  * Guidelines say to provide a unidiff (-u) rather than an old context diff.
  * Guidelines say 755 root.root for shared libraries.

 -- Ian Jackson <ian@chiark.chu.cam.ac.uk>  Wed, 1 May 1996 00:47:22 +0100
Ian Jackson 30 anni fa
parent
commit
258ed6ae6f

+ 18 - 12
TODO

@@ -1,17 +1,9 @@
 Here are some currently-known inadequacies:
 Here are some currently-known inadequacies:
 
 
 urgent
 urgent
- * Pre-Depends installation ordering
-
-done
- * a.out version
- * uncomment ELF preinst modification
- * Replaces (auto-deselect for conflicts)
- * Replaces (don't overwrite otherwise)
- * compile with ELF GCC out of the box
- * dpkg --print-architecture
- * Architecture field check
- * symlink rename change
+ * Conflicts << installation ordering
+ * Version numbers in pre-depends stuff
+ * Search for all pre-depends things at once, bomb out if any not found
 
 
 bugs that need to be fixed quickly
 bugs that need to be fixed quickly
  * version numbers not starting digit early.
  * version numbers not starting digit early.
@@ -32,9 +24,11 @@ bugs that need to be fixed quickly
  * remove old docs from /usr/doc/dpkg.
  * remove old docs from /usr/doc/dpkg.
 
 
 other stuff unlikely to get done soon
 other stuff unlikely to get done soon
+ * md5sum component in new .deb files
+ * version number comparison option
+ * diversions list as control archive entry
  * single maintainer script, and new package getting there first
  * single maintainer script, and new package getting there first
  * dpkg -s show something for virtual packages
  * dpkg -s show something for virtual packages
- * dpkg --listfiles should do better for multi-package files  (pkg, pkg: ...)
  * settable defaults for update-rc.d
  * settable defaults for update-rc.d
  * local conffiles
  * local conffiles
  * hooks
  * hooks
@@ -55,3 +49,15 @@ other stuff unlikely to get done soon
  * `fake' or `null' packages
  * `fake' or `null' packages
  * --purge remove empty directories which used too contain conffiles
  * --purge remove empty directories which used too contain conffiles
  * conffiles handling options, including `replace removed files'
  * conffiles handling options, including `replace removed files'
+
+done
+ * Pre-Depends installation ordering
+ * a.out version
+ * uncomment ELF preinst modification
+ * Replaces (auto-deselect for conflicts)
+ * Replaces (don't overwrite otherwise)
+ * compile with ELF GCC out of the box
+ * dpkg --print-architecture
+ * Architecture field check
+ * symlink rename change
+ * dpkg --listfiles should do better for multi-package files  (pkg, pkg: ...)

+ 29 - 0
debian.Changelog

@@ -1,8 +1,37 @@
+dpkg (1.1.6); priority=MEDIUM
+
+  * Check virtual dependencies when removing (ouch! - thanks SDE.)
+  * Fixed bug in internal database validity management that could
+    make dselect and dpkg dump core.  (Bug#2613.)
+  * Fixed two coredumping bugs when using local diversions.  (Bug#2804.)
+  * Fixed disappearance of overwritten packages.  (Bug#2696.)
+  * install-info won't modify dir file before start of menu.
+  * install-info will create Miscellaneous heading if no sections yet.
+
+  * Only alphanums and +-. allowed in package names - enforced by
+    dpkg-deb --build and documented in Guidelines.
+  * dselect doesn't display packages unless they are installed, selected
+    or available.
+  * dselect doesn't show spurious section and priority headings.
+  * dselect has a few extra keybindings (from Lee Olds).
+  * --force message changed to `--force enabled' so that default is OK.
+
+  * dpkg-name now includes architecture component in .deb filename,
+    and translates - in package name to _.
+  * .deb file has architecture component in filename.
+
+  * Guidelines changed to say Pre-Depends is for experts only.
+  * Guidelines say to provide a unidiff (-u) rather than an old context diff.
+  * Guidelines say 755 root.root for shared libraries.
+
+ -- Ian Jackson <ian@chiark.chu.cam.ac.uk>  Wed, 1 May 1996 00:47:22 +0100
+
 dpkg (1.1.5); priority=MEDIUM (HIGH for diversions users)
 dpkg (1.1.5); priority=MEDIUM (HIGH for diversions users)
 
 
   * Fixed coredump when using diversions.  (Bug#2603.)
   * Fixed coredump when using diversions.  (Bug#2603.)
   * Fixed typo in dpkg-divert which could lose diversions.  (Bug#2662.)
   * Fixed typo in dpkg-divert which could lose diversions.  (Bug#2662.)
 
 
+  * --force-overwrite is the default.
   * diversions.text provides better examples.
   * diversions.text provides better examples.
 
 
  -- Ian Jackson <ian@chiark.chu.cam.ac.uk>  Wed, 10 Apr 1996 13:59:30 +0100
  -- Ian Jackson <ian@chiark.chu.cam.ac.uk>  Wed, 10 Apr 1996 13:59:30 +0100

+ 3 - 3
debian.rules

@@ -1,7 +1,7 @@
 #!/usr/bin/make -f
 #!/usr/bin/make -f
 
 
 package=dpkg
 package=dpkg
-version=1.1.5
+version=1.1.6
 
 
 archi=$(shell dpkg --print-architecture)
 archi=$(shell dpkg --print-architecture)
 DIR:=$(shell pwd)
 DIR:=$(shell pwd)
@@ -58,11 +58,11 @@ binary:
 	rm debian-tmp/var/lib/dpkg/{status,available}
 	rm debian-tmp/var/lib/dpkg/{status,available}
 	dpkg --build debian-tmp
 	dpkg --build debian-tmp
 	if file main/dpkg | grep -q ELF; then \
 	if file main/dpkg | grep -q ELF; then \
-		mv debian-tmp.deb ../dpkg-$(version)elf.deb ; \
+		mv debian-tmp.deb ../dpkg-$(version)elf.$(archi).deb ; \
 		mv ../dpkg-$(version).nondebbin.tar.gz \
 		mv ../dpkg-$(version).nondebbin.tar.gz \
 		   ../dpkg-$(version)elf.nondebbin.tar.gz ; \
 		   ../dpkg-$(version)elf.nondebbin.tar.gz ; \
 	else \
 	else \
-		mv debian-tmp.deb ../dpkg-$(version).deb ; \
+		mv debian-tmp.deb ../dpkg-$(version).$(archi).deb ; \
 	fi
 	fi
 
 
 define checkdir
 define checkdir

+ 16 - 8
doc/guidelines.info-1

@@ -218,8 +218,9 @@ the guidelines below.
      course, owned by the appropriate group.
      course, owned by the appropriate group.
 
 
    * Library files should generally be mode 644 and owned by
    * Library files should generally be mode 644 and owned by
-     `root.root'.  If the package requires different permissions or
-     ownerships to function correctly, they should be used instead.
+     `root.root'; shared libraries should be mode 755.  If the package
+     requires different permissions or ownerships to function
+     correctly, they should be used instead.
 
 
    * Manual pages should be mode 644 and owned by `root.root'.  The
    * Manual pages should be mode 644 and owned by `root.root'.  The
      `nroff' source must be installed.  You should *not* install a
      `nroff' source must be installed.  You should *not* install a
@@ -471,8 +472,8 @@ for the existence of a file in the source directory.
      `<package>-<original_version>' (again, see the section below on
      `<package>-<original_version>' (again, see the section below on
      version numbering).
      version numbering).
 
 
-   * Create the context diff against the original package using `diff
-     -cNr', and use `gzip -9' to compress it.  Context diffs should be
+   * Create the unified context diff against the original package using
+     `diff -uNr', and use `gzip -9' to compress it.  Diffs should be
      named in the form <package>-<version>.diff.gz--for example,
      named in the form <package>-<version>.diff.gz--for example,
      `fileutils-3.9-3.diff.gz'.
      `fileutils-3.9-3.diff.gz'.
 
 
@@ -628,9 +629,9 @@ installation tools.
 
 
    The value of `Package' should be the name of the package.  Package
    The value of `Package' should be the name of the package.  Package
 names must start with an alphanumeric, must be at least two characters,
 names must start with an alphanumeric, must be at least two characters,
-and may contain only alphanumerics and the characters - + . @ : = % _
-(that is, hyphen, plus, stop, at, colon, equals, percent and
-underscore).  They are not case sensitive.
+and may contain only alphanumerics and the characters - + . (that is,
+hyphen, plus, stop) (1).  They are sort of case sensitive - please try
+to get the case right first time.
 
 
    The `Maintainer' field should be in the form
    The `Maintainer' field should be in the form
 
 
@@ -694,7 +695,8 @@ reluctant to downgrade packages.
 
 
 `Pre-Depends'
 `Pre-Depends'
      Used by base packages to ensure that (for example) shared
      Used by base packages to ensure that (for example) shared
-     libraries are present befoore they are upgraded.
+     libraries are present before they are upgraded.  This feature is
+     for expert use only.
 
 
 `Source'
 `Source'
      Gives the name of the source package when several binary packages
      Gives the name of the source package when several binary packages
@@ -732,6 +734,12 @@ the reasons described in `dependency-ordering.txt', and the others
 because older versions of those packages do not have the appropriate
 because older versions of those packages do not have the appropriate
 `Provides' field.
 `Provides' field.
 
 
+   ---------- Footnotes ----------
+
+   (1)  The characters @ : = % _ (at, colon, equals, percent and
+underscore) used to be legal and are still accepted when found in a
+package file, but may not be used in new packages
+
 
 
 File: guidelines.info,  Node: conffiles,  Next: Installation and Removal Scripts,  Prev: control,  Up: Control Files
 File: guidelines.info,  Node: conffiles,  Next: Installation and Removal Scripts,  Prev: control,  Up: Control Files
 
 

+ 15 - 11
doc/guidelines.texi

@@ -234,8 +234,9 @@ owned by the appropriate group.
 
 
 @item
 @item
 Library files should generally be mode 644 and owned by
 Library files should generally be mode 644 and owned by
-@code{root.root}.  If the package requires different permissions
-or ownerships to function correctly, they should be used instead.
+@code{root.root}; shared libraries should be mode 755.  If the package
+requires different permissions or ownerships to function correctly, they
+should be used instead.
 
 
 @item
 @item
 Manual pages should be mode 644 and owned by @code{root.root}.  The
 Manual pages should be mode 644 and owned by @code{root.root}.  The
@@ -529,9 +530,9 @@ but the tarfile should unpack into a directory named
 below on version numbering).
 below on version numbering).
 
 
 @item
 @item
-Create the context diff against the original package using @file{diff
--cNr}, and use @file{gzip -9} to compress it.  Context diffs should be
-named in the form <@i{package}>-<@i{version}>.diff.gz---for example,
+Create the unified context diff against the original package using
+@file{diff -uNr}, and use @file{gzip -9} to compress it.  Diffs should
+be named in the form <@i{package}>-<@i{version}>.diff.gz---for example,
 @file{fileutils-3.9-3.diff.gz}.
 @file{fileutils-3.9-3.diff.gz}.
 @end itemize
 @end itemize
 
 
@@ -684,11 +685,14 @@ The version number in the format
    Each field has a particular format and meaning for the package
    Each field has a particular format and meaning for the package
 installation tools.
 installation tools.
 
 
-The value of @file{Package} should be the name of the package.
-Package names must start with an alphanumeric, must be at least two
-characters, and may contain only alphanumerics and the characters
-- + . @@ : = % _ (that is, hyphen, plus, stop, at, colon, equals,
-percent and underscore).  They are not case sensitive.
+The value of @file{Package} should be the name of the package.  Package
+names must start with an alphanumeric, must be at least two characters,
+and may contain only alphanumerics and the characters - + . (that is,
+hyphen, plus, stop) @footnote{The characters @@ : = % _ (at, colon,
+equals, percent and underscore) used to be legal and are still accepted
+when found in a package file, but may not be used in new packages}.
+They are sort of case sensitive - please try to get the case right first
+time.
 
 
    The @code{Maintainer} field should be in the form
    The @code{Maintainer} field should be in the form
 
 
@@ -752,7 +756,7 @@ used as a location for the package in the distribution.
 A boolean field used by the base packages.
 A boolean field used by the base packages.
 @item Pre-Depends
 @item Pre-Depends
 Used by base packages to ensure that (for example) shared libraries are
 Used by base packages to ensure that (for example) shared libraries are
-present befoore they are upgraded.
+present before they are upgraded.  This feature is for expert use only.
 @item Source
 @item Source
 Gives the name of the source package when several binary packages are
 Gives the name of the source package when several binary packages are
 generated from a single source tree.
 generated from a single source tree.

+ 4 - 0
dpkg-deb/build.c

@@ -93,6 +93,10 @@ void do_build(const char *const *argv) {
     parsedb(controlfile, pdb_recordavailable|pdb_rejectstatus,
     parsedb(controlfile, pdb_recordavailable|pdb_rejectstatus,
             &checkedinfo, stderr, &warns);
             &checkedinfo, stderr, &warns);
     assert(checkedinfo->available.valid);
     assert(checkedinfo->available.valid);
+    if (strspn(checkedinfo->name,
+               "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.")
+        != strlen(checkedinfo->name))
+      ohshit("package name has characters that aren't alphanums or `-+.'");
     if (checkedinfo->priority == pri_other) {
     if (checkedinfo->priority == pri_other) {
       fprintf(stderr, "warning, `%s' contains user-defined Priority value `%s'\n",
       fprintf(stderr, "warning, `%s' contains user-defined Priority value `%s'\n",
               controlfile, checkedinfo->otherpriority);
               controlfile, checkedinfo->otherpriority);

+ 2 - 2
dselect/helpmsgs.src

@@ -1,7 +1,7 @@
 @@@ listkeys Keystrokes
 @@@ listkeys Keystrokes
 
 
 Motion keys: Next/Previous, Top/End, Up/Down, Backwards/Forwards:
 Motion keys: Next/Previous, Top/End, Up/Down, Backwards/Forwards:
-  n, Down-arrow         p, Up-arrow             move highlight
+  n, Down-arrow, j      p, Up-arrow, k          move highlight
   N, Page-down, Space   P, Page-up, Backspace   scroll list by 1 page
   N, Page-down, Space   P, Page-up, Backspace   scroll list by 1 page
   ^n                    ^p                      scroll list by 1 line
   ^n                    ^p                      scroll list by 1 line
   t, Home               e, End                  jump to top/end of list
   t, Home               e, End                  jump to top/end of list
@@ -18,7 +18,7 @@ Package states - selection:                    Package states - hold flag:
 Quit, exit, overwrite (note capitals!):         ? request help (also Help, F1)
 Quit, exit, overwrite (note capitals!):         ? request help (also Help, F1)
  Return  Confirm and quit (check dependencies)  i toggle/cycle info displays      
  Return  Confirm and quit (check dependencies)  i toggle/cycle info displays      
    Q     Confirm and quit (override dep.s)      o cycle through sort orders       
    Q     Confirm and quit (override dep.s)      o cycle through sort orders       
-   X     eXit, abandoning any changes made      v toggle verbose status display   
+ X, Esc  eXit, abandoning any changes made      v toggle verbose status display   
    R     Revert to state before this list      ^l redraw display                  
    R     Revert to state before this list      ^l redraw display                  
    U     set all to sUggested state             / search (hit Return to cancel)
    U     set all to sUggested state             / search (hit Return to cancel)
    D     set all to Directly selected state     \\ repeat last search             
    D     set all to Directly selected state     \\ repeat last search             

+ 5 - 0
dselect/methkeys.cc

@@ -62,14 +62,18 @@ const keybindings::interpretation methodlist_kinterps[] = {
 #define C(x) ((x)-'a'+1)
 #define C(x) ((x)-'a'+1)
 
 
 const keybindings::orgbinding methodlist_korgbindings[]= {
 const keybindings::orgbinding methodlist_korgbindings[]= {
+  { 'j',            "down"           }, // vi style
   { 'n',            "down"           },
   { 'n',            "down"           },
   { KEY_DOWN,       "down"           },
   { KEY_DOWN,       "down"           },
+  { 'k',            "up"             }, // vi style
   { 'p',            "up"             },
   { 'p',            "up"             },
   { KEY_UP,         "up"             },
   { KEY_UP,         "up"             },
   
   
+  { C('f'),         "scrollon"       }, // vi style
   { 'N',            "scrollon"       },
   { 'N',            "scrollon"       },
   { KEY_NPAGE,      "scrollon"       },
   { KEY_NPAGE,      "scrollon"       },
   { ' ',            "scrollon"       },
   { ' ',            "scrollon"       },
+  { C('b'),         "scrollback"     }, // vi style
   { 'P',            "scrollback"     },
   { 'P',            "scrollback"     },
   { KEY_PPAGE,      "scrollback"     },
   { KEY_PPAGE,      "scrollback"     },
   { KEY_BACKSPACE,  "scrollback"     },
   { KEY_BACKSPACE,  "scrollback"     },
@@ -105,6 +109,7 @@ const keybindings::orgbinding methodlist_korgbindings[]= {
 
 
   { KEY_ENTER,      "select-and-quit"  },
   { KEY_ENTER,      "select-and-quit"  },
   { '\r',           "select-and-quit"  },
   { '\r',           "select-and-quit"  },
+  { 27,             "abort"            }, // esc
   { 'x',            "abort"            },
   { 'x',            "abort"            },
   { 'X',            "abort"            },
   { 'X',            "abort"            },
   
   

+ 5 - 1
dselect/pkgkeys.cc

@@ -75,8 +75,10 @@ const keybindings::interpretation packagelist_kinterps[] = {
 #define C(x) ((x)-'a'+1)
 #define C(x) ((x)-'a'+1)
 
 
 const keybindings::orgbinding packagelist_korgbindings[]= {
 const keybindings::orgbinding packagelist_korgbindings[]= {
+  { 'j',            "down"           }, // vi style
   { 'n',            "down"           },
   { 'n',            "down"           },
   { KEY_DOWN,       "down"           },
   { KEY_DOWN,       "down"           },
+  { 'k',            "up"             }, // vi style
   { 'p',            "up"             },
   { 'p',            "up"             },
   { KEY_UP,         "up"             },
   { KEY_UP,         "up"             },
   
   
@@ -86,7 +88,7 @@ const keybindings::orgbinding packagelist_korgbindings[]= {
   { 'P',            "scrollback"     },
   { 'P',            "scrollback"     },
   { KEY_PPAGE,      "scrollback"     },
   { KEY_PPAGE,      "scrollback"     },
   { KEY_BACKSPACE,  "scrollback"     },
   { KEY_BACKSPACE,  "scrollback"     },
-  { 0177,/*DEL*/    "scrollback"     },
+  { 0177,           "scrollback"     }, // ASCII DEL
   { C('h'),         "scrollback"     },
   { C('h'),         "scrollback"     },
   { C('n'),         "scrollon1"      },
   { C('n'),         "scrollon1"      },
   { C('p'),         "scrollback1"    },
   { C('p'),         "scrollback1"    },
@@ -130,6 +132,8 @@ const keybindings::orgbinding packagelist_korgbindings[]= {
   { KEY_ENTER,      "quitcheck"      },
   { KEY_ENTER,      "quitcheck"      },
   { '\r',           "quitcheck"      },
   { '\r',           "quitcheck"      },
   { 'Q',            "quitnocheck"    },
   { 'Q',            "quitnocheck"    },
+  { 27,             "abortnocheck"   }, // esc
+  { 'x',            "abortnocheck"   },
   { 'X',            "abortnocheck"   },
   { 'X',            "abortnocheck"   },
   { 'R',            "revert"         },
   { 'R',            "revert"         },
   { 'U',            "revertsuggest"  },
   { 'U',            "revertsuggest"  },

+ 3 - 5
dselect/pkglist.cc

@@ -43,7 +43,7 @@ int packagelist::compareentries(struct perpackagestate *a,
     !asection || !bsection ?
     !asection || !bsection ?
       (!bsection) - (!asection) :
       (!bsection) - (!asection) :
     !*asection || !*bsection ?
     !*asection || !*bsection ?
-      (!asection) - (!bsection) :
+      (!*asection) - (!*bsection) :
     strcasecmp(asection,bsection);
     strcasecmp(asection,bsection);
   int c_priority=
   int c_priority=
     a->pkg->priority - b->pkg->priority;
     a->pkg->priority - b->pkg->priority;
@@ -95,6 +95,7 @@ void packagelist::addheading(pkginfo::pkgpriority priority,
     nallocated += nallocated+50;
     nallocated += nallocated+50;
     struct perpackagestate **newtable= new struct perpackagestate*[nallocated];
     struct perpackagestate **newtable= new struct perpackagestate*[nallocated];
     memcpy(newtable,table,nallocated*sizeof(struct perpackagestate*));
     memcpy(newtable,table,nallocated*sizeof(struct perpackagestate*));
+    delete[] table;
     table= newtable;
     table= newtable;
   }
   }
   
   
@@ -233,10 +234,7 @@ packagelist::packagelist(keybindings *kb) : baselist(kb) {
        ) {
        ) {
     struct perpackagestate *state= &datatable[nitems];
     struct perpackagestate *state= &datatable[nitems];
     state->pkg= pkg;
     state->pkg= pkg;
-    if (!informativeperfile(&pkg->available) &&
-        pkg->status == pkginfo::stat_notinstalled &&
-        pkg->priority == pkginfo::pri_unknown &&
-        !(pkg->section && *pkg->section) &&
+    if (pkg->status == pkginfo::stat_notinstalled &&
         !pkg->files &&
         !pkg->files &&
         pkg->want != pkginfo::want_install) {
         pkg->want != pkginfo::want_install) {
       pkg->clientdata= 0; continue;
       pkg->clientdata= 0; continue;

+ 1 - 2
include/dpkg-db.h

@@ -150,8 +150,7 @@ extern char *statusfile, *availablefile; /* initialised by modstatdb_init */
 struct pkginfo *findpackage(const char *name);
 struct pkginfo *findpackage(const char *name);
 void blankpackage(struct pkginfo *pp);
 void blankpackage(struct pkginfo *pp);
 void blankpackageperfile(struct pkginfoperfile *pifp);
 void blankpackageperfile(struct pkginfoperfile *pifp);
-int informative(struct pkginfo *info);
-int informativeperfile(struct pkginfoperfile *info);
+int informative(struct pkginfo *pkg, struct pkginfoperfile *info);
 int countpackages(void);
 int countpackages(void);
 void resetpackages(void);
 void resetpackages(void);
 
 

+ 14 - 11
lib/database.c

@@ -132,8 +132,20 @@ void blankpackageperfile(struct pkginfoperfile *pifp) {
 
 
 static int nes(const char *s) { return s && *s; }
 static int nes(const char *s) { return s && *s; }
 
 
-int informativeperfile(struct pkginfoperfile *info) {
-  /* Used by dselect as an aid to decide whether to display things. */
+int informative(struct pkginfo *pkg, struct pkginfoperfile *info) {
+  /* Used by dselect and dpkg query options as an aid to decide
+   * whether to display things, and by dump to decide whether to write them
+   * out.
+   */
+  if (info == &pkg->installed ?
+      ((pkg->want != want_unknown && pkg->want != want_purge) ||
+       pkg->eflag != eflagv_ok ||
+       pkg->status != stat_notinstalled ||
+       pkg->files)
+      :
+      (nes(pkg->section) ||
+       pkg->priority != pri_unknown))
+    return 1;
   if (!info->valid) return 0;
   if (!info->valid) return 0;
   if (info->depends ||
   if (info->depends ||
       nes(info->description) ||
       nes(info->description) ||
@@ -147,15 +159,6 @@ int informativeperfile(struct pkginfoperfile *info) {
   return 0;
   return 0;
 }
 }
 
 
-int informative(struct pkginfo *pkg) {
-  return ((pkg->want != want_unknown && pkg->want != want_purge) ||
-          pkg->eflag != eflagv_ok ||
-          pkg->status != stat_notinstalled ||
-          nes(pkg->section) ||
-          pkg->files ||
-          pkg->priority != pri_unknown);
-}
-
 struct pkginfo *findpackage(const char *name) {
 struct pkginfo *findpackage(const char *name) {
   struct pkginfo **pointerp, *newpkg;
   struct pkginfo **pointerp, *newpkg;
 
 

+ 6 - 6
lib/dump.c

@@ -238,6 +238,7 @@ void writedb(const char *filename, int available, int mustsync) {
   
   
   struct pkgiterator *it;
   struct pkgiterator *it;
   struct pkginfo *pigp;
   struct pkginfo *pigp;
+  struct pkginfoperfile *pifp;
   char *oldfn, *newfn;
   char *oldfn, *newfn;
   const char *which;
   const char *which;
   FILE *file;
   FILE *file;
@@ -258,12 +259,11 @@ void writedb(const char *filename, int available, int mustsync) {
 
 
   it= iterpkgstart();
   it= iterpkgstart();
   while ((pigp= iterpkgnext(it)) != 0) {
   while ((pigp= iterpkgnext(it)) != 0) {
-    if (!(informative(pigp) ||
-          informativeperfile(&pigp->available) ||
-          informativeperfile(&pigp->installed)))
-      /* Don't dump records which have no useful content. */
-      continue;
-    varbufrecord(&vb, pigp, available ? &pigp->available : &pigp->installed);
+    pifp= available ? &pigp->available : &pigp->installed;
+    /* Don't dump records which have no useful content. */
+    if (!informative(pigp,pifp)) continue;
+    if (!pifp->valid) blankpackageperfile(pifp);
+    varbufrecord(&vb,pigp,pifp);
     varbufaddc(&vb,'\n'); varbufaddc(&vb,0);
     varbufaddc(&vb,'\n'); varbufaddc(&vb,0);
     if (!fputs(vb.buf,file))
     if (!fputs(vb.buf,file))
       ohshite("failed to write %s record about `%.50s' to `%.250s'",
       ohshite("failed to write %s record about `%.50s' to `%.250s'",

+ 66 - 1
main/archives.c

@@ -41,6 +41,70 @@
 #include "main.h"
 #include "main.h"
 #include "archives.h"
 #include "archives.h"
 
 
+int filesavespackage(struct fileinlist *file, struct pkginfo *pkgtobesaved,
+                     struct pkginfo *pkgbeinginstalled) {
+  struct pkginfo *divpkg, *thirdpkg;
+  struct filepackages *packageslump;
+  int i;
+  
+  debug(dbg_eachfiledetail,"filesavespackage file `%s' package %s",
+        file->namenode->name,pkgtobesaved->name);
+  /* A package can only be saved by a file or directory which is part
+   * only of itself - it must be neither part of the new package being
+   * installed nor part of any 3rd package (this is important so that
+   * shared directories don't stop packages from disappearing).
+   */
+  /* Is the file in the package being installed ?  If so then it can't save.
+   */
+  if (file->namenode->flags & fnnf_new_inarchive) {
+    debug(dbg_eachfiledetail,"filesavespackage ... in new archive -- no save");
+    return 0;
+  }
+  /* If the file is a contended one and it's overridden by either
+   * the package we're considering disappearing or the package
+   * we're installing then they're not actually the same file, so
+   * we can't disappear the package - it is saved by this file.
+   */
+  if (file->namenode->divert && file->namenode->divert->useinstead) {
+    divpkg= file->namenode->divert->pkg;
+    if (divpkg == pkgtobesaved || divpkg == pkgbeinginstalled) {
+      debug(dbg_eachfiledetail,"filesavespackage ... diverted -- save!");
+      return 1;
+    }
+  }
+  /* Look for a 3rd package which can take over the file (in case
+   * it's a directory which is shared by many packages.
+   */
+  for (packageslump= file->namenode->packages;
+       packageslump;
+       packageslump= packageslump->more) {
+    for (i=0; i < PERFILEPACKAGESLUMP && packageslump->pkgs[i]; i++) {
+      thirdpkg= packageslump->pkgs[i];
+      debug(dbg_eachfiledetail, "filesavespackage ... also in %s",
+            thirdpkg->name);
+      /* Is this not the package being installed or the one being
+       * checked for disappearance ?
+       */
+      if (thirdpkg == pkgbeinginstalled || thirdpkg == pkgtobesaved) continue;
+      /* If !fileslistvalid then we've already disappeared this one, so
+       * we shouldn't try to make it take over this shared directory.
+       */
+      debug(dbg_eachfiledetail,"filesavespackage ...  is 3rd package");
+
+      if (!thirdpkg->clientdata->fileslistvalid) {
+        debug(dbg_eachfiledetail,
+              "process_archive ...  already disappeared !");
+        continue;
+      }
+      /* We've found a package that can take this file. */
+      debug(dbg_eachfiledetail, "filesavespackage ...  taken -- no save");
+      return 0;
+    }
+  }
+  debug(dbg_eachfiledetail, "filesavespackage ... not taken -- save !");
+  return 1;
+}
+
 void cu_pathname(int argc, void **argv) {
 void cu_pathname(int argc, void **argv) {
   ensure_pathname_nonexisting((char*)(argv[0]));
   ensure_pathname_nonexisting((char*)(argv[0]));
 } 
 } 
@@ -269,7 +333,8 @@ int tarobject(struct TarInfo *ti) {
            * check for both being the diverting package, obviously).
            * check for both being the diverting package, obviously).
            */
            */
           divpkg= nifd->namenode->divert->pkg;
           divpkg= nifd->namenode->divert->pkg;
-          debug(dbg_eachfile, "tarobject ... diverted, divpkg=%s\n",divpkg->name);
+          debug(dbg_eachfile, "tarobject ... diverted, divpkg=%s",
+                divpkg ? divpkg->name : "<none>");
           if (otherpkg == divpkg || tc->pkg == divpkg) continue;
           if (otherpkg == divpkg || tc->pkg == divpkg) continue;
         }
         }
         /* Nope ?  Hmm, file conflict, perhaps.  Check Replaces. */
         /* Nope ?  Hmm, file conflict, perhaps.  Check Replaces. */

+ 3 - 0
main/archives.h

@@ -57,6 +57,9 @@ int unlinkorrmdir(const char *filename);
 int tarobject(struct TarInfo *ti);
 int tarobject(struct TarInfo *ti);
 int tarfileread(void *ud, char *buf, int len);
 int tarfileread(void *ud, char *buf, int len);
 
 
+int filesavespackage(struct fileinlist*, struct pkginfo*,
+                     struct pkginfo *pkgbeinginstalled);
+
 void check_conflict(struct dependency *dep, struct pkginfo *pkg,
 void check_conflict(struct dependency *dep, struct pkginfo *pkg,
                     const char *pfilename, struct pkginfo **conflictorp);
                     const char *pfilename, struct pkginfo **conflictorp);
 
 

+ 1 - 1
main/enquiry.c

@@ -385,7 +385,7 @@ void enqperpackage(const char *const *argv) {
           !(pkg->section && *pkg->section) &&
           !(pkg->section && *pkg->section) &&
           !pkg->files &&
           !pkg->files &&
           pkg->want == want_unknown &&
           pkg->want == want_unknown &&
-          !informativeperfile(&pkg->installed)) {
+          !informative(pkg,&pkg->installed)) {
         printf("Package `%s' is not installed and no info is available.\n",pkg->name);
         printf("Package `%s' is not installed and no info is available.\n",pkg->name);
         failures++;
         failures++;
       } else {
       } else {

+ 1 - 1
main/errors.c

@@ -101,7 +101,7 @@ void forcibleerr(int forceflag, const char *fmt, ...) {
   va_list al;
   va_list al;
   va_start(al,fmt);
   va_start(al,fmt);
   if (forceflag) {
   if (forceflag) {
-    fputs(DPKG " - warning, overriding problem because you used --force:\n ",stderr);
+    fputs(DPKG " - warning, overriding problem because --force enabled:\n ",stderr);
     vfprintf(stderr,fmt,al);
     vfprintf(stderr,fmt,al);
     fputc('\n',stderr);
     fputc('\n',stderr);
   } else {
   } else {

+ 15 - 2
main/packages.c

@@ -246,6 +246,7 @@ void process_queue(void) {
 static int deppossi_ok_found(struct pkginfo *possdependee,
 static int deppossi_ok_found(struct pkginfo *possdependee,
                              struct pkginfo *requiredby,
                              struct pkginfo *requiredby,
                              struct pkginfo *removing,
                              struct pkginfo *removing,
+                             struct pkginfo *providing,
                              int *matched,
                              int *matched,
                              struct deppossi *checkversion,
                              struct deppossi *checkversion,
                              int *interestingwarnings,
                              int *interestingwarnings,
@@ -260,6 +261,10 @@ static int deppossi_ok_found(struct pkginfo *possdependee,
   if (possdependee == removing) {
   if (possdependee == removing) {
     varbufaddstr(oemsgs,"  Package ");
     varbufaddstr(oemsgs,"  Package ");
     varbufaddstr(oemsgs,possdependee->name);
     varbufaddstr(oemsgs,possdependee->name);
+    if (providing) {
+      varbufaddstr(oemsgs," which provides ");
+      varbufaddstr(oemsgs,providing->name);
+    }
     varbufaddstr(oemsgs," is to be removed.\n");
     varbufaddstr(oemsgs," is to be removed.\n");
     *matched= 1;
     *matched= 1;
     if (fc_depends) thisf= (dependtry >= 4) ? 2 : 1;
     if (fc_depends) thisf= (dependtry >= 4) ? 2 : 1;
@@ -300,6 +305,10 @@ static int deppossi_ok_found(struct pkginfo *possdependee,
     } else {
     } else {
       varbufaddstr(oemsgs,"  Package ");
       varbufaddstr(oemsgs,"  Package ");
       varbufaddstr(oemsgs,possdependee->name);
       varbufaddstr(oemsgs,possdependee->name);
+      if (providing) {
+        varbufaddstr(oemsgs," which provides ");
+        varbufaddstr(oemsgs,providing->name);
+      }
       varbufaddstr(oemsgs," is not configured yet.\n");
       varbufaddstr(oemsgs," is not configured yet.\n");
       if (fc_depends) thisf= (dependtry >= 4) ? 2 : 1;
       if (fc_depends) thisf= (dependtry >= 4) ? 2 : 1;
       debug(dbg_depcondetail,"      not configured/able - returning %d",thisf);
       debug(dbg_depcondetail,"      not configured/able - returning %d",thisf);
@@ -309,6 +318,10 @@ static int deppossi_ok_found(struct pkginfo *possdependee,
   default:
   default:
     varbufaddstr(oemsgs,"  Package ");
     varbufaddstr(oemsgs,"  Package ");
     varbufaddstr(oemsgs,possdependee->name);
     varbufaddstr(oemsgs,possdependee->name);
+    if (providing) {
+      varbufaddstr(oemsgs," which provides ");
+      varbufaddstr(oemsgs,providing->name);
+    }
     varbufaddstr(oemsgs," is not installed.\n");
     varbufaddstr(oemsgs," is not installed.\n");
     if (fc_depends) thisf= (dependtry >= 4) ? 2 : 1;
     if (fc_depends) thisf= (dependtry >= 4) ? 2 : 1;
     debug(dbg_depcondetail,"      not installed - returning %d",thisf);
     debug(dbg_depcondetail,"      not installed - returning %d",thisf);
@@ -341,7 +354,7 @@ int dependencies_ok(struct pkginfo *pkg, struct pkginfo *removing,
         debug(dbg_depcondetail,"      break cycle so ok and found");
         debug(dbg_depcondetail,"      break cycle so ok and found");
         found= 3; break;
         found= 3; break;
       }
       }
-      thisf= deppossi_ok_found(possi->ed,pkg,removing,
+      thisf= deppossi_ok_found(possi->ed,pkg,removing,0,
                                &matched,possi,&interestingwarnings,&oemsgs);
                                &matched,possi,&interestingwarnings,&oemsgs);
       if (thisf > found) found= thisf;
       if (thisf > found) found= thisf;
       if (found != 3 && possi->verrel == dvr_none) {
       if (found != 3 && possi->verrel == dvr_none) {
@@ -351,7 +364,7 @@ int dependencies_ok(struct pkginfo *pkg, struct pkginfo *removing,
                provider= provider->nextrev) {
                provider= provider->nextrev) {
             if (provider->up->type != dep_provides) continue;
             if (provider->up->type != dep_provides) continue;
             debug(dbg_depcondetail,"     checking provider %s",provider->up->up->name);
             debug(dbg_depcondetail,"     checking provider %s",provider->up->up->name);
-            thisf= deppossi_ok_found(provider->up->up,pkg,removing,
+            thisf= deppossi_ok_found(provider->up->up,pkg,removing,possi->ed,
                                      &matched,0,&interestingwarnings,&oemsgs);
                                      &matched,0,&interestingwarnings,&oemsgs);
             if (thisf > found) found= thisf;
             if (thisf > found) found= thisf;
           }
           }

+ 4 - 17
main/processarc.c

@@ -793,22 +793,9 @@ void process_archive(const char *filename) {
       continue;
       continue;
     }
     }
     for (cfile= otherpkg->clientdata->files;
     for (cfile= otherpkg->clientdata->files;
-         cfile;
-         cfile= cfile->next) {
-      if (!(cfile->namenode->flags & fnnf_new_inarchive)) break;
-      if (cfile->namenode->divert && cfile->namenode->divert->useinstead) {
-        /* If the file is a contended one and it's overridden by either the package
-         * we're considering disappearing or the package we're installing then
-         * they're not actually the same file, so we can't disappear the package.
-         */
-        divpkg= cfile->namenode->divert->pkg;
-        if (divpkg == pkg || divpkg == otherpkg) break;
-      }
-    }
-    if (cfile) {
-      debug(dbg_stupidlyverbose, "process_archive saved by `%s'",cfile->namenode->name);
-      continue;
-    }
+         cfile && !filesavespackage(cfile,otherpkg,pkg);
+         cfile= cfile->next);
+    if (cfile) continue;
 
 
     /* So dependency things will give right answers ... */
     /* So dependency things will give right answers ... */
     otherpkg->clientdata->istobe= itb_remove; 
     otherpkg->clientdata->istobe= itb_remove; 
@@ -924,7 +911,7 @@ void process_archive(const char *filename) {
       } else {
       } else {
         debug(dbg_eachfile,
         debug(dbg_eachfile,
               "process_archive looking for overwriting `%s' (overridden by %s)",
               "process_archive looking for overwriting `%s' (overridden by %s)",
-              cfile->namenode->name, divpkg->name);
+              cfile->namenode->name, divpkg ? divpkg->name : "<local>");
       }        
       }        
     } else {
     } else {
       divpkg= 0;
       divpkg= 0;

+ 33 - 18
main/remove.c

@@ -40,11 +40,35 @@
 #include "filesdb.h"
 #include "filesdb.h"
 #include "main.h"
 #include "main.h"
 
 
+static void checkforremoval(struct pkginfo *pkgtoremove,
+                            struct pkginfo *pkgdepcheck, /* may be virtual pkg */
+                            int *rokp, struct varbuf *raemsgs) {
+  struct deppossi *possi;
+  struct pkginfo *depender;
+  int before, ok;
+  
+  for (possi= pkgdepcheck->installed.depended; possi; possi= possi->nextrev) {
+    if (possi->up->type != dep_depends && possi->up->type != dep_predepends) continue;
+    depender= possi->up->up;
+    debug(dbg_depcon,"checking depending package `%s'",depender->name);
+    if (depender->status != stat_installed) continue;
+    if (ignore_depends(depender)) {
+      debug(dbg_depcon,"ignoring depending package `%s'\n",depender->name);
+      continue;
+    }
+    if (dependtry > 1) { if (findbreakcycle(pkgdepcheck,0)) sincenothing= 0; }
+    before= raemsgs->used;
+    ok= dependencies_ok(depender,pkgtoremove,raemsgs);
+    if (ok == 0 && depender->clientdata->istobe == itb_remove) ok= 1;
+    if (ok == 1) raemsgs->used= before; /* Don't burble about reasons for deferral */
+    if (ok < *rokp) *rokp= ok;
+  }
+}
+
 void deferred_remove(struct pkginfo *pkg) {
 void deferred_remove(struct pkginfo *pkg) {
   struct varbuf raemsgs;
   struct varbuf raemsgs;
-  int rok, before, ok;
-  struct deppossi *dep;
-  struct pkginfo *depender;
+  int rok;
+  struct dependency *dep;
 
 
   debug(dbg_general,"deferred_remove package %s",pkg->name);
   debug(dbg_general,"deferred_remove package %s",pkg->name);
   
   
@@ -77,22 +101,13 @@ void deferred_remove(struct pkginfo *pkg) {
   debug(dbg_general,"checking dependencies for remove `%s'",pkg->name);
   debug(dbg_general,"checking dependencies for remove `%s'",pkg->name);
   varbufinit(&raemsgs);
   varbufinit(&raemsgs);
   rok= 2;
   rok= 2;
-  for (dep= pkg->installed.depended; dep; dep= dep->nextrev) {
-    if (dep->up->type != dep_depends && dep->up->type != dep_predepends) continue;
-    depender= dep->up->up;
-    debug(dbg_depcon,"checking depending package `%s'",depender->name);
-    if (depender->status != stat_installed) continue;
-    if (ignore_depends(depender)) {
-      debug(dbg_depcon,"ignoring depending package `%s'\n",depender->name);
-      continue;
-    }
-    if (dependtry > 1) { if (findbreakcycle(pkg,0)) sincenothing= 0; }
-    before= raemsgs.used;
-    ok= dependencies_ok(depender,pkg,&raemsgs);
-    if (ok == 0 && depender->clientdata->istobe == itb_remove) ok= 1;
-    if (ok == 1) raemsgs.used= before; /* Don't burble about reasons for deferral */
-    if (ok < rok) rok= ok;
+  checkforremoval(pkg,pkg,&rok,&raemsgs);
+  for (dep= pkg->installed.depends; dep; dep= dep->next) {
+    if (dep->type != dep_provides) continue;
+    debug(dbg_depcon,"checking virtual package `%s'",dep->list->ed->name);
+    checkforremoval(pkg,dep->list->ed,&rok,&raemsgs);
   }
   }
+
   if (rok == 1) {
   if (rok == 1) {
     varbuffree(&raemsgs);
     varbuffree(&raemsgs);
     pkg->clientdata->istobe= itb_remove;
     pkg->clientdata->istobe= itb_remove;

+ 8 - 7
scripts/dpkg-name.1

@@ -3,11 +3,11 @@
 .\"
 .\"
 .\" This is free software; see the GNU General Public Licence version 2
 .\" This is free software; see the GNU General Public Licence version 2
 .\" or later for copying conditions.  There is NO warranty.
 .\" or later for copying conditions.  There is NO warranty.
-.TH dpkg-name 1 "January 1996" "Debian Project" "Debian GNU/Linux"
+.TH dpkg-name 1 "April 1996" "Debian Project" "Debian Linux"
 .SH NAME
 .SH NAME
 dpkg\-name \- rename Debian packages to full package names
 dpkg\-name \- rename Debian packages to full package names
 .SH SYNOPSIS
 .SH SYNOPSIS
-.B dpkg\-name [\-h|\-\-help] [\-V|\-\-version] [\-L|\-\-license] [--] [files]
+.B dpkg\-name [\-h|\-\-help] [\-v|\-\-version] [\-l|\-\-license] [--] [files]
 .SH DESCRIPTION
 .SH DESCRIPTION
 .PP
 .PP
 This manual page documents the
 This manual page documents the
@@ -15,12 +15,13 @@ This manual page documents the
 sh script which provides an easy way to rename
 sh script which provides an easy way to rename
 .B Debian
 .B Debian
 packages into their full package names. A full package name consists
 packages into their full package names. A full package name consists
-of <package>-<version>[-<revision>].deb as specified in the control
-file of the package.
+of <package>-<version>.<architecture>.deb as specified in the control
+file of the package (<version> is
+<mainstream-version>-<debian-revision>).
 .SH EXAMPLES
 .SH EXAMPLES
 .TP
 .TP
 .B dpkg-name toedeledokie
 .B dpkg-name toedeledokie
-The file `toedeledokie' will be renamed to emacs-19.29-4.deb or
+The file `toedeledokie' will be renamed to emacs-19.29-4.i386.deb or
 something similar (depending on whatever information is in the control
 something similar (depending on whatever information is in the control
 part of `toedeledokie').
 part of `toedeledokie').
 .TP
 .TP
@@ -40,9 +41,9 @@ Print copyright information and (a reference to GNU) license
 information and exit successfully.
 information and exit successfully.
 .SH BUGS?
 .SH BUGS?
 Successfully tested on
 Successfully tested on
-.B Debian GNU/Linux 
+.B Debian Linux 
 systems only. Some packages don't follow the name structure
 systems only. Some packages don't follow the name structure
-<package>-<version>[-<revision>].deb. Packages renamed by dpkg-name
+<package>-<version>.<architecture>.deb. Packages renamed by dpkg-name
 will follow this structure. Generally this will have no impact on how
 will follow this structure. Generally this will have no impact on how
 packages are installed by dselect/dpkg.
 packages are installed by dselect/dpkg.
 .SH SEE ALSO
 .SH SEE ALSO

+ 11 - 6
scripts/dpkg-name.sh

@@ -3,12 +3,12 @@
 set -e
 set -e
 
 
 prog="`basename \"${0}\"`"
 prog="`basename \"${0}\"`"
-version="0.11"; # This line modified by Makefile
+version="1.1.5"; # This line modified by Makefile
 purpose="rename Debian packages to full package names"
 purpose="rename Debian packages to full package names"
 
 
 license () {
 license () {
 echo "# ${prog} ${version} -- ${purpose}
 echo "# ${prog} ${version} -- ${purpose}
-# Copyright (C) 1995,1996 Erick Branderhorst <branderhorst@heel.fgg.eur.nl>.
+# Copyright (C) 1995,1996 Erick Branderhorst <branderh@debian.org>.
 
 
 # This is free software; you can redistribute it and/or modify it
 # This is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by the
 # under the terms of the GNU General Public License as published by the
@@ -32,7 +32,7 @@ show_version () {
 usage () {
 usage () {
 	echo "Usage: ${prog} file[s]
 	echo "Usage: ${prog} file[s]
   ${purpose}
   ${purpose}
-  file.deb changes to <package>-<version>[-<revision>].deb
+  file.deb changes to <package>-<version>.<architecture>.deb
   -h|--help|-v|--version|-l|--license  Show help/version/license"
   -h|--help|-v|--version|-l|--license  Show help/version/license"
 }
 }
 
 
@@ -51,8 +51,14 @@ rename () {
 			then
 			then
 				p=$p-$r;
 				p=$p-$r;
 			fi
 			fi
-			p=`echo $p|sed 's/ //g'`
-			p=`dirname "$1"`"/"$p.deb	
+			a=`dpkg-deb -f -- "$1" architecture`;
+			if [ -z "$a" ];
+			then
+				a=`dpkg --print-architecture`;
+				stderr "assuming "$a" architecture for \`"$1"'";
+			fi				
+			p=`echo \"$p\"|tr -ds -- '- ' _`
+			p=`dirname "$1"`"/"$p.$a.deb
 			if [ $p -ef "$1" ];									# same device and inode numbers
 			if [ $p -ef "$1" ];									# same device and inode numbers
 			then
 			then
 				stderr "skipping \`"$1"'";
 				stderr "skipping \`"$1"'";
@@ -91,4 +97,3 @@ exit 0;
 # Local variables:
 # Local variables:
 # tab-width: 2
 # tab-width: 2
 # End:
 # End:
-

+ 6 - 0
scripts/install-info.8

@@ -118,6 +118,12 @@ replaced in situ with the new entry.
 
 
 If a section is specified when removing an entry the section is
 If a section is specified when removing an entry the section is
 ignored and a warning is issued.
 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
 .TP
 .BI \-\-infodir= infodir
 .BI \-\-infodir= infodir
 Specifies that the
 Specifies that the

+ 16 - 4
scripts/install-info.pl

@@ -216,6 +216,12 @@ eof(OLD) || &ulquit("$name: read $infodir/dir: $!\n");
 close(OLD) || &ulquit("$name: close $infodir/dir after read: $!\n");
 close(OLD) || &ulquit("$name: close $infodir/dir after read: $!\n");
 while ($work[$#work] !~ m/\S/) { $#work--; }
 while ($work[$#work] !~ m/\S/) { $#work--; }
 
 
+do {
+    last if !@work;
+    $_= shift(@work);
+    push(@head,$_);
+} until (m/^\*\s*Menu:/i);
+
 if (!$remove) {
 if (!$remove) {
 
 
     for ($i=0; $i<=$#work; $i++) {
     for ($i=0; $i<=$#work; $i++) {
@@ -249,9 +255,15 @@ if (!$remove) {
         if ($mss < 0) {
         if ($mss < 0) {
             print "$name: creating new section \`$sectiontitle'\n" unless $quiet;
             print "$name: creating new section \`$sectiontitle'\n" unless $quiet;
             for ($i= $#work; $i>=0 && $work[$i] =~ m/\S/; $i--) { }
             for ($i= $#work; $i>=0 && $work[$i] =~ m/\S/; $i--) { }
-            $i >= 0 || &ulquit("$name: nowhere to create new section - giving up\n");
-            @work= (@work[0..$i], "$sectiontitle\n", "\n", @work[$i+1..$#work]);
-            $mss= $i+1;
+            if ($i <= 0) { # We ran off the top, make this section and Misc.
+                print "$name: no sections yet, creating Miscellaneous section too.\n"
+                    unless $quiet;
+                @work= ("\n", "$sectiontitle\n", "\n", "Miscellaneous:", @work);
+                $mss= 1;
+            } else {
+                @work= (@work[0..$i], "$sectiontitle\n", "\n", @work[$i+1..$#work]);
+                $mss= $i+1;
+            }
         }
         }
         while ($mss <= $#work) {
         while ($mss <= $#work) {
             $work[$mss] =~ m/\S/ || last;
             $work[$mss] =~ m/\S/ || last;
@@ -316,7 +328,7 @@ END
 
 
 if (!$nowrite) {
 if (!$nowrite) {
     open(NEW,"> $infodir/dir.new") || &ulquit("$name: create $infodir/dir.new: $!\n");
     open(NEW,"> $infodir/dir.new") || &ulquit("$name: create $infodir/dir.new: $!\n");
-    print(NEW @work) || &ulquit("$name: write $infodir/dir.new: $!\n");
+    print(NEW @head,@work) || &ulquit("$name: write $infodir/dir.new: $!\n");
     close(NEW) || &ulquit("$name: close $infodir/dir.new: $!\n");
     close(NEW) || &ulquit("$name: close $infodir/dir.new: $!\n");
 
 
     unlink("$infodir/dir.old");
     unlink("$infodir/dir.old");

+ 1 - 1
version.h

@@ -1 +1 @@
-#define DPKG_VERSION "1.1.5" /* This line modified by Makefile */
+#define DPKG_VERSION "1.1.6" /* This line modified by Makefile */