static fsw_status_t fsw_ext2_dir_lookup(struct fsw_ext2_volume *vol, struct fsw_ext2_dnode *dno, struct fsw_string *lookup_name, struct fsw_ext2_dnode **child_dno_out) { fsw_status_t status; struct fsw_shandle shand; fsw_u32 child_ino; struct ext2_dir_entry entry; struct fsw_string entry_name; // Preconditions: The caller has checked that dno is a directory node. entry_name.type = FSW_STRING_TYPE_ISO88591; // setup handle to read the directory status = fsw_shandle_open(dno, &shand); if (status) return status; // scan the directory for the file child_ino = 0; while (child_ino == 0) { // read next entry status = fsw_ext2_read_dentry(&shand, &entry); if (status) goto errorexit; if (entry.inode == 0) { // end of directory reached status = FSW_NOT_FOUND; goto errorexit; } // compare name entry_name.len = entry_name.size = entry.name_len; entry_name.data = entry.name; if (fsw_streq(lookup_name, &entry_name)) { child_ino = entry.inode; break; } } // setup a dnode for the child item status = fsw_dnode_create(dno, child_ino, FSW_DNODE_TYPE_UNKNOWN, &entry_name, child_dno_out); errorexit: fsw_shandle_close(&shand); return status; }
static fsw_status_t fsw_iso9660_dir_lookup(struct fsw_iso9660_volume *vol, struct fsw_iso9660_dnode *dno, struct fsw_string *lookup_name, struct fsw_iso9660_dnode **child_dno_out) { fsw_status_t status; struct fsw_shandle shand; struct iso9660_dirrec_buffer dirrec_buffer; struct iso9660_dirrec *dirrec = &dirrec_buffer.dirrec; // Preconditions: The caller has checked that dno is a directory node. // setup handle to read the directory status = fsw_shandle_open(dno, &shand); if (status) return status; // scan the directory for the file while (1) { // read next entry status = fsw_iso9660_read_dirrec(vol, &shand, &dirrec_buffer); if (status) goto errorexit; if (dirrec->dirrec_length == 0) { // end of directory reached status = FSW_NOT_FOUND; goto errorexit; } // skip . and .. if (dirrec->file_identifier_length == 1 && (dirrec->file_identifier[0] == 0 || dirrec->file_identifier[0] == 1)) continue; // compare name if (fsw_streq(lookup_name, &dirrec_buffer.name)) // TODO: compare case-insensitively break; } // setup a dnode for the child item status = fsw_dnode_create(dno, dirrec_buffer.ino, FSW_DNODE_TYPE_UNKNOWN, &dirrec_buffer.name, child_dno_out); if (status == FSW_SUCCESS) fsw_memcpy(&(*child_dno_out)->dirrec, dirrec, sizeof(struct iso9660_dirrec)); errorexit: fsw_shandle_close(&shand); return status; }
static fsw_status_t fsw_iso9660_dir_read(struct fsw_iso9660_volume *vol, struct fsw_iso9660_dnode *dno, struct fsw_shandle *shand, struct fsw_iso9660_dnode **child_dno_out) { fsw_status_t status; struct iso9660_dirrec_buffer dirrec_buffer; struct iso9660_dirrec *dirrec = &dirrec_buffer.dirrec; // Preconditions: The caller has checked that dno is a directory node. The caller // has opened a storage handle to the directory's storage and keeps it around between // calls. /* (vasily) directory nodes are 4096 bytes that is two logical blocks so read dir operation * should read both blocks. */ while (1) { // read next entry if (shand->pos >= dno->g.size) return FSW_NOT_FOUND; // end of directory status = fsw_iso9660_read_dirrec(vol, shand, &dirrec_buffer); if (status) return status; if (dirrec->dirrec_length == 0) { // try the next block shand->pos =(shand->pos & ~(vol->g.log_blocksize - 1)) + vol->g.log_blocksize; continue; } // skip . and .. if (dirrec->file_identifier_length == 1 && (dirrec->file_identifier[0] == 0 || dirrec->file_identifier[0] == 1)) continue; break; } // setup a dnode for the child item status = fsw_dnode_create(dno, dirrec_buffer.ino, FSW_DNODE_TYPE_UNKNOWN, &dirrec_buffer.name, child_dno_out); if (status == FSW_SUCCESS) fsw_memcpy(&(*child_dno_out)->dirrec, dirrec, sizeof(struct iso9660_dirrec)); return status; }
static fsw_status_t fsw_ext2_dir_read(struct fsw_ext2_volume *vol, struct fsw_ext2_dnode *dno, struct fsw_shandle *shand, struct fsw_ext2_dnode **child_dno_out) { fsw_status_t status; struct ext2_dir_entry entry; struct fsw_string entry_name; // Preconditions: The caller has checked that dno is a directory node. The caller // has opened a storage handle to the directory's storage and keeps it around between // calls. while (1) { // read next entry status = fsw_ext2_read_dentry(shand, &entry); if (status) return status; if (entry.inode == 0) // end of directory return FSW_NOT_FOUND; // skip . and .. if ((entry.name_len == 1 && entry.name[0] == '.') || (entry.name_len == 2 && entry.name[0] == '.' && entry.name[1] == '.')) continue; break; } // setup name entry_name.type = FSW_STRING_TYPE_ISO88591; entry_name.len = entry_name.size = entry.name_len; entry_name.data = entry.name; // setup a dnode for the child item status = fsw_dnode_create(dno, entry.inode, FSW_DNODE_TYPE_UNKNOWN, &entry_name, child_dno_out); return status; }