/* UPGRADE.C */

#include "xsdk.h"

#include <dos.h>
#include <dir.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>

/* prototype */
unsigned ctlgen(int, char *);

/****************************************************************************/
/* Deletes all files in dir 'path' that match file spec 'spec'              */
/****************************************************************************/
int delfiles(char *path, char *spec)
{
    char str[256],done;
    int files=0;
    struct ffblk ff;

sprintf(str,"%s%s",path,spec);
done=findfirst(str,&ff,0);
while(!done) {
    sprintf(str,"%s%s",path,ff.ff_name);
    if(remove(str))
		bprintf("Error removing %s\r\n",str);
    else
        files++;
    done=findnext(&ff); }
return(files);
}


unsigned ctlgen(int count, char *sn) {
unsigned z, chk=0xffff;
int ii;
for (ii=--count; ii>-1; ii--) {
    z=0x1f&~sn[ii];
    z^=chk>>10;
    chk<<=6;
    chk^=z^z<<1^z<<2^z<<4^z<<5^z<<7^z<<8^z<<9^z<<11;
    }
for (ii=count; ii>-1; ii--) {
    z=0x1f&~sn[ii];
    z^=chk>>9;
    chk<<=7;
    chk^=z^z<<2^z<<3^z<<5^z<<9^z<<11^z<<13^z<<14^z<<15;
    }
return(~chk);
}


int main(int argc, char **argv)
{
	char str[81],str1[128],str2[128]
		,cmd[81],reg[81],ctrl[81],up_dir[81],tmp[81],ch,src,found;
	long l;
	int file,nodes;
	FILE *log,*stream;
	struct ffblk ff;

if(argc<3) {	/* node directory not specified */
	bputs("usage: upgrade <node directory> <ver and rev>\r\n");
	getch();
	return(1); }
strcpy(node_dir,argv[1]);
if(node_dir[strlen(node_dir)-1]!='\\')  /* make sure node_dir ends in '\' */
    strcat(node_dir,"\\");


sprintf(str,"%sNODE.LOG",node_dir);
if((log=fopen(str,"ab"))==NULL) {
	printf("error opening %s\r\n",str);
	getch();
	return(1); }

initdata();

getcwd(up_dir,MAXDIR);		  /* Get current Directory	  */
strcat(up_dir,"\\");

sprintf(str,"TEMP%d",node_num);
mkdir(str);
chdir(str);
delfiles(".\\","*.*");

cls();
bputs("\1n\1h\1cSynchronet \1yUpgrade Door \1cv2.02\1n\r\n\r\n");
bprintf("\1gCurrently upgrading to version \1h%.2s \1n\1grev \1h%.2s\1n\r\n"
	,argv[2],argv[2]+2);
sprintf(str,"%sUPGRADE.MSG",up_dir);
printfile(str);
if(noyes("Continue with upgrade link and download")) {
	fclose(log);
	return(0); }
bprintf("\r\n\1y\1hEnter your registration number: \1w");
if(!getstr(reg,40,K_UPPER))
	return(1);
fprintf(log,"su Reg: %s\r\n",reg);
bprintf("\r\n\1y\1hEnter your control code: \1w");
if(!getstr(ctrl,40,K_UPPER))
	return(1);
fprintf(log,"su Ctrl: %s\r\n",ctrl);
attr(LIGHTGRAY);

if(strlen(reg)!=8 || strlen(ctrl)!=4 || ahtoul(ctrl)!=ctlgen(8,reg)) {
	sprintf(str,"%sINV_CTL.MSG",up_dir);
	printfile(str);
    if(strlen(reg)==8 && strlen(ctrl)==4
        && ahtoul(ctrl)!=ctlgen(8,reg))
        fprintf(log,"su Incorrect Ctrl Code\r\n");
    else
        fprintf(log,"su Incorrect Reg/Ctrl Pair\r\n");
    fclose(log);
    pause();
    return(1); }


if((file=nopen("\\src\\sbbs\\regnum.lst",O_RDONLY))==NULL) {
	printf("error opening renum.lst\r\n");
	return(1); }

if((stream=fdopen(file,"rb"))==NULL) {
	printf("error fdopening renum.lst\r\n");
	return(0); }


while(!feof(stream)) {
	src=found=0;
	nodes=250;
	if(!fgets(str1,81,stream))
		break;
	if(str1[8]==CR) 	/* no name means end of valid regs */
		break;
	if(str1[8]=='-')    /* - after reg means don't upgrade */
		continue;
	if(str1[9]=='*')    /* star in column 10 means source purchase */
		src=1;
	if(str1[9]=='1')
		nodes=1;
	if(str1[9]=='2')    /* 2 node license */
		nodes=2;
	if(str1[9]=='4')    /* 2 node license */
		nodes=4;
	str1[8]=0;
	strupr(str1);
	if(!strcmp(str1,reg)) {
		found=1;
		if(strncmp(str1+11,argv[2],4)>=0) {
			bprintf("\r\nYou already have version %2.2s revision %2.2s\r\n"
				,str1+11,str1+13);
			fprintf(log,"su Already has v%2.2s r%2.2s\r\n"
				,str1+11,str1+13);
			pause();
			return(0); }

		/*******************************************************/
		/* Upgrading from v1a to v1b - must have 'B' main flag */
		/*******************************************************/
		if(!strncmp(str1+11,"1a",2) && !strncmp(argv[2],"1b",2)
			&& !strchr(user_mf,'B')) {
			bprintf("\r\nYou haven't paid for your v1b upgrade.\r\n");
			fprintf(log,"su Hasn't paid for upgrade\r\n");
			pause();
			return(0); }

		/* Copy extra upgrade files */
		printf("\nCopying extra upgrade kits...");

		if(strncmp(str1+11,"1a10",4)<0)
			system("copy j:\\sbbs\\r10up.zip > nul");

		if(strncmp(str1+11,"1a",2)==0)
			system("copy j:\\sbbs\\1ato1b.zip > nul");

		if(strncmp(str1+11,"1b01",4)<0)
			system("copy j:\\sbbs\\1b00to01.zip > nul");

		if(strncmp(str1+11,"1b02",4)<0)
			system("copy j:\\sbbs\\1b01to02.zip > nul");

		printf("\nDone.\n");
		break; } }

fclose(stream);
if(!found) {
	sprintf(str,"%sINV_REG.MSG",up_dir);
	printfile(str);
	exit(0); }

printf("\nCopying source...");
sprintf(str2,"COPY ..\\%s\\*.OBJ > nul",argv[2]);
system(str2);
sprintf(str2,"COPY ..\\%s\\MAKEFILE > nul",argv[2]);
system(str2);
sprintf(str2,"COPY ..\\%s\\*.C > nul",argv[2]);
system(str2);
sprintf(str2,"COPY ..\\%s\\*.H > nul",argv[2]);
system(str2);
if(src) {
	sprintf(str2,"COPY ..\\%s\\ZIPLIST > nul",argv[2]);
	system(str2); }
if(nodes==1) {
	sprintf(str2,"COPY ..\\%s\\ONE\\*.* > nul",argv[2]);
	system(str2); }
else if(nodes==2) {
	sprintf(str2,"COPY ..\\%s\\TWO\\*.* > nul",argv[2]);
    system(str2); }
else if(nodes==4) {
	sprintf(str2,"COPY ..\\%s\\FOUR\\*.* > nul",argv[2]);
    system(str2); }

remove("MAIN_WFC.OBJ");
remove("VER.OBJ");
sprintf(str2,"PKUNZIP ..\\%s\\%s > nul",argv[2],reg);
system(str2);
if(findfirst("MAIN_WFC.OBJ",&ff,0)) {
	printf("Your upgrade was not found.\r\n");
	pause();
    exit(1); }

printf("\nDone.\n");
sprintf(str2,"MAKE -DN=%d",nodes);
system(str2);

if(findfirst("SBBS.EXE",&ff,0)) {
	printf("\7\r\nLink error!\r\n");
	pause();
	exit(1); }
if(src)
	system("PKZIP SOURCE @ZIPLIST");

sprintf(str2,"PKZIP UPGRADE SBBS.EXE *.ZIP ..\\%s\\FILES\\*.*",argv[2]);
if(src)
	strcat(str2," SOURCE.ZIP");
system(str2);

if(findfirst("UPGRADE.ZIP",&ff,0)) {
	printf("\7\r\nZipping error!\r\n");
	pause();
    exit(1); }

mnemonics("\r\n~Xmodem  ~Ymodem  ~Zmodem  Ymodem-~G\r\n");
bputs("\r\n\1b\1hProtocol: \1w");
ch=getkeys("XYZG",0);
switch(ch) {
	case 'X':
		strcpy(cmd,"sx");
		break;
	case 'Y':
	case 'G':
		strcpy(cmd,"sb");
		break;
	case 'Z':
		strcpy(cmd,"sz");
		break;
	default:
		fclose(log);
		return(1); }
bputs("\r\n\1n\1hStart transfer now (Ctrl-X to abort):\1n\r\n");
sprintf(str,"portx %x,%d",com_base,com_irq);
if(spawnlp(P_WAIT,"GSZ","GSZ",str,cmd,"UPGRADE.ZIP",">NUL",NULL)==NULL) {
	fprintf(log,"su Succesful Transfer of %s upgrade\r\n",argv[2]);
	sprintf(str,"%sMODUSER.DAT",node_dir);
	if((file=open(str,O_WRONLY|O_CREAT|O_BINARY,S_IWRITE|S_IREAD))==-1)
		fprintf(log,"su !! error creating %s\r\n",str);
	else {
		sprintf(str,"\r\n\r\n\r\n-B\r\n");
		write(file,str,strlen(str));
		close(file); }

	/**************************/
	/* Update the regnum file */
	/**************************/

	if((file=nopen("\\src\\sbbs\\regnum.lst",O_RDWR))==NULL) {
		printf("error opening renum.lst\r\n");
		return(1); }

	if((stream=fdopen(file,"wb"))==NULL) {
		printf("error fdopening renum.lst\r\n");
		return(0); }

	while(!feof(stream)) {
		l=ftell(stream);
		if(!fgets(str1,81,stream))
			break;
		if(str1[8]==CR) 	/* no name means end of valid regs */
			break;
		str1[8]=0;
		if(!stricmp(str1,reg)) {
			fseek(stream,l+11,SEEK_SET);
			fwrite(argv[2],4,1,stream);
			break; } }
	fclose(stream); }
else
	fprintf(log,"su Unsuccesful Transfer\r\n");
fclose(log);
delfiles(".\\","*.*");
return(0);
}
