aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Aleaxander <Aleaxander@gmail.com>2010-12-17 22:31:21 +0800
committerLiu Aleaxander <Aleaxander@gmail.com>2010-12-17 22:31:21 +0800
commiteaf68081e8efef04086368ad18f60b53d0360311 (patch)
tree6e44925ad970ddf61d0c3392e8ffc2b3e695b2e3
parentc36818139752b4505459b094061b7d1f8ccf3c4f (diff)
parentac7b5736554bcdf5ba06ac637d1028dd7ddc25db (diff)
downloadsyslinux-elflink.tar.gz
syslinux-elflink.tar.xz
syslinux-elflink.zip
Merge branch 'master' into elflinkelflink
Conflicts: com32/lib/sys/open.c core/keywords.inc version Signed-off-by: Liu Aleaxander <Aleaxander@gmail.com>
-rw-r--r--NEWS32
-rw-r--r--com32/gfxboot/gfxboot.c91
-rw-r--r--com32/gplinclude/cpuid.h6
-rw-r--r--com32/gpllib/disk/msdos.c4
-rw-r--r--com32/include/sys/bitops.h58
-rw-r--r--com32/include/unistd.h4
-rw-r--r--com32/lib/memmem.c45
-rw-r--r--com32/lib/strspn.c4
-rw-r--r--com32/lib/sys/open.c10
-rw-r--r--com32/lib/vsscanf.c25
-rw-r--r--com32/modules/chain.c49
-rw-r--r--com32/rosh/Makefile20
-rw-r--r--com32/rosh/rosh.c715
-rw-r--r--com32/rosh/rosh.h58
-rw-r--r--core/diskstart.inc5
-rw-r--r--core/fs/diskio.c2
-rw-r--r--core/fs/iso9660/iso9660.c2
-rw-r--r--core/fs/lib/mangle.c2
-rw-r--r--core/fs/pxe/dnsresolv.c2
-rw-r--r--core/fs/pxe/pxe.c14
-rw-r--r--core/keywords1
-rw-r--r--core/parseconfig.inc2
-rw-r--r--core/pxelinux.asm21
-rw-r--r--core/syslinux.ld4
-rw-r--r--core/writedec.inc5
-rw-r--r--doc/extlinux.txt2
-rw-r--r--doc/syslinux.txt17
-rwxr-xr-xextlinux/main.c43
-rw-r--r--libinstaller/syslxopt.c2
-rw-r--r--man/syslinux.15
-rw-r--r--memdisk/setup.c6
-rw-r--r--modules/Makefile2
-rw-r--r--modules/ver.asm606
-rw-r--r--sample/Makefile1
-rw-r--r--utils/isohybrid.c12
-rw-r--r--utils/memdiskfind.c12
36 files changed, 1483 insertions, 406 deletions
diff --git a/NEWS b/NEWS
index 8ecb6cd9..4c6c3405 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,38 @@ Starting with 1.47, changes marked with SYSLINUX, PXELINUX, ISOLINUX
or EXTLINUX apply to that specific program only; other changes apply
to all derivatives.
+Changes in 4.04:
+ * PXELINUX: Fix handling of unqualified DNS names.
+ * PXELINUX: Fix timer bug when PXELINUX might be unloaded
+ (Gene Cumm).
+ * core/writedec.inc: Fix duplicate declaration and overflow
+ (Gene Cumm).
+ * GCC 4.5 fixes.
+ * sample directory: Fix Makefile include (Gene Cumm).
+ * ver.com: New universal DOS/COMBOOT application to display
+ version information (includes DRMK) (Gene Cumm).
+ * rosh.c32: updated; Using getopt() for internal commands to aid
+ parsing options; Fix bugs in ls; add warm reboot and echo
+ (Gene Cumm).
+ * com32: fix a file descriptor leak.
+ * gfxboot.c32: handle TEXT..ENDTEXT; error out on no LABELs
+ found (Sebastian Herbszt).
+ * Fix booting on non-partitioned devices.
+
+Changes in 4.03:
+ * Don't hang if no configuration file is found.
+ * Better support for booting from MBRs which don't pass
+ handover information.
+ * EXTLINUX: Try to be smarter about finding the partition
+ offset.
+ * chain.c32: support chainloading Dell Real Mode Kernel (Gene
+ Cumm).
+ * chain.c32: fix booting in CHS mode.
+ * rosh.c32 updated (Gene Cumm).
+ * Fix the -s option to the syslinux/extlinux installer (Arwin
+ Vosselman).
+ * isohybrid: fix padding of large images (PJ Pandit).
+
Changes in 4.02:
* SYSLINUX: correctly handle the case where the -d option is
specified with a non-absolute path, i.e. "syslinux -d
diff --git a/com32/gfxboot/gfxboot.c b/com32/gfxboot/gfxboot.c
index dd4d6410..552728fd 100644
--- a/com32/gfxboot/gfxboot.c
+++ b/com32/gfxboot/gfxboot.c
@@ -21,6 +21,7 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <minmax.h>
#include <syslinux/loadfile.h>
#include <syslinux/config.h>
@@ -60,7 +61,7 @@
#define GFX_CB_PASSWORD_DONE 11
// real mode code chunk, will be placed into bounce buffer
-extern void realmode_callback_start, realmode_callback_end;
+extern const char realmode_callback_start[], realmode_callback_end[];
// gets in the way
#undef linux
@@ -134,6 +135,7 @@ gfx_menu_t gfx_menu;
menu_t *menu;
menu_t *menu_default;
+static menu_t *menu_ptr, **menu_next;
struct {
uint32_t jmp_table[12];
@@ -161,7 +163,7 @@ char *get_config_file_name(void);
char *skip_spaces(char *s);
char *skip_nonspaces(char *s);
void chop_line(char *s);
-int read_config_file(void);
+int read_config_file(const char *filename);
unsigned magic_ok(unsigned char *buf, unsigned *code_size);
unsigned find_file(unsigned char *buf, unsigned len, unsigned *gfx_file_start, unsigned *file_len, unsigned *code_size);
int gfx_init(char *file);
@@ -219,7 +221,7 @@ int main(int argc, char **argv)
return 0;
}
- if(read_config_file()) {
+ if(read_config_file("~")) {
printf("Error reading config file\n");
if(argc > 2) show_message(argv[2]);
@@ -313,16 +315,24 @@ void chop_line(char *s)
// return:
// 0: ok, 1: error
//
-int read_config_file(void)
+int read_config_file(const char *filename)
{
FILE *f;
char *s, *t, buf[MAX_CONFIG_LINE_LEN];
- unsigned u, menu_idx = 0, label_size = 0, append_size = 0;
- menu_t *menu_ptr = NULL, **menu_next = &menu;
+ unsigned u, top_level = 0, text = 0;
- menu_default = calloc(1, sizeof *menu_default);
+ if(!strcmp(filename, "~")) {
+ top_level = 1;
+ filename = syslinux_config_file();
+ gfx_menu.entries = 0;
+ gfx_menu.label_size = 0;
+ gfx_menu.arg_size = 0;
+ menu_ptr = NULL;
+ menu_next = &menu;
+ menu_default = calloc(1, sizeof *menu_default);
+ }
- if(!(f = fopen(syslinux_config_file(), "r"))) return 1;
+ if(!(f = fopen(filename, "r"))) return 1;
while((s = fgets(buf, sizeof buf, f))) {
chop_line(s);
@@ -332,6 +342,14 @@ int read_config_file(void)
if(*t) *t++ = 0;
t = skip_spaces(t);
+ if(!strcasecmp(s, "endtext")) {
+ text = 0;
+ continue;
+ }
+
+ if (text)
+ continue;
+
if(!strcasecmp(s, "timeout")) {
timeout = atoi(t);
continue;
@@ -340,17 +358,17 @@ int read_config_file(void)
if(!strcasecmp(s, "default")) {
menu_default->label = strdup(t);
u = strlen(t);
- if(u > label_size) label_size = u;
+ if(u > gfx_menu.label_size) gfx_menu.label_size = u;
continue;
}
if(!strcasecmp(s, "label")) {
menu_ptr = *menu_next = calloc(1, sizeof **menu_next);
menu_next = &menu_ptr->next;
- menu_idx++;
+ gfx_menu.entries++;
menu_ptr->label = menu_ptr->menu_label = strdup(t);
u = strlen(t);
- if(u > label_size) label_size = u;
+ if(u > gfx_menu.label_size) gfx_menu.label_size = u;
continue;
}
@@ -377,7 +395,7 @@ int read_config_file(void)
if(!strcasecmp(s, "append")) {
(menu_ptr ?: menu_default)->append = strdup(t);
u = strlen(t);
- if(u > append_size) append_size = u;
+ if(u > gfx_menu.arg_size) gfx_menu.arg_size = u;
continue;
}
@@ -386,6 +404,11 @@ int read_config_file(void)
continue;
}
+ if(!strcasecmp(s, "text")) {
+ text = 1;
+ continue;
+ }
+
if(!strcasecmp(s, "menu") && menu_ptr) {
s = skip_spaces(t);
t = skip_nonspaces(s);
@@ -395,17 +418,37 @@ int read_config_file(void)
if(!strcasecmp(s, "label")) {
menu_ptr->menu_label = strdup(t);
u = strlen(t);
- if(u > label_size) label_size = u;
+ if(u > gfx_menu.label_size) gfx_menu.label_size = u;
continue;
}
+
+ if(!strcasecmp(s, "include")) {
+ goto do_include;
+ }
+ }
+
+ if (!strcasecmp(s, "include")) {
+do_include:
+ s = t;
+ t = skip_nonspaces(s);
+ if (*t) *t = 0;
+ read_config_file(s);
}
}
fclose(f);
+ if (!top_level)
+ return 0;
+
+ if (gfx_menu.entries == 0) {
+ printf("No LABEL keywords found.\n");
+ return 1;
+ }
+
// final '\0'
- label_size++;
- append_size++;
+ gfx_menu.label_size++;
+ gfx_menu.arg_size++;
// ensure we have a default entry
if(!menu_default->label) menu_default->label = menu->label;
@@ -419,19 +462,16 @@ int read_config_file(void)
}
}
- gfx_menu.entries = menu_idx;
- gfx_menu.label_size = label_size;
- gfx_menu.arg_size = append_size;
gfx_menu.default_entry = menu_default->menu_label;
- gfx_menu.label_list = calloc(menu_idx, label_size);
- gfx_menu.arg_list = calloc(menu_idx, append_size);
+ gfx_menu.label_list = calloc(gfx_menu.entries, gfx_menu.label_size);
+ gfx_menu.arg_list = calloc(gfx_menu.entries, gfx_menu.arg_size);
for(u = 0, menu_ptr = menu; menu_ptr; menu_ptr = menu_ptr->next, u++) {
if(!menu_ptr->append) menu_ptr->append = menu_default->append;
if(!menu_ptr->ipappend) menu_ptr->ipappend = menu_default->ipappend;
- if(menu_ptr->menu_label) strcpy(gfx_menu.label_list + u * label_size, menu_ptr->menu_label);
- if(menu_ptr->append) strcpy(gfx_menu.arg_list + u * append_size, menu_ptr->append);
+ if(menu_ptr->menu_label) strcpy(gfx_menu.label_list + u * gfx_menu.label_size, menu_ptr->menu_label);
+ if(menu_ptr->append) strcpy(gfx_menu.arg_list + u * gfx_menu.arg_size, menu_ptr->append);
}
return 0;
@@ -535,7 +575,7 @@ int gfx_init(char *file)
gfx_config.file = gfx_config.archive_start + file_start;
- u = &realmode_callback_end - &realmode_callback_start;
+ u = realmode_callback_end - realmode_callback_start;
u = (u + REALMODE_BUF_SIZE + 0xf) & ~0xf;
if(u + code_size > lowmem_size) {
@@ -543,7 +583,8 @@ int gfx_init(char *file)
return 1;
}
- memcpy(lowmem + REALMODE_BUF_SIZE, &realmode_callback_start, &realmode_callback_end - &realmode_callback_start);
+ memcpy(lowmem + REALMODE_BUF_SIZE, realmode_callback_start,
+ realmode_callback_end - realmode_callback_start);
// fill in buffer size and location
*(uint16_t *) (lowmem + REALMODE_BUF_SIZE) = REALMODE_BUF_SIZE;
@@ -749,7 +790,7 @@ void *load_one(char *file, ssize_t *file_size)
if(size) {
buf = malloc(size);
for(i = 1, cur = 0 ; cur < size && i > 0; cur += i) {
- i = save_read(fd, buf + cur, CHUNK_SIZE);
+ i = save_read(fd, buf + cur, min(CHUNK_SIZE, size - cur));
if(i == -1) break;
gfx_progress_update(i);
}
diff --git a/com32/gplinclude/cpuid.h b/com32/gplinclude/cpuid.h
index bc9df171..53a08085 100644
--- a/com32/gplinclude/cpuid.h
+++ b/com32/gplinclude/cpuid.h
@@ -19,6 +19,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <cpufeature.h>
+#include <sys/bitops.h>
#include <sys/cpu.h>
#include <klibc/compiler.h>
@@ -173,11 +174,6 @@ typedef struct {
#define X86_VENDOR_NUM 9
#define X86_VENDOR_UNKNOWN 0xff
-static inline __purefunc bool test_bit(int nr, const uint32_t * addr)
-{
- return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;
-}
-
#define cpu_has(c, bit) test_bit(bit, (c)->x86_capability)
/*
diff --git a/com32/gpllib/disk/msdos.c b/com32/gpllib/disk/msdos.c
index affec43b..a4ee60fb 100644
--- a/com32/gpllib/disk/msdos.c
+++ b/com32/gpllib/disk/msdos.c
@@ -20,13 +20,13 @@
#include <disk/partition.h>
#include <disk/read.h>
-static inline int is_extended_partition(struct part_entry *ptab)
+static int is_extended_partition(struct part_entry *ptab)
{
return (ptab->ostype == 0x05 ||
ptab->ostype == 0x0f || ptab->ostype == 0x85);
}
-static inline int msdos_magic_present(const char *ptab)
+static int msdos_magic_present(const char *ptab)
{
return (*(uint16_t *) (ptab + 0x1fe) == 0xaa55);
}
diff --git a/com32/include/sys/bitops.h b/com32/include/sys/bitops.h
new file mode 100644
index 00000000..06cf9f3e
--- /dev/null
+++ b/com32/include/sys/bitops.h
@@ -0,0 +1,58 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * bitops.h
+ *
+ * Simple bitwise operations
+ */
+
+#ifndef _BITOPS_H
+#define _BITOPS_H
+
+#include <klibc/compiler.h>
+
+static inline void set_bit(long __bit, void *__bitmap)
+{
+ asm volatile("btsl %1,%0" : "+m" (__bitmap) : "Ir" (__bit) : "memory");
+}
+
+static inline void clr_bit(long __bit, void *__bitmap)
+{
+ asm volatile("btcl %1,%0" : "+m" (__bitmap) : "Ir" (__bit) : "memory");
+}
+
+static inline int __purefunc test_bit(long __bit, const void *__bitmap)
+{
+ unsigned char __r;
+ asm("btl %2,%1; setnz %0"
+ : "=r" (__r)
+ : "m" (__bitmap), "Ir" (__bit));
+ return __r;
+}
+
+#endif /* _BITOPS_H */
diff --git a/com32/include/unistd.h b/com32/include/unistd.h
index fc514f10..9e13381a 100644
--- a/com32/include/unistd.h
+++ b/com32/include/unistd.h
@@ -28,6 +28,10 @@ __extern int chdir(const char *);
__extern unsigned int sleep(unsigned int);
__extern unsigned int msleep(unsigned int);
+__extern int getopt(int, char *const *, const char *);
+__extern char *optarg;
+__extern int optind, opterr, optopt;
+
/* Standard file descriptor numbers. */
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
diff --git a/com32/lib/memmem.c b/com32/lib/memmem.c
index 8558a80d..7c42f1c3 100644
--- a/com32/lib/memmem.c
+++ b/com32/lib/memmem.c
@@ -18,26 +18,35 @@ void *memmem(const void *haystack, size_t n, const void *needle, size_t m)
size_t j, k, l;
- if (m > n)
- return NULL;
+ if (m > n || !m || !n)
+ return NULL;
- if (x[0] == x[1]) {
- k = 2;
- l = 1;
- } else {
- k = 1;
- l = 2;
- }
+ if (1 != m) {
+ if (x[0] == x[1]) {
+ k = 2;
+ l = 1;
+ } else {
+ k = 1;
+ l = 2;
+ }
- j = 0;
- while (j <= n - m) {
- if (x[1] != y[j + 1]) {
- j += k;
- } else {
- if (!memcmp(x + 2, y + j + 2, m - 2) && x[0] == y[j])
- return (void *)&y[j];
- j += l;
- }
+ j = 0;
+ while (j <= n - m) {
+ if (x[1] != y[j + 1]) {
+ j += k;
+ } else {
+ if (!memcmp(x + 2, y + j + 2, m - 2)
+ && x[0] == y[j])
+ return (void *)&y[j];
+ j += l;
+ }
+ }
+ } else {
+ do {
+ if (*y == *x)
+ return (void *)y;
+ y++;
+ } while (--n);
}
return NULL;
diff --git a/com32/lib/strspn.c b/com32/lib/strspn.c
index abbbf175..7a248205 100644
--- a/com32/lib/strspn.c
+++ b/com32/lib/strspn.c
@@ -11,12 +11,12 @@
#define LONG_BIT (CHAR_BIT*sizeof(long))
#endif
-static inline void set_bit(unsigned long *bitmap, unsigned int bit)
+static void set_bit(unsigned long *bitmap, unsigned int bit)
{
bitmap[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);
}
-static inline int test_bit(unsigned long *bitmap, unsigned int bit)
+static int test_bit(unsigned long *bitmap, unsigned int bit)
{
return (int)(bitmap[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1;
}
diff --git a/com32/lib/sys/open.c b/com32/lib/sys/open.c
index a071c61b..3aa211b2 100644
--- a/com32/lib/sys/open.c
+++ b/com32/lib/sys/open.c
@@ -57,15 +57,17 @@ int open(const char *pathname, int flags, ...)
fd = opendev(&__file_dev, NULL, flags);
- //printf("enter, file = %s, fd = %d\n", pathname, fd);
-
if (fd < 0)
return -1;
fp = &__file_info[fd];
- handle = open_file(pathname, &fp->i.fd);
- if (handle < 0)
+
+ handle = __com32.cs_pm->open_file(pathname, &fp->i.fd);
+ if (handle < 0) {
+ close(fd);
+ errno = ENOENT;
return -1;
+ }
fp->i.offset = 0;
fp->i.nbytes = 0;
diff --git a/com32/lib/vsscanf.c b/com32/lib/vsscanf.c
index 153dbbdd..d9fec51c 100644
--- a/com32/lib/vsscanf.c
+++ b/com32/lib/vsscanf.c
@@ -12,6 +12,7 @@
#include <string.h>
#include <limits.h>
#include <stdio.h>
+#include <sys/bitops.h>
#ifndef LONG_BIT
#define LONG_BIT (CHAR_BIT*sizeof(long))
@@ -46,25 +47,13 @@ enum bail {
bail_err /* Conversion mismatch */
};
-static inline const char *skipspace(const char *p)
+static const char *skipspace(const char *p)
{
while (isspace((unsigned char)*p))
p++;
return p;
}
-#undef set_bit
-static inline void set_bit(unsigned long *bitmap, unsigned int bit)
-{
- bitmap[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);
-}
-
-#undef test_bit
-static inline int test_bit(unsigned long *bitmap, unsigned int bit)
-{
- return (int)(bitmap[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1;
-}
-
int vsscanf(const char *buffer, const char *format, va_list ap)
{
const char *p = format;
@@ -323,7 +312,7 @@ set_integer:
if (ch == '^' && !(flags & FL_INV)) {
matchinv = 1;
} else {
- set_bit(matchmap, (unsigned char)ch);
+ set_bit((unsigned char)ch, matchmap);
state = st_match;
}
break;
@@ -335,18 +324,18 @@ set_integer:
range_start = (unsigned char)ch;
state = st_match_range;
} else {
- set_bit(matchmap, (unsigned char)ch);
+ set_bit((unsigned char)ch, matchmap);
}
break;
case st_match_range: /* %[ match after - */
if (ch == ']') {
- set_bit(matchmap, (unsigned char)'-'); /* - was last character */
+ set_bit((unsigned char)'-', matchmap); /* - was last character */
goto match_run;
} else {
int i;
for (i = range_start; i < (unsigned char)ch; i++)
- set_bit(matchmap, i);
+ set_bit(i, matchmap);
state = st_match;
}
break;
@@ -354,7 +343,7 @@ set_integer:
match_run: /* Match expression finished */
qq = q;
while (width && *q
- && test_bit(matchmap, (unsigned char)*q) ^ matchinv) {
+ && test_bit((unsigned char)*q, matchmap) ^ matchinv) {
*sarg++ = *q++;
}
if (q != qq) {
diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index 6a5b1151..89489d18 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -76,6 +76,10 @@
* equivalent to seg=0x70 file=<loader> sethidden,
* used with DOS' io.sys.
*
+ * drmk=<loader>
+ * Similar to msdos=<loader> but prepares the special options
+ * for the Dell Real Mode Kernel.
+ *
* grub=<loader>
* same as seg=0x800 file=<loader> & jumping to seg 0x820,
* used with GRUB Legacy stage2 files.
@@ -266,23 +270,21 @@ static void *read_sectors(uint64_t lba, uint8_t count)
if (lba)
return NULL; /* Can only read MBR */
- s = 1;
- h = 0;
- c = 0;
+ s = h = c = 0;
} else {
- s = (lba % disk_info.sect) + 1;
+ s = lba % disk_info.sect;
t = lba / disk_info.sect; /* Track = head*cyl */
h = t % disk_info.head;
c = t / disk_info.head;
}
- if (s > 63 || h > 256 || c > 1023)
+ if (s >= 63 || h >= 256 || c >= 1024)
return NULL;
inreg.eax.b[0] = count;
inreg.eax.b[1] = 0x02; /* Read */
- inreg.ecx.b[1] = c & 0xff;
- inreg.ecx.b[0] = s + (c >> 6);
+ inreg.ecx.b[1] = c;
+ inreg.ecx.b[0] = ((c & 0x300) >> 2) | (s+1);
inreg.edx.b[1] = h;
inreg.edx.b[0] = disk_info.disk;
inreg.ebx.w[0] = OFFS(buf);
@@ -327,22 +329,20 @@ static int write_sector(unsigned int lba, const void *data)
if (lba)
return -1; /* Can only write MBR */
- s = 1;
- h = 0;
- c = 0;
+ s = h = c = 0;
} else {
- s = (lba % disk_info.sect) + 1;
+ s = lba % disk_info.sect;
t = lba / disk_info.sect; /* Track = head*cyl */
h = t % disk_info.head;
c = t / disk_info.head;
}
- if (s > 63 || h > 256 || c > 1023)
+ if (s >= 63 || h >= 256 || c >= 1024)
return -1;
inreg.eax.w[0] = 0x0301; /* Write one sector */
- inreg.ecx.b[1] = c & 0xff;
- inreg.ecx.b[0] = s + (c >> 6);
+ inreg.ecx.b[1] = c;
+ inreg.ecx.b[0] = ((c & 0x300) >> 2) | (s+1);
inreg.edx.b[1] = h;
inreg.edx.b[0] = disk_info.disk;
inreg.ebx.w[0] = OFFS(buf);
@@ -1711,16 +1711,31 @@ int main(int argc, char *argv[])
* We only really need 4 new, usable bytes at the end.
*/
int tsize = (data[ndata].size + 19) & 0xfffffff0;
+ const union syslinux_derivative_info *sdi;
+
+ sdi = syslinux_derivative_info();
+ /* We should lookup the Syslinux partition offset and use it */
+ fs_lba = *sdi->disk.partoffset;
+ /*
+ * fs_lba should be verified against the disk as some DRMK
+ * variants will check and fail if it does not match
+ */
+ dprintf(" fs_lba offset is %d\n", fs_lba);
+ /* DRMK only uses a DWORD */
+ if (fs_lba > 0xffffffff) {
+ error("LBA very large; Only using lower 32 bits; DRMK will probably fail\n");
+ }
regs.ss = regs.fs = regs.gs = 0; /* Used before initialized */
if (!realloc(data[ndata].data, tsize)) {
error("Failed to realloc for DRMK\n");
- goto bail;
+ goto bail; /* We'll never make it */
}
data[ndata].size = tsize;
- /* ds:[bp+28] must be 0x0000003f */
+ /* ds:bp is assumed by DRMK to be the boot sector */
+ /* offset 28 is the FAT HiddenSectors value */
regs.ds = (tsize >> 4) + (opt.seg - 2);
/* "Patch" into tail of the new space */
- *(int *)(data[ndata].data + tsize - 4) = 0x0000003f;
+ *(int *)(data[ndata].data + tsize - 4) = (int)(fs_lba & 0xffffffff);
}
ndata++;
diff --git a/com32/rosh/Makefile b/com32/rosh/Makefile
index 7bf5059c..f4b7d866 100644
--- a/com32/rosh/Makefile
+++ b/com32/rosh/Makefile
@@ -1,6 +1,8 @@
## -----------------------------------------------------------------------
##
## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
+## Copyright 2010 Intel Corporation; author: H. Peter Anvin
+## Copyright 2008-2010 Gene Cumm - All Rights Reserved
##
## 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
@@ -11,18 +13,34 @@
## -----------------------------------------------------------------------
##
-## samples for syslinux users
+## ROSH Read Only Shell
##
topdir = ../..
include MCONFIG
+# from com32/sysdump/Makefile
+# The DATE is set on the make command line when building binaries for
+# official release. Otherwise, substitute a hex string that is pretty much
+# guaranteed to be unique to be unique from build to build.
+ifndef HEXDATE
+HEXDATE := $(shell $(PERL) $(topdir)/now.pl $(SRCS) $(wildcard *.h))
+endif
+ifndef DATE
+DATE := $(shell sh $(topdir)/gen-id.sh $(VERSION) $(HEXDATE))
+endif
+
+CFLAGS += -DDATE='"$(DATE)"'
+LNXCFLAGS += -DDATE='"$(DATE)"'
+
rosh.o: rosh.h
rosh.lo: rosh.h
all: rosh.c32
+allgrc: rosh.c32 rosh.lnx
+
tidy dist:
rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
diff --git a/com32/rosh/rosh.c b/com32/rosh/rosh.c
index bf1176fb..12e09995 100644
--- a/com32/rosh/rosh.c
+++ b/com32/rosh/rosh.c
@@ -20,7 +20,12 @@
/*
* ToDos:
- * rosh_ls(): sorted; then multiple columns
+ * prompt: Allow left/right arrow, home/end and more?
+ * commands Break into argv/argc-like array
+ * rosh_cfg: allow -s <file> to change config
+ * rosh_ls(): sorted; then multiple columns
+ * prompt: Possibly honor timeout on initial entry for usage as UI
+ * Also possibly honor totaltimeout
*/
/*#define DO_DEBUG 1
@@ -32,19 +37,30 @@
* debugging enabled; Comment to remove.
*/
#include "rosh.h"
+#include "../../version.h"
#define APP_LONGNAME "Read-Only Shell"
#define APP_NAME "rosh"
#define APP_AUTHOR "Gene Cumm"
#define APP_YEAR "2010"
-#define APP_VER "beta-b062"
+#define APP_VER "beta-b089"
-void rosh_version(void)
+/* Print version information to stdout
+ */
+void rosh_version(int vtype)
{
- printf("%s v %s; (c) %s %s.\n", APP_LONGNAME, APP_VER, APP_YEAR,
- APP_AUTHOR);
+ char env[256];
+ env[0] = 0;
+ printf("%s v %s; (c) %s %s.\n\tFrom Syslinux %s, %s\n", APP_LONGNAME, APP_VER, APP_YEAR, APP_AUTHOR, VERSION_STR, DATE);
+ switch (vtype) {
+ case 1:
+ rosh_get_env_ver(env, 256);
+ printf("\tRunning on %s\n", env);
+ }
}
+/* Print beta message and if DO_DEBUG/DO_DEBUG2 are active
+ */
void print_beta(void)
{
puts(rosh_beta_str);
@@ -112,33 +128,157 @@ int rosh_parse_sp_1(char *dest, const char *src, const int ipos)
return epos;
}
+/*
+ * parse_args1: Try 1 at parsing a string to an argc/argv pair. use free_args1 to free memory malloc'd
+ *
+ * Derived from com32/lib/sys/argv.c:__parse_argv()
+ * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ */
+int parse_args1(char ***iargv, const char *istr)
+{
+ int argc = 0;
+ const char *p;
+ char *q, *r, *args, **arg;
+ int sp = 1; //, qt = 0; /* Was a space; inside a quote */
+
+ /* Scan 1: Length */
+ /* I could eliminate this if I knew a max length, like strncpy() */
+ int len = strlen(istr);
+
+ /* Scan 2: Copy, nullify and make argc */
+ if (!(args = malloc(len + 1)))
+ goto fail_args;
+ q = args;
+ for (p = istr;; p++) {
+ if (*p <= ' ') {
+ if (!sp) {
+ sp = 1;
+ *q++ = '\0';
+ }
+ } else {
+ if (sp) {
+ argc++;
+ sp = 0;
+ }
+ *q++ = *p;
+ }
+ if (!*p)
+ break;
+ }
+
+ q--; /* Point q to final null */
+ /* Scan 3: Build array of pointers */
+ if (!(*iargv = malloc((argc + 1) * sizeof(char *))))
+ goto fail_args_ptr;
+ arg = *iargv;
+ arg[argc] = NULL; /* Nullify the last pointer */
+ if (*args != '\0')
+ *arg++ = args;
+ for (r = args; r < q ; r++) {
+ if (*r == '\0') {
+ *arg++ = r + 1;
+ }
+ }
+
+fail_args:
+ return argc;
+fail_args_ptr:
+ free(args);
+ return 0;
+}
+
+/* Free argv created by parse_args1()
+ * argv Argument Values
+ */
+void free_args1(char ***argv)
+{
+ char *s;
+ s = **argv;
+ free(*argv);
+ free(s);
+}
+
+/* Convert a string to an argc/argv pair
+ * str String to parse
+ * argv Argument Values
+ * returns Argument Count
+ */
+int rosh_str2argv(char ***argv, const char *str)
+{
+ return parse_args1(argv, str);
+}
+
+/* Free an argv created by rosh_str2argv()
+ * argv Argument Values to free
+ */
+void rosh_free_argv(char ***argv)
+{
+ free_args1(argv);
+}
+
+/* Print the contents of an argc/argv pair
+ * argc Argument Count
+ * argv Argument Values
+ */
+void rosh_pr_argv(int argc, char *argv[])
+{
+ int i;
+ for (i = 0; i < argc; i++) {
+ printf("%s%s", argv[i], (i < argc)? " " : "");
+ }
+ puts("");
+}
+
+/* Print the contents of an argc/argv pair verbosely
+ * argc Argument Count
+ * argv Argument Values
+ */
+void rosh_pr_argv_v(int argc, char *argv[])
+{
+ int i;
+ for (i = 0; i < argc; i++) {
+ printf("%4d '%s'\n", i, argv[i]);
+ }
+}
+
+/* Reset the getopt() environment
+ */
+void rosh_getopt_reset(void)
+{
+ optind = 0;
+ optopt = 0;
+}
+
/* Display help
* type Help type
- * cmdstr Command string
+ * cmdstr Command for which help is requested
*/
void rosh_help(int type, const char *cmdstr)
{
- const char *istr;
- istr = cmdstr;
switch (type) {
case 2:
- istr += rosh_search_nonsp(cmdstr, rosh_search_sp(cmdstr, 0));
- if ((cmdstr == NULL) || (strcmp(istr, "") == 0)) {
- rosh_version();
+ if ((cmdstr == NULL) || (strcmp(cmdstr, "") == 0)) {
+ rosh_version(0);
puts(rosh_help_str2);
} else {
- switch (istr[0]) {
+ switch (cmdstr[0]) {
+ case 'c':
+ puts(rosh_help_cd_str);
+ break;
case 'l':
puts(rosh_help_ls_str);
break;
default:
- printf(rosh_help_str_adv, istr);
+ printf(rosh_help_str_adv, cmdstr);
}
}
break;
case 1:
default:
- rosh_version();
+ if (cmdstr)
+ printf("%s: %s: unknown command\n", APP_NAME, cmdstr);
+ rosh_version(0);
puts(rosh_help_str1);
}
}
@@ -187,11 +327,13 @@ void rosh_error(const int ierrno, const char *cmdstr, const char *filestr)
/* Concatenate command line arguments into one string
* cmdstr Output command string
+ * cmdlen Length of cmdstr
* argc Argument Count
* argv Argument Values
* barg Beginning Argument
*/
-int rosh_argcat(char *cmdstr, const int argc, char *argv[], const int barg)
+int rosh_argcat(char *cmdstr, const int cmdlen, const int argc, char *argv[],
+ const int barg)
{
int i, arglen, curpos; /* index, argument length, current position
in cmdstr */
@@ -200,15 +342,15 @@ int rosh_argcat(char *cmdstr, const int argc, char *argv[], const int barg)
for (i = barg; i < argc; i++) {
arglen = strlen(argv[i]);
/* Theoretically, this should never be met in SYSLINUX */
- if ((curpos + arglen) > (ROSH_CMD_SZ - 1))
- arglen = (ROSH_CMD_SZ - 1) - curpos;
+ if ((curpos + arglen) > (cmdlen - 1))
+ arglen = (cmdlen - 1) - curpos;
memcpy(cmdstr + curpos, argv[i], arglen);
curpos += arglen;
- if (curpos >= (ROSH_CMD_SZ - 1)) {
+ if (curpos >= (cmdlen - 1)) {
/* Hopefully, curpos should not be greater than
- (ROSH_CMD_SZ - 1) */
+ (cmdlen - 1) */
/* Still need a '\0' at the last character */
- cmdstr[(ROSH_CMD_SZ - 1)] = 0;
+ cmdstr[(cmdlen - 1)] = 0;
break; /* Escape out of the for() loop;
We can no longer process anything more */
} else {
@@ -278,26 +420,19 @@ void rosh_qualify_filestr(char *filestr, const char *ifilstr,
}
/* Concatenate multiple files to stdout
- * cmdstr command string to process
+ * argc Argument Count
+ * argv Argument Values
*/
-void rosh_cat(const char *cmdstr)
+void rosh_cat(int argc, char *argv[])
{
FILE *f;
- char filestr[ROSH_PATH_SZ];
char buf[ROSH_BUF_SZ];
- int numrd;
- int cmdpos;
+ int i, numrd;
- ROSH_DEBUG("CMD: '%s'\n", cmdstr);
- /* Initialization */
- filestr[0] = 0;
- cmdpos = 0;
- /* skip the first word */
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- while (strlen(filestr) > 0) {
- printf("--File = '%s'\n", filestr);
- f = fopen(filestr, "r");
+ for (i = 0; i < argc; i++) {
+ printf("--File = '%s'\n", argv[i]);
+ errno = 0;
+ f = fopen(argv[i], "r");
if (f != NULL) {
numrd = fread(buf, 1, ROSH_BUF_SZ, f);
while (numrd > 0) {
@@ -306,36 +441,37 @@ void rosh_cat(const char *cmdstr)
}
fclose(f);
} else {
- rosh_error(errno, "cat", filestr);
+ rosh_error(errno, "cat", argv[i]);
errno = 0;
}
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
}
} /* rosh_cat */
/* Change PWD (Present Working Directory)
- * cmdstr command string to process
+ * argc Argument count
+ * argv Argument values
* ipwdstr Initial PWD
*/
-void rosh_cd(const char *cmdstr, const char *ipwdstr)
+void rosh_cd(int argc, char *argv[], const char *ipwdstr)
{
- int rv;
+ int rv = 0;
+#ifdef DO_DEBUG
char filestr[ROSH_PATH_SZ];
- int cmdpos;
- ROSH_DEBUG("CMD: '%s'\n", cmdstr);
- /* Initialization */
- filestr[0] = 0;
- cmdpos = 0;
- rv = 0;
- /* skip the first word */
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- if (strlen(filestr) != 0)
- rv = chdir(filestr);
- else
+#endif /* DO_DEBUG */
+ ROSH_DEBUG("CMD: \n");
+ ROSH_DEBUG_ARGV_V(argc, argv);
+ errno = 0;
+ if (argc == 2)
+ rv = chdir(argv[1]);
+ else if (argc == 1)
rv = chdir(ipwdstr);
+ else
+ rosh_help(2, argv[0]);
if (rv != 0) {
- rosh_error(errno, "cd", filestr);
+ if (argc == 2)
+ rosh_error(errno, "cd", argv[1]);
+ else
+ rosh_error(errno, "cd", ipwdstr);
errno = 0;
} else {
#ifdef DO_DEBUG
@@ -352,31 +488,61 @@ void rosh_cfg(void)
printf("CFG: '%s'\n", syslinux_config_file());
} /* rosh_cfg */
-/* Process optstr to optarr
- * optstr option string to process
- * optarr option array to populate
+/* Echo a string back to the screen
+ * cmdstr command string to process
*/
-void rosh_ls_arg_opt(const char *optstr, int *optarr)
+void rosh_echo(const char *cmdstr)
{
- char *cpos;
- cpos = strchr(optstr, 'l');
- if (cpos) {
- optarr[0] = cpos - optstr;
- } else {
- optarr[0] = -1;
- }
- cpos = strchr(optstr, 'F');
- if (cpos) {
- optarr[1] = cpos - optstr;
+ int bpos = 0;
+ ROSH_DEBUG("CMD: '%s'\n", cmdstr);
+ bpos = rosh_search_nonsp(cmdstr, rosh_search_sp(cmdstr, 0));
+ if (bpos > 1) {
+ ROSH_DEBUG(" bpos=%d\n", bpos);
+ printf("'%s'\n", cmdstr + bpos);
} else {
- optarr[1] = -1;
+ puts("");
}
- cpos = strchr(optstr, 'i');
- if (cpos) {
- optarr[2] = cpos - optstr;
- } else {
- optarr[2] = -1;
+} /* rosh_echo */
+
+/* Process argc/argv to optarr
+ * argc Argument count
+ * argv Argument values
+ * optarr option array to populate
+ */
+void rosh_ls_arg_opt(int argc, char *argv[], int optarr[])
+{
+ int rv = 0;
+
+ optarr[0] = -1;
+ optarr[1] = -1;
+ optarr[2] = -1;
+ rosh_getopt_reset();
+ while (rv != -1) {
+ ROSH_DEBUG2("getopt optind=%d rv=%d\n", optind, rv);
+ rv = getopt(argc, argv, rosh_ls_opt_str);
+ switch (rv) {
+ case 'l':
+ case 0:
+ optarr[0] = 1;
+ break;
+ case 'F':
+ case 1:
+ optarr[1] = 1;
+ break;
+ case 'i':
+ case 2:
+ optarr[2] = 1;
+ break;
+ case '?':
+ case -1:
+ default:
+ ROSH_DEBUG2("getopt optind=%d rv=%d\n", optind, rv);
+ break;
+ }
}
+ ROSH_DEBUG2(" end getopt optind=%d rv=%d\n", optind, rv);
+ ROSH_DEBUG2("\tIn rosh_ls_arg_opt() opt[0]=%d\topt[1]=%d\topt[2]=%d\n", optarr[0], optarr[1],
+ optarr[2]);
} /* rosh_ls_arg_opt */
/* Retrieve the size of a file argument
@@ -428,6 +594,7 @@ int rosh_ls_de_size_mode(struct dirent *de, mode_t * st_mode)
filestr2[file2pos] = '/';
}
strcpy(filestr2 + file2pos + 1, de->d_name);*/
+ errno = 0;
status = stat(de->d_name, &fdstat);
ROSH_DEBUG2("\t--stat()=%d\terr=%d\n", status, errno);
if (errno) {
@@ -621,14 +788,17 @@ void rosh_ls_arg_dir(const char *filestr, DIR * d, const int *optarr)
int filepos;
filepos = 0;
+ errno = 0;
while ((de = readdir(d))) {
filepos++;
rosh_ls_arg_dir_de(de, optarr);
}
- if (errno)
+ if (errno) {
rosh_error(errno, "ls:arg_dir", filestr);
- else if (filepos == 0)
+ errno = 0;
+ } else { if (filepos == 0)
ROSH_DEBUG("0 files found");
+ }
} /* rosh_ls_arg_dir */
/* Simple directory listing for one argument (file/directory) based on
@@ -660,9 +830,13 @@ void rosh_ls_arg(const char *filestr, const int *optarr)
if (status == 0) {
if (S_ISDIR(fdstat.st_mode)) {
ROSH_DEBUG("PATH '%s' is a directory\n", filestr);
- d = opendir(filestr);
- rosh_ls_arg_dir(filestr, d, optarr);
- closedir(d);
+ if ((d = opendir(filestr))) {
+ rosh_ls_arg_dir(filestr, d, optarr);
+ closedir(d);
+ } else {
+ rosh_error(errno, "ls", filestr);
+ errno = 0;
+ }
} else {
de.d_ino = rosh_ls_d_ino(&fdstat);
de.d_type = (IFTODT(fdstat.st_mode));
@@ -705,85 +879,50 @@ int rosh_ls_parse_opt(const char *filestr, char *optstr)
return ret;
} /* rosh_ls_parse_opt */
-/* List Directory based on cmdstr and pwdstr
- * cmdstr command string to process
- * pwdstr Present Working Directory string
+/* List Directory
+ * argc Argument count
+ * argv Argument values
*/
-void rosh_ls(const char *cmdstr)
+void rosh_ls(int argc, char *argv[])
{
- char filestr[ROSH_PATH_SZ];
- char optstr[ROSH_OPT_SZ]; /* Options string */
- int cmdpos, tpos; /* Position within cmdstr, temp position */
- int numargs; /* number of non-option arguments */
- int argpos; /* number of non-option arguments processed */
int optarr[3];
+ int i;
- ROSH_DEBUG("CMD: '%s'\n", cmdstr);
- /* Initialization */
- filestr[0] = 0;
- optstr[0] = 0;
- cmdpos = 0;
- numargs = 0;
- argpos = 0;
- /* skip the first word */
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- tpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- /* If there are no real arguments, substitute PWD */
- if (strlen(filestr) == 0) {
- strcpy(filestr, ".");
- cmdpos = tpos;
- } else { /* Parse for command line options */
- while (strlen(filestr) > 0) {
- numargs += rosh_ls_parse_opt(filestr, optstr);
- tpos = rosh_parse_sp_1(filestr, cmdstr, tpos);
- }
- if (numargs == 0) {
- strcpy(filestr, ".");
- cmdpos = tpos;
- } else {
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- }
- }
+ rosh_ls_arg_opt(argc, argv, optarr);
+ ROSH_DEBUG2("In ls()\n");
+ ROSH_DEBUG2_ARGV_V(argc, argv);
#ifdef DO_DEBUG
- if (!strchr(optstr, 'l'))
- strcat(optstr, "l");
+ optarr[0] = 2;
#endif /* DO_DEBUG */
- rosh_ls_arg_opt(optstr, optarr);
- ROSH_DEBUG("\tfopt: '%s'\n", optstr);
- while (strlen(filestr) > 0) {
- if (rosh_ls_parse_opt(filestr, NULL)) {
- rosh_ls_arg(filestr, optarr);
- argpos++;
- }
- if (argpos < numargs)
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- else
- break;
+ ROSH_DEBUG2(" argc=%d; optind=%d\n", argc, optind);
+ if (optind >= argc)
+ rosh_ls_arg(".", optarr);
+ for (i = optind; i < argc; i++) {
+ rosh_ls_arg(argv[i], optarr);
}
} /* rosh_ls */
/* Simple directory listing; calls rosh_ls()
- * cmdstr command string to process
- * pwdstr Present Working Directory string
+ * argc Argument count
+ * argv Argument values
*/
-void rosh_dir(const char *cmdstr)
+void rosh_dir(int argc, char *argv[])
{
ROSH_DEBUG(" dir implemented as ls\n");
- rosh_ls(cmdstr);
+ rosh_ls(argc, argv);
} /* rosh_dir */
/* Page through a buffer string
* buf Buffer to page through
*/
-//HERE: minor pagination issue; sometimes prints 1 less than rows
-void rosh_more_buf(char *buf, int buflen, int rows, int cols)
+void rosh_more_buf(char *buf, int buflen, int rows, int cols, char *scrbuf)
{
char *bufp, *bufeol, *bufeol2; /* Pointer to current and next
end-of-line position in buffer */
int bufpos, bufcnt; /* current position, count characters */
- char scrbuf[ROSH_SBUF_SZ];
int inc;
int i, numln; /* Index, Number of lines */
+ int elpl; /* Extra lines per line read */
(void)cols;
@@ -799,10 +938,19 @@ void rosh_more_buf(char *buf, int buflen, int rows, int cols)
bufeol = buf + buflen;
i = numln;
} else {
- i += ((bufeol2 - bufeol) / cols);
- bufeol = bufeol2 + 1;
+ elpl = ((bufeol2 - bufeol - 1) / cols);
+ if (elpl < 0)
+ elpl = 0;
+ i += elpl;
+ ROSH_DEBUG2(" %d/%d ", elpl, i+1);
+ /* If this will not push too much, use it */
+ /* but if it's the first line, use it */
+ /* //HERE: We should probably snip the line off */
+ if ((i < numln) || (i == elpl))
+ bufeol = bufeol2 + 1;
}
}
+ ROSH_DEBUG2("\n");
bufcnt = bufeol - bufp;
printf("--(%d/%d @%d)\n", bufcnt, buflen, bufpos);
memcpy(scrbuf, bufp, bufcnt);
@@ -829,7 +977,7 @@ void rosh_more_buf(char *buf, int buflen, int rows, int cols)
/* Page through a single file using the open file stream
* fd File Descriptor
*/
-void rosh_more_fd(int fd, int rows, int cols)
+void rosh_more_fd(int fd, int rows, int cols, char *scrbuf)
{
struct stat fdstat;
int status;
@@ -851,7 +999,7 @@ void rosh_more_fd(int fd, int rows, int cols)
((int)fdstat.st_size - bufpos), f);
}
fclose(f);
- rosh_more_buf(buf, bufpos, rows, cols);
+ rosh_more_buf(buf, bufpos, rows, cols, scrbuf);
}
} else {
}
@@ -859,22 +1007,22 @@ void rosh_more_fd(int fd, int rows, int cols)
} /* rosh_more_fd */
/* Page through a file like the more command
- * cmdstr command string to process
- * ipwdstr Initial PWD
+ * argc Argument Count
+ * argv Argument Values
*/
-void rosh_more(const char *cmdstr)
+void rosh_more(int argc, char *argv[])
{
- int fd;
- char filestr[ROSH_PATH_SZ];
- int cmdpos;
+ int fd, i;
+/* char filestr[ROSH_PATH_SZ];
+ int cmdpos;*/
int rows, cols;
+ char *scrbuf;
+ int ret;
- ROSH_DEBUG("CMD: '%s'\n", cmdstr);
- /* Initialization */
- filestr[0] = 0;
- cmdpos = 0;
- if (getscreensize(1, &rows, &cols)) {
- ROSH_DEBUG("getscreensize() fail; fall back\n");
+ ROSH_DEBUG_ARGV_V(argc, argv);
+ ret = getscreensize(1, &rows, &cols);
+ if (ret) {
+ ROSH_DEBUG("getscreensize() fail(%d); fall back\n", ret);
ROSH_DEBUG("\tROWS='%d'\tCOLS='%d'\n", rows, cols);
/* If either fail, go under normal size, just in case */
if (!rows)
@@ -883,51 +1031,47 @@ void rosh_more(const char *cmdstr)
cols = 75;
}
ROSH_DEBUG("\tUSE ROWS='%d'\tCOLS='%d'\n", rows, cols);
+ /* 32 bit align beginning of row and over allocate */
+ scrbuf = malloc(rows * ((cols+3)&(INT_MAX - 3)));
+ if (!scrbuf)
+ return;
- /* skip the first word */
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
- if (strlen(filestr) > 0) {
+ if (argc) {
/* There is no need to mess up the console if we don't have a
file */
rosh_console_raw();
- while (strlen(filestr) > 0) {
- printf("--File = '%s'\n", filestr);
- fd = open(filestr, O_RDONLY);
+ for (i = 0; i < argc; i++) {
+ printf("--File = '%s'\n", argv[i]);
+ errno = 0;
+ fd = open(argv[i], O_RDONLY);
if (fd != -1) {
- rosh_more_fd(fd, rows, cols);
+ rosh_more_fd(fd, rows, cols, scrbuf);
close(fd);
} else {
- rosh_error(errno, "more", filestr);
+ rosh_error(errno, "more", argv[i]);
errno = 0;
}
- cmdpos = rosh_parse_sp_1(filestr, cmdstr, cmdpos);
}
rosh_console_std();
}
+ free(scrbuf);
} /* rosh_more */
/* Page a file with rewind
- * cmdstr command string to process
- * pwdstr Present Working Directory string
- * ipwdstr Initial PWD
+ * argc Argument Count
+ * argv Argument Values
*/
-void rosh_less(const char *cmdstr)
+void rosh_less(int argc, char *argv[])
{
printf(" less implemented as more (for now)\n");
- rosh_more(cmdstr);
+ rosh_more(argc, argv);
} /* rosh_less */
/* Show PWD
- * cmdstr command string to process
*/
-void rosh_pwd(const char *cmdstr)
+void rosh_pwd(void)
{
- int istr;
char pwdstr[ROSH_PATH_SZ];
- if (cmdstr)
- istr = 0;
- ROSH_DEBUG("CMD: '%s'\n", cmdstr);
errno = 0;
if (getcwd(pwdstr, ROSH_PATH_SZ)) {
printf("%s\n", pwdstr);
@@ -935,190 +1079,223 @@ void rosh_pwd(const char *cmdstr)
rosh_error(errno, "pwd", "");
errno = 0;
}
- istr = htonl(*(int *)pwdstr);
- ROSH_DEBUG2(" --%08X\n", istr);
} /* rosh_pwd */
-/* Reboot
+/* Reboot; use warm reboot if one of certain options set
+ * argc Argument count
+ * argv Argument values
*/
-void rosh_reboot(void)
+void rosh_reboot(int argc, char *argv[])
{
-// char cmdstr[ROSH_CMD_SZ];
-// printf
- syslinux_reboot(0);
+ int rtype = 0;
+ if (argc) {
+ /* For now, just use the first */
+ switch (argv[0][0]) {
+ case '1':
+ case 's':
+ case 'w':
+ rtype = 1;
+ break;
+ case '-':
+ switch (argv[0][1]) {
+ case '1':
+ case 's':
+ case 'w':
+ rtype = 1;
+ break;
+ }
+ break;
+ }
+ }
+ syslinux_reboot(rtype);
} /* rosh_reboot */
/* Run a boot string, calling syslinux_run_command
- * cmdstr command string to process
+ * argc Argument count
+ * argv Argument values
*/
-void rosh_run(const char *cmdstr)
+void rosh_run(int argc, char *argv[])
{
- int cmdpos;
- char *cmdptr;
+ char cmdstr[ROSH_CMD_SZ];
+ int len;
- cmdpos = 0;
- ROSH_DEBUG("CMD: '%s'\n", cmdstr);
- /* skip the first word */
- cmdpos = rosh_search_sp(cmdstr, cmdpos);
- /* skip spaces */
- cmdpos = rosh_search_nonsp(cmdstr, cmdpos);
- cmdptr = (char *)(cmdstr + cmdpos);
- printf("--run: '%s'\n", cmdptr);
- syslinux_run_command(cmdptr);
+ len = rosh_argcat(cmdstr, ROSH_CMD_SZ, argc, argv, 0);
+ if (len) {
+ printf("--run: '%s'\n", cmdstr);
+ syslinux_run_command(cmdstr);
+ } else {
+ printf(APP_NAME ":run: No arguments\n");
+ }
} /* rosh_run */
-/* Process a single command string and call handling function
- * cmdstr command string to process
+/* Process an argc/argv pair and call handling function
+ * argc Argument count
+ * argv Argument values
* ipwdstr Initial Present Working Directory string
* returns Whether to exit prompt
*/
-char rosh_command(const char *cmdstr, const char *ipwdstr)
+char rosh_command(int argc, char *argv[], const char *ipwdstr)
{
- char do_exit;
- char tstr[ROSH_CMD_SZ];
+ char do_exit = false;
int tlen;
- do_exit = false;
- ROSH_DEBUG("--cmd:'%s'\n", cmdstr);
- tlen = rosh_parse_sp_1(tstr, cmdstr, 0);
- switch (cmdstr[0]) {
+ tlen = strlen(argv[0]);
+ ROSH_DEBUG_ARGV_V(argc, argv);
+ switch (argv[0][0]) {
case 'e':
case 'E':
case 'q':
case 'Q':
- if ((strncasecmp("exit", tstr, tlen) == 0) ||
- (strncasecmp("quit", tstr, tlen) == 0))
- do_exit = true;
- else
- rosh_help(1, NULL);
+ switch (argv[0][1]) {
+ case 0:
+ case 'x':
+ case 'X':
+ case 'u':
+ case 'U':
+ if ((strncasecmp("exit", argv[0], tlen) == 0) ||
+ (strncasecmp("quit", argv[0], tlen) == 0))
+ do_exit = true;
+ else
+ rosh_help(1, argv[0]);
+ break;
+ case 'c':
+ case 'C':
+ if (strncasecmp("echo", argv[0], tlen) == 0)
+ rosh_pr_argv(argc - 1, &argv[1]);
+ else
+ rosh_help(1, argv[0]);
+ break;
+ default:
+ rosh_help(1, argv[0]);
+ }
break;
case 'c':
case 'C': /* run 'cd' 'cat' 'cfg' */
- switch (cmdstr[1]) {
+ switch (argv[0][1]) {
case 'a':
case 'A':
- if (strncasecmp("cat", tstr, tlen) == 0)
- rosh_cat(cmdstr);
+ if (strncasecmp("cat", argv[0], tlen) == 0)
+ rosh_cat(argc - 1, &argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'd':
case 'D':
- if (strncasecmp("cd", tstr, tlen) == 0)
- rosh_cd(cmdstr, ipwdstr);
+ if (strncasecmp("cd", argv[0], tlen) == 0)
+ rosh_cd(argc, argv, ipwdstr);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'f':
case 'F':
- if (strncasecmp("cfg", tstr, tlen) == 0)
+ if (strncasecmp("cfg", argv[0], tlen) == 0)
rosh_cfg();
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
default:
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
}
break;
case 'd':
case 'D': /* run 'dir' */
- if (strncasecmp("dir", tstr, tlen) == 0)
- rosh_dir(cmdstr);
+ if (strncasecmp("dir", argv[0], tlen) == 0)
+ rosh_dir(argc - 1, &argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'h':
case 'H':
case '?':
- if ((strncasecmp("help", tstr, tlen) == 0) || (tlen == 1))
- rosh_help(2, cmdstr);
+ if ((strncasecmp("help", argv[0], tlen) == 0) || (tlen == 1))
+ rosh_help(2, argv[1]);
else
rosh_help(1, NULL);
break;
case 'l':
case 'L': /* run 'ls' 'less' */
- switch (cmdstr[1]) {
+ switch (argv[0][1]) {
case 0:
- case ' ':
case 's':
case 'S':
- if (strncasecmp("ls", tstr, tlen) == 0)
- rosh_ls(cmdstr);
+ if (strncasecmp("ls", argv[0], tlen) == 0)
+ rosh_ls(argc, argv);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'e':
case 'E':
- if (strncasecmp("less", tstr, tlen) == 0)
- rosh_less(cmdstr);
+ if (strncasecmp("less", argv[0], tlen) == 0)
+ rosh_less(argc - 1, &argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
default:
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
}
break;
case 'm':
case 'M':
- switch (cmdstr[1]) {
+ switch (argv[0][1]) {
case 'a':
case 'A':
- if (strncasecmp("man", tstr, tlen) == 0)
- rosh_help(2, cmdstr);
+ if (strncasecmp("man", argv[0], tlen) == 0)
+ rosh_help(2, argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'o':
case 'O':
- if (strncasecmp("more", tstr, tlen) == 0)
- rosh_more(cmdstr);
+ if (strncasecmp("more", argv[0], tlen) == 0)
+ rosh_more(argc - 1, &argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
default:
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
}
break;
case 'p':
case 'P': /* run 'pwd' */
- if (strncasecmp("pwd", tstr, tlen) == 0)
- rosh_pwd(cmdstr);
+ if (strncasecmp("pwd", argv[0], tlen) == 0)
+ rosh_pwd();
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'r':
case 'R': /* run 'run' */
- switch (cmdstr[1]) {
+ switch (argv[0][1]) {
case 0:
- case ' ':
case 'e':
case 'E':
- if (strncasecmp("reboot", tstr, tlen) == 0)
- rosh_reboot();
+ if (strncasecmp("reboot", argv[0], tlen) == 0)
+ rosh_reboot(argc - 1, &argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 'u':
case 'U':
- if (strncasecmp("run", tstr, tlen) == 0)
- rosh_run(cmdstr);
+ if (strncasecmp("run", argv[0], tlen) == 0)
+ rosh_run(argc - 1, &argv[1]);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
+ default:
+ rosh_help(1, argv[0]);
}
break;
case 'v':
case 'V':
- if (strncasecmp("version", tstr, tlen) == 0)
- rosh_version();
+ if (strncasecmp("version", argv[0], tlen) == 0)
+ rosh_version(1);
else
- rosh_help(1, NULL);
+ rosh_help(1, argv[0]);
break;
case 0:
case '\n':
break;
default:
- rosh_help(1, NULL);
- } /* switch(cmdstr[0]) */
+ rosh_help(1, argv[0]);
+ } /* switch(argv[0][0]) */
return do_exit;
} /* rosh_command */
@@ -1127,29 +1304,29 @@ char rosh_command(const char *cmdstr, const char *ipwdstr)
* icmdstr Initial command line string
* returns Exit status
*/
-int rosh_prompt(const char *icmdstr)
+int rosh_prompt(int iargc, char *iargv[])
{
int rv;
char cmdstr[ROSH_CMD_SZ];
char ipwdstr[ROSH_PATH_SZ];
char do_exit;
- char *c;
+ char **argv;
+ int argc;
rv = 0;
do_exit = false;
if (!getcwd(ipwdstr, ROSH_PATH_SZ))
strcpy(ipwdstr, "./");
- if (icmdstr[0] != '\0')
- do_exit = rosh_command(icmdstr, ipwdstr);
+ if (iargc > 1)
+ do_exit = rosh_command(iargc - 1, &iargv[1], ipwdstr);
while (!(do_exit)) {
/* Extra preceeding newline */
printf("\nrosh: ");
/* Read a line from console */
if (fgets(cmdstr, ROSH_CMD_SZ, stdin)) {
- /* remove newline from input string */
- c = strchr(cmdstr, '\n');
- *c = 0;
- do_exit = rosh_command(cmdstr, ipwdstr);
+ argc = rosh_str2argv(&argv, cmdstr);
+ do_exit = rosh_command(argc, argv, ipwdstr);
+ rosh_free_argv(&argv);
} else {
do_exit = false;
}
@@ -1160,19 +1337,21 @@ int rosh_prompt(const char *icmdstr)
int main(int argc, char *argv[])
{
int rv;
- char cmdstr[ROSH_CMD_SZ];
/* Initialization */
rv = 0;
rosh_console_std();
- if (argc != 1) {
- rv = rosh_argcat(cmdstr, argc, argv, 1);
- } else {
- rosh_version();
+ if (argc == 1) {
+ rosh_version(0);
print_beta();
- cmdstr[0] = '\0';
+ } else {
+#ifdef DO_DEBUG
+ char cmdstr[ROSH_CMD_SZ];
+ rosh_argcat(cmdstr, ROSH_CMD_SZ, argc, argv, 1);
+ ROSH_DEBUG("arg='%s'\n", cmdstr);
+#endif
}
- rv = rosh_prompt(cmdstr);
- printf("--Exiting '%s'\n", APP_NAME);
+ rv = rosh_prompt(argc, argv);
+ printf("--Exiting '" APP_NAME "'\n");
return rv;
}
diff --git a/com32/rosh/rosh.h b/com32/rosh/rosh.h
index a8edda6a..cabf556a 100644
--- a/com32/rosh/rosh.h
+++ b/com32/rosh/rosh.h
@@ -32,29 +32,36 @@
#include <stdbool.h> /* macro: true false */
#include <string.h> /* strcpy() strlen() memcpy() strchr() */
#include <sys/types.h>
+#include <limits.h>
#include <sys/stat.h> /* fstat() */
#include <fcntl.h> /* open(); open mode macros */
#include <dirent.h> /* fdopendir() opendir() readdir() closedir() DIR */
-#include <unistd.h> /* getcwd() */
+#include <unistd.h> /* getcwd() getopt() */
#include <errno.h> /* errno; error macros */
#include <netinet/in.h> /* For htonl/ntohl/htons/ntohs */
#include <ctype.h> /* isspace() */
#include <getkey.h>
-#include <consoles.h>
+#include <consoles.h> /* console_ansi_raw() console_ansi_std() */
+// #include <getopt.h> /* getopt_long() */
#ifdef DO_DEBUG
# define ROSH_DEBUG printf
+# define ROSH_DEBUG_ARGV_V rosh_pr_argv_v
/* define ROSH_DEBUG(f, ...) printf (f, ## __VA_ARGS__) */
# ifdef DO_DEBUG2
# define ROSH_DEBUG2 printf
+# define ROSH_DEBUG2_ARGV_V rosh_pr_argv_v
# else /* DO_DEBUG2 */
/* This forces a format argument into the function call */
# define ROSH_DEBUG2(f, ...) ((void)0)
+# define ROSH_DEBUG2_ARGV_V(argc, argv) ((void)0)
# endif /* DO_DEBUG2 */
#else /* DO_DEBUG */
# define ROSH_DEBUG(f, ...) ((void)0)
+# define ROSH_DEBUG_ARGV_V(argc, argv) ((void)0)
# define ROSH_DEBUG2(f, ...) ((void)0)
+# define ROSH_DEBUG2_ARGV_V(argc, argv) ((void)0)
#endif /* DO_DEBUG */
#ifdef __COM32__
@@ -89,8 +96,17 @@ int stat(const char *pathname, struct stat *buf)
return ret;
}
+int rosh_get_env_ver(char *dest, size_t n)
+{
+ const struct syslinux_version *slv = syslinux_version();
+ strncpy(dest, slv->version_string, n);
+ return 0;
+}
+
#else
# include <termios.h>
+# include <sys/ioctl.h>
+# include <sys/utsname.h>
# define ROSH_IS_COM32 0
static inline char *syslinux_config_file(void)
@@ -98,19 +114,43 @@ static inline char *syslinux_config_file(void)
return "";
}
+int rosh_get_env_ver(char *dest, size_t n)
+{
+ int ret, len;
+ struct utsname env;
+ ret= uname(&env);
+ if (ret >= 0) {
+ strncpy(dest, env.sysname, n);
+ len = strlen(dest);
+ strncpy(dest + len, " ", (n - len));
+ len = strlen(dest);
+ strncpy(dest + len, env.release, (n - len));
+ }
+ return ret;
+}
+
static inline int getscreensize(int fd, int *rows, int *cols)
{
char *str;
int rv;
- *rows = 0;
- *cols = 0;
+ struct winsize ws;
+ if (rows)
+ *rows = 0;
+ if (cols)
+ *cols = 0;
+ str = NULL;
if (fd == 1) {
- if (rows) {
+ ioctl(0, TIOCGWINSZ, &ws);
+ if (rows)
+ *rows = ws.ws_row;
+ if (cols)
+ *cols = ws.ws_col;
+ if (rows && !*rows) {
str = getenv("LINES");
if (str)
*rows = atoi(str);
}
- if (cols) {
+ if (cols && !*cols) {
str = getenv("COLUMNS");
if (str)
*cols = atoi(str);
@@ -201,6 +241,10 @@ const char rosh_beta_str[] =
const char rosh_cd_norun_str[] =
" -- cd (Change Directory) not implemented for use with run and exit.\n";
+const char rosh_help_cd_str[] = "cd Change directory\n\
+ with no argument, return to original directory from entry to rosh\n\
+ with one argument, change to that directory";
+
const char rosh_help_ls_str[] = "ls List contents of current directory\n\
-l Long format\n\
-i Inode; print Inode of file\n\
@@ -225,4 +269,6 @@ const char rosh_help_str2[] =
const char rosh_help_str_adv[] = "No additional help available for '%s'";
+const char rosh_ls_opt_str[] = "lFi";
+
#endif /* Not ROSH_H */
diff --git a/core/diskstart.inc b/core/diskstart.inc
index 642f37e5..81e983ae 100644
--- a/core/diskstart.inc
+++ b/core/diskstart.inc
@@ -180,8 +180,11 @@ harddisk:
mov dx,[di-76-10] ; Original DS
mov si,[di-76-12] ; Original SI
shr si,4
+ jz .no_partition ; SI == 0 -> assume no partition
add dx,si
- cmp dx,PartInfo >> 4
+ cmp dx,1024 ; DS:SI < 1K (inside the IVT)?
+ jb .no_partition
+ cmp dx,PartInfo >> 4 ; DS:SI in overwritten memory?
jae .no_partition
test byte [di-76],7Fh ; Sanity check: "active flag" should
jnz .no_partition ; be 00 or 80
diff --git a/core/fs/diskio.c b/core/fs/diskio.c
index 481b59b0..38d3da35 100644
--- a/core/fs/diskio.c
+++ b/core/fs/diskio.c
@@ -163,8 +163,6 @@ static int edd_rdwr_sectors(struct disk *disk, void *buf,
memset(&reset, 0, sizeof reset);
- ireg.edx.b[0] = disk->disk_number;
-
lba += disk->part_start;
while (count) {
chunk = count;
diff --git a/core/fs/iso9660/iso9660.c b/core/fs/iso9660/iso9660.c
index 8f30fed4..7def2f73 100644
--- a/core/fs/iso9660/iso9660.c
+++ b/core/fs/iso9660/iso9660.c
@@ -63,6 +63,8 @@ static void iso_mangle_name(char *dst, const char *src)
if ( (*(dst-1) != '.') && (*(dst-1) != '/') )
break;
+ if ((dst[-1] == '/') && ((dst - 1) == p))
+ break;
dst --;
i ++;
diff --git a/core/fs/lib/mangle.c b/core/fs/lib/mangle.c
index 813099fb..8c2077a9 100644
--- a/core/fs/lib/mangle.c
+++ b/core/fs/lib/mangle.c
@@ -36,6 +36,8 @@ void generic_mangle_name(char *dst, const char *src)
break;
if (dst[-1] != '/')
break;
+ if ((dst[-1] == '/') && ((dst - 1) == p))
+ break;
dst--;
i++;
diff --git a/core/fs/pxe/dnsresolv.c b/core/fs/pxe/dnsresolv.c
index 2b263fad..641ea389 100644
--- a/core/fs/pxe/dnsresolv.c
+++ b/core/fs/pxe/dnsresolv.c
@@ -215,7 +215,7 @@ uint32_t dns_resolv(const char *name)
if (!dots) {
p--; /* Remove final null */
/* Uncompressed DNS label set so it ends in null */
- strcpy(p, LocalDomain);
+ p = stpcpy(p, LocalDomain);
}
/* Fill the DNS query packet */
diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index 211dd639..40248994 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -642,8 +642,22 @@ static uint32_t pxe_getfssec(struct file *file, char *buf,
* @out: the lenght of this file, stores in file->file_len
*
*/
+static void __pxe_searchdir(const char *filename, struct file *file);
+extern uint16_t PXERetry;
+
static void pxe_searchdir(const char *filename, struct file *file)
{
+ int i = PXERetry;
+
+ do {
+ dprintf("PXE: file = %p, retries left = %d: ", file, i);
+ __pxe_searchdir(filename, file);
+ dprintf("%s\n", file->inode ? "ok" : "failed");
+ } while (!file->inode && i--);
+}
+
+static void __pxe_searchdir(const char *filename, struct file *file)
+{
struct fs_info *fs = file->fs;
struct inode *inode;
struct pxe_pvt_inode *socket;
diff --git a/core/keywords b/core/keywords
index c289ae29..7f585b48 100644
--- a/core/keywords
+++ b/core/keywords
@@ -16,6 +16,7 @@ linux
boot
bss
pxe
+pxeretry
fdimage
comboot
com32
diff --git a/core/parseconfig.inc b/core/parseconfig.inc
index 00e2163e..ec400a6f 100644
--- a/core/parseconfig.inc
+++ b/core/parseconfig.inc
@@ -464,6 +464,8 @@ AllowImplicit dw 1 ; Allow implicit kernels
AllowOptions dw 1 ; User-specified options allowed
IncludeLevel dw 1 ; Nesting level
DefaultLevel dw 0 ; The current level of default
+ global PXERetry
+PXERetry dw 0 ; Extra PXE retries
VKernel db 0 ; Have we seen any "label" statements?
%if IS_PXELINUX
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 95087c80..5341db38 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -364,6 +364,16 @@ pxenv:
pushfd
pushad
+ ; We may be removing ourselves from memory
+ cmp bx,0073h ; PXENV_RESTART_TFTP
+ jz .disable_timer
+ cmp bx,00E5h ; gPXE PXENV_FILE_EXEC
+ jnz .store_stack
+
+.disable_timer:
+ call timer_cleanup
+
+.store_stack:
mov [cs:PXEStack],sp
mov [cs:PXEStack+2],ss
lss sp,[cs:InitStack]
@@ -390,6 +400,17 @@ pxenv:
; This clobbers the AX return, but we already saved it into
; the PXEStatus variable.
popad
+
+ ; If the call failed, it could return.
+ cmp bx,0073h
+ jz .enable_timer
+ cmp bx,00E5h
+ jnz .pop_flags
+
+.enable_timer:
+ call timer_init
+
+.pop_flags:
popfd ; Restore flags (incl. IF, DF)
ret
diff --git a/core/syslinux.ld b/core/syslinux.ld
index 466b450e..c390f347 100644
--- a/core/syslinux.ld
+++ b/core/syslinux.ld
@@ -33,7 +33,7 @@ SECTIONS
/* "Early" sections (before the load) */
. = 0x1000;
- .earlybss : {
+ .earlybss (NOLOAD) : {
__earlybss_start = .;
*(.earlybss)
__earlybss_end = .;
@@ -42,7 +42,7 @@ SECTIONS
__earlybss_dwords = (__earlybss_len + 3) >> 2;
. = ALIGN(4);
- .bss16 : {
+ .bss16 (NOLOAD) : {
__bss16_start = .;
*(.bss16)
__bss16_end = .;
diff --git a/core/writedec.inc b/core/writedec.inc
index bfac0997..19e47968 100644
--- a/core/writedec.inc
+++ b/core/writedec.inc
@@ -37,6 +37,7 @@ writedec_common:
xor cx,cx ; Number of digits
.cloop:
+ mov edx,0
div ebx
inc cx
push dx
@@ -53,5 +54,5 @@ writedec_common:
popad
ret
-writechr:
- ret
+; writechr:
+; ret
diff --git a/doc/extlinux.txt b/doc/extlinux.txt
index 6974a517..9b267018 100644
--- a/doc/extlinux.txt
+++ b/doc/extlinux.txt
@@ -24,6 +24,8 @@ slight modifications.
2. The configuration file is called "extlinux.conf", and is expected
to be found in the same directory as extlinux is installed in.
+ Since 4.00 "syslinux.cfg" is also tried if "extlinux.conf" is not
+ found.
3. Pathnames can be absolute or relative; if absolute (with a leading
diff --git a/doc/syslinux.txt b/doc/syslinux.txt
index 51d1332c..5b27a6eb 100644
--- a/doc/syslinux.txt
+++ b/doc/syslinux.txt
@@ -106,24 +106,25 @@ which requires root privilege.
++++ CONFIGURATION FILE ++++
+All options here apply to PXELINUX, ISOLINUX and EXTLINUX as well as
+SYSLINUX unless otherwise noted. See the respective .txt files.
+
All the configurable defaults in SYSLINUX can be changed by putting a
file called "syslinux.cfg" in the root directory of the boot disk.
-This is a text file in either UNIX or DOS format, containing one or
-more of the following items (case is insensitive for keywords; upper
-case is used here to indicate that a word should be typed verbatim):
-
Starting with version 3.35, the configuration file can also be in
either the /boot/syslinux or /syslinux directories (searched in that
order.) If that is the case, then all filenames are assumed to be
relative to that same directory, unless preceded with a slash or
backslash.
-All options here applies to PXELINUX, ISOLINUX and EXTLINUX as well as
-SYSLINUX unless otherwise noted. See the respective .txt files.
+The configuration file is a text file in either UNIX or DOS format,
+containing one or more of the following items, each on its own line with
+optional leading whitespace. Case is insensitive for keywords; upper
+case is used here to indicate that a word should be typed verbatim.
-# comment
- A comment line. The whitespace after the hash mark is mandatory.
+#comment
+ A comment line.
INCLUDE filename
Inserts the contents of another file at this point in the
diff --git a/extlinux/main.c b/extlinux/main.c
index 002cecd9..30422c2d 100755
--- a/extlinux/main.c
+++ b/extlinux/main.c
@@ -100,6 +100,32 @@ struct geometry_table {
struct hd_geometry g;
};
+static int sysfs_get_offset(int devfd, unsigned long *start)
+{
+ struct stat st;
+ char sysfs_name[128];
+ FILE *f;
+ int rv;
+
+ if (fstat(devfd, &st))
+ return -1;
+
+ if ((size_t)snprintf(sysfs_name, sizeof sysfs_name,
+ "/sys/dev/block/%u:%u/start",
+ major(st.st_dev), minor(st.st_dev))
+ >= sizeof sysfs_name)
+ return -1;
+
+ f = fopen(sysfs_name, "r");
+ if (!f)
+ return -1;
+
+ rv = fscanf(f, "%lu", start);
+ fclose(f);
+
+ return (rv == 1) ? 0 : -1;
+}
+
/* Standard floppy disk geometries, plus LS-120. Zipdisk geometry
(x/64/32) is the final fallback. I don't know what LS-240 has
as its geometry, since I don't have one and don't know anyone that does,
@@ -123,24 +149,25 @@ int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo)
struct loop_info li;
struct loop_info64 li64;
const struct geometry_table *gp;
+ int rv = 0;
memset(geo, 0, sizeof *geo);
if (!ioctl(devfd, HDIO_GETGEO, &geo)) {
- return 0;
+ goto ok;
} else if (!ioctl(devfd, FDGETPRM, &fd_str)) {
geo->heads = fd_str.head;
geo->sectors = fd_str.sect;
geo->cylinders = fd_str.track;
geo->start = 0;
- return 0;
+ goto ok;
}
/* Didn't work. Let's see if this is one of the standard geometries */
for (gp = standard_geometries; gp->bytes; gp++) {
if (gp->bytes == totalbytes) {
memcpy(geo, &gp->g, sizeof *geo);
- return 0;
+ goto ok;
}
}
@@ -153,19 +180,25 @@ int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo)
geo->cylinders = totalbytes / (geo->heads * geo->sectors << SECTOR_SHIFT);
geo->start = 0;
- if (!opt.sectors && !opt.heads)
+ if (!opt.sectors && !opt.heads) {
fprintf(stderr,
"Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n"
" (on hard disks, this is usually harmless.)\n",
geo->heads, geo->sectors);
+ rv = 1; /* Suboptimal result */
+ }
+ok:
/* If this is a loopback device, try to set the start */
if (!ioctl(devfd, LOOP_GET_STATUS64, &li64))
geo->start = li64.lo_offset >> SECTOR_SHIFT;
else if (!ioctl(devfd, LOOP_GET_STATUS, &li))
geo->start = (unsigned int)li.lo_offset >> SECTOR_SHIFT;
+ else if (!sysfs_get_offset(devfd, &geo->start)) {
+ /* OK */
+ }
- return 1;
+ return rv;
}
/*
diff --git a/libinstaller/syslxopt.c b/libinstaller/syslxopt.c
index 9b42c66f..7ceb3ba2 100644
--- a/libinstaller/syslxopt.c
+++ b/libinstaller/syslxopt.c
@@ -68,7 +68,7 @@ const struct option long_options[] = {
{0, 0, 0, 0}
};
-const char short_options[] = "t:fid:UuzS:H:rvho:OM:ma";
+const char short_options[] = "t:fid:UuzsS:H:rvho:OM:ma";
void __attribute__ ((noreturn)) usage(int rv, enum syslinux_mode mode)
{
diff --git a/man/syslinux.1 b/man/syslinux.1
index 6babfa41..af44979b 100644
--- a/man/syslinux.1
+++ b/man/syslinux.1
@@ -140,11 +140,6 @@ first "label" command.) The default for \fIimage\fP is the same as \fIlabel\fP,
and if no "append" is given the default is to use the global entry (if any).
Use "append -" to use no options at all. Up to 128 "label" entries are
permitted.
-.TP
-.B Notes:
-Labels are mangled as if they were DOS filenames, and must be unique after
-mangling. For example, two labels "v2.1.30" and "v2.1.31" will not be
-distinguishable.
.IP
The "image" doesn't have to be a Linux kernel; it can be a boot sector or a
COMBOOT file (see below.)
diff --git a/memdisk/setup.c b/memdisk/setup.c
index 3f69cd35..43151898 100644
--- a/memdisk/setup.c
+++ b/memdisk/setup.c
@@ -119,7 +119,7 @@ static const char *getcmditem(const char *what)
*/
#define UNZIP_ALIGN 512
-extern void _end; /* Symbol signalling end of data */
+extern const char _end[]; /* Symbol signalling end of data */
void unzip_if_needed(uint32_t * where_p, uint32_t * size_p)
{
@@ -171,8 +171,8 @@ void unzip_if_needed(uint32_t * where_p, uint32_t * size_p)
? 0xFFFFFFFF : (uint32_t) ranges[i + 1].start);
/* Make sure we don't overwrite ourselves */
- if (startrange < (uint32_t) & _end)
- startrange = (uint32_t) & _end;
+ if (startrange < (uint32_t) _end)
+ startrange = (uint32_t) _end;
/* Allow for alignment */
startrange =
diff --git a/modules/Makefile b/modules/Makefile
index f3183641..9b50bb23 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -19,7 +19,7 @@ include $(topdir)/MCONFIG.embedded
INCLUDES = -I$(com32)/include
-BINS = pxechain.com poweroff.com int18.com
+BINS = pxechain.com poweroff.com int18.com ver.com
all: $(BINS)
diff --git a/modules/ver.asm b/modules/ver.asm
new file mode 100644
index 00000000..8ef63faf
--- /dev/null
+++ b/modules/ver.asm
@@ -0,0 +1,606 @@
+; ****************************************************************************
+;
+; ver.asm
+;
+; A COMBOOT/DOS COM program to display the version of the system
+; (Syslinux, DOS, or DRMK)
+;
+; Copyright (C) 2009-2010 Gene Cumm
+;
+; 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., 53 Temple Place Ste 330,
+; Boston MA 02111-1307, USA; either version 2 of the License, or
+; (at your option) any later version; incorporated herein by reference.
+;
+; ****************************************************************************
+
+; %define DEBUG
+
+ section .text
+ org 0x100
+
+_start:
+ call crlf
+ mov si,info_str
+ call writestr
+ call getdosver
+ call chkprn_dosver
+ jnz .end
+ call chkprn_syslinux
+ call crlf
+.end:
+; pop ds
+ ret
+
+
+; chkprn_syslinux
+chkprn_syslinux:
+%ifdef DEBUG
+ mov si,may_sysl_str
+ call writestr
+%endif
+ cmp eax,59530000h
+ jne .end
+ cmp ebx,4C530000h
+ jne .end
+ cmp ecx,4E490000h
+ jne .end
+ cmp edx,58550000h
+ jne .end
+.is_syslinux:
+ pushad
+%ifdef DEBUG
+ mov si,is_sysl_str
+ call writestr
+%endif
+.get_sysl_ver:
+ mov ax,0001h
+ int 22h
+; AX=0001h [2.00] Get Version
+;
+; Input: AX 0001h
+; Output: AX number of INT 22h API functions available
+; CH Syslinux major version number
+; CL Syslinux minor version number
+; DL Syslinux derivative ID (e.g. 32h = PXELINUX)
+; ES:SI Syslinux version string
+; ES:DI Syslinux copyright string
+%ifdef DEBUG
+ push si
+ push cs
+ pop ds
+ mov si,gotver_str
+ call writestr
+ pop si
+%endif
+
+.prn_ver_str:
+ mov si,syslban_str
+ call writestr
+ push ds
+ push es
+ pop ds
+ call writestr
+ call crlf
+ pop ds
+.prn_var:
+ cmp dl,31h
+ je .var_sysl
+ cmp dl,32h
+ je .var_pxel
+ cmp dl,33h
+ je .var_isol
+ cmp dl,34h
+ je .var_extl
+ jmp .var_unk
+.var_sysl:
+ mov si,sysl_str
+ call writestr
+ jmp .prn_lnxsp
+.var_pxel:
+ mov si,pxel_str
+ call writestr
+ jmp .prn_lnxsp
+.var_isol:
+ mov si,isol_str
+ call writestr
+ jmp .prn_lnxsp
+.var_extl:
+ mov si,extl_str
+ call writestr
+; jmp .prn_lnxsp
+.prn_lnxsp:
+ mov si,linsp_str
+ call writestr
+ jmp .prn_ver
+.var_unk:
+ mov si,unkvar_str
+ call writestr
+.prn_ver:
+%ifdef DEBUG
+ push si
+ push cs
+ pop ds
+ mov si,prn_ver_str
+ call writestr
+ pop si
+%endif
+.prn_ver_maj:
+ mov al,ch
+ call writedecb
+ mov dl,'.'
+ call writechr_dl
+.prn_ver_min:
+ mov al,cl
+; cmp al,10
+; jae .min_wri
+; mov al,'0'
+; call writechr
+; mov al,cl
+; .min_wri:
+; call writedecb
+ call writedecb2
+
+.end_prn:
+ popad
+.end:
+ ret
+
+; chkprn_dosver Check and print DOS version;
+; Input Data from INT21 AH=30h
+; AH Major version of DOS or 0
+; AL Minor Version
+; BH DOS type
+; BL:CX 24-bit OEM serial number
+; Return
+; ZF Unset if DOS, Set if not DOS (AX=0)
+chkprn_dosver:
+ and ax,ax ; cmp ax,0
+ jz .end
+.is_dos:
+ push eax
+ push edx
+ push si
+%ifdef DEBUG
+ mov si,is_dos_str
+ call writestr
+ call crlf
+ call prnreg_gp_l
+ call crlf
+%endif
+.var_prn:
+ cmp bh,0
+ je .var_pcdos
+ cmp bh,0FFh
+ je .var_msdos
+ cmp bh,0FDh
+ je .var_freedos
+ cmp bh,0DEh
+ je .var_drmk
+ jmp .var_unk
+.var_pcdos:
+ mov si,pcdos_str
+ call writestr
+ jmp .var_end
+.var_msdos:
+ mov si,msdos_str
+ call writestr
+ jmp .var_end
+.var_freedos:
+ mov si,freedos_str
+ call writestr
+ jmp .var_end
+.var_drmk:
+ mov si,drmk_str
+ call writestr
+ jmp .var_end
+.var_unk:
+ mov si,unkdos_str
+ call writestr
+ mov si,spparen_str
+ call writestr
+ push eax
+ mov al,bh
+ call writehex2
+ pop eax
+ mov si,parensp_str
+ call writestr
+; jmp .var_end
+.var_end:
+ call prn_dosver_num
+ call crlf
+.subver:
+ pop si
+ pop edx
+ pop eax
+ cmp bh,0FFh
+ je .msdos_ver
+ cmp bh,0DEh
+ jne .end_ver
+.drmk_ver:
+ call getprn_drmkver
+; jmp .end_ver ; DRMK returns Extended/True DOS
+.msdos_ver:
+ cmp al,5
+ jb .end_ver
+ call getprn_msdosver
+.end_ver:
+ and ax,ax ; Unset ZF
+.end:
+ ret
+
+; prn_dosver_num Print the numerical DOS version
+; Input Data from INT21 AH=30h
+; AH Major version of DOS or 0
+; AL Minor Version
+; BH DOS type
+; BL:CX 24-bit OEM serial number
+prn_dosver_num:
+ push eax
+ push edx
+ push si
+ pushfd
+.vmaj_prn:
+ call writedecb
+; call writehex2
+ mov dl,'.'
+ call writechr_dl
+.vmin_prn:
+ mov al,ah
+ call writedecb
+; call writehex2
+.serial: ; Skip if 0
+ cmp bl,0
+ jne .ser_start
+ cmp cx,0
+ je .end
+.ser_start:
+ mov si,spparen_str
+ call writestr
+ mov si,zerox_str
+ call writestr
+.ser_bl:
+ mov al,bl
+ call writehex2
+.ser_cx:
+ mov ax,cx
+ call writehex4
+.serial_end:
+ mov si,parensp_str
+ call writestr
+.end:
+ popfd
+ pop si
+ pop edx
+ pop eax
+ ret
+
+; getdosver Get the DOS version
+; Return Version or 0 + SYSLINUX message
+; EAX Part 1
+; EBX Part 2
+; ECX Part 3
+; EDX Part 4
+getdosver:
+ mov ecx,0
+ mov edx,0
+ mov ebx,0
+ mov eax,3000h
+ int 21h
+ ret
+
+; getmsdosver Get the Extended MS-DOS version
+; Returns Version
+; EAX Part 1
+; EBX Part 2
+; ECX Part 3
+; EDX Part 4
+getmsdosver:
+ mov ecx,0
+ mov edx,0
+ mov ebx,0
+ mov eax,3306h
+ int 21h
+ ret
+
+; getprn_msdosver
+getprn_msdosver:
+ pushad
+ pushfd
+ call getmsdosver
+%ifdef DEBUG
+ call prnreg_gp_l
+ call crlf
+%endif
+ mov si,dosext_str
+ call writestr
+ mov eax,ebx
+ mov ebx,0
+ mov ecx,edx
+ call prn_dosver_num
+.end:
+ popfd
+ popad
+ ret
+
+; getdrmkver: Get the DRMK-specifc OS version
+; Returns Version
+; AX OS Version
+; DX Patch Version
+getdrmkver:
+ mov ax,4452h
+ int 21h
+ ret
+
+; getdrmkver: Get the DRMK-specifc Kernel build info
+; Returns Kernel build info
+; AX Kernel build date in DOS 16-bit format
+; [ES:BX] Kernel private data
+getdrmkbld:
+ mov ax,4458h
+ int 21h
+ ret
+
+; getprn_drmkver: Get/Print DRMK-specific Version info
+getprn_drmkver:
+ pushad
+ pushfd
+.getver:
+ call getdrmkver
+.prnosver: ; "OS Version"
+ mov si,osver_str
+ call writestr
+ mov si,zerox_str
+ call writestr
+; mov ax,0
+ call writehex4
+ call crlf
+.prnpatchver: ; "Patch Version"
+ mov si,patchver_str
+ call writestr
+ mov si,zerox_str
+ call writestr
+ mov ax,dx
+ call writehex4
+ call crlf
+.getbld:
+ call getdrmkbld
+.prnkernbld: ; "Kernel Build Date"
+ mov si,kernbld_str
+ call writestr
+ call writedate_ax
+ call crlf
+.prnkernprvaddr:
+ mov si,prvdat_str
+ call writestr
+ mov ax,es
+ call writehex4
+ mov dl,':'
+ call writechr_dl
+ mov ax,bx
+ call writehex4
+ call crlf
+%ifdef DEBUG
+.prnkernprv:
+ mov di,[es:bx]
+ mov ax,di
+ call writehex4
+ call crlf
+ mov si,2
+ mov cx,8
+.prnkernprv2:
+ push cx
+ mov cx,8
+.prnkernprv1:
+ mov eax,[es:bx+si]
+ call writehex8
+ cmp cx,1
+ jbe .prnkern0dash
+ mov ax,'-'
+ call writechr
+.prnkern0dash:
+ add si,4
+ sub di,4
+ cmp di,0
+ jbe .prnkernprvend
+ loop .prnkernprv1
+ call crlf
+ pop cx
+ loop .prnkernprv2
+ jmp .end
+.prnkernprvend:
+ pop cx
+%endif
+.end:
+ popfd
+ popad
+ ret
+
+;writedate_ax Write a date in AX in ISO8601 big endian format
+; Input
+; AX Date in 16-bit DOS format
+; 2006-01-11
+; 0011010 0001 01011
+writedate_ax:
+ pushad
+ pushfd
+ mov dx,ax
+%ifdef DEBUG
+ call writehex4
+ call crlf
+%endif
+.year:
+ shr ax,9
+ add ax,1980
+ call writedecw
+ mov al,'-'
+ call writechr
+ mov ax,dx
+.month:
+ shr ax,5
+ and ax,0Fh
+; cmp ax,10
+; jae .month_wri
+; mov cx,ax
+; mov ax,'0'
+; call writechr
+; mov ax,cx
+; .month_wri:
+; call writedecb
+ call writedecb2
+ mov al,'-'
+ call writechr
+ mov ax,dx
+.day:
+ and ax,1Fh
+; cmp ax,10
+; jae .day_wri
+; mov cx,ax
+; mov ax,'0'
+; call writechr
+; mov ax,cx
+; .day_wri:
+; call writedecb
+ call writedecb2
+.end:
+ popfd
+ popad
+ ret
+
+; writechr_dl Write a character to the console saving AX
+; Input
+; DL character to write
+writechr_dl:
+ push ax
+ mov ah,02h
+ int 21h
+.end:
+ pop ax
+ ret
+
+; writechr_al Write a character to the console saving AX
+; Input
+; AL character to write
+writechr:
+writechr_al:
+ push dx
+ mov dl,al
+ call writechr_dl
+.end: pop dx
+ ret
+
+; writedecb[23] Print byte as fixed width
+; Input
+; AL number to write
+writedecb3:
+ pushfd
+ cmp al,100
+ jae .skip
+ push ax
+ mov ax,'0'
+ call writechr
+ pop ax
+.skip: popfd
+writedecb2:
+ pushfd
+ cmp al,10
+ jae .skip
+ push ax
+ mov ax,'0'
+ call writechr
+ pop ax
+.skip: popfd
+ call writedecb
+ ret
+
+
+; prnreg_gp_l Dump GP registers (Long)
+prnreg_gp_l:
+ push eax
+ push si
+ call crlf
+ mov si,sp2_str
+ call writestr
+ mov si,eax_str
+ call writestr
+ call writehex8
+ mov si,sp2_str
+ call writestr
+ mov si,ecx_str
+ call writestr
+ mov eax,ecx
+ call writehex8
+ mov si,sp2_str
+ call writestr
+ mov si,edx_str
+ call writestr
+ mov eax,edx
+ call writehex8
+ mov si,sp2_str
+ call writestr
+ mov si,ebx_str
+ call writestr
+ mov eax,ebx
+ call writehex8
+ call crlf
+ pop si
+ pop eax
+.end:
+ ret
+
+; is_zf
+is_zf:
+ push si
+ jz .true
+.false:
+ mov si,zero_not_str
+ call writestr
+ jmp .end
+.true:
+ mov si,zero_is_str
+ call writestr
+.end:
+ pop si
+ ret
+
+%include "../core/macros.inc" ; CR/LF
+%include "../core/writestr.inc" ; String output
+%include "../core/writehex.inc" ; Hexadecimal output
+%include "../core/writedec.inc" ; Decimal output
+
+ section .data
+info_str db 'Ver.com b026', CR, LF, 0
+is_dos_str db 'Found DOS', CR, LF, 0
+is_sysl_str db 'Found a Syslinux variant', CR, LF, 0
+is_drmk_str db 'Found DRMK', CR, LF, 0
+may_sysl_str db 'Maybe Syslinux variant', CR, LF, 0
+gotver_str db 'Got the version back', CR, LF, 0
+prn_ver_str db 'Printing version number', CR, LF, 0
+syslban_str db 'Syslinux banner: ',0
+sysl_str db 'SYS', 0
+pxel_str db 'PXE', 0
+isol_str db 'ISO', 0
+extl_str db 'EXT', 0
+linsp_str db 'LINUX ', 0
+unkvar_str db 'Unkown-Variant ', 0
+pcdos_str db 'PC-DOS ', 0
+msdos_str db 'MS-DOS ', 0
+freedos_str db 'FreeDOS ', 0
+unkdos_str db 'Unknown-DOS ', 0
+drmk_str db 'DRMK ', 0
+dosext_str db ' Extended DOS version: ', 0
+osver_str db ' OS Version: ', 0
+patchver_str db ' Patch Version: ', 0
+kernbld_str db ' Kernel Build Date: ', 0
+prvdat_str db ' Private Data Ptr: ', 0
+spparen_str db ' (', 0
+zerox_str db '0x', 0
+parensp_str db ') ', 0
+eax_str db 'EAX=', 0
+ebx_str db 'EBX=', 0
+ecx_str db 'ECX=', 0
+edx_str db 'EDX=', 0
+sp2_str db ' ', 0
+zero_not_str db ' NOT_Zero ',0
+zero_is_str db ' IS_Zero ',0
diff --git a/sample/Makefile b/sample/Makefile
index f1006ff9..d7f439ca 100644
--- a/sample/Makefile
+++ b/sample/Makefile
@@ -15,6 +15,7 @@
##
topdir = ..
+include $(topdir)/MCONFIG.embedded
PPMTOLSS16 = $(topdir)/utils/ppmtolss16
diff --git a/utils/isohybrid.c b/utils/isohybrid.c
index 57c1015e..7ee9a7f0 100644
--- a/utils/isohybrid.c
+++ b/utils/isohybrid.c
@@ -543,15 +543,11 @@ main(int argc, char *argv[])
if (padding)
{
- if (!(buf = realloc(buf, padding)))
- err(1, "%s: could not re-size buffer", argv[0]);
+ if (fsync(fileno(fp)))
+ err(1, "%s: could not synchronise", argv[0]);
- if (fseek(fp, isostat.st_size, SEEK_SET))
- err(1, "%s: seek error - 6", argv[0]);
-
- memset(buf, 0, padding);
- if (fwrite(buf, sizeof(char), padding, fp) != (size_t)padding)
- err(1, "%s: write error - 2", argv[0]);
+ if (ftruncate(fileno(fp), isostat.st_size + padding))
+ err(1, "%s: could not add padding bytes", argv[0]);
}
free(buf);
diff --git a/utils/memdiskfind.c b/utils/memdiskfind.c
index decc788f..815f8bc1 100644
--- a/utils/memdiskfind.c
+++ b/utils/memdiskfind.c
@@ -94,13 +94,23 @@ static size_t memlimit(void)
return maxram;
}
+static inline size_t get_page_size(void)
+{
+#ifdef _SC_PAGESIZE
+ return sysconf(_SC_PAGESIZE);
+#else
+ /* klibc, for one, doesn't have sysconf() due to excessive multiplex */
+ return getpagesize();
+#endif
+}
+
int main(int argc, char *argv[])
{
const char *map;
int memfd;
size_t fbm;
const char *ptr, *end;
- size_t page = sysconf(_SC_PAGESIZE);
+ size_t page = get_page_size();
size_t mapbase, maplen;
int err = 1;