/* ifnewer.c
 * conditional execution of a command if one file is newer than another
 *  Musus Umbra, 1997
 */

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "kernel.h"


static int file_cmp( char *a, char *b )
{
	FILE *fpa, *fpb;
	fpa = fopen(a,"rb");
	if ( !fpa )
	{
		fprintf(stderr,"ifnewer: can't read file '%s'\n",a);
		exit(1);
	}
	fpb = fopen(b,"rb");
	if ( !fpa )
	{
		fprintf(stderr,"ifnewer: can't read file '%s'\n",b);
		exit(1);
	}
	while ( fgetc(fpa) == fgetc(fpb) ) { if ( feof(fpa) ) { break; } }
	if ( feof(fpb) && feof(fpa) )
	{
		fclose(fpa); fclose(fpb);
		return 0;
	}
	fclose(fpa);
	fclose(fpb);
	return 1;
}




static int date_cmp( char *a, char *b )
{
	_kernel_osfile_block a_blk,b_blk;
	int atype, btype;

	if ( (atype = _kernel_osfile( 17, a, &a_blk )) < 0 )
	{
		fprintf(stderr,"ifnewer: can't read timestamp of '%s'\n",a);
		exit(1);
	}

	if ( (btype = _kernel_osfile( 17, b, &b_blk )) < 0 )
	{
		fprintf(stderr,"ifnewer: can't read timestamp of '%s'\n",b);
		exit(1);
	}

	if ( atype == 0 )
	{
		fprintf(stderr,"ifnewer: '%s' non-existent\n",a);
		exit(1);
	}


	if ( (atype != btype) || btype==0 )
		return -1; 

	if ( !memcmp(&a_blk,&b_blk,sizeof(_kernel_osfile_block)) )
		return 0;

	if ( (a_blk.load & b_blk.load & 0xfff00000) != 0xfff00000 )
		return file_cmp(a,b) ? -1 : 0;

	if ( (a_blk.load & 0xff) < (b_blk.load & 0xff) )
		return 1;
	if ( (a_blk.load & 0xff) > (b_blk.load & 0xff) )
		return -1;
	if ( ((unsigned int)a_blk.exec) < ((unsigned int)b_blk.exec) )
		return 1;
	if ( ((unsigned int)a_blk.exec) > ((unsigned int)b_blk.exec) )
		return -1;
	return 0;
}


int main( int argc, char *argv[] )
{
	char *command,*c;
	int  i,l;

	if ( argc<4 )
	{
		fprintf(stderr,"Syntax: ifnewer <file1> <file2> <command>\n");
		exit(2);
	}

	if ( date_cmp(argv[1],argv[2])>=0 )
		return 0;

	l = 0;
	for ( i=3; i<argc; i++ )
		l += (strlen(argv[i]) + 1);
	command = malloc( l+16 );
	if ( !command )
	{
		fprintf(stderr,"ifnewer: serious memory famine!\n");
		exit(1);
	}

	strcpy(command,"chain:");
	c = command+strlen(command);

	for ( i=3; i<argc; i++ )
	{
		strcpy(c,argv[i]);
		c += strlen(c);
		*c++ = ' ';
	}
	*(c-1) = 0;

	system(command);		/* doesn't return */
}
