-#include <lunaix/dirent.h>
#include <lunaix/fs.h>
-#include <lunaix/fs/iso9660.h>
+#include "iso9660.h"
#include <lunaix/mm/cake.h>
#include <lunaix/mm/valloc.h>
#include <lunaix/spike.h>
#include <klibc/string.h>
+#include <usr/lunaix/dirent.h>
+
extern struct cake_pile* drec_cache_pile;
void
-iso9660_fill_drecache(struct iso_drecache* cache, struct iso_drecord* drec)
+iso9660_fill_drecache(struct iso_drecache* cache,
+ struct iso_drecord* drec,
+ u32_t drec_len)
{
*cache = (struct iso_drecache){ .data_size = drec->data_size.le,
.extent_addr = drec->extent_addr.le,
.fu_size = drec->fu_sz ? drec->fu_sz : 1,
.gap_size = drec->gap_sz,
.xattr_len = drec->xattr_len };
+ u32_t padding = ((drec->name.len + sizeof(drec->name)) % 2) != 0;
+ u32_t su_offset = drec->name.len + sizeof(struct iso_drecord) + padding;
+ int su_len = drec_len - su_offset - 2, i = 0;
+
+ while (i < su_len) {
+ struct isosu_base* su_entry =
+ (struct isosu_base*)((void*)drec + su_offset + i);
+ switch (su_entry->signature) {
+ case ISORR_NM:
+ i += isorr_parse_nm(cache, (void*)su_entry);
+ break;
+ case ISORR_PX:
+ i += isorr_parse_px(cache, (void*)su_entry);
+ break;
+ case ISORR_TF:
+ i += isorr_parse_tf(cache, (void*)su_entry);
+ break;
+ case ISOSU_ST:
+ goto done;
+ default:
+ i += su_entry->length;
+ break;
+ }
+ }
+
+done:
+ if (cache->name.len) {
+ return;
+ }
+
+ // Load ISO9660 file id if no NM found.
+
+ ;
+ char name_val = drec->name.content[0];
u32_t l = drec->name.len;
+
+ if (l == 1 && !name_val) {
+ cache->name = vfs_dot;
+ return;
+ }
+
+ if(l == 1 && name_val == 1) {
+ cache->name = vfs_ddot;
+ return;
+ }
+
while (l < (u32_t)-1 && drec->name.content[l--] != ';')
;
+
l = (l + 1) ? l : drec->name.len;
- l = MIN(l, ISO9660_IDLEN);
- strncpy(cache->name_val, drec->name.content, l);
+ l = MIN(l, ISO9660_IDLEN - 1);
+
+ strncpy(cache->name_val, (const char*)drec->name.content, l);
cache->name = HSTR(cache->name_val, l);
hstr_rehash(&cache->name, HSTR_FULL_HASH);
}
int
iso9660_setup_dnode(struct v_dnode* dnode, struct v_inode* inode)
{
- if (!(inode->itype & VFS_IFDIR)) {
+ if (!check_directory_node(inode)) {
+ vfs_assign_inode(dnode, inode);
+ return 0;
+ }
+
+ struct iso_inode* isoino = inode->data;
+ if (!llist_empty(&isoino->drecaches)) {
+ dnode->data = &isoino->drecaches;
vfs_assign_inode(dnode, inode);
return 0;
}
int errno = 0;
struct device* dev = dnode->super_block->dev;
- struct iso_inode* isoino = inode->data;
- struct llist_header* lead = valloc(sizeof(*lead));
void* records = valloc(ISO9660_BLKSZ);
u32_t current_pos = -ISO9660_BLKSZ, max_pos = inode->fsize,
blk = inode->lb_addr * ISO9660_BLKSZ, blk_offset = (u32_t)-1;
- llist_init_head(lead);
-
// As per 6.8.1, Directory structure shall NOT recorded in interleave mode.
do {
if (blk_offset >= ISO9660_BLKSZ - sizeof(struct iso_drecord)) {
current_pos += ISO9660_BLKSZ;
- errno = dev->read(dev, records, blk + current_pos, ISO9660_BLKSZ);
+ errno =
+ dev->ops.read(dev, records, blk + current_pos, ISO9660_BLKSZ);
if (errno < 0) {
errno = EIO;
goto done;
break;
}
- // ignore the '.', '..' as we have built-in support
- if (drec->name.len == 1) {
- goto cont;
- }
-
struct iso_drecache* cache = cake_grab(drec_cache_pile);
- iso9660_fill_drecache(cache, drec);
- llist_append(lead, &cache->caches);
- cont:
+ iso9660_fill_drecache(cache, drec, mdu->len);
+ llist_append(&isoino->drecaches, &cache->caches);
+
blk_offset += mdu->len;
} while (current_pos + blk_offset < max_pos);
- dnode->data = lead;
- isoino->drecaches = lead;
+ dnode->data = &isoino->drecaches;
vfs_assign_inode(dnode, inode);
iso9660_dir_lookup(struct v_inode* this, struct v_dnode* dnode)
{
struct iso_inode* isoino = this->data;
- struct llist_header* lead = isoino->drecaches;
struct iso_drecache *pos, *n;
- llist_for_each(pos, n, lead, caches)
+ llist_for_each(pos, n, &isoino->drecaches, caches)
{
if (HSTR_EQ(&dnode->name, &pos->name)) {
goto found;
int
iso9660_readdir(struct v_file* file, struct dir_context* dctx)
-{
+{
struct llist_header* lead = file->dnode->data;
struct iso_drecache *pos, *n;
- u32_t counter = dctx->index - 1;
+ u32_t counter = 0;
llist_for_each(pos, n, lead, caches)
{
- if (counter == (u32_t)-1 && !(pos->flags & ISO_FHIDDEN)) {
+ if (counter == file->f_pos && !(pos->flags & ISO_FHIDDEN)) {
dctx->read_complete_callback(
- dctx, pos->name_val, pos->name.len, __get_dtype(pos));
+ dctx, HSTR_VAL(pos->name), HSTR_LEN(pos->name), __get_dtype(pos));
return 1;
}
- counter--;
+ counter++;
}
+
return 0;
}
\ No newline at end of file