/* cfengine for GNU
 
        Copyright (C) 1995
        Free Software Foundation, Inc.
 
   This file is part of GNU cfengine - written and maintained 
   by Mark Burgess, Dept of Computing and Engineering, Oslo College,
   Dept. of Theoretical physics, University of Oslo
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA

*/
 


/*******************************************************************/
/*                                                                 */
/* Checksums                                                       */
/*                                                                 */
/*******************************************************************/

#include "cf.defs.h"
#include "cf.extern.h"


CompareMD5CheckSums(file1,file2,ip,sstat,dstat)

     /* See the md5 algorithms in pub-lib/md5.c */
     /* file 1 is source                        */

char *file1, *file2;
struct Image *ip;
struct stat *sstat, *dstat;

 { static unsigned char digest1[16], digest2[16];
  int i;

Debug("CompareMD5CheckSums(%s,%s)\n",file1,file2);

if (sstat->st_size != dstat->st_size)
   {
   Debug("File sizes differ, no need to compute checksum\n");
   return true;
   }
  
Debug2("Compare checksums on %s:%s & %s\n",ip->server,file1,file2);

if (strcmp(ip->server,"localhost") == 0)
   {
   cfMDFile(file1,digest1);
   cfMDFile(file2,digest2);

   for (i = 0; i < 16; i++)
      {
      if (digest1[i] != digest2[i])
         {
         Verbose("Checksum (MD5) mismatch...\n");
         return true;
         }
      }

   return false;  /* only if files are identical */
   }
else
   {
   return CompareMD5Net(file1,file2,ip); /* client.c */
   }
}

/*******************************************************************/

CompareBinarySums(file1,file2,ip,sstat,dstat)

     /* See the md5 algorithms in pub-lib/md5.c */
     /* file 1 is source                        */

char *file1, *file2;
struct Image *ip;
struct stat *sstat, *dstat;

 { static unsigned char digest1[16], digest2[16];
   int i,fd1, fd2,bytes1, bytes2;
   char	buff1[BUFSIZ], buff2[BUFSIZ];

Debug("CompareBinarySums(%s,%s)\n",file1,file2);

if (sstat->st_size != dstat->st_size)
   {
   Debug("File sizes differ, no need to compute checksum\n");
   return true;
   }
  
Debug2("Compare binary sums on %s:%s & %s\n",ip->server,file1,file2);

if (strcmp(ip->server,"localhost") == 0)
   {
   fd1 = open(file1, O_RDONLY, 0400);
   fd2 = open(file2, O_RDONLY, 0400);
  
   do
      {
      bytes1 = read(fd1, buff1, BUFSIZ);
      bytes2 = read(fd2, buff2, BUFSIZ);

      if ((bytes1 != bytes2) || (memcmp(buff1, buff2, bytes1) != 0))
	 {
  	 Verbose("Binary Comparison mismatch...\n");
  	 close(fd2);
  	 close(fd1);
  	 return true;
  	 }
      }
   while (bytes1 > 0);
  
   close(fd2);
   close(fd1);

   return false;  /* only if files are identical */
   }
else
   {
   Verbose("Using cached md5 checksum instead\n");
   return CompareMD5Net(file1,file2,ip); /* client.c */
   }
}
