10 REM > NetFSUtl/s 0.10
   20 REM 01-May-1999 v0.10 JGH: Initial version
   30 REM
   40 REM Veneer for network commands adjusting for FileSwitch oddities.
   50 REM On RISC OS 3+, FileSwitch preprocess many filing system commands.
   60 REM This can result in some oddities when using a file server. When
   70 REM the object is on NetFS:
   80 REM  '*Free'   is translated to '*/Free'
   90 REM  '*Ex'     is translated to '*/Ex'
  100 REM  '*Rename' is translated to FSOp_Cmd 'Rename'
  110 :
  120 REM This results in:
  130 REM * The file server's *FREE command being used instead of NetFS's.
  140 REM * The file server's *EX command being used instead of NetFS's. This
  150 REM   is particularly useful on SJ servers where account and datestamp
  160 REM   information is listed.
  170 REM * RENAME is passed directly to the server. Quite often, a desktop
  180 REM   move results in a copy-and-delete instead of a rename. This
  190 REM   results in the file's low-level date-stamp being lost. NetFSUtils
  200 REM   ensures a move is always done as a RENAME it it is on the same
  210 REM   disk.
  220 :
  230 :
  240 ver$="0.10"
  250 date$="01 May 1999"
  260 ON ERROR REPORT:PRINT ERL:END
  270 :
  280 DIM mcode% &8000, L% -1
  290 sp=13:link=14:pc=15
  300 FOR opt%=0 TO 1
  310   P%=0:O%=mcode%
  320   [OPT opt%*3+4
  330   EQUD 0:\ Start
  340   EQUD Initialise
  350   EQUD Finalise
  360   EQUD 0:\ Service
  370   EQUD TitleStr
  380   EQUD HelpStr
  390   EQUD CommandTable
  400   EQUD 0:\ SWI chunk number
  410   EQUD 0:\ SWI chunk handler
  420   EQUD 0:\ SWI decoding table
  430   EQUD 0:\ SWI decoding code
  440   :
  450   .TitleStr
  460   EQUS "NetFSUtils":EQUB 0
  470   ALIGN
  480   .HelpStr
  490   EQUS "NetFSUtils"+CHR$9+ver$+" ("+date$+") "+CHR$169+" J.G.Harston":EQUB 0
  500   ALIGN
  510   :
  520   .CommandTable
  530   EQUS "NetFree"   :EQUB 0:ALIGN:EQUD NetFree
  540   EQUD &00010000   :EQUD NetFree_Syntax:EQUD NetFree_Help
  550   EQUS "NetFSUtils":EQUB 0:ALIGN:EQUD 0
  560   EQUD &00000000   :EQUD 0:EQUD NetFSUtils_Help
  570   EQUB 0:ALIGN
  580   :
  590   .NetFree_Help
  600   EQUS "*NetFree translates the *Free command to */Free on NetFS.":EQUB 13
  610   .NetFree_Syntax
  620   EQUS "Syntax: NetFree [<disk spec>]":EQUB 13
  630   EQUB 0
  640   .NetFSUtils_Help
  650   EQUS "NetFSUtils translates *Free, *Ex and *Rename on NetFS.":EQUB 13
  660   EQUB 0
  670   ALIGN
  680   :
  690   :
  700   .Initialise
  710   stmfd (sp)!,{link}
  720   mov   r0,#6
  730   mov   r3,#128
  740   swi   "OS_Module"   ; Claim 128 bytes of workspace
  750   str   r2,[r12]      ; Save pointer to workspace
  760   :
  770   mov   r0,#15        ; FSControlVec
  780   adr   r1,SJFSControl
  790   ldr   r2,[r12]
  800   swi   "OS_Claim"    ; Hook into OS_FSControl
  810   :
  820   adr   r0,SetAlias
  830   swi   "XOS_CLI"     ; Claim '*FREE' command
  840   mov   r0,#0
  850   cmp   r0,r0         ; Clear flags, etc
  860   ldmfd (sp)!,{pc}
  870   :
  880   :
  890   .Finalise
  900   stmfd (sp)!,{link}
  910   adr   r0,UnSetAlias
  920   swi   "XOS_CLI"     ; Release '*FREE' command
  930   :
  940   mov   r0,#15        ; FSControlVec
  950   adr   r1,SJFSControl
  960   ldr   r2,[r12]
  970   swi   "OS_Release"  ; Release OS_FSControl
  980   :
  990   ldr   r2,[r12]      ; Get pointer to workspace
 1000   cmp   r2,#0
 1010   movne r0,#7
 1020   swine "OS_Module"   ; Release it if it exists
 1030   mov   r0,#0
 1040   str   r0,[r12]      ; Clear pointer
 1050   cmp   r0,r0         ; Clear flags, etc
 1060   ldmfd (sp)!,{pc}
 1070   .SetAlias
 1080   EQUS  "Set Alias$Free NetFree %*0":EQUB 13
 1090   .UnSetAlias
 1100   EQUS "UnSet Alias$Free":EQUB 13
 1110   ALIGN
 1120   :
 1130   :
 1140   .NetFree              ; *NetFree [<disk spec>]
 1150   stmfd (sp)!,{r0,link} ; r0=>parameters
 1160   bl    CheckNetFS      ; If current FS NetFS?
 1170   bne   NotNetFree
 1180   adr   r0,RunFree      ; If NetFS, point to '/%.Free'
 1190   swi   "OS_CLI"        ; Issue replacement command
 1200   ldmfd (sp)!,{r0,pc}
 1210   :
 1220   .NotNetFree
 1230   ldmfd (sp)!,{r1}      ; Get r1=>parameters back
 1240   ldr   r12,[r12]       ; Get workspace pointer
 1250   adr   r0,ROMFree      ; Point to '%Free '
 1260   bl    CommandReplace  ; Build replacement command
 1270   swi   "OS_CLI"        ; Issue replacement command
 1280   ldmfd (sp)!,{pc}
 1290   .RunFree
 1300   EQUS  "/%.Free":EQUB 13
 1310   .ROMFree
 1320   EQUS "%Free "
 1330   ALIGN
 1340   :
 1350   :
 1360   .SJFSControl
 1370   cmp   r0,#6
 1380   beq   SJEx
 1390   cmp   r0,#25
 1400   beq   SJRename
 1410   movs  pc,link         ; Pass on
 1420   :
 1430   :
 1440   .SJEx
 1450   stmfd   (sp)!,{r0-r4,link} ; r1=>parameters
 1460   bl      CheckNetPath
 1470   ldmnefd (sp)!,{r0-r4,link} ; Restore if not NetFS
 1480   movnes  pc,link            ; Pass on if not NetFS
 1490   adr     r0,NetEX           ; R0=>'/EX '
 1500   bl      CommandReplace     ; Create replacement command
 1510   swi     "OS_CLI"           ; Issue replacement command
 1520   ldmfd   (sp)!,{r0-r4,link} ; Restore
 1530   ldmfd   (sp)!,{pc}         ; Claim
 1540   .NetEX
 1550   EQUS    "net:/EX "
 1560   ALIGN
 1570   :
 1580   :
 1590   .SJRename
 1600   stmfd   (sp)!,{r0-r9,link} ; r1=>oldname, r2=newname
 1610   mov     r0,#3              ; File being modified
 1620   mov     r6,#7              ; No special field, r1=>oldname
 1630   mov     r7,#0              ; No special field, r2=>newname
 1640   ldr     r8,NetFSWord       ; Filing system information word
 1650   mov     r9,#520            ; Rename
 1660   swi     "OS_UpCall"        ; Warn Filer about rename operation
 1670   :
 1680   mov     r5,r2              ; r5=>oldname
 1690   bl      CheckNetPath
 1700   ldmnefd (sp)!,{r0-r9,link} ; Not NET, restore
 1710   movnes  pc,link            ; Not NET, pass on
 1720   mov     r4,r1              ; r4=>oldname
 1730   mov     r1,r5
 1740   bl      CheckNetPath
 1750   ldmnefd (sp)!,{r0-r9,link} ; Not NET, restore
 1760   movnes  pc,link            ; Not NET, pass on
 1770   mov     r5,r1              ; r5=>newname, r4=>oldname
 1780   :
 1790   adr     r0,NetRename       ; r0=>'RENAME '
 1800   mov     r1,r4              ; r1=>oldname
 1810   bl      CommandReplace     ; Create start of replacement command
 1820   mov     r4,#ASC" "
 1830   strb    r4,[r2,#-1]        ; Replace <cr> with <spc>
 1840   mov     r1,r5              ; r1=>newname
 1850   bl      CommandLp2         ; Add to command
 1860   :
 1870   mov     r1,r0              ; r1=>command in workspace
 1880   mov     r0,#0              ; r0=NetOp_Cmd
 1890   eor     r2,r3,#127         ; r2=length of command string
 1900   mov     r3,#&80            ; r3=128 bytes max buffer length
 1910   swi     "XNetFS_DoFSOp"    ; Send command to file server
 1920   bvs     NetError
 1930   cmp     r0,#0
 1940   ldmeqfd (sp)!,{r0-r9,link} ; Restore registers
 1950   ldmeqfd (sp)!,{pc}         ; Ok, return
 1960   adr     r0,errUnknown      ; Error with unexpected result
 1970   .NetError
 1980   mov     r1,r12             ; Point to workspace
 1990   ldr     r2,[r0],#4         ; Get error number
 2000   str     r2,[r1],#4         ; Store it
 2010   .NetErrorLp
 2020   ldrb    r2,[r0],#1         ; Copy error string
 2030   strb    r2,[r1],#1
 2040   cmp     r2,#0
 2050   bne     NetErrorLp
 2060   ldmfd   (sp)!,{r0-r9,link} ; Restore registers
 2070   mov     r0,r12             ; r0=>error in workspace
 2080   swi     "XOS_GenerateError"
 2090   ldmfd   (sp)!,{pc}         ; Return error
 2100   .NetFSWord
 2110   EQUD    &86C60505
 2120   .NetRename
 2130   EQUS "RENAME "
 2140   ALIGN
 2150   .errUnknown
 2160   EQUD 254:EQUS "Unexpected FSOp result":EQUB 0
 2170   ALIGN
 2180   :
 2190   :
 2200   ; On entry, R1=>pathname
 2210   ; On exit,  R1=>pathname, net prefix skipped
 2220   ;           R0,R2 corrupted
 2230   ;           EQ=NetFS, NE=not NetFS
 2240   ;
 2250   .CheckNetPath
 2260   stmfd (sp)!,{r1,link}
 2270   mov   r0,#13
 2280   mov   r2,#0
 2290   swi   "XOS_FSControl" ; Check for fs prefix
 2300   ; bad prefix - VS
 2310   ; no prefix  - 13,r1,0
 2320   ; unknown    - 13,r1,0
 2330   ; net prefix - 13,5,non-zero
 2340   movvs   r2,#0         ; Flawed prefix, force to unknown
 2350   cmp     r2,#0
 2360   beq     CheckNetFS1   ; No prefix, check current FS
 2370   cmp     r1,#5
 2380   ldmfd   (sp)!,{r1}    ; Get r1=>parameters back
 2390   ldmnefd (sp)!,{pc}    ; NE=not NET filing system
 2400   .CheckNetPrefix
 2410   ldrb    r0,[r1],#1    ; Step past prefix
 2420   cmp     r0,#ASC":"
 2430   bne     CheckNetPrefix
 2440   ldmfd   (sp)!,{pc}    ; EQ=NET filing system
 2450   :
 2460   .CheckNetFS
 2470   stmfd (sp)!,{r1,link}
 2480   .CheckNetFS1
 2490   mov   r0,#0
 2500   mov   r1,#0
 2510   swi   "OS_Args"       ; Find current filing system
 2520   .CheckNetFS2
 2530   cmp   r0,#5
 2540   ldmfd (sp)!,{r1,pc}   ; EQ=NET filing system
 2550   :
 2560   :
 2570   ; On entry, R0=>replacement command
 2580   ;           R1=>command line
 2590   ; On exit,  R0=>newly built command
 2600   ;           R1=>after <cr> in source command
 2610   ;           R2=>after <cr> in dest command
 2620   ;           R3=remaining buffer size
 2630   ;           R4=<cr>
 2640   ;
 2650   .CommandReplace
 2660   mov   r2,r12       ; R2=>workspace
 2670   mov   r3,#127      ; Buffer size-1
 2680   .CommandLp1
 2690   ldrb  r4,[r0],#1   ; Copy replacement command
 2700   strb  r4,[r2],#1
 2710   sub   r3,r3,#1     ; Decrement count
 2720   cmp   r4,#ASC" "
 2730   bne   CommandLp1   ; Loop until space
 2740   .CommandLp2
 2750   ldrb  r4,[r1],#1   ; Copy command line
 2760   strb  r4,[r2],#1
 2770   subs  r3,r3,#1     ; Decrement count
 2780   beq   CommandEnd
 2790   cmp   r4,#ASC"!"
 2800   bcs   CommandLp2   ; Loop until space or control code
 2810   .CommandEnd
 2820   mov   r4,#13
 2830   strb  r4,[r2,#-1]  ; Ensure <cr> terminator
 2840   mov   r0,r12       ; R0=>command in workspace
 2850   mov   pc,link
 2860   :
 2870 ]NEXT
 2880 OSCLI"SAVE NetFSUtils "+STR$~mcode%+" "+STR$~O%
 2890 *SetType NetFSUtils Module
 2900 *Stamp NetFSUtils