From 47a214def6b09d93674ecb5eef1eef625f936436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 7 May 2009 08:00:10 +0000 Subject: [PATCH] * We now ignore associated files. This makes the double entries of bug #3861 disappear. * When parsing rock ridge attributes, we no longer stop when we encounter an unknown one. Instead, we just parse through until the end. The ISO image as part of #3861 also made this visible. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30655 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/file_systems/iso9660/iso9660.cpp | 84 ++++++++++++------- .../kernel/file_systems/iso9660/iso9660.h | 12 +-- .../file_systems/iso9660/kernel_interface.cpp | 6 +- 3 files changed, 61 insertions(+), 41 deletions(-) diff --git a/src/add-ons/kernel/file_systems/iso9660/iso9660.cpp b/src/add-ons/kernel/file_systems/iso9660/iso9660.cpp index 1414681713..6084ab01e7 100644 --- a/src/add-ons/kernel/file_systems/iso9660/iso9660.cpp +++ b/src/add-ons/kernel/file_systems/iso9660/iso9660.cpp @@ -303,6 +303,8 @@ parse_rock_ridge(iso9660_inode* node, char* buffer, char* end) length = *(uint8*)(buffer + 2); if (buffer + length > end) break; + if (length == 0) + break; switch (((int)buffer[0] << 8) + buffer[1]) { // Stat structure stuff @@ -496,7 +498,7 @@ parse_rock_ridge(iso9660_inode* node, char* buffer, char* end) // Deep directory record masquerading as a file. case 'CL': TRACE(("RR: found CL, length %u\n", length)); - node->flags |= ISO_ISDIR; + node->flags |= ISO_IS_DIR; node->startLBN[LSB_DATA] = *(uint32*)(buffer+4); node->startLBN[MSB_DATA] = *(uint32*)(buffer+8); break; @@ -508,7 +510,8 @@ parse_rock_ridge(iso9660_inode* node, char* buffer, char* end) case 'RE': // Relocated directory, we should skip. TRACE(("RR: found RE, length %u\n", length)); - return B_BAD_VALUE; + // TODO: support relocated directories + return B_NOT_SUPPORTED; case 'TF': TRACE(("RR: found TF, length %u\n", length)); @@ -518,10 +521,17 @@ parse_rock_ridge(iso9660_inode* node, char* buffer, char* end) TRACE(("RR: found RR, length %u\n", length)); break; + case 'SF': + TRACE(("RR: found SF, sparse files not supported!\n")); + // TODO: support sparse files + return B_NOT_SUPPORTED; + default: - TRACE(("RR: %x, %x, end of extensions.\n", - buffer[0], buffer[1])); - done = true; + if (buffer[0] == '\0') { + TRACE(("RR: end of extensions\n")); + done = true; + } else + TRACE(("RR: Unknown tag %c%c\n", buffer[0], buffer[1])); break; } } @@ -712,36 +722,45 @@ ISOReadDirEnt(iso9660_volume *volume, dircookie *cookie, struct dirent *dirent, cacheBlock = cookie->block; if (blockData != NULL && totalRead < cookie->totalSize) { - iso9660_inode node; - result = InitNode(&node, blockData + cookie->pos, &bytesRead, - volume->joliet_level); - if (result == B_OK) { - size_t nameBufferSize = bufferSize - sizeof(struct dirent); + bool done = false; + while (!done) { + iso9660_inode node; + result = InitNode(&node, blockData + cookie->pos, &bytesRead, + volume->joliet_level); + if (result != B_OK) + break; - dirent->d_dev = volume->id; - dirent->d_ino = ((ino_t)cookie->block << 30) - + (cookie->pos & 0x3fffffff); - dirent->d_reclen = sizeof(struct dirent) + node.name_length + 1; + if ((node.flags & ISO_IS_ASSOCIATED_FILE) == 0) { + size_t nameBufferSize = bufferSize - sizeof(struct dirent); - if (node.name_length <= nameBufferSize) { - // need to do some size checking here. - strlcpy(dirent->d_name, node.name, node.name_length + 1); - TRACE(("ISOReadDirEnt - success, name is %s, block %Ld, pos " - "%Ld, inode id %Ld\n", dirent->d_name, cookie->block, - cookie->pos, dirent->d_ino)); - } else { - // TODO: this can be just normal if we support reading more - // than one entry. - TRACE(("ISOReadDirEnt - ERROR, name %s does not fit in buffer " - "of size %lu\n", node.name, nameBufferSize)); - result = B_BAD_VALUE; + dirent->d_dev = volume->id; + dirent->d_ino = ((ino_t)cookie->block << 30) + + (cookie->pos & 0x3fffffff); + dirent->d_reclen = sizeof(struct dirent) + node.name_length + 1; + + if (node.name_length <= nameBufferSize) { + // need to do some size checking here. + strlcpy(dirent->d_name, node.name, node.name_length + 1); + TRACE(("ISOReadDirEnt - success, name is %s, block %Ld, pos " + "%Ld, inode id %Ld\n", dirent->d_name, cookie->block, + cookie->pos, dirent->d_ino)); + } else { + // TODO: this can be just normal if we support reading more + // than one entry. + TRACE(("ISOReadDirEnt - ERROR, name %s does not fit in buffer " + "of size %lu\n", node.name, nameBufferSize)); + result = B_BAD_VALUE; + } + + done = true; } - cookie->pos += bytesRead; - } - if (cookie->pos == volume->logicalBlkSize[FS_DATA_FORMAT]) { - cookie->pos = 0; - cookie->block++; + cookie->pos += bytesRead; + + if (cookie->pos == volume->logicalBlkSize[FS_DATA_FORMAT]) { + cookie->pos = 0; + cookie->block++; + } } } else { if (totalRead >= cookie->totalSize) @@ -782,6 +801,7 @@ InitNode(iso9660_inode* node, char* buffer, size_t* _bytesRead, memset(node->attr.stat, 0, sizeof(node->attr.stat)); node->extAttrRecLen = *(uint8*)buffer++; + TRACE(("InitNode - ext attr length is %ld\n", node->extAttrRecLen)); node->startLBN[LSB_DATA] = *(uint32*)buffer; buffer += 4; @@ -819,7 +839,7 @@ InitNode(iso9660_inode* node, char* buffer, size_t* _bytesRead, TRACE(("InitNode - file id length is %lu\n", node->name_length)); // Set defaults, in case there is no RockRidge stuff. - node->attr.stat[FS_DATA_FORMAT].st_mode |= (node->flags & ISO_ISDIR) != 0 + node->attr.stat[FS_DATA_FORMAT].st_mode |= (node->flags & ISO_IS_DIR) != 0 ? S_IFDIR | S_IXUSR | S_IRUSR | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH : S_IFREG | S_IRUSR | S_IRGRP | S_IROTH; diff --git a/src/add-ons/kernel/file_systems/iso9660/iso9660.h b/src/add-ons/kernel/file_systems/iso9660/iso9660.h index 2791bf8640..bae9bfc936 100644 --- a/src/add-ons/kernel/file_systems/iso9660/iso9660.h +++ b/src/add-ons/kernel/file_systems/iso9660/iso9660.h @@ -116,12 +116,12 @@ struct iso9660_inode { // These go with the flags member of the iso9660_volume struct. enum { - ISO_ISHIDDEN = 0, - ISO_ISDIR = 2, - ISO_ISASSOCFILE = 4, - ISO_EXTATTR = 8, - ISO_EXTPERM = 16, - ISO_MOREDIRS = 128 + ISO_IS_HIDDEN = 0x01, + ISO_IS_DIR = 0x02, + ISO_IS_ASSOCIATED_FILE = 0x04, + ISO_EXTENDED_ATTRIBUTE = 0x08, + ISO_EXTENDED_PERMISSIONS = 0x10, + ISO_MORE_DIRS = 0x80 }; diff --git a/src/add-ons/kernel/file_systems/iso9660/kernel_interface.cpp b/src/add-ons/kernel/file_systems/iso9660/kernel_interface.cpp index 53496601cc..d0b0492937 100644 --- a/src/add-ons/kernel/file_systems/iso9660/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/iso9660/kernel_interface.cpp @@ -355,7 +355,7 @@ fs_read_vnode(fs_volume *_vol, ino_t vnodeID, fs_vnode *_node, *_type = newNode->attr.stat[FS_DATA_FORMAT].st_mode & ~(S_IWUSR | S_IWGRP | S_IWOTH); *_flags = 0; - if ((newNode->flags & ISO_ISDIR) == 0) { + if ((newNode->flags & ISO_IS_DIR) == 0) { newNode->cache = file_cache_create(ns->id, vnodeID, newNode->dataLen[FS_DATA_FORMAT]); } @@ -471,7 +471,7 @@ fs_read(fs_volume *_vol, fs_vnode *_node, void *cookie, off_t pos, void *buffer, { iso9660_inode *node = (iso9660_inode *)_node->private_node; - if (node->flags & ISO_ISDIR) + if ((node->flags & ISO_IS_DIR) != 0) return EISDIR; uint32 fileSize = node->dataLen[FS_DATA_FORMAT]; @@ -548,7 +548,7 @@ fs_open_dir(fs_volume* /*_volume*/, fs_vnode* _node, void** _cookie) TRACE(("fs_open_dir - node is %p\n", node)); - if (!(node->flags & ISO_ISDIR)) + if ((node->flags & ISO_IS_DIR) == 0) return B_NOT_A_DIRECTORY; dircookie* dirCookie = (dircookie*)malloc(sizeof(dircookie));