mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-12-21 23:29:16 +00:00
05d82736bc
Add check for buffer overflow when globbing, expanding variables, or inserting aliases (PR#110). Increase buffer size from 1024 to 4096. Increase buffer for reading commands from 256 to 1024 bytes in order to match the maximum length used when reading.
914 lines
13 KiB
NASM
914 lines
13 KiB
NASM
**************************************************************************
|
|
*
|
|
* The GNO Shell Project
|
|
*
|
|
* Developed by:
|
|
* Jawaid Bazyar
|
|
* Tim Meekins
|
|
*
|
|
* $Id: alias.asm,v 1.9 1999/02/08 17:26:49 tribby Exp $
|
|
*
|
|
**************************************************************************
|
|
*
|
|
* ALIAS.ASM
|
|
* By Tim Meekins
|
|
* Modified by Dave Tribby for GNO 2.0.6
|
|
*
|
|
* Note: text set up for tabs at col 16, 22, 41, 49, 57, 65
|
|
* | | | | | |
|
|
* ^ ^ ^ ^ ^ ^
|
|
**************************************************************************
|
|
*
|
|
* Interfaces defined in this file:
|
|
*
|
|
* alias subroutine (4:argv,2:argc)
|
|
* Returns with status=0 in Accumulator
|
|
*
|
|
* unalias subroutine (4:argv,2:argc)
|
|
* return 2:status
|
|
*
|
|
* initalias jsr/rts with no parameters
|
|
*
|
|
* expandalias subroutine (4:cmd)
|
|
* return 4:buf
|
|
*
|
|
* addalias subroutine (4:aliasname,4:aliasval)
|
|
* return
|
|
*
|
|
* removealias subroutine (4:aliasname)
|
|
* return
|
|
*
|
|
* findalias subroutine (4:aliasname),space
|
|
* return 4:value
|
|
*
|
|
* startalias jsl/rtl with no parameters
|
|
*
|
|
* nextalias subroutine (4:p)
|
|
* return 2:hashvalz
|
|
*
|
|
*
|
|
**************************************************************************
|
|
|
|
mcopy /obj/gno/bin/gsh/alias.mac
|
|
|
|
dummyalias start ; ends up in root
|
|
end
|
|
|
|
setcom 60
|
|
|
|
VTABSIZE gequ 17
|
|
|
|
**************************************************************************
|
|
*
|
|
* ALIAS: builtin command
|
|
* syntax: alias [name [def]]
|
|
*
|
|
* set aliases
|
|
*
|
|
**************************************************************************
|
|
|
|
alias START
|
|
|
|
using AliasData
|
|
|
|
arg equ 1
|
|
space equ arg+4
|
|
argc equ space+3
|
|
argv equ argc+2
|
|
end equ argv+4
|
|
|
|
; subroutine (4:argv,2:argc),space
|
|
|
|
tsc
|
|
sec
|
|
sbc #space-1
|
|
tcs
|
|
phd
|
|
tcd
|
|
|
|
lock AliasMutex
|
|
lda argc How many arguments were provided?
|
|
dec a
|
|
beq showall None -- show all alias names.
|
|
dec a
|
|
beq showone One -- show a single name.
|
|
jmp setalias More -- set an alias.
|
|
|
|
;
|
|
; Show all aliases
|
|
;
|
|
showall jsl startalias
|
|
showloop jsl nextalias
|
|
sta arg
|
|
stx arg+2
|
|
ora arg+2
|
|
beq noshow
|
|
ldy #6
|
|
lda [arg],y
|
|
tax
|
|
ldy #4
|
|
lda [arg],y
|
|
jsr puts
|
|
lda #':'
|
|
jsr putchar
|
|
lda #' '
|
|
jsr putchar
|
|
ldy #10
|
|
lda [arg],y
|
|
tax
|
|
ldy #8
|
|
lda [arg],y
|
|
jsr puts
|
|
jsr newline
|
|
bra showloop
|
|
|
|
noshow jmp exit
|
|
|
|
;
|
|
; Show a single alias
|
|
;
|
|
showone ldy #4+2
|
|
lda [argv],y
|
|
tax
|
|
pha ;for findalias
|
|
ldy #4
|
|
lda [argv],y
|
|
pha
|
|
jsr puts Print name.
|
|
lda #':' Print ": ".
|
|
jsr putchar
|
|
lda #' '
|
|
jsr putchar
|
|
jsl findalias
|
|
sta arg
|
|
stx arg+2
|
|
ora arg+2
|
|
beq notthere
|
|
lda arg
|
|
jsr puts Print alias value.
|
|
jsr newline Print newline.
|
|
jmp exit All done.
|
|
|
|
notthere ldx #^noalias Print message:
|
|
lda #noalias 'Alias not defined'
|
|
jsr puts
|
|
jmp exit
|
|
|
|
;
|
|
; Set an alias name
|
|
;
|
|
setalias ldy #4+2 ;put alias name on stack
|
|
lda [argv],y
|
|
pha
|
|
ldy #4
|
|
lda [argv],y
|
|
pha
|
|
|
|
ph4 #2
|
|
~NEW
|
|
sta arg
|
|
stx arg+2
|
|
lda #0
|
|
sta [arg]
|
|
|
|
add2 argv,#8,argv
|
|
|
|
dec2 argc
|
|
|
|
buildalias lda argc
|
|
beq setit
|
|
|
|
pei (arg+2)
|
|
pei (arg)
|
|
pei (arg+2)
|
|
pei (arg)
|
|
ldy #2
|
|
lda [argv],y
|
|
pha
|
|
lda [argv]
|
|
pha
|
|
jsr catcstr
|
|
stx arg+2
|
|
sta arg
|
|
jsl nullfree
|
|
|
|
pei (arg+2)
|
|
pei (arg)
|
|
pei (arg+2)
|
|
pei (arg)
|
|
ph4 #spacestr
|
|
jsr catcstr
|
|
stx arg+2
|
|
sta arg
|
|
jsl nullfree
|
|
|
|
dec argc
|
|
add2 argv,#4,argv
|
|
bra buildalias
|
|
|
|
setit pei (arg+2)
|
|
pei (arg)
|
|
jsl addalias
|
|
pei (arg+2)
|
|
pei (arg)
|
|
jsl nullfree
|
|
|
|
exit unlock AliasMutex
|
|
lda space
|
|
sta end-3
|
|
lda space+1
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-4
|
|
tcs
|
|
|
|
lda #0 Return status always 0.
|
|
|
|
rtl
|
|
|
|
noalias dc c'Alias not defined',h'0d00'
|
|
spacestr dc c' ',h'00'
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* UNALIAS: builtin command
|
|
* syntax: unalias [var ...]
|
|
*
|
|
* removes each alias listed
|
|
*
|
|
**************************************************************************
|
|
|
|
unalias START
|
|
|
|
using AliasData
|
|
|
|
status equ 0
|
|
space equ status+2
|
|
|
|
subroutine (4:argv,2:argc),space
|
|
|
|
lock AliasMutex
|
|
|
|
stz status
|
|
|
|
lda argc
|
|
dec a
|
|
bne loop
|
|
|
|
ldx #^Usage
|
|
lda #USage
|
|
jsr errputs
|
|
inc status Return status = 1.
|
|
bra done
|
|
|
|
loop add2 argv,#4,argv
|
|
dec argc
|
|
beq done
|
|
|
|
ldy #2
|
|
lda [argv],y
|
|
pha
|
|
lda [argv]
|
|
pha
|
|
jsl removealias
|
|
|
|
bra loop
|
|
|
|
done unlock AliasMutex
|
|
return 2:status
|
|
|
|
Usage dc c'Usage: unalias name ...',h'0d00'
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Init alias table
|
|
;
|
|
;=========================================================================
|
|
|
|
initalias START
|
|
|
|
using AliasData
|
|
|
|
; Set all entries in AliasTable to 0
|
|
|
|
lda #0
|
|
ldy #VTABSIZE
|
|
tax
|
|
yahaha sta AliasTable,x
|
|
inx2
|
|
sta AliasTable,x
|
|
inx2
|
|
dey
|
|
bne yahaha
|
|
|
|
rts
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Expand alias
|
|
;
|
|
;=========================================================================
|
|
|
|
expandalias START
|
|
|
|
outbuf equ 0
|
|
sub equ outbuf+4
|
|
word equ sub+4
|
|
buf equ word+4
|
|
bufend equ buf+4
|
|
inquote equ bufend+2
|
|
bsflag equ inquote+2
|
|
space equ bsflag+2
|
|
|
|
subroutine (4:cmd),space
|
|
|
|
ph4 maxline_size Allocate result buffer.
|
|
~NEW
|
|
stx buf+2
|
|
sta buf
|
|
stx outbuf+2 Initialize "next
|
|
sta outbuf output char" pointer.
|
|
clc Calculate end of buffer-1;
|
|
adc maxline_size note: it's allocated to be in one
|
|
dec a bank, so only need low-order word.
|
|
sta bufend
|
|
|
|
jsl allocmaxline Allocate buffer for word that
|
|
stx word+2 might be an alias.
|
|
sta word
|
|
|
|
lda #0
|
|
sta [buf] In case we're called with empty string.
|
|
sta [word]
|
|
;
|
|
; Eat leading space and tabs (just in case expanding a variable added them!)
|
|
;
|
|
bra eatleader
|
|
bump_cmd inc cmd
|
|
eatleader lda [cmd]
|
|
and #$FF
|
|
jeq stringend
|
|
cmp #' '
|
|
beq bump_cmd
|
|
cmp #9
|
|
beq bump_cmd
|
|
;
|
|
; Parse the leading word
|
|
;
|
|
short a
|
|
ldy #0
|
|
bra makeword1 First time, already checked 0, ' ', 9
|
|
makeword lda [cmd],y
|
|
if2 @a,eq,#0,gotword
|
|
if2 @a,eq,#' ',gotword
|
|
if2 @a,eq,#9,gotword
|
|
makeword1 if2 @a,eq,#';',gotword
|
|
if2 @a,eq,#'&',gotword
|
|
if2 @a,eq,#'|',gotword
|
|
if2 @a,eq,#'>',gotword
|
|
if2 @a,eq,#'<',gotword
|
|
if2 @a,eq,#13,gotword
|
|
if2 @a,eq,#10,gotword
|
|
sta [word],y
|
|
iny
|
|
bra makeword
|
|
;
|
|
; We have a word. See if it's an alias.
|
|
;
|
|
gotword lda #0
|
|
sta [word],y
|
|
long a
|
|
cpy #0 Check for 0 length.
|
|
beq copyrest
|
|
phy
|
|
pei (word+2)
|
|
pei (word)
|
|
jsl findalias
|
|
sta sub
|
|
stx sub+2
|
|
ply
|
|
ora sub+2
|
|
beq copyrest
|
|
;
|
|
; Yes, this is an alias. Copy it into the output buffer.
|
|
;
|
|
add2 @y,cmd,cmd Add length to cmd pointer.
|
|
|
|
pei (sub+2) Make sure that
|
|
pei (sub) substituted string
|
|
jsr cstrlen will fit into buffer.
|
|
sec
|
|
adc outbuf
|
|
jge overflow
|
|
cmp bufend
|
|
jge overflow
|
|
|
|
ldy #0
|
|
short a
|
|
lda [sub]
|
|
putalias sta [outbuf]
|
|
inc outbuf
|
|
iny
|
|
lda [sub],y
|
|
bne putalias
|
|
long a
|
|
;
|
|
; That alias is expanded. Copy until we reach the next command.
|
|
;
|
|
copyrest stz inquote Clear the "in quotes" flag
|
|
stz bsflag and "backslashed" flag.
|
|
|
|
next anop
|
|
lda outbuf Check for output overflow.
|
|
cmp bufend
|
|
jcs overflow
|
|
lda [cmd] Transfer the character.
|
|
and #$00FF
|
|
cmp #13 If carriage-return,
|
|
bne go8bits
|
|
lda #0 treat like end-of-string.
|
|
go8bits short a
|
|
sta [outbuf]
|
|
long a
|
|
inc cmd Bump pointers.
|
|
inc outbuf
|
|
|
|
if2 @a,eq,#0,done
|
|
;
|
|
; If that was a backslashed character, don't check for special chars.
|
|
;
|
|
ldx bsflag
|
|
beq testq
|
|
stz bsflag
|
|
bra next
|
|
|
|
testq if2 @a,eq,#"'",singquoter
|
|
if2 @a,eq,#'"',doubquoter
|
|
;
|
|
; Remaining characters aren't special if we are in a quoted string
|
|
;
|
|
ldx inquote
|
|
bne next
|
|
if2 @a,eq,#';',nextalias
|
|
if2 @a,eq,#'&',nextalias
|
|
if2 @a,eq,#'|',nextalias
|
|
if2 @a,ne,#'\',next
|
|
;
|
|
; "\" found
|
|
;
|
|
backstabber sta bsflag
|
|
bra next
|
|
|
|
;
|
|
; "'" found
|
|
;
|
|
singquoter bit inquote Check "in quotes" flag.
|
|
bvs next In double quotes. Keep looking.
|
|
lda inquote Toggle single quote
|
|
eor #$8000
|
|
sta inquote
|
|
bra next
|
|
;
|
|
; '"' found
|
|
;
|
|
doubquoter bit inquote Check "in quotes" flag.
|
|
bmi next In single quotes. Keep looking.
|
|
lda inquote Toggle single quote
|
|
eor #$4000
|
|
sta inquote
|
|
bra next
|
|
|
|
;
|
|
; ";", "|", or "&" found: it's another command
|
|
;
|
|
nextalias jmp eatleader
|
|
|
|
;
|
|
; Terminate string and exit
|
|
;
|
|
stringend short a
|
|
sta [outbuf]
|
|
long a
|
|
;
|
|
; All done: clean up and return to caller
|
|
;
|
|
done ldx word+2
|
|
lda word
|
|
jsl freemaxline
|
|
|
|
return 4:buf
|
|
|
|
|
|
;
|
|
; Report overflow error
|
|
;
|
|
overflow anop
|
|
pei (buf+2) Free the output buffer.
|
|
pei (buf)
|
|
jsl nullfree
|
|
stz buf
|
|
stz buf+2
|
|
|
|
ldx #^ovferr Report overflow error.
|
|
lda #ovferr
|
|
jsr errputs
|
|
|
|
bra done
|
|
|
|
ovferr dc c'gsh: Alias overflowed line limit',h'0d00'
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Add alias to table
|
|
;
|
|
;=========================================================================
|
|
|
|
addalias START
|
|
|
|
using AliasData
|
|
|
|
tmp equ 0
|
|
ptr equ tmp+4
|
|
hashval equ ptr+4
|
|
space equ hashval+4
|
|
|
|
subroutine (4:aliasname,4:aliasval),space
|
|
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsl hashalias
|
|
sta hashval
|
|
|
|
tax
|
|
lda AliasTable,x
|
|
sta ptr
|
|
lda AliasTable+2,x
|
|
sta ptr+2
|
|
|
|
search lda ptr
|
|
ora ptr+2
|
|
beq notfound
|
|
ldy #4
|
|
lda [ptr],y
|
|
tax
|
|
ldy #4+2
|
|
lda [ptr],y
|
|
pha
|
|
phx
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsr cmpcstr
|
|
jeq replace
|
|
ldy #2
|
|
lda [ptr]
|
|
tax
|
|
lda [ptr],y
|
|
sta ptr+2
|
|
stx ptr
|
|
bra search
|
|
|
|
replace ldy #8+2
|
|
lda [ptr],y
|
|
pha
|
|
ldy #8
|
|
lda [ptr],y
|
|
pha
|
|
jsl nullfree
|
|
pei (aliasval+2)
|
|
pei (aliasval)
|
|
jsr cstrlen
|
|
inc a
|
|
pea 0
|
|
pha
|
|
~NEW
|
|
sta tmp
|
|
stx tmp+2
|
|
ldy #8
|
|
sta [ptr],y
|
|
ldy #8+2
|
|
txa
|
|
sta [ptr],y
|
|
pei (aliasval+2)
|
|
pei (aliasval)
|
|
pei (tmp+2)
|
|
pei (tmp)
|
|
jsr copycstr
|
|
jmp done
|
|
|
|
notfound ph4 #4*3
|
|
~NEW
|
|
sta ptr
|
|
stx ptr+2
|
|
ldy #2
|
|
ldx hashval
|
|
lda AliasTable,x
|
|
sta [ptr]
|
|
lda AliasTable+2,x
|
|
sta [ptr],y
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsr cstrlen
|
|
inc a
|
|
pea 0
|
|
pha
|
|
~NEW
|
|
sta tmp
|
|
stx tmp+2
|
|
ldy #4
|
|
sta [ptr],y
|
|
ldy #4+2
|
|
txa
|
|
sta [ptr],y
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
pei (tmp+2)
|
|
pei (tmp)
|
|
jsr copycstr
|
|
pei (aliasval+2)
|
|
pei (aliasval)
|
|
jsr cstrlen
|
|
inc a
|
|
pea 0
|
|
pha
|
|
~NEW
|
|
sta tmp
|
|
stx tmp+2
|
|
ldy #8
|
|
sta [ptr],y
|
|
ldy #8+2
|
|
txa
|
|
sta [ptr],y
|
|
pei (aliasval+2)
|
|
pei (aliasval)
|
|
pei (tmp+2)
|
|
pei (tmp)
|
|
jsr copycstr
|
|
ldx hashval
|
|
lda ptr
|
|
sta AliasTable,x
|
|
lda ptr+2
|
|
sta AliasTable+2,x
|
|
|
|
done return
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Remove an alias
|
|
;
|
|
;=========================================================================
|
|
|
|
removealias START
|
|
|
|
using AliasData
|
|
|
|
oldptr equ 0
|
|
ptr equ oldptr+4
|
|
space equ ptr+4
|
|
|
|
subroutine (4:aliasname),space
|
|
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsl hashalias
|
|
tax
|
|
lda AliasTable,x
|
|
sta ptr
|
|
lda AliasTable+2,x
|
|
sta ptr+2
|
|
lda #^Aliastable
|
|
sta oldptr+2
|
|
clc
|
|
txa
|
|
adc #AliasTable
|
|
sta oldptr
|
|
|
|
searchloop ora2 ptr,ptr+2,@a
|
|
beq done
|
|
|
|
ldy #4+2
|
|
lda [ptr],y
|
|
pha
|
|
ldy #4
|
|
lda [ptr],y
|
|
pha
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsr cmpcstr
|
|
beq foundit
|
|
mv4 ptr,oldptr
|
|
ldy #2
|
|
lda [ptr],y
|
|
tax
|
|
lda [ptr]
|
|
sta ptr
|
|
stx ptr+2
|
|
bra searchloop
|
|
|
|
foundit ldy #2
|
|
lda [ptr],y
|
|
sta [oldptr],y
|
|
lda [ptr]
|
|
sta [oldptr]
|
|
ldy #4+2
|
|
lda [ptr],y
|
|
pha
|
|
ldy #4
|
|
lda [ptr],y
|
|
pha
|
|
jsl nullfree
|
|
ldy #8+2
|
|
lda [ptr],y
|
|
pha
|
|
ldy #8
|
|
lda [ptr],y
|
|
pha
|
|
jsl nullfree
|
|
pei (ptr+2)
|
|
pei (ptr)
|
|
jsl nullfree
|
|
|
|
done return
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Find an alias
|
|
;
|
|
;=========================================================================
|
|
|
|
findalias START
|
|
|
|
using AliasData
|
|
|
|
ptr equ 0
|
|
value equ ptr+4
|
|
space equ value+4
|
|
|
|
subroutine (4:aliasname),space
|
|
|
|
stz value
|
|
stz value+2
|
|
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsl hashalias
|
|
tax
|
|
lda AliasTable,x
|
|
sta ptr
|
|
lda AliasTable+2,x
|
|
sta ptr+2
|
|
|
|
searchloop ora2 ptr,ptr+2,@a
|
|
beq done
|
|
|
|
ldy #4+2
|
|
lda [ptr],y
|
|
pha
|
|
ldy #4
|
|
lda [ptr],y
|
|
pha
|
|
pei (aliasname+2)
|
|
pei (aliasname)
|
|
jsr cmpcstr
|
|
beq foundit
|
|
ldy #2
|
|
lda [ptr],y
|
|
tax
|
|
lda [ptr]
|
|
sta ptr
|
|
stx ptr+2
|
|
bra searchloop
|
|
|
|
foundit ldy #8
|
|
lda [ptr],y
|
|
sta value
|
|
ldy #8+2
|
|
lda [ptr],y
|
|
sta value+2
|
|
|
|
done return 4:value
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Start alias
|
|
;
|
|
;=========================================================================
|
|
|
|
startalias START
|
|
|
|
using AliasData
|
|
|
|
stz AliasNum
|
|
mv4 AliasTable,AliasPtr
|
|
rtl
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Next alias
|
|
;
|
|
;=========================================================================
|
|
|
|
nextalias START
|
|
|
|
using AliasData
|
|
|
|
value equ 0
|
|
space equ value+4
|
|
|
|
subroutine (0:fubar),space
|
|
|
|
stz value
|
|
stz value+2
|
|
puke if2 AliasNum,cs,#VTABSIZE,done
|
|
|
|
ora2 AliasPtr,AliasPtr+2,@a
|
|
bne flush
|
|
inc AliasNum
|
|
lda AliasNum
|
|
asl2 a
|
|
tax
|
|
lda AliasTable,x
|
|
sta AliasPtr
|
|
lda AliasTable+2,x
|
|
sta AliasPtr+2
|
|
bra puke
|
|
|
|
flush mv4 AliasPtr,value
|
|
ldy #2
|
|
lda [value]
|
|
sta AliasPtr
|
|
lda [value],y
|
|
sta AliasPtr+2
|
|
|
|
done return 4:value
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Hash an alias
|
|
;
|
|
;=========================================================================
|
|
|
|
hashalias PRIVATE
|
|
|
|
hashval equ 0
|
|
space equ hashval+2
|
|
|
|
subroutine (4:p),space
|
|
|
|
lda #11
|
|
sta hashval
|
|
|
|
ldy #0
|
|
loop asl hashval
|
|
lda [p],y
|
|
and #$FF
|
|
beq done
|
|
clc
|
|
adc hashval
|
|
sta hashval
|
|
iny
|
|
bra loop
|
|
done UDivide (hashval,#VTABSIZE),(@a,@a)
|
|
|
|
asl2 a ;Make it an index.
|
|
sta hashval
|
|
|
|
return 2:hashval
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Alias data
|
|
;
|
|
;=========================================================================
|
|
|
|
AliasData DATA
|
|
|
|
AliasNum dc i2'0'
|
|
AliasPtr dc i4'0'
|
|
AliasMutex key
|
|
|
|
AliasTable ds VTABSIZE*4
|
|
|
|
END
|