/*
 * 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 mirror.c, suitable for some non-POSIX systems */

#include "stdlib.h"
#include "unistd.h"
#include <stdio.h>
#include "string.h"
#include <errno.h>
#include "limits.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "utime.h"
#include "suffix.h"
#ifndef LOOSE
typedef unsigned long ulong;
#endif
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
#ifndef NAME_MAX
#define NAME_MAX 32
#endif

extern int Create();
extern int Error();
char *progname;

static char **ftparg;
static char ftpdir[PATH_MAX+1];	/* relative to starting directory here
					and on remote.  No '/' on end. */
static int uncompressed;		/* if 1, assume master site has no compression at all */
static int toftp;

#define ftpcmd(cmd) printf("%s",cmd)

#define MESS_SIZE "%s had size %lu, expected %lu\n"
#define MESS_OWN "%s: not owner\n"
#define MESS_BIG "string too big: %s"

static int
chtime(name, tim, len) char *name; ulong tim; ulong len;
{
	struct stat s;
	time_t u[2];

	if(stat(name,&s)!=0){		/* get actual time and length */
		fprintf(stderr,"can't stat %s\n",name);
		return -1;
	}
	if((off_t)len!=s.st_size){	/* verify length is same */
		fprintf(stderr,MESS_SIZE,name,(ulong)s.st_size,len);
		return -1;
	}
	u[0] = s.st_atime;
	u[1] = (time_t)tim;
	if(utime(name,u)!=0){		/* change mtime */
		if(errno==EPERM){
			fprintf(stderr,MESS_OWN,name);
			return -1;
		}
		fprintf(stderr,"can't utime %s\n",name);
		return -1;
	}
	return 0;
}

static
walk(olddir, newdir) char *olddir; char *newdir;
{
	char *so, *sn;
	char cdcmd[5+2*PATH_MAX];

	/* see how far old and new agree */
	for( so=olddir, sn=newdir; *so==*sn; so++, sn++){
		if(*so=='/'){
			olddir = so+1;
			newdir = sn+1;
		}else if(*so=='\0'){
			olddir = so;
			newdir = sn;
			break;
		}
	}
	strcpy(cdcmd,"lcd ");
	while(so = strrchr(olddir,'/')){	/* walk up */
		strcat(cdcmd,"../");
		*so = '\0';
	}
	if(olddir[0]!='\0')
		strcat(cdcmd,"../");
	strcat(cdcmd,newdir);
	strcat(cdcmd,"\n");
	if(strcmp(cdcmd,"lcd \n")!=0){
		ftpcmd(cdcmd);		/* local cd */
		ftpcmd(cdcmd+1);	/* remote cd */
	}
	strcpy(olddir,newdir);
}

static int
get(name, tim, len, sum, suffixlist)
	char *name; ulong tim; ulong len; ulong sum;
	Suffix *suffixlist;
{
	char getcmd[5+NAME_MAX], work[PATH_MAX+1], *newdir, *basename, *suf;

	close(Create(name,0666));  /* make directories if necessary */

	if(!toftp){
		toftp = 1;
		printf("%s %s <<'!'\n",ftparg[0],ftparg[1]);  ftparg += 2;
		ftpcmd("prompt\n");
		ftpcmd("binary\n");
		ftpcmd("verbose\n");
		if(*ftparg){	/* starting directory on remote system */
			if(strlen(*ftparg)+5>PATH_MAX) Error(MESS_BIG,*ftparg);
			sprintf(work,"cd %s\n",*ftparg++);
			ftpcmd(work);
		}
	}

	/* cut path into directory and basename */
	if(strlen(name)+1>sizeof(work)) Error("filename overflow");
	strcpy(work,name);
	if(basename = strrchr(work,'/')){
		newdir = work;
		*basename++ = '\0';
	}else{
		newdir = "";
		basename = work;
	}
	walk(ftpdir,newdir);	/* cd as necessary */
	strcmp(ftpdir,newdir)==0 || Error("dir mismatch: can't happen");

	/* at last, get the file */
	suf = "";
	if(!uncompressed && need_compr(basename,suffixlist))
		suf = ".Z";	/* might want to change this to ".z" for gzip someday */
	sprintf(getcmd,"get %s%s\n",basename,suf);
	ftpcmd(getcmd);

	return 0;
}

int
main(argc,argv) int argc; char **argv;
{
#define DIE Error("can't %s %s",cmd,name)
	ulong tim, len, sum;
	char cmd[21], name[2001];
	Suffix *suffixlist;
	int err = 0;

	progname = argv[0];
	if(argc!=5)
		Error("args: <ftpcmd> <host> <directory> <suffixlist>\n"); 
	ftparg = &argv[1];
	uncompressed = read_suffix(argv[4],&suffixlist);
	while(5==fscanf(stdin,"%20s %2000s %lu %lu %lx",
				cmd,name,&tim,&len,&sum)){
		switch(*cmd){
		case 'g': /* get */
			get(name,tim,len,sum,suffixlist)==0 || DIE;
			break;
		case 'r': /* rm */
			unlink(name)==0 || DIE;
			break;
		case 't': /* time */
			chtime(name,tim,len);  /* don't DIE, just keep going */
			break;
		default:
			if(err++ < 10)
				fprintf(stderr,"? %s %s\n",cmd,name);
		}
	}
	if(toftp)
		printf("quit\n!\n");
	if(err)
		exit(1);
	exit(0);
}