unify cookie generation for solv/pysolv/rbsolv/p5solv
authorMichael Schroeder <mls@suse.de>
Mon, 29 Oct 2012 14:55:57 +0000 (15:55 +0100)
committerMichael Schroeder <mls@suse.de>
Mon, 29 Oct 2012 14:55:57 +0000 (15:55 +0100)
bindings/solv.i
examples/p5solv
examples/pysolv
examples/rbsolv
examples/solv.c

index 4401752..d551957 100644 (file)
@@ -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;
index 15487e1..9333b44 100755 (executable)
@@ -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'});
index f529d5d..479aba2 100755 (executable)
@@ -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'])
index c961b27..250f134 100755 (executable)
@@ -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)
index 7389db1..139529f 100644 (file)
@@ -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