summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux/syslinux-4.03/core/fs/iso9660/iso9660.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux/syslinux-4.03/core/fs/iso9660/iso9660.c')
-rw-r--r--contrib/syslinux/syslinux-4.03/core/fs/iso9660/iso9660.c348
1 files changed, 0 insertions, 348 deletions
diff --git a/contrib/syslinux/syslinux-4.03/core/fs/iso9660/iso9660.c b/contrib/syslinux/syslinux-4.03/core/fs/iso9660/iso9660.c
deleted file mode 100644
index 46f5f17..0000000
--- a/contrib/syslinux/syslinux-4.03/core/fs/iso9660/iso9660.c
+++ /dev/null
@@ -1,348 +0,0 @@
-#include <dprintf.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/dirent.h>
-#include <core.h>
-#include <cache.h>
-#include <disk.h>
-#include <fs.h>
-#include "iso9660_fs.h"
-
-/* Convert to lower case string */
-static inline char iso_tolower(char c)
-{
- if (c >= 'A' && c <= 'Z')
- c += 0x20;
-
- return c;
-}
-
-static struct inode *new_iso_inode(struct fs_info *fs)
-{
- return alloc_inode(fs, 0, sizeof(struct iso9660_pvt_inode));
-}
-
-static inline struct iso_sb_info *ISO_SB(struct fs_info *fs)
-{
- return fs->fs_info;
-}
-
-/*
- * 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 trailing dots and redumndant slashes, so "repe
- * cmpsb" can do a compare, and the path-searching routine gets
- * a bit of an easier job.
- *
- */
-static void iso_mangle_name(char *dst, const char *src)
-{
- char *p = dst;
- int i = FILENAME_MAX - 1;
-
- while (not_whitespace(*src)) {
- if ( *src == '/' ) {
- if ( *(src+1) == '/' ) {
- i--;
- src++;
- continue;
- }
- }
-
- *dst++ = *src ++;
- i--;
- }
-
- while ( 1 ) {
- if ( dst == p )
- break;
-
- if ( (*(dst-1) != '.') && (*(dst-1) != '/') )
- break;
- if ((dst[-1] == '/') && ((dst - 1) == p))
- break;
-
- dst --;
- i ++;
- }
-
- i ++;
- for (; i > 0; i -- )
- *dst++ = '\0';
-}
-
-static size_t iso_convert_name(char *dst, const char *src, int len)
-{
- char *p = dst;
- char c;
-
- if (len == 1) {
- switch (*src) {
- case 1:
- *p++ = '.';
- /* fall through */
- case 0:
- *p++ = '.';
- goto done;
- default:
- /* nothing special */
- break;
- }
- }
-
- while (len-- && (c = *src++)) {
- if (c == ';') /* Remove any filename version suffix */
- break;
- *p++ = iso_tolower(c);
- }
-
- /* Then remove any terminal dots */
- while (p > dst+1 && p[-1] == '.')
- p--;
-
-done:
- *p = '\0';
- return p - dst;
-}
-
-/*
- * Unlike strcmp, it does return 1 on match, or reutrn 0 if not match.
- */
-static bool iso_compare_name(const char *de_name, size_t len,
- const char *file_name)
-{
- char iso_file_name[256];
- char *p = iso_file_name;
- char c1, c2;
- size_t i;
-
- i = iso_convert_name(iso_file_name, de_name, len);
- dprintf("Compare: \"%s\" to \"%s\" (len %zu)\n",
- file_name, iso_file_name, i);
-
- do {
- c1 = *p++;
- c2 = iso_tolower(*file_name++);
-
- /* compare equal except for case? */
- if (c1 != c2)
- return false;
- } while (c1);
-
- return true;
-}
-
-/*
- * Find a entry in the specified dir with name _dname_.
- */
-static const struct iso_dir_entry *
-iso_find_entry(const char *dname, struct inode *inode)
-{
- struct fs_info *fs = inode->fs;
- block_t dir_block = PVT(inode)->lba;
- int i = 0, offset = 0;
- const char *de_name;
- int de_name_len, de_len;
- const struct iso_dir_entry *de;
- const char *data = NULL;
-
- dprintf("iso_find_entry: \"%s\"\n", dname);
-
- while (1) {
- if (!data) {
- dprintf("Getting block %d from block %llu\n", i, dir_block);
- if (++i > inode->blocks)
- return NULL; /* End of directory */
- data = get_cache(fs->fs_dev, dir_block++);
- offset = 0;
- }
-
- de = (const struct iso_dir_entry *)(data + offset);
- de_len = de->length;
- offset += de_len;
-
- /* Make sure we have a full directory entry */
- if (de_len < 33 || offset > BLOCK_SIZE(fs)) {
- /*
- * Zero = end of sector, or corrupt directory entry
- *
- * ECMA-119:1987 6.8.1.1: "Each Directory Record shall end
- * in the Logical Sector in which it begins.
- */
- data = NULL;
- continue;
- }
-
- de_name_len = de->name_len;
- de_name = de->name;
- if (iso_compare_name(de_name, de_name_len, dname)) {
- dprintf("Found.\n");
- return de;
- }
- }
-}
-
-static inline enum dirent_type get_inode_mode(uint8_t flags)
-{
- return (flags & 0x02) ? DT_DIR : DT_REG;
-}
-
-static struct inode *iso_get_inode(struct fs_info *fs,
- const struct iso_dir_entry *de)
-{
- struct inode *inode = new_iso_inode(fs);
- int blktosec = BLOCK_SHIFT(fs) - SECTOR_SHIFT(fs);
-
- if (!inode)
- return NULL;
-
- dprintf("Getting inode for: %.*s\n", de->name_len, de->name);
-
- inode->mode = get_inode_mode(de->flags);
- inode->size = de->size_le;
- PVT(inode)->lba = de->extent_le;
- inode->blocks = (inode->size + BLOCK_SIZE(fs) - 1) >> BLOCK_SHIFT(fs);
-
- /* We have a single extent for all data */
- inode->next_extent.pstart = (sector_t)de->extent_le << blktosec;
- inode->next_extent.len = (sector_t)inode->blocks << blktosec;
-
- return inode;
-}
-
-static struct inode *iso_iget_root(struct fs_info *fs)
-{
- const struct iso_dir_entry *root = &ISO_SB(fs)->root;
-
- return iso_get_inode(fs, root);
-}
-
-static struct inode *iso_iget(const char *dname, struct inode *parent)
-{
- const struct iso_dir_entry *de;
-
- dprintf("iso_iget %p %s\n", parent, dname);
-
- de = iso_find_entry(dname, parent);
- if (!de)
- return NULL;
-
- return iso_get_inode(parent->fs, de);
-}
-
-static int iso_readdir(struct file *file, struct dirent *dirent)
-{
- struct fs_info *fs = file->fs;
- struct inode *inode = file->inode;
- const struct iso_dir_entry *de;
- const char *data = NULL;
-
- while (1) {
- size_t offset = file->offset & (BLOCK_SIZE(fs) - 1);
-
- if (!data) {
- uint32_t i = file->offset >> BLOCK_SHIFT(fs);
- if (i >= inode->blocks)
- return -1;
- data = get_cache(fs->fs_dev, PVT(inode)->lba + i);
- }
- de = (const struct iso_dir_entry *)(data + offset);
-
- if (de->length < 33 || offset + de->length > BLOCK_SIZE(fs)) {
- file->offset = (file->offset + BLOCK_SIZE(fs))
- & ~(BLOCK_SIZE(fs) - 1); /* Start of the next block */
- data = NULL;
- continue;
- }
- break;
- }
-
- dirent->d_ino = 0; /* Inode number is invalid to ISO fs */
- dirent->d_off = file->offset;
- dirent->d_type = get_inode_mode(de->flags);
- dirent->d_reclen = offsetof(struct dirent, d_name) + 1 +
- iso_convert_name(dirent->d_name, de->name, de->name_len);
-
- file->offset += de->length; /* Update for next reading */
-
- return 0;
-}
-
-/* Load the config file, return 1 if failed, or 0 */
-static int iso_load_config(void)
-{
- static const char *search_directories[] = {
- "/boot/isolinux",
- "/isolinux",
- "/boot/syslinux",
- "/syslinux",
- "/",
- NULL
- };
- static const char *filenames[] = {
- "isolinux.cfg",
- "syslinux.cfg",
- NULL
- };
-
- return search_config(search_directories, filenames);
-}
-
-static int iso_fs_init(struct fs_info *fs)
-{
- struct iso_sb_info *sbi;
- char pvd[2048]; /* Primary Volume Descriptor */
- uint32_t pvd_lba;
- struct disk *disk = fs->fs_dev->disk;
- int blktosec;
-
- sbi = malloc(sizeof(*sbi));
- if (!sbi) {
- malloc_error("iso_sb_info structure");
- return 1;
- }
- fs->fs_info = sbi;
-
- /*
- * XXX: handling iso9660 in hybrid mode on top of a 4K-logical disk
- * will really, really hurt...
- */
- fs->sector_shift = fs->fs_dev->disk->sector_shift;
- fs->block_shift = 11; /* A CD-ROM block is always 2K */
- fs->sector_size = 1 << fs->sector_shift;
- fs->block_size = 1 << fs->block_shift;
- blktosec = fs->block_shift - fs->sector_shift;
-
- pvd_lba = iso_boot_info.pvd;
- if (!pvd_lba)
- pvd_lba = 16; /* Default if not otherwise defined */
-
- disk->rdwr_sectors(disk, pvd, (sector_t)pvd_lba << blktosec,
- 1 << blktosec, false);
- memcpy(&sbi->root, pvd + ROOT_DIR_OFFSET, sizeof(sbi->root));
-
- /* Initialize the cache */
- cache_init(fs->fs_dev, fs->block_shift);
-
- return fs->block_shift;
-}
-
-
-const struct fs_ops iso_fs_ops = {
- .fs_name = "iso",
- .fs_flags = FS_USEMEM | FS_THISIND,
- .fs_init = iso_fs_init,
- .searchdir = NULL,
- .getfssec = generic_getfssec,
- .close_file = generic_close_file,
- .mangle_name = iso_mangle_name,
- .load_config = iso_load_config,
- .iget_root = iso_iget_root,
- .iget = iso_iget,
- .readdir = iso_readdir,
- .next_extent = no_next_extent,
-};