core: make FILENAME_MAX common; librarize mangle/unmangle
authorH. Peter Anvin <hpa@zytor.com>
Thu, 13 Aug 2009 03:56:46 +0000 (20:56 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Thu, 13 Aug 2009 03:56:46 +0000 (20:56 -0700)
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 <hpa@zytor.com>
14 files changed:
core/config.inc
core/diskfs.inc
core/extlinux.asm
core/fs.c
core/fs/ext2/ext2.c
core/fs/fat/fat.c
core/fs/iso9660/iso9660.c
core/fs/lib/mangle.c [new file with mode: 0644]
core/fs/pxe/pxe.c
core/include/core.h
core/include/fs.h
core/isolinux.asm
core/ldlinux.asm
core/pxelinux.asm

index 5a3d1c5..269e13e 100644 (file)
@@ -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"
index 474657a..b8d0376 100644 (file)
@@ -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?
index fd9cfdd..1f5423b 100644 (file)
@@ -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
index c4bf038..ad6659b 100644 (file)
--- 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);
 }
 
 
index 91eff8f..546a127 100644 (file)
@@ -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
 };
index 83dc908..1b1c532 100644 (file)
@@ -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
 };
index 583513c..2995e34 100644 (file)
@@ -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 (file)
index 0000000..813099f
--- /dev/null
@@ -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 <string.h>
+#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';
+}
index d4662f5..38f6dff 100644 (file)
@@ -6,11 +6,7 @@
 #include <sys/cpu.h>
 #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;
 }
         
 /*
index 12ec37e..f7a6928 100644 (file)
@@ -81,5 +81,4 @@ extern char UUID[];
 
 extern volatile uint16_t BIOS_timer;
 
-
 #endif /* CORE_H */
index 21e1349..2840edb 100644 (file)
@@ -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 */
index 2816dd8..0984478 100644 (file)
@@ -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?
index f57b239..20f0ee9 100644 (file)
@@ -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
index 2e8b319..49c81f1 100644 (file)
@@ -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