/*  
    File compare utility
    Copyright (c) Tudor Hulubei & Andrei Pitis, April 1994

This file is part of UIT (UNIX Interactive Tools)

UIT 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.

UIT 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
UIT; see the file COPYING.  If not, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA.  */


#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <limits.h>
#include <fcntl.h>


#define CMP_BUFFER_SIZE		64*1024
#define min(a, b) ((a) <= (b) ? (a) : (b))


int filelength(int handle)
{
    int temp, length;
    
    temp = tell(handle);
    lseek(handle, 0, SEEK_END);
    length = tell(handle);
    lseek(handle, temp, SEEK_SET);
    return length;
}


int main(int argc, char *argv[])
{
    char *buf1, *buf2;
    int handle1, handle2, i, j, len, len1, len2, bytes_to_compare;
    
    if (argc != 3)
    {
        fprintf(stderr, "Invalid command line !\n");
        return 1;
    }
    
    if ((handle1 = open(argv[1], O_RDONLY)) == -1)
    {
        fprintf(stderr, "Can't open file %s !\n", argv[1]);
        return 1;
    }

    if ((handle2 = open(argv[2], O_RDONLY)) == -1)
    {
        close(handle2);
        fprintf(stderr, "Can't open file %s !\n", argv[2]);
        return 1;
    }

    if ((len1 = filelength(handle1)) != (len2 = filelength(handle2)))
        fprintf(stderr, "Files have different sizes !\n");
    
    len = min(len1, len2);
    
    if ((buf1 = (char *)malloc(CMP_BUFFER_SIZE)) == NULL ||
        (buf2 = (char *)malloc(CMP_BUFFER_SIZE)) == NULL)
    {
        close(handle1);
        close(handle2);
        if (buf1) free(buf1);
        fprintf(stderr, "Not enough memory !\n");
	return 1;
    }

    for (i = 0; i < len; i += CMP_BUFFER_SIZE)
    {
	bytes_to_compare = min(len - i, CMP_BUFFER_SIZE);
        if (read(handle1, buf1, bytes_to_compare) != bytes_to_compare)
        {
            close(handle1);
            close(handle2);
            free(buf1);
            free(buf2);
            fprintf(stderr, "Can't read from file %s !\n", argv[1]);
	    return 1;
        }
        if (read(handle2, buf2, bytes_to_compare) != bytes_to_compare)
        {
            close(handle1);
            close(handle2);
            free(buf1);
            free(buf2);
            fprintf(stderr, "Can't read from file %s !\n", argv[2]);
            return 1;
        }
        if (memcmp(buf1, buf2, bytes_to_compare))
            for (j = 0; j < bytes_to_compare; j++)
                if (buf1[j] != buf2[j])
                {
		    fprintf(stderr, "Filles differ at offset %d !\n", j);
		    return 1;
		}
    }

    fprintf(stderr, " Compare OK\n");
    close(handle1);
    close(handle2);
    free(buf1);
    free(buf2);
    return 1;
}
