home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ARM Club 3
/
TheARMClub_PDCD3.iso
/
hensa
/
internet
/
socketfs_2
/
S
/
Modmain
Wrap
Text File
|
1997-09-07
|
20KB
|
613 lines
; Socket.s
; : Source code to SocketFS
; : BSD sockets as files!
;
; Created : 04-07-97
; Author : R G Gammans
;
; Modified: 18-08-97
; SocketFS - BSD sockets filing system for RISC-OS.
; Copyright (C) 1997 Roger G Gammans
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;
; Author: R Gammans <rgammans@compsurg,demon.co.uk>
; Snailmail : 20 Trenches Rd, Crowborough, E Sussex, TN6 1ES UK.
;
GET AsmLib:s.DebugHdr
;Debug SETL {TRUE}
Debug SETL {FALSE}
GET AsmLib:h.SWINames
GET AsmLib:h.FSControls
GET AsmLib:h.psrFlags
GET AsmLib:h.sockConsts
IMPORT |__RelocCode|
IMPORT |_clib_initialisemodule|
IMPORT |_clib_finalisemodule|
IMPORT |malloc|
IMPORT |memcpy|
IMPORT |makeSocket|
IMPORT |inithandlerlist|
IMPORT |_Lib$Reloc$Off$DP|
AREA |!!Module$Header|, CODE, READONLY
Pc RN R15
pc RN R15
PC RN R15
tempbyte * 0 ;Use first byte of workspace as dumping ground.
SocketFSMod_BaseAddr
DCD 0
DCD Socket_Init - SocketFSMod_BaseAddr
DCD Socket_Die - SocketFSMod_BaseAddr
DCD 0 ;Later version will probaly
;handle services
DCD Socket_Title - SocketFSMod_BaseAddr
DCD Socket_HelpStr - SocketFSMod_BaseAddr
DCD Socket_HC_Table- SocketFSMod_BaseAddr
DCD 0
DCD 0
DCD 0
DCD 0
Socket_DoSWI
Socket_SWITable
DCD 0,0
Socket_Title
DCB "SocketFS",0
Socket_HelpStr DCB "SocketFS",9,"0.01 (18 Aug 1997) © Roger Gammans. Distribute as per GPL V2",0
ALIGN
Socket_HC_Table DCB "SocketFS",0
ALIGN
DCD socket_selectfs- SocketFSMod_BaseAddr
DCD 0
DCD 0
DCD socket_selectfs_help- SocketFSMod_BaseAddr
DCD 0
socket_selectfs_help
DCB &1b,1,13,13,"This command ",&1b,28,"s",&1b,2,"socket ",&1b,4,0
socket_selectfs ;Nicked form PRMs (RO3) P.2-524
STMFD R13!,{R14}
MOV R0,#FSControl_selectFS ;14
ADR R1,socket_fsname
SWI XOS_FSControl
LDMFD R13!, {PC}
Socket_Init
STMFD R13!,{R7-R11,r14}
MOV R10,R13,LSR #20 ;Which MB boundary is the stack on...
MOV R10,R10,LSL #20 ;point R10 directly at booundary...
LDMIA R10,{R4,R5} ;Get relocation for other C SVC modules....
STMFD R13!,{R4,R5} ;hold it safley on top of stack!
STMFD R13!,{R12} ;R12 corruptable under APCS-R....
; BL __RelocCode ;Do any relocations and return.
BL _clib_initialisemodule ;We use 'C' functions so...
DBSET DebugOn :OR: UseTracker
DBF "\fStarting\n-sp = &%dw\n"
MOV R0,#12 ;12 bytes ws.
BL malloc ;Allocate it!
MOVS R6,R0 ;Set flags from R0
BEQ socket_nomem ;Can't alloc ret eith error
LDMFD R13!,{r12} ;Get R12 Back..
LDR R12,[R12] ;Get ws frm private word...
STR R12,[R6,#4] ;Store stub's ws ptr.
DBF "Doing AF_INIT (sic) ws@ %4w, %cw\n"
BL inithandlerlist ;Initialise list of known address families
DBF "Done AF_INIT ws's @ %4w, %cw\n"
BL socket_clibstackunmunge ;Return stack to SVC std..
DBF "Done Stack unmunge...sp = &%dw\n"
MOV R3,R6 ;Pass our ws to FS_control as ws ptr
MOV R0,#FSControl_AddFS
ADR R1,SocketFSMod_BaseAddr
MOV R2,# socket_FSinfo - SocketFSMod_BaseAddr
DBF "About to call SWI...\n"
SWI XOS_FSControl ;Add FS info to RISC-OS
DBF "Done SWI ADDFS\n"
LDMFD R13!,{R7-r11,pc}
Socket_Die
LDR R12,[R12] ;Get pointer to workspace.
STMFD R13!,{R14} ;Save R14 on stack so we can use SWIs
MOV R0,#FSControl_removeFS
ADR R1,socket_fsname
SWI XOS_FSControl ;Tell RISC-OS FS is going...
BL socket_clibstackmunge
MOV R0,R12
BL _clib_finalisemodule
BL socket_clibstackunmunge
CMP PC,#0 ;Clear V flag.
LDMFD R13!,{pc} ;Done go home.
socket_nomem
LDMFD R13!,{R12}
LDMFD R13!,{R7-R11,R14}
ADR R0,socket_nomemmsg
ORRS PC,R14,#V_Bit
socket_nomemmsg
DCD &001FF01
DCB "No memory for filing system",13,0
ALIGN
;Need to find I bettr way of commenting these bit fields.
;socket_info_word EQU 1 << 31+
; 1 << 30 + ;Streams are interactive
; 0 << 29 + ;FS does support null length names;
; 1 << 28 + ;FS should be asked to open Non-existent files
; 0 << 27 + ;Use FSEntry Args 255 to flush
; 1 << 26 + ;We support FS_File 9
; 1 << 25 + ;We support FS_Func 20
; 0 << 24 + ;Currently reserved.
; 0 << 23 + ;we don't support ImageFS extension
; 0 << 22 + ;Do pass & and % in path
; 1 << 21 + ;Need not store dira
; 1 << 20 + ;Use Open/Get/Close in pref to File 255
; 1 << 19 + ;Use Open/Get/Close in pref to File 0
; 1 << 18 + ;Use FS_entry 9 instead of FS_Entry File
; 0 << 17 + ;Extra info word not present
; 0 << 16 + ;FS writable
; &0 << 8 + ;No defititnve limit to open files.
; 1 << 31+\
socket_info_word EQU 1 << 31+\
1 << 30+\
0 << 29+\
1 << 28+\
0 << 27+\
1 << 26+\
1 << 25+\
0 << 24+\
0 << 23+\
0 << 22+\
&F << 18+\
0 << 17+\
0 << 16+\
0 << 8+\
&00FF ;SocketFS Number
socket_FSinfo
DCD socket_fsname - SocketFSMod_BaseAddr
DCD startup_msg - SocketFSMod_BaseAddr
DCD socket_open - SocketFSMod_BaseAddr
DCD socket_read - SocketFSMod_BaseAddr
DCD socket_write - SocketFSMod_BaseAddr
DCD socket_args - SocketFSMod_BaseAddr
DCD socket_close - SocketFSMod_BaseAddr
DCD socket_file - SocketFSMod_BaseAddr
DCD socket_info_word
DCD socket_Func - SocketFSMod_BaseAddr
DCD socket_GBPB - SocketFSMod_BaseAddr
DCD 0
socket_fsname
DCB "SocketFS",0
ALIGN
startup_msg
DCB "Internet Filesystem",0
ALIGN
socket_open
STMFD R13!,{R14}
DBF "File open entry called\n"
MOVS R0,R6 ;Copy special field over
DBF " - spcf = %0s\n" , NE
DBF " - no special field\n", EQ
DBF " - fname -= %1s\n" ;reason code...
LDR R12,[R12,#4] ;Get stubs ws.
BL socket_clibstackmunge ;Set stack up for Clib.
BL makeSocket ;Call C filename processor
;This give socket in R0
BL socket_clibstackunmunge
; or -1 if no socket opened
ADD R1,R0,#1 ;Make my handle the socket number +1
; conveiently 0 now indicates file not found
MOV R2,#0 ;Unbuffered...(actually internet mod
;will buffer).
MOV R3,#0 ;File extent not used...
MOV R4,#0 ;No buffer space allocated..
MOV R0,#&D8000000 ;File Info word
;File set as readablr,writeable,Stream device and interactive
LDMFD R13!,{PC}^ ;Finish...
socket_read
STMFD R13!,{R14}
DBF "File read entry called for socket %1w\n"
SUB R0,R1,#1 ;Put socket number in R0.
SUB R13,R13,#4 ;resevre 1w ws on stack.
MOV R1,R13 ;Put buffer in R1..
MOV R2,#1 ;Put buff size in R2
;Ignore file offset as we have streams...
SWI XSocket_Read ;Call Internet module..
LDRVC R0,[R13] ;If no error get byte from buff
ADD R13,R13,#4 ;Release ws.
LDMVCFD R13!,{PC}^
LDR R1,[R0] ;Get Errno
DBF "Socket Err %1w\n"
CMP R1,#EWOULDBLOCK ;Is Rx/Tx limits.
LDMEQFD R13!,{R14} ;Get lr early so we can set flags
MOV R0,#0 ;Retrun 0 char - t
ORREQ PC,R14,#C_Bit
;Now we have to work out what to do in the case of other errs!.
LDMFD R13!,{R14} ;Return with V set!., m
ORR PC,R14,#V_Bit ;Set V flag
socket_write
STMFD R13!,{R1-R2,R14}
DBF "File write entry called\n - R0 %0b\n - R1 %1w\n"
SUB R13,R13,#4 ;Resevre 1 w one stack.
STR R0,[R13] ;Store byte to send
SUB R0,R1,#1 ;Put socket number in R0.
MOV R1,R13 ;Put buffer in R1..
MOV R2,#1 ;Put buff size in R2
SWI XSocket_Write ;Call Internet module..
ADD R13,R13,#4 ;Release stack ws.
LDMFD R13!,{R1-R2,PC}
socket_close STMFD R13!,{R14}
DBF "File close entry called\n"
SUB R0,R1,#1 ;Put Socket in R0
;Ignore other stuff as meaningless.
SWI XSocket_Close ;Call internet module
LDMFD R13!,{PC}
socket_GBPB ;Optimized multibyte get and put routines.....
;In fact in our case almost simpler than the single byte
;ones
STMFD R13!,{R0-R4,R14}
DBF "File gpbp entry called op no - %0w\n"
CMP R0,#3 ;Check reason code...
BGE socket_multiget ;Do get mutliple..
;put multiple . move regs to place for socket call
SUB R0,R1,#1
MOV R1,R2
MOV R2,R3
SWI XSocket_Write
BVS socket_gbpb_handError
MOV R5,R0
LDMFD R13!,{R0-R4,R14}
ADD R2,R2,R5 ;Compute new buff ptr
SUB R3,R3,R5 ;Compute new buff free size
ADD R4,R4,R5 ;Compute new file pointer!
MOVS PC,R14 ;Return to caller
socket_multiget
;get multiple . move regs to place for socket call
SUB R0,R1,#1
MOV R1,R2
MOV R2,R3
SWI XSocket_Read
BVS socket_gbpb_handError
MOV R5,R0
LDMFD R13!,{R0-R4,R14}
ADD R2,R2,R5 ;Compute new buff ptr
SUB R3,R3,R5 ;Compute new buff free size
ADD R4,R4,R5 ;Compute new file pointer!
MOVS PC,R14 ;Return to caller
socket_gbpb_handError
LDR R1,[R0] ;Get Errno
CMP R1,#EWOULDBLOCK ;Is Rx/Tx limits.
LDMEQFD R13!,{R0-R4,PC}^ ;Return doing nothing
;Fileswitch will work out what to tell client!
;Now we have to work out what to do in the case of other errs!.
MOV R5,R0 ;Save errrblk ptr..
LDMFD R13!,{R0-R4,R14} ;get orignal regs..
MOV R0,R5 ;restore errblk ptr
ORRS PC,R14,#V_Bit ;return with V set.
socket_args ;Handle wodges of OS_Args codes here!
STMFD R13!,{R0-R4,R14} ;Store Registers!
DBF "FS_Entry Args %0w called\n"
CMP R0,#10
ADDLE PC,PC,R0,LSL #2 ;Use old fashionned
;Swi dispatch trick
B socket_unknownCall
B socket_returnZero
LDMFD R13!,{r0-R4,PC} ;Ignore ARgs 1
B socket_returnZero
LDMFD R13!,{R0-R4,PC} ;Ignore Args 3
B socket_allocedsize
B socket_EOFcheck ;Is TCP connection open?
B socket_Flush ;Not called but triv to code!
B socket_Extent
LDMFD R13!,{R0-R4,PC} ;Not suported .. unbuffered
B socket_returnZeros
LDMFD R13!,{R0-R4,PC} ;If you've implemented an imagefs over socketfs I'd be shocked!
socket_allocedsize
LDMFD R13!,{R0-R4,R14}
MOV R2,#1
MOV PC,R14
socket_Extent
LDMFD R13!,{R0-R4,R14}
;What do we need to tell Fileswitch
MOV R2,#1
MOV PC,R14
socket_returnZero
LDMFD R13!,{R0-R4,R14}
MOV R2,#0 ;Return R2=0
MOV Pc,R14
socket_returnZeros
LDMFD R13!,{R0-R4,R14}
MOV R2,#0 ;Return R2-R3=0.
MOV R3,R2
MOV Pc,R14
socket_Flush
LDMFD R13!,{R0-R4,R14}
STMFD R13!,{R1-R4,R14}
SUB R0,R1,#1 ;Get File handle
ADD R1,R12,#tempbyte
MOV R2,#0 ;Send 0 octets
SWI XSocket_Send
LDMFD R13!,{R1-R4,PC}
socket_EOFcheck
LDMFD R13!,{R0-R4,R14}
STMFD R13!,{R14}
SUB R0,R1,#1 ;Get socket handle
ADD R1,R12,#tempbyte
MOV R2,#1 ;Get a byte
MOV R3,#(MSG_PEEK + MSG_DONTWAIT) ;but don't remove it from the queue
SWI XSocket_Recv
LDRVS R1,[R0] ;If err get ErrNo
MOVS R0,R0 ;IF read()==0
CMPNE R1,#ECONNRESET ; || ==ECONNRESET
MOV R2,#0 ; then R2=0
SUBEQ R2,R2,#1 ; else R2=-1
LDMFD R13!,{PC}^ ;return!
socket_unknownCall
ADR R0,socket_unknownCallMsg
ORRS PC,PC,#V_Bit
LDMFD R13,{R0-R4,PC}
socket_unknownCallMsg
DCD &0001FFEE
DCB "Socketfs doesn't support this call",13
ALIGN
socket_Func
STMFD R13!,{R0-R4,R14} ;Store Registers!
DBF "FS_Entry Func %0w called\n"
CMP R0,#34
ADDLE PC,PC,R0,LSL #2 ;Use old fashionned
;Swi dispatch trick
B socket_unknownCall
B socket_DoNothing ;FsEntry_Func 0
B socket_DoNothing ;FsEntry_Func 1
B socket_DoNothing ;FsEntry_Func 2
B socket_DoNothing ;FsEntry_Func 3
B socket_DoNothing ;FsEntry_Func 4
B socket_DoNothing ;FsEntry_Func 5
B socket_DoNothing ;FsEntry_Func 6
B socket_DoNothing ;FsEntry_Func 7
B socket_rename ;FsEntry_Func 8
B socket_DoNothing ;FsEntry_Func 9
B socket_DoNothing ;FsEntry_Func 10
B socket_readBoot ;FsEntry_Func 11
B socket_readDirName ;FsEntry_Func 12
B socket_readDirName ;FsEntry_Func 13
B socket_readDir ;FsEntry_Func 14
B socket_readDir ;FsEntry_Func 15
B socket_DoNothing ;FsEntry_Func 16
B socket_annouce ;FsEntry_Func 17
B socket_DoNothing ;FsEntry_Func 18
B socket_readDir ;FsEntry_Func 19
B socket_DoNothing ;FsEntry_Func 20
B socket_DoNothing ;FsEntry_Func 21
B socket_DoNothing ;FsEntry_Func 22
B socket_DoNothing ;FsEntry_Func 23
B socket_DoNothing ;FsEntry_Func 24
B socket_readDefects ;FsEntry_Func 25
B socket_DoNothing ;FsEntry_Func 26
B socket_readBoot ;FsEntry_Func 27
B socket_DoNothing ;FsEntry_Func 28
B socket_DoNothing ;FsEntry_Func 29
B socket_readFree ;FsEntry_Func 30
B socket_DoNothing ;FsEntry_Func 31
B socket_DoNothing ;FsEntry_Func 32
B socket_readUsage ;FsEntry_Func 33
B socket_DoNothing ;FsEntry_Func 34
;Some of the calls that seem to come here should never be called anyway.
;(at least assuming the PRMs are correct!)
socket_DoNothing
LDMFD R13!,{R0-R4,PC}^ ;Return to fileswitch.
socket_rename
;Can't Rename sockets so return with error
LDMFD R13!,{R0-R4,R14} ;Tidy stack
MOV R0,#1 ;mark rename failed.
MOVS pc,r14 ;return
socket_DiscBoot
;Here we use the 'C' libs memcpy to move our data to Fileswicth
;It's overkill for 5 bytes but there an outside chance it
;will validate the address for us.
MOV R1,R2
ADR R0,socket_DiscMsg
MOV R2,#socket_DiscMsg - socket_DiscMsgEnd
BL memcpy
LDMFD R13!,{R0-R4,PC}
socket_DiscMsg
DCB 3,"tcp",0
socket_DiscMsgEnd
ALIGN
socket_readDirName
;Will need to implement to support RO2
B socket_DoNothing
socket_readDir
;We essentially show an emtpy directry with
;these calls so they can all share a routine.
LDMFD R13!,{R0-R4,R14} ;Tidy stack,
MOV R3,#0 ;No records read
STR R3,[R2] ;Use 0 to terminate buffer
MVN R4,#0 ;End of directory
MOVS Pc,R14 ;Return
socket_annouce
SWI XOS_WriteS
DCB "Erk! SocketFS",13,0 ;if socketfs is default at
ALIGN ;boot then you're being clever
;or have just hung!
LDMFD R13!,{R0-R4,PC}
socket_readDefects
;OK so the internet has them, but not quite in the way
;fileswtich means. So we return an empty defect list.
MOV R0,#&20000000 ;Load the list terminator
STR R0,[R2] ;Terminate the list's first word
LDMFD R13!,{R0-R4,PC}^ ;Preserve regs and return.
socket_readBoot
LDMFD R13!,{R0-R4,R14} ;Tidy stack
MOV R2,#0 ;Boot opt=0
MOVS pc,R14 ;Return.
socket_readFree
LDMFD R13!,{R0-R4,R14} ;Tidy stack
MOV R0,#0 ;0 free space
MOV R1,#0 ;0 cont. free space
MOV R2,#0 ;0 disc size
MOVS pc,R14 ;Return.
socket_readUsage
LDMFD R13!,{R0-R4,R14} ;Tidy stack
MOV R2,#2 ;Streams have unique address space
MOVS pc,R14 ;Return.
socket_file DBF "FS_Entry File %0w called\n"
TEQ r0, #255
MOVEQ r0, #10
CMP r0, #(socket_FileTabEnd - socket_FileTab) / 4
ADDLE pc, pc, r0, LSL #2
BICS pc, lr, #V_Bit
socket_FileTab B socket_Save ; Save file
BICS pc, lr, #V_Bit ; Write catalogue info
BICS pc, lr, #V_Bit ; Write load address
BICS pc, lr, #V_Bit ; Write execution address
BICS pc, lr, #V_Bit ; Write attributes
B socket_readCat ; Read catalogue info
BICS pc, lr, #V_Bit ; Delete object
BICS pc, lr, #V_Bit ; Create file
BICS pc, lr, #V_Bit ; Create directory
BICS pc, lr, #V_Bit ; Read catalogue info
BICS pc, lr, #V_Bit ; Load file
socket_FileTabEnd
socket_Save STMFD R13!, {R0-R1, R4, R14}
BL socket_open
BEQ socket_saveErr
MOV R6,R5
MOV R1,R0
MOV R0,#1
MOV R2,R4
SUB R3,R5,R4
socket_saveloop
BGE socket_saveend
BL socket_GBPB
BVS socket_saveErr
MOVS R3,R3
BEQ socket_saveloop
socket_saveend MOV R0, R1
B socket_close
socket_saveErr
LDMFD sp!, {R0-R1, r4, R14}
ADR R0, socket_saveErrMsg
ORRS pc, lr, #V_Bit
socket_saveErrMsg
DCD &1006702
DCB "An error ocurring while saving",13,0
ALIGN
socket_readCat ;Currently we don't check wether this is a fully specified address
;with sockets in use (eg. an open file - tcp/udp connection)
MOV R0,#0 ;File not Found
BICS R15,R14,#V_Bit ;Return no err.
socket_clibstackmunge
MOV R10,R13,LSR #20 ;Which MB boundary is the stack on...
MOV R10,R10,LSL #20 ;point R10 directly at booundary...
LDMIA R10,{R4,R5} ;Get relocation for other C SVC modules....
STMFD R13!,{R4,R5} ;save old reloc modifiers over fn call
DBF "Stubs stores relocs @ &%cw\n"
LDMIB R12, {R4, R5} ;new relocation modifiers
DBF "C lib reloc directives are &%4w,&%5w\n"
STMIA R10, {R4, R5} ;set by module init
MOV fp, #0 ;halt C backtrace here!
DCD |_Lib$Reloc$Off$DP| + &E28AA000 ; This is equivalent of 'ADD r10, r10, #0' + |_Lib$Reloc$Off$DP|
MOVS Pc,R14
socket_clibstackunmunge
MOV R10,R13,LSR #20 ;Which MB boundary is the stack on...
MOV R10,R10,LSL #20 ;point R10 directly at booundary...
LDMIA R10,{R4,R5} ;Check so we can match later!
DBF "C lib reloc directives are &%4w,&%5w\n"
LDMFD R13!,{R4,R5} ;Get relocation for other C SVC modules....
STMIA R10,{R4,R5} ;put it back where it came from!
MOVS Pc,R14
END