Просмотр исходного кода

dpkg (1.2.0); priority=MEDIUM

  * dselect can sort packages by available and installed states, and
    display their version numbers.  (Use O, o and V.)
  * Hold is properly integrated as a real `wanted state', rather than
    a separate flag.
  * Epochs in version numbers implemented, using the syntax
    <epoch>:<version>-<revision>.  (Epoch not usually displayed.)
  * dselect disk method is architecture-independent (uses dpkg's
    installation architecture, and looks in the right part of the tree).

  * dselect disk method doesn't try to satisfy the predependencies of
    packages which are on hold.
  * Fixed conflict-related assertion failure.  (Bug#2784.)
  * conffiles do not cause file conflicts if the conflicting package
    is in the `configuration only' state.  (Bug#2720.)
  * Fixed messages where available version number was reported as installed
    version in conflict and dependency messages.  (Bug#2654, Bug#2974.)

  * New format .deb files are default even for a.out compiles (but
    a.out version of dpkg is in old format).
  * Characters @:= (at colon equals) in package names now strictly
    forbidden everywhere (_ is still allowed in existing packages).
  * New dpkg --print-installation-architecture option prints installation
    architecture (compiled in), rather than build architecture (determined
    from gcc -print-libgcc-file-name).

  * Version messages show whether compiled a.out or ELF (i386 only).
  * Fixed missing space in version syntax error messages.
  * Manpage dpkg.8 installed with warning about inaccuracy.

  * Guidelines don't say to stop and restart daemons in runlevels 2345;
    instead they say to start in 2345 and stop in 016.
  * Guidelines and version messages say just Debian Linux.
  * Guidelines typo fix `"stop2' => `"stop"'.  (Bug#2867.)

  * doc/Makefile.in clean properly deletes various guidelines.info* files.

 -- Ian Jackson <ian@chiark.chu.cam.ac.uk>  Thu, 16 May 1996 00:01:21 +0100
Ian Jackson лет назад: 30
Родитель
Сommit
d4d3484ac8
62 измененных файлов с 1939 добавлено и 4205 удалено
  1. 2 0
      TODO
  2. 3 0
      acconfig.h
  3. 6 0
      config.h.in
  4. 65 114
      configure
  5. 30 32
      configure.in
  6. 40 0
      debian.Changelog
  7. 23 0
      debian.buildscript
  8. 17 0
      debian.changestemplate
  9. 1 1
      debian.control
  10. 1 1
      debian.controlaout
  11. 36 0
      debian.mkchanges
  12. 8 7
      debian.rules
  13. 1 1
      doc/Makefile.in
  14. 0 1047
      doc/guidelines.info-1
  15. 0 744
      doc/guidelines.info-2
  16. 20 23
      doc/guidelines.texi
  17. 0 1056
      doc/guidelines.texi.beforeeric
  18. 0 33
      doc/guidelines.texi.rej
  19. 5 5
      dpkg-deb/build.c
  20. 4 4
      dpkg-deb/main.c
  21. 14 14
      dselect/helpmsgs.src
  22. 6 4
      dselect/main.cc
  23. 2 1
      dselect/methparse.cc
  24. 61 25
      dselect/pkgcmds.cc
  25. 12 12
      dselect/pkgdepcon.cc
  26. 96 11
      dselect/pkgdisplay.cc
  27. 106 101
      dselect/pkgkeys.cc
  28. 162 15
      dselect/pkglist.cc
  29. 40 5
      dselect/pkglist.h
  30. 4 8
      dselect/pkgsublist.cc
  31. 70 20
      dselect/pkgtop.cc
  32. 34 9
      include/dpkg-db.h
  33. 4 1
      include/dpkg.h
  34. 44 0
      lib/compat.c
  35. 11 4
      lib/database.c
  36. 8 19
      lib/dump.c
  37. 47 23
      lib/fields.c
  38. 29 49
      lib/parse.c
  39. 4 2
      lib/parsedump.h
  40. 77 6
      lib/parsehelp.c
  41. BIN
      lib/sta00630
  42. BIN
      lib/sta11978
  43. 16 0
      lib/varbuf.c
  44. 12 4
      lib/vercmp.c
  45. 77 65
      main/archives.c
  46. 14 14
      main/cleanup.c
  47. 2 2
      main/configure.c
  48. 22 50
      main/depcon.c
  49. 606 13
      main/dpkg.8
  50. 20 0
      main/dpkg.8-null
  51. 0 588
      main/dpkg.8-vuori
  52. 11 7
      main/enquiry.c
  53. 1 1
      main/errors.c
  54. 4 4
      main/help.c
  55. 10 5
      main/main.c
  56. 4 4
      main/main.h
  57. 3 5
      main/packages.c
  58. 25 29
      main/processarc.c
  59. 3 3
      main/remove.c
  60. 8 6
      methods/disk.setup
  61. 7 7
      split/main.c
  62. 1 1
      version.h

+ 2 - 0
TODO

@@ -24,6 +24,8 @@ bugs that need to be fixed quickly
  * remove old docs from /usr/doc/dpkg.
 
 other stuff unlikely to get done soon
+ * provide way for package to declare ownership of files for dpkg -S
+   and -L without having dpkg act on this
  * md5sum component in new .deb files
  * version number comparison option
  * diversions list as control archive entry

+ 3 - 0
acconfig.h

@@ -29,3 +29,6 @@
 
 /* Set this to 1 to build new archives by default. */
 #define BUILDOLDPKGFORMAT 0
+
+/* Set this string to append something to the version number. */
+#define ARCHBINFMT ""

+ 6 - 0
config.h.in

@@ -55,6 +55,9 @@
 /* Set this to 1 to build new archives by default. */
 #define BUILDOLDPKGFORMAT 0
 
+/* Set this string to append something to the version number. */
+#define ARCHBINFMT ""
+
 /* The number of bytes in a unsigned int.  */
 #undef SIZEOF_UNSIGNED_INT
 
@@ -79,6 +82,9 @@
 /* Define if you have the unsetenv function.  */
 #undef HAVE_UNSETENV
 
+/* Define if you have the vsnprintf function.  */
+#undef HAVE_VSNPRINTF
+
 /* Define if you have the <sys/cdefs.h> header file.  */
 #undef HAVE_SYS_CDEFS_H
 

+ 65 - 114
configure

@@ -18,8 +18,6 @@ ac_help="$ac_help
   --with-newdeb           make dpkg-deb default to new archives"
 ac_help="$ac_help
   --with-olddeb           make dpkg-deb default to old archives"
-ac_help="$ac_help
-  --with-newdeb           make dpkg-deb default to new archives"
 
 # Initialize some variables set by options.
 # The variables have the same names as the options, with
@@ -563,6 +561,7 @@ else
 fi
 
 
+dpkg_archset=''
 # Check whether --with-arch or --without-arch was given.
 withval="$with_arch"
 if test -n "$withval"; then
@@ -570,10 +569,7 @@ if test -n "$withval"; then
  if test "x$with_arch" = x; then
   { echo "configure: error: --with-arch requires an architecture name" 1>&2; exit 1; }
  fi
- cat >> confdefs.h <<EOF
-#define ARCHITECTURE "${with_arch}"
-EOF
-
+ dpkg_archset="${with_arch}"
 
 else
   
@@ -614,107 +610,63 @@ fi
 
  if test "x$dpkg_cv_arch" != x; then
   echo "$ac_t"""$dpkg_cv_arch$dpkg_archwhy"" 1>&6
-  cat >> confdefs.h <<EOF
-#define ARCHITECTURE "${dpkg_cv_arch}"
-EOF
-
+  dpkg_archset="${dpkg_cv_arch}"
  else
   echo "$ac_t"""failed$dpkg_archwhy"" 1>&6
  fi
 
 fi
 
- 
-# Check whether --with-newdeb or --without-newdeb was given.
-withval="$with_newdeb"
-if test -n "$withval"; then
-  
- cat >> confdefs.h <<\EOF
-#define BUILDOLDPKGFORMAT 0
+if test "x$dpkg_archset" != x
+then
+ cat >> confdefs.h <<EOF
+#define ARCHITECTURE "${dpkg_cv_arch}"
 EOF
 
+fi
 
-else
-  
- # Check whether --with-olddeb or --without-olddeb was given.
-withval="$with_olddeb"
-if test -n "$withval"; then
-  
-  cat >> confdefs.h <<\EOF
-#define BUILDOLDPKGFORMAT 1
+if test "x${dpkg_archset}" = xi386; then
+ echo $ac_n "checking for i386 system/binary format""... $ac_c" 1>&6
+ dpkg_libgcc="`$CC --print-libgcc-file-name 2>/dev/null`"
+ case "$dpkg_libgcc" in
+  *-linux*)
+   if ar p "$dpkg_libgcc" __main.o 2>/dev/null | file - 2>/dev/null | grep ELF >/dev/null; then
+    echo "$ac_t""Linux ELF" 1>&6
+    dpkg_cc_binfmt=elf
+   else
+    echo "$ac_t""Linux a.out" 1>&6
+    dpkg_cc_binfmt=a.out
+   fi
+   cat >> confdefs.h <<EOF
+#define ARCHBINFMT " $dpkg_cc_binfmt"
 EOF
 
-
-else
-  
-  case "$CC" in
-  /*)
-   pathccompiler="$CC"
-   ;;
-  *)
-   # Extract the first word of ""$CC"", so it can be a program name with args.
-set dummy "$CC"; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_path_pathccompiler'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  case "$pathccompiler" in
-  /*)
-  ac_cv_path_pathccompiler="$pathccompiler" # Let the user override the test with a path.
   ;;
   *)
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
-  for ac_dir in $PATH; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_path_pathccompiler="$ac_dir/$ac_word"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
+   echo "$ac_t""non-Linux" 1>&6
   ;;
-esac
-fi
-pathccompiler="$ac_cv_path_pathccompiler"
-if test -n "$pathccompiler"; then
-  echo "$ac_t""$pathccompiler" 1>&6
-else
-  echo "$ac_t""no" 1>&6
+ esac
 fi
 
-   ;;
-  esac
-  echo $ac_n "checking .deb format to build by default""... $ac_c" 1>&6
-  if file "$pathccompiler" 2>/dev/null | grep ELF >/dev/null 2>&1; then
-   echo "$ac_t""new (C compiler looks like ELF)" 1>&6
-   cat >> confdefs.h <<\EOF
+# Check whether --with-newdeb or --without-newdeb was given.
+withval="$with_newdeb"
+if test -n "$withval"; then
+  cat >> confdefs.h <<\EOF
 #define BUILDOLDPKGFORMAT 0
 EOF
 
-  else
-   echo "$ac_t""old (C compiler not ELF)" 1>&6
-   cat >> confdefs.h <<\EOF
-#define BUILDOLDPKGFORMAT 1
-EOF
-
-  fi
-
-fi
-
 fi
 
-
-# Check whether --with-newdeb or --without-newdeb was given.
-withval="$with_newdeb"
+# Check whether --with-olddeb or --without-olddeb was given.
+withval="$with_olddeb"
 if test -n "$withval"; then
   cat >> confdefs.h <<\EOF
-#define BUILDOLDPKGFORMAT 0
+#define BUILDOLDPKGFORMAT 1
 EOF
 
 fi
 
 
-
 echo $ac_n "checking for /usr/bin/perl""... $ac_c" 1>&6
 if test -f /usr/bin/perl
 then
@@ -770,7 +722,7 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 774 "configure"
+#line 726 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -784,7 +736,7 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 788 "configure"
+#line 740 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -818,7 +770,7 @@ else
   ac_cv_c_cross=yes
 else
 cat > conftest.$ac_ext <<EOF
-#line 822 "configure"
+#line 774 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
@@ -839,7 +791,7 @@ if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 843 "configure"
+#line 795 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -861,7 +813,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 865 "configure"
+#line 817 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -879,7 +831,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 883 "configure"
+#line 835 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -900,7 +852,7 @@ if test "$cross_compiling" = yes; then
   ac_cv_header_stdc=no
 else
 cat > conftest.$ac_ext <<EOF
-#line 904 "configure"
+#line 856 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1033,7 +985,7 @@ if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1037 "configure"
+#line 989 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1064,7 +1016,7 @@ if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1068 "configure"
+#line 1020 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1095,7 +1047,7 @@ if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1099 "configure"
+#line 1051 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1126,7 +1078,7 @@ if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1130 "configure"
+#line 1082 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char vprintf(); below.  */
@@ -1174,7 +1126,7 @@ if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1178 "configure"
+#line 1130 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char _doprnt(); below.  */
@@ -1223,7 +1175,7 @@ if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1227 "configure"
+#line 1179 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1298,7 +1250,7 @@ else
   ac_cv_c_bigendian=unknown
 # See if sys/param.h defines the BYTE_ORDER macro.
 cat > conftest.$ac_ext <<EOF
-#line 1302 "configure"
+#line 1254 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -1314,7 +1266,7 @@ if eval $ac_compile; then
   rm -rf conftest*
   # It does; now see whether it defined to BIG_ENDIAN or not.
 cat > conftest.$ac_ext <<EOF
-#line 1318 "configure"
+#line 1270 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -1343,7 +1295,7 @@ if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 1347 "configure"
+#line 1299 "configure"
 #include "confdefs.h"
 main () {
   /* Are we little or big endian?  From Harbison&Steele.  */
@@ -1382,7 +1334,7 @@ else
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 1386 "configure"
+#line 1338 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -1416,7 +1368,7 @@ else
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 1420 "configure"
+#line 1372 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -1442,14 +1394,14 @@ cat >> confdefs.h <<EOF
 EOF
 
 
-for ac_func in unsetenv alphasort scandir strerror strsignal strtoul
+for ac_func in unsetenv alphasort scandir strerror strsignal strtoul vsnprintf
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1453 "configure"
+#line 1405 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1501,7 +1453,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1505 "configure"
+#line 1457 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
@@ -1535,7 +1487,7 @@ if eval "test \"`echo '$''{'ac_cv_func_sysinfo'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1539 "configure"
+#line 1491 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char sysinfo(); below.  */
@@ -1577,7 +1529,7 @@ else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking __NR_sysinfo""... $ac_c" 1>&6
   cat > conftest.$ac_ext <<EOF
-#line 1581 "configure"
+#line 1533 "configure"
 #include "confdefs.h"
 
 #include <linux/sys.h>
@@ -1622,7 +1574,7 @@ fi
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 1626 "configure"
+#line 1578 "configure"
 #include "confdefs.h"
 #include <string.h>
 int main() { return 0; }
@@ -1659,7 +1611,7 @@ fi
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 1663 "configure"
+#line 1615 "configure"
 #include "confdefs.h"
 
 #include <sys/types.h>
@@ -1702,7 +1654,7 @@ EOF
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 1706 "configure"
+#line 1658 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1742,7 +1694,7 @@ EOF
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 1746 "configure"
+#line 1698 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1776,7 +1728,7 @@ EOF
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 1780 "configure"
+#line 1732 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1815,7 +1767,7 @@ EOF
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 1819 "configure"
+#line 1771 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1854,7 +1806,7 @@ EOF
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 1858 "configure"
+#line 1810 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1908,7 +1860,7 @@ else
    oldcflags="${CFLAGS-}"
    CFLAGS="${CFLAGS-} ${CWARNS} -Wall -Wno-implicit -Werror"
    cat > conftest.$ac_ext <<EOF
-#line 1912 "configure"
+#line 1864 "configure"
 #include "confdefs.h"
 
 #include <string.h>
@@ -1955,7 +1907,7 @@ else
    oldcflags="${CFLAGS-}"
    CFLAGS="${CFLAGS-} ${CWARNS} -Wwrite-strings -Werror"
    cat > conftest.$ac_ext <<EOF
-#line 1959 "configure"
+#line 1911 "configure"
 #include "confdefs.h"
 
 #include <string.h>
@@ -2002,7 +1954,7 @@ else
    oldcflags="${CFLAGS-}"
    CFLAGS="${CFLAGS-} ${CWARNS} -Wpointer-arith -Werror"
    cat > conftest.$ac_ext <<EOF
-#line 2006 "configure"
+#line 1958 "configure"
 #include "confdefs.h"
 
 #include <string.h>
@@ -2049,7 +2001,7 @@ else
    oldcflags="${CFLAGS-}"
    CFLAGS="${CFLAGS-} ${CWARNS} -Wimplicit -Wnested-externs -Werror"
    cat > conftest.$ac_ext <<EOF
-#line 2053 "configure"
+#line 2005 "configure"
 #include "confdefs.h"
 
 #include <string.h>
@@ -2197,7 +2149,6 @@ s%@prefix@%$prefix%g
 s%@program_transform_name@%$program_transform_name%g
 s%@CC@%$CC%g
 s%@CXX@%$CXX%g
-s%@pathccompiler@%$pathccompiler%g
 s%@perlpath@%$perlpath%g
 s%@CPP@%$CPP%g
 s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g

+ 30 - 32
configure.in

@@ -8,13 +8,14 @@ AC_PREFIX_DEFAULT(/usr)
 AC_PROG_CC
 AC_PROG_CXX
 
+dpkg_archset=''
 AC_ARG_WITH(arch,
 [  --with-arch=value       set/override (Debian) architecture value],
 [
  if test "x$with_arch" = x; then
   AC_MSG_ERROR(--with-arch requires an architecture name)
  fi
- AC_DEFINE_UNQUOTED(ARCHITECTURE, "${with_arch}")
+ dpkg_archset="${with_arch}"
 ],[
  AC_MSG_CHECKING(system architecture)
  dpkg_archwhy=''
@@ -52,45 +53,42 @@ changequote([, ])dnl
  ])
  if test "x$dpkg_cv_arch" != x; then
   AC_MSG_RESULT("$dpkg_cv_arch$dpkg_archwhy")
-  AC_DEFINE_UNQUOTED(ARCHITECTURE, "${dpkg_cv_arch}")
+  dpkg_archset="${dpkg_cv_arch}"
  else
   AC_MSG_RESULT("failed$dpkg_archwhy")
  fi
 ])
- 
-AC_ARG_WITH(newdeb,
-[  --with-newdeb           make dpkg-deb default to new archives],
-[
- AC_DEFINE(BUILDOLDPKGFORMAT, 0)
-],[
- AC_ARG_WITH(olddeb,
-[  --with-olddeb           make dpkg-deb default to old archives],
-[
-  AC_DEFINE(BUILDOLDPKGFORMAT, 1)
-],
-[
-  case "$CC" in
-  /*)
-   pathccompiler="$CC"
-   ;;
+if test "x$dpkg_archset" != x
+then
+ AC_DEFINE_UNQUOTED(ARCHITECTURE, "${dpkg_cv_arch}")
+fi
+
+if test "x${dpkg_archset}" = xi386; then
+ AC_MSG_CHECKING(for i386 system/binary format)
+ dpkg_libgcc="`$CC --print-libgcc-file-name 2>/dev/null`"
+ case "$dpkg_libgcc" in
+  *-linux*)
+   if ar p "$dpkg_libgcc" __main.o 2>/dev/null | file - 2>/dev/null | grep ELF >/dev/null; then
+    AC_MSG_RESULT(Linux ELF)
+    dpkg_cc_binfmt=elf
+   else
+    AC_MSG_RESULT(Linux a.out)
+    dpkg_cc_binfmt=a.out
+   fi
+   AC_DEFINE_UNQUOTED(ARCHBINFMT, " $dpkg_cc_binfmt")
+  ;;
   *)
-   AC_PATH_PROG(pathccompiler,"$CC")
-   ;;
-  esac
-  AC_MSG_CHECKING(.deb format to build by default)
-  if file "$pathccompiler" 2>/dev/null | grep ELF >/dev/null 2>&1; then
-   AC_MSG_RESULT([new (C compiler looks like ELF)])
-   AC_DEFINE(BUILDOLDPKGFORMAT, 0)
-  else
-   AC_MSG_RESULT([old (C compiler not ELF)])
-   AC_DEFINE(BUILDOLDPKGFORMAT, 1)
-  fi
-])])
+   AC_MSG_RESULT(non-Linux)
+  ;;
+ esac
+fi
 
 AC_ARG_WITH(newdeb,
 [  --with-newdeb           make dpkg-deb default to new archives],
 [AC_DEFINE(BUILDOLDPKGFORMAT, 0)])
-
+AC_ARG_WITH(olddeb,
+[  --with-olddeb           make dpkg-deb default to old archives],
+[AC_DEFINE(BUILDOLDPKGFORMAT, 1)])
 
 AC_MSG_CHECKING(for /usr/bin/perl)
 if test -f /usr/bin/perl
@@ -116,7 +114,7 @@ AC_C_CONST
 AC_C_BIGENDIAN
 AC_CHECK_SIZEOF(unsigned long)
 AC_CHECK_SIZEOF(unsigned int)
-AC_CHECK_FUNCS(unsetenv alphasort scandir strerror strsignal strtoul)
+AC_CHECK_FUNCS(unsetenv alphasort scandir strerror strsignal strtoul vsnprintf)
 AC_CHECK_HEADERS(sys/cdefs.h)
 
 AC_CHECK_FUNC(sysinfo,

+ 40 - 0
debian.Changelog

@@ -1,3 +1,43 @@
+dpkg (1.2.0); priority=MEDIUM
+
+  * dselect can sort packages by available and installed states, and
+    display their version numbers.  (Use O, o and V.)
+  * Hold is properly integrated as a real `wanted state', rather than
+    a separate flag.
+  * Epochs in version numbers implemented, using the syntax
+    <epoch>:<version>-<revision>.  (Epoch not usually displayed.)
+  * dselect disk method is architecture-independent (uses dpkg's
+    installation architecture, and looks in the right part of the tree).
+
+  * dselect disk method doesn't try to satisfy the predependencies of
+    packages which are on hold.
+  * Fixed conflict-related assertion failure.  (Bug#2784.)
+  * conffiles do not cause file conflicts if the conflicting package
+    is in the `configuration only' state.  (Bug#2720.)
+  * Fixed messages where available version number was reported as installed
+    version in conflict and dependency messages.  (Bug#2654, Bug#2974.)
+
+  * New format .deb files are default even for a.out compiles (but
+    a.out version of dpkg is in old format).
+  * Characters @:= (at colon equals) in package names now strictly
+    forbidden everywhere (_ is still allowed in existing packages).
+  * New dpkg --print-installation-architecture option prints installation
+    architecture (compiled in), rather than build architecture (determined
+    from gcc -print-libgcc-file-name).
+
+  * Version messages show whether compiled a.out or ELF (i386 only).
+  * Fixed missing space in version syntax error messages.
+  * Manpage dpkg.8 installed with warning about inaccuracy.
+
+  * Guidelines don't say to stop and restart daemons in runlevels 2345;
+    instead they say to start in 2345 and stop in 016.
+  * Guidelines and version messages say just Debian Linux.
+  * Guidelines typo fix `"stop2' => `"stop"'.  (Bug#2867.)
+
+  * doc/Makefile.in clean properly deletes various guidelines.info* files.
+
+ -- Ian Jackson <ian@chiark.chu.cam.ac.uk>  Thu, 16 May 1996 00:01:21 +0100
+
 dpkg (1.1.6); priority=MEDIUM
 
   * Check virtual dependencies when removing (ouch! - thanks SDE.)

+ 23 - 0
debian.buildscript

@@ -0,0 +1,23 @@
+#!/bin/sh
+set -e -x
+really ./debian.rules clean
+./debian.rules diff source
+
+./debian.rules build
+really ./debian.rules binary
+
+curd="`pwd`"
+newd="`basename \"$curd\"`"elf
+rm -rf ../"$newd"
+cp -dpR . ../"$newd"
+
+PATH=/usr/i486-linuxaout/bin:$PATH
+export PATH
+
+really ./debian.rules clean
+./debian.rules build
+really ./debian.rules binary
+
+version=`sed -n 's/^version=//p' debian.rules`
+perl debian.mkchanges "$version" <debian.changestemplate \
+ | pgp-auto -fast >dpkg-$version.`dpkg --print-architecture`.changes

+ 17 - 0
debian.changestemplate

@@ -0,0 +1,17 @@
+Date: =d
+Format: 1.5
+Distribution: unstable
+Source: dpkg
+Binary: dpkg
+Architecture: source =a
+Version: =v
+Maintainer: Ian Jackson <ian@chiark.chu.cam.ac.uk>
+Description:
+ dpkg: Package maintenance system for Debian Linux
+Changes:=c
+Files:
+ =f:dpkg-=v.tar.gz base required
+ =f:dpkg-=velf.=a.deb base required
+ =f:dpkg-=v.=a.deb byhand -
+ =f:dpkg-=velf.=a.nondebbin.tar.gz byhand -
+ =f:dpkg-=v.=a.nondebbin.tar.gz byhand -

+ 1 - 1
debian.control

@@ -6,7 +6,7 @@ Pre-Depends: libc5=, ncurses3.0
 Conflicts: dpkgname
 Replaces: dpkgname
 Maintainer: Ian Jackson <ian@chiark.chu.cam.ac.uk>
-Description: Package maintenance system for Debian GNU/Linux
+Description: Package maintenance system for Debian Linux
  This package contains the programs which handle the installation and
  removal of packages on your system.
  .

+ 1 - 1
debian.controlaout

@@ -6,7 +6,7 @@ Conflicts: dpkgname
 Replaces: dpkgname
 Pre-Depends: libc4 | libc
 Maintainer: Ian Jackson <ian@chiark.chu.cam.ac.uk>
-Description: Package maintenance system for Debian GNU/Linux
+Description: Package maintenance system for Debian Linux
  This package contains the programs which handle the installation and
  removal of packages on your system.
  .

+ 36 - 0
debian.mkchanges

@@ -0,0 +1,36 @@
+#!/usr/bin/perl
+# Usage:
+#  perl debian.mkchanges <version> <debian.changestemplate >thing.changes
+
+$x=time; sub z { $_[1]+$_[2]*60; }; @l=localtime($x); $od=1440;
+$d=&z(@l)-&z(gmtime($x)); $d+=$od; $d%=$od; $s=$d>$od/2?($d=$od-$d,'-'):'+';
+$date=sprintf("%s, %d %s %d %02d:%02d:%02d %s%02d%02d",
+ (Sun,Mon,Tue,Wed,Thu,Fri,Sat)[$l[6]], $l[3],
+ (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec)[$l[4]], $l[5]+1900,
+ $l[2],$l[1],$l[0], $s,$d/60,$d%60);
+
+($version)=@ARGV;
+chop($arch=`dpkg --print-architecture`);
+
+open(Z,"debian.Changelog");
+while(<Z>) { $changes.=$_; last if m/^ --/; }
+close(Z); $changes =~ s/^/ /g; $changes =~ s/^/\n/; $changes =~ s/\n$//;
+
+chdir("..");
+
+while (<STDIN>) {
+    s/=a/$arch/g;
+    s/=v/$version/g;
+    if (m/^ =f:(\S+) (\S+) (\S+)$/) {
+        ($file,$sec,$pri)=($1,$2,$3);
+        $!=0; chop($md5sum=`md5sum <$file`); $? && die "$file: $? $!";
+        $!=0; $size=`ls -l $file`; $? && die "$file: $? $!";
+        $size =~ m/^\S+\s+\d+\s+\S+\s+\S+\s+(\d+)\s/ || die "$file: `$size'";
+        $size= $1;
+        $_= " $md5sum $size $sec $pri $file\n";
+    } else {
+        s/=c/$changes/ || s/=d/$date/g;
+    }
+    print || die $!;
+}
+close(STDOUT) || die $!;

+ 8 - 7
debian.rules

@@ -1,7 +1,7 @@
 #!/usr/bin/make -f
 
 package=dpkg
-version=1.1.6
+version=1.2.0
 
 archi=$(shell dpkg --print-architecture)
 DIR:=$(shell pwd)
@@ -52,16 +52,17 @@ binary:
 	chown -R root.root debian-tmp
 	chmod -R g-ws debian-tmp
 	cd debian-tmp && \
-	tar cf ../../$(package)-$(version).nondebbin.tar usr var && \
-	gzip -9vf ../../$(package)-$(version).nondebbin.tar
+	tar cf ../../$(package)-$(version).$(archi).nondebbin.tar usr var && \
+	gzip -9vf ../../$(package)-$(version).$(archi).nondebbin.tar
 	mv debian-tmp/usr/bin/dpkg-deb{,.dist}
 	rm debian-tmp/var/lib/dpkg/{status,available}
-	dpkg --build debian-tmp
-	if file main/dpkg | grep -q ELF; then \
+	set -e; if file main/dpkg | grep -q ELF; then \
+		dpkg-deb --build --new debian-tmp ; \
 		mv debian-tmp.deb ../dpkg-$(version)elf.$(archi).deb ; \
-		mv ../dpkg-$(version).nondebbin.tar.gz \
-		   ../dpkg-$(version)elf.nondebbin.tar.gz ; \
+		mv ../dpkg-$(version).$(archi).nondebbin.tar.gz \
+		   ../dpkg-$(version)elf.$(archi).nondebbin.tar.gz ; \
 	else \
+		dpkg-deb --build --old debian-tmp ; \
 		mv debian-tmp.deb ../dpkg-$(version).$(archi).deb ; \
 	fi
 

+ 1 - 1
doc/Makefile.in

@@ -66,7 +66,7 @@ database-structure.monops: database-structure.ps
 clean:
 		rm -f database-structure.ps database-structure.monops ps
 		rm -f *.{aux,cp,dvi,fn,ky,log,pg,toc,tp,vr}
-		rm -f guidelines.info
+		rm -f guidelines.info*
 
 distclean:
 		rm -f Makefile *.orig *~ *.~* ./#*#

Разница между файлами не показана из-за своего большого размера
+ 0 - 1047
doc/guidelines.info-1


+ 0 - 744
doc/guidelines.info-2

@@ -1,744 +0,0 @@
-This is Info file guidelines.info, produced by Makeinfo-1.63 from the
-input file ./guidelines.texi.
-
-START-INFO-DIR-ENTRY
-* Guidelines: (guidelines).       How to make Debian packages.
-END-INFO-DIR-ENTRY
-
-
-File: guidelines.info,  Node: configuration files - /etc/skel vs /usr/doc/examples,  Next: How to write the Description control file field,  Prev: Appendix,  Up: Appendix
-
-configuration files - /etc/skel vs /usr/doc/examples
-====================================================
-
-   There seems to be a certain amount of confusion about `/etc/skel'
-and `/usr/doc/examples'. The most important thing to remember is the
-following:
-
-   Files in `/etc/skel' will *automatically* be copied into *new* user
-accounts by `adduser'.  They should not be referenced there by any
-program. Files in `/usr/doc/examples' should not be installed
-automatically.
-
-   Therefore, if the program in question need a dotfile to exist in
-advance in `$HOME' to work *sensibly* that dotfile should be installed
-in `/etc/skel' (and listed in conffiles; *note conffiles::.).
-
-   However, programs that require dotfiles in order to operate sensibly
-(dotfiles that they do not create themselves automatically, that is) are
-a bad thing, and that programs should be configured by the Debian
-default installation as close to normal as possible.
-
-   Therefore, if a program in a Debian package needs to be configured in
-some way in order to operate sensibly that configuration should be done
-in a site-wide global configuration file elsewhere in `/etc' (and that
-file should be listed in conffiles).  Only if the program doesn't
-support a site-wide default configuration should a default per-user file
-be placed in `/etc/skel' (and listed in conffiles; *note conffiles::.).
-
-   The idea is as follows:
-
-   The sysadmin should ideally not have to do any configuration other
-than that done (semi-)automatically by the postinst script.
-
-   However, if they wish to change their configuration themselves
-(because the configuration they want is beyond the scope of the
-autoconfiguration, or because the autoconfiguration doesn't exist yet,
-or because they just want to do it themselves for any reason) then
-`/usr/doc/examples' exists as *documentation* for their benefit.
-
-   The only time these files should be read are by the sysadmin using
-their favourite editor or pager, or *perhaps* (in very complex packages)
-by the postinst as a template to build on or modify.
-
-   `/etc/skel' is part of the *implementation* of this configuration.
-It contains the files that are copied into new user accounts.  It
-should probably be as empty as we can make it.
-
-   Examples:
-`.profile'
-     `/etc/skel' should not contain a `.profile' file.  Anything that
-     needs to be done there should be done in `/etc/profile'.  Anything
-     that should not go in `/etc/profile' (users can't avoid running
-     `/etc/profile') probably should not be in the default
-     configuration.  bash has generally good default behaviour.
-
-`.bash_logout'
-     Likewise, bash functions perfectly happily without a
-     `.bash_logout', so none should be provided, since anything in it is
-     a deviation from the sensible default behaviour.
-
-`.xsession'
-     `/etc/skel' should not contain a `.xsession'.  `xdm''s system-wide
-     startup file `/usr/lib/X11/xdm/Xsession' supports a system-wide
-     default user configuration (which should probably be
-     `/etc/X11/Xsession' or some such) which may be overridden by
-     `.xsession' in the user's home directory.  Therefore there is no
-     need for a `.xsession' to be installed by default and none should
-     be provided.
-
-     Instead, a sensible `/etc/X11/Xsession' should be provided, and if
-     desired this can be used as a template by users who wish to install
-     their own configuration, or alternatively a more comprehensive
-     example with much commented-out interesting stuff could be put in
-     `/usr/doc/examples'.
-
-     If the sysadmin wishes to change the system-wide default they
-     should probably do this by editing `/etc/X11/Xsession' rather than
-     creating the file in `/etc/skel', because the former will affect
-     all user accounts that haven't explicitly overridden things by
-     creating their own file while the latter will only affect new
-     accounts.
-
-     All the configuration necessary for a program to function should be
-     provided.  Therefore sysadmins will not need to go through
-     `/usr/doc/examples' while editing configuration files in `/etc'
-     except in extreme cases (like INN) where the configuration was too
-     difficult to do automatically.
-
-`site-wide defaults'
-     Site-wide defaults should not go in `/etc/skel'.  In the case of
-     twm, for example, the system-wide default should be in
-     `/etc/X11/system.twmrc'.  (The default location for this in X11R5,
-     btw, is in `/usr/lib/X11' somewhere, but we can't put it on `/usr'
-     because of CDROM distributions, etc - hence the FSSTND's mandate
-     to put configuration files in `/etc'.)
-
-`.twmrc'
-     There should be no `.twmrc' file in `/etc/skel'.  You can have one
-     in `/usr/doc/examples' if you *like*, but why bother if
-     `system.twmrc' is a good example (and indeed is the one the user is
-     using before they create their own)?
-
-`m4'
-     `/usr/doc/examples' isn't mainly for example *configuration
-     files*.  It's for any kind of example file distributed with a
-     package.  For example, GNU m4 comes with a whole pile of example
-     m4 macro scripts, which is exactly what `/usr/doc/examples' is for.
-
-   Summary
-
-   Files that should be installed in new user accounts should be in
-`/etc/skel', as that will ensure that they *are* installed in new user
-accounts!  However, we should try to avoid the need for this.
-
-   `/usr/doc/examples' is just what it says: documentation in the form
-of examples.  If a sysadmin is required to go and read these files for
-their system to work they should be told about it.  For example, here
-is what the Smail postinst script says right at the start:
-
-     I can do certain kinds of automatic configuration of your
-     mail system, by asking you a number of questions.  Later you
-     may to confirm and/or correct your answers.  In any case,
-     comprehensive information on configuring Smail is in
-     smail(5) and in /usr/doc/examples/smail and
-     /usr/doc/smail-admin-guide.
-
-
-File: guidelines.info,  Node: How to write the Description control file field,  Next: Configuration of init,  Prev: configuration files - /etc/skel vs /usr/doc/examples,  Up: Appendix
-
-How to write the Description control file field
-===============================================
-
-   The format of the `Description' field is as follows:
-
-     Description: <single line synopsis>
-      <extended description over several lines>
-
-   The extended description has several kinds of line:
-
-   * Those starting with a single space are part of a paragraph.
-     Successive lines of this form will be word-wrapped when displayed.
-     The leading space will usually be stripped off.
-
-   * Those starting with two or more spaces.  These will be displayed
-     verbatim.  If the display cannot be panned horizontally the
-     displaying program will linewrap them `hard' (ie, without taking
-     account of word breaks).  If it can they will be allowed to trail
-     off to the right.  None, one or two initial spaces may be deleted,
-     but the number of spaces deleted from each line will be the same
-     (so that you can have indenting work correctly, for example).
-
-   * Those containing a single space followed by a single full stop
-     character.  These are rendered as blank lines.  This is the *only*
-     way to get a blank line - see below.
-
-   * Those containing a space, a full stop and some more characters.
-     These are for future expansion.  *Do not* use them.
-
-   IMPORTANT and not so important TIPS:
-
-   * *Always* start extended description lines with at least *one*
-     whitespace character.  Fields in the control file and in the
-     Packages file are separated by field names starting in the first
-     column, just as in RFC822.  Forgetting the whitespace will cause
-     `dpkg-deb' (>=0.93.23) to produce a syntax error when trying to
-     build the package.  If you force it to build anyway `dpkg' will
-     refuse to install the resulting mess.
-
-   * *Do not* include any completely *empty* lines. These separate
-     different records in the Packages file, and are forbidden in
-     control files.  See the previous paragraph for what happens if you
-     get this wrong.
-
-   * The single line synopsis should be kept brief - certainly under 80
-     characters.  `dselect' displays the *first 49* characters if
-     you're using an 80-column terminal.
-
-   * Do not include the package name in the synopsis line.  The display
-     software knows how to display this already, and you do not need to
-     state it.  Remember that in many situations the user may only see
-     the synopsis line - make it as informative as you can.
-
-   * The extended description should describe what the package does and
-     how it relates to the rest of the system (in terms of, for
-     example, which subsystem it is which part of).
-
-   * Put important information first, both in the synopis and extended
-     description.  Sometimes only the first part of the synopsis or of
-     the description will be displayed.  You can assume that there will
-     usually be a way to see the whole extended description.
-
-   * You may include information about dependencies and so forth in the
-     extended description, if you wish.
-
-   * Do not use tab characters.  Their effect is not predictable.
-
-   Example control file for Smail:
-
-     Package: smail
-     Version: 3.1.29.1-13
-     Maintainer: Ian Jackson <iwj10@cus.cam.ac.uk>
-     Recommends: pine | mailx | elm | emacs | mail-user-agent
-     Suggests: metamail
-     Depends: cron, libc5
-     Conflicts: sendmail
-     Provides: mail-transport-agent
-     Description: Electronic mail transport system.
-      Smail is the recommended mail transport agent (MTA) for Debian.
-      .
-      An MTA is the innards of the mail system - it takes messages from
-      user-friendly mailer programs and arranges for them to be delivered
-      locally or passed on to other systems as required.
-      .
-      In order to make use of it you must have one or more user level
-      mailreader programs such as elm, pine, mailx or Emacs (which has Rmail
-      and VM as mailreaders) installed.  If you wish to send messages other
-      than just to other users of your system you must also have appropriate
-      networking support, in the form of IP or UUCP.
-
-
-File: guidelines.info,  Node: Configuration of init,  Next: Maintainer script arguments and how `dpkg' does things,  Prev: How to write the Description control file field,  Up: Appendix
-
-Configuration of init
-=====================
-
-   The `/etc/init.d' directory contains the scripts executed by init(8)
-when init state (or "runlevel") is changed.  This includes the boot
-process, when the multi-user state begins.  Several of these scripts
-are included with init and are intended to be executed *once*, usually
-at boot time.  An example is `/etc/init.d/boot', which is executed at
-boot time to check and mount file systems, activate swap, load kernel
-modules, etc.-everything that needs to be done before the multi-user
-state begins.  `/etc/init.d' also contains the scripts that are
-executed when entering runlevel 0 (halt), runlevel 1 (single-user) and
-runlevel 6 (reboot).
-
-   Packages can (and should) place scripts in `/etc/init.d' to start or
-stop services at boot time or during a change of runlevel.  These
-scripts should be named `/etc/init.d/'<package>, and they should accept
-one of two arguments: "start", which starts the services, or "stop",
-which stops the services.  These scripts should ensure that they will
-behave sensibly if invoked with "start" when the service is already
-running, or with "stop2 when it isn't--the best way to achieve this is
-often to use `start-stop-daemon'.
-
-   This script should not fail obscurely when the configuration files
-remain but the package has been removed, as the default in dpkg is to
-leave configuration files on the system after the package has been
-removed.  Only when it is executed with the `-purge' option will dpkg
-remove configuration files.  Therefore, you should include a `test'
-statement at the top of the script, like this:
-
-     test -f <program-executed-later-in-script> || exit 0
-
-   These scripts should be referenced, when appropriate, by symbolic
-links in the `/etc/rc?.d' directories, as below.
-
-   When changing runlevels, init looks in the directory `/etc/rc<n>.d'
-for the scripts it should execute, where <n> is the runlevel that is
-being changed to.  Please note that the "scripts" in `/etc/rc?.d' are
-not actually scripts; they are symbolic links, referencing actual
-scripts in `/etc/init.d'.  For simplicity, we refer to them as
-"scripts".
-
-   First, the scripts prefixed with a "K" are executed, followed by the
-scripts prefixed with an "S".  The "K" scripts are responsible for
-killing certain services and the "S" scripts for starting certain
-services upon *entering* the runlevel.  For example, if we are changing
-from runlevel 2 to runlevel 3, init will first execute all of the "K"
-prefixed scripts it finds in `/etc/rc3.d' (to kill services), and then
-all of the "S" prefixed scripts it finds in `/etc/rc3.d' (to start
-services).  The "K" scripts will execute the file it references with an
-argument of "stop", and the "S" scripts will execute this file with an
-argument of "start".
-
-   After the "K" or "S" prefix, there should be a number specified, and
-this number should be between 00 and 99.  The number determines the
-order in which the scripts are run.  For example, the "K20" scripts will
-be executed before the "K30" scripts.  You can use this number to make
-sure that a certain service is started before another.  For example, on
-some machines, the program `setserial' may need to properly set an IRQ
-before the `ppp' program uses a modem to connect to a network.  In this
-case, the script that runs `setserial' should have a lower number than
-the script that starts `ppp' so that it runs first:
-
-     `/etc/rc2.d/S10setserial'
-     `/etc/rc2.d/S20ppp'
-
-   If it does not matter when or in which order the script is run, use
-the number "20".  If it does, then you should talk to the maintainer of
-the `sysvinit' package or post to `debian-devel', and they will help
-you choose a number.
-
-   In Debian GNU/Linux, we try to ship our software in as much of a
-"default" state as possible.  Therefore, unless there is a good reason
-for doing differently, we ask that you start and stop the services in
-each of the multi-user state runlevels (2, 3, 4, and 5).  If a service
-needs to be stopped before a file system can be unmounted (an example is
-process accounting or quota services), then be sure to stop them in the
-halt runlevel (0), the single-user runlevel (1) and the reboot runlevel
-(6).
-
-   The system administrator will have the opportunity to customize
-runlevels by simply adding, moving, or removing the symbolic links in
-`/etc/rc?.d'.  This is why we default to running everything in the
-multi-user state-a reasonable default-and the administrator can easily
-customize init to be as complex and sophisticated as he or she wants it
-to be beyond this.
-
-   We provide a script, `update-rc.d', to make it easier for package
-maintainers to arrange for the proper creation and removal of
-`/etc/rc?.d' symbolic links from their postinst and postrm scripts.
-You should use this script to make changes to `/etc/rc?.d' and *never*
-include any `/etc/rc.?.d' symbolic links in the actual archive.
-
-   * In the postinst script, you need only do the following to setup
-     `/etc/rc?.d'.  You should redirect standard output to `/dev/null',
-     as `update-rc.d' produces insignificant output:
-
-          update-rc.d <package> default >/dev/null
-
-     where <package> is the name of the file as it appears in
-     `/etc/init.d'.  It will use the default number of "20", as
-     mentioned above.  If you need to use a different number, you can
-     specify it after "default":
-
-          update-rc.d <package> default 30 >/dev/null
-
-   * In the postrm script, you need only do the following *if and only
-     if* it is called with the `purge' argument:
-
-          if [ purge = "$1" ]
-          then
-            update-rc.d <package> remove >/dev/null
-          fi
-
-Important Note:
----------------
-
-   *Do not* include the `/etc/rc?.d/*' symbolic links in the archive!
-*This will cause problems!*  You should create them with update-rc.d,
-as above.
-
-   *Do not* include the `/etc/rc?.d/*' symbolic links in conffiles!
-*This will cause problems!*  *Do*, however, include the `/etc/init.d'
-scripts in conffiles.
-
-Example:
---------
-
-   The process accounting package wants to make sure that process
-accounting is started at boot time and that it is stopped before the
-system is halted, enters the single-user state, or is rebooted (so that
-the `/var' file system can be properly unmounted).  It puts a script
-that does this in `/etc/init.d', naming the script appropriately
-"acct".  This script accepts one of two arguments: either "start",
-which starts process accounting, or "stop", which stops it.  To ensure
-that it does not fail obscurely when the configuration files remain but
-the package has been removed, we include a `test' statement at the top
-of the script:
-
-     #! /bin/sh
-     #
-     # Start process accounting.
-     . /etc/init.d/functions
-     test -f /usr/sbin/accton || exit 0
-     case "$1" in
-       start)
-         echo "Starting process accounting"
-         /usr/sbin/accton /var/account/pacct
-         ;;
-       stop)
-         echo "Stopping process accounting"
-         /usr/sbin/accton
-         ;;
-       *)
-         echo "Usage: /etc/init.d/acct {start|stop}"
-         exit 1
-     esac
-     exit 0
-
-   You may find a skeletal script from which to base your `/etc/init.d'
-scripts in `/etc/init.d/skeleton'.
-
-   We want to stop then (re)start process accounting when entering a
-multi-user state-runlevels 2, 3, 4, and 5-and we want to stop it when
-leaving such a state-runlevels 0 (halt), 1 (single) and 6 (reboot).
-These are good defaults, and we accomplish this by including the
-following in the postinst:
-
-     update-rc.d acct default >/dev/null
-
-   When the user removes the acct packages with the `-purge' option, we
-want to make sure the `/etc/rc?.d' symbolic links are properly removed,
-so we include the following in the postrm:
-
-     update-rc.d acct remove >/dev/null
-
-   Otherwise, the `/etc/rc?.d' symbolic links will remain on the system
-along with `/etc/init.d/acct' script.
-
-
-File: guidelines.info,  Node: Maintainer script arguments and how `dpkg' does things,  Next: Mail processing packages,  Prev: Configuration of init,  Up: Appendix
-
-Maintainer script arguments and how `dpkg' does things
-======================================================
-
-   This appendix describes exactly how maintainer scripts are called,
-with what arguments, in what order, and what `dpkg' does in between.
-
-   In all cases version numbers are <version>-<revision>, if the package
-has both, or just <version>.  `upgrade' is used even when the new
-version number looks lower than the old.
-
-Summary
--------
-
-     <new preinst> install
-     <new preinst> install <old-version>
-     <new preinst> upgrade <old-version>
-     <old preinst> abort-upgrade <new-version>
-     
-     <postinst> configure
-     <old postinst> abort-upgrade <new version>
-     <conflictor's postinst> abort-remove in-favour <package> <new version>
-     <deconfigured's postinst> abort-deconfigure \
-                   in-favour <package-being-installed-but-failed> <version>
-                   removing <conflicting-package> <version>
-     
-     <prerm> remove
-     <old prerm> upgrade <new version>
-     <new prerm> failed-upgrade <old-vppersion>
-     <conflictor's prerm> remove in-favour <package> <new version>
-     <deconfigured's prerm> deconfigure \
-                   in-favour <package-being-installed> <version> \
-                   removing <conflicting-package> <version>
-     
-     <postrm> remove
-     <postrm> purge
-     <old postrm> upgrade <new-version>
-     <new postrm> failed-upgrade <old-version>
-     <new postrm> abort-install
-     <new postrm> abort-install <old-version>
-     <new postrm> abort-upgrade <old-version>
-     <disappearer's postrm> disappear <overwriter> <new version>
-
-Details of unpack phase of installation or upgrade
---------------------------------------------------
-
-   The procedure on installation/upgrade/overwrite/disappear (ie, when
-running `dpkg --unpack', or the unpack stage of `dpkg --install') is as
-follows.  In each case if an error occurs the actions in are general
-run backwards - this means that the maintainer scripts are run with
-different arguments in reverse order.  These are the `error unwind'
-calls listed below.
-
-  1.
-       a. If a version the package is already installed, call
-               <old prerm> upgrade <new version>
-
-       b. If this gives an error (ie, a non-zero exit status), dpkg will
-          attempt instead:
-               <new prerm> failed-upgrade <old-version>
-           error unwind, for both the above cases:
-               <old postinst> abort-upgrade <new version>
-
-  2. If a `conflicting' package is being removed at the same time:
-       a. If any packages depended on that conflicting package and
-          `--auto-deconfigure' is specified, call, for each such
-          package:
-               <deconfigured's prerm> deconfigure \
-                in-favour <package-being-installed> <version> \
-                removing <conflicting-package> <version>
-           error unwind:
-               <deconfigured's postinst> abort-deconfigure \
-                in-favour <package-being-installed-but-failed> <version>
-                removing <conflicting-package> <version>
-          The deconfigured packages are marked as requiring
-          configuration, so that if -install is used they will be
-          configured again if possible.
-
-       b. To prepare for removal of the conflicting package, call:
-               <conflictor's prerm> remove in-favour <package> <new version>
-           error unwind:
-               <conflictor's postinst> abort-remove in-favour <package> <new version>
-
-  3.
-       a. If the package is being upgraded, call
-               <new preinst> upgrade <old-version>
-
-       b. otherwise, if the package had some configuration files from a
-          previous version installed (ie, it is in the conffiles-only
-          state):
-               <new preinst> install <old-version>
-
-       c. otherwise (ie, the package was completely purged):
-               <new preinst> install
-           error unwind versions, respectively:
-               <new postrm> abort-upgrade <old-version>
-               <new postrm> abort-install <old-version>
-               <new postrm> abort-install
-
-  4. The new package's files are unpacked, overwriting any that may be
-     on the system already, for example any from the old package or
-     from another package (backups of the old files are left around,
-     and if anything goes wrong dpkg will attempt to put them back as
-     part of the error unwind).
-
-  5.
-       a. If the package is being upgraded, call
-               <old postrm> upgrade <new-version>
-
-       b. If this fails, dpkg will attempt:
-               <new postrm> failed-upgrade <old-version>
-           error unwind, for both cases:
-               <old preinst> abort-upgrade <new-version>
-          This is the point of no return - if dpkg gets this far, it
-     won't back off past this point if an error occurs.  This will
-     leave the package in a fairly bad state, which will require a
-     successful reinstallation to clear up, but it's when dpkg starts
-     doing things that are irreversible.
-
-  6. Any files which were in the old version of the package but not in
-     the new are removed.
-
-  7. The new file list replaces the old.
-
-  8. The new maintainer scripts replace the old.
-
-  9. Any packages all of whose files have been overwritten during the
-     installation, and which aren't required for dependencies, are
-     considered to have been removed.  For each such package,
-       a. dpkg calls:
-               <disappearer's postrm> disappear <overwriter> <new version>
-
-       b. The package's maintainer scripts are removed.
-
-       c. It is noted in the status database as being in a sane state,
-          namely not installed (any conffiles it may have are ignored).
-          Note that disappearing packages do not have their prerm
-          called, because dpkg doesn't know in advance that the package
-          is going to vanish.
-
- 10. Any files in the package we're unpacking that are also listed in
-     the file lists of other packages are removed from those lists.
-     (This will lobotomise the file list of the `conflicting' package
-     if there is one.)
-
- 11. The backup files made at 4. are deleted.
-
- 12. The new package's status is now sane, and recorded as `unpacked'.
-     Here is another point of no return - if the conflicting package's
-     removal fails we do not unwind the rest of the installation; the
-     conflicting package is left in a half-removed limbo.
-
- 13. If there was a conflicting package we go and do the removal
-     actions, starting from point 2. of the removal, below.
-
-Details of configuration
-------------------------
-
-   When we configure a package (this happens with `dpkg --install', or
-with `--configure'), we first update the conffiles and then call:
-     <postinst> configure <most-recently-configured-version>
-
-   No attempt is made to unwind after errors during configuration.
-
-Details of removal and/or configration purging
-----------------------------------------------
-
-  1.      <prerm> remove
-
-  2. The package's files are removed (except conffiles).
-
-  3.      <postrm> remove
-
-  4. All the maintainer scripts except the postrm are removed.
-
-     If we aren't purging the package we stop here.  Note that packages
-     which have no postrm and no conffiles are automatically purged
-     when removed, as there is no difference except for the dpkg status.
-
-  5. The conffiles and any backup files (`~'-files, `#*#' files,
-     `%'-files, .dpkg-{old,new,tmp}, etc.) are removed.
-
-  6.      <postrm> purge
-
-  7. The package's file list is removed.
-        No attempt is made to unwind after errors during removal.
-
-
-File: guidelines.info,  Node: Mail processing packages,  Next: Virtual dependencies,  Prev: Maintainer script arguments and how `dpkg' does things,  Up: Appendix
-
-Mail processing packages
-========================
-
-   Debian packages which process electronic mail (whether
-mail-user-agents (MUA) or alternative mail-transport-agents (MTA))
-*must* make sure that they are compatible with the configuration
-decisions below.  Failure to do this may result in lost mail, broken
-`From:' lines, and other serious brain damage!
-
-   * The mail spool is `/var/spool/mail' and the interface to send a
-     mail message is `/usr/sbin/sendmail' (as per the FSSTND).  The mail
-     spool is part of the base and not part of the MTA package.
-
-   * Mailboxes are locked using the `.lock' lockfile convention, rather
-     than fcntl, flock or lockf.
-
-   * Mailboxes are generally 660 `<user>.mail' unless the user has
-     chosen otherwise.  A MUA may remove a mailbox (unless it has
-     nonstandard permissions) in which case the MTA or another MUA must
-     recreate it if needed.  Mailboxes must be writeable by group mail.
-
-   * The mail spool is 2775 mail.mail, and MUA's need to be setgid mail
-     to do the locking mentioned above (and obviously need to avoid
-     accessing other users' mailboxes using this privilege).
-
-   * `/etc/aliases' is the source file for the system mail aliases (e.g.
-     postmaster, usenet, etc.) - it is the one which the sysadmin and
-     postinst scripts may edit.
-
-   * The convention of writing `forward to <address>' in the mailbox
-     itself is not supported.  Use a `.forward' file instead.
-
-   * The location for the `rmail' program used by UUCP for incoming mail
-     is `/usr/sbin/rmail', as per the FSSTND.  Likewise, `rsmtp', for
-     receiving batch-SMTP-over-UUCP, is in `/usr/sbin/rsmtp' if it is
-     supported.
-
-   * Smail is not using HoneyDanBer UUCP, whose uux apparently accepts
-     -a and -g options.
-
-   * If you need to know what name to use (for example) on outgoing
-     news and mail messages which are generated locally, you should use
-     the file `/etc/mailname'.  It will contain the portion after the
-     username and `@' sign for email addresses of users on the machine
-     (followed by a newline).
-
-   A package should check for the existence of this file.  If it exists
-it should use it without comment (1).  If it does not exist it should
-prompt the user for the value and store it in `/etc/mailname' as well
-as using it in the package's configuration.  The prompt should make it
-clear that the name will not just be used by that package.  E.g., in
-the same situation the INN package says:
-
-     Please enter the `mail name' of your system.  This is the hostname
-     portion of the address to be shown on outgoing news and mail messages.
-     The default is `$syshostname', your system's host name.
-     Mail name [`$syshostname']:
-   ($syshostname is the output of `hostname -fqdn').
-
-   ---------- Footnotes ----------
-
-   (1)  An MTA's prompting configuration script may wish to prompt the
-user even if it finds this file exists.
-
-
-File: guidelines.info,  Node: Virtual dependencies,  Prev: Mail processing packages,  Up: Appendix
-
-Virtual dependencies
-====================
-
-   Virtual packages are in the same namespace as real packages, and may
-have the same name.  The meaning of a virtual package in a
-dependency/conflicts list is exactly that of listing all the real
-packages which state that they are an instantiation of that virtual
-package.
-
-   This is done with a new Provides field in the control file, with a
-syntax much like the Conflicts field.
-
-   The idea is that we can have something like:
-     Package: elm
-     Depends: mta
-     
-     Package: smail
-     Provides: mta
-     Conflicts: mta
-     
-     Package: sendmail
-     Provides: mta
-     Conflicts: mta
-    The result is equivalent to elm having said
-     Package: elm
-     Depends: smail | sendmail
-
-   (There'll be a special case to say that a package may conflict with a
-virtual package which it provides - clearly ...)
-
-   If there are both a real and a virtual package of the same name then
-the dependency may be satisfied (or the conflict caused) by either the
-real package or any of the virtual packages which provide it.  This is
-so that, for example, supposing we have
-     Package: lout
-     Optional: ghostview
-   (this is a fictional example - the Lout package should not mention
-ghostview), and someone else comes up with a nice PostScript previewer,
-then they can just say
-     Package: marvelpostview
-     Provides: ghostview
-   and all will work in the interim (until, say, the Lout maintainer
-changes things).
-
-   If a dependency or a conflict has a version number attached then only
-real packages will be considered to see whether the relationship is
-satisfied (or prohibited, for a conflict) - it is assumed that a real
-package which provides virtual package is not of the `right' version.
-If there is demand it can be arranged that a package which provides a
-virtual package may mention a version number, though this is unlikely to
-be helpful:
-     Provides: mta (2.0)
-
-   If you want to specify which of a set of real packages should be the
-default to satisfy a particular dependency on a virtual package, you can
-simply list the real package as alternative before the virtual one:
-     Package: xbaseR6
-     Recommended: xsvga | x-server
-     Provides: x-base, xr6shlib
-     
-     Package: xsvga
-     Recommended: x-base
-     Provides: x-server
-     
-     Package: x8514
-     Recommended: x-base
-     Provides: x-server
-
-   Virtual package names should generally not be used in the names of
-`/etc/init.d' scripts, configuration files, logfiles, and so on, so
-that several programs providing the same virtual package name can be
-installed.
-
-

+ 20 - 23
doc/guidelines.texi

@@ -6,7 +6,7 @@
 @setchapternewpage off
 
 @iftex
-@center @titlefont{Debian GNU/Linux Packaging Guidelines}
+@center @titlefont{Debian Linux Packaging Guidelines}
 @tex
 \vskip2pt \hrule height 2pt width \hsize \vskip2pt
 @end tex
@@ -25,11 +25,11 @@ END-INFO-DIR-ENTRY
 @node Top, Additional Information, (dir), (dir)
 
 @ifinfo
-@top Debian GNU/Linux Packaging Guidelines
+@top Debian Linux Packaging Guidelines
 @end ifinfo
 
    This file documents the steps that must be taken in the preparation
-of a Debian GNU/Linux package.  All submissions to be included in the
+of a Debian Linux package.  All submissions to be included in the
 distribution proper and all packages to be considered for @file{contrib}
 or @file{non-free} availability @emph{must} conform to the guidelines
 and standards described in this document or they cannot be included or
@@ -41,11 +41,11 @@ planning on going further than just contributing a package (i.e., if
 you plan to maintain it for an extended period of time or if you are
 generally interested in becoming more involved in the Project), you
 should join the @code{debian-devel} mailing list.  For more details,
-read @file{info/mailing-lists.txt}, available at any Debian GNU/Linux
+read @file{info/mailing-lists.txt}, available at any Debian Linux
 archive.
 
    (This file was last updated on @value{DATE}.  Please check the most
-recent @file{dpkg} package at any Debian GNU/Linux archive for a
+recent @file{dpkg} package at any Debian Linux archive for a
 potentially more up to date copy.)
 
 @menu
@@ -66,10 +66,10 @@ potentially more up to date copy.)
 
    These Guidelines are intended to be fairly general.  More specific
 information is available about certain aspects of building packages,
-such as how to use the features of Init under Debian GNU/Linux and how
+such as how to use the features of Init under Debian Linux and how
 to interact with some more technical details of dpkg's operation.  This
 information can be found in the directory @file{doc/package-developer}
-at any Debian GNU/Linux archive.  At the time of this writing, the
+at any Debian Linux archive.  At the time of this writing, the
 following documents are available:
 
 @table @file
@@ -174,11 +174,11 @@ personal purposes.  Software that will typically be included in
 software that does not allow modification or redistribution of
 modifications, commercial ``demos'', and ``shareware''.
 
-   When in doubt, send mail to @file{iwj10@@cus.cam.ac.uk} and
-@file{imurdock@@debian.org}.  Be prepared to provide us with the
-copyright statement.  Software covered by the GPL, public domain
-software and BSD-like copyrights are safe; be wary of the phrases
-``commercial use prohibited'' and ``distribution restricted''.
+   When in doubt, send mail to @file{debian-devel@@lists.debian.org}.
+Be prepared to provide us with the copyright statement.  Software
+covered by the GPL, public domain software and BSD-like copyrights are
+safe; be wary of the phrases ``commercial use prohibited'' and
+``distribution restricted''.
 
    Every package submission @emph{must} be accompanied by verbatim copy
 of its copyright (with the exceptions of public domain packages and
@@ -196,7 +196,7 @@ See below for details.
 source packages.  In either case, when files have been installed,
 they must conform to the requirements described in this section.
 
-   The primary rule in Debian GNU/Linux is to follow the Linux @dfn{File
+   The primary rule in Debian Linux is to follow the Linux @dfn{File
 System Standard} (@dfn{FSSTND}).  The location of installed files
 @emph{must} comply @emph{fully} with the FSSTND.  The latest version of
 this document can be found alongside the Guidelines or at
@@ -204,7 +204,7 @@ this document can be found alongside the Guidelines or at
 Specific questions about following the standard should be addressed to
 Daniel Quinlan, the FSSTND coordinator, at @code{quinlan@@yggdrasil.com}.
 
-   In addition to the FSSTND, all Debian GNU/Linux packages must follow
+   In addition to the FSSTND, all Debian Linux packages must follow
 the guidelines below.
 
 @itemize @bullet
@@ -587,7 +587,7 @@ This will create a file called @file{debian-tmp.deb}, from the
 After the @file{binary} target has done all this, the
 @file{<@i{package}>-<@i{version}>.deb} file in the parent directory is
 the binary distribution.  This file may be distributed and installed on
-any Debian GNU/Linux system with @file{dpkg} in the same manner and
+any Debian Linux system with @file{dpkg} in the same manner and
 using the same methods as all packages are installed to the system.
 
 @item
@@ -1359,7 +1359,7 @@ scripts should be named @file{/etc/init.d/}<package>, and they should
 accept one of two arguments: "start", which starts the services, or
 "stop", which stops the services.  These scripts should ensure that they
 will behave sensibly if invoked with "start" when the service is already
-running, or with "stop2 when it isn't---the best way to achieve this is
+running, or with "stop" when it isn't---the best way to achieve this is
 often to use @file{start-stop-daemon}.
 
 This script should not fail obscurely when the configuration files
@@ -1414,14 +1414,11 @@ number "20".  If it does, then you should talk to the maintainer of the
 @code{sysvinit} package or post to @code{debian-devel}, and they will
 help you choose a number.
 
-In Debian GNU/Linux, we try to ship our software in as much of a
+In Debian Linux, we try to ship our software in as much of a
 "default" state as possible.  Therefore, unless there is a good reason
-for doing differently, we ask that you start and stop the services in
-each of the multi-user state runlevels (2, 3, 4, and 5).  If a service
-needs to be stopped before a file system can be unmounted (an example is
-process accounting or quota services), then be sure to stop them in the
-halt runlevel (0), the single-user runlevel (1) and the reboot runlevel
-(6).
+for doing differently, we ask that you start the services in each of the
+multi-user state runlevels (2, 3, 4, and 5) and stop them in the halt
+runlevel (0), the single-user runlevel (1) and the reboot runlevel (6).
 
 The system administrator will have the opportunity to customize
 runlevels by simply adding, moving, or removing the symbolic links in

Разница между файлами не показана из-за своего большого размера
+ 0 - 1056
doc/guidelines.texi.beforeeric


+ 0 - 33
doc/guidelines.texi.rej

@@ -1,33 +0,0 @@
-***************
-*** 376,390 ****
-  Generally the following compilation parameters should be used:
-  
-  @display
--         CC = gcc
--         CFLAGS = -O2
--         LDFLAGS = -s (and -N, if appropriate; see below)
-  @end display
-  
-  All installed binaries should be stripped, hence @code{-s}.  @code{-N}
-  should only be used on binaries that are very small (less than 8K with
-  the @code{-N} option, roughly) and are not likely to have multiple
-- instances in memory.  Do not use @code{-N} on daemons, no matter how
-  small they are.
-  
-  It is up to the package maintainer to decide what compilation options
---- 383,397 ----
-  Generally the following compilation parameters should be used:
-  
-  @display
-+ CC = gcc
-+ CFLAGS = -O2
-+ LDFLAGS = -s (and -N, if appropriate; see below)
-  @end display
-  
-  All installed binaries should be stripped, hence @code{-s}.  @code{-N}
-  should only be used on binaries that are very small (less than 8K with
-  the @code{-N} option, roughly) and are not likely to have multiple
-+ instances in memory.  Don't use @code{-N} on daemons, no matter how
-  small they are.
-  
-  It is up to the package maintainer to decide what compilation options

+ 5 - 5
dpkg-deb/build.c

@@ -43,12 +43,12 @@
 # define S_ISLNK(mode) ((mode&0xF000) == S_IFLNK)
 #endif
 
-static void checkversion(const char *vstring, const char *fieldname, int *errs) {
+static void checkversion(const char *vstring, const char *valuename, int *errs) {
   const char *p;
   if (!vstring || !*vstring) return;
   for (p=vstring; *p; p++) if (isdigit(*p)) return;
-  fprintf(stderr, BACKEND " - error: %s field (`%s') doesn't contain any digits\n",
-          fieldname, vstring);
+  fprintf(stderr, BACKEND " - error: %s (`%s') doesn't contain any digits\n",
+          valuename, vstring);
   (*errs)++;
 }
 
@@ -107,8 +107,8 @@ void do_build(const char *const *argv) {
               controlfile, field->name);
       warns++;
     }
-    checkversion(checkedinfo->available.version,"Version",&errs);
-    checkversion(checkedinfo->available.revision,"Revision",&errs);
+    checkversion(checkedinfo->available.version.version,"(upstream) version",&errs);
+    checkversion(checkedinfo->available.version.revision,"Debian revision",&errs);
     if (errs) ohshit("%d errors in control file",errs);
     printf(BACKEND ": building package `%s' in `%s'.\n", checkedinfo->name, debar);
 

+ 4 - 4
dpkg-deb/main.c

@@ -40,12 +40,12 @@
 #include "dpkg-deb.h"
 
 static void printversion(void) {
-  if (!fputs("Debian GNU/Linux `" BACKEND "' package archive backend "
+  if (!fputs("Debian Linux `" BACKEND "' package archive backend "
              "version " DPKG_VERSION_ARCH ".\n"
-             "Copyright (C) 1994,1995 Ian Jackson.  This is free software; see the\n"
+             "Copyright (C) 1994-1996 Ian Jackson.  This is free software; see the\n"
              "GNU General Public Licence version 2 or later for copying conditions.\n"
              "There is NO warranty.  See dpkg-deb --licence for details.\n",
-             stderr)) werr("stderr");
+             stdout)) werr("stdout");
 }
 
 static void usage(void) {
@@ -69,7 +69,7 @@ Options:  -D for debugging output; --old or --new controls archive format;\n\
 Use `" DPKG "' to install and remove packages from your system, or\n\
 `" DSELECT "' for user-friendly package management.  Packages unpacked\n\
 using `" BACKEND " --extract' will be incorrectly installed !\n",
-             stderr)) werr("stderr");
+             stdout)) werr("stdout");
 }
 
 const char thisname[]= BACKEND;

+ 14 - 14
dselect/helpmsgs.src

@@ -10,18 +10,18 @@ Motion keys: Next/Previous, Top/End, Up/Down, Backwards/Forwards:
   B, Left-arrow         F, Right-arrow          pan display by 1/3 screen
   ^b                    ^f                      pan display by 1 character
 
-Package states - selection:                    Package states - hold flag:
-  +, Insert   select package(s)                  H  put package(s) `on hold'
-  -, Delete   deselect package(s)                G  `go' - take off hold
-  _           deselect, purge configuration
+Selection for later processing:
+ +, Insert  install or upgrade      =, H  hold in present state
+ -, Delete  remove                  :, G  unhold: upgrade or leave uninstalled
+ _          remove & purge config
                                              Miscellaneous:
-Quit, exit, overwrite (note capitals!):         ? request help (also Help, F1)
- Return  Confirm and quit (check dependencies)  i toggle/cycle info displays      
-   Q     Confirm and quit (override dep.s)      o cycle through sort orders       
- X, Esc  eXit, abandoning any changes made      v toggle verbose status display   
-   R     Revert to state before this list      ^l redraw display                  
-   U     set all to sUggested state             / search (hit Return to cancel)
-   D     set all to Directly selected state     \\ repeat last search             
+Quit, exit, overwrite (note capitals!):       ?, F1 request help (also Help)
+ Return  Confirm, quit (check dependencies)     i   toggle/cycle info displays
+   Q     Confirm, quit (override dep.s)       o, O  cycle through sort options
+ X, Esc  eXit, abandoning any changes made    v, V  change status display opts
+   R     Revert to state before this list      ^l   redraw display
+   U     set all to sUggested state             /   search (Return to cancel)
+   D     set all to Directly selected state )   \\   repeat last search
 
 @@@ mainintro Introduction to package list
 
@@ -174,6 +174,6 @@ Quit:
 
 Miscellaneous:
   ?, Help, F1      request help
- ^l                redraw display                  
-  /                search (just return to cancel)  
-  \\                repeat last search             
+ ^l                redraw display
+  /                search (just return to cancel)
+  \\                repeat last search

+ 6 - 4
dselect/main.cc

@@ -75,7 +75,7 @@ static const menuentry menuentries[]= {
 };
 
 static const char programdesc[]=
-      "Debian GNU/Linux `" DSELECT "' package handling frontend.";
+      "Debian Linux `" DSELECT "' package handling frontend.";
 
 static const char copyrightstring[]=
       "Version " DPKG_VERSION_ARCH ".  Copyright (C) 1994,1995 Ian Jackson.   This is\n"
@@ -83,7 +83,7 @@ static const char copyrightstring[]=
       "copying conditions.  There is NO warranty.  See dselect --licence for details.\n";
 
 static void printversion(void) {
-  if (fprintf(stderr,"%s\n%s",programdesc,copyrightstring) == EOF) werr("stderr");
+  if (fprintf(stdout,"%s\n%s",programdesc,copyrightstring) == EOF) werr("stdout");
 }
 
 static void usage(void) {
@@ -93,7 +93,7 @@ static void usage(void) {
        "Options:  --admindir <directory>  (default is /var/lib/dpkg)\n"
        "          --help  --version  --licence   --debug <file> | -D<file> | -D\n"
        "Actions:  access update select install config remove quit menu\n",
-       stderr)) werr("stderr");
+       stdout)) werr("stdout");
 }
 
 /* These are called by C code, so need to have C calling convention */
@@ -167,7 +167,9 @@ extern void operator delete(void *p) {
 
 urqresult urq_list(void) {
   readwrite= modstatdb_init(admindir,
-                            msdbrw_writeifposs|msdbrw_availablepreferversion);
+                            // Why do I need this cast ??
+                            (modstatdb_rw)(msdbrw_writeifposs|
+                                           msdbrw_availablepreferversion));
 
   curseson();
 

+ 2 - 1
dselect/methparse.cc

@@ -183,7 +183,8 @@ void readmethods(const char *pathbase, option **optionspp, int *nread) {
         if (fstat(fileno(descfile),&stab))
           ohshite("unable to stat option description file `%.250s'",pathbuf);
         opt->description= new char[stab.st_size+1];  errno=0;
-        if (fread(opt->description,1,stab.st_size+1,descfile) != stab.st_size)
+        unsigned long filelen= stab.st_size;
+        if (fread(opt->description,1,stab.st_size+1,descfile) != filelen)
           ohshite("failed to read option description file `%.250s'",pathbuf);
         opt->description[stab.st_size]= 0;
         if (ferror(descfile))

+ 61 - 25
dselect/pkgcmds.cc

@@ -73,14 +73,26 @@ void packagelist::movecursorafter(int ncursor) {
   refreshlist(); redrawthisstate();
 }
 
-void packagelist::setwant(pkginfo::pkgwant nw) {
+pkginfo::pkgwant packagelist::reallywant(pkginfo::pkgwant nwarg,
+                                         struct perpackagestate *pkgstate) {
+  if (nwarg != pkginfo::want_sentinel) return nwarg;
+  pkginfo::pkgstatus status= pkgstate->pkg->status;
+  if (status == pkginfo::stat_notinstalled) return pkginfo::want_purge;
+  if (status == pkginfo::stat_configfiles) return pkginfo::want_deinstall;
+  return pkginfo::want_install;
+}
+
+void packagelist::setwant(pkginfo::pkgwant nwarg) {
   int index, top, bot;
+  pkginfo::pkgwant nw;
 
   if (!readwrite) { beep(); return; }
 
   if (recursive) {
     redrawitemsrange(cursorline,cursorline+1);
-    table[cursorline]->selected= nw;
+    nw= reallywant(nwarg,table[cursorline]);
+    nw= nwarg != pkginfo::want_sentinel ? nwarg :
+    table[cursorline]->selected= reallywant(nwarg,table[cursorline]);
     redraw1item(cursorline);
     top= cursorline;
     bot= cursorline+1;
@@ -89,9 +101,11 @@ void packagelist::setwant(pkginfo::pkgwant nw) {
 
     affectedrange(&top,&bot);
     for (index= top; index < bot; index++) {
-      if (!table[index]->pkg->name ||
-          table[index]->selected == nw ||
-          table[index]->selected == pkginfo::want_purge && nw == pkginfo::want_deinstall)
+      if (!table[index]->pkg->name) continue;
+      nw= reallywant(nwarg,table[index]);
+      if (table[index]->selected == nw ||
+          (table[index]->selected == pkginfo::want_purge &&
+           nw == pkginfo::want_deinstall))
         continue;
       sub->add(table[index]->pkg,nw);
     }
@@ -104,33 +118,36 @@ void packagelist::setwant(pkginfo::pkgwant nw) {
 }
 
 void packagelist::kd_select()   { setwant(pkginfo::want_install);   }
+void packagelist::kd_hold() { setwant(pkginfo::want_hold); }
 void packagelist::kd_deselect() { setwant(pkginfo::want_deinstall); }
+void packagelist::kd_unhold() { setwant(pkginfo::want_sentinel); }
 void packagelist::kd_purge()    { setwant(pkginfo::want_purge);     }
 
-void packagelist::sethold(int hold) {
-  int top, bot, index;
-
-  if (!readwrite) { beep(); return; }
-
-  affectedrange(&top,&bot);
-  for (index= top; index < bot; index++) {
-    // Sorry about the contortions, but GCC produces a silly warning otherwise
-    unsigned int neweflag= table[index]->pkg->eflag;
-    if (hold) neweflag |= pkginfo::eflagf_hold;
-    else neweflag &= ~pkginfo::eflagf_hold;
-    table[index]->pkg->eflag= (enum pkginfo::pkgeflag)neweflag;
-    redraw1item(index);
-  }
-  movecursorafter(bot);
+int would_like_to_install(pkginfo::pkgwant wantvalue, pkginfo *pkg) {
+  /* Returns: 1 for yes, 0 for no, -1 for if they want to preserve an error condition. */
+  if (wantvalue == pkginfo::want_install) return 1;
+  if (wantvalue != pkginfo::want_hold) return 0;
+  if (pkg->status == pkginfo::stat_installed) return 1;
+  if (pkg->status == pkginfo::stat_notinstalled ||
+      pkg->status == pkginfo::stat_configfiles) return 0;
+  return -1;
 }
-
-void packagelist::kd_hold()     { sethold(1);                       }
-void packagelist::kd_unhold()   { sethold(0);                       }
-
+  
 const char *packagelist::itemname(int index) {
   return table[index]->pkg->name;
 }
 
+void packagelist::kd_swapstatorder() {
+  if (sortorder == so_unsorted) return;
+  switch (statsortorder) {
+  case sso_avail:     statsortorder= sso_state;     break;
+  case sso_state:     statsortorder= sso_unsorted;  break;
+  case sso_unsorted:  statsortorder= sso_avail;     break;
+  default: internerr("unknown statsort in kd_swapstatorder");
+  }
+  resortredisplay();
+}
+
 void packagelist::kd_swaporder() {
   switch (sortorder) {
   case so_priority:  sortorder= so_section;   break;
@@ -139,6 +156,10 @@ void packagelist::kd_swaporder() {
   case so_unsorted:                           return;
   default: internerr("unknown sort in kd_swaporder");
   }
+  resortredisplay();
+}
+
+void packagelist::resortredisplay() {
   const char *oldname= table[cursorline]->pkg->name;
   sortmakeheads();
   int newcursor;
@@ -164,6 +185,22 @@ void packagelist::kd_swaporder() {
   refreshlist();
 }
 
+void packagelist::kd_versiondisplay() {
+  switch (versiondisplayopt) {
+  case vdo_both:       versiondisplayopt= vdo_none;       break;
+  case vdo_none:       versiondisplayopt= vdo_available;  break;
+  case vdo_available:  versiondisplayopt= vdo_both;       break;
+  default: internerr("unknown versiondisplayopt in kd_versiondisplay");
+  }
+  setwidths();
+  leftofscreen= 0;
+  ldrawnstart= ldrawnend= -1;
+  redrawtitle();
+  redrawcolheads();
+  redrawitemsrange(topofscreen,lesserint(topofscreen+list_height,nitems));
+  refreshlist();
+}
+
 void packagelist::kd_verbose() {
   verbose= !verbose;
   setwidths();
@@ -208,7 +245,6 @@ void packagelist::kd_revertsuggest() {
 }
 
 /* fixme: configurable purge/deselect */
-/* fixme: un-hold things */
 
 void packagelist::kd_info() {
   currentinfo++;

+ 12 - 12
dselect/pkgdepcon.cc

@@ -120,12 +120,12 @@ static int dep_update_best_to_change_stop(perpackagestate *& best, pkginfo *tryt
 int packagelist::deselect_one_of(pkginfo *per, pkginfo *ped, dependency *display) {
   perpackagestate *er= per->clientdata;
   perpackagestate *ed= ped->clientdata;
-  
-  if (!er || er->selected != pkginfo::want_install ||
-      !ed || ed->selected != pkginfo::want_install) return 0;
+
+  if (!er || !would_like_to_install(er->selected,per) ||
+      !ed || !would_like_to_install(ed->selected,ped)) return 0;
   
   add(display,dp_must);
-  
+
   er= per->clientdata;  // these can be changed by add
   ed= ped->clientdata;
   
@@ -134,9 +134,11 @@ int packagelist::deselect_one_of(pkginfo *per, pkginfo *ped, dependency *display
             this, er->pkg->name, er->spriority, ed->pkg->name, ed->spriority, display);
   
   perpackagestate *best;
-  if (er->spriority < ed->spriority) best= er;        // We'd rather change the
-  else if (er->spriority > ed->spriority) best= ed;   // one with the lowest priority.
-  
+
+  if (per->eflag & pkginfo::eflagf_reinstreq) best= ed;      // Try not keep packages
+  else if (ped->eflag & pkginfo::eflagf_reinstreq) best= er; //  needing reinstallation
+  else if (er->spriority < ed->spriority) best= er; // We'd rather change the
+  else if (er->spriority > ed->spriority) best= ed; // one with the lowest priority.
   else if (er->pkg->priority >
            er->pkg->priority) best= er;         // ... failing that the one with
   else if (er->pkg->priority <                  //  the highest priority
@@ -276,10 +278,7 @@ int deppossatisfied(deppossi *possi) {
     // and therefore OK, or a version must have been specified,
     // in which case we don't need to look at the rest anyway.
     if (possi->verrel == deppossi::dvr_none) return 1;
-    int r= versioncompare(possi->ed->available.version,
-                          possi->ed->available.revision,
-                          possi->version,
-                          possi->revision);
+    int r= versioncompare(&possi->ed->available.version,&possi->version);
     switch (possi->verrel) {
     case deppossi::dvr_earlierequal:   return r <= 0;
     case deppossi::dvr_laterequal:     return r >= 0;
@@ -296,7 +295,8 @@ int deppossatisfied(deppossi *possi) {
        provider= provider->nextrev) {
     if (provider->up->type != dep_provides) continue;
     if (provider->up->up->clientdata &&
-        provider->up->up->clientdata->selected == pkginfo::want_install)
+        would_like_to_install(provider->up->up->clientdata->selected,
+                              provider->up->up) == 1)
       return 1;
   }
   return 0;

+ 96 - 11
dselect/pkgdisplay.cc

@@ -35,9 +35,8 @@ extern "C" {
 
 /* These MUST be in the same order as the corresponding enums in dpkg-db.h */
 const char
-  *const wantstrings[]=   { "new package", "selected", "deselected", "purge", 0 },
-  *const holdstrings[]=   { "", "on hold", "REINSTALL",
-                            "hold,REINSTALL", 0 },
+  *const wantstrings[]=   { "new package", "selected", "hold", "remove", "purge", 0 },
+  *const eflagstrings[]=   { "", "REINSTALL", 0 },
   *const statusstrings[]= { "not installed", "unpacked (not set up)",
                             "failed config", "installed", "half installed",
                             "removed (configs remain)", 0                            },
@@ -49,9 +48,34 @@ const char
   *const priorityabbrevs[]=  { "Req", "Imp", "Std", "Rec",
                                "Opt", "Xtr", "Ctb",
                                "bUG", "?"                  };
-const char statuschars[]=   " uF*H-";
-const char holdchars[]=     " hRX";
-const char wantchars[]=     "n*-_";
+const char statuschars[]=   " UF*H-";
+const char eflagchars[]=     " R?#";
+const char wantchars[]=     "n*=-_";
+
+/* These MUST be in the same order as the corresponding enums in pkglist.h */
+const char
+  *const ssaabbrevs[]= { "Broken",
+                         "New",
+                         "Updated",
+                         "Obsolete/local",
+                         "Up-to-date",
+                         "Available" },
+  *const ssastrings[]= { "Brokenly installed packages",
+                         "Newly available packages",
+                         "Updated packages (newer version is available)",
+                         "Obsolete and local packages present on system",
+                         "Up to date installed packages",
+                         "Available packages (not currently installed)" };
+
+const char
+  *const sssstrings[]= { "Brokenly installed packages",
+                         "Installed packages",
+                         "Removed packages (configuration still present)",
+                         "Purged packages and those never installed" },
+  *const sssabbrevs[]= { "Broken",
+                         "Installed",
+                         "Removed",
+                         "Purged" };
 
 static int maximumstring(const char *const *array) {
   int maxlen= 0;
@@ -74,7 +98,7 @@ void packagelist::setwidths() {
     status_want_width= maximumstring(wantstrings);
     status_width= status_hold_width+status_status_width+status_want_width*2+3;
     priority_width= 8;
-   package_width= 16;
+    package_width= 16;
   } else {
     status_width= 4;
     priority_width= 3;
@@ -94,8 +118,31 @@ void packagelist::setwidths() {
     package_column= section_column + section_width + gap_width;
   }
 
-  description_column= package_column + package_width + gap_width;
-
+  int versiondescriptioncolumn= package_column + package_width + gap_width;
+  
+  switch (versiondisplayopt) {
+  case vdo_none:
+    versioninstalled_column= versioninstalled_width= 0;
+    versionavailable_column= versionavailable_width= 0;
+    description_column= versiondescriptioncolumn;
+    break;
+  case vdo_available:
+    versioninstalled_column= versioninstalled_width= 0;
+    versionavailable_column= versiondescriptioncolumn;
+    versionavailable_width= 11;
+    description_column= versionavailable_column + versionavailable_width + gap_width;
+    break;
+  case vdo_both:
+    versioninstalled_column= versiondescriptioncolumn;
+    versioninstalled_width= 11;
+    versionavailable_column= versioninstalled_column + versioninstalled_width +gap_width;
+    versionavailable_width= versioninstalled_width;
+    description_column= versionavailable_column + versionavailable_width + gap_width;
+    break;
+  default:
+    internerr("unknown versiondisplayopt in setwidths");
+  }
+    
   total_width= TOTAL_LIST_WIDTH;
   description_width= total_width - description_column;
 }
@@ -114,12 +161,50 @@ void packagelist::redrawtitle() {
     if (x < xmax) {
       switch (sortorder) {
       case so_section:
-        waddnstr(titlewin, " (by section)", xmax-x);
+        switch (statsortorder) {
+        case sso_unsorted:
+          waddnstr(titlewin, " (by section)", xmax-x);
+          break;
+        case sso_avail:
+          waddnstr(titlewin, " (avail., section)", xmax-x);
+          break;
+        case sso_state:
+          waddnstr(titlewin, " (status, section)", xmax-x);
+          break;
+        default:
+          internerr("bad statsort in redrawtitle/so_section");
+        }
         break;
       case so_priority:
-        waddnstr(titlewin, " (by priority)", xmax-x);
+        switch (statsortorder) {
+        case sso_unsorted:
+          waddnstr(titlewin, " (by priority)", xmax-x);
+          break;
+        case sso_avail:
+          waddnstr(titlewin, " (avail., priority)", xmax-x);
+          break;
+        case sso_state:
+          waddnstr(titlewin, " (status, priority)", xmax-x);
+          break;
+        default:
+          internerr("bad statsort in redrawtitle/so_priority");
+        }
         break;
       case so_alpha:
+        switch (statsortorder) {
+        case sso_unsorted:
+          waddnstr(titlewin, " (alphabetically)", xmax-x);
+          break;
+        case sso_avail:
+          waddnstr(titlewin, " (by availability)", xmax-x);
+          break;
+        case sso_state:
+          waddnstr(titlewin, " (by status)", xmax-x);
+          break;
+        default:
+          internerr("bad statsort in redrawtitle/so_priority");
+        }
+        break;
         waddnstr(titlewin, " (alphabetically)", xmax-x);
         break;
       case so_unsorted:

+ 106 - 101
dselect/pkgkeys.cc

@@ -34,110 +34,115 @@ extern "C" {
 #include "bindings.h"
 
 const keybindings::interpretation packagelist_kinterps[] = {
-  { "up",             0,  packagelist::kd_up,               qa_noquit           },
-  { "down",           0,  packagelist::kd_down,             qa_noquit           },
-  { "top",            0,  packagelist::kd_top,              qa_noquit           },
-  { "bottom",         0,  packagelist::kd_bottom,           qa_noquit           },
-  { "scrollon",       0,  packagelist::kd_scrollon,         qa_noquit           },
-  { "scrollback",     0,  packagelist::kd_scrollback,       qa_noquit           },
-  { "iscrollon",      0,  packagelist::kd_iscrollon,        qa_noquit           },
-  { "iscrollback",    0,  packagelist::kd_iscrollback,      qa_noquit           },
-  { "scrollon1",      0,  packagelist::kd_scrollon1,        qa_noquit           },
-  { "scrollback1",    0,  packagelist::kd_scrollback1,      qa_noquit           },
-  { "iscrollon1",     0,  packagelist::kd_iscrollon1,       qa_noquit           },
-  { "iscrollback1",   0,  packagelist::kd_iscrollback1,     qa_noquit           },
-  { "panon",          0,  packagelist::kd_panon,            qa_noquit           },
-  { "panback",        0,  packagelist::kd_panback,          qa_noquit           },
-  { "panon1",         0,  packagelist::kd_panon1,           qa_noquit           },
-  { "panback1",       0,  packagelist::kd_panback1,         qa_noquit           },
-  { "select",         0,  packagelist::kd_select,           qa_noquit           },
-  { "deselect",       0,  packagelist::kd_deselect,         qa_noquit           },
-  { "purge",          0,  packagelist::kd_purge,            qa_noquit           },
-  { "hold",           0,  packagelist::kd_hold,             qa_noquit           },
-  { "unhold",         0,  packagelist::kd_unhold,           qa_noquit           },
-  { "info",           0,  packagelist::kd_info,             qa_noquit           },
-  { "verbose",        0,  packagelist::kd_verbose,          qa_noquit           },
-  { "help",           0,  packagelist::kd_help,             qa_noquit           },
-  { "search",         0,  packagelist::kd_search,           qa_noquit           },
-  { "searchagain",    0,  packagelist::kd_searchagain,      qa_noquit           },
-  { "swaporder",      0,  packagelist::kd_swaporder,        qa_noquit           },
-  { "redraw",         0,  packagelist::kd_redraw,           qa_noquit           },
-  { "quitcheck",      0,  packagelist::kd_quit_noop,        qa_quitchecksave    },
-  { "quitrejectsug",  0,  packagelist::kd_revertdirect,     qa_quitnochecksave  },
-  { "quitnocheck",    0,  packagelist::kd_quit_noop,        qa_quitnochecksave  },
-  { "abortnocheck",   0,  packagelist::kd_revert_abort,     qa_quitnochecksave  },
-  { "revert",         0,  packagelist::kd_revert_abort,     qa_noquit           },
-  { "revertsuggest",  0,  packagelist::kd_revertsuggest,    qa_noquit           },
-  { "revertdirect",   0,  packagelist::kd_revertdirect,     qa_noquit           },
-  {  0,               0,                                    qa_noquit           }
+  { "up",               0,  packagelist::kd_up,               qa_noquit           },
+  { "down",             0,  packagelist::kd_down,             qa_noquit           },
+  { "top",              0,  packagelist::kd_top,              qa_noquit           },
+  { "bottom",           0,  packagelist::kd_bottom,           qa_noquit           },
+  { "scrollon",         0,  packagelist::kd_scrollon,         qa_noquit           },
+  { "scrollback",       0,  packagelist::kd_scrollback,       qa_noquit           },
+  { "iscrollon",        0,  packagelist::kd_iscrollon,        qa_noquit           },
+  { "iscrollback",      0,  packagelist::kd_iscrollback,      qa_noquit           },
+  { "scrollon1",        0,  packagelist::kd_scrollon1,        qa_noquit           },
+  { "scrollback1",      0,  packagelist::kd_scrollback1,      qa_noquit           },
+  { "iscrollon1",       0,  packagelist::kd_iscrollon1,       qa_noquit           },
+  { "iscrollback1",     0,  packagelist::kd_iscrollback1,     qa_noquit           },
+  { "panon",            0,  packagelist::kd_panon,            qa_noquit           },
+  { "panback",          0,  packagelist::kd_panback,          qa_noquit           },
+  { "panon1",           0,  packagelist::kd_panon1,           qa_noquit           },
+  { "panback1",         0,  packagelist::kd_panback1,         qa_noquit           },
+  { "select",           0,  packagelist::kd_select,           qa_noquit           },
+  { "deselect",         0,  packagelist::kd_deselect,         qa_noquit           },
+  { "purge",            0,  packagelist::kd_purge,            qa_noquit           },
+  { "hold",             0,  packagelist::kd_hold,             qa_noquit           },
+  { "unhold",           0,  packagelist::kd_unhold,           qa_noquit           },
+  { "info",             0,  packagelist::kd_info,             qa_noquit           },
+  { "verbose",          0,  packagelist::kd_verbose,          qa_noquit           },
+  { "versiondisplay",   0,  packagelist::kd_versiondisplay,   qa_noquit           },
+  { "help",             0,  packagelist::kd_help,             qa_noquit           },
+  { "search",           0,  packagelist::kd_search,           qa_noquit           },
+  { "searchagain",      0,  packagelist::kd_searchagain,      qa_noquit           },
+  { "swaporder",        0,  packagelist::kd_swaporder,        qa_noquit           },
+  { "swapstatorder",    0,  packagelist::kd_swapstatorder,    qa_noquit           },
+  { "redraw",           0,  packagelist::kd_redraw,           qa_noquit           },
+  { "quitcheck",        0,  packagelist::kd_quit_noop,        qa_quitchecksave    },
+  { "quitrejectsug",    0,  packagelist::kd_revertdirect,     qa_quitnochecksave  },
+  { "quitnocheck",      0,  packagelist::kd_quit_noop,        qa_quitnochecksave  },
+  { "abortnocheck",     0,  packagelist::kd_revert_abort,     qa_quitnochecksave  },
+  { "revert",           0,  packagelist::kd_revert_abort,     qa_noquit           },
+  { "revertsuggest",    0,  packagelist::kd_revertsuggest,    qa_noquit           },
+  { "revertdirect",     0,  packagelist::kd_revertdirect,     qa_noquit           },
+  {  0,                 0,                                    qa_noquit           }
 };
 
 #define C(x) ((x)-'a'+1)
 
 const keybindings::orgbinding packagelist_korgbindings[]= {
-  { 'j',            "down"           }, // vi style
-  { 'n',            "down"           },
-  { KEY_DOWN,       "down"           },
-  { 'k',            "up"             }, // vi style
-  { 'p',            "up"             },
-  { KEY_UP,         "up"             },
-  
-  { 'N',            "scrollon"       },
-  { KEY_NPAGE,      "scrollon"       },
-  { ' ',            "scrollon"       },
-  { 'P',            "scrollback"     },
-  { KEY_PPAGE,      "scrollback"     },
-  { KEY_BACKSPACE,  "scrollback"     },
-  { 0177,           "scrollback"     }, // ASCII DEL
-  { C('h'),         "scrollback"     },
-  { C('n'),         "scrollon1"      },
-  { C('p'),         "scrollback1"    },
-  
-  { 't',            "top"            },
-  { KEY_HOME,       "top"            },
-  { 'e',            "bottom"         },
-  { KEY_LL,         "bottom"         },
-  { KEY_END,        "bottom"         },
-  
-  { 'u',            "iscrollback"    },
-  { 'd',            "iscrollon"      },
-  { C('u'),         "iscrollback1"   },
-  { C('d'),         "iscrollon1"     },
-  
-  { 'B',            "panback"        },
-  { KEY_LEFT,       "panback"        },
-  { 'F',            "panon"          },
-  { KEY_RIGHT,      "panon"          },
-  { C('b'),         "panback1"       },
-  { C('f'),         "panon1"         },
-
-  { '+',            "select"         },
-  { KEY_IC,         "select"         },
-  { '-',            "deselect"       },
-  { KEY_DC,         "deselect"       },
-  { '_',            "purge"          },
-  { 'H',            "hold"           },
-  { 'G',            "unhold"         },
-  
-  { '?',            "help"           },
-  { KEY_HELP,       "help"           },
-  { KEY_F(1),       "help"           },
-  { 'i',            "info"           },
-  { 'o',            "swaporder"      },
-  { 'v',            "verbose"        },
-  { C('l'),         "redraw"         },
-  { '/',            "search"         },
-  { '\\',           "searchagain"    },
-
-  { KEY_ENTER,      "quitcheck"      },
-  { '\r',           "quitcheck"      },
-  { 'Q',            "quitnocheck"    },
-  { 27,             "abortnocheck"   }, // esc
-  { 'x',            "abortnocheck"   },
-  { 'X',            "abortnocheck"   },
-  { 'R',            "revert"         },
-  { 'U',            "revertsuggest"  },
-  { 'D',            "revertdirect"   },
-
-  {  -1,             0               }
+  { 'j',            "down"             }, // vi style
+  { 'n',            "down"             },
+  { KEY_DOWN,       "down"             },
+  { 'k',            "up"               }, // vi style
+  { 'p',            "up"               },
+  { KEY_UP,         "up"               },
+                                       
+  { 'N',            "scrollon"         },
+  { KEY_NPAGE,      "scrollon"         },
+  { ' ',            "scrollon"         },
+  { 'P',            "scrollback"       },
+  { KEY_PPAGE,      "scrollback"       },
+  { KEY_BACKSPACE,  "scrollback"       },
+  { 0177,           "scrollback"       }, // ASCII DEL
+  { C('h'),         "scrollback"       },
+  { C('n'),         "scrollon1"        },
+  { C('p'),         "scrollback1"      },
+                                       
+  { 't',            "top"              },
+  { KEY_HOME,       "top"              },
+  { 'e',            "bottom"           },
+  { KEY_LL,         "bottom"           },
+  { KEY_END,        "bottom"           },
+                                       
+  { 'u',            "iscrollback"      },
+  { 'd',            "iscrollon"        },
+  { C('u'),         "iscrollback1"     },
+  { C('d'),         "iscrollon1"       },
+                                       
+  { 'B',            "panback"          },
+  { KEY_LEFT,       "panback"          },
+  { 'F',            "panon"            },
+  { KEY_RIGHT,      "panon"            },
+  { C('b'),         "panback1"         },
+  { C('f'),         "panon1"           },
+                                       
+  { '+',            "select"           },
+  { KEY_IC,         "select"           },
+  { '-',            "deselect"         },
+  { KEY_DC,         "deselect"         },
+  { '_',            "purge"            },
+  { 'H',            "hold"             },
+  { '=',            "unhold"           },
+  { 'G',            "unhold"           },
+                                       
+  { '?',            "help"             },
+  { KEY_HELP,       "help"             },
+  { KEY_F(1),       "help"             },
+  { 'i',            "info"             },
+  { 'o',            "swaporder"        },
+  { 'O',            "swapstatorder"    },
+  { 'v',            "verbose"          },
+  { 'V',            "versiondisplay"   },
+  { C('l'),         "redraw"           },
+  { '/',            "search"           },
+  { '\\',           "searchagain"      },
+                                       
+  { KEY_ENTER,      "quitcheck"        },
+  { '\r',           "quitcheck"        },
+  { 'Q',            "quitnocheck"      },
+  { 27,             "abortnocheck"     }, // esc
+  { 'x',            "abortnocheck"     },
+  { 'X',            "abortnocheck"     },
+  { 'R',            "revert"           },
+  { 'U',            "revertsuggest"    },
+  { 'D',            "revertdirect"     },
+                                       
+  {  -1,             0                 }
 };

+ 162 - 15
dselect/pkglist.cc

@@ -35,6 +35,19 @@ extern "C" {
 
 int packagelist::compareentries(struct perpackagestate *a,
                                 struct perpackagestate *b) {
+  switch (statsortorder) {
+  case sso_avail:
+    if (a->ssavail != b->ssavail) return a->ssavail - b->ssavail;
+    break;
+  case sso_state:
+    if (a->ssstate != b->ssstate) return a->ssstate - b->ssstate;
+    break;
+  case sso_unsorted:
+    break;
+  default:
+    internerr("unknown statsortorder in compareentries");
+  }
+
   const char *asection= a->pkg->section;
   if (!asection && a->pkg->name) asection= "";
   const char *bsection= b->pkg->section;
@@ -87,7 +100,9 @@ void packagelist::discardheadings() {
   headings= 0;
 }
 
-void packagelist::addheading(pkginfo::pkgpriority priority,
+void packagelist::addheading(enum ssavailval ssavail,
+                             enum ssstateval ssstate,
+                             pkginfo::pkgpriority priority,
                              const char *otherpriority,
                              const char *section) {
   assert(nitems <= nallocated);
@@ -99,8 +114,8 @@ void packagelist::addheading(pkginfo::pkgpriority priority,
     table= newtable;
   }
   
-  if (debug) fprintf(debug,"packagelist[%p]::addheading(%d,%s,%s)\n",
-                     this,priority,
+  if (debug) fprintf(debug,"packagelist[%p]::addheading(%d,%d,%d,%s,%s)\n",
+                     this,ssavail,ssstate,priority,
                      otherpriority ? otherpriority : "<null>",
                      section ? section : "<null>");
 
@@ -114,6 +129,9 @@ void packagelist::addheading(pkginfo::pkgpriority priority,
   newstate->pkg= newhead;
   newstate->uprec= headings;
   headings= newstate;
+  newstate->ssavail= ssavail;
+  newstate->ssstate= ssstate;
+  newhead->clientdata= newstate;
  
   table[nitems++]= newstate;
 }
@@ -132,20 +150,111 @@ void packagelist::sortinplace() {
   qsort(table,nitems,sizeof(struct pkginfoperfile*),qsort_compareentries);
 }
 
+void packagelist::ensurestatsortinfo() {
+  const struct versionrevision *veri;
+  const struct versionrevision *vera;
+  int index;
+  
+  if (debug) fprintf(debug,"packagelist[%p]::ensurestatsortinfos() "
+                     "sortorder=%d nitems=%d\n",this,statsortorder,nitems);
+  
+  switch (statsortorder) {
+  case sso_unsorted:
+    if (debug) fprintf(debug,"packagelist[%p]::ensurestatsortinfos() unsorted\n",this);
+    return;
+  case sso_avail:
+    if (debug) fprintf(debug,"packagelist[%p]::ensurestatsortinfos() calcssadone=%d\n",
+                       this,calcssadone);
+    if (calcssadone) return;
+    for (index=0; index < nitems; index++) {
+      if (debug)
+        fprintf(debug,"packagelist[%p]::ensurestatsortinfos() i=%d pkg=%s\n",
+                this,index,table[index]->pkg->name);
+      switch (table[index]->pkg->status) {
+      case pkginfo::stat_unpacked:
+      case pkginfo::stat_halfconfigured:
+      case pkginfo::stat_halfinstalled:
+        table[index]->ssavail= ssa_broken;
+        break;
+      case pkginfo::stat_notinstalled:
+      case pkginfo::stat_configfiles:
+        table[index]->ssavail=
+          table[index]->original == pkginfo::want_unknown
+            ? ssa_notinst_unseen : ssa_notinst_seen;
+        break;
+      case pkginfo::stat_installed:
+        veri= &table[index]->pkg->installed.version;
+        vera= &table[index]->pkg->available.version;
+        if (!informativeversion(vera)) {
+          table[index]->ssavail= ssa_installed_gone;
+        } else if (versioncompare(vera,veri) > 0) {
+          table[index]->ssavail= ssa_installed_newer;
+        } else {
+          table[index]->ssavail= ssa_installed_sameold;
+        }
+        break;
+      default:
+        internerr("unknown stat in ensurestatsortinfo sso_avail");
+      }
+      if (debug)
+        fprintf(debug,"packagelist[%p]::ensurestatsortinfos() i=%d ssavail=%d\n",
+                this,index,table[index]->ssavail);
+  
+    }
+    calcssadone= 1;
+    break;
+  case sso_state:
+    if (debug) fprintf(debug,"packagelist[%p]::ensurestatsortinfos() calcsssdone=%d\n",
+                       this,calcsssdone);
+    if (calcsssdone) return;
+    for (index=0; index < nitems; index++) {
+      if (debug)
+        fprintf(debug,"packagelist[%p]::ensurestatsortinfos() i=%d pkg=%s\n",
+                this,index,table[index]->pkg->name);
+      switch (table[index]->pkg->status) {
+      case pkginfo::stat_unpacked:
+      case pkginfo::stat_halfconfigured:
+      case pkginfo::stat_halfinstalled:
+        table[index]->ssstate= sss_broken;
+        break;
+      case pkginfo::stat_notinstalled:
+        table[index]->ssstate= sss_notinstalled;
+        break;
+      case pkginfo::stat_configfiles:
+        table[index]->ssstate= sss_configfiles;
+        break;
+      case pkginfo::stat_installed:
+        table[index]->ssstate= sss_installed;
+        break;
+      default:
+        internerr("unknown stat in ensurestatsortinfo sso_state");
+      }
+      if (debug)
+        fprintf(debug,"packagelist[%p]::ensurestatsortinfos() i=%d ssstate=%d\n",
+                this,index,table[index]->ssstate);
+  
+    }
+    calcsssdone= 1;
+    break;
+  default:
+    internerr("unknown statsortorder in ensurestatsortinfo");
+  }
+}
+
 void packagelist::sortmakeheads() {
   discardheadings();
+  ensurestatsortinfo();
   sortinplace();
   assert(nitems);
 
-  if (debug) fprintf(debug,"packagelist[%p]::sortmakeheads() sortorder=%d\n",
-                     this,sortorder);
+  if (debug) fprintf(debug,"packagelist[%p]::sortmakeheads() "
+                     "sortorder=%d statsortorder=%d\n",this,sortorder,statsortorder);
   
   int nrealitems= nitems;
-  addheading(pkginfo::pri_unset,0,0);
+  addheading(ssa_none,sss_none,pkginfo::pri_unset,0,0);
 
-  if (sortorder == so_alpha) { sortinplace(); return; }
-  
-  assert(sortorder == so_section || sortorder == so_priority);
+  assert(sortorder != so_unsorted);
+  if (sortorder == so_alpha && statsortorder == sso_unsorted) { sortinplace(); return; }
 
   // Important: do not save pointers into table in this function, because
   // addheading may need to reallocate table to make it larger !
@@ -157,6 +266,24 @@ void packagelist::sortmakeheads() {
   for (a=0; a<nrealitems; a++) {
     thispkg= table[a]->pkg;
     assert(thispkg->name);
+    int ssdiff= 0;
+    ssavailval ssavail= ssa_none;
+    ssstateval ssstate= sss_none;
+    switch (statsortorder) {
+    case sso_avail:
+      ssavail= thispkg->clientdata->ssavail;
+      ssdiff= (!lastpkg || ssavail != lastpkg->clientdata->ssavail);
+      break;
+    case sso_state:
+      ssstate= thispkg->clientdata->ssstate;
+      ssdiff= (!lastpkg || ssstate != lastpkg->clientdata->ssstate);
+      break;
+    case sso_unsorted:
+      break;
+    default:
+      internerr("unknown statsortorder in sortmakeheads");
+    }
+    
     int prioritydiff= (!lastpkg ||
                        thispkg->priority != lastpkg->priority ||
                        (thispkg->priority == pkginfo::pri_other &&
@@ -166,20 +293,35 @@ void packagelist::sortmakeheads() {
                                  lastpkg->section ? lastpkg->section : ""));
 
     if (debug) fprintf(debug,"packagelist[%p]::sortmakeheads()"
-                       " pkg=%s  priority=%d otherpriority=%s %s  section=%s %s\n",
-                       this, thispkg->name, thispkg->priority,
+                       " pkg=%s  state=%d avail=%d %s  priority=%d"
+                       " otherpriority=%s %s  section=%s %s\n",
+                       this, thispkg->name,
+                       thispkg->clientdata->ssavail,
+                       thispkg->clientdata->ssstate,
+                       ssdiff ? "*diff" : "same",
+                       thispkg->priority,
                        thispkg->otherpriority ? thispkg->otherpriority : "<null>",
                        prioritydiff ? "*diff*" : "same",
                        thispkg->section ? thispkg->section : "<null>",
                        sectiondiff ? "*diff*" : "same");
 
+    if (ssdiff)
+      addheading(ssavail,ssstate,
+                 pkginfo::pri_unset,0, 0);
+    
     if (sortorder == so_section && sectiondiff)
-      addheading(pkginfo::pri_unset,0, thispkg->section ? thispkg->section : "");
+      addheading(ssavail,ssstate,
+                 pkginfo::pri_unset,0, thispkg->section ? thispkg->section : "");
+    
     if (sortorder == so_priority && prioritydiff)
-      addheading(thispkg->priority,thispkg->otherpriority, 0);
-    if (prioritydiff || sectiondiff) 
-      addheading(thispkg->priority,thispkg->otherpriority,
+      addheading(ssavail,ssstate,
+                 thispkg->priority,thispkg->otherpriority, 0);
+    
+    if (sortorder != so_alpha && (prioritydiff || sectiondiff))
+      addheading(ssavail,ssstate,
+                 thispkg->priority,thispkg->otherpriority,
                  thispkg->section ? thispkg->section : "");
+    
     lastpkg= thispkg;
   }
 
@@ -213,6 +355,7 @@ void packagelist::initialsetup() {
   currentinfo= 0;
   headings= 0;
   verbose= 0;
+  calcssadone= calcsssdone= 0;
 }
 
 void packagelist::finalsetup() {
@@ -260,6 +403,8 @@ packagelist::packagelist(keybindings *kb) : baselist(kb) {
   if (!nitems) ohshit("There are no packages to select.");
   recursive= 0;
   sortorder= so_priority;
+  statsortorder= sso_avail;
+  versiondisplayopt= vdo_both;
   sortmakeheads();
   finalsetup();
 }
@@ -276,6 +421,8 @@ packagelist::packagelist(keybindings *kb, pkginfo **pkgltab) : baselist(kb) {
   }
     
   sortorder= so_unsorted;
+  statsortorder= sso_unsorted;
+  versiondisplayopt= vdo_none;
   finalsetup();
 }
 

+ 40 - 5
dselect/pkglist.h

@@ -39,6 +39,24 @@ enum selpriority {
   // high
 };
 
+enum ssavailval {        // Availability sorting order, first to last:
+  ssa_broken,            //   Brokenly-installed and nothing available
+  ssa_notinst_unseen,    //   Entirely new packages (available but not deselected yet)
+  ssa_installed_newer,   //   Installed, newer version available
+  ssa_installed_gone,    //   Installed but no longer available
+  ssa_installed_sameold, //   Same or older version available as installed
+  ssa_notinst_seen,      //   Available but not installed
+  ssa_none=-1
+};
+
+enum ssstateval {      // State sorting order, first to last:
+  sss_broken,          //   In some way brokenly installed
+  sss_installed,       //   Installed
+  sss_configfiles,     //   Config files only
+  sss_notinstalled,    //   Not installed
+  sss_none=-1
+};
+
 struct perpackagestate {
   struct pkginfo *pkg;
   /* The `heading' entries in the list, for `all packages of type foo',
@@ -55,6 +73,8 @@ struct perpackagestate {
   selpriority spriority;             // monotonically increases (used by sublists)
   showpriority dpriority;            // monotonically increases (used by sublists)
   struct perpackagestate *uprec;     // 0 if this is not part of a recursive list
+  ssavailval ssavail;
+  ssstateval ssstate;
   varbuf relations;
 
   void free(int recursive);
@@ -62,8 +82,9 @@ struct perpackagestate {
 
 class packagelist : public baselist {
   int status_width, gap_width, section_width, priority_width;
-  int package_width, description_width;
-  int section_column, priority_column, package_column, description_column;
+  int package_width, versioninstalled_width, versionavailable_width, description_width;
+  int section_column, priority_column, versioninstalled_column;
+  int versionavailable_column, package_column, description_column;
 
   // Only used when `verbose' is set
   int status_hold_width, status_status_width, status_want_width;
@@ -75,6 +96,9 @@ class packagelist : public baselist {
   // Misc.
   int recursive, nallocated, verbose;
   enum { so_unsorted, so_section, so_priority, so_alpha } sortorder;
+  enum { sso_unsorted, sso_avail, sso_state } statsortorder;
+  enum { vdo_none, vdo_available, vdo_both } versiondisplayopt;
+  int calcssadone, calcsssdone;
   struct perpackagestate *headings;
 
   // Information displays
@@ -116,15 +140,21 @@ class packagelist : public baselist {
   void redraw1package(int index, int selected);
   int compareentries(struct perpackagestate *a, struct perpackagestate *b);
   friend int qsort_compareentries(const void *a, const void *b);
+  pkginfo::pkgwant reallywant(pkginfo::pkgwant, struct perpackagestate*);
+  int describemany(char buf[], const char *prioritystring, const char *section,
+                   const struct perpackagestate *pps);
 
   void sortmakeheads();
+  void resortredisplay();
   void movecursorafter(int ncursor);
   void initialsetup();
   void finalsetup();
+  void ensurestatsortinfo();
 
   // To do with building the list, with heading lines in it
   void discardheadings();
-  void addheading(pkginfo::pkgpriority,const char*, const char *section);
+  void addheading(enum ssavailval, enum ssstateval,
+                  pkginfo::pkgpriority, const char*, const char *section);
   void sortinplace();
   void affectedrange(int *startp, int *endp);
   void setwant(pkginfo::pkgwant nw);
@@ -140,6 +170,7 @@ class packagelist : public baselist {
   void kd_morespecific();
   void kd_lessspecific();
   void kd_swaporder();
+  void kd_swapstatorder();
   void kd_select();
   void kd_deselect();
   void kd_purge();
@@ -147,6 +178,7 @@ class packagelist : public baselist {
   void kd_unhold();
   void kd_info();
   void kd_verbose();
+  void kd_versiondisplay();
   
   packagelist(keybindings *kb); // nonrecursive
   packagelist(keybindings *kb, pkginfo **pkgltab); // recursive
@@ -164,15 +196,18 @@ class packagelist : public baselist {
 };
 
 void repeatedlydisplay(packagelist *sub, showpriority, packagelist *unredisplay =0);
+int would_like_to_install(pkginfo::pkgwant, pkginfo *pkg);
 
 extern const char *const wantstrings[];
-extern const char *const holdstrings[];
+extern const char *const eflagstrings[];
 extern const char *const statusstrings[];
 extern const char *const prioritystrings[];
 extern const char *const priorityabbrevs[];
 extern const char *const relatestrings[];
+extern const char *const ssastrings[], *const ssaabbrevs[];
+extern const char *const sssstrings[], *const sssabbrevs[];
 extern const char statuschars[];
-extern const char holdchars[];
+extern const char eflagchars[];
 extern const char wantchars[];
 
 const struct pkginfoperfile *i2info(struct pkginfo *pkg);

+ 4 - 8
dselect/pkgsublist.cc

@@ -58,7 +58,7 @@ void packagelist::add(pkginfo *pkg, pkginfo::pkgwant nw) {
   add(pkg);  if (!pkg->clientdata) return;
   pkg->clientdata->direct= nw;
   selpriority np;
-  np= (nw == pkginfo::want_install) ? sp_selecting : sp_deselecting;
+  np= would_like_to_install(nw,pkg) ? sp_selecting : sp_deselecting;
   if (pkg->clientdata->spriority > np) return;
   if (debug) fprintf(debug,"packagelist[%p]::add(pkginfo %s, %s) setting\n",
                      this,pkg->name,wantstrings[nw]);
@@ -122,7 +122,7 @@ int packagelist::add(dependency *depends, showpriority displayimportance) {
        possi=possi->next, comma=(possi && possi->next ? ", " : " or ")) {
     info(comma);
     info(possi->ed->name);
-    if (possi->version && *possi->version) {
+    if (possi->verrel != deppossi::dvr_none) {
       switch (possi->verrel) {
       case deppossi::dvr_earlierequal:  info(" (<= "); break;
       case deppossi::dvr_laterequal:    info(" (>= "); break;
@@ -131,11 +131,7 @@ int packagelist::add(dependency *depends, showpriority displayimportance) {
       case deppossi::dvr_exact:         info(" (= "); break;
       default: internerr("unknown verrel");
       }
-      info(possi->version);
-      if (possi->revision && *possi->revision) {
-        info('-');
-        info(possi->revision);
-      }
+      info(versiondescribe(&possi->version,vdew_never));
       info(")");
     }
   }
@@ -143,7 +139,7 @@ int packagelist::add(dependency *depends, showpriority displayimportance) {
   add(depends->up,info.string(),displayimportance);
   for (possi=depends->list; possi; possi=possi->next) {
     add(possi->ed,info.string(),displayimportance);
-    if (depends->type != dep_provides && (!possi->version || !*possi->version)) {
+    if (possi->verrel == deppossi::dvr_none && depends->type != dep_provides) {
       // providers aren't relevant if a version was specified, or
       // if we're looking at a provider relationship already
       deppossi *provider;

+ 70 - 20
dselect/pkgtop.cc

@@ -45,30 +45,57 @@ const char *pkgprioritystring(const struct pkginfo *pkg) {
   }
 }
 
-static int describemany(char buf[], const char *prioritystring, const char *section) {
+int packagelist::describemany(char buf[], const char *prioritystring,
+                              const char *section,
+                              const struct perpackagestate *pps) {
+  const char *ssostring, *ssoabbrev;
+  int statindent;
+
+  statindent= 0;
+  ssostring= 0;
+  ssoabbrev= "All";
+  switch (statsortorder) {
+  case sso_avail:
+    if (pps->ssavail == -1) break;
+    ssostring= ssastrings[pps->ssavail];
+    ssoabbrev= ssaabbrevs[pps->ssavail];
+    statindent++;
+    break;
+  case sso_state:
+    if (pps->ssstate == -1) break;
+    ssostring= sssstrings[pps->ssstate];
+    ssoabbrev= sssabbrevs[pps->ssstate];
+    statindent++;
+    break;
+  case sso_unsorted:
+    break;
+  default:
+    internerr("unknown statsortrder in describemany all");
+  }
+  
   if (!prioritystring) {
     if (!section) {
-      strcpy(buf, "All packages");
-      return 0;
+      strcpy(buf, ssostring ? ssostring : "All packages");
+      return statindent;
     } else {
       if (!*section) {
-        strcpy(buf, "All packages without a section");
+        sprintf(buf,"%s packages without a section",ssoabbrev);
       } else {
-        sprintf(buf, "All packages in section %s", section);
+        sprintf(buf,"%s packages in section %s",ssoabbrev,section);
       }
-      return 1;
+      return statindent+1;
     }
   } else {
     if (!section) {
-      sprintf(buf, "All %s packages", prioritystring);
-      return 1;
+      sprintf(buf,"%s %s packages",ssoabbrev,prioritystring);
+      return statindent+1;
     } else {
       if (!*section) {
-        sprintf(buf, "All %s packages without a section", prioritystring);
+        sprintf(buf,"%s %s packages without a section",ssoabbrev,prioritystring);
       } else {
-        sprintf(buf, "All %s packages in section %s", prioritystring, section);
+        sprintf(buf,"%s %s packages in section %s",ssoabbrev,prioritystring,section);
       }
-      return 2;
+      return statindent+2;
     }
   }
 }
@@ -79,7 +106,7 @@ void packagelist::redrawthisstate() {
 
   const char *section= table[cursorline]->pkg->section;
   const char *priority= pkgprioritystring(table[cursorline]->pkg);
-  char *buf= new char[220+
+  char *buf= new char[500+
                       greaterint((table[cursorline]->pkg->name
                                   ? strlen(table[cursorline]->pkg->name) : 0),
                                  (section ? strlen(section) : 0) +
@@ -91,13 +118,13 @@ void packagelist::redrawthisstate() {
             package_width,
             table[cursorline]->pkg->name,
             statusstrings[table[cursorline]->pkg->status],
-            holdstrings[table[cursorline]->pkg->eflag][0] ? " - " : "",
-            holdstrings[table[cursorline]->pkg->eflag],
+            eflagstrings[table[cursorline]->pkg->eflag][0] ? " - " : "",
+            eflagstrings[table[cursorline]->pkg->eflag],
             wantstrings[table[cursorline]->selected],
             wantstrings[table[cursorline]->original],
             priority);
   } else {
-    describemany(buf,priority,section);
+    describemany(buf,priority,section,table[cursorline]->pkg->clientdata);
   }
   mvwaddnstr(thisstatepad,0,0, buf, total_width);
   pnoutrefresh(thisstatepad, 0,leftofscreen, thisstate_row,0,
@@ -120,7 +147,7 @@ void packagelist::redraw1itemsel(int index, int selected) {
 
       mvwprintw(listpad,index,0, "%-*.*s ",
                 status_hold_width, status_hold_width,
-                holdstrings[pkg->eflag]);
+                eflagstrings[pkg->eflag]);
       wprintw(listpad, "%-*.*s ",
               status_status_width, status_status_width,
               statusstrings[pkg->status]);
@@ -143,7 +170,7 @@ void packagelist::redraw1itemsel(int index, int selected) {
 
     } else {
 
-      mvwaddch(listpad,index,0, holdchars[pkg->eflag]);
+      mvwaddch(listpad,index,0, eflagchars[pkg->eflag]);
       waddch(listpad, statuschars[pkg->status]);
       waddch(listpad,
              /* fixme: keep this feature? */
@@ -176,7 +203,22 @@ void packagelist::redraw1itemsel(int index, int selected) {
   
     mvwprintw(listpad,index,package_column-1, " %-*.*s ",
               package_width, package_width, pkg->name);
-      
+
+    if (versioninstalled_width)
+      mvwprintw(listpad,index,versioninstalled_column, "%-*.*s ",
+                versioninstalled_width, versioninstalled_width,
+                versiondescribe(&pkg->installed.version,vdew_never));
+    if (versionavailable_width) {
+      if (informativeversion(&pkg->available.version) &&
+          versioncompare(&pkg->available.version,&pkg->installed.version) > 0)
+        wattrset(listpad, selected ? selstatesel_attr : selstate_attr);
+      mvwprintw(listpad,index,versionavailable_column, "%-*.*s",
+                versionavailable_width, versionavailable_width,
+                versiondescribe(&pkg->available.version,vdew_never));
+      wattrset(listpad, selected ? listsel_attr : list_attr);
+      waddch(listpad,' ');
+    }
+
     i= description_width;
     p= info->description ? info->description : "";
     while (i>0 && *p && *p != '\n') { waddch(listpad,*p); i--; p++; }
@@ -186,11 +228,11 @@ void packagelist::redraw1itemsel(int index, int selected) {
     const char *section= pkg->section;
     const char *priority= pkgprioritystring(pkg);
 
-    char *buf= new char[220+
+    char *buf= new char[500+
                         (section ? strlen(section) : 0) +
                         (priority ? strlen(priority) : 0)];
     
-    indent= describemany(buf,priority,section);
+    indent= describemany(buf,priority,section,pkg->clientdata);
 
     mvwaddstr(listpad,index,0, "    ");
     i= total_width-6;
@@ -243,6 +285,14 @@ void packagelist::redrawcolheads() {
     mvwaddnstr(colheadspad,0,section_column, "Section", section_width);
     mvwaddnstr(colheadspad,0,priority_column, "Priority", priority_width);
     mvwaddnstr(colheadspad,0,package_column, "Package", package_width);
+
+    if (versioninstalled_width)
+      mvwaddnstr(colheadspad,0,versioninstalled_column,
+                 "Inst.ver",versioninstalled_width);
+    if (versionavailable_width)
+      mvwaddnstr(colheadspad,0,versionavailable_column,
+                 "Avail.ver",versionavailable_width);
+
     mvwaddnstr(colheadspad,0,description_column, "Description", description_width);
   }
   refreshcolheads();

+ 34 - 9
include/dpkg-db.h

@@ -42,6 +42,11 @@ struct dependency { /* dy */
   enum deptype type;
 };
 
+struct versionrevision {
+  unsigned long epoch;
+  char *version, *revision;
+};  
+
 struct deppossi { /* do */
   struct dependency *up;
   struct pkginfo *ed;
@@ -59,7 +64,7 @@ struct deppossi { /* do */
     dvr_laterstrict=   dvrf_builtup | dvrf_later   | dvrf_strict,
     dvr_exact=         0400
   } verrel;
-  char *version, *revision;
+  struct versionrevision version;
   int cyclebreak;
 };
 
@@ -85,7 +90,8 @@ struct pkginfoperfile { /* pif */
   struct dependency *depends;
   struct deppossi *depended;
   int essential; /* The `essential' flag, 1=yes, 0=no (absent) */
-  char *description, *maintainer, *version, *revision, *source, *architecture;
+  char *description, *maintainer, *source, *architecture;
+  struct versionrevision version;
   struct conffile *conffiles;
   struct arbitraryfield *arbs;
 };
@@ -96,12 +102,18 @@ struct pkginfo { /* pig */
   struct pkginfo *next;
   char *name;
   enum pkgwant {
-    want_unknown, want_install, want_deinstall, want_purge
+    want_unknown, want_install, want_hold, want_deinstall, want_purge,
+    want_sentinel /* Not allowed except as special sentinel value
+                     in some places */
   } want;
   enum pkgeflag {
-    eflagv_ok=00, eflagv_hold=01, eflagv_reinstreq=02, eflagv_both=03,
-    eflagf_hold=01, eflagf_reinstreq=02
-  } eflag; /* bitmask */
+    eflagf_reinstreq    = 01,
+    eflagf_obsoletehold = 02,
+    eflagv_ok           = 0,
+    eflagv_reinstreq    =    eflagf_reinstreq,
+    eflagv_obsoletehold =                       eflagf_obsoletehold,
+    eflagv_obsoleteboth =    eflagf_reinstreq | eflagf_obsoletehold
+  } eflag; /* bitmask, but obsoletehold no longer used except when reading */
   enum pkgstatus {
     stat_notinstalled, stat_unpacked, stat_halfconfigured,
     stat_installed, stat_halfinstalled, stat_configfiles
@@ -113,7 +125,7 @@ struct pkginfo { /* pig */
   } priority;
   char *otherpriority;
   char *section;
-  char *configversion, *configrevision;
+  struct versionrevision configversion;
   struct filedetails *files;
   struct pkginfoperfile installed;
   struct pkginfoperfile available;
@@ -150,6 +162,7 @@ extern char *statusfile, *availablefile; /* initialised by modstatdb_init */
 struct pkginfo *findpackage(const char *name);
 void blankpackage(struct pkginfo *pp);
 void blankpackageperfile(struct pkginfoperfile *pifp);
+void blankversion(struct versionrevision*);
 int informative(struct pkginfo *pkg, struct pkginfoperfile *info);
 int countpackages(void);
 void resetpackages(void);
@@ -192,6 +205,15 @@ extern const struct namevalue wantinfos[];
 
 const char *skip_slash_dotslash(const char *p);
 
+int informativeversion(const struct versionrevision *version);
+
+enum versiondisplayepochwhen { vdew_never, vdew_nonambig, vdew_always };
+void varbufversion(struct varbuf*, const struct versionrevision*,
+                   enum versiondisplayepochwhen);
+const char *parseversion(struct versionrevision *rversion, const char*);
+const char *versiondescribe(const struct versionrevision*,
+                            enum versiondisplayepochwhen);
+
 /*** from varbuf.c ***/
 
 struct varbuf;
@@ -255,12 +277,15 @@ void writedb(const char *filename, int available, int mustsync);
 
 void varbufrecord(struct varbuf*, const struct pkginfo*, const struct pkginfoperfile*);
 void varbufdependency(struct varbuf *vb, struct dependency *dep);
+void varbufprintf(struct varbuf *v, const char *fmt, ...) PRINTFFORMAT(2,3);
   /* NB THE VARBUF MUST HAVE BEEN INITIALISED AND WILL NOT BE NULL-TERMINATED */
 
 /*** from vercmp.c ***/
 
-int versioncompare(const char *version, const char *revision,
-                   const char *refversion, const char *refrevision);
+int versioncompare(const struct versionrevision *version,
+                   const struct versionrevision *refversion);
+int epochsdiffer(const struct versionrevision *a,
+                 const struct versionrevision *b);
 
 /*** from nfmalloc.c ***/
 

+ 4 - 1
include/dpkg.h

@@ -46,7 +46,10 @@
 #define REMOVECONFFEXTS    "~", ".bak", "%", \
                            DPKGTEMPEXT, DPKGNEWEXT, DPKGOLDEXT, DPKGDISTEXT
 
-#define DPKG_VERSION_ARCH  DPKG_VERSION " (" ARCHITECTURE ")"
+#ifndef ARCHBINFMT
+#define ARCHBINFMT
+#endif
+#define DPKG_VERSION_ARCH  DPKG_VERSION " (" ARCHITECTURE ARCHBINFMT ")"
 
 #define NEWCONFFILEFLAG    "newconffile"
 #define NONEXISTENTFLAG    "nonexistent"

+ 44 - 0
lib/compat.c

@@ -25,8 +25,52 @@
 #include <stdlib.h>
 #include <string.h>
 #include <dirent.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 #include "config.h"
+#include "dpkg.h"
+
+char *strcpy(char *to, const char *from) {
+  char *oto= to;
+  while ((*to++ = *from++) != 0);
+  return oto;
+}
+
+#ifndef HAVE_VSNPRINTF
+int vsnprintf (char *buf, size_t maxsize, const char *fmt, va_list al) {
+  static FILE *file= 0;
+
+  struct stat stab;
+  unsigned long want, nr;
+  int retval;
+
+  if (maxsize == 0) return -1;
+  if (!file) {
+    file= tmpfile(); if (!file) ohshite("unable to open tmpfile for vsnprintf");
+  } else {
+    if (fseek(file,0,0)) ohshite("unable to rewind at start of vsnprintf");
+    if (ftruncate(fileno(file),0)) ohshite("unable to truncate in vsnprintf");
+  }
+  if (vfprintf(file,fmt,al) == EOF) ohshite("write error in vsnprintf");
+  if (fflush(file)) ohshite("unable to flush in vsnprintf");
+  if (fstat(fileno(file),&stab)) ohshite("unable to stat in vsnprintf");
+  if (fseek(file,0,0)) ohshite("unable to rewind in vsnprintf");
+  want= stab.st_size;
+  if (want >= maxsize) {
+    want= maxsize-1; retval= -1;
+  } else {
+    retval= want;
+  }
+  nr= fread(buf,1,want-1,file);
+  if (nr != want-1) ohshite("read error in vsnprintf truncated");
+  buf[want]= 0;
+
+  return retval;
+}
+#endif
 
 #ifndef HAVE_STRERROR
 extern const char *const sys_errlist[];

+ 11 - 4
lib/database.c

@@ -106,13 +106,19 @@ static int hash(const char *name) {
  */
 }
 
+void blankversion(struct versionrevision *version) {
+  version->epoch= 0;
+  version->version= version->revision= 0;
+}
+
 void blankpackage(struct pkginfo *pigp) {
   pigp->name= 0;
   pigp->status= stat_notinstalled;
   pigp->eflag= eflagv_ok;
   pigp->want= want_unknown;
   pigp->priority= pri_unknown;
-  pigp->section= pigp->configversion= pigp->configrevision= 0;
+  pigp->section= 0;
+  blankversion(&pigp->configversion);
   pigp->files= 0;
   pigp->installed.valid= 0;
   pigp->available.valid= 0;
@@ -124,7 +130,8 @@ void blankpackageperfile(struct pkginfoperfile *pifp) {
   pifp->depends= 0;
   pifp->depended= 0;
   pifp->description= pifp->maintainer= pifp->source= 0;
-  pifp->architecture= pifp->version= pifp->revision= 0;
+  pifp->architecture= 0;
+  blankversion(&pifp->version);
   pifp->conffiles= 0;
   pifp->arbs= 0;
   pifp->valid= 1;
@@ -141,6 +148,7 @@ int informative(struct pkginfo *pkg, struct pkginfoperfile *info) {
       ((pkg->want != want_unknown && pkg->want != want_purge) ||
        pkg->eflag != eflagv_ok ||
        pkg->status != stat_notinstalled ||
+       informativeversion(&pkg->configversion) ||
        pkg->files)
       :
       (nes(pkg->section) ||
@@ -152,8 +160,7 @@ int informative(struct pkginfo *pkg, struct pkginfoperfile *info) {
       nes(info->maintainer) ||
       nes(info->source) ||
       nes(info->architecture) ||
-      nes(info->version) ||
-      nes(info->revision) ||
+      informativeversion(&info->version) ||
       info->conffiles ||
       info->arbs) return 1;
   return 0;

+ 8 - 19
lib/dump.c

@@ -44,31 +44,21 @@ void w_name(struct varbuf *vb,
 void w_version(struct varbuf *vb,
                const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
                const struct fieldinfo *fip) {
-  /* Revision information is printed in version field too. */
-  if ((!pifp->version || !*pifp->version) &&
-      (!pifp->revision || !*pifp->revision)) return;
+  /* Epoch and revision information is printed in version field too. */
+  if (!informativeversion(&pifp->version)) return;
   varbufaddstr(vb,"Version: ");
-  varbufaddstr(vb,pifp->version ? pifp->version : "");
-  if (pifp->revision && *pifp->revision) {
-    varbufaddc(vb,'-');
-    varbufaddstr(vb,pifp->revision);
-  }
+  varbufversion(vb,&pifp->version,vdew_nonambig);
   varbufaddc(vb,'\n');
 }
 
 void w_configversion(struct varbuf *vb,
                      const struct pkginfo *pigp, const struct pkginfoperfile *pifp,
                      const struct fieldinfo *fip) {
-  if ((!pigp->configversion || !*pigp->configversion) &&
-      (!pigp->configrevision || !*pigp->configrevision)) return;
   if (pifp != &pigp->installed) return;
+  if (!informativeversion(&pigp->configversion)) return;
   if (pigp->status == stat_installed || pigp->status == stat_notinstalled) return;
   varbufaddstr(vb,"Config-Version: ");
-  varbufaddstr(vb,pigp->configversion ? pigp->configversion : "");
-  if (pigp->configrevision && *pigp->configrevision) {
-    varbufaddc(vb,'-');
-    varbufaddstr(vb,pigp->configrevision);
-  }
+  varbufversion(vb,&pigp->configversion,vdew_nonambig);
   varbufaddc(vb,'\n');
 }
 
@@ -140,7 +130,7 @@ void w_status(struct varbuf *vb,
               const struct fieldinfo *fip) {
   if (pifp != &pigp->installed) return;
   assert(pigp->want <= want_purge &&
-         pigp->eflag <= eflagv_both &&
+         pigp->eflag <= eflagv_reinstreq && /* hold and hold-reinstreq NOT allowed */
          pigp->status <= stat_configfiles);
   varbufaddstr(vb,"Status: ");
   varbufaddstr(vb,wantinfos[pigp->want].name); varbufaddc(vb,' ');
@@ -167,9 +157,8 @@ void varbufdependency(struct varbuf *vb, struct dependency *dep) {
       case dvr_earlierstrict: varbufaddstr(vb,"<<"); break;
       default: internerr("unknown verrel");
       }
-      if (!isalnum(dop->version[0])) varbufaddc(vb,' ');
-      varbufaddstr(vb,dop->version);
-      if (dop->revision) { varbufaddc(vb,'-'); varbufaddstr(vb,dop->revision); }
+      varbufaddc(vb,' ');
+      varbufversion(vb,&dop->version,vdew_nonambig);
       varbufaddc(vb,')');
     }
   }

+ 47 - 23
lib/fields.c

@@ -158,27 +158,55 @@ void f_status(struct pkginfo *pigp, struct pkginfoperfile *pifp,
                              warnto,warncount,pigp, value,wantinfos,&ep);
   pigp->eflag= convert_string(filename,lno,"second (error) word in `status' field", -1,
                               warnto,warncount,pigp, ep,eflaginfos,&ep);
+  if (pigp->eflag & eflagf_obsoletehold) {
+    pigp->want= want_hold;
+    pigp->eflag &= ~eflagf_obsoletehold;
+  }
   pigp->status= convert_string(filename,lno,"third (status) word in `status' field", -1,
                                warnto,warncount,pigp, ep,statusinfos,0);
 }
 
+void f_version(struct pkginfo *pigp, struct pkginfoperfile *pifp,
+               enum parsedbflags flags,
+               const char *filename, int lno, FILE *warnto, int *warncount,
+               const char *value, const struct fieldinfo *fip) {
+  const char *emsg;
+  
+  emsg= parseversion(&pifp->version,value);
+  if (emsg) parseerr(0,filename,lno, warnto,warncount,pigp,0, "error "
+                     "in Version string `%.250s': %.250s",value,emsg);
+}  
+
+void f_revision(struct pkginfo *pigp, struct pkginfoperfile *pifp,
+                enum parsedbflags flags,
+                const char *filename, int lno, FILE *warnto, int *warncount,
+                const char *value, const struct fieldinfo *fip) {
+  char *newversion;
+
+  parseerr(0,filename,lno, warnto,warncount,pigp,1,
+           "obsolete `Revision' or `Package-Revision' field used");
+  if (!*value) return;
+  if (pifp->version.revision && *pifp->version.revision) {
+    newversion= nfmalloc(strlen(pifp->version.version)+strlen(pifp->version.revision)+2);
+    sprintf(newversion,"%s-%s",pifp->version.version,pifp->version.revision);
+  }
+  pifp->version.revision= nfstrsave(value);
+}  
+
 void f_configversion(struct pkginfo *pigp, struct pkginfoperfile *pifp,
                      enum parsedbflags flags,
                      const char *filename, int lno, FILE *warnto, int *warncount,
                      const char *value, const struct fieldinfo *fip) {
-  char *mycopy, *hyphen;
-
+  const char *emsg;
+  
   if (flags & pdb_rejectstatus)
     parseerr(0,filename,lno, warnto,warncount,pigp,0,
              "value for `config-version' field not allowed in this context");
   if (flags & pdb_recordavailable) return;
 
-  mycopy= nfstrsave(value);
-  hyphen= strrchr(mycopy,'-');
-  if (hyphen) *hyphen++= 0;
-
-  pigp->configversion= mycopy;
-  pigp->configrevision= hyphen ? hyphen : nfstrsave("");
+  emsg= parseversion(&pigp->configversion,value);
+  if (emsg) parseerr(0,filename,lno, warnto,warncount,pigp,0, "error "
+                     "in Config-Version string `%.250s': %.250s",value,emsg);
 }
 
 void f_conffiles(struct pkginfo *pigp, struct pkginfoperfile *pifp,
@@ -223,7 +251,7 @@ void f_dependency(struct pkginfo *pigp, struct pkginfoperfile *pifp,
                   enum parsedbflags flags,
                   const char *filename, int lno, FILE *warnto, int *warncount,
                   const char *value, const struct fieldinfo *fip) {
-  char *q, c1, c2;
+  char c1, c2;
   const char *p, *emsg;
   struct varbuf depname, version;
   struct dependency *dyp, **ldypp;
@@ -253,7 +281,7 @@ void f_dependency(struct pkginfo *pigp, struct pkginfoperfile *pifp,
       emsg= illegal_packagename(depname.buf,0);
       if (emsg) parseerr(0,filename,lno, warnto,warncount,pigp,0, "`%s' field,"
                          " invalid package name `%.255s': %s",
-                         fip->name, depname.buf, emsg);
+                         fip->name,depname.buf,emsg);
       dop= nfmalloc(sizeof(struct deppossi));
       dop->up= dyp;
       dop->ed= findpackage(depname.buf);
@@ -315,24 +343,20 @@ void f_dependency(struct pkginfo *pigp, struct pkginfoperfile *pifp,
           p++;
         }
         if (*p == '(') parseerr(0,filename,lno, warnto,warncount,pigp,0,
-                                "`%s' field, reference to `%.255s'"
-                                " version contains (", fip->name, depname.buf);
+                                "`%s' field, reference to `%.255s': "
+                                "version contains `('",fip->name,depname.buf);
         else if (*p == 0) parseerr(0,filename,lno, warnto,warncount,pigp,0,
-                                   "`%s' field, reference to `%.255s'"
-                                   "version unterminated", fip->name, depname.buf);
+                                   "`%s' field, reference to `%.255s': "
+                                   "version unterminated",fip->name,depname.buf);
         varbufaddc(&version,0);
-        q= strrchr(version.buf,'-');
-        if (q) {
-          *q++= 0;
-          dop->revision= nfstrsave(q);
-        } else {
-          dop->revision= 0;
-        }
-        dop->version= nfstrsave(version.buf);
+        emsg= parseversion(&dop->version,version.buf);
+        if (emsg) parseerr(0,filename,lno, warnto,warncount,pigp,0,
+                           "`%s' field, reference to `%.255s': "
+                           "error in version: %.255s",fip->name,depname.buf,emsg);
         p++; while (isspace(*p)) p++;
       } else {
         dop->verrel= dvr_none;
-        dop->revision= dop->version= 0;
+        blankversion(&dop->version);
       }
       if (!*p || *p == ',') break;
       if (*p != '|')

+ 29 - 49
lib/parse.c

@@ -31,32 +31,32 @@
 
 const struct fieldinfo fieldinfos[]= {
   /* NB: capitalisation of these strings is important. */
-  { "Package",          f_name,           w_name                                   },
-  { "Essential",        f_boolean,        w_booleandefno,  PKGIFPOFF(essential)    },
-  { "Status",           f_status,         w_status                                 },
-  { "Priority",         f_priority,       w_priority                               },
-  { "Section",          f_section,        w_section                                },
-  { "Maintainer",       f_charfield,      w_charfield,     PKGIFPOFF(maintainer)   },
-  { "Architecture",     f_charfield,      w_charfield,     PKGIFPOFF(architecture) },
-  { "Source",           f_charfield,      w_charfield,     PKGIFPOFF(source)       },
-  { "Version",          f_charfield,      w_version,       PKGIFPOFF(version)      },
-  { "Revision",         f_charfield,      w_null,          PKGIFPOFF(revision)     },
-  { "Config-Version",   f_configversion,  w_configversion                          },
-  { "Replaces",         f_dependency,     w_dependency,    dep_replaces            },
-  { "Provides",         f_dependency,     w_dependency,    dep_provides            },
-  { "Depends",          f_dependency,     w_dependency,    dep_depends             },
-  { "Pre-Depends",      f_dependency,     w_dependency,    dep_predepends          },
-  { "Recommends",       f_dependency,     w_dependency,    dep_recommends          },
-  { "Suggests",         f_dependency,     w_dependency,    dep_suggests            },
-  { "Conflicts",        f_dependency,     w_dependency,    dep_conflicts           },
-  { "Conffiles",        f_conffiles,      w_conffiles                              },
-  { "Filename",         f_filecharf,      w_filecharf,     FILEFOFF(name)          },
-  { "Size",             f_filecharf,      w_filecharf,     FILEFOFF(size)          },
-  { "MD5sum",           f_filecharf,      w_filecharf,     FILEFOFF(md5sum)        },
-  { "MSDOS-Filename",   f_filecharf,      w_filecharf,     FILEFOFF(msdosname)     },
-  { "Description",      f_charfield,      w_charfield,     PKGIFPOFF(description)  },
+  { "Package",          f_name,            w_name                                    },
+  { "Essential",        f_boolean,         w_booleandefno,   PKGIFPOFF(essential)    },
+  { "Status",           f_status,          w_status                                  },
+  { "Priority",         f_priority,        w_priority                                },
+  { "Section",          f_section,         w_section                                 },
+  { "Maintainer",       f_charfield,       w_charfield,      PKGIFPOFF(maintainer)   },
+  { "Architecture",     f_charfield,       w_charfield,      PKGIFPOFF(architecture) },
+  { "Source",           f_charfield,       w_charfield,      PKGIFPOFF(source)       },
+  { "Version",          f_version,         w_version                                 },
+  { "Revision",         f_revision,        w_null                                    },
+  { "Config-Version",   f_configversion,   w_configversion                           },
+  { "Replaces",         f_dependency,      w_dependency,     dep_replaces            },
+  { "Provides",         f_dependency,      w_dependency,     dep_provides            },
+  { "Depends",          f_dependency,      w_dependency,     dep_depends             },
+  { "Pre-Depends",      f_dependency,      w_dependency,     dep_predepends          },
+  { "Recommends",       f_dependency,      w_dependency,     dep_recommends          },
+  { "Suggests",         f_dependency,      w_dependency,     dep_suggests            },
+  { "Conflicts",        f_dependency,      w_dependency,     dep_conflicts           },
+  { "Conffiles",        f_conffiles,       w_conffiles                               },
+  { "Filename",         f_filecharf,       w_filecharf,      FILEFOFF(name)          },
+  { "Size",             f_filecharf,       w_filecharf,      FILEFOFF(size)          },
+  { "MD5sum",           f_filecharf,       w_filecharf,      FILEFOFF(md5sum)        },
+  { "MSDOS-Filename",   f_filecharf,       w_filecharf,      FILEFOFF(msdosname)     },
+  { "Description",      f_charfield,       w_charfield,      PKGIFPOFF(description)  },
   /* Note that aliases are added to the nicknames table in parsehelp.c. */
-  {  0   /* sentinel - tells code that list is ended */                            }
+  {  0   /* sentinel - tells code that list is ended */                              }
 };
 #define NFIELDS (sizeof(fieldinfos)/sizeof(struct fieldinfo))
 const int nfields= NFIELDS;
@@ -81,7 +81,6 @@ int parsedb(const char *filename, enum parsedbflags flags,
   const struct fieldinfo *fip;
   const struct nickname *nick;
   const char *fieldname;
-  char *hyphen;
   int *ip, i, c;
 
   if (warncount) *warncount= 0;
@@ -199,7 +198,7 @@ int parsedb(const char *filename, enum parsedbflags flags,
       parsemustfield(file,filename,lno, warnto,warncount,&newpig,1,
                      &newpifp->maintainer, "maintainer");
       parsemustfield(file,filename,lno, warnto,warncount,&newpig,1,
-                     &newpifp->version, "version");
+                     &newpifp->version.version, "version");
     }
     if (flags & pdb_recordavailable)
       parsemustfield(file,filename,lno, warnto,warncount,&newpig,1,
@@ -207,20 +206,6 @@ int parsedb(const char *filename, enum parsedbflags flags,
     else if (newpifp->architecture && *newpifp->architecture)
       newpifp->architecture= 0;
 
-    /* Break out the revision */
-    if (newpifp->revision) {
-      parseerr(file,filename,lno, warnto,warncount,&newpig,1,
-              "obsolete `Revision' or `Package-Revision' field used");
-    } else if (newpifp->version) {
-      hyphen= strrchr(newpifp->version,'-');
-      if (hyphen) {
-        *hyphen++= 0;
-        newpifp->revision= hyphen;
-      } else {
-        newpifp->revision= nfstrsave("");
-      }
-    }
-
     /* Check the Config-Version information:
      * If there is a Config-Version it is definitely to be used, but
      * there shouldn't be one if the package is `installed' (in which case
@@ -228,15 +213,12 @@ int parsedb(const char *filename, enum parsedbflags flags,
      * `not-installed' (in which case there is no Config-Version).
      */
     if (!(flags & pdb_recordavailable)) {
-      if (newpig.configversion) {
+      if (newpig.configversion.version) {
         if (newpig.status == stat_installed || newpig.status == stat_notinstalled)
           parseerr(file,filename,lno, warnto,warncount,&newpig,0,
                    "Configured-Version for package with inappropriate Status");
       } else {
-        if (newpig.status == stat_installed) {
-          newpig.configversion= newpifp->version;
-          newpig.configrevision= newpifp->revision;
-        }
+        if (newpig.status == stat_installed) newpig.configversion= newpifp->version;
       }
     }
 
@@ -245,8 +227,7 @@ int parsedb(const char *filename, enum parsedbflags flags,
     if (!pifp->valid) blankpackageperfile(pifp);
 
     if (!(flags & pdb_preferversion) ||
-        versioncompare(newpifp->version,newpifp->revision,
-                       pifp->version,pifp->revision) >= 0) {
+        versioncompare(&newpifp->version,&pifp->version) >= 0) {
       /* If we're ignoring older versions compare version numbers
        * and only process this entry if it's a higher version.
        */
@@ -281,7 +262,6 @@ int parsedb(const char *filename, enum parsedbflags flags,
         pigp->eflag= newpig.eflag;
         pigp->status= newpig.status;
         pigp->configversion= newpig.configversion;
-        pigp->configrevision= newpig.configrevision;
         pigp->files= 0;
       } else {
         pigp->files= newpig.files;

+ 4 - 2
lib/parsedump.h

@@ -46,12 +46,14 @@ typedef void freadfunction(struct pkginfo *pigp, struct pkginfoperfile *pifp,
                            const char *filename, int lno, FILE *warnto, int *warncount,
                            const char *value, const struct fieldinfo *fip);
 freadfunction f_name, f_charfield, f_priority, f_section, f_status, f_filecharf;
-freadfunction f_boolean, f_dependency, f_conffiles, f_configversion;
+freadfunction f_boolean, f_dependency, f_conffiles, f_version, f_revision;
+freadfunction f_configversion;
 
 typedef void fwritefunction(struct varbuf*, const struct pkginfo*,
                             const struct pkginfoperfile*, const struct fieldinfo*);
 fwritefunction w_name, w_charfield, w_priority, w_section, w_status, w_configversion;
-fwritefunction w_version, w_null, w_booleandefno, w_dependency, w_conffiles, w_filecharf;
+fwritefunction w_version, w_null, w_booleandefno, w_dependency, w_conffiles;
+fwritefunction w_filecharf;
 
 struct fieldinfo {
   const char *name;

+ 77 - 6
lib/parsehelp.c

@@ -88,23 +88,24 @@ const struct namevalue statusinfos[]= {  /* Note !  These must be in order ! */
 };
 
 const struct namevalue eflaginfos[]= {  /* Note !  These must be in order ! */
-  { "ok",             eflagv_ok         },
-  { "hold",           eflagv_hold       },
-  { "reinstreq",      eflagv_reinstreq  },
-  { "hold-reinstreq", eflagv_both       },
-  {  0                                  }
+  { "ok",                      eflagv_ok                 },
+  { "reinstreq",               eflagv_reinstreq          },
+  { "hold",                    eflagv_obsoletehold       },
+  { "hold-reinstreq",          eflagv_obsoleteboth       },
+  {  0                                                   }
 };
 
 const struct namevalue wantinfos[]= {  /* Note !  These must be in order ! */
   { "unknown",   want_unknown    },
   { "install",   want_install    },
+  { "hold",      want_hold       },
   { "deinstall", want_deinstall  },
   { "purge",     want_purge      },
   {  0                           }
 };
 
 const char *illegal_packagename(const char *p, const char **ep) {
-  static const char alsoallowed[]= "-_+.@:=%";
+  static const char alsoallowed[]= "-+._"; /* _ is deprecated */
   static char buf[150];
   int c;
   
@@ -134,6 +135,76 @@ const struct nickname nicknames[]= {
   {  0                                 }
 };
 
+int informativeversion(const struct versionrevision *version) {
+  return (version->epoch ||
+          (version->version && *version->version) ||
+          (version->revision && *version->revision));
+}
+
+void varbufversion(struct varbuf *vb,
+                   const struct versionrevision *version,
+                   enum versiondisplayepochwhen vdew) {
+  switch (vdew) {
+  case vdew_never:
+    break;
+  case vdew_nonambig:
+    if (!version->epoch &&
+        (!version->version || !strchr(version->version,':')) &&
+        (!version->revision || !strchr(version->revision,':'))) break;
+  case vdew_always: /* FALL THROUGH */
+    varbufprintf(vb,"%lu:",version->epoch);
+    break;
+  default:
+    internerr("bad versiondisplayepochwhen in varbufversion");
+  }
+  if (version->version) varbufaddstr(vb,version->version);
+  if (version->revision && *version->revision) {
+    varbufaddc(vb,'-');
+    varbufaddstr(vb,version->revision);
+  }
+}
+
+const char *versiondescribe(const struct versionrevision *version,
+                            enum versiondisplayepochwhen vdew) {
+  static struct varbuf bufs[10];
+  static int bufnum=0;
+
+  struct varbuf *vb;
+  
+  if (!informativeversion(version)) return "<none>";
+
+  vb= &bufs[bufnum]; bufnum++; if (bufnum == 10) bufnum= 0;
+  varbufreset(vb);
+  varbufversion(vb,version,vdew);
+  varbufaddc(vb,0);
+
+  return vb->buf;
+}
+
+const char *parseversion(struct versionrevision *rversion, const char *string) {
+  char *hyphen, *colon, *eepochcolon;
+  unsigned long epoch;
+
+  if (!*string) return "version string is empty";
+  
+  colon= strchr(string,':');
+  if (colon) {
+    epoch= strtoul(string,&eepochcolon,10);
+    if (colon != eepochcolon) return "epoch in version is not number";
+    if (!*++colon) return "nothing after colon in version number";
+    string= colon+1;
+    rversion->epoch= epoch;
+  } else {
+    rversion->epoch= 0;
+  }
+  rversion->version= nfstrsave(string);
+  hyphen= strrchr(rversion->version,'-');
+  if (hyphen) *hyphen++= 0;
+  rversion->revision= hyphen ? hyphen : nfstrsave("");
+  
+  return 0;
+}
+
 void parsemustfield(FILE *file, const char *filename, int lno,
                     FILE *warnto, int *warncount,
                     const struct pkginfo *pigp, int warnonly,



+ 16 - 0
lib/varbuf.c

@@ -30,6 +30,22 @@ void varbufaddc(struct varbuf *v, int c) {
   v->buf[v->used++]= c;
 }
 
+void varbufprintf(struct varbuf *v, const char *fmt, ...) {
+  int ou, r;
+  va_list al;
+
+  ou= v->used;
+  v->used+= strlen(fmt);
+
+  do {
+    varbufextend(v);
+    va_start(al,fmt);
+    r= vsnprintf(v->buf+ou,v->size-ou,fmt,al);
+    va_end(al);
+    v->used= ou+r;
+  } while (r >= v->size-ou-1);
+}
+
 void varbufaddstr(struct varbuf *v, const char *s) {
   int l, ou;
   l= strlen(s);

+ 12 - 4
lib/vercmp.c

@@ -27,6 +27,11 @@
 #include "dpkg-db.h"
 #include "parsedump.h"
 
+int epochsdiffer(const struct versionrevision *a,
+                 const struct versionrevision *b) {
+  return a->epoch != b->epoch;
+}
+
 static int verrevcmp(const char *val, const char *ref) {
   int vc, rc;
   long vl, rl;
@@ -56,9 +61,12 @@ static int verrevcmp(const char *val, const char *ref) {
   }
 }
 
-int versioncompare(const char *version, const char *revision,
-                   const char *refversion, const char *refrevision) {
+int versioncompare(const struct versionrevision *version,
+                   const struct versionrevision *refversion) {
   int r;
-  r= verrevcmp(version,refversion);  if (r) return r;
-  return verrevcmp(revision,refrevision);
+
+  if (version->epoch > refversion->epoch) return 1;
+  if (version->epoch < refversion->epoch) return 1;
+  r= verrevcmp(version->version,refversion->version);  if (r) return r;
+  return verrevcmp(version->revision,refversion->revision);
 }

+ 77 - 65
main/archives.c

@@ -137,12 +137,12 @@ static int does_replace(struct pkginfo *newpigp,
   struct dependency *dep;
   
   debug(dbg_depcon,"does_replace new=%s old=%s (%s)",newpigp->name,
-        oldpigp->name,versiondescribe(oldpigp->installed.version,
-                                      oldpigp->installed.revision));
+        oldpigp->name,versiondescribe(&oldpigp->installed.version,
+                                      vdew_always));
   for (dep= newpifp->depends; dep; dep= dep->next) {
     if (dep->type != dep_replaces || dep->list->ed != oldpigp) continue;
     debug(dbg_depcondetail,"does_replace ... found old, version %s",
-          versiondescribe(dep->list->version,dep->list->revision));
+          versiondescribe(&dep->list->version,vdew_always));
     if (!versionsatisfied(&oldpigp->installed,dep->list)) continue;
     debug(dbg_depcon,"does_replace ... yes");
     return 1;
@@ -339,6 +339,11 @@ int tarobject(struct TarInfo *ti) {
         }
         /* Nope ?  Hmm, file conflict, perhaps.  Check Replaces. */
         if (otherpkg->clientdata->replacingfilesandsaid) continue;
+        /* Is the package with the conflicting file in the `config files
+         * only' state ?  If so it must be a config file and we can
+         * silenty take it over.
+         */
+        if (otherpkg->status == stat_configfiles) continue;
         /* Perhaps we're removing a conflicting package ? */
         if (otherpkg->clientdata->istobe == itb_remove) continue;
         if (does_replace(tc->pkg,&tc->pkg->available,otherpkg)) {
@@ -547,75 +552,82 @@ void check_conflict(struct dependency *dep, struct pkginfo *pkg,
     varbuffree(&removalwhy);
     return;
   }
-  if (fixbyrm &&
-      ((pkg->available.essential && fixbyrm->installed.essential) ||
-       ((fixbyrm->want != want_install || does_replace(pkg,&pkg->available,fixbyrm)) &&
-        (!fixbyrm->installed.essential || fc_removeessential)))) {
+  if (fixbyrm) {
     ensure_package_clientdata(fixbyrm);
-    assert(fixbyrm->clientdata->istobe == itb_normal);
-    fixbyrm->clientdata->istobe= itb_remove;
-    fprintf(stderr, DPKG ": considering removing %s in favour of %s ...\n",
-            fixbyrm->name, pkg->name);
-    if (fixbyrm->status != stat_installed) {
-      fprintf(stderr,
-              "%s is not properly installed - ignoring any dependencies on it.\n",
-              fixbyrm->name);
-      pdep= 0;
-    } else {
-      for (pdep= fixbyrm->installed.depended;
-           pdep;
-           pdep= pdep->nextrev) {
-        if (pdep->up->type != dep_depends && pdep->up->type != dep_predepends) continue;
-        if (depisok(pdep->up, &removalwhy, 0,0)) continue;
-        varbufaddc(&removalwhy,0);
-        if (!try_remove_can(pdep,fixbyrm,removalwhy.buf))
-          break;
-      }
-      if (!pdep) {
-        /* If we haven't found a reason not to yet, let's look some more. */
-        for (providecheck= fixbyrm->installed.depends;
-             providecheck;
-             providecheck= providecheck->next) {
-          if (providecheck->type != dep_provides) continue;
-          for (pdep= providecheck->list->ed->installed.depended;
-               pdep;
-               pdep= pdep->nextrev) {
-            if (pdep->up->type != dep_depends && pdep->up->type != dep_predepends)
-              continue;
-            if (depisok(pdep->up, &removalwhy, 0,0)) continue;
-            varbufaddc(&removalwhy,0);
-            fprintf(stderr, DPKG
-                    ": may have trouble removing %s, as it provides %s ...\n",
-                    fixbyrm->name, providecheck->list->ed->name);
-            if (!try_remove_can(pdep,fixbyrm,removalwhy.buf))
-              goto break_from_both_loops_at_once;
+    if (fixbyrm->clientdata->istobe == itb_installnew) {
+      fixbyrm= dep->up;
+      ensure_package_clientdata(fixbyrm);
+    }
+    if (((pkg->available.essential && fixbyrm->installed.essential) ||
+         (((fixbyrm->want != want_install && fixbyrm->want != want_hold) ||
+           does_replace(pkg,&pkg->available,fixbyrm)) &&
+          (!fixbyrm->installed.essential || fc_removeessential)))) {
+      assert(fixbyrm->clientdata->istobe == itb_normal);
+      fixbyrm->clientdata->istobe= itb_remove;
+      fprintf(stderr, DPKG ": considering removing %s in favour of %s ...\n",
+              fixbyrm->name, pkg->name);
+      if (fixbyrm->status != stat_installed) {
+        fprintf(stderr,
+                "%s is not properly installed - ignoring any dependencies on it.\n",
+                fixbyrm->name);
+        pdep= 0;
+      } else {
+        for (pdep= fixbyrm->installed.depended;
+             pdep;
+             pdep= pdep->nextrev) {
+          if (pdep->up->type != dep_depends && pdep->up->type != dep_predepends)
+            continue;
+          if (depisok(pdep->up, &removalwhy, 0,0)) continue;
+          varbufaddc(&removalwhy,0);
+          if (!try_remove_can(pdep,fixbyrm,removalwhy.buf))
+            break;
+        }
+        if (!pdep) {
+          /* If we haven't found a reason not to yet, let's look some more. */
+          for (providecheck= fixbyrm->installed.depends;
+               providecheck;
+               providecheck= providecheck->next) {
+            if (providecheck->type != dep_provides) continue;
+            for (pdep= providecheck->list->ed->installed.depended;
+                 pdep;
+                 pdep= pdep->nextrev) {
+              if (pdep->up->type != dep_depends && pdep->up->type != dep_predepends)
+                continue;
+              if (depisok(pdep->up, &removalwhy, 0,0)) continue;
+              varbufaddc(&removalwhy,0);
+              fprintf(stderr, DPKG
+                      ": may have trouble removing %s, as it provides %s ...\n",
+                      fixbyrm->name, providecheck->list->ed->name);
+              if (!try_remove_can(pdep,fixbyrm,removalwhy.buf))
+                goto break_from_both_loops_at_once;
+            }
           }
+        break_from_both_loops_at_once:;
         }
-      break_from_both_loops_at_once:;
       }
-    }
-    if (!pdep && skip_due_to_hold(fixbyrm)) {
-      pdep= &flagdeppossi;
-    }
-    if (!pdep && (fixbyrm->eflag & eflagf_reinstreq)) {
-      if (fc_removereinstreq) {
-        fprintf(stderr, DPKG ": package %s requires reinstallation, but will"
-                " remove anyway as you request.\n", fixbyrm->name);
-      } else {
-        fprintf(stderr, DPKG ": package %s requires reinstallation, will not remove.\n",
-                fixbyrm->name);
+      if (!pdep && skip_due_to_hold(fixbyrm)) {
         pdep= &flagdeppossi;
       }
+      if (!pdep && (fixbyrm->eflag & eflagf_reinstreq)) {
+        if (fc_removereinstreq) {
+          fprintf(stderr, DPKG ": package %s requires reinstallation, but will"
+                  " remove anyway as you request.\n", fixbyrm->name);
+        } else {
+          fprintf(stderr, DPKG ": package %s requires reinstallation, "
+                  "will not remove.\n", fixbyrm->name);
+          pdep= &flagdeppossi;
+        }
+      }
+      if (!pdep) {
+        /* This conflict is OK - we'll remove the conflictor. */
+        *conflictorp= fixbyrm;
+        varbuffree(&conflictwhy); varbuffree(&removalwhy);
+        fprintf(stderr, DPKG ": yes, will remove %s in favour of %s.\n",
+                fixbyrm->name, pkg->name);
+        return;
+      }
+      fixbyrm->clientdata->istobe= itb_normal; /* put it back */
     }
-    if (!pdep) {
-      /* This conflict is OK - we'll remove the conflictor. */
-      *conflictorp= fixbyrm;
-      varbuffree(&conflictwhy); varbuffree(&removalwhy);
-      fprintf(stderr, DPKG ": yes, will remove %s in favour of %s.\n",
-              fixbyrm->name, pkg->name);
-      return;
-    }
-    fixbyrm->clientdata->istobe= itb_normal; /* put it back */
   }
   varbufaddc(&conflictwhy,0);
   fprintf(stderr, DPKG ": regarding %s containing %s:\n%s",

+ 14 - 14
main/cleanup.c

@@ -104,8 +104,8 @@ void cu_prermupgrade(int argc, void **argv) {
   if (cleanup_pkg_failed++) return;
   maintainer_script_installed(pkg,POSTINSTFILE,"post-installation",
                               "abort-upgrade",
-                              versiondescribe(pkg->available.version,
-                                              pkg->available.revision),
+                              versiondescribe(&pkg->available.version,
+                                              vdew_nonambig),
                               (char*)0);
   pkg->status= stat_installed;
   pkg->eflag &= ~eflagf_reinstreq;
@@ -128,11 +128,11 @@ void cu_prermdeconfigure(int argc, void **argv) {
 
   maintainer_script_installed(deconf,POSTINSTFILE,"post-installation",
                               "abort-deconfigure", "in-favour", infavour->name,
-                              versiondescribe(infavour->available.version,
-                                              infavour->available.revision),
+                              versiondescribe(&infavour->available.version,
+                                              vdew_nonambig),
                               "removing", conflictor->name,
-                              versiondescribe(conflictor->installed.version,
-                                              conflictor->installed.revision),
+                              versiondescribe(&conflictor->installed.version,
+                                              vdew_nonambig),
                               (char*)0);
   deconf->status= stat_installed;
   modstatdb_note(deconf);
@@ -145,8 +145,8 @@ void cu_prerminfavour(int argc, void **argv) {
   if (cleanup_conflictor_failed++) return;
   maintainer_script_installed(conflictor,POSTINSTFILE,"post-installation",
                               "abort-remove", "in-favour", infavour->name,
-                              versiondescribe(infavour->available.version,
-                                              infavour->available.revision),
+                              versiondescribe(&infavour->available.version,
+                                              vdew_nonambig),
                               (char*)0);
   conflictor->status= stat_installed;
   conflictor->eflag &= ~eflagf_reinstreq;
@@ -175,8 +175,8 @@ void cu_preinstnew(int argc, void **argv) {
 
   if (cleanup_pkg_failed++) return;
   maintainer_script_new(POSTRMFILE,"post-removal",cidir,cidirrest,
-                        "abort-install", versiondescribe(pkg->installed.version,
-                                                         pkg->installed.revision),
+                        "abort-install", versiondescribe(&pkg->installed.version,
+                                                         vdew_nonambig),
                         (char*)0);
   pkg->status= stat_configfiles;
   pkg->eflag &= ~eflagf_reinstreq;
@@ -193,8 +193,8 @@ void cu_preinstupgrade(int argc, void **argv) {
   if (cleanup_pkg_failed++) return;
   maintainer_script_new(POSTRMFILE,"post-removal",cidir,cidirrest,
                         "abort-upgrade",
-                        versiondescribe(pkg->installed.version,
-                                        pkg->installed.revision),
+                        versiondescribe(&pkg->installed.version,
+                                        vdew_nonambig),
                         (char*)0);
   pkg->status= *oldstatusp;
   pkg->eflag &= ~eflagf_reinstreq;
@@ -207,8 +207,8 @@ void cu_postrmupgrade(int argc, void **argv) {
 
   if (cleanup_pkg_failed++) return;
   maintainer_script_installed(pkg,PREINSTFILE,"pre-installation",
-                              "abort-upgrade", versiondescribe(pkg->available.version,
-                                                               pkg->available.revision),
+                              "abort-upgrade", versiondescribe(&pkg->available.version,
+                                                               vdew_nonambig),
                               (char*)0);
   cleanup_pkg_failed--;
 }

+ 2 - 2
main/configure.c

@@ -378,8 +378,8 @@ void deferred_configure(struct pkginfo *pkg) {
 
   if (maintainer_script_installed(pkg, POSTINSTFILE, "post-installation",
                                   "configure",
-                                  versiondescribe(pkg->configversion,
-                                                  pkg->configrevision),
+                                  versiondescribe(&pkg->configversion,
+                                                  vdew_nonambig),
                                   (char*)0))
     putchar('\n');
 

+ 22 - 50
main/depcon.c

@@ -30,12 +30,12 @@
 
 #include "main.h"
 
-int versionsatisfied5(const char *itver, const char *itrev,
-                      const char *refver, const char *refrev,
+int versionsatisfied3(const struct versionrevision *it,
+                      const struct versionrevision *ref,
                       enum depverrel verrel) {
   int r;
   if (verrel == dvr_none) return 1;
-  r= versioncompare(itver,itrev,refver,refrev);
+  r= versioncompare(it,ref);
   switch (verrel) {
   case dvr_earlierequal:   return r <= 0;
   case dvr_laterequal:     return r >= 0;
@@ -47,27 +47,7 @@ int versionsatisfied5(const char *itver, const char *itrev,
 }
 
 int versionsatisfied(struct pkginfoperfile *it, struct deppossi *against) {
-  return versionsatisfied5(it->version, it->revision,
-                           against->version, against->revision, against->verrel);
-}
-
-const char *versiondescribe(const char *ver, const char *rev) {
-  static char bufs[10][512];
-  static int bufnum=0;
-  char *buf;
-  
-  buf= bufs[bufnum]; bufnum++; if (bufnum == 10) bufnum= 0;
-  
-  if (!ver || !*ver) {
-    strcpy(buf,"<unknown>");
-  } else {
-    if (rev && *rev) {
-      sprintf(buf, "%.250s-%.250s", ver, rev);
-    } else {
-      sprintf(buf, "%.250s", ver);
-    }
-  }
-  return buf;
+  return versionsatisfied3(&it->version,&against->version,against->verrel);
 }
 
 struct cyclesofarlink {
@@ -245,30 +225,28 @@ int depisok(struct dependency *dep, struct varbuf *whynot,
      * the end we'll have accumulated all the reasons in whynot and
      * can return `0'.
      */
-    
+
     for (possi= dep->list; possi; possi= possi->next) {
       switch (possi->ed->clientdata->istobe) {
       case itb_remove:
-        sprintf(linebuf, "  %.250s is to be removed.\n", possi->ed->name);
+        sprintf(linebuf,"  %.250s is to be removed.\n",possi->ed->name);
         break;
       case itb_deconfigure:
-        sprintf(linebuf, "  %.250s is to be deconfigured.\n", possi->ed->name);
+        sprintf(linebuf,"  %.250s is to be deconfigured.\n",possi->ed->name);
         break;
       case itb_installnew:
-        if (versionsatisfied(&possi->ed->available, possi)) return 1;
-        sprintf(linebuf, "  %.250s is to be installed, but is version %.250s.\n",
+        if (versionsatisfied(&possi->ed->available,possi)) return 1;
+        sprintf(linebuf,"  %.250s is to be installed, but is version %.250s.\n",
                 possi->ed->name,
-                versiondescribe(possi->ed->available.version,
-                                possi->ed->available.revision));
+                versiondescribe(&possi->ed->available.version,vdew_nonambig));
         break;
       case itb_normal: case itb_preinstall:
         switch (possi->ed->status) {
         case stat_installed:
-          if (versionsatisfied(&possi->ed->installed, possi)) return 1;
-          sprintf(linebuf, "  %.250s is installed, but is version %.250s.\n",
+          if (versionsatisfied(&possi->ed->installed,possi)) return 1;
+          sprintf(linebuf,"  %.250s is installed, but is version %.250s.\n",
                   possi->ed->name,
-                  versiondescribe(possi->ed->available.version,
-                                  possi->ed->available.revision));
+                  versiondescribe(&possi->ed->installed.version,vdew_nonambig));
           break;
         case stat_notinstalled:
           /* Don't say anything about this yet - it might be a virtual package.
@@ -280,24 +258,20 @@ int depisok(struct dependency *dep, struct varbuf *whynot,
         case stat_unpacked:
         case stat_halfconfigured:
           if (allowunconfigd) {
-            if (!possi->ed->configversion || !*possi->ed->configversion) {
+            if (!informativeversion(&possi->ed->configversion)) {
               sprintf(linebuf, "  %.250s is unpacked, but has never been configured.\n",
                       possi->ed->name);
               break;
             } else if (!versionsatisfied(&possi->ed->installed, possi)) {
               sprintf(linebuf, "  %.250s is unpacked, but is version %.250s.\n",
                       possi->ed->name,
-                      versiondescribe(possi->ed->available.version,
-                                      possi->ed->available.revision));
+                      versiondescribe(&possi->ed->available.version,vdew_nonambig));
               break;
-            } else if (!versionsatisfied5(possi->ed->configversion,
-                                          possi->ed->configrevision,
-                                          possi->version, possi->revision,
-                                          possi->verrel)) {
+            } else if (!versionsatisfied3(&possi->ed->configversion,
+                                          &possi->version,possi->verrel)) {
               sprintf(linebuf, "  %.250s latest configured version is %.250s.\n",
                       possi->ed->name,
-                      versiondescribe(possi->ed->configversion,
-                                      possi->ed->configrevision));
+                      versiondescribe(&possi->ed->configversion,vdew_nonambig));
               break;
             } else {
               return 1;
@@ -396,8 +370,7 @@ int depisok(struct dependency *dep, struct varbuf *whynot,
         if (!versionsatisfied(&possi->ed->available, possi)) break;
         sprintf(linebuf, "  %.250s (version %.250s) is to be installed.\n",
                 possi->ed->name,
-                versiondescribe(possi->ed->available.version,
-                                possi->ed->available.revision));
+                versiondescribe(&possi->ed->available.version,vdew_nonambig));
         varbufaddstr(whynot, linebuf);
         if (!canfixbyremove) return 0;
         nconflicts++;
@@ -411,8 +384,7 @@ int depisok(struct dependency *dep, struct varbuf *whynot,
           if (!versionsatisfied(&possi->ed->installed, possi)) break;
           sprintf(linebuf, "  %.250s (version %.250s) is %s.\n",
                   possi->ed->name,
-                  versiondescribe(possi->ed->available.version,
-                                  possi->ed->available.revision),
+                  versiondescribe(&possi->ed->installed.version,vdew_nonambig),
                   statusstrings[possi->ed->status]);
           varbufaddstr(whynot, linebuf);
           if (!canfixbyremove) return 0;
@@ -455,8 +427,8 @@ int depisok(struct dependency *dep, struct varbuf *whynot,
         case itb_installnew:
           /* Don't pay any attention to the Provides field of the
            * currently-installed version of the package we're trying
-           * to install.  We dealt with that by using the available
-           * information above.
+           * to install.  We dealt with that package by using the
+           * available information above.
            */
           continue; 
         case itb_remove:

+ 606 - 13
main/dpkg.8

@@ -1,20 +1,613 @@
-.\" Hey, Emacs!  This is an -*- nroff -*- source file.
-.TH DPKG 8 "29th November 1995" "Debian Project" "Debian GNU/Linux"
+.TH dpkg 8
 .SH NAME
-dpkg \- Debian package installation tool
+dpkg - a low-level package manager for Debian GNU/Linux
+
+.SH SYNOPSIS
+
+.B dpkg
+[options] action
+
+.SH WARNING WARNING WARNING
+
+This manual was inaccurate when it was written and is now also out of
+date.
+
+It should
+.I not
+be used by package maintainers wishing to understand how
+.B dpkg
+will install their packages.
+
+It may be useful to users wishing to understand
+.BR "dpkg"'s
+command line options and package states in more detail than that
+provided by
+.BR "dpkg --help" .
+
+The descriptions of what
+.B dpkg
+does when installing and removing packages are particularly
+inadequate.  For detailed information about this please refer to the
+Debian Packaging Guidelines, available under
+.I guidelines
+in the GNU Info system.
+
 .SH DESCRIPTION
+
+.B dpkg
+is a medium-level tool to install, build, remove and manage Debian
+GNU/Linux packages. The primary and more user-friendly front-end
+for
 .B dpkg
-does not have a useful man page.  Please do not report this as a bug,
-as this has already been done many times.
+is
+.B dselect(8).
+.B dpkg
+itself is totally controlled via command line parameters, whose include
+one or more options and exactly one action. The action-parameter tells
+dpkg what to do and options control the behaviour of the action in some
+way.
+
+.B dpkg
+can be also be used as a front-end to
+.B dpkg-deb.
+Actions
+.B -b
+,
+.B --build
+,
+.B -c
+,
+.B --contents
+,
+.B -I
+,
+.B --info
+,
+.B -f
+,
+.B --field
+,
+.B -e
+,
+.B --control
+,
+.B -x
+,
+.B --extract
+,
+.B -X
+,
+.B --vextract
+and
+.B --fsys-tarfile
+are
+.B dpkg-deb
+actions and if they are encountered,
+.B dpkg
+just runs
+.B dpkg-deb
+with the parameters given to it. Please refer to
+.B dpkg-deb(8)
+for information about these actions.
+
+.SS ACTIONS
+
+.TP
+.B dpkg -i | --install <package file name> ...
+Install specified packages. If
+.B --recursive
+or
+.B -R
+option is specified,
+.I <package file name>
+must refer to a directory instead.
+
+Installation consists of the following steps:
+.br
+.B 1.
+Extract the controlfiles of the new package.
+.br
+.B 2.
+If another version of the same package was installed before the
+new installation, execute
+.I prerm
+script of the old package.
+.br
+.B 3.
+Run
+.I preinst
+script, if provided by the package.
+.br
+.B 4.
+Unpack the files and at the same time, backup the old files
+so that if something goes wrong, we can restore them.
+.br
+.B 5.
+If another version of the same package was installed before
+the new installation, execute the
+.I postrm
+script of the old package. Note that this script is executed after the
+.I preinst
+script of the new package, because new files are written at the same
+time, old files are removed.
+.br
+.B 6.
+eonfigure the package. See
+.B --configure
+for detailed information about how this is done.
+.TP
+.B dpkg --unpack <package file name> ...
+Unpack package, but don't configure it. If
+.B --recursive
+or
+.B -R
+option is specified,
+.I <package file name>
+must refer to a directory instead.
+.TP
+.B dpkg --configure     <package name> ... | -a|--pending
+Reconfigure an unpacked package.
+If
+.B -a
+or
+.B --pending
+is given instead of package name, all unpacked, but unconfigured
+packages are configured.
+
+Configuring consists of the following steps:
+.br
+.B 1.
+Unpack the configuration files and at the same time, backup the old
+configuration files, so that we can restore them, if
+something goes
+wrong.
+.br
+.B 2.
+Run
+.I postinst
+script, if provided by the package.
+.TP
+.B dpkg -r|--remove | --purge <package name> ... | -a|--pending
+Remove an installed package.
+.B --purge
+removes everything, including configuration files,
+.B --remove
+removes everything, but not configuration files. (configuration files are
+the files listed in
+.I conffiles
+-control file). If
+.B -a
+or
+.B --pending
+is given instead of package name all packages unpacked, but marked to be
+removed or purged are removed or purged (in file
+.I /var/lib/dpkg/status
+).
+
+Removing of a package consists of the following steps:
+.br
+.B 1.
+Run prerm script
+.br
+.B 2.
+Remove the installed files
+.br
+.B 3.
+Run postrm script
+.br
+.TP
+.B dpkg -A | --avail <package file name> ...
+Update 
+.B dpkg
+and
+.B dselect's
+idea of which packages are available with information about the package
+.I <package file name>.
+If
+.B --recursive
+or
+.B -R
+option is specified,
+.I <package file name>
+must refer to a directory instead.
+.TP
+.B dpkg --update-avail | --merge-avail <Packages-file>
+Update
+.B dpkg's
+and
+.B dselect's
+idea of which packages are available. With action 
+.B --merge-avail,
+information is combined from the old information and from the
+.I <Packages-file>.
+With action
+.B --update-avail,
+old information is replaced with the information in the
+.I <Packages-file>.
+The
+.I <Packages-file>
+distributed with Debian GNU/Linux is simply named
+.I Packages.
+.TP
+.B dpkg --yet-to-unpack
+Searches for packages selected for installation, but which for some
+reason still haven't been installed.
+.TP
+.B dpkg -l|--list [<package-name-pattern> ...]
+List packages matching given pattern. If no
+.B <package-name-pattern>
+is given, list all packages in
+.I /var/lib/dpkg/available.
+Normal shell wildchars are allowed in
+.B <package-name-pattern>.
+.TP
+.B dpkg -L|--listfiles <package-name> ...
+List files installed to your system from a package
+.B <package-name>.
+However, note that files created by package-specific
+installation-scripts are not listed.
+.TP
+.B dpkg -C|--audit
+Searches for packages that have been installed only partially on your
+system.
+.B dpkg
+will suggest what to do with them to get them working.
+.TP
+.B dpkg -S|--search <filename-search-pattern> ...
+Search for a filename from installed packages. All standard shell
+wildchars can be used in the pattern.
+.TP
+.B dpkg -s|--status <package-name> ...
+Report status of specified package. This just displays the entry in from
+the installed package status database.
+.TP
+.B dpkg --help
+Display a brief help.
+.TP
+.B dpkg --licence
+Display licence of
+.B dpkg.
+.TP
+.B dpkg --version
+Display version information.
+.TP
+.B dpkg-deb-actions
+See
+.B dpkg-deb(8)
+for more information about these actions.
+
+.B dpkg -b|--build <directory> [<filename>]
+- Build a Debian GNU/Linux package.
+.br
+.B dpkg -c|--contents <filename>
+- List contents of Debian GNU/Linux package.
+.br
+.B dpkg -e|--control <filename> [<directory>]
+- Extract control-information from a package.
+.br
+.B dpkg -x|--extract <filename> <directory>
+- Extract the files contained by package.
+.br
+.B dpkg -f|--field <filename> [<control-field>...]
+- Display control field(s) of a package.
+.br
+.B dpkg --fsys-tarfile <filename>
+- Display the filesystem tar-file contained by a Debian package.
+.br
+.B dpkg -I|--info <filename> [<control-file>]
+- Show information about a package.
+.br
+.B dpkg -X|--vextract <filename> <directory>
+- Extract and display the filenames contained by a package.
 
-Instead, if you are a competent and accurate writer and are willing to
-spend the time reading the source code and writing good manpages
-please write a better man page than this one.
+.SS OPTIONS
 
-Type
-.B dpkg \-\-help
-for a brief summary of how to use dpkg.
+.TP
+.B -B | --auto-deconfigure
+While a package is removed, there is a possibility that another
+installed package depended on the removed package. Specifying this
+option will cause automatical deconfiguration of the package which
+depended on the removed package.
+.TP
+.B -Dh | --debug=help
+Give help about debugging options.
+.TP
+.B -D<octal> | --debug=<octal>
+Set debugging on.
+.B <octal>
+is a octal number formed by bitwise-orring desired values together from
+the list below (note that these values may change in future releases).
 
+ number  description
+    1   Generally helpful progress information
+    2   Invocation and status of maintainer scripts
+   10   Output for each file processed
+  100   Lots of output for each file processed
+   20   Output for each configuration file
+  200   Lots of output for each configuration file
+   40   Dependencies and conflicts
+  400   Lots of dependencies/conflicts output
+ 1000   Lots of drivel about eg the dpkg/info dir
+ 2000   Insane amounts of drivel
+.TP
+.B --force-<things> | --no-force-<things> | --refuse-<things>
+Force or refuse (no-force and refuse stands for the same thing) to do
+some things.
+.B <things>
+is a comma separated list of things specified below:
+
+.I downgrade(*):
+Install a package, even if newer version of it is already installed.
+
+.I configure-any:
+Configure also unpacked, but unconfigured packages on whose current
+package depends on.
+
+.I remove-reinstreq:
+Remove a package, even if it's broken and marked to require
+reinstallation. This may, for example, cause parts of the package to
+remain on the system, which will then be forgotten by
+.B dpkg.
+
+.I hold:
+Don't care, wheter a package is on hold or not.
+
+.I remove-essential:
+Remove, even if the package is considered essential. Essential packages
+contains mostly very basic unix commands and such. Removing them might
+cause the whole system to stop working, so use with caution.
+
+.I conflicts:
+Install, even if it conflicts with another package. This is dangerous,
+for it will usually cause overwriting of some files.
+
+.I depends:
+Remove, even if another package depends on this one. This will usually
+break the other package.
+
+.I depends-version:
+Don't care about versions when checking depencies. This will usually
+break the other package.
+
+Things marked with (*) are forced by default.
+.I Warning:
+These options are mostly intended to be used by experts only. Using them
+without fully understanding their effects may break your whole system.
+
+.TP
+.B --ignore-depends=<package>,...
+Ignore depency-checking for specified packages (actually, checking is
+performed, but only warnings about conflicts are given, nothing else).
+.TP
+.B --largemem | --smallmem
+Tells
+.B dpkg
+wheter to preserve memory or consume it as much as needed.
+.TP
+.B --new | --old
+Select new or old package format. This is a
+.B dpkg-deb(8)
+option.
+.TP
+.B --nocheck
+Don't read or check contents of control file while building a package.
+This is a
+.B dpkg-deb(8)
+option.
+.TP
+.B --no-act
+Do everything, which is supposed to be done, but don't write any
+changes. This is used to see, what would happen with specified action,
+without actually modifying anything.
+
+Be sure to give
+.B --no-act
+before action-parameter, or you might end up with undesirable results.
+(e.g.
+.B dpkg --purge foo --no-act
+will first purge package foo and then try to purge package --no-act,
+even though you propably expected it to actually do nothing)
+.TP
+.B -R | --recursive
+Recursively handle all regular files matching pattern
+.I *.deb
+found at specified directories and all of its subdirectories. This
+can be used with 
+.B -i
+,
+.B -A
+,
+.B --install
+,
+.B --unpack
+and
+.B --avail
+actions.
+.TP
+.B -G
+Don't install package, if newer version of the same package is already
+installed. This is an alias to 
+.B--refuse-downgrade.
+.TP
+.B -R|--root=<dir> | --admindir=<dir> | --instdir=<dir>
+Change default directories.
+.B admindir
+defaults to
+.I /var/lib/dpkg
+and contains many files that give information about status of installed
+or uninstalled packages, etc.
+.B instdir
+defaults to
+.I /
+and refers to the directory where packages are to be installed.
+.B instdir
+is also the directory passed to
+.B chroot(2)
+before running package's installation scripts, which means that the
+scripts see
+.B instdir
+as a root directory.
+Changing
+.B root
+changes
+.B instdir
+to
+.I <dir>
+and
+.B admindir
+to
+.I <dir>/var/lib/dpkg.
+.TP
+.B -O | --selected-only
+Only process the packages that are selected for installation. The actual
+marking is done with
+.B dselect
+or by
+.B dpkg,
+when it handles packages. i.e. When, for example a package is removed,
+it will be marked selected for installation, etc.
+.TP
+.B -E | --skip-same-version
+Don't install the package, if the same version of the package is already
+installed.
+
+.SH INFORMATION ABOUT PACKAGES
+.B dpkg
+maintains some usable information about available packages. The
+information is divided in three classes:
+.B states
+,
+.B selection states
+and
+.B flags.
+These values are intended to be changed mainly with
+.B dselect.
+.SS PACKAGE STATES
+.TP
+.B installed
+The package is unpacked and configured ok.
+.TP
+.B half-installed
+The installation of the package has been started, but not completed for
+some reason.
+.TP
+.B not-installed
+The package is not installed on your system.
+.TP
+.B unpacked
+The package is unpacked, but not configured.
+.TP
+.B half-configured
+The package is unpacked and configuration has been started, but not yet
+completed for some reason.
+.TP
+.B config-files
+Only the configuration files of the package exist on the system.
+.SS PACKAGE SELECTION STATES
+.TP
+.B install
+The package is selected for installation.
+.TP
+.B deinstall
+The package is selected for deinstallation (i.e. we want to remove all
+files, except configuration files).
+.TP
+.B purge
+The package is selected to be purged (i.e. we want to remove everything,
+even configuration files).
+.SS PACKAGE FLAGS
+.TP
+.B hold
+A package marked to be on
+.B hold
+is not handled by
+.B dpkg,
+unless forced to do that with option
+.B --force-hold.
+.TP
+.B reinst-required
+A package marked
+.B reinst-required
+is broken and requires reinstallation. These packages cannot be removed,
+unless forced with option
+.B --force-reinstreq.
+
+.SH FILES
+The files listed here are in their default directories, see option
+.B --admindir
+to see how to change locations of these files.
+.TP
+.I /var/lib/dpkg/available
+List of available packages.
+.TP
+.I /var/lib/dpkg/status
+Statuses of available packages. This file contains information about
+wheter a package is marked for removing or not, wheter it is installed
+or not, etc. See section
+.B INFORMATION ABOUT PACKAGES
+for more info.
+.TP
+.I control
+See
+.B deb(5)
+for more information about this file.
+.TP
+.I conffiles
+.B dpkg.
+See
+.B deb(5)
+for more information about this file.
+.TP
+.I preinst
+See
+.B deb(5)
+for more information about this file.
+.TP
+.I postinst
+See
+.B deb(5)
+for more information about this file.
+.TP
+.I prerm
+See
+.B deb(5)
+for more information about this file.
+.TP
+.I postrm
+See
+.B deb(5)
+for more information about this file.
+
+.SH ENVIRONMENT VARIABLES
+.TP
+.B DPKG_NO_TSTP
+Define this to something, if you prefer
+.B dpkg
+starting a new shell rather than suspending
+.B dpkg,
+while doing a shell escape.
+.TP
+.B SHELL
+The program
+.B dpkg
+will execute while starting a new shell.
+
+.SH SEE ALSO
+.B deb(5)
+,
+.B dpkg-deb(8)
+,
+.B dselect(8)
+and
+.B deb-control(5)
+
+.SH BUGS
+
+.B --no-act
+usually gives less information that might be helpful.
 .SH AUTHOR
-Ian Jackson <ijackson@gnu.ai.mit.edu>; tarfile extraction code
-contributed by Bruce Perens <bruce@pixar.com>.
+.B dpkg
+is written by Ian Jackson (ian@chiark.chu.cam.ac.uk). Manual page added
+by Juho Vuori (javuori@cc.helsinki.fi).
+
+

+ 20 - 0
main/dpkg.8-null

@@ -0,0 +1,20 @@
+.\" Hey, Emacs!  This is an -*- nroff -*- source file.
+.TH DPKG 8 "29th November 1995" "Debian Project" "Debian GNU/Linux"
+.SH NAME
+dpkg \- Debian package installation tool
+.SH DESCRIPTION
+.B dpkg
+does not have a useful man page.  Please do not report this as a bug,
+as this has already been done many times.
+
+Instead, if you are a competent and accurate writer and are willing to
+spend the time reading the source code and writing good manpages
+please write a better man page than this one.
+
+Type
+.B dpkg \-\-help
+for a brief summary of how to use dpkg.
+
+.SH AUTHOR
+Ian Jackson <ijackson@gnu.ai.mit.edu>; tarfile extraction code
+contributed by Bruce Perens <bruce@pixar.com>.

+ 0 - 588
main/dpkg.8-vuori

@@ -1,588 +0,0 @@
-.TH dpkg 8
-.SH NAME
-dpkg - a low-level package manager for Debian GNU/Linux
-
-.SH SYNOPSIS
-
-.B dpkb
-[options] action
-
-.SH DESCRIPTION
-
-.B dpkg
-is a medium-level tool to install, build, remove and manage Debian
-GNU/Linux packages. The primary and more user-friendly front-end
-for
-.B dpkg
-is
-.B dselect(8).
-.B dpkg
-itself is totally controlled via command line parameters, whose include
-one or more options and exactly one action. The action-parameter tells
-dpkg what to do and options control the behaviour of the action in some
-way.
-
-.B dpkg
-can be also be used as a front-end to
-.B dpkg-deb.
-Actions
-.B -b
-,
-.B --build
-,
-.B -c
-,
-.B --contents
-,
-.B -I
-,
-.B --info
-,
-.B -f
-,
-.B --field
-,
-.B -e
-,
-.B --control
-,
-.B -x
-,
-.B --extract
-,
-.B -X
-,
-.B --vextract
-and
-.B --fsys-tarfile
-are
-.B dpkg-deb
-actions and if they are encountered,
-.B dpkg
-just runs
-.B dpkg-deb
-with the parameters given to it. Please refer to
-.B dpkg-deb(8)
-for information about these actions.
-
-.SS ACTIONS
-
-.TP
-.B dpkg -i | --install <package file name> ...
-Install specified packages. If
-.B --recursive
-or
-.B -R
-option is specified,
-.I <package file name>
-must refer to a directory instead.
-
-Installation consists of the following steps:
-.br
-.B 1.
-Extract the controlfiles of the new package.
-.br
-.B 2.
-If another version of the same package was installed before the
-new installation, execute
-.I prerm
-script of the old package.
-.br
-.B 3.
-Run
-.I preinst
-script, if provided by the package.
-.br
-.B 4.
-Unpack the files and at the same time, backup the old files
-so that if something goes wrong, we can restore them.
-.br
-.B 5.
-If another version of the same package was installed before
-the new installation, execute the
-.I postrm
-script of the old package. Note that this script is executed after the
-.I preinst
-script of the new package, because new files are written at the same
-time, old files are removed.
-.br
-.B 6.
-eonfigure the package. See
-.B --configure
-for detailed information about how this is done.
-.TP
-.B dpkg --unpack <package file name> ...
-Unpack package, but don't configure it. If
-.B --recursive
-or
-.B -R
-option is specified,
-.I <package file name>
-must refer to a directory instead.
-.TP
-.B dpkg --configure     <package name> ... | -a|--pending
-Reconfigure an unpacked package.
-If
-.B -a
-or
-.B --pending
-is given instead of package name, all unpacked, but unconfigured
-packages are configured.
-
-Configuring consists of the following steps:
-.br
-.B 1.
-Unpack the configuration files and at the same time, backup the old
-configuration files, so that we can restore them, if
-something goes
-wrong.
-.br
-.B 2.
-Run
-.I postinst
-script, if provided by the package.
-.TP
-.B dpkg -r|--remove | --purge <package name> ... | -a|--pending
-Remove an installed package.
-.B --purge
-removes everything, including configuration files,
-.B --remove
-removes everything, but not configuration files. (configuration files are
-the files listed in
-.I conffiles
--control file). If
-.B -a
-or
-.B --pending
-is given instead of package name all packages unpacked, but marked to be
-removed or purged are removed or purged (in file
-.I /var/lib/dpkg/status
-).
-
-Removing of a package consists of the following steps:
-.br
-.B 1.
-Run prerm script
-.br
-.B 2.
-Remove the installed files
-.br
-.B 3.
-Run postrm script
-.br
-.TP
-.B dpkg -A | --avail <package file name> ...
-Update 
-.B dpkg
-and
-.B dselect's
-idea of which packages are available with information about the package
-.I <package file name>.
-If
-.B --recursive
-or
-.B -R
-option is specified,
-.I <package file name>
-must refer to a directory instead.
-.TP
-.B dpkg --update-avail | --merge-avail <Packages-file>
-Update
-.B dpkg's
-and
-.B dselect's
-idea of which packages are available. With action 
-.B --merge-avail,
-information is combined from the old information and from the
-.I <Packages-file>.
-With action
-.B --update-avail,
-old information is replaced with the information in the
-.I <Packages-file>.
-The
-.I <Packages-file>
-distributed with Debian GNU/Linux is simply named
-.I Packages.
-.TP
-.B dpkg --yet-to-unpack
-Searches for packages selected for installation, but which for some
-reason still haven't been installed.
-.TP
-.B dpkg -l|--list [<package-name-pattern> ...]
-List packages matching given pattern. If no
-.B <package-name-pattern>
-is given, list all packages in
-.I /var/lib/dpkg/available.
-Normal shell wildchars are allowed in
-.B <package-name-pattern>.
-.TP
-.B dpkg -L|--listfiles <package-name> ...
-List files installed to your system from a package
-.B <package-name>.
-However, note that files created by package-specific
-installation-scripts are not listed.
-.TP
-.B dpkg -C|--audit
-Searches for packages that have been installed only partially on your
-system.
-.B dpkg
-will suggest what to do with them to get them working.
-.TP
-.B dpkg -S|--search <filename-search-pattern> ...
-Search for a filename from installed packages. All standard shell
-wildchars can be used in the pattern.
-.TP
-.B dpkg -s|--status <package-name> ...
-Report status of specified package. This just displays the entry in from
-the installed package status database.
-.TP
-.B dpkg --help
-Display a brief help.
-.TP
-.B dpkg --licence
-Display licence of
-.B dpkg.
-.TP
-.B dpkg --version
-Display version information.
-.TP
-.B dpkg-deb-actions
-See
-.B dpkg-deb(8)
-for more information about these actions.
-
-.B dpkg -b|--build <directory> [<filename>]
-- Build a Debian GNU/Linux package.
-.br
-.B dpkg -c|--contents <filename>
-- List contents of Debian GNU/Linux package.
-.br
-.B dpkg -e|--control <filename> [<directory>]
-- Extract control-information from a package.
-.br
-.B dpkg -x|--extract <filename> <directory>
-- Extract the files contained by package.
-.br
-.B dpkg -f|--field <filename> [<control-field>...]
-- Display control field(s) of a package.
-.br
-.B dpkg --fsys-tarfile <filename>
-- Display the filesystem tar-file contained by a Debian package.
-.br
-.B dpkg -I|--info <filename> [<control-file>]
-- Show information about a package.
-.br
-.B dpkg -X|--vextract <filename> <directory>
-- Extract and display the filenames contained by a package.
-
-.SS OPTIONS
-
-.TP
-.B -B | --auto-deconfigure
-While a package is removed, there is a possibility that another
-installed package depended on the removed package. Specifying this
-option will cause automatical deconfiguration of the package which
-depended on the removed package.
-.TP
-.B -Dh | --debug=help
-Give help about debugging options.
-.TP
-.B -D<octal> | --debug=<octal>
-Set debugging on.
-.B <octal>
-is a octal number formed by bitwise-orring desired values together from
-the list below (note that these values may change in future releases).
-
- number  description
-    1   Generally helpful progress information
-    2   Invocation and status of maintainer scripts
-   10   Output for each file processed
-  100   Lots of output for each file processed
-   20   Output for each configuration file
-  200   Lots of output for each configuration file
-   40   Dependencies and conflicts
-  400   Lots of dependencies/conflicts output
- 1000   Lots of drivel about eg the dpkg/info dir
- 2000   Insane amounts of drivel
-.TP
-.B --force-<things> | --no-force-<things> | --refuse-<things>
-Force or refuse (no-force and refuse stands for the same thing) to do
-some things.
-.B <things>
-is a comma separated list of things specified below:
-
-.I downgrade(*):
-Install a package, even if newer version of it is already installed.
-
-.I configure-any:
-Configure also unpacked, but unconfigured packages on whose current
-package depends on.
-
-.I remove-reinstreq:
-Remove a package, even if it's broken and marked to require
-reinstallation. This may, for example, cause parts of the package to
-remain on the system, which will then be forgotten by
-.B dpkg.
-
-.I hold:
-Don't care, wheter a package is on hold or not.
-
-.I remove-essential:
-Remove, even if the package is considered essential. Essential packages
-contains mostly very basic unix commands and such. Removing them might
-cause the whole system to stop working, so use with caution.
-
-.I conflicts:
-Install, even if it conflicts with another package. This is dangerous,
-for it will usually cause overwriting of some files.
-
-.I depends:
-Remove, even if another package depends on this one. This will usually
-break the other package.
-
-.I depends-version:
-Don't care about versions when checking depencies. This will usually
-break the other package.
-
-Things marked with (*) are forced by default.
-.I Warning:
-These options are mostly intended to be used by experts only. Using them
-without fully understanding their effects may break your whole system.
-
-.TP
-.B --ignore-depends=<package>,...
-Ignore depency-checking for specified packages (actually, checking is
-performed, but only warnings about conflicts are given, nothing else).
-.TP
-.B --largemem | --smallmem
-Tells
-.B dpkg
-wheter to preserve memory or consume it as much as needed.
-.TP
-.B --new | --old
-Select new or old package format. This is a
-.B dpkg-deb(8)
-option.
-.TP
-.B --nocheck
-Don't read or check contents of control file while building a package.
-This is a
-.B dpkg-deb(8)
-option.
-.TP
-.B --no-act
-Do everything, which is supposed to be done, but don't write any
-changes. This is used to see, what would happen with specified action,
-without actually modifying anything.
-
-Be sure to give
-.B --no-act
-before action-parameter, or you might end up with undesirable results.
-(e.g.
-.B dpkg --purge foo --no-act
-will first purge package foo and then try to purge package --no-act,
-even though you propably expected it to actually do nothing)
-.TP
-.B -R | --recursive
-Recursively handle all regular files matching pattern
-.I *.deb
-found at specified directories and all of its subdirectories. This
-can be used with 
-.B -i
-,
-.B -A
-,
-.B --install
-,
-.B --unpack
-and
-.B --avail
-actions.
-.TP
-.B -G
-Don't install package, if newer version of the same package is already
-installed. This is an alias to 
-.B--refuse-downgrade.
-.TP
-.B -R|--root=<dir> | --admindir=<dir> | --instdir=<dir>
-Change default directories.
-.B admindir
-defaults to
-.I /var/lib/dpkg
-and contains many files that give information about status of installed
-or uninstalled packages, etc.
-.B instdir
-defaults to
-.I /
-and refers to the directory where packages are to be installed.
-.B instdir
-is also the directory passed to
-.B chroot(2)
-before running package's installation scripts, which means that the
-scripts see
-.B instdir
-as a root directory.
-Changing
-.B root
-changes
-.B instdir
-to
-.I <dir>
-and
-.B admindir
-to
-.I <dir>/var/lib/dpkg.
-.TP
-.B -O | --selected-only
-Only process the packages that are selected for installation. The actual
-marking is done with
-.B dselect
-or by
-.B dpkg,
-when it handles packages. i.e. When, for example a package is removed,
-it will be marked selected for installation, etc.
-.TP
-.B -E | --skip-same-version
-Don't install the package, if the same version of the package is already
-installed.
-
-.SH INFORMATION ABOUT PACKAGES
-.B dpkg
-maintains some usable information about available packages. The
-information is divided in three classes:
-.B states
-,
-.B selection states
-and
-.B flags.
-These values are intended to be changed mainly with
-.B dselect.
-.SS PACKAGE STATES
-.TP
-.B installed
-The package is unpacked and configured ok.
-.TP
-.B half-installed
-The installation of the package has been started, but not completed for
-some reason.
-.TP
-.B not-installed
-The package is not installed on your system.
-.TP
-.B unpacked
-The package is unpacked, but not configured.
-.TP
-.B half-configured
-The package is unpacked and configuration has been started, but not yet
-completed for some reason.
-.TP
-.B config-files
-Only the configuration files of the package exist on the system.
-.SS PACKAGE SELECTION STATES
-.TP
-.B install
-The package is selected for installation.
-.TP
-.B deinstall
-The package is selected for deinstallation (i.e. we want to remove all
-files, except configuration files).
-.TP
-.B purge
-The package is selected to be purged (i.e. we want to remove everything,
-even configuration files).
-.SS PACKAGE FLAGS
-.TP
-.B hold
-A package marked to be on
-.B hold
-is not handled by
-.B dpkg,
-unless forced to do that with option
-.B --force-hold.
-.TP
-.B reinst-required
-A package marked
-.B reinst-required
-is broken and requires reinstallation. These packages cannot be removed,
-unless forced with option
-.B --force-reinstreq.
-
-.SH FILES
-The files listed here are in their default directories, see option
-.B --admindir
-to see how to change locations of these files.
-.TP
-.I /var/lib/dpkg/available
-List of available packages.
-.TP
-.I /var/lib/dpkg/status
-Statuses of available packages. This file contains information about
-wheter a package is marked for removing or not, wheter it is installed
-or not, etc. See section
-.B INFORMATION ABOUT PACKAGES
-for more info.
-.TP
-.I control
-See
-.B deb(5)
-for more information about this file.
-.TP
-.I conffiles
-.B dpkg.
-See
-.B deb(5)
-for more information about this file.
-.TP
-.I preinst
-See
-.B deb(5)
-for more information about this file.
-.TP
-.I postinst
-See
-.B deb(5)
-for more information about this file.
-.TP
-.I prerm
-See
-.B deb(5)
-for more information about this file.
-.TP
-.I postrm
-See
-.B deb(5)
-for more information about this file.
-
-.SH ENVIRONMENT VARIABLES
-.TP
-.B DPKG_NO_TSTP
-Define this to something, if you prefer
-.B dpkg
-starting a new shell rather than suspending
-.B dpkg,
-while doing a shell escape.
-.TP
-.B SHELL
-The program
-.B dpkg
-will execute while starting a new shell.
-
-.SH SEE ALSO
-.B deb(5)
-,
-.B dpkg-deb(8)
-,
-.B dselect(8)
-and
-.B deb-control(5)
-
-.SH BUGS
-
-.B --no-act
-usually gives less information that might be helpful.
-.SH AUTHOR
-.B dpkg
-is written by Ian Jackson (ian@chiark.chu.cam.ac.uk). Manual page added
-by Juho Vuori (javuori@cc.helsinki.fi).
-
-

+ 11 - 7
main/enquiry.c

@@ -2,7 +2,7 @@
  * dpkg - main program for package management
  * enquiry.c - status enquiry and listing options
  *
- * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
+ * Copyright (C) 1995,1996 Ian Jackson <ijackson@gnu.ai.mit.edu>
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as
@@ -73,11 +73,11 @@ Desired=Unknown/Install/Remove/Purge\n\
   if (!pkg->installed.valid) blankpackageperfile(&pkg->installed);
   limiteddescription(pkg,44,&pdesc,&l);
   printf("%c%c%c %-15.15s %-14.14s %.*s\n",
-         "uirp"[pkg->want],
+         "uihrp"[pkg->want],
          "nUFiHc"[pkg->status],
-         " hRX"[pkg->eflag],
+         " R?#"[pkg->eflag],
          pkg->name,
-         versiondescribe(pkg->installed.version,pkg->installed.revision),
+         versiondescribe(&pkg->installed.version,vdew_never),
          l, pdesc);
 }         
 
@@ -431,19 +431,23 @@ void enqperpackage(const char *const *argv) {
 }
 
 void assertsupportpredepends(const char *const *argv) {
+  static struct versionrevision predepversion = {~0UL,0,0};
   struct pkginfo *pkg;
   
   if (*argv) badusage("--assert-support-predepends does not take any arguments");
 
   modstatdb_init(admindir,msdbrw_readonly);
   pkg= findpackage("dpkg");
-
+  if (!predepversion.epoch == ~0UL) {
+    predepversion.epoch= 0;
+    predepversion.version= nfstrsave("1.1.0");
+    predepversion.revision= 0;
+  }
   switch (pkg->status) {
   case stat_installed:
     break;
   case stat_unpacked: case stat_halfconfigured:
-    if (versionsatisfied5(pkg->configversion,pkg->configrevision,
-                          "1.1.0","", dvr_laterequal))
+    if (versionsatisfied3(&pkg->configversion,&predepversion,dvr_laterequal))
       break;
     printf("Version of dpkg with Pre-Depends support not yet configured.\n"
            " Please use `dpkg --configure dpkg', and then try again.\n");

+ 1 - 1
main/errors.c

@@ -86,7 +86,7 @@ int reportbroken_retexitstatus(void) {
 }
 
 int skip_due_to_hold(struct pkginfo *pkg) {
-  if (!(pkg->eflag & eflagf_hold)) return 0;
+  if (pkg->want != want_hold) return 0;
   if (fc_hold) {
     fprintf(stderr, "Package %s was on hold, processing it anyway as you request\n",
             pkg->name);

+ 4 - 4
main/help.c

@@ -323,8 +323,8 @@ int maintainer_script_alternative(struct pkginfo *pkg,
 
   oldscriptpath= pkgadminfile(pkg,scriptname);
   arglist= buildarglist(scriptname,
-                        ifok,versiondescribe(pkg->available.version,
-                                             pkg->available.revision),
+                        ifok,versiondescribe(&pkg->available.version,
+                                             vdew_nonambig),
                         (char*)0);
   sprintf(buf,"old %s script",description);
   if (stat(oldscriptpath,&stab)) {
@@ -363,8 +363,8 @@ int maintainer_script_alternative(struct pkginfo *pkg,
   fprintf(stderr, DPKG " - trying script from the new package instead ...\n");
 
   arglist= buildarglist(scriptname,
-                        iffallback,versiondescribe(pkg->installed.version,
-                                                   pkg->installed.revision),
+                        iffallback,versiondescribe(&pkg->installed.version,
+                                                   vdew_nonambig),
                         (char*)0);
   strcpy(cidirrest,scriptname);
   sprintf(buf,"new %s script",description);

+ 10 - 5
main/main.c

@@ -41,12 +41,12 @@
 #include "main.h"
 
 static void printversion(void) {
-  if (!fputs("Debian GNU/Linux `" DPKG "' package management program version "
+  if (!fputs("Debian Linux `" DPKG "' package management program version "
               DPKG_VERSION_ARCH ".\n"
-             "Copyright 1994,1995 Ian Jackson, Bruce Perens.  This is free software;\n"
+             "Copyright 1994-1996 Ian Jackson, Bruce Perens.  This is free software;\n"
              "see the GNU General Public Licence version 2 or later for copying\n"
              "conditions.  There is NO warranty.  See dpkg --licence for details.\n",
-             stderr)) werr("stderr");
+             stdout)) werr("stdout");
 }
 
 static void usage(void) {
@@ -74,7 +74,7 @@ Options: --help --version --licence   --force-help  -Dh|--debug=help\n\
          --largemem|--smallmem   --no-act\n\
 \n\
 Use `" DSELECT "' for user-friendly package management.\n",
-             stderr)) werr("stderr");
+             stdout)) werr("stdout");
 }
 
 const char thisname[]= DPKG;
@@ -209,7 +209,7 @@ DPKG " forcing options - control behaviour when problems found:\n\
   auto-select [*]        (De)select packages to install (remove) them\n\
   dowgrade [*]           Replace a package with a lower version\n\
   configure-any          Configure any package which may help this one\n\
-  hold                   Process packages which are on hold\n\
+  hold                   Process incidental packages even when on hold\n\
   bad-path               PATH is missing important programs, problems likely\n\
   overwrite              Overwrite a file from one package with another\n\
   overwrite-diverted     Overwrite a diverted file with an undiverted version\n\
@@ -264,6 +264,7 @@ static const struct cmdinfo cmdinfos[]= {
   { "yet-to-unpack",      0,   0,  0, 0,               setaction,     act_unpackchk  },
   { "assert-support-predepends", 0, 0,  0, 0,          setaction,    act_assuppredep },
   { "print-architecture", 0,   0,  0, 0,               setaction,     act_printarch  },
+  { "print-installation-architecture", 0,0,  0,0,      setaction,  act_printinstarch },
   { "predep-package",     0,   0,  0, 0,               setaction,  act_predeppackage },
   { "pending",           'a',  0,  &f_pending,     0,  0,             1              },
   { "recursive",         'R',  0,  &f_recursive,   0,  0,             1              },
@@ -364,6 +365,10 @@ int main(int argc, const char *const *argv) {
   case act_predeppackage:
     predeppackage(argv);
     break;
+  case act_printinstarch:
+    if (printf("%s\n",architecture) == EOF) werr("stdout");
+    if (fflush(stdout)) werr("stdout");
+    break;
   case act_printarch:
     printarchitecture(argv);
     break;

+ 4 - 4
main/main.h

@@ -51,7 +51,8 @@ struct packageinlist {
 enum action { act_unset, act_install, act_unpack, act_avail, act_configure,
               act_remove, act_purge, act_list, act_avreplace, act_avmerge,
               act_unpackchk, act_status, act_search, act_audit, act_listfiles,
-              act_assuppredep, act_printarch, act_predeppackage };
+              act_assuppredep, act_printarch, act_predeppackage,
+              act_printinstarch };
 
 enum conffopt {
   cfof_prompt        =     001,
@@ -184,14 +185,13 @@ void debug(int which, const char *fmt, ...) PRINTFFORMAT(2,3);
 
 int depisok(struct dependency *dep, struct varbuf *whynot,
             struct pkginfo **fixbyrm, int allowunconfigd);
-const char *versiondescribe(const char *ver, const char *rev);
 struct cyclesofarlink;
 int findbreakcycle(struct pkginfo *pkg, struct cyclesofarlink *sofar);
 void describedepcon(struct varbuf *addto, struct dependency *dep);
 
 int versionsatisfied(struct pkginfoperfile *it, struct deppossi *against);
-int versionsatisfied5(const char *itver, const char *itrev,
-                      const char *refver, const char *refrev,
+int versionsatisfied3(const struct versionrevision *it,
+                      const struct versionrevision *ref,
                       enum depverrel verrel);
 
 #endif /* MAIN_H */

+ 3 - 5
main/packages.c

@@ -172,8 +172,6 @@ void process_queue(void) {
     
     if (!pkg) continue; /* duplicate, which we removed earlier */
 
-    if (skip_due_to_hold(pkg)) { pkg->clientdata->istobe= itb_normal; continue; }
-    
     assert(pkg->status <= stat_configfiles);
 
     if (setjmp(ejbuf)) {
@@ -280,8 +278,8 @@ static int deppossi_ok_found(struct pkginfo *possdependee,
       varbufaddstr(oemsgs,"  Version of ");
       varbufaddstr(oemsgs,possdependee->name);
       varbufaddstr(oemsgs," on system is ");
-      varbufaddstr(oemsgs,versiondescribe(possdependee->installed.version,
-                                           possdependee->installed.revision));
+      varbufaddstr(oemsgs,versiondescribe(&possdependee->installed.version,
+                                          vdew_nonambig));
       varbufaddstr(oemsgs,".\n");
       assert(checkversion->verrel != dvr_none);
       if (fc_depends) thisf= (dependtry >= 3) ? 2 : 1;
@@ -297,7 +295,7 @@ static int deppossi_ok_found(struct pkginfo *possdependee,
         possdependee->clientdata->istobe == itb_installnew) {
       debug(dbg_depcondetail,"      unpacked/halfconfigured, defer");
       return 1;
-    } else if (!removing && fc_configureany) {
+    } else if (!removing && fc_configureany && !skip_due_to_hold(possdependee)) {
       fprintf(stderr, DPKG
               ": also configuring `%s' (required by `%s')\n",
               possdependee->name, requiredby->name);

+ 25 - 29
main/processarc.c

@@ -82,7 +82,8 @@ void process_archive(const char *filename) {
   struct dirent *de;
   struct stat stab;
   struct packageinlist *deconpil, *deconpiltemp;
-
+  enum versiondisplayepochwhen needepochs;
+  
   cleanup_pkg_failed= cleanup_conflictor_failed= 0;
   admindirlen= strlen(admindir);
 
@@ -180,8 +181,6 @@ void process_archive(const char *filename) {
                 "package architecture (%s) does not match system (%s)",
                 pkg->available.architecture,architecture);
     
-  if (skip_due_to_hold(pkg)) { pop_cleanup(ehflag_normaltidy); return; }
-  
   if (!pkg->installed.valid) blankpackageperfile(&pkg->installed);
   assert(pkg->available.valid);
 
@@ -205,27 +204,28 @@ void process_archive(const char *filename) {
   }
 
   if (pkg->status == stat_installed) {
-    r= versioncompare(pkg->available.version,pkg->available.revision,
-                      pkg->installed.version,pkg->installed.revision);
+    r= versioncompare(&pkg->available.version,&pkg->installed.version);
     if (r < 0) {
+      needepochs= epochsdiffer(&pkg->available.version,&pkg->installed.version) ?
+        vdew_always : vdew_never;
       if (fc_downgrade) {
         fprintf(stderr, DPKG " - warning: downgrading %.250s from %.250s to %.250s.\n",
                 pkg->name,
-                versiondescribe(pkg->installed.version,pkg->installed.revision),
-                versiondescribe(pkg->available.version,pkg->available.revision));
+                versiondescribe(&pkg->installed.version,needepochs),
+                versiondescribe(&pkg->available.version,needepochs));
       } else {
         fprintf(stderr, "Will not downgrade"
                 " %.250s from version %.250s to %.250s, skipping.\n",
                 pkg->name,
-                versiondescribe(pkg->installed.version,pkg->installed.revision),
-                versiondescribe(pkg->available.version,pkg->available.revision));
+                versiondescribe(&pkg->installed.version,needepochs),
+                versiondescribe(&pkg->available.version,needepochs));
         pop_cleanup(ehflag_normaltidy);
         return;
       }
     } else if (r == 0 && f_skipsame && /* same version fully installed ? */
                pkg->status == stat_installed && !(pkg->eflag &= eflagf_reinstreq)) {
       fprintf(stderr, "Version %.250s of %.250s already installed, skipping.\n",
-              versiondescribe(pkg->installed.version,pkg->installed.revision),
+              versiondescribe(&pkg->installed.version,vdew_never),
               pkg->name);
       pop_cleanup(ehflag_normaltidy);
       return;
@@ -400,11 +400,11 @@ void process_archive(const char *filename) {
                    3,(void*)deconpil->pkg,(void*)conflictor,(void*)pkg);
       maintainer_script_installed(deconpil->pkg, PRERMFILE, "pre-removal",
                                   "deconfigure", "in-favour", pkg->name,
-                                  versiondescribe(pkg->available.version,
-                                                  pkg->available.revision),
+                                  versiondescribe(&pkg->available.version,
+                                                  vdew_nonambig),
                                   "removing", conflictor->name,
-                                  versiondescribe(conflictor->installed.version,
-                                                  conflictor->installed.revision),
+                                  versiondescribe(&conflictor->installed.version,
+                                                  vdew_nonambig),
                                   (char*)0);
     }
     conflictor->status= stat_halfconfigured;
@@ -413,8 +413,8 @@ void process_archive(const char *filename) {
                  2,(void*)conflictor,(void*)pkg);
     maintainer_script_installed(conflictor, PRERMFILE, "pre-removal",
                                 "remove", "in-favour", pkg->name,
-                                versiondescribe(pkg->available.version,
-                                                pkg->available.revision),
+                                versiondescribe(&pkg->available.version,
+                                                vdew_nonambig),
                                 (char*)0);
     conflictor->status= stat_halfinstalled;
     modstatdb_note(conflictor);
@@ -432,15 +432,15 @@ void process_archive(const char *filename) {
     push_cleanup(cu_preinstnew,~ehflag_normaltidy, 0,0,
                  3,(void*)pkg,(void*)cidir,(void*)cidirrest);
     maintainer_script_new(PREINSTFILE, "pre-installation", cidir, cidirrest,
-                          "install", versiondescribe(pkg->installed.version,
-                                                     pkg->installed.revision),
+                          "install", versiondescribe(&pkg->installed.version,
+                                                     vdew_nonambig),
                           (char*)0);
   } else {
     push_cleanup(cu_preinstupgrade,~ehflag_normaltidy, 0,0,
                  4,(void*)pkg,(void*)cidir,(void*)cidirrest,(void*)&oldversionstatus);
     maintainer_script_new(PREINSTFILE, "pre-installation", cidir, cidirrest,
-                          "upgrade", versiondescribe(pkg->installed.version,
-                                                     pkg->installed.revision),
+                          "upgrade", versiondescribe(&pkg->installed.version,
+                                                     vdew_nonambig),
                           (char*)0);
     printf("Unpacking replacement %.250s ...\n",pkg->name);
   }
@@ -715,10 +715,7 @@ void process_archive(const char *filename) {
       newpossi->ed= possi->ed;
       newpossi->next= 0; newpossi->nextrev= newpossi->backrev= 0;
       newpossi->verrel= possi->verrel;
-      if (possi->verrel != dvr_none) {
-        newpossi->version= possi->version;
-        newpossi->revision= possi->revision;
-      }
+      if (possi->verrel != dvr_none) newpossi->version= possi->version;
       newpossi->cyclebreak= 0;
       *newpossilastp= newpossi;
       newpossilastp= &newpossi->next;
@@ -746,7 +743,6 @@ void process_archive(const char *filename) {
   pkg->installed.source= pkg->available.source;
   pkg->installed.architecture= 0; /* This is irrelevant in the status file. */
   pkg->installed.version= pkg->available.version;
-  pkg->installed.revision= pkg->available.revision;
 
   /* We have to generate our own conffiles structure. */
   pkg->installed.conffiles= 0; iconffileslastp= &pkg->installed.conffiles;
@@ -844,8 +840,8 @@ void process_archive(const char *filename) {
     maintainer_script_installed(otherpkg, POSTRMFILE,
                                 "post-removal script (for disappearance)",
                                 "disappear", pkg->name, 
-                                versiondescribe(pkg->available.version,
-                                                pkg->available.revision),
+                                versiondescribe(&pkg->available.version,
+                                                vdew_nonambig),
                                 (char*)0);
 
     /* OK, now we delete all the stuff in the `info' directory .. */
@@ -881,8 +877,8 @@ void process_archive(const char *filename) {
 
     otherpkg->installed.depends= 0;
     otherpkg->installed.essential= 0;
-    otherpkg->installed.description= otherpkg->installed.maintainer=
-      otherpkg->installed.version= otherpkg->installed.revision= 0;
+    otherpkg->installed.description= otherpkg->installed.maintainer= 0;
+    blankversion(&otherpkg->installed.version);
     otherpkg->installed.arbs= 0;
     otherpkg->clientdata->fileslistvalid= 0;
 

+ 3 - 3
main/remove.c

@@ -323,7 +323,7 @@ void removal_bulk(struct pkginfo *pkg) {
     /* We're about to remove the configuration, so remove the note
      * about which version it was ...
      */
-    pkg->configversion= pkg->configrevision= 0;
+    blankversion(&pkg->configversion);
     modstatdb_note(pkg);
     
     /* Remove from our list any conffiles that aren't ours any more or
@@ -455,8 +455,8 @@ void removal_bulk(struct pkginfo *pkg) {
      */
     pkg->installed.depends= 0;
     pkg->installed.essential= 0;
-    pkg->installed.description= pkg->installed.maintainer=
-      pkg->installed.version= pkg->installed.revision= 0;
+    pkg->installed.description= pkg->installed.maintainer= 0;
+    blankversion(&pkg->installed.version);
     pkg->installed.arbs= 0;
   }
       

+ 8 - 6
methods/disk.setup

@@ -8,6 +8,8 @@ option=$3
 cd "$vardir/methods/disk"
 tp=/tmp/ddm$$
 
+iarch=`dpkg --print-installation-architecture`
+
 xit=1
 trap '
 	rm -f $tp.?
@@ -353,7 +355,7 @@ just answer \`none' and we'll go through the parts I need individually."
 	defhierbase=none
 	if [ -n "$p_hierbase" ]
 	then
-		if [ -d "$mountpoint/$p_hierbase/stable/binary" ]
+		if [ -d "$mountpoint/$p_hierbase/stable/binary-i386" ]
 		then
 			echo "
 Last time you said \`$p_hierbase', and that looks plausible."
@@ -364,7 +366,7 @@ Last time you said \`$p_hierbase', but that doesn't look plausible,
 since \`$p_hierbase/stable/binary' doesn't seem to exist."
 		fi
 	fi
-	if [ none = "$defhierbase" -a -d "$mountpoint/debian/stable/binary" ]
+	if [ none = "$defhierbase" -a -d "$mountpoint/debian/stable/binary-i386" ]
 	then
 		echo "
 \`/debian' exists and looks plausible, so that's the default."
@@ -381,20 +383,20 @@ since \`$p_hierbase/stable/binary' doesn't seem to exist."
 	then
 		hierbase=""
 		break
-	elif [ -d "$mountpoint/$response/stable/binary" ]
+	elif [ -d "$mountpoint/$response/stable/binary-i386" ]
 	then
 		hierbase="`echo \"$response\" | sed -e 's:/$::; s:^/*:/:'`"
 		break
 	fi
 	echo \
-"$response/stable/binary does not exist.
+"$response/stable/binary-i386 does not exist.
 "
 done
 
 whichmain=stable
 if [ -n "$hierbase" ]
 then
-	if [ -d "$mountpoint/$hierbase/development/binary" ]
+	if [ -d "$mountpoint/$hierbase/unstable/binary-$iarch" ]
 	then
 		echo \
 '
@@ -438,7 +440,7 @@ find_area () {
 	this_packages=''
 	if [ -n "$hierbase" ]
 	then
-		check_binary $1 "$hierbase/$3/binary"
+		check_binary $1 "$hierbase/$3/binary-$iarch"
 	fi
 	if [ $option = cdrom -a $2 = nf -a -z "$this_binary" ]
 	then

+ 7 - 7
split/main.c

@@ -34,12 +34,12 @@
 
 static void printversion(void) {
   if (!fputs
-      ("Debian GNU/Linux `" SPLITTER "' package archive split/join tool;\n"
-       "version " DPKG_VERSION_ARCH
-       ".  Copyright (C) 1994,1995 Ian Jackson.  This is free\n"
-       "software; see the GNU General Public Licence version 2 or later for copying\n"
-       "conditions.  There is NO warranty.  See dpkg-split --licence for details.\n",
-       stderr)) werr("stderr");
+      ("Debian Linux `" SPLITTER "' package split/join tool; "
+       "version " DPKG_VERSION_ARCH ".\n"
+       "Copyright (C) 1994-1996 Ian Jackson.  This is free software; see the\n"
+       "GNU General Public Licence version 2 or later for copying conditions.\n"
+       "There is NO warranty.  See dpkg-split --licence for details.\n",
+       stdout)) werr("stdout");
 }
 
 static void usage(void) {
@@ -60,7 +60,7 @@ Options:  --depotdir <directory>  (default is /var/lib/dpkg/parts)\n\
           --msdos                 (generate 8.3 filenames)\n\
 \n\
 Exit status: 0 = OK;  1 = -a is not a part;  2 = trouble!\n",
-             stderr)) werr("stderr");
+             stdout)) werr("stdout");
 }
 
 const char thisname[]= SPLITTER;

+ 1 - 1
version.h

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