2

I have already seen Easily unpack DEB, edit postinst, and repack DEB - however, that one doesn't explain how to properly change the .deb version number if I want to do some changes the original .deb file.

I'm on Ubuntu 14.04, and let's take hostapd for an example:

$ mkdir /tmp/debtest
$ cd /tmp/debtest/
$ apt-get download hostapd
Get:1 http://dk.archive.ubuntu.com/ubuntu/ trusty-updates/universe hostapd amd64 1:2.1-0ubuntu1.4 [423 kB]
Fetched 423 kB in 1s (361 kB/s)  
$ ls -la hostapd_1%3a2.1-0ubuntu1.4_amd64.deb 
-rw-rw-r-- 1 myuser myuser 422846 Nov 10  2015 hostapd_1%3a2.1-0ubuntu1.4_amd64.deb

Now we can unpack as in the cited link above:

$ mkdir unpack-hostapd
$ dpkg-deb -R hostapd_1%3a2.1-0ubuntu1.4_amd64.deb unpack-hostapd
$ ls -la unpack-hostapd/
total 20
drwxr-xr-x 5 myuser myuser 4096 Jan 26 11:31 .
drwxrwxr-x 3 myuser myuser 4096 Jan 26 11:31 ..
drwxr-xr-x 2 myuser myuser 4096 Nov  9  2015 DEBIAN
drwxr-xr-x 6 myuser myuser 4096 Nov  9  2015 etc
drwxr-xr-x 4 myuser myuser 4096 Nov  9  2015 usr

Let's say I want to make a trival change, say appending a line of text to README.Debian:

echo "Just a test line" >> unpack-hostapd/usr/share/doc/hostapd/README.Debian

... and now I want to repack this as a new .deb.

First question - is there a way to retrieve the current (old) version of the package from the unpacked state? Because I don't trust filenames, I'd usually do:

$ apt-cache policy hostapd
hostapd:
  Installed: (none)
  Candidate: 1:2.1-0ubuntu1.4
...

... and this tells me I've downloaded version 1:2.1-0ubuntu1.4 of the package when I used apt-get download... - but not necessarily what is the version inside the unpack-hostapd directory. Is there a command that will tell me the package version of the originating .deb that was unpacked into the unpack-hostapd directory?

Now, I've used debchange as dch -i before to auto-increment a version number (although in other source projects), but when I try it here:

$ cd unpack-hostapd
$ pwd
/tmp/debtest/unpack-hostapd
$ dch -e
dch: fatal error at line 580:
Cannot find debian/changelog anywhere!
Are you in the source code tree?
(You could use --create if you wish to create this file.)
$ find . -name 'changelog*'
./usr/share/doc/hostapd/changelog.Debian.gz
$ dpkg -c ../hostapd_1%3a2.1-0ubuntu1.4_amd64.deb | grep changelog
-rw-r--r-- root/root      2126 2015-11-09 14:56 ./usr/share/doc/hostapd/changelog.Debian.gz

... but, I cannot change any of that here.

So, my second question is: is there an easy way (like dch -i is for source packages) to change the .deb package version number, and possibly add a changelog, to an unpacked .deb package like this?

Of course, ultimately I'd like to re-pack this new version as a .deb package, for which the link above suggests something like dpkg-deb -b unpack-hostapd hostapd_1%3a2.1-0ubuntu1.4_amd64.deb; although, say here I'd rather use version 1:2.2, so I'd finally use a filename like dpkg-deb -b unpack-hostapd hostapd_1%3a2.2_amd64.deb - however, that version should also match what is recorded inside the .deb, and I don't know how to do that...

sdbbs
  • 480
  • 1
    Is working with the source directly not an option? – Faheem Mitha Jan 26 '17 at 10:51
  • Thanks @FaheemMitha - in my actual case no, working with the source directly is not an option – sdbbs Jan 26 '17 at 10:52
  • 1
    Could you expand on why this is the case? Just curious. I haven't checked, but I assume the hostapd sources are available. And presumably rebuilding them is not an issue. Oh, I believe the Debian metadata is in the DEBIAN directory, though I'm not 100% sure about that. – Faheem Mitha Jan 26 '17 at 10:57
  • Sure - it's because in my actual case, I have to include source from several versions ahead, meaning that the source tree is completely changed, and thus I cannot compile it on the older system I have as a debian package; replacing the executables with the ones built from the vanilla source works good for me - except the version numbers screw everything up, because when I do update, the "new" versions get overwritten (and I wouldn't like to "pin" packages either) – sdbbs Jan 26 '17 at 11:08
  • 1
    Hmm. You should be able to use the source that corresponds to your current binary package to do everything. Are you saying it's not available? Messing with a binary package should be very much a last resort. I don't think I've ever had to do that. And there are various ways to stop an older package to get upgraded - but that's a separate topic. – Faheem Mitha Jan 26 '17 at 15:17
  • Thanks @FaheemMitha - it is a last resort; say, the current version of the package on the OS I use use is 1.0; the latest version of the source (which fixes a bug) is 3.0 - and 3.0 as a source has such a different organisation of the tree in files and directories, that if I just copy/paste it in src/ of the Deb package source, I get a ton of errors and it doesn't compile; Compiling the Deb of 3.0 has a different set of dependencies so it won't compile on the OS; compiling 3.0 standalone and replacing the executables works for me. – sdbbs Jan 27 '17 at 08:25
  • 1
    Oh, I see. Yes, if the Debian packaging corresponds to a older version, and if you want to use a newer version, and things have changed a lot in between, there's no easy solution. Personally I'd try to fix up the Debian packaging, but I understand that you might not want to do that. Though I'm surprised you can't get a version of the packaging corresponding to 3.0. I see the current version in unstable in 2.6. – Faheem Mitha Jan 27 '17 at 09:53
  • @FaheemMitha - Yes; btw I just used those numbers (1.0 , 3.0) as an example (which is why I used the word "say"), they do not correspond to my actual use case/reality. – sdbbs Jan 27 '17 at 10:36

2 Answers2

4

The version is defined in the binary control file, which is extracted in DEBIAN/control when using dpkg-deb -R. Look for a Version: field:

Version: 1:2.5.2+v2.4-3+b1

This is where you'd edit the version number for your new package. (You can optionally add a changelog entry to the changelog in usr/share/doc/hostapd/changelog.Debian.gz.) Then you can rebuild your package like this, so that dpkg-deb determines the correct file name for you:

mkdir newpkg
dpkg-deb -b hostapd newpkg

This will produce a new package in the newpkg directory, named appropriately.

Ideally you should check your new binaries' library requirements and update the dependency information in control too!

Stephen Kitt
  • 434,908
  • Thanks @StephenKitt - I ended up doing something similar, good to know I wasn't way too off :) – sdbbs Jan 26 '17 at 12:17
1

Here's what kind of manual edit worked for me - however, this was sort of a blind guess, so still nice to have an answer from someone who understands the system:

# decompress changelog.Debian.gz
unpack-hostapd$ gzip -d  usr/share/doc/hostapd/changelog.Debian.gz

# edit the uncompressed changelog.Debian:
# add this on top:
# wpa (2.2) trusty-security; urgency=medium
# 
# * whatever
# 
# wpa (2.1-0ubuntu1.4) trusty-security; urgency=medium
# ....
unpack-hostapd$ nano usr/share/doc/hostapd/changelog.Debian

# repack changelog.Debian.gz
unpack-hostapd$ gzip -9 usr/share/doc/hostapd/changelog.Debian

# change DEBIAN/control - Source: and Version:
# change to:
# Source: wpa (2.2)
# Version: 1:2.2
unpack-hostapd$ nano DEBIAN/control

# repack .deb:
unpack-hostapd$ cd ..
$ dpkg-deb -b unpack-hostapd hostapd_1%3a2.2_amd64.deb

# now can install the deb
sudo dpkg -i hostapd_1%3a2.2_amd64.deb
sdbbs
  • 480
  • 1
    It's nice to update the source version, although it doesn't have much actual consequence in the binary package. The only change I'd make to the above is delegating the construction of the new file name to dpkg-deb at the end! – Stephen Kitt Jan 26 '17 at 12:19