[Reproducible-commits] [dpkg] 37/74: libdpkg: Add new struct dpkg_ar and basic operations
Mattia Rizzolo
mattia at debian.org
Sun Jul 3 22:22:55 UTC 2016
This is an automated email from the git hooks/post-receive script.
mattia pushed a commit to annotated tag 1.18.8
in repository dpkg.
commit a15e095201abd2cb3490337b620ede8338bc3de1
Author: Guillem Jover <guillem at debian.org>
Date: Thu Feb 2 04:38:39 2012 +0100
libdpkg: Add new struct dpkg_ar and basic operations
Switch current code to use dpkg_ar instead of taking a filename and a
file descriptor arguments.
---
debian/changelog | 1 +
dpkg-deb/build.c | 31 +++++++------
dpkg-deb/extract.c | 48 +++++++++-----------
dpkg-split/dpkg-split.h | 5 ++-
dpkg-split/info.c | 117 +++++++++++++++++++++++++++---------------------
dpkg-split/main.c | 10 +++--
dpkg-split/queue.c | 8 ++--
dpkg-split/split.c | 14 +++---
lib/dpkg/ar.c | 114 +++++++++++++++++++++++++++++++++++-----------
lib/dpkg/ar.h | 28 +++++++++---
lib/dpkg/libdpkg.map | 5 +++
11 files changed, 237 insertions(+), 144 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index 356e12c..efde397 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -17,6 +17,7 @@ dpkg (1.18.8) UNRELEASED; urgency=medium
start-stop-daemon.
* Set return buffer length for sysctl(2) calls on */kFreeBSD in
start-stop-daemon.
+ * Abstract ar archive handling behind a new struct dpkg_ar and functions.
* Perl modules:
- Use warnings::warnif() instead of carp() for deprecated warnings.
- Add new format_range() method and deprecate dpkg() and rfc822() methods
diff --git a/dpkg-deb/build.c b/dpkg-deb/build.c
index fafaa1e..de870f6 100644
--- a/dpkg-deb/build.c
+++ b/dpkg-deb/build.c
@@ -474,11 +474,11 @@ do_build(const char *const *argv)
{
struct compress_params control_compress_params;
struct dpkg_error err;
+ struct dpkg_ar *ar;
const char *dir, *dest;
char *ctrldir;
char *debar;
char *tfbuf;
- int arfd;
int gzfd;
/* Decode our arguments. */
@@ -511,9 +511,8 @@ do_build(const char *const *argv)
/* Now that we have verified everything its time to actually
* build something. Let's start by making the ar-wrapper. */
- arfd = creat(debar, 0644);
- if (arfd < 0)
- ohshite(_("unable to create '%.255s'"), debar);
+ ar = dpkg_ar_create(debar, 0644);
+
unsetenv("TAR_OPTIONS");
/* Create a temporary file to store the control data in. Immediately
@@ -557,11 +556,11 @@ do_build(const char *const *argv)
ohshite(_("failed to stat temporary file (%s)"), _("control member"));
sprintf(versionbuf, "%-8s\n%jd\n", OLDARCHIVEVERSION,
(intmax_t)controlstab.st_size);
- if (fd_write(arfd, versionbuf, strlen(versionbuf)) < 0)
+ if (fd_write(ar->fd, versionbuf, strlen(versionbuf)) < 0)
ohshite(_("error writing '%s'"), debar);
- if (fd_fd_copy(gzfd, arfd, -1, &err) < 0)
+ if (fd_fd_copy(gzfd, ar->fd, -1, &err) < 0)
ohshit(_("cannot copy '%s' into archive '%s': %s"), _("control member"),
- debar, err.str);
+ ar->name, err.str);
} else if (deb_format.major == 2) {
const char deb_magic[] = ARCHIVEVERSION "\n";
char adminmember[16 + 1];
@@ -569,9 +568,9 @@ do_build(const char *const *argv)
sprintf(adminmember, "%s%s", ADMINMEMBER,
compressor_get_extension(control_compress_params.type));
- dpkg_ar_put_magic(debar, arfd);
- dpkg_ar_member_put_mem(debar, arfd, DEBMAGIC, deb_magic, strlen(deb_magic));
- dpkg_ar_member_put_file(debar, arfd, adminmember, gzfd, -1);
+ dpkg_ar_put_magic(ar);
+ dpkg_ar_member_put_mem(ar, DEBMAGIC, deb_magic, strlen(deb_magic));
+ dpkg_ar_member_put_file(ar, adminmember, gzfd, -1);
} else {
internerr("unknown deb format version %d.%d", deb_format.major, deb_format.minor);
}
@@ -583,7 +582,7 @@ do_build(const char *const *argv)
/* In old format, the data member is just concatenated after the
* control member, so we do not need a temporary file and can use
* the compression file descriptor. */
- gzfd = arfd;
+ gzfd = ar->fd;
} else if (deb_format.major == 2) {
/* Start by creating a new temporary file. Immediately unlink the
* temporary file so others can't mess with it. */
@@ -613,14 +612,14 @@ do_build(const char *const *argv)
if (lseek(gzfd, 0, SEEK_SET))
ohshite(_("failed to rewind temporary file (%s)"), _("data member"));
- dpkg_ar_member_put_file(debar, arfd, datamember, gzfd, -1);
+ dpkg_ar_member_put_file(ar, datamember, gzfd, -1);
close(gzfd);
}
- if (fsync(arfd))
- ohshite(_("unable to sync file '%s'"), debar);
- if (close(arfd))
- ohshite(_("unable to close file '%s'"), debar);
+ if (fsync(ar->fd))
+ ohshite(_("unable to sync file '%s'"), ar->name);
+
+ dpkg_ar_close(ar);
free(debar);
diff --git a/dpkg-deb/extract.c b/dpkg-deb/extract.c
index 6c63498..b46851c 100644
--- a/dpkg-deb/extract.c
+++ b/dpkg-deb/extract.c
@@ -107,6 +107,7 @@ extracthalf(const char *debar, const char *dir,
{
struct dpkg_error err;
const char *errstr;
+ struct dpkg_ar *ar;
char versionbuf[40];
struct deb_version version;
off_t ctrllennum, memberlen = 0;
@@ -115,23 +116,14 @@ extracthalf(const char *debar, const char *dir,
pid_t c1=0,c2,c3;
int p1[2], p2[2];
int p2_out;
- int arfd;
- struct stat stab;
char nlc;
int adminmember = -1;
bool header_done;
enum compressor_type decompressor = COMPRESSOR_TYPE_GZIP;
- if (strcmp(debar, "-") == 0)
- arfd = STDIN_FILENO;
- else
- arfd = open(debar, O_RDONLY);
- if (arfd < 0)
- ohshite(_("failed to read archive '%.255s'"), debar);
- if (fstat(arfd, &stab))
- ohshite(_("failed to fstat archive"));
+ ar = dpkg_ar_open(debar);
- r = read_line(arfd, versionbuf, strlen(DPKG_AR_MAGIC), sizeof(versionbuf) - 1);
+ r = read_line(ar->fd, versionbuf, strlen(DPKG_AR_MAGIC), sizeof(versionbuf) - 1);
if (r < 0)
read_fail(r, debar, _("archive magic version number"));
@@ -141,7 +133,7 @@ extracthalf(const char *debar, const char *dir,
for (;;) {
struct ar_hdr arh;
- r = fd_read(arfd, &arh, sizeof(arh));
+ r = fd_read(ar->fd, &arh, sizeof(arh));
if (r != sizeof(arh))
read_fail(r, debar, _("archive member header"));
@@ -149,7 +141,7 @@ extracthalf(const char *debar, const char *dir,
if (dpkg_ar_member_is_illegal(&arh))
ohshit(_("file '%.250s' is corrupt - bad archive header magic"), debar);
- memberlen = dpkg_ar_member_get_size(debar, &arh);
+ memberlen = dpkg_ar_member_get_size(ar, &arh);
if (!header_done) {
char *infobuf;
@@ -157,7 +149,7 @@ extracthalf(const char *debar, const char *dir,
ohshit(_("file '%.250s' is not a debian binary archive (try dpkg-split?)"),
debar);
infobuf= m_malloc(memberlen+1);
- r = fd_read(arfd, infobuf, memberlen + (memberlen & 1));
+ r = fd_read(ar->fd, infobuf, memberlen + (memberlen & 1));
if (r != (memberlen + (memberlen & 1)))
read_fail(r, debar, _("archive information header member"));
infobuf[memberlen] = '\0';
@@ -177,8 +169,8 @@ extracthalf(const char *debar, const char *dir,
} else if (arh.ar_name[0] == '_') {
/* Members with ‘_’ are noncritical, and if we don't understand
* them we skip them. */
- if (fd_skip(arfd, memberlen + (memberlen & 1), &err) < 0)
- ohshit(_("cannot skip archive member from '%s': %s"), debar, err.str);
+ if (fd_skip(ar->fd, memberlen + (memberlen & 1), &err) < 0)
+ ohshit(_("cannot skip archive member from '%s': %s"), ar->name, err.str);
} else {
if (strncmp(arh.ar_name, ADMINMEMBER, strlen(ADMINMEMBER)) == 0) {
const char *extension = arh.ar_name + strlen(ADMINMEMBER);
@@ -219,8 +211,8 @@ extracthalf(const char *debar, const char *dir,
ctrllennum= memberlen;
}
if (!adminmember != !admininfo) {
- if (fd_skip(arfd, memberlen + (memberlen & 1), &err) < 0)
- ohshit(_("cannot skip archive member from '%s': %s"), debar, err.str);
+ if (fd_skip(ar->fd, memberlen + (memberlen & 1), &err) < 0)
+ ohshit(_("cannot skip archive member from '%s': %s"), ar->name, err.str);
} else {
/* Yes! - found it. */
break;
@@ -232,7 +224,7 @@ extracthalf(const char *debar, const char *dir,
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);
+ (intmax_t)ar->size, (intmax_t)ctrllennum);
m_output(stdout, _("<standard output>"));
}
} else if (strncmp(versionbuf, "0.93", 4) == 0) {
@@ -247,7 +239,7 @@ extracthalf(const char *debar, const char *dir,
if (errstr)
ohshit(_("archive has invalid format version: %s"), errstr);
- r = read_line(arfd, ctrllenbuf, 1, sizeof(ctrllenbuf) - 1);
+ r = read_line(ar->fd, ctrllenbuf, 1, sizeof(ctrllenbuf) - 1);
if (r < 0)
read_fail(r, debar, _("archive control member size"));
if (sscanf(ctrllenbuf, "%jd%c%d", &ctrllennum, &nlc, &dummy) != 2 ||
@@ -257,9 +249,9 @@ extracthalf(const char *debar, const char *dir,
if (admininfo) {
memberlen = ctrllennum;
} else {
- memberlen = stab.st_size - ctrllennum - strlen(ctrllenbuf) - l;
- if (fd_skip(arfd, ctrllennum, &err) < 0)
- ohshit(_("cannot skip archive control member from '%s': %s"), debar,
+ memberlen = ar->size - ctrllennum - strlen(ctrllenbuf) - l;
+ if (fd_skip(ar->fd, ctrllennum, &err) < 0)
+ ohshit(_("cannot skip archive control member from '%s': %s"), ar->name,
err.str);
}
@@ -267,8 +259,8 @@ extracthalf(const char *debar, const char *dir,
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));
+ (intmax_t)ar->size, (intmax_t)ctrllennum,
+ (intmax_t)(ar->size - ctrllennum - strlen(ctrllenbuf) - l));
m_output(stdout, _("<standard output>"));
}
} else {
@@ -284,9 +276,9 @@ extracthalf(const char *debar, const char *dir,
c1 = subproc_fork();
if (!c1) {
close(p1[0]);
- if (fd_fd_copy(arfd, p1[1], memberlen, &err) < 0)
+ if (fd_fd_copy(ar->fd, p1[1], memberlen, &err) < 0)
ohshit(_("cannot copy archive member from '%s' to decompressor pipe: %s"),
- debar, err.str);
+ ar->name, err.str);
if (close(p1[1]))
ohshite(_("cannot close decompressor pipe"));
exit(0);
@@ -309,7 +301,7 @@ extracthalf(const char *debar, const char *dir,
exit(0);
}
close(p1[0]);
- close(arfd);
+ dpkg_ar_close(ar);
if (taroption) close(p2[1]);
if (taroption) {
diff --git a/dpkg-split/dpkg-split.h b/dpkg-split/dpkg-split.h
index e0acc44..3064d4d 100644
--- a/dpkg-split/dpkg-split.h
+++ b/dpkg-split/dpkg-split.h
@@ -22,6 +22,7 @@
#ifndef DPKG_SPLIT_H
#define DPKG_SPLIT_H
+#include <dpkg/ar.h>
#include <dpkg/deb-version.h>
action_func do_split;
@@ -63,9 +64,9 @@ extern const char *opt_outputfile;
extern int opt_npquiet;
extern int opt_msdos;
-void rerreof(FILE *f, const char *fn) DPKG_ATTR_NORET;
+void read_fail(int rc, const char *filename, const char *what) DPKG_ATTR_NORET;
void print_info(const struct partinfo *pi);
-struct partinfo *read_info(FILE *partfile, const char *fn, struct partinfo *ir);
+struct partinfo *read_info(struct dpkg_ar *ar, struct partinfo *ir);
void reassemble(struct partinfo **partlist, const char *outputfile);
void mustgetpartinfo(const char *filename, struct partinfo *ri);
diff --git a/dpkg-split/info.c b/dpkg-split/info.c
index ac6e439..57de75e 100644
--- a/dpkg-split/info.c
+++ b/dpkg-split/info.c
@@ -38,6 +38,7 @@
#include <dpkg/c-ctype.h>
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>
+#include <dpkg/fdio.h>
#include <dpkg/ar.h>
#include <dpkg/options.h>
@@ -82,7 +83,9 @@ static char *nextline(char **ripp, const char *fn, const char *what) {
* @return Part info (nfmalloc'd) if was an archive part and we read it,
* NULL if it wasn't.
*/
-struct partinfo *read_info(FILE *partfile, const char *fn, struct partinfo *ir) {
+struct partinfo *
+read_info(struct dpkg_ar *ar, struct partinfo *ir)
+{
static char *readinfobuf= NULL;
static size_t readinfobuflen= 0;
@@ -91,118 +94,128 @@ struct partinfo *read_info(FILE *partfile, const char *fn, struct partinfo *ir)
char magicbuf[sizeof(DPKG_AR_MAGIC) - 1], *rip, *partnums, *slash;
const char *err;
struct ar_hdr arh;
- int c;
- struct stat stab;
+ ssize_t rc;
- if (fread(magicbuf, 1, sizeof(magicbuf), partfile) != sizeof(magicbuf)) {
- if (ferror(partfile))
- ohshite(_("error reading %.250s"), fn);
+ rc = fd_read(ar->fd, magicbuf, sizeof(magicbuf));
+ if (rc != sizeof(magicbuf)) {
+ if (rc < 0)
+ ohshite(_("error reading %.250s"), ar->name);
else
return NULL;
}
if (memcmp(magicbuf, DPKG_AR_MAGIC, sizeof(magicbuf)))
return NULL;
- if (fread(&arh,1,sizeof(arh),partfile) != sizeof(arh)) rerreof(partfile,fn);
+ rc = fd_read(ar->fd, &arh, sizeof(arh));
+ if (rc != sizeof(arh))
+ read_fail(rc, ar->name, "ar header");
dpkg_ar_normalize_name(&arh);
if (strncmp(arh.ar_name, PARTMAGIC, sizeof(arh.ar_name)) != 0)
return NULL;
if (dpkg_ar_member_is_illegal(&arh))
- ohshit(_("file '%.250s' is corrupt - bad magic at end of first header"), fn);
- thisilen = dpkg_ar_member_get_size(fn, &arh);
+ ohshit(_("file '%.250s' is corrupt - bad magic at end of first header"),
+ ar->name);
+ thisilen = dpkg_ar_member_get_size(ar, &arh);
if (thisilen >= readinfobuflen) {
- readinfobuflen= thisilen+1;
+ readinfobuflen = thisilen + 2;
readinfobuf= m_realloc(readinfobuf,readinfobuflen);
}
- if (fread(readinfobuf,1,thisilen,partfile) != thisilen) rerreof(partfile,fn);
+ rc = fd_read(ar->fd, readinfobuf, thisilen + (thisilen & 1));
+ if (rc != (ssize_t)(thisilen + (thisilen & 1)))
+ read_fail(rc, ar->name, "reading header member");
if (thisilen & 1) {
- c= getc(partfile); if (c==EOF) rerreof(partfile,fn);
+ int c = readinfobuf[thisilen + 1];
+
if (c != '\n')
ohshit(_("file '%.250s' is corrupt - bad padding character (code %d)"),
- fn, c);
+ ar->name, c);
}
readinfobuf[thisilen] = '\0';
if (memchr(readinfobuf,0,thisilen))
- ohshit(_("file '%.250s' is corrupt - nulls in info section"), fn);
+ ohshit(_("file '%.250s' is corrupt - nulls in info section"), ar->name);
- ir->filename= fn;
+ ir->filename = ar->name;
rip= readinfobuf;
err = deb_version_parse(&ir->fmtversion,
- nextline(&rip, fn, _("format version number")));
+ nextline(&rip, ar->name, _("format version number")));
if (err)
- ohshit(_("file '%.250s' has invalid format version: %s"), fn, err);
+ ohshit(_("file '%.250s' has invalid format version: %s"), ar->name, err);
if (ir->fmtversion.major != 2)
ohshit(_("file '%.250s' is format version %d.%d; get a newer dpkg-split"),
- fn, ir->fmtversion.major, ir->fmtversion.minor);
+ ar->name, ir->fmtversion.major, ir->fmtversion.minor);
- ir->package = nfstrsave(nextline(&rip, fn, _("package name")));
- ir->version = nfstrsave(nextline(&rip, fn, _("package version number")));
- ir->md5sum = nfstrsave(nextline(&rip, fn, _("package file MD5 checksum")));
+ ir->package = nfstrsave(nextline(&rip, ar->name, _("package name")));
+ ir->version = nfstrsave(nextline(&rip, ar->name, _("package version number")));
+ ir->md5sum = nfstrsave(nextline(&rip, ar->name, _("package file MD5 checksum")));
if (strlen(ir->md5sum) != MD5HASHLEN ||
strspn(ir->md5sum, "0123456789abcdef") != MD5HASHLEN)
ohshit(_("file '%.250s' is corrupt - bad MD5 checksum '%.250s'"),
- fn, ir->md5sum);
+ ar->name, ir->md5sum);
- ir->orglength = parse_intmax(nextline(&rip, fn, _("archive total size")),
- fn, _("archive total size"));
- ir->maxpartlen = parse_intmax(nextline(&rip, fn, _("archive part offset")),
- fn, _("archive part offset"));
+ ir->orglength = parse_intmax(nextline(&rip, ar->name, _("archive total size")),
+ ar->name, _("archive total size"));
+ ir->maxpartlen = parse_intmax(nextline(&rip, ar->name, _("archive part offset")),
+ ar->name, _("archive part offset"));
- partnums = nextline(&rip, fn, _("archive part numbers"));
+ partnums = nextline(&rip, ar->name, _("archive part numbers"));
slash= strchr(partnums,'/');
if (!slash)
- ohshit(_("file '%.250s' is corrupt - no slash between archive part numbers"), fn);
+ ohshit(_("file '%.250s' is corrupt - no slash between archive part numbers"), ar->name);
*slash++ = '\0';
- templong = parse_intmax(slash, fn, _("number of archive parts"));
+ templong = parse_intmax(slash, ar->name, _("number of archive parts"));
if (templong <= 0 || templong > INT_MAX)
- ohshit(_("file '%.250s' is corrupt - bad number of archive parts"), fn);
+ ohshit(_("file '%.250s' is corrupt - bad number of archive parts"), ar->name);
ir->maxpartn= templong;
- templong = parse_intmax(partnums, fn, _("archive parts number"));
+ templong = parse_intmax(partnums, ar->name, _("archive parts number"));
if (templong <= 0 || templong > ir->maxpartn)
- ohshit(_("file '%.250s' is corrupt - bad archive part number"), fn);
+ ohshit(_("file '%.250s' is corrupt - bad archive part number"), ar->name);
ir->thispartn= templong;
/* If the package was created with dpkg 1.16.1 or later it will include
* the architecture. */
if (*rip != '\0')
- ir->arch = nfstrsave(nextline(&rip, fn, _("package architecture")));
+ ir->arch = nfstrsave(nextline(&rip, ar->name, _("package architecture")));
else
ir->arch = NULL;
- if (fread(&arh,1,sizeof(arh),partfile) != sizeof(arh)) rerreof(partfile,fn);
+ rc = fd_read(ar->fd, &arh, sizeof(arh));
+ if (rc != sizeof(arh))
+ read_fail(rc, ar->name, "reading data part member ar header");
dpkg_ar_normalize_name(&arh);
if (dpkg_ar_member_is_illegal(&arh))
- ohshit(_("file '%.250s' is corrupt - bad magic at end of second header"), fn);
+ ohshit(_("file '%.250s' is corrupt - bad magic at end of second header"),
+ ar->name);
if (strncmp(arh.ar_name,"data",4))
- ohshit(_("file '%.250s' is corrupt - second member is not data member"), fn);
+ ohshit(_("file '%.250s' is corrupt - second member is not data member"),
+ ar->name);
- ir->thispartlen = dpkg_ar_member_get_size(fn, &arh);
+ ir->thispartlen = dpkg_ar_member_get_size(ar, &arh);
ir->thispartoffset= (ir->thispartn-1)*ir->maxpartlen;
if (ir->maxpartn != (ir->orglength+ir->maxpartlen-1)/ir->maxpartlen)
- ohshit(_("file '%.250s' is corrupt - wrong number of parts for quoted sizes"), fn);
+ ohshit(_("file '%.250s' is corrupt - wrong number of parts for quoted sizes"),
+ ar->name);
if (ir->thispartlen !=
(ir->thispartn == ir->maxpartn
? ir->orglength - ir->thispartoffset : ir->maxpartlen))
- ohshit(_("file '%.250s' is corrupt - size is wrong for quoted part number"), fn);
+ ohshit(_("file '%.250s' is corrupt - size is wrong for quoted part number"),
+ ar->name);
ir->filesize = (strlen(DPKG_AR_MAGIC) +
sizeof(arh) + thisilen + (thisilen & 1) +
sizeof(arh) + ir->thispartlen + (ir->thispartlen & 1));
- if (fstat(fileno(partfile), &stab))
- ohshite(_("unable to fstat part file '%.250s'"), fn);
- if (S_ISREG(stab.st_mode)) {
+ if (S_ISREG(ar->mode)) {
/* Don't do this check if it's coming from a pipe or something. It's
* only an extra sanity check anyway. */
- if (stab.st_size < ir->filesize)
- ohshit(_("file '%.250s' is corrupt - too short"), fn);
+ if (ar->size < ir->filesize)
+ ohshit(_("file '%.250s' is corrupt - too short"), ar->name);
}
ir->headerlen = strlen(DPKG_AR_MAGIC) +
@@ -212,14 +225,14 @@ struct partinfo *read_info(FILE *partfile, const char *fn, struct partinfo *ir)
}
void mustgetpartinfo(const char *filename, struct partinfo *ri) {
- FILE *part;
+ struct dpkg_ar *part;
- part= fopen(filename,"r");
+ part = dpkg_ar_open(filename);
if (!part)
ohshite(_("cannot open archive part file '%.250s'"), filename);
- if (!read_info(part,filename,ri))
+ if (!read_info(part, ri))
ohshite(_("file '%.250s' is not an archive part"), filename);
- fclose(part);
+ dpkg_ar_close(part);
}
void print_info(const struct partinfo *pi) {
@@ -255,18 +268,18 @@ do_info(const char *const *argv)
{
const char *thisarg;
struct partinfo *pi, ps;
- FILE *part;
+ struct dpkg_ar *part;
if (!*argv)
badusage(_("--%s requires one or more part file arguments"),
cipaction->olong);
while ((thisarg= *argv++)) {
- part= fopen(thisarg,"r");
+ part = dpkg_ar_open(thisarg);
if (!part)
ohshite(_("cannot open archive part file '%.250s'"), thisarg);
- pi= read_info(part,thisarg,&ps);
- fclose(part);
+ pi = read_info(part, &ps);
+ dpkg_ar_close(part);
if (pi) {
print_info(pi);
} else {
diff --git a/dpkg-split/main.c b/dpkg-split/main.c
index 988034b..bcc1dc7 100644
--- a/dpkg-split/main.c
+++ b/dpkg-split/main.c
@@ -109,9 +109,13 @@ const char *opt_outputfile = NULL;
int opt_npquiet = 0;
int opt_msdos = 0;
-void rerreof(FILE *f, const char *fn) {
- if (ferror(f)) ohshite(_("error reading %.250s"),fn);
- ohshit(_("unexpected end of file in %.250s"),fn);
+void DPKG_ATTR_NORET
+read_fail(int rc, const char *filename, const char *what)
+{
+ if (rc >= 0)
+ ohshit(_("unexpected end of file in %s in %.255s"), what, filename);
+ else
+ ohshite(_("error reading %s from file %.255s"), what, filename);
}
static void
diff --git a/dpkg-split/queue.c b/dpkg-split/queue.c
index daf00aa..8ea2a30 100644
--- a/dpkg-split/queue.c
+++ b/dpkg-split/queue.c
@@ -136,9 +136,9 @@ do_auto(const char *const *argv)
struct partinfo *refi, **partlist, *otherthispart;
struct partqueue *queue;
struct partqueue *pq;
+ struct dpkg_ar *part;
unsigned int i;
int j;
- FILE *part;
if (!opt_outputfile)
badusage(_("--auto requires the use of the --output option"));
@@ -147,16 +147,16 @@ do_auto(const char *const *argv)
badusage(_("--auto requires exactly one part file argument"));
refi= nfmalloc(sizeof(struct partqueue));
- part= fopen(partfile,"r");
+ part = dpkg_ar_open(partfile);
if (!part)
ohshite(_("unable to read part file '%.250s'"), partfile);
- if (!read_info(part,partfile,refi)) {
+ if (!read_info(part, refi)) {
if (!opt_npquiet)
printf(_("File '%.250s' is not part of a multipart archive.\n"), partfile);
m_output(stdout, _("<standard output>"));
return 1;
}
- fclose(part);
+ dpkg_ar_close(part);
queue = scandepot();
partlist= nfmalloc(sizeof(struct partinfo*)*refi->maxpartn);
diff --git a/dpkg-split/split.c b/dpkg-split/split.c
index 8137654..fd47aea 100644
--- a/dpkg-split/split.c
+++ b/dpkg-split/split.c
@@ -165,7 +165,7 @@ mksplit(const char *file_src, const char *prefix, off_t maxpartsize,
}
for (curpart = 1; curpart <= nparts; curpart++) {
- int fd_dst;
+ struct dpkg_ar *ar;
varbuf_reset(&file_dst);
/* Generate output filename. */
@@ -196,12 +196,10 @@ mksplit(const char *file_src, const char *prefix, off_t maxpartsize,
}
/* Split the data. */
- fd_dst = creat(file_dst.buf, 0644);
- if (fd_dst < 0)
- ohshite(_("unable to open file '%s'"), file_dst.buf);
+ ar = dpkg_ar_create(file_dst.buf, 0644);
/* Write the ar header. */
- dpkg_ar_put_magic(file_dst.buf, fd_dst);
+ dpkg_ar_put_magic(ar);
/* Write the debian-split part. */
varbuf_printf(&partmagic,
@@ -209,17 +207,17 @@ mksplit(const char *file_src, const char *prefix, off_t maxpartsize,
SPLITVERSION, pkg->set->name, version, hash,
(intmax_t)st.st_size, (intmax_t)partsize,
curpart, nparts, pkg->available.arch->name);
- dpkg_ar_member_put_mem(file_dst.buf, fd_dst, PARTMAGIC,
+ dpkg_ar_member_put_mem(ar, PARTMAGIC,
partmagic.buf, partmagic.used);
varbuf_reset(&partmagic);
/* Write the data part. */
varbuf_printf(&partname, "data.%d", curpart);
- dpkg_ar_member_put_file(file_dst.buf, fd_dst, partname.buf,
+ dpkg_ar_member_put_file(ar, partname.buf,
fd_src, cur_partsize);
varbuf_reset(&partname);
- close(fd_dst);
+ dpkg_ar_close(ar);
printf("%d ", curpart);
}
diff --git a/lib/dpkg/ar.c b/lib/dpkg/ar.c
index 97eefb6..0aec95d 100644
--- a/lib/dpkg/ar.c
+++ b/lib/dpkg/ar.c
@@ -25,7 +25,9 @@
#include <sys/stat.h>
#include <time.h>
+#include <fcntl.h>
#include <stdint.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -35,12 +37,73 @@
#include <dpkg/buffer.h>
#include <dpkg/ar.h>
+struct dpkg_ar *
+dpkg_ar_fdopen(const char *filename, int fd)
+{
+ struct dpkg_ar *ar;
+ struct stat st;
+
+ if (fstat(fd, &st) != 0)
+ ohshite(_("failed to fstat archive"));
+
+ ar = m_malloc(sizeof(*ar));
+ ar->name = filename;
+ ar->mode = st.st_mode;
+ ar->size = st.st_size;
+ ar->time = st.st_mtime;
+ ar->fd = fd;
+
+ return ar;
+}
+
+struct dpkg_ar *
+dpkg_ar_open(const char *filename)
+{
+ int fd;
+
+ if (strcmp(filename, "-") == 0)
+ fd = STDIN_FILENO;
+ else
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ ohshite(_("failed to read archive '%.255s'"), filename);
+
+ return dpkg_ar_fdopen(filename, fd);
+}
+
+struct dpkg_ar *
+dpkg_ar_create(const char *filename, mode_t mode)
+{
+ int fd;
+
+ fd = creat(filename, mode);
+ if (fd < 0)
+ ohshite(_("unable to create '%.255s'"), filename);
+
+ return dpkg_ar_fdopen(filename, fd);
+}
+
+void
+dpkg_ar_set_mtime(struct dpkg_ar *ar, time_t mtime)
+{
+ ar->time = mtime;
+}
+
+void
+dpkg_ar_close(struct dpkg_ar *ar)
+{
+ if (close(ar->fd))
+ ohshite(_("unable to close file '%s'"), ar->name);
+ free(ar);
+}
+
static void
-dpkg_ar_member_init(struct dpkg_ar_member *member, const char *name, off_t size)
+dpkg_ar_member_init(struct dpkg_ar *ar, struct dpkg_ar_member *member,
+ const char *name, off_t size)
{
member->name = name;
member->size = size;
- member->time = time(NULL);
+ member->time = ar->time;
member->mode = 0100644;
member->uid = 0;
member->gid = 0;
@@ -62,7 +125,7 @@ dpkg_ar_normalize_name(struct ar_hdr *arh)
}
off_t
-dpkg_ar_member_get_size(const char *ar_name, struct ar_hdr *arh)
+dpkg_ar_member_get_size(struct dpkg_ar *ar, struct ar_hdr *arh)
{
const char *str = arh->ar_size;
int len = sizeof(arh->ar_size);
@@ -77,7 +140,7 @@ dpkg_ar_member_get_size(const char *ar_name, struct ar_hdr *arh)
if (*str < '0' || *str > '9')
ohshit(_("invalid character '%c' in archive '%.250s' "
"member '%.16s' size"),
- *str, ar_name, arh->ar_name);
+ *str, ar->name, arh->ar_name);
size *= 10;
size += *str++ - '0';
@@ -93,15 +156,14 @@ dpkg_ar_member_is_illegal(struct ar_hdr *arh)
}
void
-dpkg_ar_put_magic(const char *ar_name, int ar_fd)
+dpkg_ar_put_magic(struct dpkg_ar *ar)
{
- if (fd_write(ar_fd, DPKG_AR_MAGIC, strlen(DPKG_AR_MAGIC)) < 0)
- ohshite(_("unable to write file '%s'"), ar_name);
+ if (fd_write(ar->fd, DPKG_AR_MAGIC, strlen(DPKG_AR_MAGIC)) < 0)
+ ohshite(_("unable to write file '%s'"), ar->name);
}
void
-dpkg_ar_member_put_header(const char *ar_name, int ar_fd,
- struct dpkg_ar_member *member)
+dpkg_ar_member_put_header(struct dpkg_ar *ar, struct dpkg_ar_member *member)
{
char header[sizeof(struct ar_hdr) + 1];
int n;
@@ -116,32 +178,32 @@ dpkg_ar_member_put_header(const char *ar_name, int ar_fd,
(unsigned long)member->uid, (unsigned long)member->gid,
(unsigned long)member->mode, (intmax_t)member->size);
if (n != sizeof(struct ar_hdr))
- ohshit(_("generated corrupt ar header for '%s'"), ar_name);
+ ohshit(_("generated corrupt ar header for '%s'"), ar->name);
- if (fd_write(ar_fd, header, n) < 0)
- ohshite(_("unable to write file '%s'"), ar_name);
+ if (fd_write(ar->fd, header, n) < 0)
+ ohshite(_("unable to write file '%s'"), ar->name);
}
void
-dpkg_ar_member_put_mem(const char *ar_name, int ar_fd,
+dpkg_ar_member_put_mem(struct dpkg_ar *ar,
const char *name, const void *data, size_t size)
{
struct dpkg_ar_member member;
- dpkg_ar_member_init(&member, name, size);
- dpkg_ar_member_put_header(ar_name, ar_fd, &member);
+ dpkg_ar_member_init(ar, &member, name, size);
+ dpkg_ar_member_put_header(ar, &member);
/* Copy data contents. */
- if (fd_write(ar_fd, data, size) < 0)
- ohshite(_("unable to write file '%s'"), ar_name);
+ if (fd_write(ar->fd, data, size) < 0)
+ ohshite(_("unable to write file '%s'"), ar->name);
if (size & 1)
- if (fd_write(ar_fd, "\n", 1) < 0)
- ohshite(_("unable to write file '%s'"), ar_name);
+ if (fd_write(ar->fd, "\n", 1) < 0)
+ ohshite(_("unable to write file '%s'"), ar->name);
}
void
-dpkg_ar_member_put_file(const char *ar_name, int ar_fd,
+dpkg_ar_member_put_file(struct dpkg_ar *ar,
const char *name, int fd, off_t size)
{
struct dpkg_error err;
@@ -155,15 +217,15 @@ dpkg_ar_member_put_file(const char *ar_name, int ar_fd,
size = st.st_size;
}
- dpkg_ar_member_init(&member, name, size);
- dpkg_ar_member_put_header(ar_name, ar_fd, &member);
+ dpkg_ar_member_init(ar, &member, name, size);
+ dpkg_ar_member_put_header(ar, &member);
/* Copy data contents. */
- if (fd_fd_copy(fd, ar_fd, size, &err) < 0)
+ if (fd_fd_copy(fd, ar->fd, size, &err) < 0)
ohshit(_("cannot append ar member file (%s) to '%s': %s"),
- name, ar_name, err.str);
+ name, ar->name, err.str);
if (size & 1)
- if (fd_write(ar_fd, "\n", 1) < 0)
- ohshite(_("unable to write file '%s'"), ar_name);
+ if (fd_write(ar->fd, "\n", 1) < 0)
+ ohshite(_("unable to write file '%s'"), ar->name);
}
diff --git a/lib/dpkg/ar.h b/lib/dpkg/ar.h
index 81a061e..ba3ebd9 100644
--- a/lib/dpkg/ar.h
+++ b/lib/dpkg/ar.h
@@ -39,6 +39,17 @@ DPKG_BEGIN_DECLS
#define DPKG_AR_MAGIC "!<arch>\n"
/**
+ * An archive (Unix ar) file.
+ */
+struct dpkg_ar {
+ const char *name;
+ mode_t mode;
+ time_t time;
+ off_t size;
+ int fd;
+};
+
+/**
* In-memory archive member information.
*/
struct dpkg_ar_member {
@@ -52,17 +63,24 @@ struct dpkg_ar_member {
gid_t gid;
};
+struct dpkg_ar *
+dpkg_ar_fdopen(const char *filename, int fd);
+struct dpkg_ar *dpkg_ar_open(const char *filename);
+struct dpkg_ar *dpkg_ar_create(const char *filename, mode_t mode);
+void dpkg_ar_set_mtime(struct dpkg_ar *ar, time_t mtime);
+void dpkg_ar_close(struct dpkg_ar *ar);
+
void dpkg_ar_normalize_name(struct ar_hdr *arh);
bool dpkg_ar_member_is_illegal(struct ar_hdr *arh);
-void dpkg_ar_put_magic(const char *ar_name, int ar_fd);
-void dpkg_ar_member_put_header(const char *ar_name, int ar_fd,
+void dpkg_ar_put_magic(struct dpkg_ar *ar);
+void dpkg_ar_member_put_header(struct dpkg_ar *ar,
struct dpkg_ar_member *member);
-void dpkg_ar_member_put_file(const char *ar_name, int ar_fd, const char *name,
+void dpkg_ar_member_put_file(struct dpkg_ar *ar, const char *name,
int fd, off_t size);
-void dpkg_ar_member_put_mem(const char *ar_name, int ar_fd, const char *name,
+void dpkg_ar_member_put_mem(struct dpkg_ar *ar, const char *name,
const void *data, size_t size);
-off_t dpkg_ar_member_get_size(const char *ar_name, struct ar_hdr *arh);
+off_t dpkg_ar_member_get_size(struct dpkg_ar *ar, struct ar_hdr *arh);
/** @} */
diff --git a/lib/dpkg/libdpkg.map b/lib/dpkg/libdpkg.map
index ddf898f..93f0bfe 100644
--- a/lib/dpkg/libdpkg.map
+++ b/lib/dpkg/libdpkg.map
@@ -19,6 +19,11 @@ global:
dpkg_program_done;
# Ar support
+ dpkg_ar_fdopen;
+ dpkg_ar_create;
+ dpkg_ar_open;
+ dpkg_ar_set_mtime;
+ dpkg_ar_close;
dpkg_ar_normalize_name;
dpkg_ar_member_is_illegal;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/dpkg.git
More information about the Reproducible-commits
mailing list