From aa31421bfe835dadd29da3aa46ee446038f80d02 Mon Sep 17 00:00:00 2001
From: Matthew Almond <malmond@fb.com>
Date: Sun, 31 Jan 2021 13:51:16 -0800
Subject: [PATCH 03/30] Match formatting/style of existing code
The existing code contains some variability in formatting. I'm not sure
if { is meant to be on the end of the line, or on a new line, but I've
standardized on the former.
The indentation is intended to match the existing convention: 4 column
indent, but 8 column wide tab characters. This is easy to follow/use in
vim, but is surprisingly difficult to get right in vscode. I am doing
this reformat here and now, and future changes will be after this.
I'm keen to fold the patches together, but for now, I'm trying to keep
the history of #1470 linear so everyone can follow along.
---
lib/rpmplugins.c | 6 +-
plugins/reflink.c | 407 ++++++++++++++++++---------------
rpm2extents.c | 562 ++++++++++++++++++++--------------------------
3 files changed, 462 insertions(+), 513 deletions(-)
diff --git a/lib/rpmplugins.c b/lib/rpmplugins.c
index c5084d398..3da3097af 100644
--- a/lib/rpmplugins.c
+++ b/lib/rpmplugins.c
@@ -368,9 +368,9 @@ rpmRC rpmpluginsCallFsmFilePre(rpmPlugins plugins, rpmfi fi, const char *path,
rc = RPMRC_FAIL;
} else if (hook_rc == RPMRC_PLUGIN_CONTENTS && rc != RPMRC_FAIL) {
if (rc == RPMRC_PLUGIN_CONTENTS) {
- /*
- Another plugin already said it'd handle contents. It's undefined how
- these would combine, so treat this as a failure condition.
+ /* Another plugin already said it'd handle contents. It's
+ * undefined how these would combine, so treat this as a
+ * failure condition.
*/
rc = RPMRC_FAIL;
} else {
diff --git a/plugins/reflink.c b/plugins/reflink.c
index d7f19acd9..9eaa87094 100644
--- a/plugins/reflink.c
+++ b/plugins/reflink.c
@@ -32,31 +32,32 @@
#include "lib/rpmhash.H"
#include "lib/rpmhash.C"
-/*
-We use this in find to indicate a key wasn't found. This is an unrecoverable
-error, but we can at least show a decent error. 0 is never a valid offset
-because it's the offset of the start of the file.
-*/
+/* We use this in find to indicate a key wasn't found. This is an
+ * unrecoverable error, but we can at least show a decent error. 0 is never a
+ * valid offset because it's the offset of the start of the file.
+ */
#define NOT_FOUND 0
#define BUFFER_SIZE (1024 * 128)
-/* magic value at end of file (64 bits) that indicates this is a transcoded rpm */
+/* magic value at end of file (64 bits) that indicates this is a transcoded
+ * rpm.
+ */
#define MAGIC 3472329499408095051
struct reflink_state_s {
- /* Stuff that's used across rpms */
- long fundamental_block_size;
- char *buffer;
+ /* Stuff that's used across rpms */
+ long fundamental_block_size;
+ char *buffer;
- /* stuff that's used/updated per psm */
- uint32_t keys, keysize;
+ /* stuff that's used/updated per psm */
+ uint32_t keys, keysize;
- // table for current rpm, keys * (keysize + sizeof(rpm_loff_t))
- unsigned char *table;
- FD_t fd;
- rpmfiles files;
- inodeIndexHash inodeIndexes;
+ /* table for current rpm, keys * (keysize + sizeof(rpm_loff_t)) */
+ unsigned char *table;
+ FD_t fd;
+ rpmfiles files;
+ inodeIndexHash inodeIndexes;
};
typedef struct reflink_state_s * reflink_state;
@@ -73,60 +74,62 @@ static unsigned int inodeId(rpm_ino_t a)
}
static rpmRC reflink_init(rpmPlugin plugin, rpmts ts) {
- reflink_state state = rcalloc(1, sizeof(struct reflink_state_s));
+ reflink_state state = rcalloc(1, sizeof(struct reflink_state_s));
- /*
- IOCTL-FICLONERANGE(2): ...Disk filesystems generally require the offset and
- length arguments to be aligned to the fundamental block size.
+ /* IOCTL-FICLONERANGE(2): ...Disk filesystems generally require the offset
+ * and length arguments to be aligned to the fundamental block size.
+ *
+ * The value of "fundamental block size" is directly related to the
+ * system's page size, so we should use that.
+ */
+ state->fundamental_block_size = sysconf(_SC_PAGESIZE);
+ state->buffer = rcalloc(1, BUFFER_SIZE);
+ rpmPluginSetData(plugin, state);
- The value of "fundamental block size" is directly related to the system's
- page size, so we should use that.
- */
- state->fundamental_block_size = sysconf(_SC_PAGESIZE);
- state->buffer = rcalloc(1, BUFFER_SIZE);
- rpmPluginSetData(plugin, state);
-
- return RPMRC_OK;
+ return RPMRC_OK;
}
static void reflink_cleanup(rpmPlugin plugin) {
- reflink_state state = rpmPluginGetData(plugin);
- free(state->buffer);
- free(state);
+ reflink_state state = rpmPluginGetData(plugin);
+ free(state->buffer);
+ free(state);
}
static rpmRC reflink_psm_pre(rpmPlugin plugin, rpmte te) {
reflink_state state = rpmPluginGetData(plugin);
state->fd = rpmteFd(te);
if (state->fd == 0) {
- rpmlog(RPMLOG_DEBUG, _("reflink: fd = 0, no install\n"));
- return RPMRC_OK;
+ rpmlog(RPMLOG_DEBUG, _("reflink: fd = 0, no install\n"));
+ return RPMRC_OK;
}
rpm_loff_t current = Ftell(state->fd);
uint64_t magic;
if (Fseek(state->fd, -(sizeof(magic)), SEEK_END) < 0) {
- rpmlog(RPMLOG_ERR, _("reflink: failed to seek for magic\n"));
- if (Fseek(state->fd, current, SEEK_SET) < 0) {
- /* yes this gets a bit repetitive */
- rpmlog(RPMLOG_ERR, _("reflink: unable to seek back to original location\n"));
- }
- return RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("reflink: failed to seek for magic\n"));
+ if (Fseek(state->fd, current, SEEK_SET) < 0) {
+ /* yes this gets a bit repetitive */
+ rpmlog(RPMLOG_ERR,
+ _("reflink: unable to seek back to original location\n"));
+ }
+ return RPMRC_FAIL;
}
size_t len = sizeof(magic);
if (Fread(&magic, len, 1, state->fd) != len) {
- rpmlog(RPMLOG_ERR, _("reflink: unable to read magic\n"));
- if (Fseek(state->fd, current, SEEK_SET) < 0) {
- rpmlog(RPMLOG_ERR, _("reflink: unable to seek back to original location\n"));
- }
- return RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("reflink: unable to read magic\n"));
+ if (Fseek(state->fd, current, SEEK_SET) < 0) {
+ rpmlog(RPMLOG_ERR,
+ _("reflink: unable to seek back to original location\n"));
+ }
+ return RPMRC_FAIL;
}
if (magic != MAGIC) {
- rpmlog(RPMLOG_DEBUG, _("reflink: not transcoded\n"));
- if (Fseek(state->fd, current, SEEK_SET) < 0) {
- rpmlog(RPMLOG_ERR, _("reflink: unable to seek back to original location\n"));
- return RPMRC_FAIL;
- }
- return RPMRC_OK;
+ rpmlog(RPMLOG_DEBUG, _("reflink: not transcoded\n"));
+ if (Fseek(state->fd, current, SEEK_SET) < 0) {
+ rpmlog(RPMLOG_ERR,
+ _("reflink: unable to seek back to original location\n"));
+ return RPMRC_FAIL;
+ }
+ return RPMRC_OK;
}
rpmlog(RPMLOG_DEBUG, _("reflink: *is* transcoded\n"));
Header h = rpmteHeader(te);
@@ -136,53 +139,60 @@ static rpmRC reflink_psm_pre(rpmPlugin plugin, rpmte te) {
headerPutString(h, RPMTAG_PAYLOADFORMAT, "clon");
headerFree(h);
state->files = rpmteFiles(te);
- /* tail of file contains offset_table, offset_checksums
- then magic
- */
+ /* tail of file contains offset_table, offset_checksums then magic */
if (Fseek(state->fd, -(sizeof(rpm_loff_t) * 2 + sizeof(magic)), SEEK_END) < 0) {
- rpmlog(RPMLOG_ERR, _("reflink: failed to seek for tail %p\n"), state->fd);
- return RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("reflink: failed to seek for tail %p\n"),
+ state->fd);
+ return RPMRC_FAIL;
}
rpm_loff_t table_start;
len = sizeof(table_start);
if (Fread(&table_start, len, 1, state->fd) != len) {
- rpmlog(RPMLOG_ERR, _("reflink: unable to read table_start\n"));
- return RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("reflink: unable to read table_start\n"));
+ return RPMRC_FAIL;
}
if (Fseek(state->fd, table_start, SEEK_SET) < 0) {
- rpmlog(RPMLOG_ERR, _("reflink: unable to seek to table_start\n"));
- return RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("reflink: unable to seek to table_start\n"));
+ return RPMRC_FAIL;
}
len = sizeof(state->keys);
if (Fread(&state->keys, len, 1, state->fd) != len) {
- rpmlog(RPMLOG_ERR, _("reflink: unable to read number of keys\n"));
- return RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("reflink: unable to read number of keys\n"));
+ return RPMRC_FAIL;
}
len = sizeof(state->keysize);
if (Fread(&state->keysize, len, 1, state->fd) != len) {
- rpmlog(RPMLOG_ERR, _("reflink: unable to read keysize\n"));
- return RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("reflink: unable to read keysize\n"));
+ return RPMRC_FAIL;
}
- rpmlog(RPMLOG_DEBUG, _("reflink: table_start=0x%lx, keys=%d, keysize=%d\n"), table_start, state->keys, state->keysize);
- // now get digest table if there is a reason to have one.
+ rpmlog(
+ RPMLOG_DEBUG,
+ _("reflink: table_start=0x%lx, keys=%d, keysize=%d\n"),
+ table_start, state->keys, state->keysize
+ );
+ /* now get digest table if there is a reason to have one. */
if (state->keys == 0 || state->keysize == 0) {
- // no files (or no digests(!))
- state->table = NULL;
+ /* no files (or no digests(!)) */
+ state->table = NULL;
} else {
- int table_size = state->keys * (state->keysize + sizeof(rpm_loff_t));
- state->table = rcalloc(1, table_size);
- if (Fread(state->table, table_size, 1, state->fd) != table_size) {
- rpmlog(RPMLOG_ERR, _("reflink: unable to read table\n"));
- return RPMRC_FAIL;
- }
- state->inodeIndexes = inodeIndexHashCreate(state->keys, inodeId, inodeCmp, NULL, NULL);
+ int table_size = state->keys * (state->keysize + sizeof(rpm_loff_t));
+ state->table = rcalloc(1, table_size);
+ if (Fread(state->table, table_size, 1, state->fd) != table_size) {
+ rpmlog(RPMLOG_ERR, _("reflink: unable to read table\n"));
+ return RPMRC_FAIL;
+ }
+ state->inodeIndexes = inodeIndexHashCreate(
+ state->keys, inodeId, inodeCmp, NULL, NULL
+ );
}
- // seek back to original location
- // might not be needed if we seek to offset immediately
+ /* Seek back to original location.
+ * Might not be needed if we seek to offset immediately
+ */
if (Fseek(state->fd, current, SEEK_SET) < 0) {
- rpmlog(RPMLOG_ERR, _("reflink: unable to seek back to original location\n"));
- return RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR,
+ _("reflink: unable to seek back to original location\n"));
+ return RPMRC_FAIL;
}
return RPMRC_OK;
}
@@ -192,40 +202,45 @@ static rpmRC reflink_psm_post(rpmPlugin plugin, rpmte te, int res)
reflink_state state = rpmPluginGetData(plugin);
state->files = rpmfilesFree(state->files);
if (state->table) {
- free(state->table);
- state->table = NULL;
+ free(state->table);
+ state->table = NULL;
}
if (state->inodeIndexes) {
- inodeIndexHashFree(state->inodeIndexes);
- state->inodeIndexes = NULL;
+ inodeIndexHashFree(state->inodeIndexes);
+ state->inodeIndexes = NULL;
}
return RPMRC_OK;
}
-// have a prototype, warnings system
+/* have a prototype, warnings system */
rpm_loff_t find(const unsigned char *digest, reflink_state state);
rpm_loff_t find(const unsigned char *digest, reflink_state state) {
# if defined(__GNUC__)
- /* GCC nested function because bsearch's comparison function can't access
- state-keysize otherwise
- */
- int cmpdigest(const void *k1, const void *k2) {
- rpmlog(RPMLOG_DEBUG, _("reflink: cmpdigest k1=%p k2=%p\n"), k1, k2);
- return memcmp(k1, k2, state->keysize);
- }
+ /* GCC nested function because bsearch's comparison function can't access
+ * state-keysize otherwise
+ */
+ int cmpdigest(const void *k1, const void *k2) {
+ rpmlog(RPMLOG_DEBUG, _("reflink: cmpdigest k1=%p k2=%p\n"), k1, k2);
+ return memcmp(k1, k2, state->keysize);
+ }
# endif
- rpmlog(RPMLOG_DEBUG, _("reflink: bsearch(key=%p, base=%p, nmemb=%d, size=%lu)\n"), digest, state->table, state->keys, state->keysize + sizeof(rpm_loff_t));
- char *entry = bsearch(digest, state->table, state->keys, state->keysize + sizeof(rpm_loff_t), cmpdigest);
- if (entry == NULL) {
- return NOT_FOUND;
- }
- rpm_loff_t offset = *(rpm_loff_t *)(entry + state->keysize);
- return offset;
+ rpmlog(RPMLOG_DEBUG,
+ _("reflink: bsearch(key=%p, base=%p, nmemb=%d, size=%lu)\n"),
+ digest, state->table, state->keys,
+ state->keysize + sizeof(rpm_loff_t));
+ char *entry = bsearch(digest, state->table, state->keys,
+ state->keysize + sizeof(rpm_loff_t), cmpdigest);
+ if (entry == NULL) {
+ return NOT_FOUND;
+ }
+ rpm_loff_t offset = *(rpm_loff_t *)(entry + state->keysize);
+ return offset;
}
-static rpmRC reflink_fsm_file_pre(rpmPlugin plugin, rpmfi fi, const char* path, mode_t file_mode, rpmFsmOp op)
+static rpmRC reflink_fsm_file_pre(rpmPlugin plugin, rpmfi fi, const char* path,
+ mode_t file_mode, rpmFsmOp op)
{
struct file_clone_range fcr;
rpm_loff_t size;
@@ -234,99 +249,119 @@ static rpmRC reflink_fsm_file_pre(rpmPlugin plugin, rpmfi fi, const char* path,
reflink_state state = rpmPluginGetData(plugin);
if (state->table == NULL) {
- // no table means rpm is not in reflink format, so leave. Now.
- return RPMRC_OK;
+ /* no table means rpm is not in reflink format, so leave. Now. */
+ return RPMRC_OK;
}
if (op == FA_TOUCH) {
- // we're not overwriting an existing file
- return RPMRC_OK;
+ /* we're not overwriting an existing file. */
+ return RPMRC_OK;
}
fcr.dest_offset = 0;
if (S_ISREG(file_mode) && !(rpmfiFFlags(fi) & RPMFILE_GHOST)) {
- rpm_ino_t inode = rpmfiFInode(fi);
- /* check for hard link entry in table. GetEntry overwrites hlix with the address of the first match */
- if (inodeIndexHashGetEntry(state->inodeIndexes, inode, &hlix, NULL, NULL)) {
- // entry is in table, use hard link
- char *fn = rpmfilesFN(state->files, hlix[0]);
- if (link(fn, path) != 0) {
- rpmlog(RPMLOG_ERR, _("reflink: Unable to hard link %s -> %s due to %s\n"), fn, path, strerror(errno));
- free(fn);
- return RPMRC_FAIL;
- }
- free(fn);
- return RPMRC_PLUGIN_CONTENTS;
- }
- /* if we didn't hard link, then we'll track this inode as being created soon */
- if (rpmfiFNlink(fi) > 1) {
- /* minor optimization: only store files with more than one link */
- inodeIndexHashAddEntry(state->inodeIndexes, inode, rpmfiFX(fi));
- }
- /* derived from wfd_open in fsm.c */
- mode_t old_umask = umask(0577);
- dst = open(path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR);
- umask(old_umask);
- if (dst == -1) {
- rpmlog(RPMLOG_ERR, _("reflink: Unable to open %s for writing due to %s, flags = %x\n"), path, strerror(errno), rpmfiFFlags(fi));
- return RPMRC_FAIL;
- }
- size = rpmfiFSize(fi);
- if (size > 0) {
- /* round src_length down to fundamental_block_size multiple */
- fcr.src_length = size / state->fundamental_block_size * state->fundamental_block_size;
- if ((size % state->fundamental_block_size) > 0) {
- /* round up to next fundamental_block_size. We expect the data in the rpm to be similarly padded */
- fcr.src_length += state->fundamental_block_size;
- }
- fcr.src_fd = Fileno(state->fd);
- if (fcr.src_fd == -1) {
- close(dst);
- rpmlog(RPMLOG_ERR, _("reflink: src fd lookup failed\n"));
- return RPMRC_FAIL;
- }
- fcr.src_offset = find(rpmfiFDigest(fi, NULL, NULL), state);
- if (fcr.src_offset == NOT_FOUND) {
- close(dst);
- rpmlog(RPMLOG_ERR, _("reflink: digest not found\n"));
- return RPMRC_FAIL;
- }
- rpmlog(RPMLOG_DEBUG, _("reflink: Reflinking %lu bytes at %lu to %s orig size=%lu, file=%ld\n"), fcr.src_length, fcr.src_offset, path, size, fcr.src_fd);
- rc = ioctl(dst, FICLONERANGE, &fcr);
- if (rc) {
- rpmlog(RPMLOG_WARNING, _("reflink: falling back to copying bits for %s due to %d, %d = %s\n"), path, rc, errno, strerror(errno));
- if (Fseek(state->fd, fcr.src_offset, SEEK_SET) < 0) {
- close(dst);
- rpmlog(RPMLOG_ERR, _("reflink: unable to seek on copying bits\n"));
- return RPMRC_FAIL;
- }
- rpm_loff_t left = size;
- size_t len, read, written;
- while (left) {
- len = (left > BUFFER_SIZE ? BUFFER_SIZE : left);
- read = Fread(state->buffer, len, 1, state->fd);
- if (read != len) {
- close(dst);
- rpmlog(RPMLOG_ERR, _("reflink: short read on copying bits\n"));
- return RPMRC_FAIL;
- }
- written = write(dst, state->buffer, len);
- if (read != written) {
- close(dst);
- rpmlog(RPMLOG_ERR, _("reflink: short write on copying bits\n"));
- return RPMRC_FAIL;
- }
- left -= len;
- }
- } else {
- /* reflink worked, so truncate */
- rc = ftruncate(dst, size);
- if (rc) {
- rpmlog(RPMLOG_ERR, _("reflink: Unable to truncate %s to %ld due to %s\n"), path, size, strerror(errno));
- return RPMRC_FAIL;
- }
- }
- }
- close(dst);
- return RPMRC_PLUGIN_CONTENTS;
+ rpm_ino_t inode = rpmfiFInode(fi);
+ /* check for hard link entry in table. GetEntry overwrites hlix with
+ * the address of the first match.
+ */
+ if (inodeIndexHashGetEntry(state->inodeIndexes, inode, &hlix, NULL,
+ NULL)) {
+ /* entry is in table, use hard link */
+ char *fn = rpmfilesFN(state->files, hlix[0]);
+ if (link(fn, path) != 0) {
+ rpmlog(RPMLOG_ERR,
+ _("reflink: Unable to hard link %s -> %s due to %s\n"),
+ fn, path, strerror(errno));
+ free(fn);
+ return RPMRC_FAIL;
+ }
+ free(fn);
+ return RPMRC_PLUGIN_CONTENTS;
+ }
+ /* if we didn't hard link, then we'll track this inode as being
+ * created soon
+ */
+ if (rpmfiFNlink(fi) > 1) {
+ /* minor optimization: only store files with more than one link */
+ inodeIndexHashAddEntry(state->inodeIndexes, inode, rpmfiFX(fi));
+ }
+ /* derived from wfd_open in fsm.c */
+ mode_t old_umask = umask(0577);
+ dst = open(path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR);
+ umask(old_umask);
+ if (dst == -1) {
+ rpmlog(RPMLOG_ERR,
+ _("reflink: Unable to open %s for writing due to %s, flags = %x\n"),
+ path, strerror(errno), rpmfiFFlags(fi));
+ return RPMRC_FAIL;
+ }
+ size = rpmfiFSize(fi);
+ if (size > 0) {
+ /* round src_length down to fundamental_block_size multiple */
+ fcr.src_length = size / state->fundamental_block_size * state->fundamental_block_size;
+ if ((size % state->fundamental_block_size) > 0) {
+ /* round up to next fundamental_block_size. We expect the data
+ * in the rpm to be similarly padded.
+ */
+ fcr.src_length += state->fundamental_block_size;
+ }
+ fcr.src_fd = Fileno(state->fd);
+ if (fcr.src_fd == -1) {
+ close(dst);
+ rpmlog(RPMLOG_ERR, _("reflink: src fd lookup failed\n"));
+ return RPMRC_FAIL;
+ }
+ fcr.src_offset = find(rpmfiFDigest(fi, NULL, NULL), state);
+ if (fcr.src_offset == NOT_FOUND) {
+ close(dst);
+ rpmlog(RPMLOG_ERR, _("reflink: digest not found\n"));
+ return RPMRC_FAIL;
+ }
+ rpmlog(RPMLOG_DEBUG,
+ _("reflink: Reflinking %lu bytes at %lu to %s orig size=%lu, file=%ld\n"),
+ fcr.src_length, fcr.src_offset, path, size, fcr.src_fd);
+ rc = ioctl(dst, FICLONERANGE, &fcr);
+ if (rc) {
+ rpmlog(RPMLOG_WARNING,
+ _("reflink: falling back to copying bits for %s due to %d, %d = %s\n"),
+ path, rc, errno, strerror(errno));
+ if (Fseek(state->fd, fcr.src_offset, SEEK_SET) < 0) {
+ close(dst);
+ rpmlog(RPMLOG_ERR,
+ _("reflink: unable to seek on copying bits\n"));
+ return RPMRC_FAIL;
+ }
+ rpm_loff_t left = size;
+ size_t len, read, written;
+ while (left) {
+ len = (left > BUFFER_SIZE ? BUFFER_SIZE : left);
+ read = Fread(state->buffer, len, 1, state->fd);
+ if (read != len) {
+ close(dst);
+ rpmlog(RPMLOG_ERR,
+ _("reflink: short read on copying bits\n"));
+ return RPMRC_FAIL;
+ }
+ written = write(dst, state->buffer, len);
+ if (read != written) {
+ close(dst);
+ rpmlog(RPMLOG_ERR,
+ _("reflink: short write on copying bits\n"));
+ return RPMRC_FAIL;
+ }
+ left -= len;
+ }
+ } else {
+ /* reflink worked, so truncate */
+ rc = ftruncate(dst, size);
+ if (rc) {
+ rpmlog(RPMLOG_ERR,
+ _("reflink: Unable to truncate %s to %ld due to %s\n"),
+ path, size, strerror(errno));
+ return RPMRC_FAIL;
+ }
+ }
+ }
+ close(dst);
+ return RPMRC_PLUGIN_CONTENTS;
}
return RPMRC_OK;
}
diff --git a/rpm2extents.c b/rpm2extents.c
index 5662b86a6..c111be0a2 100644
--- a/rpm2extents.c
+++ b/rpm2extents.c
@@ -24,7 +24,7 @@
#include "debug.h"
/* hash of void * (pointers) to file digests to offsets within output.
- The length of the key depends on what the FILEDIGESTALGO is.
+ * The length of the key depends on what the FILEDIGESTALGO is.
*/
#undef HASHTYPE
#undef HTKEYTYPE
@@ -34,7 +34,9 @@
#include "lib/rpmhash.H"
#include "lib/rpmhash.C"
-/* magic value at end of file (64 bits) that indicates this is a transcoded rpm */
+/* magic value at end of file (64 bits) that indicates this is a transcoded
+ * rpm.
+ */
#define MAGIC 3472329499408095051
struct digestoffset {
@@ -64,77 +66,54 @@ static int digestor(
int algo;
rpmRC rc = RPMRC_FAIL;
- for (algo = 0; algo < algos_len; algo++)
- {
- fdInitDigest(fdi, algos[algo], 0);
+ for (algo = 0; algo < algos_len; algo++) {
+ fdInitDigest(fdi, algos[algo], 0);
}
fdilength = ufdCopy(fdi, fdo);
- if (fdilength == -1)
- {
- fprintf(stderr, _("digest cat failed\n"));
- goto exit;
+ if (fdilength == -1) {
+ fprintf(stderr, _("digest cat failed\n"));
+ goto exit;
}
len = sizeof(fdilength);
- if (Fwrite(&fdilength, len, 1, validationo) != len)
- {
- fprintf(stderr, _("Unable to write input length %zd\n"), fdilength);
- goto exit;
+ if (Fwrite(&fdilength, len, 1, validationo) != len) {
+ fprintf(stderr, _("Unable to write input length %zd\n"), fdilength);
+ goto exit;
}
len = sizeof(algos_len);
- if (Fwrite(&algos_len, len, 1, validationo) != len)
- {
- fprintf(stderr, _("Unable to write number of validation digests\n"));
- goto exit;
+ if (Fwrite(&algos_len, len, 1, validationo) != len) {
+ fprintf(stderr, _("Unable to write number of validation digests\n"));
+ goto exit;
}
- for (algo = 0; algo < algos_len; algo++)
- {
- fdFiniDigest(fdi, algos[algo], (void **)&filedigest, &filedigest_len, 0);
-
- algo_name = pgpValString(PGPVAL_HASHALGO, algos[algo]);
- algo_name_len = (uint32_t)strlen(algo_name);
- algo_digest_len = (uint32_t)filedigest_len;
-
- len = sizeof(algo_name_len);
- if (Fwrite(&algo_name_len, len, 1, validationo) != len)
- {
- fprintf(
- stderr,
- _("Unable to write validation algo name length\n")
- );
- goto exit;
- }
- len = sizeof(algo_digest_len);
- if (Fwrite(&algo_digest_len, len, 1, validationo) != len)
- {
- fprintf(
- stderr,
- _("Unable to write number of bytes for validation digest\n")
- );
- goto exit;
- }
- if (Fwrite(algo_name, algo_name_len, 1, validationo) != algo_name_len)
- {
- fprintf(stderr, _("Unable to write validation algo name\n"));
- goto exit;
- }
- if (
- Fwrite(
- filedigest,
- algo_digest_len,
- 1,
- validationo
- ) != algo_digest_len
- )
- {
- fprintf(
- stderr,
- _("Unable to write validation digest value %u, %zu\n"),
- algo_digest_len,
- filedigest_len
- );
- goto exit;
- }
+ for (algo = 0; algo < algos_len; algo++) {
+ fdFiniDigest(fdi, algos[algo], (void **)&filedigest, &filedigest_len, 0);
+
+ algo_name = pgpValString(PGPVAL_HASHALGO, algos[algo]);
+ algo_name_len = (uint32_t)strlen(algo_name);
+ algo_digest_len = (uint32_t)filedigest_len;
+
+ len = sizeof(algo_name_len);
+ if (Fwrite(&algo_name_len, len, 1, validationo) != len) {
+ fprintf(stderr,
+ _("Unable to write validation algo name length\n"));
+ goto exit;
+ }
+ len = sizeof(algo_digest_len);
+ if (Fwrite(&algo_digest_len, len, 1, validationo) != len) {
+ fprintf(stderr,
+ _("Unable to write number of bytes for validation digest\n"));
+ goto exit;
+ }
+ if (Fwrite(algo_name, algo_name_len, 1, validationo) != algo_name_len) {
+ fprintf(stderr, _("Unable to write validation algo name\n"));
+ goto exit;
+ }
+ if (Fwrite(filedigest, algo_digest_len, 1, validationo ) != algo_digest_len) {
+ fprintf(stderr,
+ _("Unable to write validation digest value %u, %zu\n"),
+ algo_digest_len, filedigest_len);
+ goto exit;
+ }
}
rc = RPMRC_OK;
exit:
@@ -145,23 +124,20 @@ static rpmRC process_package(FD_t fdi, FD_t validationi)
{
uint32_t diglen;
/* GNU C extension: can use diglen from outer context */
- int digestSetCmp(const unsigned char * a, const unsigned char * b)
- {
- return memcmp(a, b, diglen);
+ int digestSetCmp(const unsigned char * a, const unsigned char * b) {
+ return memcmp(a, b, diglen);
}
- unsigned int digestSetHash(const unsigned char * digest)
- {
+ unsigned int digestSetHash(const unsigned char * digest) {
/* assumes sizeof(unsigned int) < diglen */
return *(unsigned int *)digest;
}
- int digestoffsetCmp(const void * a, const void * b)
- {
- return digestSetCmp(
- ((struct digestoffset *)a)->digest,
- ((struct digestoffset *)b)->digest
- );
+ int digestoffsetCmp(const void * a, const void * b) {
+ return digestSetCmp(
+ ((struct digestoffset *)a)->digest,
+ ((struct digestoffset *)b)->digest
+ );
}
FD_t fdo;
@@ -179,65 +155,52 @@ static rpmRC process_package(FD_t fdi, FD_t validationi)
fdo = fdDup(STDOUT_FILENO);
- if (rpmReadPackageRaw(fdi, &sigh, &h))
- {
- fprintf(stderr, _("Error reading package\n"));
- exit(EXIT_FAILURE);
+ if (rpmReadPackageRaw(fdi, &sigh, &h)) {
+ fprintf(stderr, _("Error reading package\n"));
+ exit(EXIT_FAILURE);
}
if (rpmLeadWrite(fdo, h))
{
- fprintf(
- stderr,
- _("Unable to write package lead: %s\n"),
- Fstrerror(fdo)
- );
- exit(EXIT_FAILURE);
+ fprintf(stderr, _("Unable to write package lead: %s\n"),
+ Fstrerror(fdo));
+ exit(EXIT_FAILURE);
}
- if (rpmWriteSignature(fdo, sigh))
- {
- fprintf(stderr, _("Unable to write signature: %s\n"), Fstrerror(fdo));
- exit(EXIT_FAILURE);
+ if (rpmWriteSignature(fdo, sigh)) {
+ fprintf(stderr, _("Unable to write signature: %s\n"), Fstrerror(fdo));
+ exit(EXIT_FAILURE);
}
- if (headerWrite(fdo, h, HEADER_MAGIC_YES))
- {
- fprintf(stderr, _("Unable to write headers: %s\n"), Fstrerror(fdo));
- exit(EXIT_FAILURE);
+ if (headerWrite(fdo, h, HEADER_MAGIC_YES)) {
+ fprintf(stderr, _("Unable to write headers: %s\n"), Fstrerror(fdo));
+ exit(EXIT_FAILURE);
}
/* Retrieve payload size and compression type. */
- { const char *compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR);
- rpmio_flags = rstrscat(NULL, "r.", compr ? compr : "gzip", NULL);
+ {
+ const char *compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR);
+ rpmio_flags = rstrscat(NULL, "r.", compr ? compr : "gzip", NULL);
}
gzdi = Fdopen(fdi, rpmio_flags); /* XXX gzdi == fdi */
free(rpmio_flags);
- if (gzdi == NULL)
- {
- fprintf(stderr, _("cannot re-open payload: %s\n"), Fstrerror(gzdi));
- exit(EXIT_FAILURE);
+ if (gzdi == NULL) {
+ fprintf(stderr, _("cannot re-open payload: %s\n"), Fstrerror(gzdi));
+ exit(EXIT_FAILURE);
}
rpmfiles files = rpmfilesNew(NULL, h, 0, RPMFI_KEEPHEADER);
- rpmfi fi = rpmfiNewArchiveReader(
- gzdi,
- files,
- RPMFI_ITER_READ_ARCHIVE_CONTENT_FIRST
- );
+ rpmfi fi = rpmfiNewArchiveReader(gzdi, files,
+ RPMFI_ITER_READ_ARCHIVE_CONTENT_FIRST);
/* this is encoded in the file format, so needs to be fixed size (for
- now?)
- */
+ * now?)
+ */
diglen = (uint32_t)rpmDigestLength(rpmfiDigestAlgo(fi));
- digestSet ds = digestSetCreate(
- rpmfiFC(fi),
- digestSetHash,
- digestSetCmp,
- NULL
- );
+ digestSet ds = digestSetCreate(rpmfiFC(fi), digestSetHash, digestSetCmp,
+ NULL);
struct digestoffset offsets[rpmfiFC(fi)];
pos = RPMLEAD_SIZE + headerSizeof(sigh, HEADER_MAGIC_YES);
@@ -247,139 +210,114 @@ static rpmRC process_package(FD_t fdi, FD_t validationi)
zeros = xcalloc(fundamental_block_size, 1);
- while (next >= 0)
- {
- next = rpmfiNext(fi);
- if (next == RPMERR_ITER_END)
- {
- rc = RPMRC_OK;
- break;
- }
- mode = rpmfiFMode(fi);
- if (!S_ISREG(mode) || !rpmfiArchiveHasContent(fi))
- {
- /* not a regular file, or the archive doesn't contain any content for
- this entry
- */
- continue;
- }
- digest = rpmfiFDigest(fi, NULL, NULL);
- if (digestSetGetEntry(ds, digest, NULL))
- {
- /* This specific digest has already been included, so skip it */
- continue;
- }
- pad = pad_to(pos, fundamental_block_size);
- if (Fwrite(zeros, sizeof(char), pad, fdo) != pad)
- {
- fprintf(stderr, _("Unable to write padding\n"));
- rc = RPMRC_FAIL;
- goto exit;
- }
- /* round up to next fundamental_block_size */
- pos += pad;
- digestSetAddEntry(ds, digest);
- offsets[offset_ix].digest = digest;
- offsets[offset_ix].pos = pos;
- offset_ix++;
- size = rpmfiFSize(fi);
- rc = rpmfiArchiveReadToFile(fi, fdo, 0);
- if (rc != RPMRC_OK)
- {
- fprintf(stderr, _("rpmfiArchiveReadToFile failed with %d\n"), rc);
- goto exit;
- }
- pos += size;
+ while (next >= 0) {
+ next = rpmfiNext(fi);
+ if (next == RPMERR_ITER_END) {
+ rc = RPMRC_OK;
+ break;
+ }
+ mode = rpmfiFMode(fi);
+ if (!S_ISREG(mode) || !rpmfiArchiveHasContent(fi)) {
+ /* not a regular file, or the archive doesn't contain any content
+ * for this entry.
+ */
+ continue;
+ }
+ digest = rpmfiFDigest(fi, NULL, NULL);
+ if (digestSetGetEntry(ds, digest, NULL)) {
+ /* This specific digest has already been included, so skip it. */
+ continue;
+ }
+ pad = pad_to(pos, fundamental_block_size);
+ if (Fwrite(zeros, sizeof(char), pad, fdo) != pad) {
+ fprintf(stderr, _("Unable to write padding\n"));
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+ /* round up to next fundamental_block_size */
+ pos += pad;
+ digestSetAddEntry(ds, digest);
+ offsets[offset_ix].digest = digest;
+ offsets[offset_ix].pos = pos;
+ offset_ix++;
+ size = rpmfiFSize(fi);
+ rc = rpmfiArchiveReadToFile(fi, fdo, 0);
+ if (rc != RPMRC_OK) {
+ fprintf(stderr, _("rpmfiArchiveReadToFile failed with %d\n"), rc);
+ goto exit;
+ }
+ pos += size;
}
Fclose(gzdi); /* XXX gzdi == fdi */
- qsort(
- offsets,
- (size_t)offset_ix,
- sizeof(struct digestoffset),
- digestoffsetCmp
- );
+ qsort(offsets, (size_t)offset_ix, sizeof(struct digestoffset),
+ digestoffsetCmp);
len = sizeof(offset_ix);
- if (Fwrite(&offset_ix, len, 1, fdo) != len)
- {
- fprintf(stderr, _("Unable to write length of table\n"));
- rc = RPMRC_FAIL;
- goto exit;
+ if (Fwrite(&offset_ix, len, 1, fdo) != len) {
+ fprintf(stderr, _("Unable to write length of table\n"));
+ rc = RPMRC_FAIL;
+ goto exit;
}
len = sizeof(diglen);
- if (Fwrite(&diglen, len, 1, fdo) != len)
- {
- fprintf(stderr, _("Unable to write length of digest\n"));
- rc = RPMRC_FAIL;
- goto exit;
+ if (Fwrite(&diglen, len, 1, fdo) != len) {
+ fprintf(stderr, _("Unable to write length of digest\n"));
+ rc = RPMRC_FAIL;
+ goto exit;
}
len = sizeof(rpm_loff_t);
- for (int x = 0; x < offset_ix; x++)
- {
- if (Fwrite(offsets[x].digest, diglen, 1, fdo) != diglen)
- {
- fprintf(stderr, _("Unable to write digest\n"));
- rc = RPMRC_FAIL;
- goto exit;
- }
- if (Fwrite(&offsets[x].pos, len, 1, fdo) != len)
- {
- fprintf(stderr, _("Unable to write offset\n"));
- rc = RPMRC_FAIL;
- goto exit;
- }
+ for (int x = 0; x < offset_ix; x++) {
+ if (Fwrite(offsets[x].digest, diglen, 1, fdo) != diglen) {
+ fprintf(stderr, _("Unable to write digest\n"));
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+ if (Fwrite(&offsets[x].pos, len, 1, fdo) != len) {
+ fprintf(stderr, _("Unable to write offset\n"));
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
}
validation_pos = (
- pos + sizeof(offset_ix) + sizeof(diglen) +
- offset_ix * (diglen + sizeof(rpm_loff_t))
+ pos + sizeof(offset_ix) + sizeof(diglen) +
+ offset_ix * (diglen + sizeof(rpm_loff_t))
);
ssize_t validation_len = ufdCopy(validationi, fdo);
- if (validation_len == -1)
- {
- fprintf(stderr, _("digest table ufdCopy failed\n"));
- rc = RPMRC_FAIL;
- goto exit;
+ if (validation_len == -1) {
+ fprintf(stderr, _("digest table ufdCopy failed\n"));
+ rc = RPMRC_FAIL;
+ goto exit;
}
/* add more padding so the last file can be cloned. It doesn't matter that
- the table and validation etc are in this space. In fact, it's pretty
- efficient if it is
+ * the table and validation etc are in this space. In fact, it's pretty
+ * efficient if it is.
*/
- pad = pad_to(
- (
- validation_pos + validation_len + 2 * sizeof(rpm_loff_t) +
- sizeof(uint64_t)
- ),
- fundamental_block_size
- );
- if (Fwrite(zeros, sizeof(char), pad, fdo) != pad)
- {
- fprintf(stderr, _("Unable to write final padding\n"));
- rc = RPMRC_FAIL;
- goto exit;
+ pad = pad_to((validation_pos + validation_len + 2 * sizeof(rpm_loff_t) +
+ sizeof(uint64_t)), fundamental_block_size);
+ if (Fwrite(zeros, sizeof(char), pad, fdo) != pad) {
+ fprintf(stderr, _("Unable to write final padding\n"));
+ rc = RPMRC_FAIL;
+ goto exit;
}
zeros = _free(zeros);
- if (Fwrite(&pos, len, 1, fdo) != len)
- {
- fprintf(stderr, _("Unable to write offset of digest table\n"));
- rc = RPMRC_FAIL;
- goto exit;
+ if (Fwrite(&pos, len, 1, fdo) != len) {
+ fprintf(stderr, _("Unable to write offset of digest table\n"));
+ rc = RPMRC_FAIL;
+ goto exit;
}
- if (Fwrite(&validation_pos, len, 1, fdo) != len)
- {
- fprintf(stderr, _("Unable to write offset of validation table\n"));
- rc = RPMRC_FAIL;
- goto exit;
+ if (Fwrite(&validation_pos, len, 1, fdo) != len) {
+ fprintf(stderr, _("Unable to write offset of validation table\n"));
+ rc = RPMRC_FAIL;
+ goto exit;
}
uint64_t magic = MAGIC;
len = sizeof(magic);
- if (Fwrite(&magic, len, 1, fdo) != len)
- {
- fprintf(stderr, _("Unable to write magic\n"));
- rc = RPMRC_FAIL;
- goto exit;
+ if (Fwrite(&magic, len, 1, fdo) != len) {
+ fprintf(stderr, _("Unable to write magic\n"));
+ rc = RPMRC_FAIL;
+ goto exit;
}
exit:
@@ -389,8 +327,7 @@ exit:
return rc;
}
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
rpmRC rc;
int cprc = 0;
uint8_t algos[argc - 1];
@@ -402,118 +339,95 @@ int main(int argc, char *argv[])
xsetprogname(argv[0]); /* Portability call -- see system.h */
rpmReadConfigFiles(NULL, NULL);
- if (argc > 1 && (rstreq(argv[1], "-h") || rstreq(argv[1], "--help")))
- {
- fprintf(stderr, _("Usage: %s [DIGESTALGO]...\n"), argv[0]);
- exit(EXIT_FAILURE);
+ if (argc > 1 && (rstreq(argv[1], "-h") || rstreq(argv[1], "--help"))) {
+ fprintf(stderr, _("Usage: %s [DIGESTALGO]...\n"), argv[0]);
+ exit(EXIT_FAILURE);
}
- if (argc == 1)
- {
- fprintf(
- stderr,
- _("Need at least one DIGESTALGO parameter, e.g. 'SHA256'\n")
- );
- exit(EXIT_FAILURE);
+ if (argc == 1) {
+ fprintf(stderr,
+ _("Need at least one DIGESTALGO parameter, e.g. 'SHA256'\n"));
+ exit(EXIT_FAILURE);
}
- for (int x = 0; x < (argc - 1); x++)
- {
- if (pgpStringVal(PGPVAL_HASHALGO, argv[x + 1], &algos[x]) != 0)
- {
- fprintf(
- stderr,
- _("Unable to resolve '%s' as a digest algorithm, exiting\n"),
- argv[x + 1]
- );
- exit(EXIT_FAILURE);
- }
+ for (int x = 0; x < (argc - 1); x++) {
+ if (pgpStringVal(PGPVAL_HASHALGO, argv[x + 1], &algos[x]) != 0)
+ {
+ fprintf(stderr,
+ _("Unable to resolve '%s' as a digest algorithm, exiting\n"),
+ argv[x + 1]);
+ exit(EXIT_FAILURE);
+ }
}
- if (pipe(mainpipefd) == -1)
- {
- fprintf(stderr, _("Main pipe failure\n"));
- exit(EXIT_FAILURE);
+ if (pipe(mainpipefd) == -1) {
+ fprintf(stderr, _("Main pipe failure\n"));
+ exit(EXIT_FAILURE);
}
- if (pipe(metapipefd) == -1)
- {
- fprintf(stderr, _("Meta pipe failure\n"));
- exit(EXIT_FAILURE);
+ if (pipe(metapipefd) == -1) {
+ fprintf(stderr, _("Meta pipe failure\n"));
+ exit(EXIT_FAILURE);
}
cpid = fork();
- if (cpid == 0)
- {
- /* child: digestor */
- close(mainpipefd[0]);
- close(metapipefd[0]);
- FD_t fdi = fdDup(STDIN_FILENO);
- FD_t fdo = fdDup(mainpipefd[1]);
- FD_t validationo = fdDup(metapipefd[1]);
- rc = digestor(fdi, fdo, validationo, algos, argc - 1);
- Fclose(validationo);
- Fclose(fdo);
- Fclose(fdi);
+ if (cpid == 0) {
+ /* child: digestor */
+ close(mainpipefd[0]);
+ close(metapipefd[0]);
+ FD_t fdi = fdDup(STDIN_FILENO);
+ FD_t fdo = fdDup(mainpipefd[1]);
+ FD_t validationo = fdDup(metapipefd[1]);
+ rc = digestor(fdi, fdo, validationo, algos, argc - 1);
+ Fclose(validationo);
+ Fclose(fdo);
+ Fclose(fdi);
} else {
- /* parent: main program */
- close(mainpipefd[1]);
- close(metapipefd[1]);
- FD_t fdi = fdDup(mainpipefd[0]);
- FD_t validationi = fdDup(metapipefd[0]);
- rc = process_package(fdi, validationi);
- Fclose(validationi);
- /* fdi is normally closed through the stacked file gzdi in the function. */
- /* wait for child process (digestor for stdin) to complete. */
- if (rc != RPMRC_OK)
- {
- if (kill(cpid, SIGTERM) != 0)
- {
- fprintf(
- stderr,
- _("Failed to kill digest process when main process failed: %s\n"),
- strerror(errno)
- );
- }
- }
- w = waitpid(cpid, &wstatus, 0);
- if (w == -1)
- {
- fprintf(stderr, _("waitpid failed\n"));
- cprc = EXIT_FAILURE;
- } else if (WIFEXITED(wstatus))
- {
- cprc = WEXITSTATUS(wstatus);
- if (cprc != 0)
- {
- fprintf(
- stderr,
- _("Digest process non-zero exit code %d\n"),
- cprc
- );
- }
- } else if (WIFSIGNALED(wstatus))
- {
- fprintf(
- stderr,
- _("Digest process was terminated with a signal: %d\n"),
- WTERMSIG(wstatus)
- );
- cprc = EXIT_FAILURE;
- } else
- {
- /* don't think this can happen, but covering all bases */
- fprintf(stderr, _("Unhandled circumstance in waitpid\n"));
- cprc = EXIT_FAILURE;
- }
- if (cprc != EXIT_SUCCESS)
- {
- rc = RPMRC_FAIL;
- }
+ /* parent: main program */
+ close(mainpipefd[1]);
+ close(metapipefd[1]);
+ FD_t fdi = fdDup(mainpipefd[0]);
+ FD_t validationi = fdDup(metapipefd[0]);
+ rc = process_package(fdi, validationi);
+ Fclose(validationi);
+ /* fdi is normally closed through the stacked file gzdi in the
+ * function.
+ * Wait for child process (digestor for stdin) to complete.
+ */
+ if (rc != RPMRC_OK) {
+ if (kill(cpid, SIGTERM) != 0) {
+ fprintf(stderr,
+ _("Failed to kill digest process when main process failed: %s\n"),
+ strerror(errno));
+ }
+ }
+ w = waitpid(cpid, &wstatus, 0);
+ if (w == -1) {
+ fprintf(stderr, _("waitpid failed\n"));
+ cprc = EXIT_FAILURE;
+ } else if (WIFEXITED(wstatus)) {
+ cprc = WEXITSTATUS(wstatus);
+ if (cprc != 0) {
+ fprintf(stderr,
+ _("Digest process non-zero exit code %d\n"),
+ cprc);
+ }
+ } else if (WIFSIGNALED(wstatus)) {
+ fprintf(stderr,
+ _("Digest process was terminated with a signal: %d\n"),
+ WTERMSIG(wstatus));
+ cprc = EXIT_FAILURE;
+ } else {
+ /* Don't think this can happen, but covering all bases */
+ fprintf(stderr, _("Unhandled circumstance in waitpid\n"));
+ cprc = EXIT_FAILURE;
+ }
+ if (cprc != EXIT_SUCCESS) {
+ rc = RPMRC_FAIL;
+ }
}
- if (rc != RPMRC_OK)
- {
- /* translate rpmRC into generic failure return code. */
- return EXIT_FAILURE;
+ if (rc != RPMRC_OK) {
+ /* translate rpmRC into generic failure return code. */
+ return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
--
2.35.1