2067 lines
48 KiB
ArmAsm
2067 lines
48 KiB
ArmAsm
; BSDSocket Extension for AMOS Professional
|
|
; Copyright 2023 John Bintz
|
|
; Licensed under the MIT License
|
|
;
|
|
; Writing this code the right way, 25 years later.
|
|
|
|
; extension number 18
|
|
ExtNb equ 18-1
|
|
Version MACRO
|
|
dc.b "1.0.0-20230401"
|
|
ENDM
|
|
VerNumber equ $1
|
|
|
|
;---------------------------------------------------------------------
|
|
; Include the files automatically calculated by
|
|
; Library_Digest.AMOS
|
|
;---------------------------------------------------------------------
|
|
Incdir "Stuff:development/amos-professional-official-mas/"
|
|
Incdir "Stuff:development/amos-professional-official-mas/includes/"
|
|
Include "BSDSocket_Size.s"
|
|
Include "BSDSocket_Labels.s"
|
|
Include "+AMOS_Includes.s"
|
|
Include "socket_lvo.i"
|
|
|
|
; get the effective address of something in extension memory
|
|
Dlea MACRO
|
|
MOVE.L ExtAdr+ExtNb*16(A5),\2
|
|
ADD.W #\1-MB,\2
|
|
ENDM
|
|
|
|
; load the base of extension memory into a register
|
|
Dload MACRO
|
|
MOVE.L ExtAdr+ExtNb*16(A5),\1
|
|
ENDM
|
|
|
|
; call an AmigaOS function via LVO(A6)
|
|
CALLLIB MACRO
|
|
JSR _LVO\1(A6)
|
|
ENDM
|
|
|
|
; bsdsocket library stuff
|
|
; ported from the various C include headers
|
|
SOCK_STREAM EQU 1
|
|
PF_INET EQU 2
|
|
AF_INET EQU PF_INET
|
|
IPPROTO_TCP EQU 6
|
|
|
|
INADDR_ANY EQU 0
|
|
|
|
FIONBIO EQU $8004667E
|
|
FIONASYNC EQU $8004667D
|
|
|
|
SOL_SOCKET EQU $FFFF
|
|
SO_REUSEADDR EQU $4
|
|
|
|
MAX_SOCKETS EQU 64
|
|
|
|
len_sockaddr_in EQU 16
|
|
sockaddr_in_sin_len EQU 0
|
|
sockaddr_in_sin_family EQU 1
|
|
sockaddr_in_sin_port EQU 2
|
|
sockaddr_in_sin_addr EQU 4
|
|
|
|
; global errors
|
|
Error_OtherError EQU -1
|
|
Error_LibraryNotOpen EQU -2
|
|
Error_PortOutOfRange EQU -11
|
|
Error_FdsetOutOfRange EQU -11
|
|
Error_UnableToBind EQU -12
|
|
|
|
; wrap code that doesn't take arguments with these
|
|
PreserveStackInstruction MACRO
|
|
MOVEM.L A2-A6/D6-D7,-(SP)
|
|
ENDM
|
|
RestoreStackInstruction MACRO
|
|
MOVEM.L (SP)+,A2-A6/D6-D7
|
|
ENDM
|
|
|
|
; wrap code that takes arguments with these
|
|
PreserveStackFunction MACRO
|
|
MOVEM.L A2/A4-A6/D6-D7,-(SP)
|
|
ENDM
|
|
RestoreStackFunction MACRO
|
|
MOVEM.L (SP)+,A2/A4-A6/D6-D7
|
|
ENDM
|
|
|
|
LoadBSDSocketBase MACRO
|
|
MOVE.L BSDSocketBase-MB(A3),A6
|
|
ENDM
|
|
|
|
WithDataStorage MACRO
|
|
MOVE.L A3,-(SP)
|
|
Dload A3
|
|
ENDM
|
|
|
|
EndDataStorage MACRO
|
|
MOVE.L (SP)+,A3
|
|
ENDM
|
|
|
|
; fdset macros
|
|
EnsureValidFdset MACRO
|
|
CMP.L #MaxFd_sets,\1
|
|
BLT \2
|
|
|
|
MOVE.L #Error_FdsetOutOfRange,D3
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
ENDM
|
|
|
|
EnsureValidFdsetBit MACRO
|
|
CMP.L #64,\1
|
|
BGE _EnsureValidFdsetBit_Fail\@
|
|
BRA \2
|
|
_EnsureValidFdsetBit_Fail\@:
|
|
MOVE.L \3,D3
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
ENDM
|
|
|
|
LeaFdset MACRO
|
|
MOVE.L \1,-(SP)
|
|
Dlea fd_sets,\2 ; base of all, these are longs
|
|
ROL.L #3,\1 ; multiply by 8
|
|
ADD.L \1,\2 ; add to base of all
|
|
MOVE.L (SP)+,\1
|
|
ENDM
|
|
|
|
; LeaFdsetForBit fd_set reg,target address,target bit in address
|
|
LeaFdsetForBit MACRO
|
|
LeaFdset \1,\2 ; get fdset base address in \2
|
|
MOVE.L D3,-(SP)
|
|
MOVE.L \3,D3 ; Put target bit into D3
|
|
ROR.L #5,D3 ; lop off the first 5 bits
|
|
AND.L #$7,D3 ; only keep the top three
|
|
ROL.L #2,D3 ; multiply by 4
|
|
ADD.L D3,\2 ; add that value to the fdset address
|
|
|
|
AND.L #$1F,\3 ; only keep 0-31 in \3
|
|
|
|
MOVEQ #1,D3
|
|
ROL.L \3,D3 ; shift that bit left as many as target
|
|
MOVE.L D3,\3 ; put that in the target
|
|
MOVE.L (SP)+,D3
|
|
|
|
ENDM
|
|
|
|
; d0 = value to be divided
|
|
; d1 = divisor
|
|
; returns:
|
|
; d0 = divided value
|
|
; d1 = remainder
|
|
LongDivideD0ByD1 MACRO
|
|
CMP.L D0,D1
|
|
BMI _LongDivide_StartDivide\@
|
|
|
|
MOVE.L D0,D1
|
|
MOVEQ #0,D0
|
|
BRA _LongDivide_Skip\@
|
|
|
|
_LongDivide_StartDivide\@:
|
|
|
|
MOVEM.L D2-D4,-(SP)
|
|
MOVEQ #0,D2 ; remainder
|
|
MOVE.L #31,D3 ; bit tracking
|
|
; d4 tracks the status register
|
|
|
|
_LongDivide_ContinueDivide\@:
|
|
ASL.L #1,D0
|
|
SCS D4 ; bit that got rolled out
|
|
AND.L #1,D4
|
|
ROL.L #1,D2
|
|
ADD.L D4,D2 ; roll the value onto the remainder
|
|
|
|
MOVE.L D2,D4
|
|
SUB.L D1,D4
|
|
|
|
BMI _LongDivide_NotDivisible\@
|
|
ADDQ #1,D0
|
|
MOVE.L D4,D2
|
|
|
|
_LongDivide_NotDivisible\@:
|
|
DBRA D3,_LongDivide_ContinueDivide\@
|
|
MOVE.L D2,D1
|
|
MOVEM.L (SP)+,D2-D4
|
|
|
|
_LongDivide_Skip\@:
|
|
ENDM
|
|
|
|
EvenOutStringAddress MACRO
|
|
MOVE.W \1,\2
|
|
AND.W #$0001,\2
|
|
ADD.W \2,\1
|
|
ENDM
|
|
|
|
; check if we've opened the bsd socket library
|
|
; we do this a lot, this could probably become something
|
|
; we jsr to...
|
|
; TODO make into routine
|
|
EnsureBSDSocketLibrary MACRO
|
|
MOVEM.L A2,-(SP)
|
|
Dload A2
|
|
TST.L BSDSocketBase-MB(A2)
|
|
MOVEM.L (SP)+,A2
|
|
|
|
BNE \1
|
|
|
|
MOVE.L #Error_LibraryNotOpen,D3
|
|
ENDM
|
|
|
|
; TODO token casing consistency
|
|
|
|
Start dc.l C_Tk-C_Off
|
|
dc.l C_Lib-C_Tk
|
|
dc.l C_Title-C_Lib
|
|
dc.l C_End-C_Title
|
|
; don't copy first library routine unless needed
|
|
dc.w 0
|
|
; API we're using
|
|
dc.b "AP20"
|
|
|
|
;---------------------------------------------------------------------
|
|
; Creates the pointers to functions
|
|
;---------------------------------------------------------------------
|
|
MCInit
|
|
C_Off
|
|
REPT Lib_Size
|
|
MC
|
|
ENDR
|
|
|
|
; make it way harder to get these confused
|
|
AddTokenInstruction MACRO
|
|
dc.w L_\1,L_Nul
|
|
ENDM
|
|
|
|
AddTokenFunction MACRO
|
|
dc.w L_Nul,L_\1
|
|
ENDM
|
|
|
|
******************************************************************
|
|
* TOKEN TABLE + Addresses
|
|
|
|
; TOKEN_START
|
|
C_Tk dc.w 1,0
|
|
dc.b $80,-1
|
|
|
|
AddTokenFunction SocketLibraryOpen
|
|
dc.b "socket library ope","n"+$80,"0",-1
|
|
|
|
AddTokenInstruction SocketLibraryClose
|
|
dc.b "socket library clos","e"+$80,"I",-1
|
|
|
|
AddTokenFunction SocketCreateInetSocket
|
|
dc.b "socket create inet socke","t"+$80,"0",-1
|
|
|
|
AddTokenFunction SocketConnect
|
|
dc.b "socket connec","t"+$80,"00t2,0",-1
|
|
|
|
AddTokenFunction SocketSendString
|
|
dc.b "socket send","$"+$80,"00,2",-1
|
|
|
|
AddTokenFunction SocketBind
|
|
dc.b "socket bin","d"+$80,"00t2,0",-1
|
|
|
|
AddTokenFunction SocketErrno
|
|
dc.b "socket errn","o"+$80,"0",-1
|
|
|
|
AddTokenFunction SocketListen
|
|
dc.b "socket liste","n"+$80,"00",-1
|
|
|
|
AddTokenFunction SocketAccept
|
|
dc.b "socket accep","t"+$80,"00",-1
|
|
|
|
AddTokenFunction SocketSetNonblocking
|
|
dc.b "socket set nonblockin","g"+$80,"00,0",-1
|
|
|
|
AddTokenFunction SocketSetsockoptInt
|
|
dc.b "socket setsockopt in","t"+$80,"00,0,0",-1
|
|
|
|
AddTokenFunction SocketFdsetZero
|
|
dc.b "socket fdset zer","o"+$80,"00",-1
|
|
|
|
AddTokenFunction SocketFdsetSet
|
|
dc.b "socket fdset se","t"+$80,"00,0t0",-1
|
|
|
|
AddTokenFunction SocketFdsetIsSet
|
|
dc.b "socket fdset is se","t"+$80,"00,0",-1
|
|
|
|
AddTokenFunction SocketSelect
|
|
dc.b "socket selec","t"+$80,"00,0,0,0,0",-1
|
|
|
|
AddTokenFunction SocketGetDebugArea
|
|
dc.b "socket get debug are","a"+$80,"0",-1
|
|
|
|
AddTokenFunction SocketGetHost
|
|
dc.b "socket get hos","t"+$80,"00",-1
|
|
|
|
AddTokenFunction SocketInetNtoA
|
|
dc.b "socket inet ntoa","$"+$80,"20",-1
|
|
|
|
AddTokenFunction SocketRecvString
|
|
dc.b "socket recv","$"+$80,"20,0",-1
|
|
|
|
AddTokenFunction SocketRecvData
|
|
dc.b "socket rec","v"+$80,"00t0,0",-1
|
|
|
|
AddTokenFunction SocketGetPort
|
|
dc.b "socket get por","t"+$80,"00",-1
|
|
|
|
AddTokenFunction SocketGetsockoptInt
|
|
dc.b "socket getsockopt in","t"+$80,"00,0",-1
|
|
|
|
AddTokenFunction SocketSendData
|
|
dc.b "socket sen","d"+$80,"00,0,0",-1
|
|
|
|
AddTokenFunction SocketWaitAsyncWriting
|
|
dc.b "socket wait async writin","g"+$80,"00,0",-1
|
|
|
|
AddTokenFunction SocketWaitAsyncReading
|
|
dc.b "socket wait async readin","g"+$80,"00,0",-1
|
|
|
|
AddTokenFunction SocketReuseAddr
|
|
dc.b "socket reuse add","r"+$80,"00",-1
|
|
|
|
AddTokenFunction DnsGetHostAddressByName
|
|
dc.b "dns get address by name","$"+$80,"22",-1
|
|
|
|
AddTokenFunction SocketSetTimeout
|
|
dc.b "socket set timeou","t"+$80,"00,0",-1
|
|
|
|
AddTokenFunction SocketCloseSocket
|
|
dc.b "socket close socke","t"+$80,"00",-1
|
|
|
|
; TOKEN_END
|
|
dc.w 0
|
|
dc.l 0 ; Important!
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
Lib_Ini 0
|
|
;---------------------------------------------------------------------
|
|
|
|
C_Lib
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; COLD START
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Def Cold
|
|
; - - - - - - - - - - - - -
|
|
cmp.l #"APex",d1 Version 1.10 or over?
|
|
bne.s BadVer
|
|
movem.l a3-a6,-(sp)
|
|
|
|
; ensure we can get to our data area
|
|
lea MB(pc),a2
|
|
move.l a2,ExtAdr+ExtNb*16(a5)
|
|
|
|
; cleanup on exit code in editor
|
|
lea Warm(pc),a0
|
|
move.l a0,ExtAdr+ExtNb*16+4(a5)
|
|
|
|
; cleanup when shutting down program
|
|
lea End(pc),a0
|
|
move.l a0,ExtAdr+ExtNb*16+8(a5)
|
|
|
|
movem.l (sp)+,a3-a6
|
|
moveq #ExtNb,d0 ; * NO ERRORS
|
|
move.w #VerNumber,d1 ; * Current version
|
|
rts
|
|
; In case this extension is runned on AMOSPro V1.00
|
|
BadVer moveq #-1,d0 ; * Bad version number
|
|
sub.l a0,a0
|
|
rts
|
|
|
|
MB:
|
|
BSDSocketBase dc.l 0 ; library base
|
|
|
|
IoctlSockOptScratch ds.l 2
|
|
len_sockaddr_in_ptr dc.l len_sockaddr_in
|
|
|
|
MaxFd_sets EQU 16
|
|
fd_sets dcb.l (MaxFd_sets*2),0
|
|
select_timeval dcb.l 2,0
|
|
timeout_timeval dcb.l (MAX_SOCKETS*2),0
|
|
getsockopt_len ds.l 1
|
|
|
|
MaxSocketSeen dc.w 0
|
|
|
|
sockaddr_ram ds.l 1
|
|
AcceptScratchArea ds.b 16
|
|
SelectScratchArea ds.l 2
|
|
|
|
DebugArea dcb.l 8,0
|
|
|
|
BSDSocketLibrary dc.b "bsdsocket.library",0
|
|
INADDR_ANY_String dc.b "INADDR_ANY",0
|
|
even
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; SCREEN RESET: back to AMOS requester (Called by AMOSPro)
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Warm
|
|
; - - - - - - - - - - - - -
|
|
Rbsr L_DoSocketLibraryClose
|
|
rts
|
|
|
|
; Program shutdown
|
|
End
|
|
Rbsr L_DoSocketLibraryClose
|
|
rts
|
|
|
|
;--------------------------------------------------------------------
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; Leave one empty routine here!
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Empty
|
|
; - - - - - - - - - - - - -
|
|
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Library Open
|
|
;
|
|
; Attempt to open bsdsocket.library version 4
|
|
;
|
|
; @return int address of library if opened, 0 if opening failed
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketLibraryOpen
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackInstruction
|
|
|
|
; ensure the library is closed before we try to reopen it
|
|
Rbsr L_DoSocketLibraryClose
|
|
|
|
Dload A3
|
|
MOVEQ #4,D0
|
|
Dlea BSDSocketLibrary,A1
|
|
MOVEA.L 4,A6
|
|
CALLLIB OpenLibrary
|
|
|
|
MOVE.L D0,BSDSocketBase-MB(A3)
|
|
BEQ _SocketLibraryOpen_Finish
|
|
|
|
; reserve ram for sockaddr_ins
|
|
MOVE.L #MAX_SOCKETS*len_sockaddr_in,D0
|
|
Rjsr L_RamFast
|
|
BEQ _SocketLibraryOpen_Finish
|
|
|
|
MOVE.L D0,sockaddr_ram-MB(A3)
|
|
|
|
_SocketLibraryOpen_Finish:
|
|
MOVE.L BSDSocketBase-MB(A3),D3
|
|
|
|
RestoreStackInstruction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; Socket Library Close
|
|
;
|
|
; Close bsdsocket.library if it was opened before. Does nothing if it's not.
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketLibraryClose
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackInstruction
|
|
|
|
Rbsr L_DoSocketLibraryClose
|
|
|
|
RestoreStackInstruction
|
|
RTS
|
|
|
|
|
|
; Utility functions
|
|
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; DoSocketSockaddrFree(sockaddr address D3)
|
|
;
|
|
; Free memory from sockaddrin
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
Lib_Def DoSocketSockaddrFree
|
|
|
|
MOVEM.L A1/D0,-(SP)
|
|
MOVE.L D3,A1 ; address
|
|
MOVE.L #len_sockaddr_in,D0
|
|
Rjsr L_RamFree
|
|
MOVEM.L (SP)+,A1/D0
|
|
|
|
RTS
|
|
|
|
|
|
; - - - - - - - - - -
|
|
; d0 = SocketIPAddressPortToSockaddr(socket d0, ip address d1, port d2)
|
|
;
|
|
; Turn an IP address and port into a sockaddr_in strucure
|
|
;
|
|
; d0 - 0 on success, -1 on failure
|
|
; - - - - - - - -
|
|
Lib_Def SocketIPAddressPortToSockaddr
|
|
|
|
; bail early if the port is too big
|
|
CMP.L #65535,D2
|
|
BLS _ToSockaddr_PortOK
|
|
|
|
MOVE.L #Error_PortOutOfRange,D0
|
|
RTS
|
|
|
|
_ToSockaddr_PortOK:
|
|
|
|
MOVEM.L A0/A3/D3,-(SP)
|
|
|
|
Dload A3
|
|
MOVE.L #len_sockaddr_in,D3
|
|
MULU D0,D3 ; D0 is socket
|
|
MOVE.L sockaddr_ram-MB(A3),A0
|
|
ADD.L D3,A0 ; A0 contains our offset in ram
|
|
|
|
MOVE.B #len_sockaddr_in,sockaddr_in_sin_len(A0)
|
|
MOVE.B #AF_INET,sockaddr_in_sin_family(A0)
|
|
MOVE.W D2,sockaddr_in_sin_port(A0)
|
|
|
|
MOVEM.L A0-A3/D3,-(SP)
|
|
|
|
MOVE.L D1,A0 ; ip address
|
|
ADDQ #2,A0 ; string data starts 2 bytes in
|
|
|
|
; if the string contains "INADDR_ANY", we use that value instead
|
|
MOVE.L A0,A1
|
|
Dlea INADDR_ANY_String,A2
|
|
MOVEQ #0,D3
|
|
|
|
_ToSockaddr_KeepCheckingString_1:
|
|
MOVE.B (A2)+,D3
|
|
BNE _ToSockaddr_KeepCheckingString_2
|
|
|
|
MOVE.L #INADDR_ANY,D0
|
|
BRA _ToSockaddr_DoneParsing
|
|
|
|
_ToSockaddr_KeepCheckingString_2:
|
|
CMP.B (A1)+,D3
|
|
BEQ _ToSockaddr_KeepCheckingString_1
|
|
|
|
_ToSockaddr_ParseIPAddress:
|
|
Dload A3
|
|
LoadBSDSocketBase
|
|
CALLLIB inet_addr
|
|
|
|
_ToSockaddr_DoneParsing:
|
|
MOVEM.L (SP)+,A0-A3/D3
|
|
MOVE.L D0,sockaddr_in_sin_addr(A0)
|
|
|
|
MOVE.L A0,D0
|
|
MOVEM.L (SP)+,A0/A3/D3
|
|
RTS
|
|
|
|
; basics
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Create Inet Socket
|
|
;
|
|
; Create an Internet-ready socket, the one you're most
|
|
; likely wanting to create.
|
|
;
|
|
; @return number of socket, -1 on failure, -2 on library not open
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketCreateInetSocket
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackInstruction
|
|
|
|
EnsureBSDSocketLibrary _SocketCreateInetSocket_LibraryOpen
|
|
|
|
RestoreStackInstruction
|
|
Ret_Int
|
|
|
|
_SocketCreateInetSocket_LibraryOpen:
|
|
|
|
MOVE.L #PF_INET,D0
|
|
MOVE.L #SOCK_STREAM,D1
|
|
MOVE.L #IPPROTO_TCP,D2
|
|
Dload A3
|
|
LoadBSDSocketBase
|
|
CALLLIB socket
|
|
|
|
MOVE.L D0,D3
|
|
|
|
; if this socket number is higher than the last one we've seen
|
|
; increment it
|
|
BMI _SocketCreateInetSocket_Done
|
|
|
|
MOVEQ #0,D1
|
|
MOVE.W MaxSocketSeen-MB(A3),D1
|
|
CMP.L D0,D1
|
|
BGT _SocketCreateInetSocket_Done
|
|
|
|
MOVE.W D0,MaxSocketSeen-MB(A3)
|
|
|
|
|
|
_SocketCreateInetSocket_Done:
|
|
|
|
RestoreStackInstruction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Connect(LONG SocketID to String IP Address, LONG Port)
|
|
;
|
|
; Connect a socket to a remote IP address and port.
|
|
;
|
|
; @return:
|
|
; 0 on connect
|
|
; -1 on other error
|
|
; -2 on library not open
|
|
; -11 on port out of range
|
|
; -12 on unable to connect
|
|
; -13 on unable to allocate ram for sockaddr
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketConnect
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,D2 ; port
|
|
MOVE.L (A3)+,D1 ; ip address
|
|
MOVE.L (A3)+,D0 ; socket id
|
|
|
|
EnsureBSDSocketLibrary _SocketConnect_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketConnect_LibraryOpen:
|
|
|
|
MOVE.L D0,-(SP) ; socket id onto stack
|
|
|
|
Rbsr L_SocketIPAddressPortToSockaddr
|
|
TST.L D0
|
|
BGT _SocketConnect_SockaddrIn
|
|
|
|
MOVE.L (SP)+,D1
|
|
|
|
MOVE.L D0,D3
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketConnect_SockaddrIn:
|
|
|
|
MOVE.L D0,A0
|
|
MOVE.L (SP)+,D0
|
|
|
|
MOVE.L D0,-(SP)
|
|
MOVEM.L A0/A3,-(SP)
|
|
Dload A3
|
|
; socket id is in D0
|
|
; sockaddr_in is in A0
|
|
MOVE.L #len_sockaddr_in,D1 ; len
|
|
LoadBSDSocketBase
|
|
CALLLIB connect
|
|
MOVEM.L (SP)+,A0/A3
|
|
|
|
MOVE.L D0,D3
|
|
MOVE.L (SP)+,D0
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Send$(LONG SocketID, String Data)
|
|
;
|
|
; Send a string to a connected socket
|
|
;
|
|
; @return:
|
|
; number of characters sent
|
|
; -1 on other error
|
|
; -2 on library not open
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketSendString
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,A0 ; string
|
|
MOVE.L (A3)+,D0 ; socket id
|
|
MOVE.W (A0)+,D1 ; string length, increment pointer
|
|
|
|
EnsureBSDSocketLibrary _SocketSendString_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketSendString_LibraryOpen:
|
|
MOVEQ #0,D2 ; flags
|
|
|
|
WithDataStorage
|
|
LoadBSDSocketBase
|
|
CALLLIB send
|
|
EndDataStorage
|
|
|
|
MOVE.L D0,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Send(LONG SocketID, void * Data, LONG length)
|
|
;
|
|
; Send a block of data to a connected socket
|
|
;
|
|
; @return:
|
|
; number of characters sent
|
|
; -1 on other error
|
|
; -2 on library not open
|
|
; -3 on negative length
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketSendData
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,D1 ; length
|
|
MOVE.L (A3)+,A0 ; data
|
|
MOVE.L (A3)+,D0 ; socket
|
|
|
|
EnsureBSDSocketLibrary _SocketSendData_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketSendData_LibraryOpen:
|
|
TST.L D1
|
|
BGE _SocketSendData_NotNegative
|
|
|
|
MOVE.L #-3,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketSendData_NotNegative:
|
|
MOVEQ #0,D2 ; flags
|
|
|
|
WithDataStorage
|
|
LoadBSDSocketBase
|
|
CALLLIB send
|
|
EndDataStorage
|
|
|
|
MOVE.L D0,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Bind(LONG SocketID to String IP Address, LONG Port)
|
|
;
|
|
; Bind a socket to a local IP address and port
|
|
;
|
|
; @return:
|
|
; 0 on success
|
|
; -1 on other error
|
|
; -2 on library not open
|
|
; -11 on port out of range
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketBind
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,D2 ; port
|
|
MOVE.L (A3)+,D1 ; ip address
|
|
MOVE.L (A3)+,D0 ; socket id
|
|
|
|
EnsureBSDSocketLibrary _SocketBind_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketBind_LibraryOpen:
|
|
; store current socket id for later
|
|
MOVE.L D0,-(SP)
|
|
|
|
Rbsr L_SocketIPAddressPortToSockaddr
|
|
TST.L D0
|
|
BGE _SocketBind_SockaddrIn
|
|
|
|
MOVE.L (SP)+,D1
|
|
MOVE.L D0,D3
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketBind_SockaddrIn:
|
|
MOVE.L D0,A0
|
|
MOVE.L (SP)+,D0
|
|
|
|
WithDataStorage
|
|
; socket id is in D0
|
|
; sockaddr_in is in A0
|
|
MOVE.L #len_sockaddr_in,D1 ; len
|
|
LoadBSDSocketBase
|
|
CALLLIB bind
|
|
EndDataStorage
|
|
|
|
MOVE.L D0,D3
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Errno
|
|
;
|
|
; Get the BSDSocket error number of the last failed command
|
|
;
|
|
; @return:
|
|
; Last BSD Socket error
|
|
; -2 on library not open
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketErrno
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackInstruction
|
|
|
|
EnsureBSDSocketLibrary _SocketErrno_LibraryOpen
|
|
|
|
RestoreStackInstruction
|
|
Ret_Int
|
|
|
|
_SocketErrno_LibraryOpen:
|
|
WithDataStorage
|
|
LoadBSDSocketBase
|
|
CALLLIB Errno
|
|
EndDataStorage
|
|
|
|
MOVE.L D0,D3
|
|
|
|
RestoreStackInstruction
|
|
RTS
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Listen(Socket ID LONG)
|
|
;
|
|
; Start listening on a socket
|
|
;
|
|
; @return:
|
|
; 0 on sucess
|
|
; -1 on failure
|
|
; -2 on library not open
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketListen
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,D0 ; Socket ID
|
|
|
|
EnsureBSDSocketLibrary _SocketListen_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketListen_LibraryOpen:
|
|
MOVE.L D3,D2
|
|
MOVEQ #5,D1
|
|
|
|
WithDataStorage
|
|
LoadBSDSocketBase
|
|
CALLLIB listen
|
|
EndDataStorage
|
|
|
|
MOVE.L D0,D3
|
|
|
|
RestoreStackFunction
|
|
RTS
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Accept(Socket ID LONG)
|
|
;
|
|
; Accept a connection on a socket. This is blocking unless you set
|
|
; Ioctl to be non-blocking!
|
|
;
|
|
; @return:
|
|
; remote socket
|
|
; -1 on failure
|
|
; -2 on library not open
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketAccept
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,D0 ; socket
|
|
|
|
EnsureBSDSocketLibrary _SocketAccept_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketAccept_LibraryOpen:
|
|
|
|
MOVE.L D3,D2
|
|
|
|
WithDataStorage
|
|
Dlea AcceptScratchArea,A0
|
|
Dlea len_sockaddr_in_ptr,A1
|
|
LoadBSDSocketBase
|
|
CALLLIB accept
|
|
EndDataStorage
|
|
|
|
MOVE.L D0,D3
|
|
BMI _SocketAccept_Failed
|
|
|
|
Dload A0
|
|
|
|
; update highest socket number seen
|
|
MOVEQ #0,D1
|
|
MOVE.W MaxSocketSeen-MB(A0),D1
|
|
CMP.L D0,D1
|
|
|
|
BGT _SocketAccept_CopySockaddrIn
|
|
MOVE.W D0,MaxSocketSeen-MB(A0)
|
|
|
|
_SocketAccept_CopySockaddrIn:
|
|
; we're putting sockaddr in info into our own storage area
|
|
MOVE.L D0,D1 ; new socket in d1
|
|
MULU #len_sockaddr_in,D1
|
|
MOVE.L sockaddr_ram-MB(A0),A0
|
|
ADD.L D1,A0 ; new socket sockaddr_in target in A0
|
|
|
|
Dlea AcceptScratchArea,A1
|
|
MOVEQ #len_sockaddr_in,D1
|
|
SUBQ #1,D1
|
|
_SocketAccept_CopyLoop:
|
|
MOVE.B (A1)+,(A0)+
|
|
DBRA D1,_SocketAccept_CopyLoop
|
|
|
|
_SocketAccept_Failed:
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Set Nonblocking(Socket ID LONG, Mode BOOLEAN)
|
|
;
|
|
; Configure a socket to be nonblocking (true) or blocking (false)
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketSetNonblocking
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L (A3)+,D0 ; socket
|
|
MOVE.L D3,D1 ; mode
|
|
|
|
EnsureBSDSocketLibrary _SocketSetNonblocking_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
RTS
|
|
|
|
_SocketSetNonblocking_LibraryOpen:
|
|
TST.L D1
|
|
BEQ _SocketSetNonblocking_IsBlocking
|
|
MOVEQ #1,D1
|
|
BRA _SocketSetNonblocking_Ioctl
|
|
|
|
_SocketSetNonblocking_IsBlocking:
|
|
MOVEQ #0,D1
|
|
|
|
_SocketSetNonblocking_Ioctl:
|
|
|
|
WithDataStorage
|
|
MOVE.L D1,IoctlSockOptScratch-MB(A3)
|
|
Dlea IoctlSockOptScratch,A0
|
|
MOVE.L #FIONBIO,D1
|
|
LoadBSDSocketBase
|
|
CALLLIB IoctlSocket
|
|
|
|
MOVE.L D0,D3
|
|
EndDataStorage
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Setsockopt Int(Socket ID LONG, Option LONG, Value LONG)
|
|
;
|
|
; Set a socket option
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketSetsockoptInt
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
; Value is in D3
|
|
MOVE.L (A3)+,D2 ; Option
|
|
MOVE.L (A3)+,D0 ; Socket ID
|
|
|
|
EnsureBSDSocketLibrary _SocketSetsockoptInt_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketSetsockoptInt_LibraryOpen:
|
|
Rbsr L_SetSockoptInt
|
|
|
|
MOVE.L D0,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Getsockopt Int(Socket ID LONG, Option LONG)
|
|
;
|
|
; Get a socket option's value
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketGetsockoptInt
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,D2 ; option
|
|
MOVE.L (A3)+,D0 ; socket
|
|
|
|
EnsureBSDSocketLibrary _SocketGetsockoptInt_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketGetsockoptInt_LibraryOpen:
|
|
MOVE.L #SOL_SOCKET,D1 ; level
|
|
|
|
MOVE.L A3,-(SP)
|
|
WithDataStorage
|
|
Dlea IoctlSockOptScratch,A0 ; optval
|
|
MOVE.L #4,getsockopt_len-MB(A3)
|
|
Dlea getsockopt_len,A1
|
|
|
|
LoadBSDSocketBase
|
|
CALLLIB getsockopt
|
|
EndDataStorage
|
|
MOVE.L (SP)+,A3
|
|
|
|
MOVE.L D0,D3
|
|
BPL _SocketGetsockoptInt_GetValue
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketGetsockoptInt_GetValue
|
|
Dlea IoctlSockOptScratch,A0
|
|
MOVE.L (A0),D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Fdset Zero(fd_set LONG)
|
|
;
|
|
; Clear out the indicated fd_set.
|
|
;
|
|
; @return Address of fd_set (2 longs), -1 if our of range, -2 no library
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketFdsetZero
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
EnsureBSDSocketLibrary _SocketFdsetZero_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketFdsetZero_LibraryOpen:
|
|
EnsureValidFdset D3,_SocketFdsetZero_ClearFdset
|
|
|
|
_SocketFdsetZero_ClearFdset
|
|
LeaFdset D3,A0
|
|
MOVE.L A0,D3
|
|
CLR.L (A0)+
|
|
CLR.L (A0)+
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Fdset Set(fd_set LONG, bit LONG to value BOOL)
|
|
;
|
|
; Set or unset an fd_set's bit
|
|
;
|
|
; @return Address of fd_set (2 longs), -1 if out of range, -2 no library
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketFdsetSet
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,D2 ; value
|
|
MOVE.L (A3)+,D1 ; bit
|
|
MOVE.L (A3)+,D0 ; fd_set
|
|
|
|
EnsureBSDSocketLibrary _SocketFdsetSet_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketFdsetSet_LibraryOpen:
|
|
EnsureValidFdset D0,_SocketFdsetSet_CheckBit
|
|
|
|
_SocketFdsetSet_CheckBit:
|
|
EnsureValidFdsetBit D1,_SocketFdsetSet_CheckNegative,#Error_FdsetOutOfRange
|
|
|
|
_SocketFdsetSet_CheckNegative:
|
|
CMP.L #0,D1
|
|
BGE _SocketFdsetSet_SetFdset
|
|
|
|
MOVE.L #Error_FdsetOutOfRange,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketFdsetSet_SetFdset:
|
|
; get correct fdset
|
|
|
|
MOVE.L A0,-(SP)
|
|
LeaFdsetForBit D0,A0,D1 ; D1 contains bit mask
|
|
|
|
TST.L D2 ; zero/false for clearing
|
|
BEQ _SocketFdsetSet_Clear
|
|
|
|
; setting
|
|
MOVE.L (A0),D3
|
|
OR.L D1,D3
|
|
BRA _SocketFdsetSet_Done
|
|
|
|
_SocketFdsetSet_Clear:
|
|
MOVE.L #$FFFFFFFF,D4
|
|
SUB.L D1,D4
|
|
|
|
MOVE.L (A0),D3
|
|
AND.L D4,D3
|
|
|
|
_SocketFdsetSet_Done:
|
|
MOVE.L D3,(A0)
|
|
MOVE.L (SP)+,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Fdset Is Set(fd_set LONG, Bit LONG)
|
|
;
|
|
; Return the status of a bit in an fd_set.
|
|
;
|
|
; @return 0 if not set, -1 if it is set, -2 on library not open
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketFdsetIsSet
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,D1 ; bit
|
|
MOVE.L (A3)+,D0 ; fdset
|
|
|
|
EnsureBSDSocketLibrary _SocketFdsetIsSet_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketFdsetIsSet_LibraryOpen:
|
|
EnsureValidFdset D0,_SocketFdsetIsSet_CheckBit
|
|
|
|
_SocketFdsetIsSet_CheckBit:
|
|
EnsureValidFdsetBit D1,_SocketFdsetIsSet_CheckNegative,#Error_FdsetOutOfRange
|
|
|
|
_SocketFdsetIsSet_CheckNegative:
|
|
CMP.L #0,D1
|
|
BGE _SocketFdsetIsSet_CheckFdsetBit
|
|
|
|
MOVE.L #Error_FdsetOutOfRange,D1
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketFdsetIsSet_CheckFdsetBit:
|
|
; get correct fdset
|
|
LeaFdsetForBit D0,A0,D1 ; D1 contains bit mask
|
|
|
|
MOVE.L (A0),D3
|
|
AND.L D1,D3 ; compare mask to value
|
|
|
|
BNE _SocketFdsetIsSet_IsSet
|
|
|
|
MOVEQ #0,D3
|
|
BRA _SocketFdsetIsSet_Done
|
|
|
|
_SocketFdsetIsSet_IsSet:
|
|
MOVE.L #-1,D3
|
|
|
|
_SocketFdsetIsSet_Done:
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Select(Max Socket long, Read fd_set long, Write fd_set long, error fd_set long, ms timeout long)
|
|
;
|
|
; Wait on the socket identifiers in the fd_sets, until the timeout expires.
|
|
;
|
|
; @return
|
|
; -2 on library not open
|
|
; -20 on read fd_set out of range
|
|
; -21 on write fd_set out of range
|
|
; -22 on error fd_set out of range
|
|
; -23 on ms must be positive
|
|
; number of sockets found on success
|
|
; 0 on timeout
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketSelect
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,D4 ; ms timeout
|
|
MOVE.L (A3)+,D3 ; error fd_set
|
|
MOVE.L (A3)+,D2 ; write fd_set
|
|
MOVE.L (A3)+,D1 ; read fd_set
|
|
MOVE.L (A3)+,D0 ; fd count
|
|
|
|
EnsureBSDSocketLibrary _SocketSelect_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketSelect_LibraryOpen:
|
|
EnsureValidFdsetBit D1,_SocketSelect_CheckWrite,#-20
|
|
|
|
_SocketSelect_CheckWrite:
|
|
EnsureValidFdsetBit D2,_SocketSelect_CheckError,#-21
|
|
|
|
_SocketSelect_CheckError:
|
|
EnsureValidFdsetBit D3,_SocketSelect_CheckTimeout,#-22
|
|
|
|
_SocketSelect_CheckTimeout:
|
|
CMP.L #0,D4
|
|
BGE _SocketSelect_MaybeReadFdset
|
|
|
|
MOVE.L #-23,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketSelect_MaybeReadFdset:
|
|
MOVE.L #0,A0
|
|
CMP.L #-1,D1
|
|
BEQ _SocketSelect_MaybeWriteFdset
|
|
LeaFdset D1,A0
|
|
|
|
_SocketSelect_MaybeWriteFdset
|
|
MOVE.L #0,A1
|
|
CMP.L #-1,D2
|
|
BEQ _SocketSelect_MaybeErrorFdset
|
|
LeaFdset D2,A1
|
|
|
|
_SocketSelect_MaybeErrorFdset
|
|
MOVE.L #0,A2
|
|
CMP.L #-1,D3
|
|
BEQ _SocketSelect_PerformSelect
|
|
LeaFdset D3,A2
|
|
|
|
_SocketSelect_PerformSelect
|
|
MOVE.L A3,-(SP)
|
|
; D4 contains microseconds
|
|
Rbsr L_MicrosecondsToTimeval ; A3 contains select_timeval
|
|
|
|
MOVEQ #0,D1
|
|
|
|
Dload A4
|
|
|
|
MOVE.L BSDSocketBase-MB(A4),A6
|
|
CALLLIB WaitSelect
|
|
MOVE.L (SP)+,A3
|
|
|
|
MOVE.L D0,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Get Debug Area
|
|
;
|
|
; Get the memory location for debug info. Put stuff in debug area while
|
|
; working on this extension and look it up in AMOS later.
|
|
;
|
|
; @return address of debug area
|
|
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketGetDebugArea
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
Dlea DebugArea,A0
|
|
MOVE.L A0,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Get Host(Socket LONG)
|
|
;
|
|
; Get the host long value for this socket's sockaddr_in.
|
|
;
|
|
; @return host long value
|
|
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketGetHost
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MULU #len_sockaddr_in,D3
|
|
Dload A0
|
|
MOVE.L sockaddr_ram-MB(A0),A0
|
|
ADD.L D3,A0
|
|
MOVE.L sockaddr_in_sin_addr(A0),D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Get Port(Socket LONG)
|
|
;
|
|
; Get the port word value for this socket's sockaddr_in.
|
|
;
|
|
; @return port word value
|
|
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketGetPort
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MULU #len_sockaddr_in,D3
|
|
Dload A0
|
|
MOVE.L sockaddr_ram-MB(A0),A0
|
|
ADD.L D3,A0
|
|
MOVEQ #0,D3
|
|
MOVE.W sockaddr_in_sin_port(A0),D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Inet Ntoa$(host LONG)
|
|
;
|
|
; Turn a host into a string
|
|
;
|
|
; @return host long value
|
|
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketInetNtoA
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
EnsureBSDSocketLibrary _SocketInetNtoa_LibraryOpen
|
|
|
|
RestoreStackInstruction
|
|
Ret_Int
|
|
|
|
_SocketInetNtoa_LibraryOpen:
|
|
MOVE.L D3,D0
|
|
WithDataStorage
|
|
LoadBSDSocketBase
|
|
CALLLIB Inet_NtoA
|
|
EndDataStorage
|
|
|
|
MOVEQ #0,D3
|
|
MOVE.L D0,A0
|
|
MOVE.L D0,A2 ; A0/A1 will get nuked by L_Demande
|
|
|
|
_SocketInetNtoA_StringSizeLoop:
|
|
TST.B (A0)+
|
|
BNE _SocketInetNtoA_StringSizeLoop
|
|
|
|
MOVE.L A0,D3
|
|
SUB.L A2,D3 ; D3 = length
|
|
Rjsr L_Demande ; string base address is in A0/A1
|
|
|
|
MOVE.W D3,(A0)+ ; length of string
|
|
SUBQ #1,D3
|
|
|
|
_SocketInetNtoA_StringCopyLoop:
|
|
MOVE.B (A2,D3),(A0,D3)
|
|
DBRA D3,_SocketInetNtoA_StringCopyLoop
|
|
|
|
; make the address even
|
|
EvenOutStringAddress A0,D3
|
|
|
|
MOVE.L A0,HiChaine(A5) ; Does L_Demande nuke A5 too?
|
|
|
|
MOVE.L A1,D3 ; string return
|
|
|
|
RestoreStackFunction
|
|
Ret_String
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Recv$(socket LONG, max length LONG)
|
|
;
|
|
; Receive at most length bytes of data from the socket
|
|
;
|
|
; @return string of bytes
|
|
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketRecvString
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L (A3)+,D1 ; socket
|
|
MOVE.L D3,D0 ; length
|
|
|
|
EnsureBSDSocketLibrary _SocketRecvString_LibraryOpen
|
|
|
|
MOVE.L ChVide(A5),D3
|
|
|
|
RestoreStackFunction
|
|
Ret_String
|
|
|
|
_SocketRecvString_LibraryOpen:
|
|
TST.L D0
|
|
BGT _SocketRecvString_NotNegative
|
|
|
|
MOVE.L ChVide(A5),D3
|
|
|
|
RestoreStackFunction
|
|
Ret_String
|
|
|
|
_SocketRecvString_NotNegative:
|
|
CMP.L #65536,D0
|
|
BLT _SocketRecvString_NotTooLong
|
|
|
|
MOVE.L ChVide(A5),D3
|
|
|
|
RestoreStackFunction
|
|
Ret_String
|
|
|
|
_SocketRecvString_NotTooLong:
|
|
MOVE.L A3,-(SP) ; preserve A3
|
|
|
|
MOVE.L D0,-(SP) ; preserve D0
|
|
; reserve memory for recv buffer
|
|
Rjsr L_RamFast ; D0 now contains memory pointer
|
|
BNE _SocketRecvString_BufferAllocated
|
|
; reserve failed
|
|
MOVE.L (SP)+,D0
|
|
|
|
MOVE.L (SP)+,A3
|
|
|
|
MOVE.L ChVide(A5),D3 ; empty string
|
|
RestoreStackFunction
|
|
Ret_String
|
|
|
|
_SocketRecvString_BufferAllocated:
|
|
MOVE.L D0,A0 ; buffer address
|
|
MOVE.L D1,D0 ; socket
|
|
MOVE.L (SP)+,D1 ; length
|
|
MOVEQ #0,D2 ; flags
|
|
|
|
MOVEM.L A0-A1/D1,-(SP)
|
|
|
|
WithDataStorage
|
|
LoadBSDSocketBase
|
|
CALLLIB recv ; D0 has received length or -1
|
|
EndDataStorage
|
|
|
|
MOVEM.L (SP)+,A0-A1/D1
|
|
|
|
; did we receive data? if we didn't get a single byte, we're done
|
|
TST.L D0
|
|
BGT _SocketRecvString_DataReceived
|
|
|
|
; free ram
|
|
MOVE.L D1,D0
|
|
MOVE.L A0,A1
|
|
Rjsr L_RamFree
|
|
|
|
MOVE.L (SP)+,A3
|
|
|
|
MOVE.L ChVide(A5),D3
|
|
RestoreStackFunction
|
|
Ret_String
|
|
|
|
; TODO received data is wrong somewhere
|
|
|
|
_SocketRecvString_DataReceived:
|
|
; D0 contains receive length
|
|
|
|
MOVE.L D1,-(SP)
|
|
MOVEQ #0,D3
|
|
MOVE.W D0,D3 ; prep for L_Demande. can we request a zero length string?
|
|
MOVE.L A0,A2 ; L_Demande blows away A0 and A1, A2 now contains buffer
|
|
Rjsr L_Demande ; A0/A1 contain string address
|
|
|
|
MOVE.W D3,(A0)+ ; put in string length
|
|
SUBQ #1,D3 ; reduce by one for DBRA
|
|
MOVE.L A2,A3 ; A3 now contains start of buffer
|
|
|
|
_SocketRecvString_CopyData:
|
|
MOVE.B (A2,D3),(A0,D3)
|
|
DBRA D3,_SocketRecvString_CopyData
|
|
|
|
EvenOutStringAddress A0,D2
|
|
|
|
; add to string manager for garbage collection?
|
|
MOVE.L A0,HiChaine(A5)
|
|
MOVE.L (SP)+,D0
|
|
|
|
; free ram
|
|
MOVE.L A1,-(SP) ; A1 contains our string addres
|
|
|
|
;MOVE.L D1,D0
|
|
MOVE.L A3,A1
|
|
Rjsr L_RamFree
|
|
|
|
MOVE.L (SP)+,D3 ; string return
|
|
|
|
MOVE.L (SP)+,A3
|
|
|
|
RestoreStackFunction
|
|
Ret_String
|
|
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Recv(socket LONG to address LONG, max size LONG)
|
|
;
|
|
; Receive at most length bytes of data from the socket into an existing
|
|
; memory area
|
|
;
|
|
; @return length read, -? on failure
|
|
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketRecvData
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,D1 ; length
|
|
MOVE.L (A3)+,A0 ; address
|
|
MOVE.L (A3)+,D0 ; socket
|
|
MOVEQ #0,D2 ; flags
|
|
|
|
EnsureBSDSocketLibrary _SocketRecvData_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketRecvData_LibraryOpen:
|
|
TST.L D1
|
|
BGT _SocketRecvData_PositiveLength
|
|
|
|
MOVE.L #-3,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketRecvData_PositiveLength:
|
|
WithDataStorage
|
|
LoadBSDSocketBase
|
|
CALLLIB recv ; D0 has received length or -1
|
|
EndDataStorage
|
|
|
|
MOVE.L D0,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
|
|
|
|
; actually close the library
|
|
|
|
Lib_Def DoSocketLibraryClose
|
|
|
|
Dload A3
|
|
TST.L sockaddr_ram-MB(A3)
|
|
BEQ _DoSocketLibraryClose_CloseLibrary
|
|
|
|
MOVE.L sockaddr_ram-MB(A3),A1
|
|
MOVE.L #MAX_SOCKETS*len_sockaddr_in,D0
|
|
Rjsr L_RamFree
|
|
CLR.L sockaddr_ram-MB(A3) ; prevent double free
|
|
|
|
_DoSocketLibraryClose_CloseLibrary:
|
|
|
|
MOVE.L BSDSocketBase-MB(A3),D0
|
|
|
|
BEQ _DoSocketLibraryClose_Skip
|
|
CLR.L BSDSocketBase-MB(A3) ; prevent double free
|
|
|
|
MOVE.L D0,A1
|
|
MOVE.L 4,A6
|
|
CALLLIB CloseLibrary
|
|
|
|
_DoSocketLibraryClose_Skip:
|
|
RTS
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Wait Async Writing(Socket long, ms timeout long)
|
|
;
|
|
; Wait for this socket to be ready for writing, with a timeout
|
|
;
|
|
; @return
|
|
; 1 on success
|
|
; -2 on library not open
|
|
; -3 on not interesting yet
|
|
; 0 on timeout
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketWaitAsyncWriting
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,D4 ; ms timeout
|
|
MOVE.L (A3)+,D0 ; socket
|
|
|
|
EnsureBSDSocketLibrary _SocketWaitAsyncWriting_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketWaitAsyncWriting_LibraryOpen:
|
|
MOVEM.L A3-A4,-(SP)
|
|
Dload A4
|
|
|
|
MOVE.L D4,-(SP)
|
|
MOVEQ #0,D1
|
|
LeaFdset D1,A0
|
|
; Clear fdset
|
|
CLR.L (A0)+
|
|
CLR.L (A0)+
|
|
|
|
; we'll use the first FdSet
|
|
MOVE.L D0,D2
|
|
LeaFdsetForBit D1,A0,D2
|
|
MOVE.L D2,(A0)
|
|
MOVE.L (SP)+,D4
|
|
|
|
Rbsr L_MicrosecondsToTimeval ; A3 contains timeval
|
|
|
|
Dload A4
|
|
MOVE.L D0,-(SP)
|
|
; set up WaitSelect
|
|
MOVEQ #0,D1
|
|
LeaFdset D1,A1 ; write fdset
|
|
|
|
MOVE.L #0,A0 ; read fdset
|
|
MOVE.L #0,A2 ; error fdset
|
|
MOVEQ #0,D0
|
|
MOVE.W MaxSocketSeen-MB(A4),D0
|
|
ADDQ #1,D0 ; number of file descriptors + 1
|
|
MOVEQ #0,D1 ; mask
|
|
|
|
MOVE.L BSDSocketBase-MB(A4),A6
|
|
CALLLIB WaitSelect
|
|
|
|
TST.L D0 ; timeout, pass through
|
|
BPL _SocketWaitAsyncWriting_Done
|
|
MOVE.L (SP)+,D0 ; D0 contains socket again
|
|
|
|
Dload A4
|
|
; a socket became interesting, check the Fdset
|
|
MOVE.L D0,-(SP)
|
|
MOVE.L D0,D3 ; socket in D3
|
|
MOVEQ #0,D1 ; fdset in D1
|
|
LeaFdsetForBit D1,A0,D3 ; A0 is mem, D3 is mask
|
|
AND.L D3,(A0) ; D3 should mask (A0)
|
|
BEQ _SocketWaitAsyncWriting_CheckSockopt ; if yes, is ready
|
|
MOVE.L (SP)+,D0
|
|
|
|
; not interesting yet
|
|
MOVEM.L (SP)+,A3-A4
|
|
MOVE.L #-3,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketWaitAsyncWriting_CheckSockopt:
|
|
MOVE.L (SP)+,D0 ; socket
|
|
MOVE.L #$1007,D2 ; option
|
|
MOVE.L #SOL_SOCKET,D1 ; level
|
|
|
|
MOVE.L A3,-(SP)
|
|
|
|
WithDataStorage
|
|
Dlea IoctlSockOptScratch,A0 ; optval
|
|
MOVE.L #4,getsockopt_len-MB(A3)
|
|
Dlea getsockopt_len,A1
|
|
|
|
LoadBSDSocketBase
|
|
CALLLIB getsockopt
|
|
EndDataStorage
|
|
|
|
MOVE.L (SP)+,A3
|
|
|
|
TST.L D0
|
|
BPL _SocketWaitAsyncWriting_Ready
|
|
|
|
MOVEM.L (SP)+,A3-A4
|
|
MOVE.L #-3,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketWaitAsyncWriting_Ready:
|
|
MOVEM.L (SP)+,A3-A4
|
|
MOVEQ #1,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketWaitAsyncWriting_Done:
|
|
MOVE.L (SP)+,D1
|
|
MOVEM.L (SP)+,A3-A4
|
|
|
|
MOVE.L D0,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Wait Async Reading(Socket long, ms timeout long)
|
|
;
|
|
; Wait for this socket to be ready for reading, with a timeout
|
|
;
|
|
; @return
|
|
; 1 on success
|
|
; -2 on library not open
|
|
; -3 on not interesting yet
|
|
; 0 on timeout
|
|
; -1 on error
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketWaitAsyncReading
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,D4 ; ms timeout
|
|
MOVE.L (A3)+,D0 ; socket
|
|
|
|
EnsureBSDSocketLibrary _SocketWaitAsyncReading_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketWaitAsyncReading_LibraryOpen:
|
|
MOVEM.L A3-A4,-(SP)
|
|
Dload A4
|
|
|
|
MOVE.L D4,-(SP)
|
|
MOVEQ #0,D1
|
|
LeaFdset D1,A0
|
|
; Clear fdset
|
|
CLR.L (A0)+
|
|
CLR.L (A0)+
|
|
|
|
; we'll use the first FdSet
|
|
MOVE.L D0,D2
|
|
LeaFdsetForBit D1,A0,D2
|
|
MOVE.L D2,(A0)
|
|
MOVE.L (SP)+,D4
|
|
|
|
Rbsr L_MicrosecondsToTimeval ; A3 contains timeval
|
|
|
|
Dload A4
|
|
MOVE.L D0,-(SP)
|
|
; set up WaitSelect
|
|
MOVEQ #0,D1
|
|
LeaFdset D1,A0 ; read fdset
|
|
|
|
MOVE.L #0,A1 ; write fdset
|
|
MOVE.L #0,A2 ; error fdset
|
|
MOVEQ #0,D0
|
|
MOVE.W MaxSocketSeen-MB(A4),D0
|
|
ADDQ #1,D0 ; number of file descriptors + 1
|
|
MOVEQ #0,D1
|
|
|
|
MOVE.L BSDSocketBase-MB(A4),A6
|
|
CALLLIB WaitSelect
|
|
|
|
TST.L D0 ; timeout, pass through
|
|
BEQ _SocketWaitAsyncReading_Done
|
|
BMI _SocketWaitAsyncReading_Done
|
|
MOVE.L (SP)+,D0 ; D0 contains socket again
|
|
|
|
;Dload A4
|
|
; a socket became interesting, check the Fdset
|
|
MOVE.L D0,D3 ; socket in D3
|
|
MOVEQ #0,D1 ; fdset in D1
|
|
LeaFdsetForBit D1,A0,D3 ; A0 is mem, D3 is mask
|
|
AND.L D3,(A0) ; D3 should mask (A0)
|
|
BEQ _SocketWaitAsyncReading_Ready ; if yes, is ready
|
|
|
|
; not interesting yet
|
|
MOVEM.L (SP)+,A3-A4
|
|
MOVE.L #-3,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketWaitAsyncReading_Ready:
|
|
MOVEM.L (SP)+,A3-A4
|
|
MOVEQ #1,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketWaitAsyncReading_Done:
|
|
MOVE.L (SP)+,D1
|
|
MOVEM.L (SP)+,A3-A4
|
|
|
|
MOVE.L D0,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Reuse Addr(Socket ID LONG)
|
|
;
|
|
; Specifically set the SO_REUSEADDR function on a socket
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketReuseAddr
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
EnsureBSDSocketLibrary _SocketReuseAddr_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketReuseAddr_LibraryOpen:
|
|
MOVE.L D3,D0
|
|
MOVE.L #SO_REUSEADDR,D2
|
|
MOVEQ #1,D3
|
|
|
|
Rbsr L_SetSockoptInt
|
|
|
|
MOVE.L D0,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; A3 MicrosecondsToTimeval(Microseconds D4)
|
|
;
|
|
; Create a Timeval struct from microseconds
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
Lib_Def MicrosecondsToTimeval
|
|
|
|
MULU #1000,D4 ; we accept milliseconds
|
|
; turn this into seconds and microseconds via divide
|
|
|
|
MOVEM.L D0/D1/A5,-(SP)
|
|
MOVE.L D4,D0
|
|
MOVE.L #1000000,D1
|
|
|
|
LongDivideD0ByD1
|
|
|
|
Dlea select_timeval,A3
|
|
MOVE.L D0,(A3)+
|
|
MOVE.L D1,(A3)+
|
|
MOVEM.L (SP)+,D0/D1/A5
|
|
Dlea select_timeval,A3
|
|
|
|
RTS
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; D0 SetSockoptInt(Socket D0, Option D2, Value D3)
|
|
;
|
|
; Set a socket option
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
Lib_Def SetSockoptInt
|
|
|
|
MOVEM.L A0/D1-D3,-(SP)
|
|
|
|
MOVE.L #SOL_SOCKET,D1 ; Level
|
|
|
|
WithDataStorage
|
|
Dlea IoctlSockOptScratch,A0 ; optval
|
|
MOVE.L D3,A0
|
|
MOVEQ #4,D3
|
|
|
|
LoadBSDSocketBase
|
|
CALLLIB setsockopt
|
|
EndDataStorage
|
|
|
|
MOVEM.L (SP)+,A0/D1-D3
|
|
RTS
|
|
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Dns Get Host Address By Name$(Name String)
|
|
;
|
|
; Get the status of a socket
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par DnsGetHostAddressByName
|
|
|
|
PreserveStackFunction
|
|
EnsureBSDSocketLibrary _DnsGetHostAddressByName_LibraryOpen
|
|
|
|
MOVE.L ChVide(A5),D3
|
|
|
|
RestoreStackFunction
|
|
Ret_String
|
|
|
|
_DnsGetHostAddressByName_LibraryOpen:
|
|
|
|
; string so you need demande, hichaine, and chvide
|
|
MOVE.L D3,A0 ; name
|
|
ADD.L #2,A0 ; skip length, string is null terminated (?)
|
|
|
|
WithDataStorage
|
|
LoadBSDSocketBase
|
|
CALLLIB gethostbyname
|
|
EndDataStorage
|
|
|
|
TST.L D0
|
|
BNE _DnsGetHostAddressByName_GetIPAddress
|
|
|
|
RestoreStackFunction
|
|
|
|
MOVE.L ChVide(A5),D3
|
|
Ret_String
|
|
|
|
_DnsGetHostAddressByName_GetIPAddress:
|
|
|
|
MOVE.L D0,A0
|
|
MOVE.L 16(A0),A1 ; **h_addr_list
|
|
MOVE.L (A1),A1 ; *h_addr_list
|
|
MOVE.L (A1),D0 ; h_addr_list[0]
|
|
|
|
WithDataStorage
|
|
LoadBSDSocketBase
|
|
CALLLIB Inet_NtoA
|
|
EndDataStorage
|
|
|
|
MOVE.L D0,A2
|
|
MOVE.L A2,-(SP)
|
|
MOVEQ #0,D3
|
|
|
|
_DnsGetHostAddressByName_GetIPAddressLength:
|
|
ADDQ #1,D3
|
|
TST.B (A2)+
|
|
BNE _DnsGetHostAddressByName_GetIPAddressLength
|
|
MOVE.L (SP)+,A2
|
|
|
|
Rjsr L_Demande ; string is in A0/A1
|
|
MOVE.W D3,(A0)+
|
|
SUBQ #1,D3
|
|
|
|
_DnsGetHostAddressByName_KeepCopying:
|
|
MOVE.B (A2,D3),(A0,D3)
|
|
DBRA D3,_DnsGetHostAddressByName_KeepCopying
|
|
|
|
EvenOutStringAddress A0,D0
|
|
|
|
MOVE.L A0,HiChaine(A5)
|
|
MOVE.L A1,D3
|
|
|
|
RestoreStackFunction
|
|
|
|
Ret_String
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Set Timeout(Socket ID LONG, ms Long)
|
|
;
|
|
; Set SO_SNDTIMEO and SO_RCVTIMEO on a socket
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketSetTimeout
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
|
|
MOVE.L D3,D4 ; milliseconts
|
|
MOVE.L (A3)+,D0 ; socket id
|
|
|
|
EnsureBSDSocketLibrary _SocketSetTimeout_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketSetTimeout_LibraryOpen:
|
|
MOVE.L A3,-(SP)
|
|
Rbsr L_MicrosecondsToTimeval
|
|
MOVE.L A3,A0 ; select_timeval
|
|
MOVE.L (SP)+,A3
|
|
|
|
MOVE.L D0,D1 ; socket id
|
|
ROL.L #1,D1 ; *2
|
|
Dlea timeout_timeval,A1
|
|
ADD.L D1,A1
|
|
MOVE.L (A0)+,(A1)+ ; copy timeval
|
|
MOVE.L (A0)+,(A1)+
|
|
SUB.L #8,A1 ; go back
|
|
|
|
WithDataStorage
|
|
; socket is d0
|
|
MOVE.L #SOL_SOCKET,D1 ; Level
|
|
MOVE.L #$1005,D2 ; SO_SNDTIMEO
|
|
MOVE.L A1,A0 ; timeval
|
|
MOVEQ #8,D3
|
|
|
|
MOVEM.L D0/A0,-(SP)
|
|
LoadBSDSocketBase
|
|
CALLLIB setsockopt
|
|
|
|
TST.L D0
|
|
BNE _SocketSetTimeout_Fail
|
|
MOVEM.L (SP)+,D0/A0 ; socket/timeval
|
|
|
|
MOVE.L #SOL_SOCKET,D1
|
|
MOVE.L #$1006,D2 ; SO_RCVTIMEO
|
|
MOVEQ #8,D3
|
|
|
|
LoadBSDSocketBase
|
|
CALLLIB setsockopt
|
|
|
|
EndDataStorage
|
|
|
|
MOVE.L D0,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketSetTimeout_Fail:
|
|
MOVEM.L (SP)+,D1/A0
|
|
EndDataStorage
|
|
|
|
MOVE.L D0,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; =Socket Close Socket(Socket ID LONG)
|
|
;
|
|
; Close a socket
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Par SocketCloseSocket
|
|
; - - - - - - - - - - - - -
|
|
PreserveStackFunction
|
|
EnsureBSDSocketLibrary _SocketCloseSocket_LibraryOpen
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
_SocketCloseSocket_LibraryOpen:
|
|
|
|
MOVE.L D3,D0
|
|
|
|
WithDataStorage
|
|
LoadBSDSocketBase
|
|
CALLLIB CloseSocket
|
|
EndDataStorage
|
|
|
|
MOVE.L D0,D3
|
|
|
|
RestoreStackFunction
|
|
Ret_Int
|
|
|
|
;
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; Even if you do not have error messages, you MUST
|
|
; leave TWO routines empty at the end...
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_Empty
|
|
Lib_Empty
|
|
; - - - - - - - - - - - - -
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; Finish the library
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Lib_End
|
|
; - - - - - - - - - - - - -
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; TITLE OF THE EXTENSION
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
C_Title dc.b "AMOSPro BSD Socket Library "
|
|
Version
|
|
dc.b " (code.hackerbun.dev)"
|
|
dc.b 0,"$VER: "
|
|
Version
|
|
dc.b 0
|
|
Even
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
; END OF THE EXTENSION
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
C_End dc.w 0
|
|
even
|