Add "onerror" configuration directive
authorhpa <hpa>
Thu, 27 Nov 2003 05:36:16 +0000 (05:36 +0000)
committerhpa <hpa>
Thu, 27 Nov 2003 05:36:16 +0000 (05:36 +0000)
NEWS
isolinux.asm
keywords
keywords.inc
ldlinux.asm
parseconfig.inc
pxelinux.asm
syslinux.doc
ui.inc

diff --git a/NEWS b/NEWS
index 7c76e87..ec26f7d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ them.
 Changes in 2.08:
        * Add new configuration command "ontimeout" to allow timeout
          to have a different action than just pressing Enter.
+       * Add new configuration command "onerror" to allow a custom
+         command to be executed in case the kernel image is not found.
        * Fix bugs in the COMBOOT/COM32 command-line parsing.  APPEND
          now works with COMBOOT/COM32 images.
        * PXELINUX: Poll for ARP requests while sitting at the
@@ -15,7 +17,8 @@ Changes in 2.08:
        * MEMDISK: Add an API to query for the existence of MEMDISK.
        * SYSLINUX: Fix loading boot sectors (.bs/.bss) from floppy
          disk.
-       * .c32 is now one of the extensions searched for automatically.
+       * .c32 is now one of the extensions searched for
+         automatically.
 
 Changes in 2.07:
        * MEMDISK: Workaround for BIOSes which go into a snit when
index 57488cb..fd67d2e 100644 (file)
@@ -134,6 +134,7 @@ VKernelBuf: resb vk_size            ; "Current" vkernel
                alignb 4
 AppendBuf       resb max_cmd_len+1     ; append=
 Ontimeout      resb max_cmd_len+1      ; ontimeout
+Onerror                resb max_cmd_len+1      ; onerror
 KbdMap         resb 256                ; Keyboard map
 FKeyName       resb 10*FILENAME_MAX    ; File names for F-key help
 NumBuf         resb 15                 ; Buffer to load number
@@ -1614,6 +1615,7 @@ img_table:
 ;
 AppendLen       dw 0                    ; Bytes in append= command
 OntimeoutLen   dw 0                    ; Bytes in ontimeout command
+OnerrorLen     dw 0                    ; Bytes in onerror command
 KbdTimeOut      dw 0                    ; Keyboard timeout (if any)
 CmdLinePtr     dw cmd_line_here        ; Command line advancing pointer
 initrd_flag    equ $
index 4e55f15..28efdbc 100644 (file)
--- a/keywords
+++ b/keywords
@@ -14,6 +14,7 @@ say
 serial
 timeout
 ontimeout
+onerror
 f0
 f1
 f2
index 2fcae3b..7496dab 100644 (file)
@@ -58,6 +58,7 @@ keywd_table:
                keyword serial,    pc_serial
                keyword timeout,   pc_timeout
                keyword ontimeout, pc_ontimeout
+               keyword onerror,   pc_onerror
                keyword f1,        pc_fkey,     FKeyName+(0<<FILENAME_MAX_LG2)
                keyword f2,        pc_fkey,     FKeyName+(1<<FILENAME_MAX_LG2)
                keyword f3,        pc_fkey,     FKeyName+(2<<FILENAME_MAX_LG2)
index 13b9b36..745aec2 100644 (file)
@@ -124,6 +124,7 @@ VKernelBuf: resb vk_size            ; "Current" vkernel
                alignb 4
 AppendBuf       resb max_cmd_len+1     ; append=
 Ontimeout      resb max_cmd_len+1      ; ontimeout
+Onerror                resb max_cmd_len+1      ; onerror
 KbdMap         resb 256                ; Keyboard map
 FKeyName       resb 10*16              ; File names for F-key help
 NumBuf         resb 15                 ; Buffer to load number
@@ -1434,6 +1435,7 @@ debug_magic       dw 0D00Dh               ; Debug code sentinel
 %endif
 AppendLen       dw 0                    ; Bytes in append= command
 OntimeoutLen   dw 0                    ; Bytes in ontimeout command
+OnerrorLen     dw 0                    ; Bytes in onerror command
 KbdTimeOut      dw 0                    ; Keyboard timeout (if any)
 CmdLinePtr     dw cmd_line_here        ; Command line advancing pointer
 initrd_flag    equ $
index 34842d8..ebb74de 100644 (file)
@@ -22,8 +22,7 @@
 ; 
 pc_default:    mov di,default_cmd
                call getline
-               xor al,al
-               stosb                           ; null-terminate
+               mov byte [di-1],0               ; null-terminate
                ret
 
 ;
@@ -31,11 +30,20 @@ pc_default: mov di,default_cmd
 ;
 pc_ontimeout:  mov di,Ontimeout
                call getline
-               sub di,Ontimeout
+               sub di,Ontimeout+1              ; Don't need final space
                mov [OntimeoutLen],di
                ret
 
 ;
+; "onerror" command
+;
+pc_onerror:    mov di,Onerror
+               call getline
+               sub di,Onerror
+               mov [OnerrorLen],di
+               ret
+
+;
 ; "append" command
 ;
 pc_append:      cmp word [VKernelCtr],byte 0
index d53924b..0822992 100644 (file)
@@ -206,6 +206,7 @@ VKernelBuf: resb vk_size            ; "Current" vkernel
                alignb 4
 AppendBuf       resb max_cmd_len+1     ; append=
 Ontimeout      resb max_cmd_len+1      ; ontimeout
+Onerror                resb max_cmd_len+1      ; onerror
 KbdMap         resb 256                ; Keyboard map
 BootFile       resb 256                ; Boot file from DHCP packet
 PathPrefix     resb 256                ; Path prefix derived from the above
@@ -2509,6 +2510,7 @@ BaseStack dd StackBuf             ; SS:ESP of base stack
                dw 0
 AppendLen       dw 0                    ; Bytes in append= command
 OntimeoutLen   dw 0                    ; Bytes in ontimeout command
+OnerrorLen     dw 0                    ; Bytes in onerror command
 KbdTimeOut      dw 0                    ; Keyboard timeout (if any)
 CmdLinePtr     dw cmd_line_here        ; Command line advancing pointer
 initrd_flag    equ $
index 2cf0101..e621b50 100644 (file)
@@ -228,6 +228,23 @@ ONTIMEOUT kernel options...
        then "DEFAULT" is used only if the user presses <Enter> to
        boot.
 
+ONERROR kernel options...
+       If a kernel image is not found (either due to it not existing,
+       or because IMPLICIT is set), run the specified command.  The
+       faulty command line is appended to the specified options, so
+       if the ONERROR directive reads as:
+
+               ONERROR xyzzy plugh
+
+       ... and the command line as entered by the user is:
+
+               foo bar baz
+
+       ... SYSLINUX will execute the following as if entered by the
+       user:
+       
+               xyzzy plugh foo bar baz
+
 SERIAL port [[baudrate] flowcontrol]
        Enables a serial port to act as the console.  "port" is a
        number (0 = /dev/ttyS0 = COM1, etc.) or an I/O port address
diff --git a/ui.inc b/ui.inc
index 8688c32..c11c088 100644 (file)
--- a/ui.inc
+++ b/ui.inc
@@ -276,7 +276,17 @@ get_kernel:     mov byte [KernelName+FILENAME_MAX],0       ; Zero-terminate filename/e
                add bx,byte 4
                cmp bx,exten_table_end
                jna .search_loop                ; allow == case (final case)
-bad_kernel:     
+               ; Fall into bad_kernel
+;
+; bad_kernel: Kernel image not found
+; bad_implicit: The user entered a nonvirtual kernel name, with "implicit 0"
+;
+bad_implicit:
+bad_kernel:
+               mov cx,[OnerrorLen]
+               and cx,cx
+               jnz on_error
+.really:
                mov si,KernelName
                 mov di,KernelCName
                push di
@@ -287,13 +297,37 @@ bad_kernel:
                 call cwritestr
                 mov si,crlf_msg
                 jmp abort_load                  ; Ask user for clue
+
 ;
-; bad_implicit: The user entered a nonvirtual kernel name, with "implicit 0"
+; on_error: bad kernel, but we have onerror set
 ;
-bad_implicit:   mov si,KernelName              ; For the error message
-                mov di,KernelCName
-                call unmangle_name
-                jmp short bad_kernel
+on_error:
+               mov si,Onerror
+               mov di,command_line
+               push si                         ; <A>
+               push di                         ; <B>
+               push cx                         ; <C>
+               push cx                         ; <D>
+               push di                         ; <E>
+               repe cmpsb
+               pop di                          ; <E> di == command_line
+               pop bx                          ; <D> bx == [OnerrorLen]
+               je bad_kernel.really            ; Onerror matches command_line already
+               neg bx                          ; bx == -[OnerrorLen]
+               lea cx,[max_cmd_len+bx]
+               ; CX == max_cmd_len-[OnerrorLen]
+               mov di,command_line+max_cmd_len-1
+               mov byte [di+1],0               ; Enforce null-termination
+               lea si,[di+bx]
+               std
+               rep movsb                       ; Make space in command_line
+               cld
+               pop cx                          ; <C> cx == [OnerrorLen]
+               pop di                          ; <B> di == command_line
+               pop si                          ; <A> si  == Onerror
+               rep movsb
+               jmp load_kernel
+
 ;
 ; vk_found: We *are* using a "virtual kernel"
 ;