From 0456f52098e30355a09ad2e05c3a26fc2dbc1752 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 12 Aug 2009 20:56:46 -0700 Subject: [PATCH] core: make FILENAME_MAX common; librarize mangle/unmangle FILENAME_MAX was 2^8 in all variants by now; make it a common define. Libraries mangle/unmangle; we have generic_mangle_name for Unix-like filesystems, and unmangle now defaults to simple strcpy. Signed-off-by: H. Peter Anvin --- core/config.inc | 6 +++++ core/diskfs.inc | 1 - core/extlinux.asm | 1 - core/fs.c | 18 ++++++++------ core/fs/ext2/ext2.c | 60 ++--------------------------------------------- core/fs/fat/fat.c | 49 +++++++++++++++----------------------- core/fs/iso9660/iso9660.c | 29 +++++------------------ core/fs/lib/mangle.c | 47 +++++++++++++++++++++++++++++++++++++ core/fs/pxe/pxe.c | 36 +++++++++++----------------- core/include/core.h | 1 - core/include/fs.h | 22 ++++++++++++++--- core/isolinux.asm | 2 -- core/ldlinux.asm | 1 - core/pxelinux.asm | 2 -- 14 files changed, 124 insertions(+), 151 deletions(-) create mode 100644 core/fs/lib/mangle.c diff --git a/core/config.inc b/core/config.inc index 5a3d1c5..269e13e 100644 --- a/core/config.inc +++ b/core/config.inc @@ -32,6 +32,12 @@ MAX_FKEYS equ 12 ; Number of F-key help files %assign HAS_LOCALBOOT 1 ; +; log2(Max filename size Including final null) +; +FILENAME_MAX_LG2 equ 8 +FILENAME_MAX equ (1 << FILENAME_MAX_LG2) ; Max mangled filename size + +; ; Version number definitinons ; %include "../version.gen" diff --git a/core/diskfs.inc b/core/diskfs.inc index 474657a..b8d0376 100644 --- a/core/diskfs.inc +++ b/core/diskfs.inc @@ -21,7 +21,6 @@ ; ; Some semi-configurable constants... change on your own risk. ; -FILENAME_MAX equ (1 << FILENAME_MAX_LG2) ; Max mangled filename size NULLFILE equ 0 ; Null character == empty filename NULLOFFSET equ 0 ; Position in which to look retry_count equ 16 ; How patient are we with the disk? diff --git a/core/extlinux.asm b/core/extlinux.asm index fd9cfdd..1f5423b 100644 --- a/core/extlinux.asm +++ b/core/extlinux.asm @@ -23,7 +23,6 @@ ; Some semi-configurable constants... change on your own risk. ; my_id equ extlinux_id -FILENAME_MAX_LG2 equ 8 ; log2(Max filename size Including final null) extern ext2_fs_ops ROOT_FS_OPS equ ext2_fs_ops diff --git a/core/fs.c b/core/fs.c index c4bf038..ad6659b 100644 --- a/core/fs.c +++ b/core/fs.c @@ -61,8 +61,8 @@ void load_config(com32sys_t *regs) void mangle_name(com32sys_t *regs) { - char *src = MK_PTR(regs->ds, regs->esi.w[0]); - char *dst = MK_PTR(regs->es, regs->edi.w[0]); + 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); } @@ -70,13 +70,17 @@ void mangle_name(com32sys_t *regs) void unmangle_name(com32sys_t *regs) { - char *src = MK_PTR(regs->ds, regs->esi.w[0]); - char *dst = MK_PTR(regs->es, regs->edi.w[0]); - int len; + const char *src = MK_PTR(regs->ds, regs->esi.w[0]); + char *dst = MK_PTR(regs->es, regs->edi.w[0]); + + if (this_fs->fs_ops->unmangle_name) + this_fs->fs_ops->unmangle_name(dst, src); + else + strcpy(dst, src); - len = this_fs->fs_ops->unmangle_name(dst, src); /* Update the di register to point to the last null char */ - regs->edi.w[0] += len; + dst = strchr(dst, '\0'); + regs->edi.w[0] = OFFS_WRT(dst, regs->es); } diff --git a/core/fs/ext2/ext2.c b/core/fs/ext2/ext2.c index 91eff8f..546a127 100644 --- a/core/fs/ext2/ext2.c +++ b/core/fs/ext2/ext2.c @@ -6,8 +6,6 @@ #include "ext2_fs.h" #include "fs.h" -#define FILENAME_MAX_LG2 8 -#define FILENAME_MAX (1 << FILENAME_MAX_LG2) #define MAX_SYMLINKS 64 #define SYMLINK_SECTORS 2 @@ -99,60 +97,6 @@ static void ext2_close_file(struct file *file) } /** - * mangle_name: - * - * Mangle a filename pointed to by DS:SI(of regs) into a - * buffer pointed to by ES:DI(of regs); ends on encountering - * any whitespace. - * - */ -static void ext2_mangle_name(char *dst, char *src) -{ - char *p = dst; - int i = FILENAME_MAX -1; - - while(*src > ' ') { - if (*src == '/') { - if (*(src+1) == '/') { - src ++; - i --; - continue; - } - } - i --; - *dst++ = *src++; - } - - while (1) { - if (dst == p) - break; - if (*(dst-1) != '/') - break; - - dst --; - i ++; - } - - i ++; - for (; i > 0; i --) - *dst++ = '\0'; -} - -/* - * Does the opposite of mangle_name; converts a DOS-mangled - * filename to the conventional representation. This is - * needed for the BOOT_IMAGE= parameter for the kernel. - * - * it returns the lenght of the filename. - */ -static int ext2_unmangle_name(char *dst, char *src) -{ - strcpy(dst, src); - return strlen(src); -} - - -/** * get_group_desc: * * get the group's descriptor of group_num @@ -812,7 +756,7 @@ const struct fs_ops ext2_fs_ops = { .searchdir = ext2_searchdir, .getfssec = ext2_getfssec, .close_file = ext2_close_file, - .mangle_name = ext2_mangle_name, - .unmangle_name = ext2_unmangle_name, + .mangle_name = generic_mangle_name, + .unmangle_name = NULL, .load_config = ext2_load_config }; diff --git a/core/fs/fat/fat.c b/core/fs/fat/fat.c index 83dc908..1b1c532 100644 --- a/core/fs/fat/fat.c +++ b/core/fs/fat/fat.c @@ -6,9 +6,6 @@ #include "fat_fs.h" #include "fs.h" - -#define FILENAME_MAX_LG2 8 -#define FILENAME_MAX (1 << FILENAME_MAX_LG2) #define ROOT_DIR_WORD 0x002f /* file structure. This holds the information for each currently open file */ @@ -352,55 +349,47 @@ static uint32_t vfat_getfssec(struct file *gfile, char *buf, int sectors, * ends on encountering any whitespace. * */ -static void vfat_mangle_name(char *dst, char *src) +static void vfat_mangle_name(char *dst, const char *src) { char *p = dst; + char c; int i = FILENAME_MAX -1; - while(*src > ' ') { - if ( *src == '\\' ) - *src = '/'; + /* + * Copy the filename, converting backslash to slash and + * collapsing duplicate separators. + */ + while (not_whitespace(c = *src)) { + if (c == '\\') + c = '/'; - if (*src == '/') { - if (*(src+1) == '/') { - src ++; - i --; + if (c == '/') { + if (src[1] == '/' || src[1] == '\\') { + src++; + i--; continue; } } - i --; + i--; *dst++ = *src++; } + /* Strip terminal slashes or whitespace */ while (1) { if (dst == p) break; if ((*(dst-1) != '/') && (*(dst-1) != '.')) break; - dst --; - i ++; + dst--; + i++; } - i ++; + i++; for (; i > 0; i --) *dst++ = '\0'; } - -/* - * Does the opposite of mangle_name; converts a DOS-mangled - * filename to the conventional representation. This is - * needed for the BOOT_IMAGE= parameter for the kernel. - * - * it returns the lenght of the filename. - */ -static int vfat_unmangle_name(char *dst, char *src) -{ - strcpy(dst, src); - return strlen(src); -} - /** * mangle_dos_name: * @@ -959,6 +948,6 @@ const struct fs_ops vfat_fs_ops = { .getfssec = vfat_getfssec, .close_file = vfat_close_file, .mangle_name = vfat_mangle_name, - .unmangle_name = vfat_unmangle_name, + .unmangle_name = NULL, .load_config = vfat_load_config }; diff --git a/core/fs/iso9660/iso9660.c b/core/fs/iso9660/iso9660.c index 583513c..2995e34 100644 --- a/core/fs/iso9660/iso9660.c +++ b/core/fs/iso9660/iso9660.c @@ -8,14 +8,11 @@ #define DEBUG 1 -#define FILENAME_MAX_LG2 8 -#define FILENAME_MAX (1 << FILENAME_MAX_LG2) #define ISO_SECTOR_SHIFT 11 #define ISO_SECTOR_SIZE (1 << ISO_SECTOR_SHIFT) #define ROOT_DIR_WORD 0x002f #define TRACKBUF_SIZE 8192 - struct open_file_t { sector_t file_sector; uint32_t file_bytesleft; @@ -95,22 +92,22 @@ static void iso_close_file(struct file *file) * a bit of an easier job. * */ -static void iso_mangle_name(char *dst, char *src) +static void iso_mangle_name(char *dst, const char *src) { char *p = dst; int i = FILENAME_MAX - 1; - while ( *src > ' ' ) { + while (not_whitespace(*src)) { if ( *src == '/' ) { if ( *(src+1) == '/' ) { - i --; - src ++; + i--; + src++; continue; } } *dst++ = *src ++; - i --; + i--; } while ( 1 ) { @@ -129,20 +126,6 @@ static void iso_mangle_name(char *dst, char *src) *dst++ = '\0'; } - -/* - * Does the opposite of mangle_name; converts a DOS-mangled - * filename to the conventional representation. This is - * needed for the BOOT_IMAGE= parameter for the kernel. - * - * it returns the lenght of the filename. - */ -static int iso_unmangle_name(char *dst, char *src) -{ - strcpy(dst, src); - return strlen(src); -} - /** * compare the names si and di and report if they are * equal from an ISO 9600 perspective. @@ -556,6 +539,6 @@ const struct fs_ops iso_fs_ops = { .getfssec = iso_getfssec, .close_file = iso_close_file, .mangle_name = iso_mangle_name, - .unmangle_name = iso_unmangle_name, + .unmangle_name = NULL, .load_config = iso_load_config }; diff --git a/core/fs/lib/mangle.c b/core/fs/lib/mangle.c new file mode 100644 index 0000000..813099f --- /dev/null +++ b/core/fs/lib/mangle.c @@ -0,0 +1,47 @@ +/** + * mangle_name: + * + * Mangle a filename pointed to by src into a buffer pointed + * to by dst; ends on encountering any whitespace. + * dst is preserved. + * + * This verifies that a filename is < FILENAME_MAX characters, + * doesn't contain whitespace, zero-pads the output buffer, + * and removes redundant slashes. + * + */ + +#include +#include "fs.h" + +void generic_mangle_name(char *dst, const char *src) +{ + char *p = dst; + int i = FILENAME_MAX-1; + + while (not_whitespace(*src)) { + if (*src == '/') { + if (src[1] == '/') { + src++; + i--; + continue; + } + } + i--; + *dst++ = *src++; + } + + while (1) { + if (dst == p) + break; + if (dst[-1] != '/') + break; + + dst--; + i++; + } + + i++; + for (; i > 0; i --) + *dst++ = '\0'; +} diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c index d4662f5..38f6dff 100644 --- a/core/fs/pxe/pxe.c +++ b/core/fs/pxe/pxe.c @@ -6,11 +6,7 @@ #include #include "pxe.h" -#define FILENAME_MAX_LG2 7 -#define FILENAME_MAX (1 << FILENAME_MAX_LG2) - #define GPXE 1 -#define USE_PXE_PROVIDED_STACK 0 static struct open_file_t Files[MAX_OPEN]; @@ -228,9 +224,9 @@ int gendotquad(char *dst, uint32_t ip) * return the the string address after the ip string * */ -static char *parse_dotquad(char *ip_str, uint32_t *res) +static const char *parse_dotquad(const char *ip_str, uint32_t *res) { - char *p = ip_str; + const char *p = ip_str; int i = 0; uint8_t part = 0; uint32_t ip = 0; @@ -343,10 +339,10 @@ static int pxe_get_cached_info(int type) * url is a URL (contains ://) * */ -static int is_url(char *url) +static int is_url(const char *url) { while (*url) { - if(! strncmp(url, "://", 3)) + if (!strncmp(url, "://", 3)) return 1; url++; @@ -438,9 +434,9 @@ static void get_packet_gpxe(struct open_file_t *file) * the download host, 0 for no host, or -1 for a gPXE URL. * */ -static void pxe_mangle_name(char *dst, char *src) +static void pxe_mangle_name(char *dst, const char *src) { - char *p = src; + const char *p = src; uint32_t ip = 0; int i = 0; @@ -492,15 +488,15 @@ static void pxe_mangle_name(char *dst, char *src) i = FILENAME_MAX - 5; do { - if (*p <= ' ') - break; - *dst++ = *p++; - }while (i--); + if (!not_whitespace(*p)) + break; + *dst++ = *p++; + } while (i--); - i ++; + i++; while (i) { *dst++ = 0; - i --; + i--; } #if 0 @@ -516,10 +512,8 @@ static void pxe_mangle_name(char *dst, char *src) * Does the opposite of mangle_name; converts a DOS-mangled * filename to the conventional representation. This is * needed for the BOOT_IMAGE= parameter for the kernel. - * - * it returns the lenght of the filename. */ -static int pxe_unmangle_name(char *dst, char *src) +static void pxe_unmangle_name(char *dst, const char *src) { uint32_t ip = *(uint32_t *)src; int ip_len = 0; @@ -528,10 +522,8 @@ static int pxe_unmangle_name(char *dst, char *src) ip_len = gendotquad(dst, *(uint32_t *)src); dst += ip_len; } - src += 4;; + src += 4; strcpy(dst, src); - - return strlen(src) + ip_len; } /* diff --git a/core/include/core.h b/core/include/core.h index 12ec37e..f7a6928 100644 --- a/core/include/core.h +++ b/core/include/core.h @@ -81,5 +81,4 @@ extern char UUID[]; extern volatile uint16_t BIOS_timer; - #endif /* CORE_H */ diff --git a/core/include/fs.h b/core/include/fs.h index 21e1349..2840edb 100644 --- a/core/include/fs.h +++ b/core/include/fs.h @@ -16,6 +16,9 @@ #define MAX_OPEN_LG2 5 #define MAX_OPEN (1 << MAX_OPEN_LG2) +#define FILENAME_MAX_LG2 8 +#define FILENAME_MAX (1 << FILENAME_MAX_LG2) + struct fs_info { const struct fs_ops *fs_ops; struct device *fs_dev; @@ -42,13 +45,18 @@ struct fs_ops { void (*searchdir)(char *, struct file *); uint32_t (*getfssec)(struct file *, char *, int, bool *); void (*close_file)(struct file *); - void (*mangle_name)(char *, char *); - int (*unmangle_name)(char *, char *); + void (*mangle_name)(char *, const char *); + void (*unmangle_name)(char *, const char *); void (*load_config)(com32sys_t *); }; enum dev_type {CHS, EDD}; - + +/* + * Generic functions that filesystem drivers may choose to use + */ +void generic_mangle_name(char *, const char *); + /* * Struct device contains: * the pointer points to the disk structure, @@ -65,4 +73,12 @@ struct device { uint32_t cache_size; }; +/* + * Our definition of "not whitespace" + */ +static inline bool not_whitespace(char c) +{ + return (unsigned char)c > ' '; +} + #endif /* FS_H */ diff --git a/core/isolinux.asm b/core/isolinux.asm index 2816dd8..0984478 100644 --- a/core/isolinux.asm +++ b/core/isolinux.asm @@ -26,8 +26,6 @@ ; Some semi-configurable constants... change on your own risk. ; my_id equ isolinux_id -FILENAME_MAX_LG2 equ 8 ; log2(Max filename size Including final null) -FILENAME_MAX equ (1 << FILENAME_MAX_LG2) NULLFILE equ 0 ; Zero byte == null file name NULLOFFSET equ 0 ; Position in which to look retry_count equ 6 ; How patient are we with the BIOS? diff --git a/core/ldlinux.asm b/core/ldlinux.asm index f57b239..20f0ee9 100644 --- a/core/ldlinux.asm +++ b/core/ldlinux.asm @@ -29,7 +29,6 @@ ; Some semi-configurable constants... change on your own risk. ; my_id equ syslinux_id -FILENAME_MAX_LG2 equ 8 ; log2(Max filename size Including final null) extern vfat_fs_ops ROOT_FS_OPS equ vfat_fs_ops diff --git a/core/pxelinux.asm b/core/pxelinux.asm index 2e8b319..49c81f1 100644 --- a/core/pxelinux.asm +++ b/core/pxelinux.asm @@ -29,8 +29,6 @@ ; Some semi-configurable constants... change on your own risk. ; my_id equ pxelinux_id -FILENAME_MAX_LG2 equ 8 ; log2(Max filename size Including final null) -FILENAME_MAX equ (1 << FILENAME_MAX_LG2) NULLFILE equ 0 ; Zero byte == null file name NULLOFFSET equ 4 ; Position in which to look REBOOT_TIME equ 5*60 ; If failure, time until full reset -- 2.7.4