From 50ada341c2ef6d348c59b4478fdfacf956369f69 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Mon, 29 Oct 2012 15:55:57 +0100 Subject: [PATCH] unify cookie generation for solv/pysolv/rbsolv/p5solv --- bindings/solv.i | 9 +++++++++ examples/p5solv | 27 +++++++++++++-------------- examples/pysolv | 30 ++++++++++++++---------------- examples/rbsolv | 27 ++++++++++++--------------- examples/solv.c | 15 ++++++--------- 5 files changed, 54 insertions(+), 54 deletions(-) diff --git a/bindings/solv.i b/bindings/solv.i index 4401752..d551957 100644 --- a/bindings/solv.i +++ b/bindings/solv.i @@ -840,6 +840,15 @@ typedef struct { solv_chksum_add($self, &stb.st_size, sizeof(stb.st_size)); solv_chksum_add($self, &stb.st_mtime, sizeof(stb.st_mtime)); } + void add_fstat(int fd) { + struct stat stb; + if (fstat(fd, &stb)) + memset(&stb, 0, sizeof(stb)); + solv_chksum_add($self, &stb.st_dev, sizeof(stb.st_dev)); + solv_chksum_add($self, &stb.st_ino, sizeof(stb.st_ino)); + solv_chksum_add($self, &stb.st_size, sizeof(stb.st_size)); + solv_chksum_add($self, &stb.st_mtime, sizeof(stb.st_mtime)); + } SWIGCDATA raw() { int l; const unsigned char *b; diff --git a/examples/p5solv b/examples/p5solv index 15487e1..9333b44 100755 --- a/examples/p5solv +++ b/examples/p5solv @@ -23,6 +23,7 @@ sub new { sub calc_cookie_fp { my ($self, $fp) = @_; my $chksum = solv::Chksum->new($solv::REPOKEY_TYPE_SHA256); + $chksum->add("1.1"); $chksum->add_fp($fp); return $chksum->raw(); } @@ -35,6 +36,17 @@ sub calc_cookie_file { return $chksum->raw(); } +sub calc_cookie_ext { + my ($self, $f, $cookie) = @_; + my $chksum = solv::Chksum->new($solv::REPOKEY_TYPE_SHA256); + $chksum->add("1.1"); + $chksum->add($cookie); + $chksum->add_fstat(fileno($f)) if $f; + my $extcookie = $chksum->raw(); + substr($extcookie, 0, 1) = chr(1) if ord(substr($extcookie, 0, 1)) == 0; + return $extcookie; +} + sub cachepath { my ($self, $ext) = @_; my $path = $self->{'alias'}; @@ -139,19 +151,6 @@ sub usecachedrepo { return undef; } -sub genextcookie { - my ($self, $f) = @_; - my $chksum = solv::Chksum->new($solv::REPOKEY_TYPE_SHA256); - $chksum->add($self->{'cookie'}); - if ($f) { - my @s = stat($f); - $chksum->add("@s"); - } - my $extcookie = $chksum->raw(); - substr($extcookie, 0, 1) = chr(1) if ord(substr($extcookie, 0, 1)) == 0; - $self->{'extcookie'} = $extcookie; -} - sub writecachedrepo { my ($self, $ext, $info) = @_; mkdir("/var/cache/solv", 0755) unless -d "/var/cache/solv"; @@ -171,7 +170,7 @@ sub writecachedrepo { } solv::xfclose($ff); if ($self->{'type'} ne 'system' && !$ext) { - $self->genextcookie($f) unless $self->{'extcookie'}; + $self->{'extcookie'} ||= $self->calc_cookie_ext($f, $self->{'cookie'}); syswrite($f, $self->{'extcookie'}); } syswrite($f, $ext ? $self->{'extcookie'} : $self->{'cookie'}); diff --git a/examples/pysolv b/examples/pysolv index f529d5d..479aba2 100755 --- a/examples/pysolv +++ b/examples/pysolv @@ -53,9 +53,22 @@ def calc_cookie_file(filename): def calc_cookie_fp(fp): chksum = solv.Chksum(solv.REPOKEY_TYPE_SHA256) + chksum.add("1.1"); chksum.add_fp(fp) return chksum.raw() +def calc_cookie_ext(f, cookie): + chksum = solv.Chksum(solv.REPOKEY_TYPE_SHA256) + chksum.add("1.1"); + chksum.add(cookie) + if f: + chksum.add_fstat(f.fileno()) + extcookie = chksum.raw() + # compatibility to c code + if ord(extcookie[0]) == 0: + extcookie[0] = chr(1) + return extcookie + class repo_generic(dict): def __init__(self, name, type, attribs = {}): for k in attribs: @@ -225,21 +238,6 @@ class repo_generic(dict): return False return True - def genextcookie(self, f): - chksum = solv.Chksum(solv.REPOKEY_TYPE_SHA256) - chksum.add(self['cookie']) - if f: - stat = os.fstat(f.fileno()) - chksum.add(str(stat[ST_DEV])) - chksum.add(str(stat[ST_INO])) - chksum.add(str(stat[ST_SIZE])) - chksum.add(str(stat[ST_MTIME])) - extcookie = chksum.raw() - # compatibility to c code - if ord(extcookie[0]) == 0: - extcookie[0] = chr(1) - self['extcookie'] = extcookie - def writecachedrepo(self, ext, info=None): try: if not os.path.isdir("/var/cache/solv"): @@ -255,7 +253,7 @@ class repo_generic(dict): self.handle.write_first_repodata(f) if self.type != 'system' and not ext: if 'extcookie' not in self: - self.genextcookie(f) + self['extcookie'] = calc_cookie_ext(f, self['cookie']) f.write(self['extcookie']) if not ext: f.write(self['cookie']) diff --git a/examples/rbsolv b/examples/rbsolv index c961b27..250f134 100755 --- a/examples/rbsolv +++ b/examples/rbsolv @@ -27,6 +27,7 @@ class Repo_generic def calc_cookie_fp(f) chksum = Solv::Chksum.new(Solv::REPOKEY_TYPE_SHA256) + chksum.add("1.1") chksum.add_fp(f) return chksum.raw end @@ -38,6 +39,16 @@ class Repo_generic return chksum.raw end + def calc_cookie_ext(f, cookie) + chksum = Solv::Chksum.new(Solv::REPOKEY_TYPE_SHA256) + chksum.add("1.1") + chksum.add(cookie) + chksum.add_fstat(f.fileno) if f + extcookie = chksum.raw() + extcookie[0] = 1 if extcookie[0] == 0 + return extcookie + end + def cachepath(ext = nil) path = @name.sub(/^\./, '_') path += ext ? "_#{ext}.solvx" : '.solv' @@ -147,20 +158,6 @@ class Repo_generic return true end - def genextcookie(f) - chksum = Solv::Chksum.new(Solv::REPOKEY_TYPE_SHA256) - chksum.add(@cookie) - if f - s = f.stat() - chksum.add(s.dev.to_s) - chksum.add(s.ino.to_s) - chksum.add(s.size.to_s) - chksum.add(s.mtime.to_s) - end - @extcookie = chksum.raw() - @extcookie[0] = 1 if @extcookie[0] == 0 - end - def writecachedrepo(ext, info = nil) begin Dir::mkdir("/var/cache/solv", 0755) unless FileTest.directory?("/var/cache/solv") @@ -177,7 +174,7 @@ class Repo_generic Solv::xfclose(sf) f.sysseek(0, IO::SEEK_END) if @type != 'system' && !ext - genextcookie(f) unless @extcookie + @extcookie = calc_cookie_ext(f, @cookie) unless @extcookie f.syswrite(@extcookie) end f.syswrite(ext ? @extcookie : @cookie) diff --git a/examples/solv.c b/examples/solv.c index 7389db1..139529f 100644 --- a/examples/solv.c +++ b/examples/solv.c @@ -1048,10 +1048,12 @@ calc_checksum_fp(FILE *fp, Id chktype, unsigned char *out) } void -calc_checksum_stat(struct stat *stb, Id chktype, unsigned char *out) +calc_checksum_stat(struct stat *stb, Id chktype, unsigned *cookie, unsigned char *out) { void *h = solv_chksum_create(chktype); solv_chksum_add(h, CHKSUM_IDENT, strlen(CHKSUM_IDENT)); + if (cookie) + solv_chksum_add(h, cookie, 32); solv_chksum_add(h, &stb->st_dev, sizeof(stb->st_dev)); solv_chksum_add(h, &stb->st_ino, sizeof(stb->st_ino)); solv_chksum_add(h, &stb->st_size, sizeof(stb->st_size)); @@ -1202,13 +1204,8 @@ writecachedrepo(Repo *repo, Repodata *info, const char *repoext, unsigned char * /* we just need some unique ID */ struct stat stb; if (!fstat(fileno(fp), &stb)) - { - int i; - - calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, cinfo->extcookie); - for (i = 0; i < 32; i++) - cinfo->extcookie[i] ^= cookie[i]; - } + memset(&stb, 0, sizeof(stb)); + calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, cookie, cinfo->extcookie); if (cinfo->extcookie[0] == 0) cinfo->extcookie[0] = 1; } @@ -1712,7 +1709,7 @@ read_repos(Pool *pool, struct repoinfo *repoinfos, int nrepoinfos) printf("no installed database:"); memset(&stb, 0, sizeof(&stb)); #endif - calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, installedcookie); + calc_checksum_stat(&stb, REPOKEY_TYPE_SHA256, 0, installedcookie); if (usecachedrepo(repo, 0, installedcookie, 0)) printf(" cached\n"); else -- 2.7.4