Przeglądaj źródła

dpkg (1.3.7) unstable; urgency=low (medium for source pkg docs)

  * dselect +/-/_/= on lines for all broken, new, local or whatever
    packages do not affect _all_ packages.  (Bug#4129.)

  * Support for diff-only uploads in source packaging tools.
  * dpkg-genchanges -d<descripfile> option renamed to -C.
  * dpkg-buildpackage understands -m, -v, -C (for dpkg-genchanges).
  * Support for debian/shlibs.local added to dpkg-shlibdeps.
  * Shared library files' search order defined in dpkg-source(1), and
    relevant files added to the FILES section.

  * Programmers' manual describes source packaging tools.
  * Policy manual mentions shared library control area file.
  * dpkg-source manpage includes dpkg-shlibdeps in title line.
  * Manuals have changelog and automatic version numbering.
  * changelogs (for dpkg and for manuals) installed.
  * binary target split into binary-arch and binary-indep in manual.
  * Manpages should be compressed.
  * Copyright file is moved to /usr/doc/<package>/copyright.
  * Changelogs must be installed in /usr/doc/<package>.

  * dpkg-deb(8) moved to dpkg-deb(1).

  * binary target split into binary-arch and binary-indep in source.
  * changelog entry for 1.2.14 copied from that (forked) release.

 -- Ian Jackson <ian@chiark.chu.cam.ac.uk>  Thu, 22 Aug 1996 15:36:12 +0100
Ian Jackson 30 lat temu
rodzic
commit
cf5f3a2c92

+ 40 - 0
debian/changelog

@@ -1,3 +1,32 @@
+dpkg (1.3.7) unstable; urgency=low (medium for source pkg docs)
+
+  * dselect +/-/_/= on lines for all broken, new, local or whatever
+    packages do not affect _all_ packages.  (Bug#4129.)
+
+  * Support for diff-only uploads in source packaging tools.
+  * dpkg-genchanges -d<descripfile> option renamed to -C.
+  * dpkg-buildpackage understands -m, -v, -C (for dpkg-genchanges).
+  * Support for debian/shlibs.local added to dpkg-shlibdeps.
+  * Shared library files' search order defined in dpkg-source(1), and
+    relevant files added to the FILES section.
+
+  * Programmers' manual describes source packaging tools.
+  * Policy manual mentions shared library control area file.
+  * dpkg-source manpage includes dpkg-shlibdeps in title line.
+  * Manuals have changelog and automatic version numbering.
+  * changelogs (for dpkg and for manuals) installed.
+  * binary target split into binary-arch and binary-indep in manual.
+  * Manpages should be compressed.
+  * Copyright file is moved to /usr/doc/<package>/copyright.
+  * Changelogs must be installed in /usr/doc/<package>.
+  
+  * dpkg-deb(8) moved to dpkg-deb(1).
+
+  * binary target split into binary-arch and binary-indep in source.
+  * changelog entry for 1.2.14 copied from that (forked) release.
+
+ -- Ian Jackson <ian@chiark.chu.cam.ac.uk>  Thu, 22 Aug 1996 15:36:12 +0100
+
 dpkg (1.3.6) experimental; urgency=low (HIGH for new source format)
 
   * dpkg-source now has broken argument unparsing for tar.  (Bug#4195.)
@@ -106,6 +135,17 @@ dpkg (1.3.0) experimental; urgency=LOW
 
  -- Ian Jackson <ian@chiark.chu.cam.ac.uk>  Tue, 6 Aug 1996 02:31:52 +0100
 
+
+dpkg (1.2.14) stable unstable; urgency=MEDIUM
+
+  * dselect +/-/_/= on lines for all broken, new, local or whatever
+    packages do not affect _all_ packages.  (Bug#4129.)
+
+  * NOTE - THE HISTORY FORKS HERE.  1.2.14's change appears in 1.3.7.
+
+ -- Ian Jackson <ian@chiark.chu.cam.ac.uk>  Thu, 22 Aug 1996 00:39:52 +0100
+
+
 dpkg (1.2.13) unstable; urgency=LOW
 
   * dpkg --search produces correct output for diversions.

+ 8 - 1
debian/rules

@@ -19,7 +19,13 @@ clean:
 	-rm -f config.cache config.status config.h install config.log
 	find -name '*~' -print0 | xargs -r0 rm --
 
-binary:	checkroot build
+binary:		binary-arch binary-indep
+
+binary-indep:
+	$(checkdir)
+
+binary-arch:	checkroot build
+	$(checkdir)
 	-rm -rf debian/tmp
 	install -d debian/tmp debian/tmp/DEBIAN debian/tmp/etc/dpkg
 	install -d debian/tmp/usr/doc/{copyright,dpkg}
@@ -40,6 +46,7 @@ binary:	checkroot build
 		install
 	cp debian/copyright debian/tmp/usr/doc/copyright/dpkg
 	cp TODO debian/tmp/usr/doc/dpkg/WISHLIST
+	gzip -9v debian/tmp/usr/doc/dpkg/changelog.*
 	touch debian/tmp/var/lib/dpkg/{status,available}
 	dpkg-shlibdeps -dPre-Depends main/dpkg dselect/dselect
 	dpkg-gencontrol

+ 19 - 12
doc/Makefile.in

@@ -35,9 +35,7 @@ INSTALL_DATA = @INSTALL_DATA@
 MAKEINFO = makeinfo
 TEXI2DVI = texi2dvi
 
-DPKGDOCS= developer-keys.pgp
-
-SGMLDOCS= programmer policy
+SGMLDOCSTAMPS= programmer.html-stamp policy.html-stamp
 
 # Files folded into manuals
 OBSOLETEDOCS= descriptions.txt upgrades+errors.txt \
@@ -46,10 +44,18 @@ OBSOLETEDOCS= descriptions.txt upgrades+errors.txt \
  disappear-replace.txt diversions.text \
  essential-flag.txt version-ordering.txt
 
-all:		$(DPKGDOCS) $(SGMLDOCS)
+all:		$(DPKGDOCS) $(SGMLDOCSTAMPS)
+
+manuals-version:	changelog Makefile
+		v=`dpkg-parsechangelog -lchangelog | sed -n 's/^Version: //p'` && \
+		echo "<!entity manuals-version \"$$v\">" >$@.new
+		d=`pwd | sed -e 's,/doc$$,,; s,^.*dpkg-\([0-9.]*\),\1,'` && \
+		echo "<!entity dpkg-version \"$$d\">" >>$@.new
+		mv $@.new $@
 
-$(SGMLDOCS):
-		debiandoc2html $@.sgml
+%.html-stamp:	%.sgml manuals-version
+		rm -rf $*.html
+		debiandoc2html $<
 		touch $@
 
 guidelines.info: guidelines.texi
@@ -65,7 +71,7 @@ database-structure.monops: database-structure.ps
 		mv ps database-structure.monops
 
 clean:
-		rm -f $(SGMLDOCS)
+		rm -f $(SGMLDOCSTAMPS)
 		rm -f database-structure.ps database-structure.monops ps
 		rm -f *.{aux,cp,dvi,fn,ky,log,pg,toc,tp,vr,bak}
 		rm -f guidelines.info* *.sasp*
@@ -78,9 +84,10 @@ install:	all
 		$(INSTALL_DATA) deb.5 $(man5dir)/deb.$(man5)
 		$(INSTALL_DATA) deb-old.5 $(man5dir)/deb-old.$(man5)
 		$(INSTALL_DATA) deb-control.5 $(man5dir)/deb-control.$(man5)
-		set -e; for f in $(SGMLDOCS) ; do \
-			cp -r $$f.html $(dpkgdocdir)/$$f.html ; \
-		done
-		set -e; for d in $(DPKGDOCS) ; do \
-			$(INSTALL_DATA) $$d $(dpkgdocdir)/$$d ; \
+		set -e; for f in $(SGMLDOCSTAMPS) ; do \
+			g=`echo $$f | sed -e 's/-stamp$$//'` ; \
+			cp -r $$g $(dpkgdocdir)/$$g ; \
 		done
+		$(INSTALL_DATA) developer-keys.pgp $(dpkgdocdir)/.
+		$(INSTALL_DATA) ../debian/changelog $(dpkgdocdir)/changelog.dpkg
+		$(INSTALL_DATA) changelog $(dpkgdocdir)/changelog.manuals

+ 9 - 0
doc/changelog

@@ -0,0 +1,9 @@
+debian-manuals (0.2.0.0) experimental;
+
+  * Draft releases.
+
+ -- Ian Jackson <ian@chiark.chu.cam.ac.uk>  Wed, 21 Aug 1996 15:07:53 +0100
+
+Local variables:
+mode: debian-changelog
+End:

BIN
doc/developer-keys.pgp


+ 2 - 0
doc/manuals-version

@@ -0,0 +1,2 @@
+<!entity manuals-version "0.2.0.0">
+<!entity dpkg-version "1.3.7">

+ 259 - 14
doc/policy.sgml

@@ -1,4 +1,7 @@
-<!doctype debiandoc system>
+<!doctype debiandoc system [
+<!entity % manuals-version-def system "manuals-version">
+%manuals-version-def;
+]>
 
 <!--
  Debian Linux package policy manual.
@@ -10,7 +13,7 @@
 
 <title>Debian policy manual
 <author>Ian Jackson <email/ijackson@gnu.ai.mit.edu/
-<version>version 0.1, <date>
+<version>version &manuals-version; (dpkg &dpkg-version;), <date>
 
 <abstract>
 This manual describes the policy requirements which must be satisfied
@@ -338,7 +341,7 @@ Instructions for configuring or using the package should not be
 included - that is what installation scripts, manpages, Info files and
 <tt>/usr/doc/<var/package/</> are for.  Copyright statements and other
 administrivia should not be included - that is what
-<tt>/usr/doc/copyright</> is for.
+<tt>/usr/doc/<var/package//copyright</> is for.
 <p>
 
 If you wish to include a list in your extended with entries which are
@@ -397,7 +400,7 @@ don't consider it a bug you should leave the bug in our bug tracking
 system open anyway.
 <p>
 
-Manpages should be installed uncompressed.
+Manpages should be installed compressed using <tt/gzip -9/.
 <p>
 
 If one manpage needs to be accesssible via several names it is better
@@ -461,10 +464,11 @@ binary package to contain it, so that it does not take up disk space
 on the machines of users who do not need or want it installed.
 <p>
 
-It is often a good idea to put text information files that come with
-the source package in <tt>/usr/doc/<var/package/</> in the binary
-package.  However, don't install the instructions for building and
-installing the package, of course!
+It is often a good idea to put text information files (<tt/README/s,
+changelogs, and so forth) that come with the source package in
+<tt>/usr/doc/<var/package/</> in the binary package.  However, don't
+install the instructions for building and installing the package, of
+course!
 
 <sect1>Preferred documentation formats
 <p>
@@ -489,7 +493,23 @@ These files should not be referenced by any program - they're there
 for the benefit of the system administrator and users, as
 documentation only.
 
-<sect1 id="copyrightfile"><tt>/usr/doc/copyright/<var/package/</tt>
+<sect1 id="instchangelog"><tt>/usr/doc/<var/package//changelog.Debian.gz</tt>
+<p>
+
+This installed file must contain a copy of the <tt>debian/changelog</>
+file from your Debian source tree.
+<p>
+
+It should be installed compressed using <tt/gzip -9/, as it will
+become large with time even if it starts out small.
+<p>
+
+If the package has only one changelog which is used both as the Debian
+changelog and the upstream one because there is no separate upstream
+maintainer then the changelog should usually be installed as
+<tt>/usr/doc/<var/package//changelog.gz</> instead.
+
+<sect1 id="copyrightfile"><tt>/usr/doc/<var/package//copyright</tt>
 <p>
 
 This file must contain details of the authorship and copyright of the
@@ -508,14 +528,16 @@ Regents of the University of California at Berkeley (BSD) licence or
 Larry Wall's Artistic Licence please say so instead of including a
 copy of the licence.  The files <tt/BSD/, <tt/GPL/, <tt/LGPL/ and
 <tt/Artistic/ are be available in <tt>/usr/doc/copyright</tt> for you
-to refer to.  The package's copyright file should not be compressed.
+to refer to.
+<p>
+
+The copyright file should not be compressed unless it is very large.
 <p>
 
 Do not use the copyright file as a general <tt/README/ file.  If your
 package has such a file it should be installed in
 <tt>/usr/doc/<var/package//README</> or <tt/README.Debian/ or some
-other appropriate place.  Do not make links between
-<tt>/usr/doc/<var/package/</> and the <tt/copyright/ directory.
+other appropriate place.
 
 <sect1>Symbolic links
 <p>
@@ -841,7 +863,9 @@ the combined shared libraries package).
 <p>
 
 Follow the directions in the <prgn/dpkg/ programmers' manual for
-putting the shared library in its package.
+putting the shared library in its package, and make sure you include a
+<tt/shlibs/ control area file with details of the dependencies for
+packages which use the library.
 
 <sect>Application configuration files, dotfiles and <tt>/etc/skel</>
 <p>
@@ -1042,6 +1066,78 @@ problems.
 
 <chapt id="sourcepkg">Source package
 
+<sect>Releases of packages by other than the usual Debian maintainer
+<p>
+
+Under certain circumstances it is necessary for someone other than the
+usual package maintainer to make a release of a package.  For example,
+a porter for another architecture may have to make some small changes
+to the source package and does not wish to wait with uploading their
+release until the main maintainer has incorporated the patch, or a
+serious security problem may have come to light requiring immediate
+attention.
+<p>
+
+Maintainers other than the usual package maintainer should make as few
+changes to the package as possible, and they should always send a
+unified context diff (<tt/diff -u/) detailing their changes to the bug
+tracking system properly flagged with the correct package so that the
+usual maintainer is kept aware of the situation.
+<p>
+
+When someone other than the usual maintainer releases a package they
+should add a new component to the <var/debian-revision/ component of
+the version number - that is, the portion after the (last) hyphen.
+This extra component will start at <tt/1/.  This is to avoid
+`stealing' one of the usual maintainer's version numbers, possibly
+disrupting their work.  If there is no <var/debian-revision/ component
+in the version number then one should be created, starting at <tt/1/.
+<p>
+
+If it is absolutely necessary for someone other than the usual
+maintainer to make a release based on a new upstream version then the
+person making the release should start with the <var/debian-revision/
+value <tt/0.1/.  The usual maintainer of a package should start their
+<var/debian-revision/ numbering at <tt/1/.
+
+
+<sect>Standards conformance and <tt/Standards-Version/
+<p>
+
+You should specify the most recent version of the packaging standards
+with which your package complies in the source package's
+<tt/Standards-Version/ field.
+<p>
+
+This value will be used to file bug reports automatically if your
+package becomes too much out of date.
+<p>
+
+The value corresponds to a version of the Debian manuals, as can be
+found on the title page or page headers and footers (depending on the
+format).  The value for this version of the manuals and packaging
+standards is <tt/&manuals-version;/.
+<p>
+
+The version number has four components - major and minor number and
+major and minor patchlevel.  When the standards change in a way that
+requires every package to change the major number will be changed.
+Significant changes that will require work in many packages will be
+signaled by a change to the minor number.  The major patchlevel will
+be changed for any change to the meaning of the standards, however
+small; the minor patchlevel will be changed when only cosmetic,
+typographical or other edits which do not change the meaning are made.
+<p>
+
+You should regularly, and especially if your package has become out of
+date, install the most recent version of dpkg and read
+<tt>/usr/doc/dpkg/changelog-manuals</> to see which changes, if any,
+are relevant.  If any are relevant you should look up the relevant
+section in the policy or programmers' manuals and update your package.
+When your package complies with the new standards you may update the
+<tt/Standards-Version/ source package field and release it.
+
+
 <sect>Documentation and the <tt/changelog/
 <p>
 
@@ -1050,7 +1146,7 @@ the <tt>debian/changelog</tt> file.
 <p>
 
 A copy of the file which will be installed in
-<tt>/usr/doc/copyright/<var/package/</tt> should be in
+<tt>/usr/doc/<var/package//copyright</tt> should be in
 <tt>debian/copyright</tt>.
 <p>
 
@@ -1219,4 +1315,153 @@ see the responses.
 As ever on the net, please trim down the quoting of articles you're
 replying to.
 
+
+<chapt id="conversion">Conversion procedure from old source packages
+<p>
+
+This is a brief summary of the procedure for converting a
+pre-2.0.0.0-format source package into the new format.
+<p>
+
+You are strongly advised to download and examine the <prgn/hello/
+package, and to read the section in the <prgn/dpkg/ programmers'
+manual describing the source packaging tools.  More detail about the
+exact functionality of these tools is available in <manref
+name=dpkg-source section=1>.
+<p>
+
+<list>
+
+<item>
+Download the original source code from wherever it can be found and do
+any rearrangement required to make it look like the original tree of
+the Debian source.  Put it in
+<tt><var/package/-<var/upstream-version/.orig/</> or
+<tt/<var/package/_<var/upstream-version/.orig.tar.gz/.
+
+<item>
+Rename all files <tt/debian.*/ to <tt>debian/*</>.  There may be some
+exceptions to this, but this is a good start.
+
+<item>
+Edit the <tt>debian/changelog</> - create or rename it if necessary.
+Add a new revision to the top with the appropriate details, and a
+local variables entry to the bottom to set Emacs to the right mode:
+<example>
+Local variables:
+mode: debian-changelog
+End:
+</example>
+
+<item>
+Edit/create <tt>debian/control</>:
+<list compact>
+<item>
+Remove the <tt/Version/ field.  If it is generated unusually (not
+equal to the source version) you must use the -v option to
+dpkg-gencontrol (see below).  <tt/Section/, <tt/Priority/,
+<tt/Maintainer/ go above the first blank line, most of the rest below.
+
+<item>
+Reorder the fields and add a blank line at an appropriate point,
+separating the source package fields from the binary package
+fields.
+
+<item>
+Add the <tt/Source/ field.
+
+<item>
+Add the <tt/Standards-Version/ field.  The current value is
+<tt/&manuals-version;/.
+
+<item>
+Change the <tt/Architecture/ field for each package to <tt/any/,
+<tt/all/ or whatever.  If there isn't an <tt/Architecture/ field add
+one.
+
+<item>
+If any other seddery or things used to happen to make the binary
+control files use <prgn/dpkg-gencontrol/'s variable substitution
+features to achieve the same effect.  Use <tt>debian/substvars</> if
+you need to put unusally-generated information (apart from details of
+<tt/.deb/ files) in the <tt/.changes/ file too.
+</list>
+
+<item>
+Edit the <tt>debian/rules</>:
+<list compact>
+<item>
+Remove the <prgn/source/ and <prgn/diff/ and any <prgn/changes/ and
+<prgn/dist/ targets.  These things now happen in a package-independent
+way and are not done by <tt>debian/rules</>.
+<item>
+Split the <prgn/binary/ target into <prgn/binary-arch/ and
+<prgn/binary-indep/; in many cases all of <prgn/binary/ should go into
+<prgn/binary-arch/.  Create the <prgn/binary/ target and the unused of
+the two other <prgn/binary-*/ targets if there is one - you can copy
+the ones from the <prgn/hello/ package.
+<item>
+Change the <prgn/binary/ target to use <prgn/dpkg-gencontrol/ to make
+the package control file(s).  Move it to after all the files have been
+installed but just before the last <prgn/chown/ and <prgn/chmod/ in
+the target.
+<item>
+Change occurrences of <tt/debian-tmp/ to <tt>debian/tmp</>.
+<item>
+Change occurrences of <tt/debian.{post,pre}{inst,rm}/ to
+<tt>debian/*</>.
+<item>
+Remove the version number setting at the top, if there is one.
+<item>
+Ensure that the package's Debian-specific and upstream changelogs are
+installed.
+</list>
+
+<item>
+Check that the <tt>debian/README</> is really the copyright file, and
+if so rename it to <tt>debian/copyright</> and edit
+<tt>debian/rules</> to cope with this and to change the installation
+of the copyright file from <tt>/usr/doc/<var/package//copyright</>
+instead of <tt>/usr/doc/copyright/<var/package/</>.  If it isn't then
+find <tt>debian/copyright</> and decide what to do with the
+<tt>README</>.
+
+<item>
+Check for various other anachronisms and problems:
+<list compact>
+<item>
+Remove any <tt/Package_Revision/, <tt/Package-Revision/ or
+<tt/Revision/ fields.
+<item>
+Rename <tt/Optional/ to <tt/Suggests/, <tt/Recommended/ to
+<tt/Recommends/.
+<item>
+Change <tt>/usr/doc/examples/<var/package/</> to
+<tt>/usr/doc/<var/package//examples</>.
+<item>
+Make sure that manpages are installed compressed.
+<item>
+Check that the description has an extended description, is
+well-formatted and meaningful and helpful to people wanting to know
+whether to install a package.
+</list>
+
+<item>
+Look everything over.
+
+<item>
+Do a test build using <tt/dpkg-buildpackage -ur -uc -r<var/whatever//.
+Check the permissions and locations of files in the resulting package
+by eyeballing the output of <tt/dpkg-deb --contents/, and check that
+the source build happened OK.  Test install the binary package(s) and
+test extract the source package(s).
+
+<item>
+Sign the release: either re-run <prgn/dpkg-buildpackage/ (this will
+rebuild the package entirely), or PGP-sign the <tt/.dsc/, rebuild the
+<tt/.changes/ using <prgn/dpkg-genchanges/, and then PGP-sign the
+<tt/.changes/.
+
+</list>
+
 </book>

Plik diff jest za duży
+ 1329 - 0
doc/policy.text


+ 307 - 23
doc/programmer.sgml

@@ -1,4 +1,7 @@
-<!doctype debiandoc system>
+<!doctype debiandoc system [
+<!entity % manuals-version-def system "manuals-version">
+%manuals-version-def;
+]>
 
 <!--
  Debian Linux dpkg package installation tool.
@@ -11,7 +14,7 @@
 
 <title><prgn/dpkg/ programmers' manual
 <author>Ian Jackson <email/ijackson@gnu.ai.mit.edu/
-<version><date>
+<version>version &manuals-version; (dpkg &dpkg-version;), <date>
 
 <abstract>
 This manual describes the technical aspects of creating Debian binary
@@ -217,6 +220,11 @@ This is the key description file used by <prgn/dpkg/.  It specifies the
 package's name and version, gives its description for the user, states
 its relationships with other packages, and so forth.
 See <ref id="controlfile">.
+<p>
+
+It is usually generated automatically from information in the source
+package by the <prgn/dpkg-gencontrol/ program, and with assistance
+from <prgn/dpkg-shlibdeps/.  See <ref id="sourcetools">.
 
 <tag><tt/postinst/, <tt/preinst/, <tt/postrm/, <tt/prerm/
 <item>
@@ -350,14 +358,250 @@ fields is available in <ref id="controlfields">.
 The Debian binary packages in the distribution are generated from
 Debian sources, which are in a special format to assist the easy and
 automatic building of binaries.
+
+<sect id="sourcetools">Tools for processing source packages
+<p>
+
+Various tools are provided for manipulating source packages; they pack
+and unpack sources and help build of binary packages and help manage
+the distribution of new versions.
+<p>
+
+They are introduced and typical uses described here; see <manref
+name=dpkg-source section=1> for full documentation about their
+arguments and operation.
+<p>
+
+For examples of how to construct a Debian source package, and how to
+use those utilities that are used by Debian source packages, please
+see the <prgn/hello/ example package.
+
+<sect1><prgn/dpkg-source/ - packs and unpacks Debian source packages
+<p>
+
+This program is frequently used by hand, and is also called from
+package-independent automated building scripts such as
+<prgn/dpkg-buildpackage/.
+<p>
+
+To unpack a package it is typically invoked with
+<example>
+dpkg-source -x <var>.../path/to/filename</>.dsc
+</example>
+with the <tt/<var/filename/.tar.gz/ and
+<tt/<var/filename/.diff.gz/ (if applicable) in the same directory.  It
+unpacks into <tt/<var/package/-<var/version//, and if applicable
+<tt/<var/package/-<var/version/.orig/, in the current directory.
+<p>
+
+To create a packed source archive it is typically invoked:
+<example>
+dpkg-source -b <var/package/-<var/version/
+</example>
+This will create the <tt/.dsc/, <tt/.tar.gz/ and <tt/.diff.gz/ (if
+appropriate) in the current directory.  <prgn/dpkg-source/ does not
+clean the source tree first - this must be done separately if it is
+required.
+<p>
+
+See also <ref id="sourcearchives">.
+
+
+<sect1><prgn/dpkg-buildpackage/ - overall package-building control
+script
+<p>
+
+<prgn/dpkg-buildpackage/ is a script which invokes <prgn/dpkg-source/,
+the <tt>debian/rules</> targets <prgn/clean/, <prgn/build/ and
+<prgn/binary/, <prgn/dpkg-genchanges/ and <prgn/pgp/ to build a signed
+source and binary package upload.
+<p>
+
+It is usually invoked by hand from the top level of the built or
+unbuilt source directory.  It may be invoked with no arguments; useful
+arguments include:
+<taglist compact>
+<tag><tt/-uc/, <tt/-us/
+<item>Do not PGP-sign the <tt/.changes/ file or the source package
+<tt/.dsc/ file, respectively.
+
+<tag><tt/-p<var/pgp-command//
+<item>Invoke <var/pgp-command/ instead of finding <tt/pgp/ on the
+<prgn/PATH/.  <var/pgp-command/ must behave just like <prgn/pgp/.
+
+<tag><tt/-r<var/root-command//
+<item>When root privilege is required, invoke the command
+<var/root-command/.  <var/root-command/ should invoke its first
+argument as a command, from the <prgn/PATH/ if necessary, and pass its
+second and subsequent arguments to the command it calls.  If no
+<var/root-command/ is supplied then <var/dpkg-buildpackage/ will take
+no special action to gain root privilege, so that for most packages it
+will have to be invoked as root to start with.
+
+<tag><tt/-b/, <tt/-B/
+<item>Two types of binary-only build and upload - see <manref
+name=dpkg-source section=1>.
+</taglist>
+
+
+<sect1><prgn/dpkg-gencontrol/ - generates binary package control files
+<p>
+
+This program is usually called from <tt>debian/rules</> (see <ref
+id="sourcetree">) in the top level of the source tree.
+<p>
+
+This is usually done just before the files and directories in the
+temporary directory tree where the package is being built have their
+permissions and ownerships set and the package is constructed using
+<prgn/dpkg-deb/<footnote>This is so that the control file which is
+produced has the right permissions</footnote>.
+<p>
+
+<prgn/dpkg-gencontrol/ must be called after all the files which are to
+go into the package have been placed in the temporary build directory,
+so that its calculation of the installed size of a package is correct.
 <p>
 
-Tools are provided for manipulating source packages; they pack and
-unpack sources and help build of binary packages and help manage the
-distribution of new versions.  See <manref name=dpkg-source section=1>
-for details.
+It is also necessary for <prgn/dpkg-gencontrol/ to be run after
+<prgn/dpkg-shlibdeps/ so that the variable substitutions created by
+<prgn/dpkg-shlibdeps/ in <tt>debian/substvars</> are available.
+<p>
+
+For a package which generates only one binary package, and which
+builds it in <tt>debian/tmp</> relative to the top of the source
+package, it is usually sufficient to call:
+<example>
+dpkg-gencontrol
+</example>
+<p>
+
+Sources which build several binaries will typically need something
+like:
+<example>
+dpkg-gencontrol -Pdebian/tmp-<var/pkg/ -p<var/package/
+</example>
+The <tt/-P/ tells <prgn/dpkg-gencontrol/ that the package is being
+built in a non-default directory, and the <tt/-p/ tells it which
+package's control file should be generated.
+<p>
+
+<prgn/dpkg-gencontrol/ also adds information to the list of files in
+<tt>debian/files</>, for the benefit of (for example) a future
+invocation of <prgn/dpkg-genchanges/.
+
+
+<sect1><prgn/dpkg-shlibdeps/ - calculates shared library dependencies
+<p>
 
-<sect>The Debianised source tree
+This program is usually called from <tt>debian/rules</> just before
+<prgn/dpkg-gencontrol/ (see <ref id="sourcetree">), in the top level
+of the source tree.
+<p>
+
+Its arguments are executables<footnote>They may be specified either
+in the locations in the source tree where they are created or in the
+locations in the temporary build tree where they are installed prior
+to binary package creation.</footnote> for which shared library
+dependencies should be included in the binary package's control file.
+<p>
+
+If some of the executable(s) shared libraries should only warrant a
+<tt/Recommends/ or <tt/Suggests/, or if some warrant a
+<tt/Pre-Depends/, this can be achieved by using the
+<tt/-d<var/dependency-field// option before those executable(s).
+(Each <tt/-d/ option takes effect until the next <tt/-d/.)
+<p>
+
+<prgn/dpkg-shlibdeps/ does not directly cause the output control file
+to be modified.  Instead by default it adds to the
+<tt>debian/substvars</> file variable settings like
+<tt/shlibs:Depends/.  These variable settings must be referenced in
+dependency fields in the appropriate per-binary-package sections of
+the source control file.
+<p>
+
+For example, the <prgn/procps/ package generates two kinds of
+binaries, simple C binaries like <prgn/ps/ which require a
+predependency and full-screen ncurses binaries like <prgn/top/ which
+require only a recommendation.  It can say in its <tt>debian/rules</>:
+<example>
+dpkg-shlibdeps -dPre-Depends ps -dRecommends top
+</example>
+and then in its main control file <tt>debian/control</>:
+<example>
+<var/.../
+Package: procps
+Pre-Depends: ${shlibs:Pre-Depends}
+Recommends: ${shlibs:Recommends}
+<var/.../
+</example>
+<p>
+
+Sources which produce several binary packages with different shared
+library dependency requirements can use the <tt/-p<var/varnameprefix//
+option to override the default <tt/shlib:/ prefix (one invocation of
+<prgn/dpkg-shlibdeps/ per setting of this option).  They can thus
+produce several sets of dependency variables, each of the form
+<tt/<var/varnameprefix/:<var/dependencyfield//, which can be referred
+to in the appropriate parts of the binary package control files.
+
+
+<sect1><prgn/dpkg-distaddfile/ - adds a file to <tt>debian/files</>
+<p>
+
+Some packages' uploads need to include files other than the source and
+binary package files.
+<p>
+
+<prgn/dpkg-distaddfile/ adds a file to the <tt>debian/files</> file so
+that it will be included in the <tt/.changes/ file when
+<prgn/dpkg-genchanges/ is run.
+<p>
+
+It is usually invoked from the <prgn/binary/ target of
+<tt>debian/rules</>:
+<example>
+dpkg-distaddfile <var/filename/ <var/section/ <var/priority/
+</example>
+The <var/filename/ is relative to the directory where
+<prgn/dpkg-genchanges/ will expect to find it - this is usually the
+directory above the top level of the source tree.  The
+<tt>debian/rules</> target should put the file there just before or
+just after calling <prgn/dpkg-distaddfile/.
+<p>
+
+The <var/section/ and <var/priority/ are passed unchanged into the
+resulting <tt/.changes/ file.  See <ref id="f-classification">.
+
+
+<sect1><prgn/dpkg-genchanges/ - generates a <tt/.changes/ upload
+control file
+<p>
+
+This program is usually called by package-independent automatic
+building scripts such as <prgn/dpkg-buildpackage/, but it may also be
+called by hand.
+<p>
+
+It is usually called in the top level of a built source tree, and when
+invoked with no arguments will print out a straightforward
+<tt/.changes/ file based on the information in the source package's
+changelog and control file and the binary and source packages which
+should have been built.
+
+
+<sect1><prgn/dpkg-parsechangelog/ - produces parsed representation of
+a changelog
+<p>
+
+This program is used internally by <prgn/dpkg-source/ et al.  It may
+also occasionally be useful in <tt>debian/rules</> and elsewhere.  It
+parses a changelog, <tt>debian/changelog</> by default, and prints a
+control-file format representation of the information in it to
+standard output.
+
+<sect id="sourcetree">The Debianised source tree
 <p>
 
 The source archive scheme described later is intended to allow a
@@ -421,21 +665,37 @@ run <prgn/clean/ first, it is a good idea to <tt/touch build/ when the
 build process is complete.  This will ensure that if <tt>debian/rules
 build</tt> is run again it will not rebuild the whole program.
 
-<tag/<tt/binary//
+<tag/<tt/binary/, <tt/binary-arch/, <tt/binary-indep/
 <item>
 
-This target should be all that is necessary for the user to build the
-binary package.  It should depend on the <prgn/build/ target, above,
-so that the package is built if it has not been already.  It should
-then create the binary package(s), using <prgn/dpkg-gencontrol/ to
-make their control files and <prgn/dpkg-deb/ to build them and place
-them in the parent of the top level directory.
+The <prgn/binary/ target should be all that is necessary for the user
+to build the binary package.  It is split into two parts:
+<prgn/binary-arch/ builds the packages' output files which are
+specific to a particular architecture, and <prgn/binary-indep/
+builds those which are not.
+<p>
+
+<prgn/binary/ should usually be a target with no commands which simply
+depends on <prgn/binary-arch/ and <prgn/binary-indep/.
+<p>
+
+Both <prgn/binary-*/ targets should depend on the <prgn/build/ target,
+above, so that the package is built if it has not been already.  It
+should then create the relevant binary package(s), using
+<prgn/dpkg-gencontrol/ to make their control files and <prgn/dpkg-deb/
+to build them and place them in the parent of the top level directory.
+<p>
+
+If one of the <prgn/binary-*/ targets has nothing to do (this will be
+always be the case if the source generates only a single binary
+package, whether architecture-dependent or not) it <em/must/ still
+exist, but should always succeed.
 <p>
 
 <ref id="binarypkg"> describes how to construct binary packages.
 <p>
 
-The <prgn/binary/ target must be invoked as root.
+The <prgn/binary/ targets must be invoked as root.
 
 <tag/<tt/clean//
 <item>
@@ -1218,10 +1478,11 @@ separated by spaces.
 <p>
 
 In the <tt/.dsc/ (Debian source control) file each line contains the
-MD5 checksum, size and filename of the tarfile and (optionally) diff
-file which make up the remainder of the source package.<footnote>That
-is, the parts which are not the <tt/.dsc/.</footnote> The exact forms
-of the filenames are described in <ref id="sourcearchives">.
+MD5 checksum, size and filename of the tarfile and (if applicable)
+diff file which make up the remainder of the source
+package.<footnote>That is, the parts which are not the
+<tt/.dsc/.</footnote> The exact forms of the filenames are described
+in <ref id="sourcearchives">.
 <p>
 
 In the <tt/.changes/ file this contains one line per file being
@@ -1233,10 +1494,20 @@ id="f-classification">.  If no section or priority is specified then
 specified for new packages to be installed properly.
 <p>
 
-The special value <tt/byhand/ for the section indicates that the file
-in question is not an ordinary package file and must by installed by
-hand by the distribution maintainers.  If the section is <tt/byhand/
-the priority should be <tt/-/.
+The special value <tt/byhand/ for the section in a <tt/.changes/ file
+indicates that the file in question is not an ordinary package file
+and must by installed by hand by the distribution maintainers.  If the
+section is <tt/byhand/ the priority should be <tt/-/.
+<p>
+
+If a new Debian revision of a package is being shipped and no new
+original source archive is being distributed the <tt/.dsc/ must still
+contain the <tt/Files/ field entry for the original source archive
+<tt/<var/package/-<var/upstream-version/.orig.tar.gz/, but the
+<tt/.changes/ file should leave it out.  In this case the original
+source archive on the distribution site must match exactly,
+byte-for-byte, the original source archive which was used to generate
+the <tt/.dsc/ file and diff which are being uploaded.
 
 
 <sect1 id="f-Standards-Version"><tt/Standards-Version/
@@ -1252,6 +1523,7 @@ package needs attention.
 Its format is the same as that of a version number except that no
 epoch or Debian revision is allowed - see <ref id="versions">.
 
+
 <sect1 id="f-Distribution"><tt/Distribution/
 <p>
 
@@ -2222,6 +2494,18 @@ version clause in the <tt/Pre-Depends/ field.
 
 </taglist>
 
+<sect1>Dependencies on shared libraries
+<p>
+
+The dependency fields listed above are used by packages which need
+shared libraries to declare dependencies on the appropriate packages.
+<p>
+
+These dependencies are usually determined automatically using
+<prgn/dpkg-shlibdeps/ and inserted in the package control file using
+the control file substitution variables mechanism; see <ref
+id="srcsubstvars"> and <ref id="sourcetools">.
+
 <sect1>Deconfiguration due to removal during bulk installations
 <p>
 

+ 3 - 3
dpkg-deb/Makefile.in

@@ -23,8 +23,8 @@ exec_prefix = $(prefix)
 bindir = $(exec_prefix)/bin
 libdir = $(prefix)/lib
 mandir = $(prefix)/man
-man8dir = $(mandir)/man8
-man8 = 8
+man1dir = $(mandir)/man1
+man1 = 1
 
 SRC = main.c build.c extract.c info.c
 OBJ = main.o build.o extract.o info.o
@@ -63,4 +63,4 @@ distclean:	clean
 
 install:	all
 		$(INSTALL_PROGRAM) -s dpkg-deb $(bindir)/dpkg-deb
-		$(INSTALL_DATA) dpkg-deb.8 $(man8dir)/dpkg-deb.$(man8)
+		$(INSTALL_DATA) dpkg-deb.1 $(man1dir)/dpkg-deb.$(man1)

dpkg-deb/dpkg-deb.8 → dpkg-deb/dpkg-deb.1


+ 15 - 2
dselect/pkgcmds.cc

@@ -33,7 +33,19 @@ extern "C" {
 #include "dselect.h"
 #include "pkglist.h"
 
-static int matches(struct pkginfo *pkg, struct pkginfo *comparewith) {
+int packagelist::affectedmatches(struct pkginfo *pkg, struct pkginfo *comparewith) {
+  switch (statsortorder) {
+  case sso_avail:
+    if (comparewith->clientdata->ssavail != pkg->clientdata->ssavail) return 0;
+    break;
+  case sso_state:
+    if (comparewith->clientdata->ssstate != pkg->clientdata->ssstate) return 0;
+    break;
+  case sso_unsorted:
+    break;
+  default:
+    internerr("unknown statsortorder in affectedmatches");
+  }
   if (comparewith->priority != pkginfo::pri_unset &&
       (comparewith->priority != pkg->priority ||
        comparewith->priority == pkginfo::pri_other &&
@@ -60,7 +72,8 @@ void packagelist::affectedrange(int *startp, int *endp) {
     return;
   }
   *startp= index;
-  while (index < nitems && matches(table[index]->pkg,table[cursorline]->pkg)) index++;
+  while (index < nitems && affectedmatches(table[index]->pkg,table[cursorline]->pkg))
+    index++;
   *endp= index;
 }
 

+ 1 - 0
dselect/pkglist.h

@@ -160,6 +160,7 @@ class packagelist : public baselist {
   void addheading(enum ssavailval, enum ssstateval,
                   pkginfo::pkgpriority, const char*, const char *section);
   void sortinplace();
+  int affectedmatches(struct pkginfo *pkg, struct pkginfo *comparewith);
   void affectedrange(int *startp, int *endp);
   void setwant(pkginfo::pkgwant nw);
   void sethold(int hold);

+ 33 - 11
scripts/dpkg-buildpackage.sh

@@ -12,13 +12,19 @@ Ian Jackson.  This is free software; see the GNU General Public Licence
 version 2 or later for copying conditions.  There is NO warranty.
 
 Usage: dpkg-buildpackage [options]
-Options:  -r<gain-root-command>
-          -p<pgp-command>
-          -b         (binary-only)
-          -B         (binary-only, no arch-indep files)
-          -us        (unsigned source)
-          -uc        (unsigned changes)
-          -h         print this message
+Options: -r<gain-root-command>
+         -p<pgp-command>
+         -us           unsigned source
+         -uc           unsigned changes
+         -b            binary-only, do not build source } also passed to
+         -B            binary-only, no arch-indep files } dpkg-genchanges
+         -v<version>   changes since version <version>      }
+         -m<maint>     maintainer for release is <maint>    } only passed
+         -C<descfile>  changes are described in <descfile>  }  to dpkg-
+         -si (default) src includes orig for rev. 0 or 1    } genchanges
+         -sa           uploaded src includes orig (default) }
+         -sd           uploaded src is diff and .dsc only   }
+         -h            print this message
 END
 }
 
@@ -26,6 +32,11 @@ rootcommand=''
 pgpcommand=pgp
 signsource=signfile
 signchanges=signfile
+binarytarget=binary
+sourcestyle=''
+version=''
+maint=''
+desc=''
 
 while [ $# != 0 ]
 do
@@ -36,7 +47,13 @@ do
 	-p*)	pgpcommand="$value" ;;
 	-us)	signsource=: ;;
 	-uc)	signchanges=: ;;
-	-b|-B)	binaryonly=$1 ;;
+	-sa)	sourcestyle='' ;;
+	-sd)	sourcestyle=-sd ;;
+	-b)	binaryonly=-b ;;
+	-B)	binaryonly=-b; binarytarget=binary-arch ;;
+	-v*)	version="$value" ;;
+	-m*)	maint="$value" ;;
+	-C*)	descfile="$value" ;;
 	*)	echo >&2 "$progname: unknown option or argument $1"
 		usageversion; exit 2 ;;
 	esac
@@ -66,14 +83,19 @@ signfile () {
 	mv -- "../$1.asc" "../$1"
 }
 
-set -x -e
+set -- $binaryonly
+if [ -n "$maint"	]; then set -- "$@" "-m$maint"		; fi
+if [ -n "$version"	]; then set -- "$@" "-v$version"	; fi
+if [ -n "$desc"		]; then set -- "$@" "-C$desc"		; fi
+
+set -x
 
 $rootcommand debian/rules clean
 if [ x$binaryonly = x ]; then
 	cd ..; dpkg-source -b "$dirn"; cd "$dirn"
 fi
 debian/rules build
-$rootcommand debian/rules binary
+$rootcommand debian/rules $binarytarget
 $signsource "$pv.dsc"
-dpkg-genchanges $binaryonly >../"$pva.changes"
+dpkg-genchanges $binaryonly $sourcestyle >../"$pva.changes"
 $signchanges "$pva.changes"

+ 17 - 10
scripts/dpkg-genchanges.pl

@@ -8,6 +8,7 @@ $changelogfile= 'debian/changelog';
 $fileslistfile= 'debian/files';
 $varlistfile= 'debian/substvars';
 $uploadfilesdir= '..';
+$sourcestyle= 'i';
 
 use POSIX;
 use POSIX qw(:errno_h :signal_h);
@@ -23,15 +24,17 @@ version 2 or later for copying conditions.  There is NO warranty.
 
 Usage: dpkg-genchanges [options ...]
 
-Options:  -b                     binary-only build - no source files
-          -B                     architecture-only build - no src or \`all'
+Options:  -b or -B (identical)   binary-only build - no source files
           -c<controlfile>        get control info from this file
           -l<changelogfile>      get per-version info from this file
           -f<fileslistfile>      get .deb files list from this file
           -v<sinceversion>       include all changes later than version
-          -d<changesdescription> use change description from this file
+          -C<changesdescription> use change description from this file
           -m<maintainer>         override changelog's maintainer value
-          -u<uploadfilesdir>     directory with files (default is \`..'
+          -u<uploadfilesdir>     directory with files (default is \`..')
+          -si (default)          src includes orig for debian-revision 0 or 1
+          -sa                    source includes orig src
+          -sd                    source is diff and .dsc only
           -F<changelogformat>    force change log format
           -V<name>=<value>       set a substitution variable
           -T<varlistfile>        read variables here, not debian/substvars
@@ -47,15 +50,15 @@ $i=100;grep($fieldimps{$_}=$i--,
 
 while (@ARGV) {
     $_=shift(@ARGV);
-    if (m/^-b$/) {
+    if (m/^-b$|^-B$/) {
         $binaryonly= 1;
-    } elsif (m/^-B$/) {
-        $binaryonly= 2;
+    } elsif (m/^-s([iad])$/) {
+        $sourcestyle= $1;
     } elsif (m/^-c/) {
         $controlfile= $';
     } elsif (m/^-l/) {
         $changelogfile= $';
-    } elsif (m/^-d/) {
+    } elsif (m/^-C/) {
         $changesdescription= $';
     } elsif (m/^-f/) {
         $fileslistfile= $';
@@ -96,7 +99,6 @@ while(<FL>) {
             &warn("duplicate files list entry for file $1 (line $.)");
         $f2sec{$1}= $5;
         $f2pri{$1}= $6;
-        next if $4 eq 'all' && $binaryonly>=2;
         push(@fileslistfiles,$1);
     } elsif (m/^([-+.,_0-9a-zA-Z]+) (\S+) (\S+)$/) {
         defined($f2sec{$1}) &&
@@ -135,7 +137,6 @@ for $_ (keys %fi) {
         } elsif (s/^X[BS]*C[BS]*-//i) {
             $f{$_}= $v;
         } elsif (m/^Architecture$/) {
-            next if $v eq 'all' && $binaryonly>=2;
             $v= $arch if $v eq 'any';
             push(@archvalues,$v) unless $archadded{$v}++;
         } elsif (m/^(Package|Essential|Pre-Depends|Depends|Provides)$/ ||
@@ -208,6 +209,12 @@ if (!$binaryonly) {
         push(@sourcefiles,$file);
     }
     for $f (@sourcefiles) { $f2sec{$f}= $sec; $f2pri{$f}= $pri; }
+    
+    if (($sourcestyle =~ m/i/ && $version !~ m/-[01]$/ ||
+         $sourcestyle =~ m/d/) &&
+        grep(m/\.diff\.gz$/,@sourcefiles)) {
+        @sourcefiles= grep(!m/\.orig\.tar\.gz$/,@sourcefiles);
+    }
 }
 
 $f{'Format'}= $substvar{'Format'};

+ 11 - 6
scripts/dpkg-shlibdeps.pl

@@ -8,6 +8,7 @@ use POSIX qw(:errno_h :signal_h);
 
 $shlibsoverride= '/etc/dpkg/shlibs.override';
 $shlibsdefault= '/etc/dpkg/shlibs.default';
+$shlibslocal= 'debian/shlibs.local';
 $shlibsppdir= '/var/lib/dpkg/info';
 $shlibsppext= '.shlibs';
 $varnameprefix= 'shlibs';
@@ -28,13 +29,14 @@ version 2 or later for copying conditions.  There is NO warranty.
 Usage:
   dpkg-shlibdeps [<option> ...] <executable>|-e<executable> [<option>] ...
 Positional arguments/options (order is significant):
-          <executable>           } include dependencies for <executable>
-          -e<executable>         }  (use -e if <executable> starts with \`-')
-          -d<dependencyfield>    next executable(s) set shlibs:<dependencyfield>
+       <executable>           } include dependencies for <executable>
+       -e<executable>         }  (use -e if <executable> starts with \`-')
+       -d<dependencyfield>    next executable(s) set shlibs:<dependencyfield>
 Overall options (have global effect no matter where placed):
-          -p<varnameprefix>      set <varnameprefix>:* instead of shlibs:*.
-          -O                     print variable settings to stdout
-          -T<varlistfile>        update variables here, not debian/substvars
+       -p<varnameprefix>      set <varnameprefix>:* instead of shlibs:*.
+       -O                     print variable settings to stdout
+       -L<localshlibsfile>    shlibs override file, not debian/shlibs.local
+       -T<varlistfile>        update variables here, not debian/substvars
 Dependency fields recognised are ".join("/",@depfields)."
 ";
 }
@@ -47,6 +49,8 @@ while (@ARGV) {
         $varlistfile= $';
     } elsif (m/^-p(\w[-:0-9A-Za-z]*)$/) {
         $varnameprefix= $1;
+    } elsif (m/^-L/) {
+        $shlibslocal= $';
     } elsif (m/^-O$/) {
         $stdout= 1;
     } elsif (m/^-h$/) {
@@ -102,6 +106,7 @@ while (<P>) {
 close(P); $? && subprocerr("dpkg --search");
 
 for ($i=0;$i<=$#libname;$i++) {
+    scanshlibsfile($shlibslocal,$libname[$i],$libsoname[$i],$libf[$i]) && next;
     scanshlibsfile($shlibsoverride,$libname[$i],$libsoname[$i],$libf[$i]) && next;
     if (!defined($pathpackages{$libpath[$i]})) {
         &warn("could not find any packages for $libpath[$i]".

+ 192 - 21
scripts/dpkg-source.1

@@ -2,7 +2,7 @@
 .\" Authors: Ian Jackson
 .TH DPKG\-SOURCE 1 "7th Auguest" "Debian Project" "Debian GNU/Linux manual"
 .SH NAME 
-dpkg\-source, dpkg\-gencontrol, dpkg\-genchanges,
+dpkg\-source, dpkg\-gencontrol, dpkg\-shlibdeps, dpkg\-genchanges,
 dpkg\-buildpackage, dpkg\-distaddfile, dpkg\-parsechangelog
 \- Debian source package tools
 .SH SYNOPSIS
@@ -51,6 +51,19 @@ where
 is a dependency field name.  Any other variables starting
 .I shlibs:
 are removed from the file.
+.B dpkg-shlibdeps
+will read shared library dependency information from
+.BR debian/shlibs.local ,
+.BR /etc/dpkg/shlibs.override ,
+the
+.B shlibs
+control area file of the package containing the file which
+.B ldd
+reports as satisfying the library dependency, or
+.BR /etc/dpkg/shlibs.default .
+The first match will be used.  See the
+.I dpkg programmers' manual
+for details of the format of shared library dependency files.
 
 .B dpkg-genchanges
 reads information from an unpacked and built Debian source tree and
@@ -85,7 +98,7 @@ by all the source package tools.
 .TP
 .BI -v version
 In
-.BR dpkg-genchanges " and " dpkg-parsechangelog
+.BR dpkg-buildpackage ", " dpkg-genchanges " and " dpkg-parsechangelog
 this causes changelog information from all versions strictly later
 than
 .I version
@@ -96,6 +109,42 @@ In
 it sets the version number of the binary package which will be
 generated.
 .TP
+.BI -C changesdescription
+Read the description of the changes from the file
+.I changesdescription
+rather than using the information from the source tree's changelog
+file.  This is understood by
+.BR dpkg-buildpackage " and " dpkg-genchanges .
+.TP
+.BI -m maintaineraddress
+Use
+.I maintaineraddress
+as the name and email address of the maintainer for this upload,
+rather than using the information from the source tree's changelog.
+This is understood by
+.BR dpkg-buildpackage " and " dpkg-genchanges .
+.TP
+.BR -si ", " -sa ", " -sd
+These options control whether the original source archive is included
+in the upload generated by
+.BR dpkg-buildpackage " and " dpkg-genchanges
+if any source is being generated (ie,
+.BR -b " or " -B
+haven't been used).
+
+By default, or if
+.B -si
+is specified, the original source will be included if the version
+number ends in
+.BR -0 " or " -1 ,
+ie if the Debian revision part of the version number is
+.BR 0 " or " 1 .
+
+.B -sa
+forces the inclusion of the original source;
+.B -sd
+forces its exclusion and includes only the diff.
+.TP
 .BI -V name = value
 Set an output substitution variable.
 This option is understood by
@@ -130,7 +179,16 @@ this specifies that a binary-only build is taking place.
 indicates that no source files are to be built and/or distributed, and
 .B -B
 that no architecture-independent binary package files are to be
-distributed either.
+distributed either.  The distinction between
+.BR -b " and " -B
+is only used by
+.BR dpkg-buildpackage ;
+.B dpkg-genchanges
+just produces a
+.B .changes
+file for whatever files were produced by the
+.B binary-*
+target(s) of the package being built.
 
 .B -b
 tells
@@ -167,6 +225,10 @@ the standard format described in the
 This option is understood by
 .BR dpkg-source ", " dpkg-gencontrol " and " dpkg-genchanges .
 .SH DPKG-SOURCE OPTIONS
+When the common options
+.BR -c " and " -l
+are given with relative pathnames these are interpreted starting at
+the source tree's top level directory.
 .TP
 .B -x
 Extract a source package.  One non-option argument should be supplied,
@@ -184,14 +246,116 @@ the
 Build: pack up a source tree.  One or two non-option arguments should
 be supplied.  The first is taken as the name of the directory
 containing the unpacked source tree.  If a second argument is supplied
-it should either be the name of the original source directory or the
-empty string if the package is a Debian-specific one and so has no
+it should be the name of the original source directory or tarfile or
+the empty string if the package is a Debian-specific one and so has no
 Debianisation diffs.  If no second argument is supplied then
 .B dpkg-source
-will assume the directory
+will look for the original source tarfile
+.IB package _ upstream-version .orig.tar.gz
+or the original source directory
 .IB directory .orig
-if exists or the empty string (no original source, and so no diff) if
-it doesn't.
+or the empty string (no original source, and so no diff) depending on
+the arguments.
+.TP
+.BR -sa , -sp , -su , -sk , -sA , -sP , -sU , -sK , -ss " with " -b
+If
+.BR -sk " or " -sp
+is specified
+.B dpkg-source
+expects the original source as a tarfile, by default
+.IB package _ upstream-version .orig.tar.gz\fR.
+It will leave this original source in place as a tarfile, or copy it
+to the current directory if it isn't already there
+If
+.B -sp
+is used rather than
+.B -sk
+it will remove it again afterwards.
+
+If
+.BR -su " or " -sr
+is specified the original source is expected as a directory, by
+default
+.IB package - upstream-version .orig
+and
+.B dpkg-source
+will create a new original source archive from it.  If
+.B -sr
+is used
+.B dpkg-source will remove that directory after it has been used.
+
+If
+.B -ss
+is specified
+.B dpkg-source
+will expect that the original source is available both as a directory
+and as a tarfile.  If will use the directory to create the diff, but
+the tarfile to create the
+.BR .dsc .
+This option must be used with care - if the directory and tarfile do
+not match a bad source archive will be generated.
+
+If
+.B -sn
+is specified
+.B dpkg-source
+will not look for any original source, and will not generate a diff.
+The second argument, if supplied, must be the empty string.  This is
+used for Debian-specific packages which do not have a separate
+upstream source and therefore have no debianisation diffs.
+
+If
+.BR -sa " or " -sA
+is specified
+.B dpkg-source
+will look for the original source archive as a tarfile or as a
+directory - the second argument, if any, may be either, or the empty
+string (this is equivalent to using
+.BR -sn ).
+If a tarfile is found it will unpack it to create the diff and remove
+it afterwards (this is equivalent to
+.BR -sp );
+if a directory is found it will pack it to create the original source
+and remove it afterwards (this is equivalent to
+.BR -sr );
+if neither is found it will assume that the package has no
+debianisation diffs, only a straightforward source archive (this is
+equivalent to
+.BR -sn ).
+If both are found then dpkg-source will ignore the directory,
+overwriting it, if
+.B -sA
+was specified (this is equivalent to
+.BR -sP )
+or raise an error if
+.B -sa
+was specified.
+.B -sA
+is the default.
+
+.BR -sa ", " -sp ", " -sk ", " -su " and "  -sr
+will not overwrite existing tarfiles or directories.  If this is
+desired then
+.BR -sA ", " -sP ", " -sK ", " -su " and "  -sR
+should be used instead.
+.TP
+.BR -sp , -su , -sn " with " -x
+In all cases any existing original source tree will be removed.
+
+If
+.B -sp
+is used when extracting then the original source (if any) will be left
+as a tarfile.  If it is not already located in the current directory
+or if an existing but different file is there it will be copied there.
+This is the default.
+
+.B -su
+unpacks the original source tree.
+
+.B -sn
+ensures that the original source is neither copied to the current
+directory nor unpacked.  Any original source tree that was in the
+current directory is still removed.
 .SH DPKG-GENCONTROL OPTIONS
 .B dpkg-gencontrol
 does not take any non-option arguments.
@@ -282,6 +446,14 @@ Likewise, any existing substitution variables starting with
 .BR shlib: )
 are removed from the the substitution variables file.
 .TP
+.BI -L localshlibsfile
+Causes
+.B dpkg-shlibs
+to read overriding shared library dependency information from
+.I localshlibsfile
+instead of
+.BR debian/shlibs.local .
+.TP
 .B -O
 Causes the substitution variable settings to be printed to standard
 output, rather than being added to the substitution variables file
@@ -291,18 +463,6 @@ by default).
 .B dpkg-gencontrol
 does not take any non-option arguments.
 .TP
-.BI -d changesdescription
-Read the description of the changes from the file
-.I changesdescription
-rather than using the information from the source tree's changelog
-file.
-.TP
-.BI -m maintaineraddress
-Use
-.I maintaineraddress
-as the name and email address of the maintainer for this upload,
-rather than using the information from the source tree's changelog.
-.TP
 .BI -u uploadfilesdir
 Look for the files to be uploaded in
 .I uploadfilesdir
@@ -491,6 +651,15 @@ file.
 .TP
 .B debian/substvars
 List of substitution variables and values.
+.TP
+.B debian/shlibs.local
+Package-local overriding shared library dependency information.
+.TP
+.B /etc/dpkg/shlibs.override
+Per-system overriding shared library dependency information.
+.TP
+.B /etc/dpkg/shlibs.default
+Per-system default shared library dependency information.
 .SH BUGS
 The point at which field overriding occurs compared to certain
 standard output field settings is rather confused.
@@ -503,8 +672,10 @@ not matter, since
 are not legal in package names or version numbers.
 .SH SEE ALSO
 .IR "dpkg programmers' manual" ,
+.br
 .IR "Debian policy manual" ,
-.BR dpkg\-deb (8),
+.br
+.BR dpkg\-deb (1),
 .BR dpkg (8),
 .BR dselect (8).
 .SH AUTHOR

+ 289 - 143
scripts/dpkg-source.pl

@@ -1,11 +1,13 @@
 #!/usr/bin/perl
 
-use POSIX;
-use POSIX qw(:errno_h :signal_h);
-
 $dpkglibdir= ".";
 $version= '1.3.0'; # This line modified by Makefile
 
+$sourcestyle= 'X';
+
+use POSIX;
+use POSIX qw(:errno_h :signal_h);
+
 push(@INC,$dpkglibdir);
 require 'controllib.pl';
 
@@ -15,21 +17,27 @@ sub usageversion {
 Ian Jackson.  This is free software; see the GNU General Public Licence
 version 2 or later for copying conditions.  There is NO warranty.
 
-Usage:
-  dpkg-source -x <filename>.dsc
-  dpkg-source -b <directory> [<orig-directory>|\'\']
-Options:  -c<controlfile>        get control info from this file\n".
-"(for -b)  -l<changelogfile>      get per-version info from this file
-          -F<changelogformat>    force change log format
-          -V<name>=<value>       set a substitution variable
-          -T<varlistfile>        read variables here, not debian/substvars
-          -D<field>=<value>      override or add a .dsc field and value
-          -U<field>              remove a field
-          -h                     print this message
-Relative filenames for -c and -l are interpreted starting at the
-source tree's top level directory.  If <orig-directory> is omitted then
-it defaults to <directory>.orig if that exists or to \'\' (indicating a
-Debian-special package without a diff) if <directory>.orig doesn\`t.
+Usage:  dpkg-source -x <filename>.dsc
+        dpkg-source -b <directory> [<orig-directory>|<orig-targz>|\'\']
+Build options:   -c<controlfile>     get control info from this file
+                 -l<changelogfile>   get per-version info from this file
+                 -F<changelogformat> force change log format
+                 -V<name>=<value>    set a substitution variable
+                 -T<varlistfile>     read variables here, not debian/substvars
+                 -D<field>=<value>   override or add a .dsc field and value
+                 -U<field>           remove a field
+                 -sa                 auto select orig source (-sA is default)
+                 -sk                 use packed orig source (unpack & keep)
+                 -sp                 use packed orig source (unpack & remove)
+                 -su                 use unpacked orig source (pack & keep)
+                 -sr                 use unpacked orig source (pack & remove)
+                 -ss                 trust packed & unpacked orig src are same
+                 -sn                 there is no diff, do main tarfile only
+                 -sA,-sK,-sP,-sU,-sR like -sa,-sp,-sk,-su,-sr but may overwrite
+Extract options: -sp (default)       leave orig source packed in current dir
+                 -sn                 do not copy original source to current dir
+                 -su                 unpack original source tree too
+General options: -h                  print this message
 ";
 }
 
@@ -42,6 +50,8 @@ while (@ARGV && $ARGV[0] =~ m/^-/) {
         &setopmode('build');
     } elsif (m/^-x$/) {
         &setopmode('extract');
+    } elsif (m/^-s([akpursnAKPUR])$/) {
+        $sourcestyle= $1;
     } elsif (m/^-c/) {
         $controlfile= $';
     } elsif (m/^-l/) {
@@ -69,30 +79,17 @@ defined($opmode) || &usageerr("need -x or -b");
 
 if ($opmode eq 'build') {
 
+    $sourcestyle =~ y/X/A/;
+    $sourcestyle =~ m/[akpursnAKPUR]/ ||
+        &usageerr("source handling style -s$sourcestyle not allowed with -b");
+
     @ARGV || &usageerr("-b needs a directory");
-    @ARGV<=2 || &usageerr("-b takes at most a directory and an orig directory");
+    @ARGV<=2 || &usageerr("-b takes at most a directory and an orig source argument");
     $dir= shift(@ARGV);
-    $dir= "./$dir" unless $dir =~ m:^/:;
+    $dir= "./$dir" unless $dir =~ m:^/:; $dir =~ s,/*$,,;
     stat($dir) || &error("cannot stat directory $dir: $!");
     -d $dir || &error("directory argument $dir is not a directory");
 
-    if (@ARGV) {
-        $origdir= shift(@ARGV);
-        if (length($origdir)) {
-            $origdir= "./$origdir" unless $origdir =~ m:^/:;
-            stat($origdir) || &error("cannot find orig directory $origdir: $!");
-            -d $origdir || &error("orig directory argument $origdir is not a directory");
-        }
-    } elsif (!stat("$dir.orig")) {
-        $! == ENOENT || &error("cannot stat tentative orig dir $dir.orig: $!");
-        $origdir= '';
-    } elsif (-d _) {
-        $origdir= "$dir.orig";
-    } else {
-        &error("tentative orig directory $dir.orig is not a directory");
-    }
-print STDERR ">$dir|$origdir<\n";
-
     $changelogfile= "$dir/debian/changelog" unless defined($changelogfile);
     $controlfile= "$dir/debian/control" unless defined($controlfile);
     
@@ -176,53 +173,156 @@ print STDERR ">$dir|$origdir<\n";
     $f{'Source'}= $sourcepackage;
     for $f (keys %remove) { delete $f{&capit($f)}; }
 
-    $version= $f{'Version'}; $version =~ s/^\d+://;
-    $basenamerev= $basename= $sourcepackage.'_'.$version;
-    $basename =~ s/-[^_]+$//;
+    $version= $f{'Version'};
+    $version =~ s/^\d+://; $upstreamversion= $version; $upstreamversion =~ s/-[^-]*$//;
+    $basenamerev= $sourcepackage.'_'.$version;
+    $basename= $sourcepackage.'_'.$upstreamversion;
     $basedirname= $basename;
 #print STDERR ">$basedirname<\n";
     $basedirname =~ s/_/-/;
 #print STDERR ">$basedirname<\n";
 
+    $origdir= "$dir.orig";
+    $origtargz= "$basename.orig.tar.gz";
+    if (@ARGV) {
+        $origarg= shift(@ARGV);
+        if (length($origarg)) {
+            stat($origarg) || &error("cannot stat orig argument $origarg: $!");
+            if (-d _) {
+                $origdir= $origarg;
+                $origdir= "./$origdir" unless $origdir =~ m,^/,; $origdir =~ s,/*$,,;
+                $sourcestyle =~ y/aA/rR/;
+                $sourcestyle =~ m/[ursURS]/ ||
+                    &error("orig argument is unpacked but source handling style".
+                           " -s$sourcestyle calls for packed (.orig.tar.gz)");
+            } elsif (-f _) {
+                $origtargz= $origarg;
+                $sourcestyle =~ y/aA/pP/;
+                $sourcestyle =~ m/[kpsKPS]/ ||
+                    &error("orig argument is packed but source handling style".
+                           " -s$sourcestyle calls for unpacked (.orig/)");
+            } else {
+                &error("orig argument $origarg is not a plain file or directory");
+            }
+        } else {
+            $sourcestyle =~ y/aA/nn/;
+            $sourcestyle =~ m/n/ ||
+                &error("orig argument is empty (means no orig, no diff)".
+                       " but source handling style -s$sourcestyle wants something");
+        }
+    }
+
+    if ($sourcestyle =~ m/[aA]/) {
+        if (stat("$origtargz")) {
+            -f _ || &error("packed orig \`$origtargz' exists but is not a plain file");
+            $sourcestyle =~ y/aA/pP/;
+        } elsif ($! != ENOENT) {
+            &syserr("unable to stat putative packed orig \`$origtargz'");
+        } elsif (stat("$origdir")) {
+            -d _ || &error("unpacked orig \`$origdir' exists but is not a directory");
+            $sourcestyle =~ y/aA/rR/;
+        } elsif ($! != ENOENT) {
+            &syserr("unable to stat putative unpacked orig \`$origdir'");
+        } else {
+            $sourcestyle =~ y/aA/nn/;
+        }
+    }
     $dirbase= $dir; $dirbase =~ s,/?$,,; $dirbase =~ s,[^/]+$,,; $dirname= $&;
-    if (length($origdir)) {
+    $dirname eq $basedirname || &warn("source directory \`$dir' is not <sourcepackage>".
+                                      "-<upstreamversion> \`$basedirname'");
+    
+    if ($sourcestyle ne 'n') {
         $origdirbase= $origdir; $origdirbase =~ s,/?$,,;
         $origdirbase =~ s,[^/]+$,,; $origdirname= $&;
 
         $origdirname eq "$basedirname.orig" ||
-            &warn(".orig directory name $origdirname is not package-origversion".
-                  " (wanted $basedirname.orig)");
+            &warn(".orig directory name $origdirname is not <package>".
+                  "-<upstreamversion> (wanted $basedirname.orig)");
         $tardirbase= $origdirbase; $tardirname= $origdirname;
-        $tarname= "$basename.orig.tar.gz";
+
+        $tarname= $origtargz;
+        $tarname eq "$basename.orig.tar.gz" ||
+            &warn(".orig.tar.gz name $tarname is not <package>-<upstreamversion>".
+                  ".orig.tar.gz (wanted $basename.orig.tar.gz)");
     } else {
         $tardirbase= $dirbase; $tardirname= $dirname;
         $tarname= "$basename.tar.gz";
     }
 
-    print("$progname: building $sourcepackage in $tarname\n")
-        || &syserr("write building tar message");
-    &forkgzipwrite($tarname);
-    defined($c2= fork) || &syserr("fork for tar");
-    if (!$c2) {
-        chdir($tardirbase) || &syserr("chdir to above (orig) source $tardirbase");
-        open(STDOUT,">&GZIP") || &syserr("reopen gzip for tar");
-        # FIXME: put `--' argument back when tar is fixed
-        exec('tar','-cO',$tardirname); &syserr("exec tar");
+#print STDERR ">$dir|$origdir|$origtargz|$sourcestyle<\n";
+
+    if ($sourcestyle =~ m/[nurUR]/) {
+
+        if (stat($tarname)) {
+            $sourcestyle =~ m/[nUR]/ ||
+                &error("tarfile \`$tarname' already exists, not overwriting,".
+                       " giving up; use -sU or -sR to override");
+        } elsif ($! != ENOENT) {
+            &syserr("unable to check for existence of \`$tarname'");
+        }
+
+#print STDERR ">$tarname|$tardirbase|$tardirname<\n";
+    
+        print("$progname: building $sourcepackage in $tarname\n")
+            || &syserr("write building tar message");
+        &forkgzipwrite("$tarname.new");
+        defined($c2= fork) || &syserr("fork for tar");
+        if (!$c2) {
+            chdir($tardirbase) || &syserr("chdir to above (orig) source $tardirbase");
+#system('pwd && ls');
+            open(STDOUT,">&GZIP") || &syserr("reopen gzip for tar");
+            # FIXME: put `--' argument back when tar is fixed
+            exec('tar','-cO',$tardirname); &syserr("exec tar");
+        }
+        close(GZIP);
+        &reapgzip;
+        $c2 == waitpid($c2,0) || &syserr("wait for tar");
+        $? && !(WIFSIGNALED($c2) && WTERMSIG($c2) == SIGPIPE) && subprocerr("tar");
+        rename("$tarname.new",$tarname) ||
+            &syserr("unable to rename \`$tarname.new' (newly created) to \`$tarname'");
+
+    } else {
+        
+        print("$progname: building $sourcepackage using existing $tarname\n")
+            || &syserr("write using existing tar message");
+        
     }
-    close(GZIP);
-    &reapgzip;
-    $c2 == waitpid($c2,0) || &syserr("wait for tar");
-    $? && !(WIFSIGNALED($c2) && WTERMSIG($c2) == SIGPIPE) && subprocerr("tar");
+    
     addfile("$tarname");
 
-    if (length($origdir)) {
+    if ($sourcestyle =~ m/[kpKP]/) {
+
+        if (stat($origdir)) {
+            $sourcestyle =~ m/[KP]/ ||
+                &error("orig dir \`$origdir' already exists, not overwriting,".
+                       " giving up; use -sA, -sK or -sP to override");
+            erasedir($origdir);
+        } elsif ($! != ENOENT) {
+            &syserr("unable to check for existence of orig dir \`$origdir'");
+        }
+
+        $expectprefix= $origdir; $expectprefix =~ s,^\./,,;
+        checktarsane($origtargz,$expectprefix);
+        mkdir("$origtargz.tmp-nest",0755) ||
+            &syserr("unable to create \`$origdirtargz.tmp-nest'");
+        extracttar($origtargz,"$origtargz.tmp-nest");
+        rename("$origtargz.tmp-nest/$expectprefix",$expectprefix) ||
+            &syserr("unable to rename \`$origtargz.tmp-nest/$expectprefix' to ".
+                    "\`$expectprefix'");
+        rmdir("$origtargz.tmp-nest") ||
+            &syserr("unable to remove \`$origdirtargz.tmp-nest'");
+
+    }
+        
+    if ($sourcestyle =~ m/[kpursKPUR]/) {
+        
         print("$progname: building $sourcepackage in $basenamerev.diff.gz\n")
             || &syserr("write building diff message");
         &forkgzipwrite("$basenamerev.diff.gz");
 
         defined($c2= open(FIND,"-|")) || &syserr("fork for find");
         if (!$c2) {
-            chdir($dirname) || &syserr("chdir to $dirname for find");
+            chdir($dir) || &syserr("chdir to $dir for find");
             exec('find','.','-print0'); &syserr("exec find");
         }
         $/= "\0";
@@ -268,7 +368,7 @@ print STDERR ">$dir|$origdir<\n";
                         $difflinefound=1;
                     } else {
                         s/\n$//;
-                        &internerr("unknown line from diff -u on $dirname/$fn: \`$_'");
+                        &internerr("unknown line from diff -u on $dir/$fn: \`$_'");
                     }
                     print(GZIP $_) || &syserr("failed to write to gzip");
                 }
@@ -278,7 +378,7 @@ print STDERR ">$dir|$origdir<\n";
                         &unrepdiff("diff gave 1 but no diff lines found");
                     }
                 } else {
-                    subprocerr("diff on $dirname/$fn");
+                    subprocerr("diff on $dir/$fn");
                 }
             } elsif (-p _) {
                 $type{$fn}= 'pipe';
@@ -291,13 +391,13 @@ print STDERR ">$dir|$origdir<\n";
                 &unrepdiff("unknown file type ($!)");
             }
         }
-        close(FIND); $? && subprocerr("find on $dirname");
+        close(FIND); $? && subprocerr("find on $dir");
         close(GZIP) || &syserr("finish write to gzip pipe");
         &reapgzip;
 
         defined($c2= open(FIND,"-|")) || &syserr("fork for 2nd find");
         if (!$c2) {
-            chdir($origdirname) || &syserr("chdir to $origdirname for 2nd find");
+            chdir($origdir) || &syserr("chdir to $origdir for 2nd find");
             exec('find','.','-print0'); &syserr("exec 2nd find");
         }
         $/= "\0";
@@ -318,6 +418,11 @@ print STDERR ">$dir|$origdir<\n";
         close(FIND); $? && subprocerr("find on $dirname");
 
         &addfile("$basenamerev.diff.gz");
+
+    }
+
+    if ($sourcestyle =~ m/[prPR]/) {
+        erasedir($origdir);
     }
 
     print("$progname: building $sourcepackage in $basenamerev.dsc\n")
@@ -334,6 +439,10 @@ print STDERR ">$dir|$origdir<\n";
 
 } else {
 
+    $sourcestyle =~ y/X/p/;
+    $sourcestyle =~ m/[pun]/ ||
+        &usageerr("source handling style -s$sourcestyle not allowed with -b");
+
     @ARGV==1 || &usageerr("-x needs exactly one argument, the .dsc");
     $dsc= shift(@ARGV);
     $dsc= "./$dsc" unless $dsc =~ m:^/:;
@@ -381,72 +490,7 @@ print STDERR ">$dir|$origdir<\n";
     checkstats($tarfile);
     checkstats($difffile) if length($difffile);
 
-    &forkgzipread("$dscdir/$tarfile");
-    defined($c2= open(CPIO,"-|")) || &syserr("fork for cpio");
-    if (!$c2) {
-        open(STDIN,"<&GZIP") || &syserr("reopen gzip for cpio");
-        &cpiostderr;
-        exec('cpio','-0t'); &syserr("exec cpio");
-    }
-    $/= "\0";
-    close(GZIP);
-  file:
-    while (defined($fn= <CPIO>)) {
-        $fn =~ s/\0$//; $pname= $fn; $pname =~ y/ -~/?/c;
-        $fn =~ m/\n/ &&
-            &error("tarfile contains object with newline in its name ($pname)");
-        $slash= substr($fn,length($expectprefix),1);
-        (($slash eq '/' || $slash eq '') &&
-         substr($fn,0,length($expectprefix)) eq $expectprefix) ||
-             &error("tarfile contains object ($pname) not in expected directory".
-                    " ($expectprefix)");
-        $fn =~ m,/\.\./, &&
-            &error("tarfile contains object with /../ in its name ($pname)");
-        push(@filesinarchive,$fn);
-    }
-    close(CPIO); $? && subprocerr("cpio");
-    $/= "\n";
-    &reapgzip;
-
-    &forkgzipread("$dscdir/$tarfile");
-    defined($c2= open(TAR,"-|")) || &syserr("fork for tar -t");
-    if (!$c2) {
-        $ENV{'LANG'}= 'C';
-        open(STDIN,"<&GZIP") || &syserr("reopen gzip for tar -t");
-        exec('tar','-vvtf','-'); &syserr("exec tar -vvtf -");
-    }
-    close(GZIP);
-    $efix= 0;
-  file:
-    while (length($_= <TAR>)) {
-        s/\n$//;
-        m,^(\S{10})\s, ||
-            &error("tarfile contains unknown object listed by tar as \`$_'");
-        $fn= $filesinarchive[$efix++]; $mode= $1;
-        if ($mode =~ m/^l/) { $_ =~ s/ -\> .*//; }
-        substr($_,length($_)-length($fn)-1) eq " $fn" ||
-            &error("tarfile contains unexpected object listed by tar as \`$_',".
-                   " expected \`$fn'");
-        $mode =~ s/^([-dpsl])// ||
-            &error("tarfile contains object \`$fn' with unknown or forbidden type \`".
-                   substr($_,0,1)."'");
-        $fn =~ m/\.dpkg-orig$/ &&
-            &error("tarfile contains file with name ending .dpkg-orig");
-        $type= $&;
-        $mode =~ m/[sStT]/ && $type ne 'd' &&
-            &error("tarfile contains setuid, setgid or sticky object \`$fn'");
-        $fn eq "$expectprefix/debian" && $type ne 'd' &&
-            &error("tarfile contains object `debian' that isn't a directory");
-        $fn =~ s,/$,, if $type eq 'd';
-        $dirname= $fn;
-        $dirname =~ s,/[^/]+$,, && !defined($dirincluded{$dirname}) &&
-            &error("tarfile contains object \`$fn' but its containing ".
-                   "directory \`$dirname' does not precede it");
-        $dirincluded{$fn}= 1 if $type eq 'd';
-        $notfileobject{$fn}= 1 if $type ne '-';
-    }
-    close(TAR); $? && subprocerr("tar -t");
-    &reapgzip;
+    checktarsane("$dscdir/$tarfile",$expectprefix);
 
     if (length($difffile)) {
         if (!$dirincluded{"$expectprefix/debian"}) {
@@ -483,20 +527,39 @@ print STDERR ">$dir|$origdir<\n";
         &reapgzip;
     }
 
-    print("$progname: extracting $sourcepackage in $newdirectory".
-          ($difffile ? " and $expectprefix" : '')."\n")
+    print("$progname: extracting $sourcepackage in $newdirectory\n")
         || &syserr("write extracting message");
     
     &erasedir($newdirectory);
     &erasedir("$newdirectory.orig");
 
-    &extracttar;
+    extracttar("$dscdir/$tarfile",'.');
     
     if (length($difffile)) {
         rename($expectprefix,$newdirectory) ||
             &syserr("failed to rename newly-extracted $expectprefix to $newdirectory");
-        
-        &extracttar;
+
+        if ($sourcestyle =~ m/u/) {
+            extracttar("$dscdir/$tarfile",'.');
+        } elsif ($sourcestyle =~ m/p/) {
+            stat("$dscdir/$tarfile") ||
+                &syserr("failed to stat \`$dscdir/$tarfile' to see if need to copy");
+            ($dsctardev,$dsctarino) = stat _;
+            $dumptar= $sourcepackage.'_'.$baseversion.'.orig.tar.gz';
+            if (!stat($dumptar)) {
+                $! == ENOENT || &syserr("failed to check destination \`$dumptar'".
+                                        " to see if need to copy");
+            } else {
+                ($dumptardev,$dumptarino) = stat _;
+                if ($dumptardev == $dsctardev && $dumptarino == $dsctarino) {
+                    $dumptar= '';
+                }
+            }
+            if (length($dumptar)) {
+                system('cp','--',"$dscdir/$tarfile","$dumptar");
+                $? && subprocerr("cp $dscdir/$tarfile to $dumptar");
+            }
+        }                
 
         if ($mkdebian) {
             mkdir("$newdirectory/debian",0777) ||
@@ -575,17 +638,101 @@ sub checkstats {
 sub erasedir {
     my ($dir) = @_;
     if (!lstat($dir)) {
-        $! == ENOENT || &syserr("cannot stat output directory $dir (before removal)");
-    } else {
-        system 'rm','-r','--',$dir;
-        $? && subprocerr("rm -r $dir");
+        $! == ENOENT && return;
+        &syserr("cannot stat directory $dir (before removal)");
+    }
+    system 'rm','-rf','--',$dir;
+    $? && subprocerr("rm -rf $dir");
+    if (!stat($dir)) {
+        $! == ENOENT && return;
+        &syserr("unable to check for removal of dir \`$dir'");
+    }
+    &failure("rm -rf failed to remove \`$dir'");
+}
+
+sub checktarsane {
+    my ($tarfileread,$epfx) = @_;
+    my $c2,$fn,$pname,$slash,$mode,$dirname,$type;
+
+    &forkgzipread("$tarfileread");
+    defined($c2= open(CPIO,"-|")) || &syserr("fork for cpio");
+    if (!$c2) {
+        open(STDIN,"<&GZIP") || &syserr("reopen gzip for cpio");
+        &cpiostderr;
+        exec('cpio','-0t'); &syserr("exec cpio");
     }
+    $/= "\0";
+    close(GZIP);
+  file:
+    while (defined($fn= <CPIO>)) {
+        $fn =~ s/\0$//; $pname= $fn; $pname =~ y/ -~/?/c;
+        $fn =~ m/\n/ &&
+            &error("tarfile \`$tarfileread' contains object with".
+                   " newline in its name ($pname)");
+        $slash= substr($fn,length($epfx),1);
+        (($slash eq '/' || $slash eq '') &&
+         substr($fn,0,length($epfx)) eq $epfx) ||
+             &error("tarfile \`$tarfileread' contains object ($pname) ".
+                    "not in expected directory ($epfx)");
+        $fn =~ m,/\.\./, &&
+            &error("tarfile \`$tarfilread' contains object with".
+                   " /../ in its name ($pname)");
+        push(@filesinarchive,$fn);
+    }
+    close(CPIO); $? && subprocerr("cpio");
+    
+    $/= "\n";
+    &reapgzip;
+    &forkgzipread("$tarfileread");
+    defined($c2= open(TAR,"-|")) || &syserr("fork for tar -t");
+    if (!$c2) {
+        $ENV{'LANG'}= 'C';
+        open(STDIN,"<&GZIP") || &syserr("reopen gzip for tar -t");
+        exec('tar','-vvtf','-'); &syserr("exec tar -vvtf -");
+    }
+    close(GZIP);
+    $efix= 0;
+  file:
+    while (length($_= <TAR>)) {
+        s/\n$//;
+        m,^(\S{10})\s, ||
+            &error("tarfile \`$tarfileread' contains unknown object ".
+                   "listed by tar as \`$_'");
+        $fn= $filesinarchive[$efix++]; $mode= $1;
+        if ($mode =~ m/^l/) { $_ =~ s/ -\> .*//; }
+        substr($_,length($_)-length($fn)-1) eq " $fn" ||
+            &error("tarfile \`$tarfileread' contains unexpected object".
+                   " listed by tar as \`$_', expected \`$fn'");
+        $mode =~ s/^([-dpsl])// ||
+            &error("tarfile \`$tarfileread' contains object \`$fn' with ".
+                   "unknown or forbidden type \`".substr($_,0,1)."'");
+        $fn =~ m/\.dpkg-orig$/ &&
+            &error("tarfile \`$tarfileread' contains file with name ending .dpkg-orig");
+        $type= $&;
+        $mode =~ m/[sStT]/ && $type ne 'd' &&
+            &error("tarfile \`$tarfileread' contains setuid, setgid".
+                   " or sticky object \`$fn'");
+        $fn eq "$epfx/debian" && $type ne 'd' &&
+            &error("tarfile \`$tarfileread' contains object \`debian'".
+                   " that isn't a directory");
+        $fn =~ s,/$,, if $type eq 'd';
+        $dirname= $fn;
+        $dirname =~ s,/[^/]+$,, && !defined($dirincluded{$dirname}) &&
+            &error("tarfile \`$tarfileread' contains object \`$fn' but its containing ".
+                   "directory \`$dirname' does not precede it");
+        $dirincluded{$fn}= 1 if $type eq 'd';
+        $notfileobject{$fn}= 1 if $type ne '-';
+    }
+    close(TAR); $? && subprocerr("tar -t");
+    &reapgzip;
 }
 
 sub extracttar {
-    &forkgzipread("$dscdir/$tarfile");
+    my ($tarfileread,$dirchdir) = @_;
+    &forkgzipread("$tarfileread");
     defined($c2= fork) || &syserr("fork for cpio -i");
     if (!$c2) {
+        chdir("$dirchdir") || &syserr("cannot chdir to \`$dirchdir' for tar extract");
         open(STDIN,"<&GZIP") || &syserr("reopen gzip for cpio -i");
         &cpiostderr;
         exec('cpio','-Hustar','-im','--no-preserve-owner'); &syserr("exec cpio -i");
@@ -670,16 +817,15 @@ sub reapgzip {
     $cgz == waitpid($cgz,0) || &syserr("wait for gzip");
     !$? || ($gzipsigpipeok && WIFSIGNALED($?) && WTERMSIG($?)==SIGPIPE) ||
         subprocerr("gzip");
-    (@stat= stat(GZIPFILE)) || &syserr("cannot stat file after run gzip");
-    $size= $stat[7];
     close(GZIPFILE);
 }
 
 sub addfile {
     my ($filename)= @_;
+    stat($filename) || &syserr("could not stat output file \`$filename'");
+    $size= (stat _)[7];
     my $md5sum= `md5sum <$filename`;
     $? && &subprocerr("md5sum $filename");
-    $md5sum =~ s/^([0-9a-f]{32})\n$/$1/ ||
-        die "$progname: failure: md5sum gave bogus output \`$_'\n";
+    $md5sum =~ s/^([0-9a-f]{32})\n$/$1/ || &failure("md5sum gave bogus output \`$_'");
     $f{'Files'}.= "\n $md5sum $size $filename";
 }

+ 1 - 1
version.h

@@ -1 +1 @@
-#define DPKG_VERSION "1.3.6" /* This line modified by Makefile */
+#define DPKG_VERSION "1.3.7" /* This line modified by Makefile */