diff --git a/src/tests/add-ons/kernel/file_systems/iso9660/r5/Jamfile b/src/tests/add-ons/kernel/file_systems/iso9660/r5/Jamfile deleted file mode 100644 index a4c80d126f..0000000000 --- a/src/tests/add-ons/kernel/file_systems/iso9660/r5/Jamfile +++ /dev/null @@ -1,43 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel file_systems iso9660 ; - -# save original optimization level -oldOPTIM = $(OPTIM) ; - -# set some additional defines (most of them are currently unused in the iso9660 add-on) -{ - local defines = - KEEP_WRONG_DIRENT_RECLEN - ; - -# if $(COMPILE_FOR_R5) { - defines += COMPILE_FOR_R5 ; -# } - - if $(DEBUG) = 0 { - # the gcc on BeOS doesn't compile BFS correctly with -O2 or more - OPTIM = -O1 ; - } - - defines = [ FDefines $(defines) ] ; - SubDirCcFlags $(defines) -Wall -Wno-multichar ; -} - -KernelAddon iso9660 : - iso.c - kernel_interface.c - ; - -rule InstallISO9660 -{ - Depends $(<) : $(>) ; -} - -actions ignore InstallISO9660 -{ - cp $(>) /boot/home/config/add-ons/kernel/file_systems/ -} - -InstallISO9660 install : iso9660 ; - -# restore original optimization level -OPTIM = $(oldOPTIM) ; diff --git a/src/tests/add-ons/kernel/file_systems/iso9660/r5/LICENSE b/src/tests/add-ons/kernel/file_systems/iso9660/r5/LICENSE deleted file mode 100644 index 86a4268fa9..0000000000 --- a/src/tests/add-ons/kernel/file_systems/iso9660/r5/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ ----------------------- -Be Sample Code License ----------------------- - -Copyright 1991-1999, Be Incorporated. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions, and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions, and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/tests/add-ons/kernel/file_systems/iso9660/r5/cache.h b/src/tests/add-ons/kernel/file_systems/iso9660/r5/cache.h deleted file mode 100644 index b491d141d7..0000000000 --- a/src/tests/add-ons/kernel/file_systems/iso9660/r5/cache.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef _CACHE_H_ -#define _CACHE_H_ - -#include - -typedef struct hash_ent { - int dev; - off_t bnum; - off_t hash_val; - void *data; - struct hash_ent *next; -} hash_ent; - - -typedef struct hash_table { - hash_ent **table; - int max; - int mask; /* == max - 1 */ - int num_elements; -} hash_table; - - -#define HT_DEFAULT_MAX 128 - - -typedef struct cache_ent { - int dev; - off_t block_num; - int bsize; - volatile int flags; - - void *data; - void *clone; /* copy of data by set_block_info() */ - int lock; - - void (*func)(off_t bnum, size_t num_blocks, void *arg); - off_t logged_bnum; - void *arg; - - struct cache_ent *next, /* points toward mru end of list */ - *prev; /* points toward lru end of list */ - -} cache_ent; - -#define CE_NORMAL 0x0000 /* a nice clean pristine page */ -#define CE_DIRTY 0x0002 /* needs to be written to disk */ -#define CE_BUSY 0x0004 /* this block has i/o happening, don't touch it */ - - -typedef struct cache_ent_list { - cache_ent *lru; /* tail of the list */ - cache_ent *mru; /* head of the list */ -} cache_ent_list; - - -typedef struct block_cache { - lock lock; - int flags; - int cur_blocks; - int max_blocks; - hash_table ht; - - cache_ent_list normal, /* list of "normal" blocks (clean & dirty) */ - locked; /* list of clean and locked blocks */ -} block_cache; - -#if 0 /* XXXdbg -- need to deal with write through caches */ -#define DC_WRITE_THROUGH 0x0001 /* cache is write-through (for floppies) */ -#endif - -#define ALLOW_WRITES 1 -#define NO_WRITES 0 - -extern _IMPEXP_KERNEL int init_block_cache(int max_blocks, int flags); -extern _IMPEXP_KERNEL void shutdown_block_cache(void); - -extern _IMPEXP_KERNEL void force_cache_flush(int dev, int prefer_log_blocks); -extern _IMPEXP_KERNEL int flush_blocks(int dev, off_t bnum, int nblocks); -extern _IMPEXP_KERNEL int flush_device(int dev, int warn_locked); - -extern _IMPEXP_KERNEL int init_cache_for_device(int fd, off_t max_blocks); -extern _IMPEXP_KERNEL int remove_cached_device_blocks(int dev, int allow_write); - -extern _IMPEXP_KERNEL void *get_block(int dev, off_t bnum, int bsize); -extern _IMPEXP_KERNEL void *get_empty_block(int dev, off_t bnum, int bsize); -extern _IMPEXP_KERNEL int release_block(int dev, off_t bnum); -extern _IMPEXP_KERNEL int mark_blocks_dirty(int dev, off_t bnum, int nblocks); - - -extern _IMPEXP_KERNEL int cached_read(int dev, off_t bnum, void *data, off_t num_blocks, int bsize); -extern _IMPEXP_KERNEL int cached_write(int dev, off_t bnum, const void *data, - off_t num_blocks, int bsize); -extern _IMPEXP_KERNEL int cached_write_locked(int dev, off_t bnum, const void *data, - off_t num_blocks, int bsize); -extern _IMPEXP_KERNEL int set_blocks_info(int dev, off_t *blocks, int nblocks, - void (*func)(off_t bnum, size_t nblocks, void *arg), - void *arg); - - -extern _IMPEXP_KERNEL size_t read_phys_blocks (int fd, off_t bnum, void *data, uint num_blocks, int bsize); -extern _IMPEXP_KERNEL size_t write_phys_blocks(int fd, off_t bnum, void *data, uint num_blocks, int bsize); - -#endif /* _CACHE_H_ */ diff --git a/src/tests/add-ons/kernel/file_systems/iso9660/r5/fsproto.h b/src/tests/add-ons/kernel/file_systems/iso9660/r5/fsproto.h deleted file mode 100644 index 000809c3bc..0000000000 --- a/src/tests/add-ons/kernel/file_systems/iso9660/r5/fsproto.h +++ /dev/null @@ -1,240 +0,0 @@ -#ifndef _FSPROTO_H -#define _FSPROTO_H - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -typedef dev_t nspace_id; -typedef ino_t vnode_id; - -/* - * PUBLIC PART OF THE FILE SYSTEM PROTOCOL - */ - -#define WSTAT_MODE 0x0001 -#define WSTAT_UID 0x0002 -#define WSTAT_GID 0x0004 -#define WSTAT_SIZE 0x0008 -#define WSTAT_ATIME 0x0010 -#define WSTAT_MTIME 0x0020 -#define WSTAT_CRTIME 0x0040 - -#define WFSSTAT_NAME 0x0001 - -#define B_ENTRY_CREATED 1 -#define B_ENTRY_REMOVED 2 -#define B_ENTRY_MOVED 3 -#define B_STAT_CHANGED 4 -#define B_ATTR_CHANGED 5 -#define B_DEVICE_MOUNTED 6 -#define B_DEVICE_UNMOUNTED 7 - -#define B_STOP_WATCHING 0x0000 -#define B_WATCH_NAME 0x0001 -#define B_WATCH_STAT 0x0002 -#define B_WATCH_ATTR 0x0004 -#define B_WATCH_DIRECTORY 0x0008 - -#define SELECT_READ 1 -#define SELECT_WRITE 2 -#define SELECT_EXCEPTION 3 - -#define B_CUR_FS_API_VERSION 2 - -struct attr_info; -struct index_info; - -typedef int op_read_vnode(void *ns, vnode_id vnid, char r, void **node); -typedef int op_write_vnode(void *ns, void *node, char r); -typedef int op_remove_vnode(void *ns, void *node, char r); -typedef int op_secure_vnode(void *ns, void *node); - -typedef int op_walk(void *ns, void *base, const char *file, char **newpath, - vnode_id *vnid); - -typedef int op_access(void *ns, void *node, int mode); - -typedef int op_create(void *ns, void *dir, const char *name, - int omode, int perms, vnode_id *vnid, void **cookie); -typedef int op_mkdir(void *ns, void *dir, const char *name, int perms); -typedef int op_symlink(void *ns, void *dir, const char *name, - const char *path); -typedef int op_link(void *ns, void *dir, const char *name, void *node); - -typedef int op_rename(void *ns, void *olddir, const char *oldname, - void *newdir, const char *newname); -typedef int op_unlink(void *ns, void *dir, const char *name); -typedef int op_rmdir(void *ns, void *dir, const char *name); - -typedef int op_readlink(void *ns, void *node, char *buf, size_t *bufsize); - -typedef int op_opendir(void *ns, void *node, void **cookie); -typedef int op_closedir(void *ns, void *node, void *cookie); -typedef int op_rewinddir(void *ns, void *node, void *cookie); -typedef int op_readdir(void *ns, void *node, void *cookie, long *num, - struct dirent *buf, size_t bufsize); - -typedef int op_open(void *ns, void *node, int omode, void **cookie); -typedef int op_close(void *ns, void *node, void *cookie); -typedef int op_free_cookie(void *ns, void *node, void *cookie); -typedef int op_read(void *ns, void *node, void *cookie, off_t pos, void *buf, - size_t *len); -typedef int op_write(void *ns, void *node, void *cookie, off_t pos, - const void *buf, size_t *len); -typedef int op_readv(void *ns, void *node, void *cookie, off_t pos, const iovec *vec, - size_t count, size_t *len); -typedef int op_writev(void *ns, void *node, void *cookie, off_t pos, const iovec *vec, - size_t count, size_t *len); -typedef int op_ioctl(void *ns, void *node, void *cookie, int cmd, void *buf, - size_t len); -typedef int op_setflags(void *ns, void *node, void *cookie, int flags); - -typedef int op_rstat(void *ns, void *node, struct stat *); -typedef int op_wstat(void *ns, void *node, struct stat *, long mask); -typedef int op_fsync(void *ns, void *node); - -typedef int op_select(void *ns, void *node, void *cookie, uint8 event, - uint32 ref, selectsync *sync); -typedef int op_deselect(void *ns, void *node, void *cookie, uint8 event, - selectsync *sync); - -typedef int op_initialize(const char *devname, void *parms, size_t len); -typedef int op_mount(nspace_id nsid, const char *devname, ulong flags, - void *parms, size_t len, void **data, vnode_id *vnid); -typedef int op_unmount(void *ns); -typedef int op_sync(void *ns); -typedef int op_rfsstat(void *ns, struct fs_info *); -typedef int op_wfsstat(void *ns, struct fs_info *, long mask); - - -typedef int op_open_attrdir(void *ns, void *node, void **cookie); -typedef int op_close_attrdir(void *ns, void *node, void *cookie); -typedef int op_rewind_attrdir(void *ns, void *node, void *cookie); -typedef int op_read_attrdir(void *ns, void *node, void *cookie, long *num, - struct dirent *buf, size_t bufsize); -typedef int op_remove_attr(void *ns, void *node, const char *name); -typedef int op_rename_attr(void *ns, void *node, const char *oldname, - const char *newname); -typedef int op_stat_attr(void *ns, void *node, const char *name, - struct attr_info *buf); - -typedef int op_write_attr(void *ns, void *node, const char *name, int type, - const void *buf, size_t *len, off_t pos); -typedef int op_read_attr(void *ns, void *node, const char *name, int type, - void *buf, size_t *len, off_t pos); - -typedef int op_open_indexdir(void *ns, void **cookie); -typedef int op_close_indexdir(void *ns, void *cookie); -typedef int op_rewind_indexdir(void *ns, void *cookie); -typedef int op_read_indexdir(void *ns, void *cookie, long *num, - struct dirent *buf, size_t bufsize); -typedef int op_create_index(void *ns, const char *name, int type, int flags); -typedef int op_remove_index(void *ns, const char *name); -typedef int op_rename_index(void *ns, const char *oldname, - const char *newname); -typedef int op_stat_index(void *ns, const char *name, struct index_info *buf); - -typedef int op_open_query(void *ns, const char *query, ulong flags, - port_id port, long token, void **cookie); -typedef int op_close_query(void *ns, void *cookie); -typedef int op_read_query(void *ns, void *cookie, long *num, - struct dirent *buf, size_t bufsize); - -typedef struct vnode_ops { - op_read_vnode (*read_vnode); - op_write_vnode (*write_vnode); - op_remove_vnode (*remove_vnode); - op_secure_vnode (*secure_vnode); - op_walk (*walk); - op_access (*access); - op_create (*create); - op_mkdir (*mkdir); - op_symlink (*symlink); - op_link (*link); - op_rename (*rename); - op_unlink (*unlink); - op_rmdir (*rmdir); - op_readlink (*readlink); - op_opendir (*opendir); - op_closedir (*closedir); - op_free_cookie (*free_dircookie); - op_rewinddir (*rewinddir); - op_readdir (*readdir); - op_open (*open); - op_close (*close); - op_free_cookie (*free_cookie); - op_read (*read); - op_write (*write); - op_readv (*readv); - op_writev (*writev); - op_ioctl (*ioctl); - op_setflags (*setflags); - op_rstat (*rstat); - op_wstat (*wstat); - op_fsync (*fsync); - op_initialize (*initialize); - op_mount (*mount); - op_unmount (*unmount); - op_sync (*sync); - op_rfsstat (*rfsstat); - op_wfsstat (*wfsstat); - op_select (*select); - op_deselect (*deselect); - op_open_indexdir (*open_indexdir); - op_close_indexdir (*close_indexdir); - op_free_cookie (*free_indexdircookie); - op_rewind_indexdir (*rewind_indexdir); - op_read_indexdir (*read_indexdir); - op_create_index (*create_index); - op_remove_index (*remove_index); - op_rename_index (*rename_index); - op_stat_index (*stat_index); - op_open_attrdir (*open_attrdir); - op_close_attrdir (*close_attrdir); - op_free_cookie (*free_attrdircookie); - op_rewind_attrdir (*rewind_attrdir); - op_read_attrdir (*read_attrdir); - op_write_attr (*write_attr); - op_read_attr (*read_attr); - op_remove_attr (*remove_attr); - op_rename_attr (*rename_attr); - op_stat_attr (*stat_attr); - op_open_query (*open_query); - op_close_query (*close_query); - op_free_cookie (*free_querycookie); - op_read_query (*read_query); -} vnode_ops; - -extern _IMPEXP_KERNEL int new_path(const char *path, char **copy); -extern _IMPEXP_KERNEL void free_path(char *p); - -extern _IMPEXP_KERNEL int notify_listener(int op, nspace_id nsid, - vnode_id vnida, vnode_id vnidb, - vnode_id vnidc, const char *name); -extern _IMPEXP_KERNEL int send_notification(port_id port, long token, - ulong what, long op, nspace_id nsida, - nspace_id nsidb, vnode_id vnida, - vnode_id vnidb, vnode_id vnidc, - const char *name); -extern _IMPEXP_KERNEL int get_vnode(nspace_id nsid, vnode_id vnid, void **data); -extern _IMPEXP_KERNEL int put_vnode(nspace_id nsid, vnode_id vnid); -extern _IMPEXP_KERNEL int new_vnode(nspace_id nsid, vnode_id vnid, void *data); -extern _IMPEXP_KERNEL int remove_vnode(nspace_id nsid, vnode_id vnid); -extern _IMPEXP_KERNEL int unremove_vnode(nspace_id nsid, vnode_id vnid); -extern _IMPEXP_KERNEL int is_vnode_removed(nspace_id nsid, vnode_id vnid); - - -extern _EXPORT vnode_ops fs_entry; -extern _EXPORT int32 api_version; - -#endif diff --git a/src/tests/add-ons/kernel/file_systems/iso9660/r5/iso.c b/src/tests/add-ons/kernel/file_systems/iso9660/r5/iso.c deleted file mode 100644 index b31c6d1d79..0000000000 --- a/src/tests/add-ons/kernel/file_systems/iso9660/r5/iso.c +++ /dev/null @@ -1,961 +0,0 @@ -/* -** Copyright 1999, Be Incorporated. All Rights Reserved. -** This file may be used under the terms of the Be Sample Code License. -** -** Copyright 2001, pinc Software. All Rights Reserved. -** -** iso9960/multi-session -** 2001-03-11: added multi-session support, axeld. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rock.h" -#include "iso.h" - -#define TRACE_ISO9660 0 -#if TRACE_ISO9660 -# define TRACE(x) dprintf x -#else -# define TRACE(x) ; -#endif - - -// Just needed here -static status_t unicode_to_utf8(const char *src, int32 *srcLen, char *dst, int32 *dstLen); - - -// Size of primary volume descriptor for ISO9660 -#define ISO_PVD_SIZE 882 - -// ISO9660 should start with this string -const char *kISO9660IDString = "CD001"; - -#if 0 -static int GetLogicalBlockSize(int fd); -static off_t GetNumDeviceBlocks(int fd, int block_size); -#endif -static int GetDeviceBlockSize(int fd); - -static int InitVolDate(ISOVolDate *date, char *buf); -static int InitRecDate(ISORecDate *date, char *buf); -static int InitVolDesc(nspace *vol, char *buf); - -#if 0 // currently unused -static int -GetLogicalBlockSize(int fd) -{ - partition_info p_info; - - if (ioctl(fd, B_GET_PARTITION_INFO, &p_info) == B_NO_ERROR) { - TRACE(("GetLogicalBlockSize: ioctl suceed\n")); - return p_info.logical_block_size; - } - TRACE(("GetLogicalBlockSize = ioctl returned error\n")); - - return 0; -} - - -static off_t -GetNumDeviceBlocks(int fd, int block_size) -{ - struct stat st; - device_geometry dg; - - if (ioctl(fd, B_GET_GEOMETRY, &dg) >= 0) { - return (off_t)dg.cylinder_count * - (off_t)dg.sectors_per_track * - (off_t)dg.head_count; - } - - /* if the ioctl fails, try just stat'ing in case it's a regular file */ - if (fstat(fd, &st) < 0) - return 0; - - return st.st_size / block_size; -} -#endif - - -static int -GetDeviceBlockSize(int fd) -{ - struct stat st; - device_geometry dg; - - if (ioctl(fd, B_GET_GEOMETRY, &dg) < 0) { - if (fstat(fd, &st) < 0 || S_ISDIR(st.st_mode)) - return 0; - - return 512; /* just assume it's a plain old file or something */ - } - - return dg.bytes_per_sector; -} - - -// From EncodingComversions.cpp - -// Pierre's (modified) Uber Macro - -// NOTE: iso9660 seems to store the unicode text in big-endian form -#define u_to_utf8(str, uni_str)\ -{\ - if ((B_BENDIAN_TO_HOST_INT16(uni_str[0])&0xff80) == 0)\ - *str++ = B_BENDIAN_TO_HOST_INT16(*uni_str++);\ - else if ((B_BENDIAN_TO_HOST_INT16(uni_str[0])&0xf800) == 0) {\ - str[0] = 0xc0|(B_BENDIAN_TO_HOST_INT16(uni_str[0])>>6);\ - str[1] = 0x80|(B_BENDIAN_TO_HOST_INT16(*uni_str++)&0x3f);\ - str += 2;\ - } else if ((B_BENDIAN_TO_HOST_INT16(uni_str[0])&0xfc00) != 0xd800) {\ - str[0] = 0xe0|(B_BENDIAN_TO_HOST_INT16(uni_str[0])>>12);\ - str[1] = 0x80|((B_BENDIAN_TO_HOST_INT16(uni_str[0])>>6)&0x3f);\ - str[2] = 0x80|(B_BENDIAN_TO_HOST_INT16(*uni_str++)&0x3f);\ - str += 3;\ - } else {\ - int val;\ - val = ((B_BENDIAN_TO_HOST_INT16(uni_str[0])-0xd7c0)<<10) | (B_BENDIAN_TO_HOST_INT16(uni_str[1])&0x3ff);\ - str[0] = 0xf0 | (val>>18);\ - str[1] = 0x80 | ((val>>12)&0x3f);\ - str[2] = 0x80 | ((val>>6)&0x3f);\ - str[3] = 0x80 | (val&0x3f);\ - uni_str += 2; str += 4;\ - }\ -} - - -static status_t -unicode_to_utf8(const char *src, int32 *srcLen, char *dst, int32 *dstLen) -{ - int32 srcLimit = *srcLen; - int32 dstLimit = *dstLen; - int32 srcCount = 0; - int32 dstCount = 0; - - for (srcCount = 0; srcCount < srcLimit; srcCount += 2) { - uint16 *UNICODE = (uint16 *)&src[srcCount]; - uchar utf8[4]; - uchar *UTF8 = utf8; - int32 utf8Len; - int32 j; - - u_to_utf8(UTF8, UNICODE); - - utf8Len = UTF8 - utf8; - if ((dstCount + utf8Len) > dstLimit) - break; - - for (j = 0; j < utf8Len; j++) - dst[dstCount + j] = utf8[j]; - dstCount += utf8Len; - } - - *srcLen = srcCount; - *dstLen = dstCount; - - return ((dstCount > 0) ? B_NO_ERROR : B_ERROR); -} - - -// #pragma mark - -// Functions specific to iso driver. - - -int -ISOMount(const char *path, const int flags, nspace **newVol, bool allow_joliet) -{ - // path: path to device (eg, /dev/disk/scsi/030/raw) - // partition: partition number on device ???? - // flags: currently unused - - // determine if it is an ISO volume. - char buffer[ISO_PVD_SIZE]; - bool done = false; - bool is_iso = false; - off_t offset = 0x8000; - ssize_t retval; - partition_info partitionInfo; - int deviceBlockSize, multiplier; - nspace *vol; - int result = B_NO_ERROR; - - (void)flags; - - TRACE(("ISOMount - ENTER\n")); - - vol = (nspace *)calloc(sizeof(nspace), 1); - if (vol == NULL) { - TRACE(("ISOMount - mem error \n")); - return ENOMEM; - } - - memset(&partitionInfo, 0, sizeof(partition_info)); - - /* open and lock the device */ - vol->fdOfSession = open(path, O_RDONLY); - - /* try to open the raw device to get access to the other sessions as well */ - if (vol->fdOfSession >= 0) { - if (ioctl(vol->fdOfSession, B_GET_PARTITION_INFO, &partitionInfo) < B_NO_ERROR) { - TRACE(("B_GET_PARTITION_INFO: ioctl returned error\n")); - strcpy(partitionInfo.device, path); - } - TRACE(("ISOMount: open device/file \"%s\"\n", partitionInfo.device)); - - vol->fd = open(partitionInfo.device, O_RDONLY); - } - - if (vol->fdOfSession < 0 || vol->fd < 0) { - close(vol->fd); - close(vol->fdOfSession); - - TRACE(("ISO9660 ERROR - Unable to open <%s>\n", path)); - free(vol); - return EINVAL; - } - - deviceBlockSize = GetDeviceBlockSize(vol->fdOfSession); - if (deviceBlockSize < 0) { - TRACE(("ISO9660 ERROR - device block size is 0\n")); - close(vol->fd); - close(vol->fdOfSession); - - free(vol); - return EINVAL; - } - - vol->joliet_level = 0; - while ((!done) && (offset < 0x10000)) { - retval = read_pos (vol->fdOfSession, offset, (void *)buffer, ISO_PVD_SIZE); - if (retval < ISO_PVD_SIZE) { - is_iso = false; - break; - } - - if (strncmp(buffer + 1, kISO9660IDString, 5) == 0) { - if ((*buffer == 0x01) && (!is_iso)) { - // ISO_VD_PRIMARY - - off_t maxBlocks; - - TRACE(("ISOMount: Is an ISO9660 volume, initting rec\n")); - - InitVolDesc(vol, buffer); - strncpy(vol->devicePath,path,127); - vol->id = ISO_ROOTNODE_ID; - TRACE(("ISO9660: vol->blockSize = %d\n", vol->logicalBlkSize[FS_DATA_FORMAT])); - - multiplier = deviceBlockSize / vol->logicalBlkSize[FS_DATA_FORMAT]; - TRACE(("ISOMount: block size multiplier is %d\n", multiplier)); - - // if the session is on a real device, size != 0 - if (partitionInfo.size != 0) - maxBlocks = (partitionInfo.size+partitionInfo.offset) / vol->logicalBlkSize[FS_DATA_FORMAT]; - else - maxBlocks = vol->volSpaceSize[FS_DATA_FORMAT]; - - /* Initialize access to the cache so that we can do cached i/o */ - TRACE(("ISO9660: cache init: dev %d, max blocks %Ld\n", vol->fd, maxBlocks)); - init_cache_for_device(vol->fd,maxBlocks); - is_iso = true; - } else if ((*buffer == 0x02) && is_iso && allow_joliet) { - // ISO_VD_SUPPLEMENTARY - - // JOLIET extension - // test escape sequence for level of UCS-2 characterset - if (buffer[88] == 0x25 && buffer[89] == 0x2f) { - switch (buffer[90]) { - case 0x40: vol->joliet_level = 1; break; - case 0x43: vol->joliet_level = 2; break; - case 0x45: vol->joliet_level = 3; break; - } - - TRACE(("ISO9660 Extensions: Microsoft Joliet Level %d\n", vol->joliet_level)); - - // Because Joliet-stuff starts at other sector, - // update root directory record. - if (vol->joliet_level > 0) - InitNode(&(vol->rootDirRec), &buffer[156], NULL, 0); - - } - } else if (*(unsigned char *)buffer == 0xff) { - // ISO_VD_END - done = true; - } else - TRACE(("found header %d\n",*buffer)); - } - offset += 0x800; - } - - if (!is_iso) { - // It isn't an ISO disk. - if (vol->fdOfSession >= 0) - close(vol->fdOfSession); - if (vol->fd >= 0) - close(vol->fd); - - free(vol); - vol = NULL; - result = EINVAL; - TRACE(("ISOMount: Not an ISO9660 volume!\n")); - } - - TRACE(("ISOMount - EXIT, result %s, returning %p\n", strerror(result), vol)); - *newVol = vol; - return result; -} - - -/** Reads in a single directory entry and fills in the values in the - * dirent struct. Uses the cookie to keep track of the current block - * and position within the block. Also uses the cookie to determine when - * it has reached the end of the directory file. - * - * NOTE: If your file sytem seems to work ok from the command line, but - * the tracker doesn't seem to like it, check what you do here closely; - * in particular, if the d_ino in the stat struct isn't correct, the tracker - * will not display the entry. - */ - -int -ISOReadDirEnt(nspace *ns, dircookie *cookie, struct dirent *dirent, size_t bufsize) -{ - off_t totalRead = cookie->pos + ((cookie->block - cookie->startBlock) * - ns->logicalBlkSize[FS_DATA_FORMAT]); - off_t cacheBlock; - char *blockData; - int result = B_NO_ERROR; - int bytesRead = 0; - bool block_out = false; - - TRACE(("ISOReadDirEnt - ENTER\n")); - - // If we're at the end of the data in a block, move to the next block. - while (1) { - blockData = (char *)get_block(ns->fd, cookie->block, - ns->logicalBlkSize[FS_DATA_FORMAT]); - block_out = true; - - if (blockData != NULL && *(blockData + cookie->pos) == 0) { - //NULL data, move to next block. - release_block(ns->fd, cookie->block); - block_out = false; - totalRead += ns->logicalBlkSize[FS_DATA_FORMAT] - cookie->pos; - cookie->pos = 0; - cookie->block++; - } - else - break; - - if (totalRead >= cookie->totalSize) - break; - } - - cacheBlock = cookie->block; - if (blockData != NULL && totalRead < cookie->totalSize) { - vnode node; - - if ((result = InitNode(&node, blockData + cookie->pos, &bytesRead, ns->joliet_level)) == - B_NO_ERROR) - { - int nameBufSize = (bufsize - (2 * sizeof(dev_t) + 2* sizeof(ino_t) + - sizeof(unsigned short))); - - dirent->d_ino = (cookie->block << 30) + (cookie->pos & 0xFFFFFFFF); - dirent->d_reclen = node.fileIDLen; - - if (node.fileIDLen <= nameBufSize) { - // need to do some size checking here. - strncpy(dirent->d_name, node.fileIDString, node.fileIDLen +1); - TRACE(("ISOReadDirEnt - success, name is %s\n", dirent->d_name)); - } else { - TRACE(("ISOReadDirEnt - ERROR, name %s does not fit in buffer of size %d\n", node.fileIDString, nameBufSize)); - result = EINVAL; - } - cookie->pos += bytesRead; - } - } else { - if (totalRead >= cookie->totalSize) - result = ENOENT; - else - result = ENOMEM; - } - - if (block_out) - release_block(ns->fd, cacheBlock); - - TRACE(("ISOReadDirEnt - EXIT, result is %s, vnid is %Lu\n", strerror(result), dirent->d_ino)); - return result; -} - - -int -InitVolDesc(nspace *vol, char *buffer) -{ - TRACE(("InitVolDesc - ENTER\n")); - - vol->volDescType = *(uint8 *)buffer++; - - vol->stdIDString[5] = '\0'; - strncpy(vol->stdIDString, buffer, 5); - buffer += 5; - - vol->volDescVersion = *(uint8 *)buffer; - buffer += 2; // 8th byte unused - - vol->systemIDString[32] = '\0'; - strncpy(vol->systemIDString, buffer, 32); - buffer += 32; - TRACE(("InitVolDesc - system id string is %s\n", vol->systemIDString)); - - vol->volIDString[32] = '\0'; - strncpy(vol->volIDString, buffer, 32); - buffer += (32 + 80-73 + 1); // bytes 80-73 unused - TRACE(("InitVolDesc - volume id string is %s\n", vol->volIDString)); - - vol->volSpaceSize[LSB_DATA] = *(uint32 *)buffer; - buffer += 4; - vol->volSpaceSize[MSB_DATA] = *(uint32 *)buffer; - buffer+= (4 + 120-89 + 1); // bytes 120-89 unused - - vol->volSetSize[LSB_DATA] = *(uint16*)buffer; - buffer += 2; - vol->volSetSize[MSB_DATA] = *(uint16*)buffer; - buffer += 2; - - vol->volSeqNum[LSB_DATA] = *(uint16*)buffer; - buffer += 2; - vol->volSeqNum[MSB_DATA] = *(uint16*)buffer; - buffer += 2; - - vol->logicalBlkSize[LSB_DATA] = *(uint16*)buffer; - buffer += 2; - vol->logicalBlkSize[MSB_DATA] = *(uint16*)buffer; - buffer += 2; - - vol->pathTblSize[LSB_DATA] = *(uint32*)buffer; - buffer += 4; - vol->pathTblSize[MSB_DATA] = *(uint32*)buffer; - buffer += 4; - - vol->lPathTblLoc[LSB_DATA] = *(uint16*)buffer; - buffer += 2; - vol->lPathTblLoc[MSB_DATA] = *(uint16*)buffer; - buffer += 2; - - vol->optLPathTblLoc[LSB_DATA] = *(uint16*)buffer; - buffer += 2; - vol->optLPathTblLoc[MSB_DATA] = *(uint16*)buffer; - buffer += 2; - - vol->mPathTblLoc[LSB_DATA] = *(uint16*)buffer; - buffer += 2; - vol->mPathTblLoc[MSB_DATA] = *(uint16*)buffer; - buffer += 2; - - vol->optMPathTblLoc[LSB_DATA] = *(uint16*)buffer; - buffer += 2; - vol->optMPathTblLoc[MSB_DATA] = *(uint16*)buffer; - buffer += 2; - - // Fill in directory record. - InitNode(&(vol->rootDirRec), buffer, NULL, 0); - - vol->rootDirRec.id = ISO_ROOTNODE_ID; - buffer += 34; - - vol->volSetIDString[128] = '\0'; - strncpy(vol->volSetIDString, buffer, 128); - buffer += 128; - TRACE(("InitVolDesc - volume set id string is %s\n", vol->volSetIDString)); - - vol->pubIDString[128] = '\0'; - strncpy(vol->pubIDString, buffer, 128); - buffer += 128; - TRACE(("InitVolDesc - volume pub id string is %s\n", vol->pubIDString)); - - vol->dataPreparer[128] = '\0'; - strncpy(vol->dataPreparer, buffer, 128); - buffer += 128; - TRACE(("InitVolDesc - volume dataPreparer string is %s\n", vol->dataPreparer)); - - vol->appIDString[128] = '\0'; - strncpy(vol->appIDString, buffer, 128); - buffer += 128; - TRACE(("InitVolDesc - volume app id string is %s\n", vol->appIDString)); - - vol->copyright[38] = '\0'; - strncpy(vol->copyright, buffer, 38); - buffer += 38; - TRACE(("InitVolDesc - copyright is %s\n", vol->copyright)); - - vol->abstractFName[38] = '\0'; - strncpy(vol->abstractFName, buffer, 38); - buffer += 38; - - vol->biblioFName[38] = '\0'; - strncpy(vol->biblioFName, buffer, 38); - buffer += 38; - - InitVolDate(&(vol->createDate), buffer); - buffer += 17; - - InitVolDate(&(vol->modDate), buffer); - buffer += 17; - - InitVolDate(&(vol->expireDate), buffer); - buffer += 17; - - InitVolDate(&(vol->effectiveDate), buffer); - buffer += 17; - - vol->fileStructVers = *(uint8 *)buffer; - return 0; -} - - -int -InitNode(vnode *rec, char *buffer, int *_bytesRead, uint8 joliet_level) -{ - int result = B_NO_ERROR; - uint8 recLen = *(uint8 *)buffer++; - bool no_rock_ridge_stat_struct = TRUE; - - if (_bytesRead != NULL) - *_bytesRead = recLen; - - TRACE(("InitNode - ENTER, bufstart is %p, record length is %d bytes\n", buffer, recLen)); - - if (recLen > 0) { - rec->extAttrRecLen = *(uint8 *)buffer++; - - rec->startLBN[LSB_DATA] = *(uint32 *)buffer; - buffer += 4; - rec->startLBN[MSB_DATA] = *(uint32 *)buffer; - buffer += 4; - TRACE(("InitNode - data start LBN is %ld\n", rec->startLBN[FS_DATA_FORMAT])); - - rec->dataLen[LSB_DATA] = *(uint32 *)buffer; - buffer += 4; - rec->dataLen[MSB_DATA] = *(uint32 *)buffer; - buffer += 4; - TRACE(("InitNode - data length is %ld\n", rec->dataLen[FS_DATA_FORMAT])); - - InitRecDate(&(rec->recordDate), buffer); - buffer += 7; - - rec->flags = *(uint8 *)buffer; - buffer++; - TRACE(("InitNode - flags are %d\n", rec->flags)); - - rec->fileUnitSize = *(uint8 *)buffer; - buffer++; - TRACE(("InitNode - fileUnitSize is %d\n", rec->fileUnitSize)); - - rec->interleaveGapSize = *(uint8 *)buffer; - buffer++; - TRACE(("InitNode - interleave gap size = %d\n", rec->interleaveGapSize)); - - rec->volSeqNum = *(uint32 *)buffer; - buffer += 4; - TRACE(("InitNode - volume seq num is %ld\n", rec->volSeqNum)); - - rec->fileIDLen = *(uint8*)buffer; - buffer++; - TRACE(("InitNode - file id length is %d\n", rec->fileIDLen)); - - if (rec->fileIDLen > 0) { - // JOLIET extension: - // on joliet discs, buffer[0] can be 0 for Unicoded filenames, - // so I've added a check here to test explicitely for - // directories (which have length 1) - if (rec->fileIDLen == 1) { - // Take care of "." and "..", the first two dirents are - // these in iso. - if (buffer[0] == 0) { - rec->fileIDString = strdup("."); - rec->fileIDLen = 1; - } else if (buffer[0] == 1) { - rec->fileIDString = strdup(".."); - rec->fileIDLen = 2; - } - } else { - // JOLIET extension: - // convert Unicode16 string to UTF8 - if (joliet_level > 0) { - // Assume that the unicode->utf8 conversion produces 4 byte - // utf8 characters, and allocate that much space - rec->fileIDString = (char *)malloc(rec->fileIDLen * 2 + 1); - if (rec->fileIDString != NULL) { - status_t err; - int32 srcLen = rec->fileIDLen; - int32 dstLen = rec->fileIDLen * 2; - - err = unicode_to_utf8(buffer, &srcLen, rec->fileIDString, &dstLen); - if (err < B_NO_ERROR) { - dprintf("iso9660: error converting unicode->utf8\n"); - result = err; - } else { - rec->fileIDString[dstLen] = '\0'; - rec->fileIDLen = dstLen; - } - } else { - // Error - result = ENOMEM; - TRACE(("InitNode - unable to allocate memory!\n")); - } - } else { - rec->fileIDString = (char *)malloc((rec->fileIDLen) + 1); - - if (rec->fileIDString != NULL) { - strncpy(rec->fileIDString, buffer, rec->fileIDLen); - rec->fileIDString[rec->fileIDLen] = '\0'; - } else { - // Error - result = ENOMEM; - TRACE(("InitNode - unable to allocate memory!\n")); - } - } - } - - // Get rid of semicolons, which are used to delineate file versions.q - { - char *semi = NULL; - while ((semi = strchr(rec->fileIDString, ';')) != NULL) - semi[0] = '\0'; - } - TRACE(("DirRec ID String is: %s\n", rec->fileIDString)); - - if (result == B_NO_ERROR) { - buffer += rec->fileIDLen; - if (!(rec->fileIDLen % 2)) - buffer++; - - // Now we're at the start of the rock ridge stuff - { - char *altName = NULL; - char *slName = NULL; - uint16 altNameSize = 0; - uint16 slNameSize = 0; - uint8 slFlags = 0; - uint8 length = 0; - bool done = FALSE; - - TRACE(("RR: Start of extensions, but at %p\n", buffer)); - - memset(&(rec->attr.stat), 0, 2 * sizeof(struct stat)); - - // Set defaults, in case there is no RR stuff. - rec->attr.stat[FS_DATA_FORMAT].st_mode = (S_IRUSR | S_IRGRP | S_IROTH); - - while (!done) - { - buffer += length; - length = *(uint8 *)(buffer + 2); - switch (0x100 * buffer[0] + buffer[1]) - { - // Stat structure stuff - case 'PX': - { - uint8 bytePos = 3; - TRACE(("RR: found PX, length %u\n", length)); - rec->attr.pxVer = *(uint8*)(buffer + bytePos++); - no_rock_ridge_stat_struct = FALSE; - - // st_mode - rec->attr.stat[LSB_DATA].st_mode = *(mode_t*)(buffer + bytePos); - bytePos += 4; - rec->attr.stat[MSB_DATA].st_mode = *(mode_t*)(buffer + bytePos); - bytePos += 4; - - // st_nlink - rec->attr.stat[LSB_DATA].st_nlink = *(nlink_t*)(buffer+bytePos); - bytePos += 4; - rec->attr.stat[MSB_DATA].st_nlink = *(nlink_t*)(buffer + bytePos); - bytePos += 4; - - // st_uid - rec->attr.stat[LSB_DATA].st_uid = *(uid_t*)(buffer+bytePos); - bytePos += 4; - rec->attr.stat[MSB_DATA].st_uid = *(uid_t*)(buffer+bytePos); - bytePos += 4; - - // st_gid - rec->attr.stat[LSB_DATA].st_gid = *(gid_t*)(buffer+bytePos); - bytePos += 4; - rec->attr.stat[MSB_DATA].st_gid = *(gid_t*)(buffer+bytePos); - bytePos += 4; - break; - } - - case 'PN': - TRACE(("RR: found PN, length %u\n", length)); - break; - - // Symbolic link info - case 'SL': - { - uint8 bytePos = 3; - uint8 lastCompFlag = 0; - uint8 addPos = 0; - bool slDone = FALSE; - bool useSeparator = TRUE; - - TRACE(("RR: found SL, length %u\n", length)); - TRACE(("Buffer is at %p\n", buffer)); - TRACE(("Current length is %u\n", slNameSize)); - //kernel_debugger(""); - rec->attr.slVer = *(uint8*)(buffer + bytePos++); - slFlags = *(uint8*)(buffer + bytePos++); - - TRACE(("sl flags are %u\n", slFlags)); - while (!slDone && bytePos < length) - { - uint8 compFlag = *(uint8*)(buffer + bytePos++); - uint8 compLen = *(uint8*)(buffer + bytePos++); - - if (slName == NULL) useSeparator = FALSE; - - addPos = slNameSize; - - TRACE(("sl comp flags are %u, length is %u\n", compFlag, compLen)); - TRACE(("Current name size is %u\n", slNameSize)); - switch (compFlag) - { - case SLCP_CONTINUE: - useSeparator = FALSE; - default: - // Add the component to the total path. - slNameSize += compLen; - if ( useSeparator ) slNameSize++; - if (slName == NULL) - slName = (char*)malloc(slNameSize + 1); - else - slName = (char*)realloc(slName, slNameSize + 1); - - if (useSeparator) - { - TRACE(("Adding separator\n")); - slName[addPos++] = '/'; - } - - TRACE(("doing memcopy of %u bytes at offset %d\n", compLen, addPos)); - memcpy((slName + addPos), (buffer + bytePos), compLen); - - addPos += compLen; - useSeparator = TRUE; - break; - - case SLCP_CURRENT: - TRACE(("InitNode - found link to current directory\n")); - slNameSize += 2; - if (slName == NULL) - slName = (char*)malloc(slNameSize + 1); - else - slName = (char*)realloc(slName, slNameSize + 1); - memcpy(slName + addPos, "./", 2); - useSeparator = FALSE; - break; - - case SLCP_PARENT: - slNameSize += 3; - if (slName == NULL) - slName = (char*)malloc(slNameSize + 1); - else - slName = (char*)realloc(slName, slNameSize + 1); - memcpy(slName + addPos, "../", 3); - useSeparator = FALSE; - break; - - case SLCP_ROOT: - TRACE(("InitNode - found link to root directory\n")); - slNameSize += 1; - if (slName == NULL) - slName = (char*)malloc(slNameSize + 1); - else - slName = (char*)realloc(slName, slNameSize + 1); - memcpy(slName + addPos, "/", 1); - useSeparator = FALSE; - break; - - case SLCP_VOLROOT: - slDone = TRUE; - break; - - case SLCP_HOST: - slDone = TRUE; - break; - } - slName[slNameSize] = '\0'; - lastCompFlag = compFlag; - bytePos += compLen; - TRACE(("Current sl name is \'%s\'\n", slName)); - } - rec->attr.slName = slName; - TRACE(("InitNode = symlink name is \'%s\'\n", slName)); - break; - } - - // Altername name - case 'NM': - { - uint8 bytePos = 3; - uint8 flags = 0; - uint16 oldEnd = altNameSize; - - altNameSize += length - 5; - if (altName == NULL) - altName = (char *)malloc(altNameSize + 1); - else - altName = (char *)realloc(altName, altNameSize + 1); - - TRACE(("RR: found NM, length %u\n", length)); - // Read flag and version. - rec->attr.nmVer = *(uint8 *)(buffer + bytePos++); - flags = *(uint8 *)(buffer + bytePos++); - - TRACE(("RR: nm buffer is %s, start at %p\n", (buffer + bytePos), buffer + bytePos)); - - // Build the file name. - memcpy(altName + oldEnd, buffer + bytePos, length - 5); - altName[altNameSize] = '\0'; - TRACE(("RR: alt name is %s\n", altName)); - - // If the name is not continued in another record, update - // the record name. - if (!(flags & NM_CONTINUE)) - { - // Get rid of the ISO name, replace with RR name. - if (rec->fileIDString != NULL) - free(rec->fileIDString); - rec->fileIDString = altName; - rec->fileIDLen = altNameSize; - } - break; - } - - // Deep directory record masquerading as a file. - case 'CL': - TRACE(("RR: found CL, length %u\n", length)); - rec->flags |= ISO_ISDIR; - rec->startLBN[LSB_DATA] = *(uint32*)(buffer+4); - rec->startLBN[MSB_DATA] = *(uint32*)(buffer+8); - break; - - case 'PL': - TRACE(("RR: found PL, length %u\n", length)); - break; - - // Relocated directory, we should skip. - case 'RE': - result = EINVAL; - TRACE(("RR: found RE, length %u\n", length)); - break; - - case 'TF': - TRACE(("RR: found TF, length %u\n", length)); - break; - - case 'RR': - TRACE(("RR: found RR, length %u\n", length)); - break; - - default: - TRACE(("RR: %c%c (%d, %d)\n",buffer[0],buffer[1],buffer[0],buffer[1])); - TRACE(("RR: End of extensions.\n")); - done = TRUE; - break; - } - } - } - } - } else { - TRACE(("InitNode - File ID String is 0 length\n")); - result = ENOENT; - } - } else - result = ENOENT; - - TRACE(("InitNode - EXIT, result is %s name is \'%s\'\n", strerror(result), rec->fileIDString)); - - if (no_rock_ridge_stat_struct) { - if (rec->flags & ISO_ISDIR) - rec->attr.stat[FS_DATA_FORMAT].st_mode |= (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH); - else - rec->attr.stat[FS_DATA_FORMAT].st_mode |= (S_IFREG); - } - - return result; -} - - -static int -InitVolDate(ISOVolDate *date, char *buffer) -{ - memcpy(date, buffer, 17); - return 0; -} - - -static int -InitRecDate(ISORecDate *date, char *buffer) -{ - memcpy(date, buffer, 7); - return 0; -} - - -int -ConvertRecDate(ISORecDate* inDate, time_t* outDate) -{ - time_t time; - int days, i, year, tz; - - year = inDate->year -70; - tz = inDate->offsetGMT; - - if (year < 0) { - time = 0; - } else { - const int monlen[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - - days = (year * 365); - - if (year > 2) - days += (year + 1)/ 4; - - for (i = 1; (i < inDate->month) && (i < 12); i++) { - days += monlen[i-1]; - } - - if (((year + 2) % 4) == 0 && inDate->month > 2) - days++; - - days += inDate->date - 1; - time = ((((days*24) + inDate->hour) * 60 + inDate->minute) * 60) - + inDate->second; - if (tz & 0x80) - tz |= (-1 << 8); - - if (-48 <= tz && tz <= 52) - time += tz *15 * 60; - } - *outDate = time; - return 0; -} - diff --git a/src/tests/add-ons/kernel/file_systems/iso9660/r5/iso.h b/src/tests/add-ons/kernel/file_systems/iso9660/r5/iso.h deleted file mode 100644 index 656b78113d..0000000000 --- a/src/tests/add-ons/kernel/file_systems/iso9660/r5/iso.h +++ /dev/null @@ -1,230 +0,0 @@ -/* -** Copyright 1999, Be Incorporated. All Rights Reserved. -** This file may be used under the terms of the Be Sample Code License. -** -** Copyright 2001, pinc Software. All Rights Reserved. -*/ - -#ifndef _ISO_H -#define _ISO_H - -#include -#include -#include -#include -#include -#include - -#include - -// ISO structure has both msb and lsb first data. These let you do a -// compile-time switch for different platforms. - -enum -{ - LSB_DATA = 0, - MSB_DATA -}; - -// This defines the data format for the platform we are compiling -// for. -#if BYTE_ORDER == __LITTLE_ENDIAN -#define FS_DATA_FORMAT LSB_DATA -#else -#define FS_DATA_FORMAT MSB_DATA -#endif - -// ISO pdf file spec I read appears to be WRONG about the date format. See -// www.alumni.caltech.edu/~pje/iso9660.html, definition there seems -// to match. -typedef struct ISOVolDate -{ - char year[5]; - char month[3]; - char day[3]; - char hour[3]; - char minute[3]; - char second[3]; - char hunSec[3]; - int8 offsetGMT; -} ISOVolDate; - -typedef struct ISORecDate -{ - uint8 year; // Year - 1900 - uint8 month; - uint8 date; - uint8 hour; - uint8 minute; - uint8 second; - int8 offsetGMT; -} ISORecDate; - -/* This next section is data structure to hold the data found in the rock ridge extensions. */ -typedef struct RRAttr -{ - char* slName; - struct stat stat[2]; - uint8 nmVer; - uint8 pxVer; - uint8 slVer; -} RRAttr; - -/* For each item on the disk (directory, file, etc), your filesystem should allocate a vnode struct and - pass it back to the kernel when fs_read_vnode is called. This struct is then passed back in to - your file system by functions that reference an item on the disk. You'll need to be able to - create a vnode from a vnode id, either by hashing the id number or encoding the information needed - to create the vnode in the vnode id itself. Vnode ids are assigned by your file system when the - filesystem walk function is called. For this driver, the block number is encoded in the upper bits - of the vnode id, and the offset within the block in the lower, allowing me to just read the info - to fill in the vnode struct from the disk. When the kernel is done with a vnode, it will call - fs_write_vnode (somewhat of a misnomer) where you should deallocate the struct. -*/ - -typedef struct vnode -{ - /* Most drivers will probably want the first things defined here. */ - vnode_id id; - vnode_id parID; // parent vnode ID. - - // End of members other drivers will definitely want. - - /* The rest of this struct is very ISO-specific. You should replace the rest of this - definition with the stuff your file system needs. - */ - uint8 extAttrRecLen; // Length of extended attribute record. - uint32 startLBN[2]; // Logical block # of start of file/directory data - uint32 dataLen[2]; // Length of file section in bytes - ISORecDate recordDate; // Date file was recorded. - - // BIT MEANING - // --- ----------------------------- - uint8 flags; // 0 - is hidden - // 1 - is directory - // 2 - is "Associated File" - // 3 - Info is structed according to extended attr record - // 4 - Owner, group, ppermisssions are specified in the - // extended attr record - // 5 - Reserved - // 6 - Reserved - // 7 - File has more that one directory record - - uint8 fileUnitSize; // Interleave only - uint8 interleaveGapSize; // Interleave only - uint32 volSeqNum; // Volume sequence number of volume - uint8 fileIDLen; // Length of volume "ID" (name) - char* fileIDString; // Volume "ID" (name) - - // The rest is Rock Ridge extensions. I suggest www.leo.org for spec info. - RRAttr attr; -} vnode; - -// These go with the flags member of the nspace struct. -enum -{ - ISO_ISHIDDEN = 0, - ISO_ISDIR = 2, - ISO_ISASSOCFILE = 4, - ISO_EXTATTR = 8, - ISO_EXTPERM = 16, - ISO_MOREDIRS = 128 -}; - - -// Arbitrarily - selected root vnode id -#define ISO_ROOTNODE_ID 1 - -/* Structure used for directory "cookie". When you are asked - to open a directory, you are asked to create a cookie for it - and pass it back. The cookie should contain the information you - need to determine where you are at in reading the directory - entries, incremented every time readdir is called, until finally - the end is reached, when readdir returns NULL. */ -typedef struct dircookie -{ - off_t startBlock; - off_t block; // Current block - off_t pos; // Position within block. - off_t totalSize; // Size of directory file - off_t id; -} dircookie; - -/* You may also need to define a cookie for files, which again is - allocated every time a file is opened and freed when the free - cookie function is called. For ISO, we didn't need one. -*/ - -typedef struct attrfilemap -{ - char *name; - off_t offset; -} attrfilemap; - -/* This is the global volume nspace struct. When mount is called , this struct should - be allocated. It is passed back into the functions so that you can get at any - global information you need. You'll need to change this struct to suit your purposes. -*/ - -typedef struct nspace -{ - // Start of members other drivers will definitely want. - nspace_id id; // ID passed in to fs_mount - int fd; // File descriptor - int fdOfSession; // File descriptor of the (mounted) session - //unsigned int blockSize; // usually need this, but it's part of ISO - - char devicePath[127]; - //off_t numBlocks; // May need this, but it's part of ISO - - // End of members other drivers will definitely want. - - // attribute extensions - int32 readAttributes; - attrfilemap *attrFileMap; - vnode_id attributesID; - - // JOLIET extension: joliet_level for this volume - uint8 joliet_level; - - // All this stuff comes straight from ISO primary volume - // descriptor structure. - uint8 volDescType; // Volume Descriptor type byte1 - char stdIDString[6]; // Standard ID, 1 extra for null byte2-6 - uint8 volDescVersion; // Volume Descriptor version byte7 - // 8th byte unused - char systemIDString[33]; // System ID, 1 extra for null byte9-40 - char volIDString[33]; // Volume ID, 1 extra for null byte41-72 - // bytes 73-80 unused - uint32 volSpaceSize[2]; // #logical blocks, lsb and msb byte81-88 - // bytes 89-120 unused - uint16 volSetSize[2]; // Assigned Volume Set Size of Vol byte121-124 - uint16 volSeqNum[2]; // Ordinal number of volume in Set byte125-128 - uint16 logicalBlkSize[2]; // Logical blocksize, usually 2048 byte129-132 - uint32 pathTblSize[2]; // Path table size byte133-149 - uint16 lPathTblLoc[2]; // Loc (Logical block #) of "Type L" path table byte141-144 - uint16 optLPathTblLoc[2]; // Loc (Logical block #) of optional Type L path tbl byte145-148 - uint16 mPathTblLoc[2]; // Loc (Logical block #) of "Type M" path table byte149-152 - uint16 optMPathTblLoc[2]; // Loc (Logical block #) of optional Type M path tbl byte153-156 - vnode rootDirRec; // Directory record for root directory byte157-190 - char volSetIDString[29]; // Name of multi-volume set where vol is member byte191-318 - char pubIDString[129]; // Name of publisher byte319-446 - char dataPreparer[129]; // Name of data preparer byte447-574 - char appIDString[129]; // Identifies data fomrat byte575-702 - char copyright[38]; // Copyright string byte703-739 - char abstractFName[38]; // Name of file in root that has abstract byte740-776 - char biblioFName[38]; // Name of file in root that has biblio byte777-813 - - ISOVolDate createDate; // Creation date byte - ISOVolDate modDate; // Modification date - ISOVolDate expireDate; // Data expiration date - ISOVolDate effectiveDate; // Data effective data - - uint8 fileStructVers; // File structure version byte882 -} nspace; - -int ISOMount(const char *path, const int flags, nspace** newVol, bool allow_joliet); -int ISOReadDirEnt(nspace* ns, dircookie* cookie, struct dirent* buf, size_t bufsize); -int InitNode(vnode* rec, char* buf, int* bytesRead, uint8 joliet_level); -int ConvertRecDate(ISORecDate* inDate, time_t* outDate); - -#endif diff --git a/src/tests/add-ons/kernel/file_systems/iso9660/r5/kernel_interface.c b/src/tests/add-ons/kernel/file_systems/iso9660/r5/kernel_interface.c deleted file mode 100644 index 30bb3c21fa..0000000000 --- a/src/tests/add-ons/kernel/file_systems/iso9660/r5/kernel_interface.c +++ /dev/null @@ -1,840 +0,0 @@ -/* -** Copyright 1999, Be Incorporated. All Rights Reserved. -** This file may be used under the terms of the Be Sample Code License. -** -** Copyright 2001, pinc Software. All Rights Reserved. -** -** iso9960/multi-session, 1.0.0 -** 2001-03-11: added multi-session support, axeld. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iso.h" - -#define TRACE_ISO9660 0 -#if TRACE_ISO9660 -# define TRACE(x) dprintf x -#else -# define TRACE(x) ; -#endif - - -/* Start of fundamental (read-only) required functions */ -static int fs_mount(nspace_id nsid, const char *device, ulong flags, - void *parms, size_t len, void **data, vnode_id *vnid); -static int fs_unmount(void *_ns); - -int fs_walk(void *_ns, void *_base, const char *file, - char **newpath, vnode_id *vnid); - -int fs_read_vnode(void *_ns, vnode_id vnid, char r, void **node); -int fs_write_vnode(void *_ns, void *_node, char r); -static int fs_read_stat(void *_ns, void *_node, struct stat *st); -static int fs_open(void *_ns, void *_node, int omode, void **cookie); -static int fs_read(void *_ns, void *_node, void *cookie, off_t pos, - void *buf, size_t *len); -/// fs_free_cookie - free cookie for file created in open. -static int fs_free_cookie(void *ns, void *node, void *cookie); -static int fs_close(void *ns, void *node, void *cookie); - -// fs_access - checks permissions for access. -static int fs_access(void *_ns, void *_node, int mode); - -// fs_opendir - creates fs-specific "cookie" struct that can tell where -// we are at in the directory list. -static int fs_open_dir(void* _ns, void* _node, void** cookie); -// fs_readdir - read 1 or more dirents, keep state in cookie, return -// 0 when no more entries. -static int fs_read_dir(void *_ns, void *_node, void *cookie, - long *num, struct dirent *buf, size_t bufsize); -// fs_rewinddir - set cookie to represent beginning of directory, so -// later fs_readdir calls start at beginning. -static int fs_rewind_dir(void *_ns, void *_node, void *cookie); -// fs_closedir - Do whatever you need to to close a directory (sometimes -// nothing), but DON'T free the cookie! -static int fs_close_dir(void *_ns, void *_node, void *cookie); -// fs_fee_dircookie - Free the fs-specific cookie struct -static int fs_free_dir_cookie(void *_ns, void *_node, void *cookie); - -// fs_rfsstat - Fill in fs_info struct for device. -static int fs_read_fs_stat(void *_ns, struct fs_info *); - -// fs_readlink - Read in the name of a symbolic link. -static int fs_read_link(void *_ns, void *_node, char *buf, size_t *bufsize); - - - -/* vnode_ops struct. Fill this in to tell the kernel how to call - functions in your driver. -*/ - -vnode_ops fs_entry = { - &fs_read_vnode, // read_vnode func ptr - &fs_write_vnode, // write_vnode func ptr - NULL, // remove_vnode func ptr - NULL, // secure_vnode func ptr - &fs_walk, // walk func ptr - &fs_access, // access func ptr - NULL, // create func ptr - NULL, // mkdir func ptr - NULL, - NULL, - NULL, - NULL, // unlink func ptr - NULL, // rmdir func ptr - &fs_read_link, // readlink func ptr - &fs_open_dir, // opendir func ptr - &fs_close_dir, // closedir func ptr - &fs_free_dir_cookie, // free_dircookie func ptr - &fs_rewind_dir, // rewinddir func ptr - &fs_read_dir, // readdir func ptr - &fs_open, // open file func ptr - &fs_close, // close file func ptr - &fs_free_cookie, // free cookie func ptr - &fs_read, // read file func ptr - NULL, // write file func ptr - NULL, /* readv */ - NULL, /* writev */ - NULL, // ioctl func ptr - NULL, // setflags file func ptr - &fs_read_stat, // rstat func ptr - NULL, // wstat func ptr - NULL, - NULL, // initialize func ptr - &fs_mount, // mount func ptr - &fs_unmount, // unmount func ptr - NULL, // sync func ptr - &fs_read_fs_stat, // rfsstat func ptr - NULL, // wfsstat func ptr - NULL, - NULL, - NULL, // open indexdir func ptr - NULL, // close indexdir func ptr - NULL, // free indexdir cookie func ptr - NULL, // rewind indexdir func ptr - NULL, // read indexdir func ptr - NULL, // create index func ptr - NULL, // remove index func ptr - NULL, // rename index func ptr - NULL, // stat index func ptr - NULL, //&isofs_open_attrdir, // open attrdir func ptr - NULL, //&isofs_close_attrdir, // close attrdir func ptr - NULL, //&isofs_free_attrdir_cookie, // free attrdir cookie func ptr - NULL, //&isofs_rewind_attrdir, // rewind attrdir func ptr - NULL, //&isofs_read_attrdir, // read attrdir func ptr - NULL, // write attr func ptr - NULL, //&isofs_read_attr, // read attr func ptr - NULL, // remove attr func ptr - NULL, // rename attr func ptr - NULL, //&isofs_stat_attr, // stat attr func ptr - NULL, // open query func ptr - NULL, // close query func ptr - NULL, // free query cookie func ptr - NULL // read query func ptr -}; - -int32 api_version = B_CUR_FS_API_VERSION; - - -static int -fs_mount(nspace_id nsid, const char *device, ulong flags, void *parms, - size_t len, void **data, vnode_id *vnid) -{ - /* - Kernel passes in nspace_id, (representing a disk or partition?) - and a string representing the device (eg, "/dev/scsi/disk/030/raw) - Flags will be used for things like specifying read-only mounting. - parms is parameters passed in as switches from the mount command, - and len is the length of the otions. data is a pointer to a - driver-specific struct that should be allocated in this routine. - It will then be passed back in by the kernel to a number of the other - fs driver functions. vnid should also be passed back to the kernel, - representing the vnode id of the root vnode. - */ - int result = EINVAL; - // return EINVAL if it's not a device compatible with the driver. - bool allow_joliet = true; - nspace *vol; - - (void)flags; - - /* Create semaphore if it's not already created. When do we need to - use semaphores? */ - - // Check for a 'nojoliet' parm - // all we check for is the existance of 'nojoliet' in the parms. - if (parms != NULL) { - uint32 i; - char *spot; - char *buf; - - // Make sure the len argument isn't too large - if (len > 1024) - return EINVAL; - - buf = malloc(len + 1); - if (!buf) - return ENOMEM; - - memcpy(buf, parms, len); - buf[len] = 0; - // lower case the parms data - for (i = 0; i < len + 1; i++) - buf[i] = tolower(buf[i]); - - // look for nojoliet - spot = strstr(buf, "nojoliet"); - if (spot != NULL) - allow_joliet = false; - - free(buf); - } - - // Try and mount volume as an ISO volume. - result = ISOMount(device, O_RDONLY, &vol, allow_joliet); - - // If it is ISO … - if (result == B_NO_ERROR) { - //vnode_id rootID = vol->rootDirRec.startLBN[FS_DATA_FORMAT]; - //*vnid = rootID; - *vnid = ISO_ROOTNODE_ID; - *data = (void*)vol; - - vol->id = nsid; - - // You MUST do this. Create the vnode for the root. - result = new_vnode(nsid, *vnid, (void*)&(vol->rootDirRec)); - if (result != B_NO_ERROR) { - remove_cached_device_blocks(vol->fd, 0); - free(vol); - result = EINVAL; - } else - result = B_NO_ERROR; - } - return result; -} - - -static int -fs_unmount(void *_ns) -{ - int result = B_NO_ERROR; - nspace *ns = (nspace *)_ns; - - TRACE(("fs_unmount - ENTER\n")); - - remove_cached_device_blocks(ns->fd, 0); - close(ns->fdOfSession); - result = close(ns->fd); - - free(ns); - - TRACE(("fs_unmount - EXIT, result is %s\n", strerror(result))); - return result; -} - - -static int -fs_read_fs_stat(void *_ns, struct fs_info *fss) -{ - // Fill in fs_info struct for device. - nspace *ns = (nspace *)_ns; - int i; - - TRACE(("fs_rfsstat - ENTER\n")); - - // Fill in device id. - //fss->dev = ns->fd; - - // Root vnode ID - //fss->root = ISO_ROOTNODE_ID; - - // File system flags. - fss->flags = B_FS_IS_PERSISTENT | B_FS_IS_READONLY; - - // FS block size. - fss->block_size = ns->logicalBlkSize[FS_DATA_FORMAT]; - - // IO size - specifies buffer size for file copying - fss->io_size = 65536; - - // Total blocks? - fss->total_blocks = ns->volSpaceSize[FS_DATA_FORMAT]; - - // Free blocks = 0, read only - fss->free_blocks = 0; - - // Device name. - strncpy(fss->device_name, ns->devicePath, sizeof(fss->device_name)); - - strncpy(fss->volume_name, ns->volIDString, sizeof(fss->volume_name)); - for (i = strlen(fss->volume_name)-1; i >=0 ; i--) - if (fss->volume_name[i] != ' ') - break; - - if (i < 0) - strcpy(fss->volume_name, "UNKNOWN"); - else - fss->volume_name[i + 1] = 0; - - // File system name - strcpy(fss->fsh_name, "iso9660"); - - TRACE(("fs_rfsstat - EXIT\n")); - return 0; -} - -/* fs_walk - the walk function just "walks" through a directory looking for - the specified file. When you find it, call get_vnode on its vnid to init - it for the kernel. -*/ - -int -fs_walk(void *_ns, void *base, const char *file, char **newpath, - vnode_id *vnid) -{ - /* Starting at the base, find file in the subdir, and return path - string and vnode id of file. */ - nspace *ns = (nspace *)_ns; - vnode *baseNode = (vnode*)base; - uint32 dataLen = baseNode->dataLen[FS_DATA_FORMAT]; - vnode *newNode = NULL; - int result = ENOENT; - bool done = FALSE; - uint32 totalRead = 0; - off_t block = baseNode->startLBN[FS_DATA_FORMAT]; - - TRACE(("fs_walk - looking for %s in dir file of length %d\n", file, - baseNode->dataLen[FS_DATA_FORMAT])); - - if (strcmp(file, ".") == 0) { - // base directory - TRACE(("fs_walk - found \".\" file.\n")); - *vnid = baseNode->id; - if (get_vnode(ns->id, *vnid, (void **)&newNode) != 0) - result = EINVAL; - else - result = B_NO_ERROR; - } else if (strcmp(file, "..") == 0) { - // parent directory - TRACE(("fs_walk - found \"..\" file.\n")); - *vnid = baseNode->parID; - if (get_vnode(ns->id, *vnid, (void **)&newNode) != 0) - result = EINVAL; - else - result = B_NO_ERROR; - } else { - // look up file in the directory - char *blockData; - - while ((totalRead < dataLen) && !done) { - off_t cachedBlock = block; - - blockData = (char *)get_block(ns->fd, block, ns->logicalBlkSize[FS_DATA_FORMAT]); - if (blockData != NULL) { - int bytesRead = 0; - off_t blockBytesRead = 0; - vnode node; - int initResult; - - TRACE(("fs_walk - read buffer from disk at LBN %Ld into buffer 0x%x.\n", - block, blockData)); - - // Move to the next 2-block set if necessary - // Don't go over end of buffer, if dir record sits on boundary. - - node.fileIDString = NULL; - node.attr.slName = NULL; - - while (blockBytesRead < 2*ns->logicalBlkSize[FS_DATA_FORMAT] - && totalRead + blockBytesRead < dataLen - && blockData[0] != 0 - && !done) - { - initResult = InitNode(&node, blockData, &bytesRead, ns->joliet_level); - TRACE(("fs_walk - InitNode returned %s, filename %s, %d bytes read\n", strerror(initResult), node.fileIDString, bytesRead)); - - if (initResult == B_NO_ERROR) { - if (strlen(node.fileIDString) == strlen(file) - && !strncmp(node.fileIDString, file, strlen(file))) - { - TRACE(("fs_walk - success, found vnode at block %Ld, pos %Ld\n", block, blockBytesRead)); - *vnid = (block << 30) + (blockBytesRead & 0xFFFFFFFF); - TRACE(("fs_walk - New vnode id is %Ld\n", *vnid)); - - if (get_vnode(ns->id, *vnid, (void **)&newNode) != 0) - result = EINVAL; - else { - newNode->parID = baseNode->id; - done = TRUE; - result = B_NO_ERROR; - } - } else { - if (node.fileIDString != NULL) { - free(node.fileIDString); - node.fileIDString = NULL; - } - if (node.attr.slName != NULL) { - free(node.attr.slName); - node.attr.slName = NULL; - } - } - } else { - result = initResult; - if (bytesRead == 0) - done = TRUE; - } - blockData += bytesRead; - blockBytesRead += bytesRead; - - TRACE(("fs_walk - Adding %d bytes to blockBytes read (total %Ld/%Ld).\n", - bytesRead, blockBytesRead, baseNode->dataLen[FS_DATA_FORMAT])); - } - totalRead += ns->logicalBlkSize[FS_DATA_FORMAT]; - block++; - - TRACE(("fs_walk - moving to next block %Ld, total read %Ld\n", block, totalRead)); - release_block(ns->fd, cachedBlock); - - } else - done = TRUE; - } - - // Check to see if vnode is a symbolic link. If so, fill in the newpath variable - // with the path to the real file, and call put_vnode. - if (newNode != NULL) { - if (S_ISLNK(newNode->attr.stat[FS_DATA_FORMAT].st_mode) && newpath != NULL) { - TRACE(("fs_walk - symbolic link file \'%s\' requested.\n", newNode->attr.slName)); - result = new_path(newNode->attr.slName, newpath); - put_vnode(ns->id, *vnid); - } - } - } - TRACE(("fs_walk - EXIT, result is %s, vnid is %Lu\n", strerror(result), *vnid)); - return result; -} - - -int -fs_read_vnode(void *_ns, vnode_id vnid, char reenter, void **node) -{ - uint32 block, pos; - nspace *ns = (nspace*)_ns; - int result = B_NO_ERROR; - vnode *newNode = (vnode*)calloc(sizeof(vnode), 1); - - (void)reenter; - - pos = (vnid & 0x3FFFFFFF); - block = (vnid >> 30); - - TRACE(("fs_read_vnode - ENTER, block = %ld, pos = %ld, raw = %Lu node 0x%x\n", - block, pos, vnid, newNode)); - - if (newNode != NULL) { - if (vnid == ISO_ROOTNODE_ID) { - TRACE(("fs_read_vnode - root node requested.\n")); - memcpy(newNode, &(ns->rootDirRec), sizeof(vnode)); - *node = (void*)newNode; - } else { - char *blockData = (char *)get_block(ns->fd, block, ns->logicalBlkSize[FS_DATA_FORMAT]); - - if (pos > ns->logicalBlkSize[FS_DATA_FORMAT]) { - if (blockData != NULL) - release_block(ns->fd, block); - - result = EINVAL; - } else if (blockData != NULL) { - result = InitNode(newNode, blockData + pos, NULL, ns->joliet_level); - release_block(ns->fd, block); - newNode->id = vnid; - - TRACE(("fs_read_vnode - init result is %s\n", strerror(result))); - *node = (void *)newNode; - TRACE(("fs_read_vnode - new file %s, size %ld\n", newNode->fileIDString, newNode->dataLen[FS_DATA_FORMAT])); - } - } - } else - result = ENOMEM; - - TRACE(("fs_read_vnode - EXIT, result is %s\n", strerror(result))); - return result; -} - - -int -fs_write_vnode(void *ns, void *_node, char reenter) -{ - int result = B_NO_ERROR; - vnode *node = (vnode*)_node; - - (void)ns; - (void)reenter; - - TRACE(("fs_write_vnode - ENTER (0x%x)\n", node)); - - if (node != NULL) { - if (node->id != ISO_ROOTNODE_ID) { - if (node->fileIDString != NULL) - free (node->fileIDString); - if (node->attr.slName != NULL) - free (node->attr.slName); - - free(node); - } - } - - TRACE(("fs_write_vnode - EXIT\n")); - return result; -} - - -static int -fs_read_stat(void *_ns, void *_node, struct stat *st) -{ - nspace *ns = (nspace*)_ns; - vnode *node = (vnode*)_node; - int result = B_NO_ERROR; - time_t time; - - TRACE(("fs_rstat - ENTER\n")); - - st->st_dev = ns->id; - st->st_ino = node->id; - st->st_nlink = node->attr.stat[FS_DATA_FORMAT].st_nlink; - st->st_uid = node->attr.stat[FS_DATA_FORMAT].st_uid; - st->st_gid = node->attr.stat[FS_DATA_FORMAT].st_gid; - st->st_blksize = 65536; - st->st_mode = node->attr.stat[FS_DATA_FORMAT].st_mode; - - // Same for file/dir in ISO9660 - st->st_size = node->dataLen[FS_DATA_FORMAT]; - if (ConvertRecDate(&(node->recordDate), &time) == B_NO_ERROR) - st->st_ctime = st->st_mtime = st->st_atime = time; - - TRACE(("fs_rstat - EXIT, result is %s\n", strerror(result))); - - return result; -} - - -static int -fs_open(void *_ns, void *_node, int omode, void **cookie) -{ - int result = B_NO_ERROR; - - (void)_ns; - (void)cookie; - - // Do not allow any of the write-like open modes to get by - if ((omode == O_WRONLY) || (omode == O_RDWR)) - result = EROFS; - else if((omode & O_TRUNC) || (omode & O_CREAT)) - result = EROFS; - - return result; -} - - -static int -fs_read(void *_ns, void *_node, void *cookie, off_t pos, void *buf, size_t *len) -{ - nspace *ns = (nspace *)_ns; // global stuff - vnode *node = (vnode *)_node; // The read file vnode. - uint16 blockSize = ns->logicalBlkSize[FS_DATA_FORMAT]; - uint32 startBlock = node->startLBN[FS_DATA_FORMAT] + (pos / blockSize); - off_t blockPos = pos %blockSize; - off_t numBlocks = 0; - uint32 dataLen = node->dataLen[FS_DATA_FORMAT]; - int result = B_NO_ERROR; - size_t endLen = 0; - size_t reqLen = *len; - size_t startLen = 0; - - (void)cookie; - - // Allow an open to work on a dir, but no reads - if (node->flags & ISO_ISDIR) - return EISDIR; - - if (pos < 0) - pos = 0; - *len = 0; - - // If passed-in requested length is bigger than file size, change it to - // file size. - if (reqLen + pos > dataLen) - reqLen = dataLen - pos; - - // Compute the length of the partial start-block read, if any. - - if (reqLen + blockPos <= blockSize) - startLen = reqLen; - else if (blockPos > 0) - startLen = blockSize - blockPos; - - if (blockPos == 0 && reqLen >= blockSize) { - TRACE(("Setting startLen to 0, even block read\n")); - startLen = 0; - } - - // Compute the length of the partial end-block read, if any. - if (reqLen + blockPos > blockSize) - endLen = (reqLen +blockPos) % blockSize; - - // Compute the number of middle blocks to read. - numBlocks = ((reqLen - endLen - startLen) / blockSize); - - //dprintf("fs_read - ENTER, pos is %Ld, len is %lu\n", pos, reqLen); - //dprintf("fs_read - filename is %s\n", node->fileIDString); - //dprintf("fs_read - total file length is %lu\n", dataLen); - //dprintf("fs_read - start block of file is %lu\n", node->startLBN[FS_DATA_FORMAT]); - //dprintf("fs_read - block pos is %Lu\n", blockPos); - //dprintf("fs_read - read block will be %lu\n", startBlock); - //dprintf("fs_read - startLen is %lu\n", startLen); - //dprintf("fs_read - endLen is %lu\n", endLen); - //dprintf("fs_read - num blocks to read is %Ld\n", numBlocks); - - if (pos >= dataLen) { - // If pos >= file length, return length of 0. - *len = 0; - return B_OK; - } - - // Read in the first, potentially partial, block. - if (startLen > 0) { - off_t cachedBlock = startBlock; - char *blockData = (char *)get_block(ns->fd, startBlock, blockSize); - if (blockData != NULL) { - //dprintf("fs_read - copying first block, len is %d.\n", startLen); - memcpy(buf, blockData+blockPos, startLen); - *len += startLen; - release_block(ns->fd, cachedBlock); - startBlock++; - } - else result = EIO; - } - - // Read in the middle blocks. - if (numBlocks > 0 && result == B_NO_ERROR) { - TRACE(("fs_read - getting middle blocks\n")); - result = cached_read(ns->fd, startBlock, - ((char *)buf) + startLen, - numBlocks, - blockSize); - if (result == B_NO_ERROR) - *len += blockSize * numBlocks; - } - - // Read in the last partial block. - if (result == B_NO_ERROR && endLen > 0) { - off_t endBlock = startBlock + numBlocks; - char *endBlockData = (char*)get_block(ns->fd, endBlock, blockSize); - if (endBlockData != NULL) { - char *endBuf = ((char *)buf) + (reqLen - endLen); - - memcpy(endBuf, endBlockData, endLen); - release_block(ns->fd, endBlock); - *len += endLen; - } else - result = EIO; - } - - TRACE(("fs_read - EXIT, result is %s\n", strerror(result))); - return result; -} - - -static int -fs_close(void *ns, void *node, void *cookie) -{ - (void)ns; - (void)node; - (void)cookie; - - //dprintf("fs_close - ENTER\n"); - //dprintf("fs_close - EXIT\n"); - return 0; -} - -static int -fs_free_cookie(void *ns, void *node, void *cookie) -{ - (void)ns; - (void)node; - (void)cookie; - - // We don't allocate file cookies, so we do nothing here. - //dprintf("fs_free_cookie - ENTER\n"); - //if (cookie != NULL) free (cookie); - //dprintf("fs_free_cookie - EXIT\n"); - return 0; -} - -// fs_access - checks permissions for access. -static int -fs_access(void *ns, void *node, int mode) -{ - (void)ns; - (void)node; - (void)mode; - - // ns - global, fs-specific struct for device - // node - node to check permissions for - // mode - requested permissions on node. - //dprintf("fs_access - ENTER\n"); - //dprintf("fs_access - EXIT\n"); - return 0; -} - -static int -fs_read_link(void *_ns, void *_node, char *buffer, size_t *_bufferSize) -{ - vnode *node = (vnode *)_node; - int result = EINVAL; - - (void)_ns; - - if (S_ISLNK(node->attr.stat[FS_DATA_FORMAT].st_mode)) { - size_t length = strlen(node->attr.slName); - if (length > *_bufferSize) - memcpy(buffer, node->attr.slName, length); - else - memcpy(buffer, node->attr.slName, length); - - result = B_NO_ERROR; - *_bufferSize = length; - } - - return result; -} - - -static int -fs_open_dir(void *_ns, void *_node, void **cookie) -{ - vnode *node = (vnode *)_node; - int result = B_NO_ERROR; - dircookie *dirCookie = (dircookie *)malloc(sizeof(dircookie)); - - (void)_ns; - - TRACE(("fs_opendir - ENTER, node is 0x%x\n", _node)); - - if (!(node->flags & ISO_ISDIR)) - result = EMFILE; - - if (dirCookie != NULL) { - dirCookie->startBlock = node->startLBN[FS_DATA_FORMAT]; - dirCookie->block = node->startLBN[FS_DATA_FORMAT]; - dirCookie->totalSize = node->dataLen[FS_DATA_FORMAT]; - dirCookie->pos = 0; - dirCookie->id = node->id; - *cookie = (void *)dirCookie; - } else - result = ENOMEM; - - TRACE(("fs_opendir - EXIT\n")); - return result; -} - - -static int -fs_read_dir(void *_ns, void *_node, void *_cookie, long *num, - struct dirent *buffer, size_t bufferSize) -{ - int result = B_NO_ERROR; - nspace *ns = (nspace *)_ns; - dircookie *dirCookie = (dircookie *)_cookie; - - (void)_node; - - TRACE(("fs_readdir - ENTER\n")); - - result = ISOReadDirEnt(ns, dirCookie, buffer, bufferSize); - - // If we succeeded, return 1, the number of dirents we read. - if (result == B_NO_ERROR) - *num = 1; - else - *num = 0; - - // When you get to the end, don't return an error, just return - // a zero in *num. - - if (result == ENOENT) - result = B_NO_ERROR; - - TRACE(("fs_readdir - EXIT, result is %s\n", strerror(result))); - return result; -} - - -static int -fs_rewind_dir(void *ns, void *node, void* _cookie) -{ - int result = EINVAL; - dircookie *cookie = (dircookie*)_cookie; - - (void)ns; - (void)node; - - //dprintf("fs_rewinddir - ENTER\n"); - if (cookie != NULL) { - cookie->block = cookie->startBlock; - cookie->pos = 0; - result = B_NO_ERROR; - } - //dprintf("fs_rewinddir - EXIT, result is %s\n", strerror(result)); - return result; -} - - -static int -fs_close_dir(void *ns, void *node, void *cookie) -{ - (void)ns; - (void)node; - (void)cookie; - - // ns - global, fs-specific struct for device - // node - directory to close - // cookie - current cookie for directory. - //dprintf("fs_closedir - ENTER\n"); - //dprintf("fs_closedir - EXIT\n"); - return 0; -} - - -static int -fs_free_dir_cookie(void *ns, void *node, void *cookie) -{ - (void)ns; - (void)node; - - // ns - global, fs-specific struct for device - // node - directory related to cookie - // cookie - current cookie for directory, to free. - //dprintf("fs_free_dircookie - ENTER\n"); - if (cookie != NULL) - free(cookie); - - //dprintf("fs_free_dircookie - EXIT\n"); - return 0; -} diff --git a/src/tests/add-ons/kernel/file_systems/iso9660/r5/lock.h b/src/tests/add-ons/kernel/file_systems/iso9660/r5/lock.h deleted file mode 100644 index d2941ead29..0000000000 --- a/src/tests/add-ons/kernel/file_systems/iso9660/r5/lock.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _LOCK_H -#define _LOCK_H - -#include - -#include - -typedef struct lock lock; -typedef struct mlock mlock; - -struct lock { - sem_id s; - long c; -}; - -struct mlock { - sem_id s; -}; - -extern _IMPEXP_KERNEL int new_lock(lock *l, const char *name); -extern _IMPEXP_KERNEL int free_lock(lock *l); - -#define LOCK(l) if (atomic_add(&l.c, -1) <= 0) acquire_sem(l.s); -#define UNLOCK(l) if (atomic_add(&l.c, 1) < 0) release_sem(l.s); - -extern _IMPEXP_KERNEL int new_mlock(mlock *l, long c, const char *name); -extern _IMPEXP_KERNEL int free_mlock(mlock *l); - -#define LOCKM(l,cnt) acquire_sem_etc(l.s, cnt, 0, 0) -#define UNLOCKM(l,cnt) release_sem_etc(l.s, cnt, 0) - -#endif diff --git a/src/tests/add-ons/kernel/file_systems/iso9660/r5/rock.h b/src/tests/add-ons/kernel/file_systems/iso9660/r5/rock.h deleted file mode 100644 index 53736d90df..0000000000 --- a/src/tests/add-ons/kernel/file_systems/iso9660/r5/rock.h +++ /dev/null @@ -1,32 +0,0 @@ -// rock.h - -/* - Copyright 1999, Be Incorporated. All Rights Reserved. - This file may be used under the terms of the Be Sample Code License. -*/ - -// Altername name field flags. -enum -{ - NM_CONTINUE = 1, - NM_CURRENT = 2, - NM_PARENT = 4, - NM_HOST = 32 -} NMFLAGS; - -// Symbolic link field flags -enum -{ - SL_CONTINUE = 1 -} SLFLAGS; - -// Symbolic link field component flags -enum -{ - SLCP_CONTINUE = 1, - SLCP_CURRENT = 2, - SLCP_PARENT = 4, - SLCP_ROOT = 8, - SLCP_VOLROOT = 16, - SLCP_HOST = 32 -} SLCPFLAGS;