diff options
author | Guillem Jover <guillem@debian.org> | 2012-03-26 05:47:43 +0200 |
---|---|---|
committer | Guillem Jover <guillem@debian.org> | 2012-04-09 16:32:10 +0200 |
commit | c13a013fd8778f9f558bedfb532c011dcb304394 (patch) | |
tree | 2cf1d7568773866a3ec473a14c42a3c31e6c5a20 /dpkg-deb/extract.c | |
parent | a44743e16e53c3ec812d48e0579344f447cf72dd (diff) | |
download | dpkg-c13a013fd8778f9f558bedfb532c011dcb304394.tar.gz |
Switch deb format version handling to use the new deb-version module
This simplifies the parsing and checking and avoids having to treat the
format versions as floats, which can cause parse errors depending on the
locale (this only affected the old deb format).
Diffstat (limited to 'dpkg-deb/extract.c')
-rw-r--r-- | dpkg-deb/extract.c | 71 |
1 files changed, 39 insertions, 32 deletions
diff --git a/dpkg-deb/extract.c b/dpkg-deb/extract.c index d0b04a10a..08b0664a8 100644 --- a/dpkg-deb/extract.c +++ b/dpkg-deb/extract.c @@ -3,6 +3,7 @@ * extract.c - extracting archives * * Copyright © 1994,1995 Ian Jackson <ian@chiark.greenend.org.uk> + * Copyright © 2006-2012 Guillem Jover <guillem@debian.org> * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,6 +48,7 @@ #include <dpkg/command.h> #include <dpkg/compress.h> #include <dpkg/ar.h> +#include <dpkg/deb-version.h> #include <dpkg/options.h> #include "dpkg-deb.h" @@ -105,8 +107,9 @@ void extracthalf(const char *debar, const char *dir, const char *taroption, int admininfo) { + const char *err; char versionbuf[40]; - float versionnum; + struct deb_version version; off_t ctrllennum, memberlen = 0; ssize_t r; int dummy; @@ -117,7 +120,7 @@ extracthalf(const char *debar, const char *dir, const char *taroption, struct stat stab; char nlc; int adminmember; - bool oldformat, header_done; + bool header_done; enum compressor_type decompressor = compressor_type_gzip; arfd = open(debar, O_RDONLY); @@ -131,8 +134,6 @@ extracthalf(const char *debar, const char *dir, const char *taroption, read_fail(r, debar, _("archive magic version number")); if (strcmp(versionbuf, DPKG_AR_MAGIC) == 0) { - oldformat = false; - ctrllennum= 0; header_done = false; for (;;) { @@ -149,7 +150,6 @@ extracthalf(const char *debar, const char *dir, const char *taroption, memberlen = dpkg_ar_member_get_size(debar, &arh); if (!header_done) { char *infobuf; - char *cur; if (strncmp(arh.ar_name, DEBMAGIC, sizeof(arh.ar_name)) != 0) ohshit(_("file `%.250s' is not a debian binary archive (try dpkg-split?)"),debar); @@ -158,17 +158,16 @@ extracthalf(const char *debar, const char *dir, const char *taroption, if (r != (memberlen + (memberlen & 1))) read_fail(r, debar, _("archive information header member")); infobuf[memberlen] = '\0'; - cur= strchr(infobuf,'\n'); - if (!cur) ohshit(_("archive has no newlines in header")); - *cur = '\0'; - cur= strchr(infobuf,'.'); - if (!cur) ohshit(_("archive has no dot in version number")); - *cur = '\0'; - if (strcmp(infobuf,"2")) - ohshit(_("archive version %.250s not understood, get newer dpkg-deb"), infobuf); - *cur= '.'; - strncpy(versionbuf,infobuf,sizeof(versionbuf)); - versionbuf[sizeof(versionbuf) - 1] = '\0'; + + if (strchr(infobuf, '\n') == NULL) + ohshit(_("archive has no newlines in header")); + err = deb_version_parse(&version, infobuf); + if (err) + ohshit(_("archive has invalid format version: %s"), err); + if (version.major != 2) + ohshit(_("archive is format version %d.%d; get a newer dpkg-deb"), + version.major, version.minor); + free(infobuf); header_done = true; @@ -211,21 +210,23 @@ extracthalf(const char *debar, const char *dir, const char *taroption, } if (admininfo >= 2) { - printf(_(" new debian package, version %s.\n" - " size %jd bytes: control archive= %jd bytes.\n"), - versionbuf, (intmax_t)stab.st_size, (intmax_t)ctrllennum); + printf(_(" new debian package, version %d.%d.\n" + " size %jd bytes: control archive=%jd bytes.\n"), + version.major, version.minor, + (intmax_t)stab.st_size, (intmax_t)ctrllennum); m_output(stdout, _("<standard output>")); } - } else if (strncmp(versionbuf, "0.93", 4) == 0 && - sscanf(versionbuf,"%f%c%d",&versionnum,&nlc,&dummy) == 2 && - nlc == '\n') { + } else if (strncmp(versionbuf, "0.93", 4) == 0) { char ctrllenbuf[40]; int l = 0; - oldformat = true; l = strlen(versionbuf); - if (l && versionbuf[l - 1] == '\n') - versionbuf[l - 1] = '\0'; + + if (strchr(versionbuf, '\n') == NULL) + ohshit(_("archive has no newlines in header")); + err = deb_version_parse(&version, versionbuf); + if (err) + ohshit(_("archive has invalid format version: %s"), err); r = read_line(arfd, ctrllenbuf, 1, sizeof(ctrllenbuf)); if (r < 0) @@ -243,9 +244,10 @@ extracthalf(const char *debar, const char *dir, const char *taroption, } if (admininfo >= 2) { - printf(_(" old debian package, version %s.\n" - " size %jd bytes: control archive= %jd, main archive= %jd.\n"), - versionbuf, (intmax_t)stab.st_size, (intmax_t)ctrllennum, + printf(_(" old debian package, version %d.%d.\n" + " size %jd bytes: control archive=%jd, main archive=%jd.\n"), + version.major, version.minor, + (intmax_t)stab.st_size, (intmax_t)ctrllennum, (intmax_t)(stab.st_size - ctrllennum - strlen(ctrllenbuf) - l)); m_output(stdout, _("<standard output>")); } @@ -323,12 +325,17 @@ extracthalf(const char *debar, const char *dir, const char *taroption, subproc_wait_check(c2, _("<decompress>"), PROCPIPE); if (c1 != -1) subproc_wait_check(c1, _("paste"), 0); - if (oldformat && admininfo) { - if (versionnum == 0.931F) { + if (version.major == 0 && admininfo) { + /* Handle the version as a float to preserve the behaviour of old code, + * because even if the format is defined to be padded by 0's that might + * not have been always true for really ancient versions... */ + while (version.minor && (version.minor % 10) == 0) + version.minor /= 10; + + if (version.minor == 931) movecontrolfiles(OLDOLDDEBDIR); - } else if (versionnum == 0.932F || versionnum == 0.933F) { + else if (version.minor == 932 || version.minor == 933) movecontrolfiles(OLDDEBDIR); - } } } |