/*
 * The author of this software is Eric Grosse.  Copyright (c) 1993 by AT&T.
 * Permission to use, copy, modify, and distribute this software for any
 * purpose without fee is hereby granted, provided that this entire notice
 * is included in all copies of any software which is or includes a copy
 * or modification of this software and in all copies of the supporting
 * documentation for such software.
 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
 */

/* deprecated version of masterslave.c, suitable for some non-POSIX systems */

/* for internationalization... */
#define MESS_OPEN "can't open %s\n"
#define MESS_SUM "can't sum %s\n"
#define MESS_TIM "%s: same time, different contents?!!\n"
#define MESS_SORT "input should be sorted: %s\n"
#include "stdlib.h"
#include <stdio.h>
#include "string.h"
#include <fcntl.h>
typedef unsigned long ulong;
extern FILE *zopen();  /* like fopen, but for compressed files */

int incremental = 0;
char *progname;

typedef struct Fsum{
	ulong tim, len, sum;
	char name[2001];
	char ok;	/* other fields are valid if this is nonzero */
} Fsum;

FILE*
Fopen(path,mode) char *path; char *mode;
{
	FILE *f;
	if( strcmp(mode,"r")==0 && strcmp(path+strlen(path)-2,".Z")==0 )
		f = zopen(path);
	else
		f = fopen(path,mode);
	if(!f){
		fprintf(stderr,MESS_OPEN,path);
		perror("");
		exit(1);
	}
	return f;
}

next_Fsum(f,s) FILE *f; Fsum *s;
{
	Fsum old;
	strcpy(old.name,s->name);
	s->ok = (4==fscanf(f,"%2000s %lu %lu %lx",
			s->name,&s->tim,&s->len,&s->sum));
	if(s->ok && strcmp(old.name,s->name)>=0 ){
		fprintf(stderr,MESS_SORT,s->name);
		exit(1);
	}
}

cmd(c,s) char *c; struct Fsum *s;
{
	int fd;
	if(incremental){
		switch(*c){
			case 'g':	/* "get" */
				fd = open(s->name,O_RDONLY);
				if(crc(fd,&s->sum,&s->len))
					fprintf(stderr,MESS_SUM,s->name);
				close(fd);
			case 'o':	/* "ok" or fall-through from "get" */
				printf("%s %lu %lu %lx\n",s->name,s->tim,s->len,s->sum);
			/* "time" can't happen;  if "rm", do nothing */
		}
	}else{	/* normal case */
		if(*c!='o')	/* skip if "ok" */
			printf("%s %s %lu %lu %lx\n",c,s->name,s->tim,s->len,s->sum);
	}
}

int
main(argc,argv) int argc; char **argv;
{
	int cmp;
	FILE *master, *slave;
	Fsum m, s;

	progname = argv[0];
	if(argc==4 && strcmp(argv[1],"-i")==0){
		incremental = 1;
		argv++;
		argc--;
	}
	if(argc!=3) exit(3);
	master = Fopen(argv[1],"r");
	slave = Fopen(argv[2],"r");
	m.name[0] = '\0';  /* for benefit of sort check in next_Fsum */
	s.name[0] = '\0';
	next_Fsum(master,&m);
	next_Fsum(slave,&s);
	while(m.ok||s.ok){
		if( !m.ok ) cmp = 1;
		else if ( !s.ok ) cmp = -1;
		else cmp = strcmp(m.name,s.name);
		if( cmp < 0 ){
			cmd("get",&m);
			next_Fsum(master,&m);
		}else if( cmp > 0 ){
			cmd("rm",&s);
			next_Fsum(slave,&s);
		}else{ /* cmp==0 */
			if( m.tim!=s.tim ){
				if(m.len==s.len && m.sum==s.sum)
					cmd("time",&m);
				else
					cmd("get",&m);
			}else if( m.len!=s.len ||
				(m.sum!=0 && s.sum!=0 && m.sum!=s.sum) ){
				fprintf(stderr,MESS_TIM,m.name);
				cmd("get",&m);
			}else if(incremental && m.sum==0){
				cmd("get",&m);
			}else{
				cmd("ok",&m);
			}
			next_Fsum(master,&m);
			next_Fsum(slave,&s);
		}
	}
	exit(0);
}