/************************* Hydra/3 - Main Unit ******************************
*									    *
*	  Copyright 1995 by Dreamer/1oo% and Neurodancer/1oo%		    *
*									    *
****************************************************************************/

signal on syntax

/************************ CONFIG if neccessary! ****************************/

aocom="AO"			/* BBSCommand for "Adopt Orphans"	*/
wrcom="wr"			/* BBSCommand for "Write" Description	*/
hststring="HST"			/* used for HST-Check			*/
newname.0="new"			/* Show "New" - Language 0		*/
newname.1="neu"			/* Show "New" - Language 1		*/
newcom.0="new"			/* UDBase Command "New" - Language 0	*/
newcom.1="neu"			/* UDBase Command "New" - Language 1	*/

/************************** Multilanguage Config ***************************/

/* Language 0 (here = English) */

shared.0	="Shared mode required on this port to run Hydra!n1Inform the Sysop, please!"
hstcon.0	="Sorry! Hydra cannot be used with HST-Protocol."
nothyddir.0	="This is no subboard for Hydra-Transfers!n1c3Please use subboard c7"hydradir"c3 instead."
readselect.0	="Reading Selectlist..."
dizbld.0	="Disabled"
notnufffc.0	="Sorry, not enough file credits!"
notnuffbc.0	="Sorry, not enough byte credits!"
notnuffdfc.0	="Sorry, not enough daily file credits!"
notnuffdbc.0	="Sorry, not enough daily byte credits!"
yeppo.0		="Y"
strtxfer.0	="Really start transfer? (c3Lc2 = Logoff after xfer!)"
inithyd.0	="Initiating Hydracom!"
abort.0		="^X to abort."
lookatdir.0	="Looking for uploads..."
found.0		="found"
fincom.0	="Found incomplete uploads:"
compcom.0	="Found finished, yet not moved Files. Move to Filebase or Delete?"
movdel.0	="c7[c3Mc7]c2ove / c7[c3Dc7]c2elete?"
move.0		="Move"
Delete.0	="Delete"
contUL.0	="Do you want to resume uploading? "
delnow.0	="Delete unfinished files? "
deliUL.0	="Deleting incomplete uploads..."
Update.0	="Updating download-counter:"
CDcopy.0	="Copying file to CD-Rom Xfer-Temp..."
complete.0	="complete" /* 8 chars! */
Yes.0		="Yes"
No.0		="No"

/* Language 1 (here = German) */

shared.1	="Port muss im Shared mode laufen, damit Hydra gestartet werden kann!n1Bitte informiere den Sysop!"
hstcon.1	="Tut mir leid! Hydra kann mit dem HST-Protokoll nicht benutzt werden."
nothyddir.1	="Du bist nicht im Verzeichnis fuer Hydra-Uploads!n1c3Bitte benutze das Verzeichnis c7"hydradir"c3 stattdessen."
readselect.1	="Auslesen der gemerkten Files..."
dizbld.1	="Keine"
notnufffc.1	="Du hast nicht genug File-Kredit!"
notnuffbc.1	="Du hast nicht genug Byte-Kredit!"
notnuffdfc.1	="Du hast heute nicht mehr genug File-Kredit!"
notnuffdbc.1	="Du hast heute nicht mehr genug Byte-Kredit!"
yeppo.1		="J"
strtxfer.1	="Uebertragung wirklich beginnen? (c3Lc2 = Logoff nach der Uebertragung!)"
inithyd.1	="Hydracom wird gestartet!"
abort.1		="Abbruch mit CTRL-X."
lookatdir.1	="Suche nach Uploads..."
found.1		="gefunden"
fincom.1	="Unvollstaendige Uploads gefunden:"
compcom.1	="Vollstaendige, aber noch nicht in Fileliste integrierte Files gefunden.n1In die Fileliste einfuegen, oder Loeschen?"
movdel.1	="c7[c3Ec7]c2infuegen / c7[c3Lc7]c2oeschen?"
move.1		="Einfuegen"
Delete.1	="Loeschen"
contUL.1	="Willst Du diese Files fertig uploaden? "
delnow.1	="Sollen die unvollstaendigen Files gelöscht werden? "
deliUL.1	="Loesche die unvollstaendigen Uploads..."
Update.1	="Erhoehe Download-Zaehler von:"
CDcopy.1	="Kopiere das File ins CD-Rom-Temp..."
complete.1	="  fertig" /* 8 chars! */
Yes.1		="Ja"
No.1		="Nein"

/********************************** Begin **********************************/

options results
changewhere "Hydra/3 UL/DL"
version="o.27"

/******************** Init Rexxsupport.library, if n/a *********************/

IF ~SHOW('LIBRARIES','rexxsupport.library') THEN
	IF ~ADDLIB('rexxsupport.library',0,-30,0) THEN
		EXIT(10)

/************* Getting all neccessary data on serial and other *************/

getuser 23 ; port=result
getuser 24 ; realbd=result*10
getuser 39 ; uucpdir="Mail:Users/"result
getuser 1306724 ; myloc=result
getuser 1307654 ; concode=result
getuser 1410470 ; Unit=Result
getuser 1210478 ; Idlebaud=result*10
getuser 1310486 ; DevName=result
getuser 1311992 ; progpath=result
getuser 1100452 ; lng=result
getuser 2307346 ; temppath=result
getuser 2307626 ; cdpath=result

ByteCred=0; FileCred=0; Fileup=0; Byteup=0; Filedn=0; Bytedn=0; AddSize=0; found=0

call InitScr

/******************************** read config ******************************/

if exists(progpath"Hydra3.cfg") then do
	open(cfg,progpath"Hydra3.cfg","R")
		call getline; hydradir=line
		call getline; UDloc=line
		call getline; incDL=line
		call getline; logwrite=line
	close(cfg)
	end
else do
	transmit "c1Config-File is missing!"; exit
end

/************************* check Port for Shared mode **********************/

getuser 1410474
if ~bittst(d2c(result,4),5) then do
	transmit "n1c1"shared.lng
	exit
end

/********************** Check for correct subboard *************************/

getuser 49 ; subname=result
if upper(subname)~=upper(hydradir) then do
	hyst=index(nothyddir.lng,'HYDRADIR')
	nothyddir.lng=substr(nothyddir.lng,1,hyst-1)||hydradir||substr(nothyddir.lng,hyst+8)
	transmit "n1c1"nothyddir.lng"n1"
	bufferflush
	exit
end

/************************* check for HST-Protocol **************************/

if index(concode,hststring)~=0 then do
	transmit "n1c1"hstcon.lng"n1"
	bufferflush
	exit
end

/********************** check existance of hydra-temp-Dir ******************/

if ~exists('UDBase'UDloc':Hydra') then do
	call makedir('UDbase'UDloc':Hydra')
end

/************** getting Default-Ratios via NewSubboardStructure ************/

pb=null(); GetUser 1412312
struct=import(offset(pb,result+227),40)

parse var struct MTimeCredit 2 x 32 UpRatioBytes 34 UCB 36 UpRatioFiles 38 UCF 40

getuser 1100702+(2*(c2d(UpRatioFiles)-1)); FileRatio = result
getuser 1100703+(2*(c2d(UpRatioBytes)-1)); ByteRatio = result

/*************** check, if there where some incomplete Uploads *************/

Dirlist=showdir(uucpdir'/Hydra.BAD')

if Dirlist ~= "" then do
	if words(dirlist)=2 then do
		if left(word(Dirlist,1),8) ~= "BAD-XFER" then do
			transmit "n1c3"compcom.lng"c7"
		end
	end
	bufferflush
	do x=1 to words(Dirlist)
		if left(word(Dirlist,x),8) ~= "BAD-XFER" then do
			Size=word(Statef(uucpdir'/Hydra.BAD/'word(Dirlist,x)),2)
			sendstring "c6"left(word(Dirlist,x),20," ")" c7- c6"right(Size,8," ")" c7Bytes - "
			sendstring movdel.lng" c7 "
			do forever
				sendstring d2c(8)"g0"; getuser 70
				if result=left(Move.lng,1) then do
					transmit d2c(8)||Move.lng
					address command 'move 'uucpdir'/Hydra.BAD/'word(Dirlist,x)' to UDBase'UDloc':Hydra/'
					fileup=fileup+1
					byteup=byteup+Size
					Filecred=Filecred-Fileratio
					Bytecred=Bytecred-Size*byteratio
					leave
				end
				if result=left(Delete.lng,1) then do
					transmit d2c(8)||Delete.lng
					call Delete(uucpdir'/Hydra.BAD/'word(Dirlist,x))
					leave
				end
				if result="###PANIC" then do
					setclip('LostStuff',UDloc" 0 0")
					exit
				end
			end
		end
	end
	if exists(uucpdir'/Hydra.BAD/BAD-XFER.LOG') then do
		bufferflush
		transmit "n1c3"fincom.lng"c7"
		open(bad,uucpdir'/Hydra.BAD/BAD-XFER.LOG','R')
			Logline = readln(bad)
			do until eof(bad)
				parse var logline fname badname fsize x
				badsize=word(statef(uucpdir"/Hydra.BAD/"badname),2)
				transmit "c6"left(fname,20," ")" c7- c6"right(badsize,8," ")" c7of c6"right(fsize,8," ")" c7Bytes"
				Logline = readln(bad)
			end
		close(bad)
		call setclip(port'resume','SET!')
		prompt 1 YESNO "n1c2"contUL.lng"c7[c3"yeppo.lng"c7/c2nc7] "
		if upper(result)="YES" then address command 'move 'uucpdir'/Hydra.BAD/BAD-XFER.#? to UDBase'UDloc':Hydra/'
		else do
			prompt 1 YESNO "n1c2"delnow.lng"c7[c3"yeppo.lng"c7/c2nc7] "
			if upper(result)="YES" then do
				transmit "c3n1"deliUL.lng"n1"
				address command 'delete 'uucpdir'/Hydra.BAD/BAD-XFER.#?'
			end
		end
		drop Logline
	end
	call InitScr
end

/********** Creation of Hydrasendlist reading all necessary data ***********/
/*************** out of the Selectlist and copy CDTemp-Files ***************/

transmit "@4n1c2"readselect.lng"n1c7"

if ~exists(CDpath) then do
	if right(CDpath,1)="/" then do
		call makedir(left(CDpath,length(CDpath)-1))
	end
	else call makedir(CDpath)
end

transmit "c4--c7[ c2Filename c7]c4--------------------.-c7[ c2Filesize c7]c4-.-c7[ c2Credits Bytes c4.c2 Files c7]c4-"

open('Lst',temppath||port'HydFileLst','W')

pb=null() ; GetUser 1401978 ; pointer=result
getuser 1209644 ; num=result

do a=0 to num-1

	struct=import(offset(pb,pointer+a*156),156)
	parse var struct size 5 title"00"x 36 loc"00"x 131 base 133,
		sdownfiles 134 sdownbytes 135 temp 136 cdrom 137,
		freestuff 138 autokill 139 bytedl 143,
		filedl 145 adate 151 number

	Bytedl=c2d(Bytedl); Filedl=c2d(filedl); size=c2d(size)

	if c2d(Freestuff)~=0 then do
		bytedl=0; filedl=0
		end
	b=a+1 ; Loc.b = loc
		Name.b = Title
		FileCR.b = Filedl
		ByteCR.b = Bytedl		
		cd.b = cdrom

	sendstring "c7"title".34}c4|c7 "insert(" ",Size,0,(12-length(Size))," ")" c4|c7 "insert(" ",Bytedl,0,(15-length(Bytedl))," ")" c4|c7 "insert(" ",Filedl,0,(4-length(Filedl))," ")
	if c2d(Freestuff)~=0 then transmit " c2*"
	if c2d(cdrom)=1 then do
		transmit " c6CD"
		transmit "n1c6"cdcopy.lng
		address command "copy "Loc||title" to "CDpath
		transmit "^1                                                                             ^2"
		Loc.b=CDpath; Loc=CDpath
	end

	writeln('Lst',loc||title)
	Filecred=Filecred+FileDl
	Bytecred=Bytecred+ByteDl
	Addsize=Addsize+Size
end
if num=0 then transmit "c7    *** c3No files selected!c7 ***    c4|            c70 c4|               c70c4 |    c70"
transmit "c4.-----------------------.---------¦--------------¦-----------------¦---------"

close('Lst')

sendstring "c4|>23}c4`--c7[ c2Sum: c4|c7 "insert(" ",AddSize,0,(12-length(AddSize))," ")" c4|c7 "insert(" ",Bytecred,0,(15-length(Bytecred))," ")" c4|c7 "insert(" ",Filecred,0,(4-length(Filecred))," ")
transmit "c4|>33}c4`--------------^-----------------^---------n1|"

/********************** Print out infos on ratios **************************/

if Byteratio=0 then bytestr="c3nc7/c3a"
	else bytestr="c31c7:c3"byteratio
if Fileratio=0 then filestr="c3nc7/c3a"
	else filestr="c31c7:c3"fileratio

getuser 1100663 
FileDiz=BitTST(d2c(result+(result<0)*256),6)
ByteDiz=BitTST(d2c(result+(result<0)*256),7)

if FileDiz=1 then filestr="c3"dizbld.lng
if ByteDiz=1 then bytestr="c3"dizbld.lng

transmit "`--c7[ c2Byte-Ratio: "bytestr"c6  -  c2File-Ratio: "filestr" c7]c4--- -- -"

/********************* check, if user got enough Credz *********************/

if FileDiz=0 then do
	getuser 1200686
	if result~=0 then do
		t=result ; getuser 1200534 ; t=c2d(t)-c2d(result)
		if t-Filecred<0 then do
			transmit "n1c1"notnuffdfc.lng
			exit
		end
	end
	getuser 34
	if result-Filecred<0 then do
		transmit "n1c1"notnufffc.lng
		exit
	end
end

if ByteDiz=0 then do
	getuser 1400664
	if result~=0 then do
		t=result ; getuser 1400528 ; t=t-result
		if t-Bytecred<0 then do
			transmit "n1c1"notnuffdbc.lng
			exit
		end
	end
	getuser 35
	if result-Bytecred<0 then do
		transmit "n1c1"notnuffbc.lng
		exit
	end
end

Filecred=0; Bytecred=0

/*********************** Ask User to start transfer ************************/

sendstring "n2c2"strtxfer.lng" c7[c3"yeppo.lng"c7/c2nc7/c2lc7] "
getchar

if upper(result)~="Y" & c2d(result) ~= 13 & upper(result)~="L" then do
	transmit no.lng
	call delete(temppath||port"hydfilelst")
	address command 'move UDBase'UDloc':Hydra/#? to 'uucpdir'/Hydra.BAD/'
	if num~=0 then do a=1 to b
		If c2d(cd.a)=1 then call delete(CDpath||Name.a)
		end
	exit
end
if result="###PANIC" then do
	setclip('LostStuff',UDloc" 0 0")
	if num~=0 then do a=1 to b
		If c2d(cd.a)=1 then call delete(CDpath||Name.a)
		end
	exit
end

if upper(result)="L" then do
	transmit "Logoff"
	logoff=1
	end
else do
	transmit yes.lng
	logoff=0
end

/******************* Disable Idle-timer (via FreezeIdle) *******************/

setobject 1 ; putuser 1110341

/***************************** Hydracom call !!! ***************************/

transmit "n2z1c7 "inithyd.lng" z0 - "abort.lng"c1"

address command 'hydracom speed 'idlebaud' line 'realbd' port 'unit' device 'devname' dropdtr receive UDBase'UDloc':Hydra/ result 'temppath||port'HydraLog nobell handshake hard send @'temppath||port'hydfilelst'

/***************************** Clearing CDtemp ******************************/

if num~=0 then do a=1 to b
	If c2d(cd.a)=1 then call delete(CDpath||Name.a)
end

/********* compare HydraLog, ajusting Credits and write to CNet-Logs ********/

getuser 1209644 ; num=result
getuser 1500000 ; date=substr(result,5,6)||substr(result,16,7)
getuser 1 ; Handle=left(result,21,' ')

if incDL=1 then transmit "f1@0n2c3"Update.lng"n1c2"
else transmit "f1@0"

open(log,temppath||port'HydraLog','R')
open(cred,temppath||port'HydraCred','W')

if exists('SysData:Log/Uloads') then open(ul,'SysData:Log/Uloads','A')
	else open(ul,'SysData:Log/Uloads','W')
if exists('SysData:Log/Dloads') then open(dl,'SysData:Log/Dloads','A')
	else open(dl,'SysData:Log/Dloads','W')

do until eof(log)
	Logline=readln(log)
	parse var logline transt fsize x x cps x x x x x fname x

	If transt='H' then do cnt=1 to num
		if (Loc.cnt||Name.cnt)=fname then do
			/* begin SI/V\S - optimized by dRm! */
			if exists(Loc.cnt"data/_Items3")&incDL=1 then do
				transmit Name.cnt

				open(file,Loc.cnt||"data/_Items3","R");
					Itemdat=readch(file,65536);
				close(file);

				ILen=length(Itemdat)
				do i=1 by 168 to ILen while found=0;if substr(Itemdat,i,length(Name.cnt))=Name.cnt then do;found=1;adr=i;end;end

				if found=1 then do
					it=c2d(substr(Itemdat,adr+60,4))
					it=it+1; it=d2c(it)
					ItemdatNew=overlay(it,Itemdat,adr+60+4-length(it))

					open(file,Loc.cnt"data/_Items3","W");
						writech(file,ItemdatNew);
					close(file);
					found=0
				end
			end
			/* end SI/V\S */
			Filecred=Filecred+FileCR.cnt
			Bytecred=Bytecred+ByteCR.cnt
			filedn=filedn+1
			bytedn=bytedn+fsize
			if logwrite=1 then
			call writeln(dl,'c2'date'c7'handle'c6H'||(realbd%100)' 'left(cps,4,' ')' 'left(Name.cnt,16,' ')||right((fsize%1024),4,' ')' c5'right(Loc.cnt,length(Loc.cnt)-8));
		end
	end
	else if transt='R' & exists('UDbase'UDloc':Hydra/'fname) then do 
			Filecred=Filecred-Fileratio
			Bytecred=Bytecred-fsize*byteratio
			fileup=fileup+1
			byteup=byteup+fsize
			call writeln(cred,fname" "fsize" "||Byteratio*fsize||" "Fileratio);
			if logwrite=1 then
			call writeln(ul,'c2'date'c7'handle'c6H'||(realbd%100)' 'left(cps,4,' ')' 'left(fname,16,' ')||right((fsize%1024),4,' ')' c1Hydra!');
		end
end

close (log)
close (cred)
close (ul)
close (dl)

addtime ((byteup/realbd)/60)*c2d(MTimeCredit)/100

setclip('LostStuff',UDloc" "||byteup*byteratio||" "||fileup*fileratio)

/************************ Ajusting UL/DL Statistics ************************/

byteup=byteup % 1024
bytedn=bytedn % 1024

getuser 30; setobject result+byteup; putuser 30
getuser 32; setobject result+bytedn; putuser 32
getuser 31; setobject result+fileup; putuser 31
getuser 33; setobject result+filedn; putuser 33
getuser 1410386 ; setobject result+filedn; putuser 1410386
getuser 1410390 ; setobject result+bytedn; putuser 1410390

/***************************** Ajusting credits ****************************/

getuser 34 ; setobject result-FileCred; putuser 34
getuser 35 ; setobject result-ByteCred; putuser 35

/****** Getting contents of Hydra-temp-dir and moving to destination *******/

transmit "n2c3"lookatdir.lng"n1"

HydDir=showdir('UDBase'UDloc':Hydra','files')
lclist=""

do z=1 to words(HydDir)
	actFile=word(HydDir,z)
	If actFile='' then break
	if left(actfile,8)='BAD-XFER' then do
		if ~exists(uucpdir'/Hydra.BAD') then call makedir(uucpdir'/Hydra.BAD')
		call setclip(port'resume')
		address command 'move UDBase'UDloc':Hydra/'actFile' to 'uucpdir'/Hydra.BAD/'
	end
	else do
		transmit 'c6'found.lng': c7'actFile
		address command 'move UDBase'UDloc':Hydra/'actFile' to 'myloc
		lclist=lclist" "actfile
	end
end

/****************** check user for AO-Access, if n/a set it ****************/

getuser 1100662 ; privs=d2c(result+(result<0)*256)
aopriv=BitTST(privs,5)
if aopriv=0 then do
	privs=c2d(BitSET(privs,5))
	privs=privs-(privs>127)*256
	setobject privs ; putuser 1100662
	call setclip(port'aopriv','SET!')
end

/***************** check for incoming OLMs and disable them ****************/

if exists(temppath'_olm'port) then
	call rename(temppath"_olm"port, temppath"__olm"port)

/********************** Final adoption of new Files ************************/

bufferflush

if num=filedn & logoff=0 then logoff=2
if num=filedn & logoff=1 then logoff=3

setclip('Logoff',logoff)

if fileup>0 then do
		setclip('lclist',lclist)
		setclip('myloc',myloc)
		setobject 163; putuser 68
		bbscommand ";"newcom.lng"0!;"aocom"!;"wrcom" "newname.lng
		end
	else bbscommand ";setallback"

/********************************* END ! ***********************************/

exit

/****************************** Subroutines ********************************/

InitScr:
transmit x2c(196631196E32196332197A342048796472612F33202D2019633356)version||x2c(20197A30)
transmit x2c(196E31196337446F6E6520696E203139393520627920447265616D65722F537570706C65782F316F6F252E)
transmit x2c(4164646974696F6E616C20636F64696E67206279204E6575726F64616E6365722F41627973732F316F6F2520616E642053492F595C532E)
return

getline:
do forever
	line=readln(cfg)
	if (line~="") then do
		if left(line,2)~="//" then leave
	end
	if eof(cfg) then leave
end
return

/******************************** ERROR ! **********************************/

syntax:
emsg="r0c2 Line: c7"sigl"c2, c7"rc"c2 -c6 "errortext(rc)
getuser 23 ; port=result
transmit "n1c1r1 Error occured! "emsg
if exists("SysData:Log/port"port) then open(clog,"SysData:Log/port"port,"A")
	else open(clog,"SysData:Log/port"port,"W")
writeln(clog,"c2             c1Hydra Error: "emsg)
close(clog)
transmit "c1Important: c2Please report the sysop about the c3linec2 and the c3error-numberc2!"
transmit "c6Any Key to Continue! g0"
exit
