summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-14 13:40:04 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-14 13:40:04 -0800
commit5e50b4d4faf398f072c0dea814b11db1a95efeec (patch)
tree19dcc5e2a882156516ebcd8403b5e40921bef647
parent3399f97a70cdca0cb05129ea3fb5e9dd42c35d9c (diff)
downloadsyslinux-5e50b4d4faf398f072c0dea814b11db1a95efeec.tar.gz
config: allow a chdir at the time a new configuration file is loaded
If a directory name/path prefix is appended to a loaded configuration file, do a chdir at that point. We finally have all the mechanism to do this right. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--core/cmdline.inc1
-rw-r--r--core/comboot.inc4
-rw-r--r--core/conio.inc2
-rw-r--r--core/extern.inc8
-rw-r--r--core/fs.c23
-rw-r--r--core/include/core.h3
-rw-r--r--core/include/fs.h5
-rw-r--r--core/kernel.inc3
-rw-r--r--core/newconfig.c41
-rw-r--r--core/parsecmd.inc8
-rw-r--r--core/parseconfig.inc12
-rw-r--r--core/runkernel.inc10
-rw-r--r--core/ui.inc17
13 files changed, 98 insertions, 39 deletions
diff --git a/core/cmdline.inc b/core/cmdline.inc
index 8b84f48d..d860ac70 100644
--- a/core/cmdline.inc
+++ b/core/cmdline.inc
@@ -37,6 +37,7 @@ make_plain_cmdline:
dec di
mov [CmdLinePtr],di
+ mov byte [es:di],0 ; Null-terminate
pop es
ret
diff --git a/core/comboot.inc b/core/comboot.inc
index e271b9ec..25c4e186 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -517,7 +517,7 @@ comapi_open:
mov ds,P_ES
mov si,P_SI
mov di,InitRD
- pm_call mangle_name
+ pm_call pm_mangle_name
pop ds
pm_call pm_searchdir
jz comapi_err
@@ -749,7 +749,7 @@ comapi_runkernel:
mov ds,P_DS
mov si,P_SI
mov di,KernelName
- pm_call mangle_name
+ pm_call pm_mangle_name
pop ds
pm_call pm_searchdir
jz comapi_err
diff --git a/core/conio.inc b/core/conio.inc
index 835359fb..60d1fcb2 100644
--- a/core/conio.inc
+++ b/core/conio.inc
@@ -207,7 +207,7 @@ msg_viewimage:
mov byte [si],0 ; Zero-terminate filename
mov si,VGAFileBuf
mov di,VGAFileMBuf
- pm_call mangle_name
+ pm_call pm_mangle_name
call core_open
jz msg_putcharnext ; Not there
call vgadisplayfile
diff --git a/core/extern.inc b/core/extern.inc
index da6c675b..3e25226a 100644
--- a/core/extern.inc
+++ b/core/extern.inc
@@ -13,14 +13,18 @@
extern hello
; fs.c
- extern fs_init, pm_searchdir, getfssec, mangle_name, load_config
- extern unmangle_name, close_file
+ extern fs_init, pm_searchdir, getfssec, pm_mangle_name, load_config
+ extern pm_unmangle_name, close_file
; chdir.c
extern pm_realpath
; readdir.c
extern opendir, readdir, closedir
+
+ ; newconfig.c
+ extern pm_is_config_file
+
%if IS_PXELINUX
; pxe.c
extern unload_pxe, reset_pxe
diff --git a/core/fs.c b/core/fs.c
index 6acfd3be..c53636f2 100644
--- a/core/fs.c
+++ b/core/fs.c
@@ -70,26 +70,39 @@ void load_config(void)
printf("ERROR: No configuration file found\n");
}
-void mangle_name(com32sys_t *regs)
+void pm_mangle_name(com32sys_t *regs)
{
const char *src = MK_PTR(regs->ds, regs->esi.w[0]);
char *dst = MK_PTR(regs->es, regs->edi.w[0]);
-
- this_fs->fs_ops->mangle_name(dst, src);
+
+ mangle_name(dst, src);
}
+void mangle_name(char *dst, const char *src)
+{
+ this_fs->fs_ops->mangle_name(dst, src);
+}
-void unmangle_name(com32sys_t *regs)
+/*
+ * XXX: current unmangle_name() is stpcpy() on all filesystems; consider
+ * eliminating it as a method.
+ */
+void pm_unmangle_name(com32sys_t *regs)
{
const char *src = MK_PTR(regs->ds, regs->esi.w[0]);
char *dst = MK_PTR(regs->es, regs->edi.w[0]);
- dst = this_fs->fs_ops->unmangle_name(dst, src);
+ dst = unmangle_name(dst, src);
/* Update the di register to point to the last null char */
regs->edi.w[0] = OFFS_WRT(dst, regs->es);
}
+char *unmangle_name(char *dst, const char *src)
+{
+ return this_fs->fs_ops->unmangle_name(dst, src);
+}
+
void getfssec(com32sys_t *regs)
{
int sectors;
diff --git a/core/include/core.h b/core/include/core.h
index 88ced70d..c955e730 100644
--- a/core/include/core.h
+++ b/core/include/core.h
@@ -11,6 +11,9 @@ extern char CurrentDirName[];
extern char SubvolName[];
extern char ConfigName[];
extern char KernelName[];
+extern char cmd_line[];
+extern char ConfigFile[];
+extern char KernelCName[];
/* diskstart.inc isolinux.asm*/
extern void getlinsec(void);
diff --git a/core/include/fs.h b/core/include/fs.h
index 124a8161..49026141 100644
--- a/core/include/fs.h
+++ b/core/include/fs.h
@@ -166,8 +166,11 @@ static inline struct file *handle_to_file(uint16_t handle)
}
/* fs.c */
-void mangle_name(com32sys_t *);
+void pm_mangle_name(com32sys_t *);
+void pm_unmangle_name(com32sys_t *);
void pm_searchdir(com32sys_t *);
+void mangle_name(char *, const char *);
+char *unmangle_name(char *, const char *);
int searchdir(const char *name);
void _close_file(struct file *);
diff --git a/core/kernel.inc b/core/kernel.inc
index 5e1c7a39..3ac5af1c 100644
--- a/core/kernel.inc
+++ b/core/kernel.inc
@@ -62,6 +62,9 @@ linux_fdctab resb 12
cmd_line_here equ $ ; F800 Should be out of the way
endstruc
+ global cmd_line
+cmd_line equ (real_mode_seg << 4) + cmd_line_here
+
;
; Old kernel command line signature
;
diff --git a/core/newconfig.c b/core/newconfig.c
new file mode 100644
index 00000000..08027a39
--- /dev/null
+++ b/core/newconfig.c
@@ -0,0 +1,41 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ * 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, Inc., 51 Franklin St, Fifth Floor,
+ * Boston MA 02110-1301, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * newconfig.c
+ *
+ * Load a new configuration file
+ */
+
+#include "core.h"
+#include "fs.h"
+
+void pm_is_config_file(com32sys_t *regs)
+{
+ char target_cwd[FILENAME_MAX];
+ const char *p;
+
+ (void)regs;
+
+ /* Save configuration file as an absolute path for posterity */
+ realpath(ConfigName, KernelCName, FILENAME_MAX);
+
+ /* If we got anything on the command line, do a chdir */
+ p = cmd_line;
+ while (*p && !not_whitespace(*p))
+ p++;
+
+ if (*p) {
+ mangle_name(target_cwd, p);
+ chdir(target_cwd);
+ }
+}
diff --git a/core/parsecmd.inc b/core/parsecmd.inc
index ab5a7df9..b6a2c829 100644
--- a/core/parsecmd.inc
+++ b/core/parsecmd.inc
@@ -122,17 +122,11 @@ Onerror resb max_cmd_len+1 ; onerror
section .bss16
KbdMap resb 256 ; Keyboard map
FKeyName resb MAX_FKEYS*FILENAME_MAX ; File names for F-key help
-KernelCNameLen resw 1 ; Length of unmangled kernel name
InitRDCNameLen resw 1 ; Length of unmangled initrd name
-%if IS_SYSLINUX
-KernelName resb FILENAME_MAX+1 ; Mangled name for kernel
-KernelCName resb FILENAME_MAX+2 ; Unmangled kernel name
-InitRDCName resb FILENAME_MAX+2 ; Unmangled initrd name
-%else
+ global KernelName, KernelCName
KernelName resb FILENAME_MAX ; Mangled name for kernel
KernelCName resb FILENAME_MAX ; Unmangled kernel name
InitRDCName resb FILENAME_MAX ; Unmangled initrd name
-%endif
MNameBuf resb FILENAME_MAX
InitRD resb FILENAME_MAX
diff --git a/core/parseconfig.inc b/core/parseconfig.inc
index ad89f58d..b30dbc2a 100644
--- a/core/parseconfig.inc
+++ b/core/parseconfig.inc
@@ -104,7 +104,7 @@ pc_kernel: cmp byte [VKernel],0
mov [VKernelBuf+vk_type],al
call pc_getline
mov di,VKernelBuf+vk_rname
- pm_call mangle_name
+ pm_call pm_mangle_name
.err: ret
;
@@ -147,7 +147,7 @@ pc_setint16:
pc_filecmd: push ax ; Function to tailcall
call pc_getline
mov di,MNameBuf
- pm_call mangle_name
+ pm_call pm_mangle_name
pm_call pm_searchdir
jnz .ok
pop ax ; Drop the successor function
@@ -160,7 +160,7 @@ pc_filecmd: push ax ; Function to tailcall
pc_opencmd: push ax ; Function to tailcall
call pc_getline
mov di,MNameBuf
- pm_call mangle_name
+ pm_call pm_mangle_name
call core_open
jnz .ok
pop ax ; Drop the successor function
@@ -289,7 +289,7 @@ pc_serial: call getint
pc_filename: push ax
call pc_getline
pop di
- pm_call mangle_name ; Mangle file name
+ pm_call pm_mangle_name ; Mangle file name
ret
;
@@ -314,7 +314,7 @@ pc_label: call commit_vk ; Commit any current vkernel
mov byte [VKernel],1 ; We've seen a "label" statement
mov si,VKernelBuf+vk_vname ; By default, rname == mangled vname
mov di,VKernelBuf+vk_rname
- pm_call mangle_name
+ pm_call pm_mangle_name
mov si,AppendBuf ; Default append==global append
mov di,VKernelBuf+vk_append
mov cx,[AppendLen]
@@ -409,7 +409,7 @@ commit_vk:
mov cx,7 ; "initrd="
rep movsb
mov si,InitRD
- pm_call unmangle_name
+ pm_call pm_unmangle_name
mov al,' '
stosb
diff --git a/core/runkernel.inc b/core/runkernel.inc
index f07c70f6..30177e80 100644
--- a/core/runkernel.inc
+++ b/core/runkernel.inc
@@ -78,10 +78,8 @@ construct_cmdline:
mov cx,boot_image_len
rep movsb
mov si,KernelCName ; Unmangled kernel name
- mov cx,[KernelCNameLen]
- rep movsb
- mov al,' ' ; Space
- stosb
+ call strcpy
+ mov byte [es:di-1],' ' ; Follow by space
call do_ip_append ; Handle IPAppend
@@ -546,7 +544,7 @@ parse_load_initrd:
push di
mov di,InitRD ; Target buffer for mangled name
- pm_call mangle_name
+ pm_call pm_mangle_name
pop di
call loadinitrd
@@ -593,7 +591,7 @@ loadinitrd:
push edi
mov si,InitRD
mov di,InitRDCName
- pm_call unmangle_name ; Create human-readable name
+ pm_call pm_unmangle_name ; Create human-readable name
sub di,InitRDCName
mov [InitRDCNameLen],di
mov di,InitRD
diff --git a/core/ui.inc b/core/ui.inc
index 827710f2..5fe3e539 100644
--- a/core/ui.inc
+++ b/core/ui.inc
@@ -333,11 +333,11 @@ load_kernel: ; Load the kernel now
mov si,command_line
mov di,KernelName
push si
- pm_call mangle_name
+ pm_call pm_mangle_name
pop si
;
; Fast-forward to first option (we start over from the beginning, since
-; mangle_name doesn't necessarily return a consistent ending state.)
+; pm_mangle_name doesn't necessarily return a consistent ending state.)
;
clin_non_wsp: lodsb
cmp al,' '
@@ -400,6 +400,7 @@ vk_check:
mov si,VKernelBuf+vk_append
mov cx,[VKernelBuf+vk_appendlen]
rep movsb
+ mov byte [es:di],cl ; Null-terminate
mov [CmdLinePtr],di ; Where to add rest of cmd
pop es
mov di,KernelName
@@ -440,6 +441,7 @@ vk_check:
mov di,cmd_line_here
mov cx,[AppendLen]
rep movsb
+ mov byte [es:di],cl ; Null-terminate
mov [CmdLinePtr],di
pop di
pop si
@@ -487,7 +489,7 @@ bad_kernel:
mov si,KernelName
mov di,KernelCName
push di
- pm_call unmangle_name ; Get human form
+ pm_call pm_unmangle_name ; Get human form
mov si,err_notfound ; Complain about missing kernel
call writestr
pop si ; KernelCName
@@ -616,9 +618,7 @@ kernel_good:
mov si,KernelName
mov di,KernelCName
- pm_call unmangle_name
- sub di,KernelCName
- mov [KernelCNameLen],di
+ pm_call pm_unmangle_name
; Default memory limit, can be overridden by image loaders
mov eax,[HighMemRsvd]
@@ -675,9 +675,8 @@ is_unknown_filetype:
is_config_file:
push si
- mov si,KernelCName ; Save the config file name, for posterity
- mov di,ConfigName
- pm_call pm_realpath
+ call make_plain_cmdline
+ pm_call pm_is_config_file
pop si
call openfd
call reset_config