;: > pronet-server.s
;:
;: ©1994-1995 by Michael Krause
;:
;: 16.07.1994	started..
;: 24-01-95 if a port number occurs again while ADDNEWHANDLER, we assume that
;:          other side has reset, so we clear all our data and start from the
;:	    beginning!! v34.1

;: 01-04-95 SegList splitting v34.2

;: 14-04-95 MsgRemDisk (or similar??) won't cause the 50frames-Delay.
;:	    dann noch ACT_READ bug-gefixt??
;: 15-04-95 read und write geben statt NO_FREE_STORE jetzt OBJECT_TOO_LARGE
;:	    zurück v34.3

;: 17-04-95 READ-Transfer umgebaut v34.4
;: 29-04-95 EXAMINE-Packets neu programmiert v34.5

;: 08-05-95 Statt des Devicenamens wird jetzt Unitnummer
;:	    vom CLI-String übernommen v34.6

;: 12-05-95 MsgRemDisk didn't set d7... v34.7

;: 15-06-95 SegList splitting removed. v34.8

DEBUG		equ	0

;++ bei aCT_NEWHANDLER nach CreateStdPacket prüfen -> freemem

		include	"exec/exec.i"
		include	"dos/dos.i"
		include	"dos/dosextens.i"
		include	"dos/filehandler.i"
		include	"devices/input.i"
		include	"devices/inputevent.i"
		include	"A:ProNET/include/devices/pronet.i"
		include	"A:OSmacros.i"

		include	"A:ProNET/source/network.i"

		include	"exec_lib.i"
		include	"dos_lib.i"
		include	"intuition_lib.i"

	      STRUCTURE	PNSHandlerNode,0
		APTR	phn_next		;Verkettung
		UWORD	phn_port		;dazugehörige Portnummer
		APTR	phn_handlerID		;ProcessID des Handlers
		APTR	phn_packet		;StandardPKT zur Handlerkommunikation
					; packet ist *sp_Pkt, nicht *sp_Msg!!
		APTR	phn_devnode	;DevNode des Handlers
		APTR	phn_volnode	;aktuelle Volume
		APTR	phn_dlbuf	;DownLoad-Buffer
		APTR	phn_dlbufpt	;aktuelle Position
		ULONG	phn_dlbytes	;wieviel Bytes noch ?? 0 = nix
		LABEL	phn_SIZEOF

		section	startup,code

j		cmp.w	#2,d0		* UNIT as Argument?
		bls.s	.cont
		jsr	dec2long
		move.l	d1,unit

.cont

	IFNE	DEBUG
	bsr	dinit
	ENDC

		move.l	4.w,a6
		move.l	ThisTask(a6),ourtask
		lea	dosname(pc),a1
		moveq	#33,d0
		jsr	-552(a6)
		move.l	d0,dosbase
		beq.s	nodos

		move.l	ourtask(pc),a0
		move.l	#-1,pr_WindowPtr(a0)

		bsr	StartInputHandler

		bsr	startpronet
		tst.w	d0
		bne.s	nopronet

		bsr	startmessage
		bra	Wait4Message

nopronet	move.l	dosbase(pc),a1
		move.l	4.w,a6
		jsr	-414(a6)
nodos
	IFNE	DEBUG
	bsr	dexit
	ENDC
		moveq	#20,d0
		rts

		dc.b	"$VER: pronet-server 34.9 (18-06-95)",13,10,0
		even

startpronet	moveq	#pnr_Size,d0
		bsr	GetIORequest
		move.l	d0,pronetio
		beq	spnoioreq
		bsr	CreatePort
		move.l	d0,pronetmsgport
		beq	spnomsgport
		lea	pronetname(pc),a0
		move.l	unit(pc),d0
		moveq	#0,d1
		move.l	pronetio(pc),a1
		move.w	#0,pnr_NetSourcePort(a1)
		move.l	pronetmsgport(pc),pnr_MsgPort(a1)
		move.l	4.w,a6
		LIBCALL	OpenDevice
		tst.l	d0
		bne.s	spnodev
		move.l	pronetio(pc),a1
		move.w	#CMD_WRITE,IO_COMMAND(a1)
		clr.l	pnr_Length2(a1)
		move.l	pronetmsgport(pc),a0
		move.b	MP_SIGBIT(a0),Signal.pronet
		moveq	#0,d0
		rts

spnodev		move.l	pronetmsgport(pc),a0
		bsr	DeletePort
spnomsgport	move.l	pronetio(pc),a0
		bsr	FreeIORequest
spnoioreq	moveq	#-1,d0
		rts

; -- InputHandler zum Handlen der DISKREMOVED/INSERTED-Messages hochfahren
; -- und entsprechende Signalbits für's Hauptprogramm eintragen.
StartInputHandler
		move.l	4.w,a6
		moveq	#-1,d0
		LIBCALL	AllocSignal
		move.b	d0,Signal.diskins
		moveq	#-1,d0
		LIBCALL	AllocSignal
		move.b	d0,Signal.diskrem

		moveq	#IOSTD_SIZE,d0
		bsr	GetIORequest
		move.l	d0,a3
		move.l	a3,inputio
		lea	inputname(pc),a0
		moveq	#0,d0
		moveq	#0,d1
		move.l	a3,a1
		move.l	4.w,a6
		LIBCALL	OpenDevice

		move.l	a3,a1
		move.w	#IND_ADDHANDLER,IO_COMMAND(a1)
		move.l	#.int,IO_DATA(a1)
		LIBCALL	DoIO
		rts
.int		dc.l	0,0
		dc.b	NT_INTERRUPT,100
		dc.l	.intname,0,InputHandlerRout
.intname	dc.b	"ProNET Server",0
		even

startmessage	move.l	dosbase(pc),a6
		LIBCALL	Output
		move.l	d0,d1
		move.l	#starttext,d2
		move.l	#starttextl,d3
		LIBCALL	Write
		rts

w4mquitflag	dc.w	0
Wait4Message	tst.w	w4mquitflag
		bne	.quit
		clr.w	w4mquitflag

		lea	Signals(pc),a3	* auf die Messages
		moveq	#0,d0		* an allen möglichen
		moveq	#numports-1,d1	* Ports warten
.loop1		move.b	(a3),d2
		bmi.s	.0
		bset	d2,d0
.0		addq.w	#6,a3
		dbra	d1,.loop1
	IFNE	DEBUG
	lea	dwaitt(pc),a0
	bsr	dtype
	ENDC
		move.l	4.w,a6
		LIBCALL	Wait
					* entsprechende Routinen
		moveq	#31,d7		* aufrufen
.00		rol.l	#1,d0
		bcc.s	.notthisbit
		lea	Signals(pc),a3
		moveq	#numports-1,d4
.01		cmp.b	(a3),d7
		bne.s	.notthisport
		movem.l	d0/d4/d7/a3,-(sp)
		move.l	2(a3),a3
		jsr	(a3)
		movem.l	(sp)+,d0/d4/d7/a3
.notthisport	addq.w	#6,a3
		dbra	d4,.01
.notthisbit	dbra	d7,.00	

		bra	Wait4Message
.quit		rts
Signals:
Signal.pronet	dc.b	-1,0			;Signalbit
		dc.l	GetProNETMsg		;entsprechende Routine
Signal.diskins	dc.b	-1,0
		dc.l	MsgDiskIns
Signal.diskrem	dc.b	-1,0
		dc.l	MsgDiskRem
numports	equ	3

InputHandlerRout
		movem.l	a0/a1/a6,-(sp)
		move.l	a0,d0
		beq.s	.ende
		move.l	4.w,a6
.1		move.b	ie_Class(a0),d0
		cmp.b	#IECLASS_DISKREMOVED,d0
		beq.s	.diskrem
		cmp.b	#IECLASS_DISKINSERTED,d0
		beq.s	.diskins
.next		move.l	(a0),a0
		move.l	a0,d0
		bne.s	.1
.ende		movem.l	(sp)+,a0/a1/a6
		move.l	a0,d0
		rts
.diskrem	move.l	ourtask(pc),a1
		moveq	#0,d0
		move.b	Signal.diskrem(pc),d1
		bset	d1,d0
		LIBCALL	Signal
		bra.s	.next
.diskins	move.l	ourtask(pc),a1
		moveq	#0,d0
		move.b	Signal.diskins(pc),d1
		bset	d1,d0
		LIBCALL	Signal
		bra.s	.next

; -- Eine Disk wurde neu eingelegt - hier wird getestet, ob es eine
; -- von unseren Gast-Handlern ist, wenn ja, werden entsprechende
; -- Maßnahmen eingeleitet...
MsgDiskIns
		IFNE	DEBUG
		move.w	#$0f0,$dff180
		ENDC
		move.l	#ACTION_DISKINS,d6
		moveq	#2,d7
		bra.s	msginsrem_sub

; -- Eine Disk wurde entnommen - siehe 'MsgDiskIns'
MsgDiskRem
		IFNE	DEBUG
		move.w	#$f00,$dff180
		ENDC
		move.l	#ACTION_DISKREM,d6
		moveq	#2,d7
		bra.s	msginsrem_nodel

msginsrem_sub	subq.w	#1,d7
		bpl.s	.0
		rts
.0		move.l	dosbase(pc),a6
		moveq	#50,d1
		LIBCALL	Delay

msginsrem_nodel	lea	HandlerList(pc),a2	;in d6 ACTION_DISKINS/REM
.loop		move.l	(a2),d0
		beq.s	msginsrem_sub
		move.l	d0,a2
		move.l	phn_handlerID(a2),a0
		bsr	FindVolume
		cmp.l	phn_volnode(a2),d0
		beq.s	.loop
		move.l	d0,a5
		move.l	d0,phn_volnode(a2)	* Disk wurde gewechselt !!

		move.l	phn_dlbytes(a2),d0	;es wird gerade downgeloadet
		bne.s	.ende			;(ne Msg würde den Betrieb
						;stören !!)
		move.l	pronetio(pc),a4		* Message an den Handler
		move.w	phn_port(a2),pnr_NetDestPort(a4)	* schicken..
		lea	sendbuf,a3
		move.l	d6,(a3)+
		cmp.l	#ACTION_DISKREM,d6
		beq.s	.nocopy
		move.l	a5,d0
		lsr.l	#2,d0
		move.l	d0,(a3)+
		lea	dol_VolumeDate(a5),a0
		move.l	(a0)+,(a3)+
		move.l	(a0)+,(a3)+
		move.l	(a0)+,(a3)+	;VolumeDate und Name
		move.l	dol_Name(a5),a0	;müssen kopiert werden..
		add.l	a0,a0
		add.l	a0,a0
		moveq	#0,d0
		move.b	(a0),d0
		addq.w	#1,d0
.copyname	move.b	(a0)+,(a3)+
		dbra	d0,.copyname
.nocopy		lea	sendbuf,a0
		move.l	a0,pnr_Data1(a4)
		sub.l	a0,a3
		move.l	a3,pnr_Length1(a4)
		move.l	4.w,a6
		move.l	a4,a1
		LIBCALL	DoIO
.ende		rts

GetProNETMsg	move.l	4.w,a6
		move.l	pronetmsgport(pc),a0
		LIBCALL	GetMsg
		tst.l	d0
		beq	.ende
		move.l	d0,actpronetmsg
		move.l	d0,a2
		lea	MN_SIZE(a2),a2
		move.w	(a2)+,d2	;[d2] Sourceport [a2] Data
		move.l	(a2)+,d0	;[d0] dp_Action
	IFNE	DEBUG
	bsr	dtypedec
	bsr	dcr
	ENDC
		lea	sendbuf+12,a3	;[a3] sendbuf+12
		move.l	d0,-12(a3)
		move.l	pronetio(pc),a4	;[a4] PNRequest
		move.w	d2,pnr_NetDestPort(a4)
		lea	HandlerList(pc),a5
.findnodeloop	move.l	(a5),a5
		move.l	a5,d1
		beq.s	.findrout
		cmp.w	phn_port(a5),d2
		bne.s	.findnodeloop
		move.l	phn_dlbytes(a5),d7
		beq.s	.nodown
		lea	ACT_WRITEdownload(pc),a1
		bra.s	.callit
.nodown		move.l	phn_packet(a5),a4
		move.l	d0,dp_Action(a4)
.findrout	lea	at(pc),a0
		moveq	#atl-1,d1
.findroutloop	cmp.l	(a0),d0
		bcs.s	.next
		cmp.l	4(a0),d0
		bls.s	.jsrroutine
.next		lea	12(a0),a0
		dbra	d1,.findroutloop
		bsr	ACT_NIL
		bra.s	.reply
.jsrroutine	sub.l	(a0),d0
		add.l	d0,d0
		move.l	8(a0),a0
		lea	at(pc),a1
		add.w	(a0,d0.l),a1
.callit		jsr	(a1)
.reply		move.l	actpronetmsg(pc),a1
		move.l	4.w,a6
		LIBCALL	ReplyMsg
		bra	GetProNETMsg
.ende		rts

		cnop	0,4
at		;dc.l	lowerbound,upperbound,tableaddress
		dc.l	7,34,actiontable1
		dc.l	40,40,actiontable2
		dc.l	82,82,actiontable3
		dc.l	87,87,actiontable4
		dc.l	1004,1008,actiontable5
		dc.l	1020,1034,actiontable6
		dc.l	2008,2009,actiontable7
		dc.l	4097,4098,actiontable8
		dc.l	4200,4200,actiontable9
		dc.l	19941994,19941994,actiontable10
		dc.l	19941998,19941999,actiontable11
atl		equ	(*-at)/12

		cnop	0,4
actiontable1	dc.w	ACT_CURRENT_VOLUME-at,ACT_LOCATE_OBJECT-at,ACT_RENAME_DISK-at,ACT_NIL-at,ACT_NIL-at
		dc.w	ACT_NIL-at,ACT_NIL-at,ACT_NIL-at,ACT_FREE_LOCK-at,ACT_DELETE_OBJECT-at
		dc.w	ACT_RENAME_OBJECT-at,ACT_MORE_CACHE-at,ACT_COPY_DIR-at,ACT_NIL-at
		dc.w	ACT_SET_PROTECT-at,ACT_CREATE_DIR-at,ACT_EXAMINE_OBJECT-at,ACT_EXAMINE_OBJECT-at
		dc.w	ACT_DISK_INFO-at,ACT_INFO-at,ACT_FLUSH-at,ACT_SET_COMMENT-at
		dc.w	ACT_PARENT-at,ACT_NIL-at,ACT_INHIBIT-at,ACT_NIL-at
		dc.w	ACT_NIL-at,ACT_SET_DATE-at
actiontable2	dc.w	ACT_SAME_LOCK-at
actiontable3	dc.w	ACT_READ-at
actiontable4	dc.w	ACT_WRITE-at
actiontable5	dc.w	ACT_FINDxxx-at
		dc.w	ACT_FINDxxx-at,ACT_FINDxxx-at,ACT_END-at,ACT_SEEK-at
actiontable6	dc.w	ACT_FORMAT-at,ACT_MAKE_LINK-at,ACT_SET_FILE_SIZE-at,ACT_WRITE_PROTECT-at
		dc.w	ACT_READ_LINK-at,ACT_NIL-at,ACT_FH_FROM_LOCK-at,ACT_NIL-at
		dc.w	ACT_CHANGE_MODE-at,ACT_NIL-at,ACT_COPY_DIR_FH-at,ACT_PARENT_FH-at
		dc.w	ACT_NIL-at,ACT_NIL-at,ACT_EXAMINE_FH-at
actiontable7	dc.w	ACT_LOCK_RECORD-at,ACT_FREE_RECORD-at
actiontable8	dc.w	ACT_ADD_NOTIFY-at,ACT_REMOVE_NOTIFY-at
actiontable9	dc.w	ACT_SERIALIZE_DISK-at
actiontable10	dc.w	ACT_NEWHANDLER-at
actiontable11	dc.w	ACT_RUN-at,ACT_PAGE-at

		cnop	0,4
** The routines will be called with the registers containing following:
** a6 Execbase
** a5 PNSHandlerNode für den entspr. Port oder NULL (packet->dp_action is ready !!)
** a4 phn_packet
** a3 sendbuf+12 (sendbuf filled with dp_Action,{res1},{res2})
** a2 received data (after dp_Action)
** d2 Sourceport

ACT_NIL
		move.l	#DOSFALSE,d0
		move.l	#ERROR_ACTION_NOT_KNOWN,d1
		bra	answerpacket

ACT_LOCATE_OBJECT
		move.l	(a2)+,dp_Arg1(a4)
		move.l	(a2)+,dp_Arg3(a4)
		addq.w	#2,a2	;frei, wegen LW-align..
		move.l	a2,d0
		lsr.l	#2,d0
		move.l	d0,dp_Arg2(a4)
		bsr	dopacket
		tst.l	d0
		beq.s	.return
		move.l	d0,a0
		add.l	a0,a0
		add.l	a0,a0
		move.l	fl_Volume(a0),(a3)+
.return		bra	answerpacket

ACT_RENAME_DISK
		addq.w	#2,a2
		move.l	a2,d0
		lsr.l	#2,d0
		move.l	d0,dp_Arg1(a4)
		bsr	dopacket
		bra	answerpacket

ACT_FREE_LOCK
		move.l	(a2)+,dp_Arg1(a4)
		bra	dopacket

ACT_DELETE_OBJECT
		move.l	(a2)+,dp_Arg1(a4)
		addq.w	#2,a2
		move.l	a2,d0
		lsr.l	#2,d0
		move.l	d0,dp_Arg2(a4)
		bsr	dopacket
		bra	answerpacket

ACT_RENAME_OBJECT
		move.l	(a2)+,dp_Arg1(a4)
		move.l	(a2)+,dp_Arg3(a4)
		addq.w	#2,a2
		lea	256(a2),a0
		move.l	a2,d0
		move.l	a0,d1
		lsr.l	#2,d0
		lsr.l	#2,d1
		move.l	d0,dp_Arg2(a4)
		move.l	d1,dp_Arg4(a4)
		bsr	dopacket
		bra	answerpacket

ACT_MORE_CACHE
		move.l	(a2),dp_Arg1(a4)
		bsr	dopacket
		bra	answerpacket

ACT_COPY_DIR
		move.l	(a2),dp_Arg1(a4)
		bsr	dopacket
		tst.l	d0
		beq.s	.return
		move.l	d0,a0
		add.l	a0,a0
		add.l	a0,a0
		move.l	fl_Volume(a0),(a3)+
		move.l	fl_Access(a0),(a3)+
.return		bra	answerpacket

ACT_SET_PROTECT
		move.l	(a2)+,dp_Arg2(a4)
		move.l	(a2)+,dp_Arg4(a4)
		addq.w	#2,a2
		move.l	a2,d0
		lsr.l	#2,d0
		move.l	d0,dp_Arg3(a4)
		bsr	dopacket
		bra	answerpacket

ACT_CREATE_DIR
		move.l	(a2)+,dp_Arg1(a4)
		addq.w	#2,a2
		move.l	a2,d0
		lsr.l	#2,d0
		move.l	d0,dp_Arg2(a4)
		bsr	dopacket
		tst.l	d0
		beq.s	.return
		move.l	d0,a0
		add.l	a0,a0
		add.l	a0,a0
		move.l	fl_Volume(a0),(a3)+
		move.l	fl_Access(a0),(a3)+
.return		bra	answerpacket

ACT_EXAMINE_OBJECT	;EXAMINEs neu 29-04-95
		move.l	(a2)+,dp_Arg1(a4)
act_ex_entry	lea	workfib,a1
		move.l	a1,d0
		lsr.l	#2,d0
		move.l	d0,dp_Arg2(a4)
		move.l	(a2)+,(a1)+	;fib_DiskKey
		addq.l	#4,a1
		move.w	#32/4-1,d0
.copyname	move.l	(a2)+,(a1)+
		dbra	d0,.copyname	;fib_FileName

		bsr	dopacket

		lea	workfib,a1	;return whole FIB
		move.w	#(fib_SIZEOF)/4-1,d0
.copyfib	move.l	(a1)+,(a3)+
		dbra	d0,.copyfib

		movem.l	dp_Res1(a4),d0/d1
		bra	answerpacket

ACT_EXAMINE_FH
		GETBPTR	(a2)+,a0
		move.l	fh_Arg1(a0),dp_Arg1(a4)
		bra.s	act_ex_entry

ACT_FLUSH
		bsr	dopacket
		bra	answerpacket

ACT_SET_COMMENT
		move.l	(a2)+,dp_Arg2(a4)
		move.l	a2,d0
		move.l	a2,d1
		addq.l	#2,d0
		add.l	#82,d1
		lsr.l	#2,d0
		lsr.l	#2,d1
		move.l	d1,dp_Arg3(a4)
		move.l	d0,dp_Arg4(a4)
		bsr	dopacket
		bra	answerpacket

ACT_PARENT
		bra	ACT_COPY_DIR

ACT_SET_DATE
		move.l	(a2)+,dp_Arg2(a4)
		move.l	a2,dp_Arg4(a4)
		lea	14(a2),a2
		move.l	a2,d0
		lsr.l	#2,d0
		move.l	d0,dp_Arg3(a4)
		bsr	dopacket
		bra	answerpacket

ACT_SAME_LOCK
		move.l	(a2)+,dp_Arg1(a4)
		move.l	(a2),dp_Arg2(a4)
		bsr	dopacket
		tst.w	d0
		bne.s	.return
		cmp.l	#ERROR_ACTION_NOT_KNOWN,d1
		bne.s	.return
		moveq	#DOSFALSE,d0
		moveq	#0,d1
		GETBPTR	-4(a2),a0	;Locks von Hand vergleichen..
		GETBPTR	(a2),a1
		move.l	fl_Volume(a0),d2
		cmp.l	fl_Volume(a1),d2
		bne.s	.return
		move.l	fl_Key(a0),d2
		cmp.l	fl_Key(a1),d2
		bne.s	.return
		moveq	#DOSTRUE,d0
.return		bra	answerpacket

ACT_READ	** New routine on 17-04-95
		GETBPTR	(a2)+,a0
		move.l	fh_Arg1(a0),dp_Arg1(a4)
		move.l	(a2),d7		;Length of the read packet

		moveq	#0,d6		;NumBytes already read

		move.l	pronetio(pc),a2
		lea	sendbuf,a3
		move.l	a3,pnr_Data1(a2)

.loop		move.l	#MAXPACKETSIZE,d0	*Read A Bunch of Bytes
		cmp.l	d0,d7
		bcc.s	.lenok
		move.l	d7,d0
.lenok		move.l	d0,dp_Arg3(a4)
		lea	12(a3),a0
		move.l	a0,dp_Arg2(a4)
		bsr	dopacket
		tst.l	d0			*Error?
		bmi.s	.ERROR

		move.l	d0,4(a3)		*Send packet including
		add.l	#12,d0			*num bytes now read
		move.l	d0,pnr_Length1(a2)
		move.l	a2,a1
		LIBCALL	DoIO

		move.l	4(a3),d0
		beq.s	.EOF			*EOF occured

		add.l	d0,d6
		sub.l	d0,d7
		bgt.s	.loop			*still bytes left

.EOF	* In case of EOF, we don't have to send an additional msg, because
	* the handler already knows that we have reached the end.
		rts

.ERROR		move.l	d0,4(a3)		*send error msg
		move.l	d1,8(a3)
		move.l	a3,pnr_Data1(a2)
		move.l	#12,pnr_Length1(a2)
		move.l	a2,a1
		LIBCALL	SendIO

		move.l	#ACTION_SEEK,dp_Action(a4) *and reset filepointer
		move.l	d6,dp_Arg2(a4)
		move.l	#OFFSET_CURRENT,dp_Arg3(a4)
		bsr	dopacket

		move.l	a2,a1
		LIBCALL	WaitIO
		rts

ACT_WRITE
		GETBPTR	(a2)+,a0
		move.l	fh_Arg1(a0),dp_Arg1(a4)
		move.l	(a2),d0
		move.l	d0,dp_Arg3(a4)
		bsr	AllocVec
		move.l	d0,d3
		beq.s	.error_nostore
		move.l	d3,dp_Arg2(a4)
		moveq	#0,d0
		bsr	answerpacket
		move.l	d3,phn_dlbuf(a5)
		move.l	d3,phn_dlbufpt(a5)
		move.l	dp_Arg3(a4),phn_dlbytes(a5)
		rts
.error_nostore
		moveq	#-1,d0
		move.l	#ERROR_OBJECT_TOO_LARGE,d1
		bra	answerpacket


ACT_WRITEdownload	;called with phnnode in a5
			;and a2 *data+4 (must be 'sub'ed with 4)
	IFNE	DEBUG
	lea	ddownloadt(pc),a0
	bsr	dtype
	ENDC

		move.l	phn_dlbytes(a5),d2
		move.l	#MAXPACKETSIZE,d3
		cmp.l	d3,d2
		bcc.s	.0
		move.l	d2,d3
.0		lea	-4(a2),a0
		move.l	phn_dlbufpt(a5),a1
		move.l	d3,d0
		move.l	4.w,a6
		LIBCALL	CopyMem
		add.l	d3,phn_dlbufpt(a5)
		sub.l	d3,phn_dlbytes(a5)
		bne.s	.ende
		; das war das letzte Stück -> jetzt ACTION_WRITE !!
		bsr	dopacket
		bsr	answerpacket
		move.l	phn_dlbuf(a5),a1
		bra	FreeVec
.ende		rts

ACT_FINDxxx
		moveq	#fh_SIZEOF,d0
		bsr	AllocVec
		move.l	d0,d3
		move.l	d0,a1
		moveq	#-1,d0
		move.l	d0,fh_Pos(a1)
		move.l	d0,fh_End(a1)
		move.l	(a2)+,dp_Arg2(a4)
		addq.w	#2,a2
		move.l	a2,d0
		lsr.l	#2,d0
		move.l	d0,dp_Arg3(a4)
		move.l	a1,d0
		lsr.l	#2,d0
		move.l	d0,dp_Arg1(a4)
		bsr	dopacket
		tst.w	d0
		beq.s	.return_err
		lsr.l	#2,d3
		move.l	d3,(a3)+
		bra	answerpacket
.return_err	bsr	answerpacket
		move.l	d3,a1
		bra	FreeVec

ACT_END
		GETBPTR	(a2),a0
		move.l	fh_Arg1(a0),dp_Arg1(a4)
		bsr	dopacket
		bsr	answerpacket
		GETBPTR	(a2),a1
		bra	FreeVec

ACT_SEEK
		GETBPTR	(a2)+,a0
		move.l	fh_Arg1(a0),dp_Arg1(a4)
		move.l	(a2)+,dp_Arg2(a4)
		move.l	(a2),dp_Arg3(a4)
		bsr	dopacket
		bra	answerpacket

ACT_FORMAT
		move.l	(a2)+,dp_Arg2(a4)
		addq.w	#2,a2
		move.l	a2,d0
		lsr.l	#2,d0
		move.l	d0,dp_Arg1(a4)
		bsr	dopacket
		bra	answerpacket

ACT_MAKE_LINK
		move.l	(a2)+,d2
		move.l	d2,dp_Arg4(a4)
		move.l	(a2)+,dp_Arg1(a4)
		cmp.l	#LINK_HARD,d2
		beq.s	.hardlink
.softlink	move.l	a2,dp_Arg3(a4)
		lea	256+2(a2),a2
		bra.s	.doit
.hardlink	move.l	(a2)+,dp_Arg3(a4)
		addq.w	#2,a2
.doit		move.l	a2,d0
		lsr.l	#2,d0
		move.l	d0,dp_Arg2(a4)
		bsr	dopacket
		bra	answerpacket

ACT_SET_FILE_SIZE
		GETBPTR	(a2)+,a0
		move.l	fh_Arg1(a0),dp_Arg1(a4)
		move.l	(a2)+,dp_Arg2(a4)
		move.l	(a2),dp_Arg3(a4)
		bsr	dopacket
		bra	answerpacket

ACT_WRITE_PROTECT
		move.l	(a2)+,dp_Arg1(a4)
		move.l	(a2),dp_Arg2(a4)
		bsr	dopacket
		bra	answerpacket

ACT_READ_LINK
		move.l	(a2)+,dp_Arg1(a4)
		move.l	(a2)+,dp_Arg4(a4)
		move.l	a2,dp_Arg2(a4)
		move.l	a3,dp_Arg3(a4)
		add.l	dp_Arg4(a4),a3
		bsr	dopacket
		bra	answerpacket

ACT_FH_FROM_LOCK
		moveq	#fh_SIZEOF,d0
		bsr	AllocVec
		move.l	d0,d3
		move.l	d0,a1
		moveq	#-1,d0
		move.l	d0,fh_Pos(a1)
		move.l	d0,fh_End(a1)
		move.l	(a2)+,dp_Arg2(a4)
		move.l	d3,d0
		lsr.l	#2,d0
		move.l	d0,dp_Arg1(a4)
		bsr	dopacket
		tst.w	d0
		beq.s	.return_err
		lsr.l	#2,d3
		move.l	d3,(a3)+
		bra	answerpacket
.return_err	bsr	answerpacket
		move.l	d3,a1
		bra	FreeVec

ACT_CHANGE_MODE
		move.l	(a2)+,d2
		move.l	d2,dp_Arg1(a4)
		cmp.l	#CHANGE_LOCK,d2
		beq.s	.change_lock
.change_fh	GETBPTR	(a2)+,a0
		move.l	fh_Arg1(a0),dp_Arg2(a4)
		bra.s	.cont
.change_lock	move.l	(a2)+,dp_Arg2(a4)
.cont		move.l	(a2),dp_Arg3(a4)
		bsr	dopacket
		cmp.l	#CHANGE_LOCK,d2
		bne.s	.0
		GETBPTR	dp_Arg2(a4),a2
		move.l	fl_Access(a2),(a3)+
.0		bra	answerpacket

ACT_COPY_DIR_FH
		bra	ACT_PARENT_FH

ACT_PARENT_FH
		GETBPTR	(a2),a0
		move.l	fh_Arg1(a0),dp_Arg1(a4)
		bsr	dopacket
		tst.l	d0
		beq.s	.return
		move.l	d0,a0
		add.l	a0,a0
		add.l	a0,a0
		move.l	fl_Volume(a0),(a3)+
		move.l	fl_Access(a0),(a3)+
.return		bra	answerpacket

ACT_LOCK_RECORD
		GETBPTR	(a2)+,a0
		move.l	fh_Arg1(a0),dp_Arg1(a4)
		move.l	(a2)+,dp_Arg2(a4)
		move.l	(a2)+,dp_Arg3(a4)
		move.l	(a2)+,dp_Arg4(a4)
		move.l	(a2),dp_Arg5(a4)
		bsr	dopacket
		bra	answerpacket

ACT_FREE_RECORD
		GETBPTR	(a2)+,a0
		move.l	fh_Arg1(a0),dp_Arg1(a4)
		move.l	(a2)+,dp_Arg2(a4)
		move.l	(a2),dp_Arg3(a4)
		bsr	dopacket
		bra	answerpacket

ACT_ADD_NOTIFY
		bra	ACT_NIL

ACT_REMOVE_NOTIFY
		bra	ACT_NIL

ACT_SERIALIZE_DISK
		bsr	dopacket
		bra	answerpacket

ACT_INHIBIT	move.l	(a2)+,dp_Arg1(a4)
		bsr	dopacket
		bra	answerpacket

ACT_INFO
		move.l	(a2)+,d4
		moveq	#id_SIZEOF,d0
		bsr	AllocVec
		move.l	d0,a2
		move.l	a2,d3
		lsr.l	#2,d0
		move.l	d0,dp_Arg2(a4)
		move.l	d4,dp_Arg1(a4)
		bsr	dopacket
		tst.w	d0
		beq.s	.return
		moveq	#8,d2
.1		move.l	(a2)+,(a3)+
		dbra	d2,.1
.return		bsr	answerpacket
		move.l	d3,a1
		bra	FreeVec

ACT_DISK_INFO
		moveq	#id_SIZEOF,d0
		bsr	AllocVec
		move.l	d0,a2
		move.l	a2,d3
		lsr.l	#2,d0
		move.l	d0,dp_Arg1(a4)
		bsr	dopacket
		tst.w	d0
		beq.s	.return
		moveq	#8,d2
.1		move.l	(a2)+,(a3)+
		dbra	d2,.1
.return		bsr	answerpacket
		move.l	d3,a1
		bra	FreeVec

ACT_CURRENT_VOLUME
		GETBPTR	(a2),a0
		move.l	fh_Arg1(a0),dp_Arg1(a4)
		bsr	dopacket
		move.l	d0,(a3)+
		bra	answerpacket

ACT_NEWHANDLER
; -- has other side been reset?? --> current portnumber will be
; -- associated with a PHN in A5 !!
		move.l	a5,d1
		beq.s	.oki
		* here we have to free all PNSHandlerNodes !!

	IFNE	DEBUG
	lea	dresett(pc),a0
	bsr	dtype
	ENDC

		movem.l	a2/a3/d2/d3,-(sp)
		move.l	HandlerList(pc),a2
.freeloop	move.l	phn_packet(a2),a0
		sub.l	#sp_Pkt,a0
		bsr	DeleteStdPacket	;wichtig, da Signalbit freigegeben
		move.l	a2,a1		;werden muß
		move.l	(a2),a2
		bsr	FreeVec
		move.l	a2,d0
		bne.s	.freeloop
		movem.l	(sp)+,a2/a3/d2/d3
		sub.l	a5,a5
		clr.l	HandlerList ;<<-- hatte ich mal vergessen :(

; -- everything OK now.
.oki		move.l	a2,d1
	IFNE	DEBUG
	lea	daccesst(pc),a0
	bsr	dtype
	move.l	d1,a0
	bsr	dtype
	bsr	dcr
	ENDC

		move.l	dosbase(pc),a6
		LIBCALL	DeviceProc
		move.l	d0,d6		;Handler-ProcessID finden
		beq.s	.error
		move.l	a2,a0
.1		cmp.b	#":",(a2)+
		bne.s	.1
		clr.b	-(a2)
		bsr	FindDosNode
		move.l	d0,d5
		beq.s	.error
		move.l	#phn_SIZEOF,d0
		bsr	AllocVec
		tst.l	d0
		beq.s	.error
		move.l	d0,a2
		move.l	d5,phn_devnode(a2)
		move.w	d2,phn_port(a2)
		move.l	d6,phn_handlerID(a2)
		bsr	CreateStdPacket
		tst.l	d0
		beq.s	.error
		add.l	#sp_Pkt,d0
		move.l	d0,phn_packet(a2)
		lea	HandlerList(pc),a0
		move.l	(a0),phn_next(a2)
		move.l	a2,(a0)
		moveq	#0,d0
		bsr	answerpacket
	IFNE	DEBUG
	lea	dokt(pc),a0
	bsr	dtype
	ENDC
		bra	MsgDiskIns	;akt. Volumenode erstellen..
.error		moveq	#-1,d0
		bra	answerpacket

; -- Do Packet and Return Results
dopacket	; a5 *PNSHandlerNode
		move.l	phn_handlerID(a5),a0
		move.l	phn_packet(a5),a1
		sub.w	#sp_Pkt,a1	;Zeiger zurückdrehen auf Msg-
		bra	SyncStdPkt	;Struktur..

answerpacket	; d0 Result1
		; d1 Result2
		; a3 *end of sendbuf
		lea	sendbuf,a0
		movem.l	d0/d1,4(a0)
		move.l	4.w,a6
		move.l	pronetio(pc),a1
		sub.l	a0,a3
		move.l	a0,pnr_Data1(a1)
		move.l	a3,pnr_Length1(a1)
		LIBCALL	DoIO
		rts

****************************************************************************

; -- Find DLT_DEVICE entry in DosList with dol_Name = [a0]
FindDosNode	; a0 *devicename
		; RETURNS d0 *DosList or NULL
		movem.l	d6/a2/a5/a6,-(sp)
		moveq	#0,d6
		move.l	a0,a2
		move.l	4.w,a6
		LIBCALL	Forbid
		move.l	dosbase(pc),a5
		move.l	dl_Root(a5),a5
		move.l	rn_Info(a5),a5
		add.l	a5,a5
		add.l	a5,a5
		addq.w	#di_DevInfo,a5
.loop		move.l	(a5),d0
		beq.s	.ende
		add.l	d0,d0
		add.l	d0,d0
		move.l	d0,a5
		move.l	dol_Type(a5),d0		;DLT_DEVICE ?
		bne.s	.loop
		move.l	dol_Name(a5),a0
		add.l	a0,a0
		add.l	a0,a0
		addq.w	#1,a0
		move.l	a2,a1
		bsr	CompareStrings
		tst.w	d0
		bne.s	.loop
		;gefunden !
		move.l	a5,d6
.ende		LIBCALL	Permit
		move.l	d6,d0
		movem.l	(sp)+,d6/a2/a5/a6
		rts

; -- Find DLT_VOLUME entry in DosList with dol_Task = a0
FindVolume	; a0 *HandlerID
		; RETURNS d0 *DosList or NULL
		movem.l	d6/a2/a5/a6,-(sp)
		moveq	#0,d6
		move.l	a0,a2
		move.l	4.w,a6
		LIBCALL	Forbid
		move.l	dosbase(pc),a5
		move.l	dl_Root(a5),a5
		move.l	rn_Info(a5),a5
		add.l	a5,a5
		add.l	a5,a5
		addq.w	#di_DevInfo,a5
.loop		move.l	(a5),d0
		beq.s	.ende
		add.l	d0,d0
		add.l	d0,d0
		move.l	d0,a5
		cmp.l	#DLT_VOLUME,dol_Type(a5)
		bne.s	.loop
		cmp.l	dol_Task(a5),a2
		bne.s	.loop
		;gefunden !
		move.l	a5,d6
.ende		LIBCALL	Permit
		move.l	d6,d0
		movem.l	(sp)+,d6/a2/a5/a6
		rts

; -- Compare two null-terminated strings. Case-insensitive
CompareStrings	; a0 *String1
		; a1 *String2
		; RETURNS d0 = 0 --> Strings equal
		move.l	d2,-(sp)
		moveq	#-1,d0
.loop		move.b	(a0)+,d1
		move.b	(a1)+,d2
		bclr	#5,d1
		bclr	#5,d2
		cmp.b	d1,d2
		bne.s	.ende
		tst.b	d1
		bne.s	.loop
		moveq	#0,d0
.ende		move.l	(sp)+,d2
		rts

; -- AllocVec on Kick1.3 - requirements fixed to PUBLIC|CLEAR
AllocVec	; d0 bytesize
		movem.l	d2/a6,-(sp)
		move.l	4.w,a6
		addq.l	#4,d0
		move.l	d0,d2
		move.l	#MEMF_PUBLIC!MEMF_CLEAR,d1
		LIBCALL	AllocMem
		tst.l	d0
		beq.s	.nomem
		move.l	d0,a0
		move.l	d2,(a0)+
		move.l	a0,d0
.nomem		movem.l	(sp)+,d2/a6
		rts

; -- FreeVec
FreeVec		; a1 memory-block
		move.l	a6,-(sp)
		move.l	4.w,a6
		move.l	-(a1),d0
		LIBCALL	FreeMem
		move.l	(sp)+,a6
		rts

dec2long	; konvertiert Dezimalstring ab (a0) zu Longword in D1 !!
		moveq	#0,d1
.loop		moveq	#0,d0
		move.b	(a0)+,d0
		sub.b	#"0",d0
		cmp.b	#9,d0
		bhi.s	.oki
		move.l	d1,d2
		lsl.l	#3,d1
		add.l	d2,d1
		add.l	d2,d1
		add.l	d0,d1
		bra.s	.loop
.oki		rts

***************************************************************************
; -- Spezielle Sachen, die nichts mit dem Netzwerk zu tun haben, sondern
; -- für pronet-run und pronet-page gedacht sind !!!!

; in a2 data nach dp_Action..
ACT_RUN
		move.l	dosbase(pc),a6
		move.l	a2,d1
		moveq	#0,d2
		moveq	#0,d3
		jsr	-222(a6)
		rts

ACT_PAGE
		move.l	4.w,a6
		lea	intname(pc),a1
		moveq	#0,d0
		jsr	-552(a6)
		move.l	d0,a6
		lea	sendbuf,a3
		lea	.tex1(pc),a0
.1		move.b	(a0)+,(a3)+
		bpl.s	.1
		move.b	#0,(a3)+
		move.b	#20,(a3)+
		move.b	#25,(a3)+
.2		move.b	(a2)+,d0
		cmp.b	#$0a,d0
		beq.s	.3
		move.b	d0,(a3)+
		bra.s	.2
.3		clr.b	(a3)+
		clr.b	(a3)+
		lea	sendbuf,a0
		moveq	#0,d0
		moveq	#40,d1
		LIBCALL	DisplayAlert
		move.l	a6,a1
		move.l	4.w,a6
		jsr	-414(a6)
		rts

.tex1		dc.b	0,20,15,"pronet-page message:",0,-1
		even

		include	"A:ProNET/source/dospackets.s"
		include	"A:ProNET/source/devio.s"

	IFNE	DEBUG
		include	"A:OSdebugging.s"
dwaitt	dc.b	"Waiting for signals..",10,0
ddownloadt	dc.b	"**DOWNLOAD**",10,0
dresett		dc.b	27,"c** RESET **",10,0
daccesst	dc.b	"NEWHANDLER requires access to ",0
dokt		dc.b	"!access possible!",10,0
dreadt		dc.b	"ACT_READ: ",0
	even
	ENDC
;----------------------------------------------------------------------------

dosname		dc.b	"dos.library",0
intname		dc.b	"intuition.library",0
pronetname	dc.b	"pronet.device",0
inputname	dc.b	"input.device",0
starttext	dc.b	"ProNET V2 by Michael Krause - Server active..",10
starttextl	equ	*-starttext
procname	dc.b	"ProNET-Server"
		even

unit		dc.l	0
ourtask		dc.l	0
dosbase		dc.l	0
pronetio	dc.l	0
inputio		dc.l	0
pronetmsgport	dc.l	0
actpronetmsg	dc.l	0
HandlerList	dc.l	0	;einfache Liste mit allen Handlers, die
				;an uns hängen..

		section	b,bss

sendbuf		ds.b	$4000
workfib		ds.b	fib_SIZEOF
