static int ext2fs_readdir(struct open_file *f, struct dirent *d) { struct file *fp = (struct file *)f->f_fsdata; struct ext2dirent *ed; char *buf; size_t buf_size; int error; /* * assume that a directory entry will not be split across blocks */ again: if (fp->f_seekp >= fp->f_di.di_size) return (ENOENT); error = buf_read_file(f, &buf, &buf_size); if (error) return (error); ed = (struct ext2dirent *)buf; fp->f_seekp += ed->d_reclen; if (ed->d_ino == (ino_t)0) goto again; d->d_type = EXTFTODT(ed->d_type); strncpy(d->d_name, ed->d_name, ed->d_namlen); d->d_name[ed->d_namlen] = '\0'; return (0); }
/* * Copy a portion of a file into kernel memory. * Cross block boundaries when necessary. */ __compactcall int ufs_read(struct open_file *f, void *start, size_t size, size_t *resid) { struct file *fp = (struct file *)f->f_fsdata; size_t csize; char *buf; size_t buf_size; int rc = 0; char *addr = start; while (size != 0) { if (fp->f_seekp >= (off_t)fp->f_di.di_size) break; rc = buf_read_file(f, &buf, &buf_size); if (rc) break; csize = size; if (csize > buf_size) csize = buf_size; memcpy(addr, buf, csize); fp->f_seekp += csize; addr += csize; size -= csize; } if (resid) *resid = size; return rc; }
/* * Find an inode's block. Look it up in the ifile. Whee! */ static int find_inode_sector(ino32_t inumber, struct open_file *f, daddr_t *isp) { struct file *fp = (struct file *)f->f_fsdata; struct fs *fs = fp->f_fs; daddr_t ifileent_blkno; char *ent_in_buf; size_t buf_after_ent; int rc; rc = read_inode(fs->lfs_ifile, f); if (rc) return rc; ifileent_blkno = (inumber / fs->lfs_ifpb) + fs->lfs_cleansz + fs->lfs_segtabsz; fp->f_seekp = (off_t)ifileent_blkno * fs->fs_bsize + (inumber % fs->lfs_ifpb) * sizeof (IFILE_Vx); rc = buf_read_file(f, &ent_in_buf, &buf_after_ent); if (rc) return rc; /* make sure something's not badly wrong, but don't panic. */ if (buf_after_ent < sizeof (IFILE_Vx)) return EINVAL; *isp = FSBTODB(fs, ((IFILE_Vx *)ent_in_buf)->if_daddr); if (*isp == LFS_UNUSED_DADDR) /* again, something badly wrong */ return EINVAL; return 0; }
/* * Search a directory for a name and return its * i_number. */ static int search_directory(char *name, struct open_file *f, ino_t *inumber_p) { struct file *fp = (struct file *)f->f_fsdata; struct ext2dirent *dp, *edp; char *buf; size_t buf_size; int namlen, length; int error; length = strlen(name); fp->f_seekp = 0; while (fp->f_seekp < fp->f_di.di_size) { error = buf_read_file(f, &buf, &buf_size); if (error) return (error); dp = (struct ext2dirent *)buf; edp = (struct ext2dirent *)(buf + buf_size); while (dp < edp) { if (dp->d_ino == (ino_t)0) goto next; namlen = dp->d_namlen; if (namlen == length && strncmp(name, dp->d_name, length) == 0) { /* found entry */ *inumber_p = dp->d_ino; return (0); } next: dp = (struct ext2dirent *)((char *)dp + dp->d_reclen); } fp->f_seekp += buf_size; } return (ENOENT); }
static int ext2fs_read(struct open_file *f, void *addr, size_t size, size_t *resid) { struct file *fp = (struct file *)f->f_fsdata; size_t csize, buf_size; char *buf; int error = 0; while (size != 0) { if (fp->f_seekp >= fp->f_di.di_size) break; error = buf_read_file(f, &buf, &buf_size); if (error) break; csize = size; if (csize > buf_size) csize = buf_size; bcopy(buf, addr, csize); fp->f_seekp += csize; addr += csize; size -= csize; } if (resid) *resid = size; return (error); }
static int cd9660_read(struct open_file *f, void *start, size_t size, size_t *resid) { struct file *fp = (struct file *)f->f_fsdata; char *buf, *addr; size_t buf_size, csize; int rc = 0; addr = start; while (size) { if (fp->f_off < 0 || fp->f_off >= fp->f_size) break; rc = buf_read_file(f, &buf, &buf_size); if (rc) break; csize = size > buf_size ? buf_size : size; bcopy(buf, addr, csize); fp->f_off += csize; addr += csize; size -= csize; } if (resid) *resid = size; return (rc); }
/* * Copy a portion of a file into kernel memory. * Cross block boundaries when necessary. * * Parameters: * resid: out */ static int ufs_read(struct open_file *f, void *start, size_t size, size_t *resid) { struct file *fp = (struct file *)f->f_fsdata; size_t csize; char *buf; size_t buf_size; int rc = 0; char *addr = start; while (size != 0) { if (fp->f_seekp >= fp->f_di.di_size) break; rc = buf_read_file(f, &buf, &buf_size); if (rc) break; csize = size; if (csize > buf_size) csize = buf_size; bcopy(buf, addr, csize); fp->f_seekp += csize; addr += csize; size -= csize; } if (resid) *resid = size; return (rc); }
static int ufs_readdir(struct open_file *f, struct dirent *d) { struct file *fp = (struct file *)f->f_fsdata; struct direct *dp; char *buf; size_t buf_size; int error; /* * assume that a directory entry will not be split across blocks */ again: if (fp->f_seekp >= fp->f_di.di_size) return (ENOENT); error = buf_read_file(f, &buf, &buf_size); if (error) return (error); dp = (struct direct *)buf; fp->f_seekp += dp->d_reclen; if (dp->d_ino == (ino_t)0) goto again; d->d_type = dp->d_type; strcpy(d->d_name, dp->d_name); return (0); }
__compactcall void ext2fs_ls(struct open_file *f, const char *pattern) { struct file *fp = (struct file *)f->f_fsdata; size_t block_size = fp->f_fs->e2fs_bsize; char *buf; size_t buf_size; lsentry_t *names = NULL; fp->f_seekp = 0; while (fp->f_seekp < (off_t)fp->f_di.e2di_size) { struct ext2fs_direct *dp, *edp; int rc = buf_read_file(f, &buf, &buf_size); if (rc) goto out; if (buf_size != block_size || buf_size == 0) goto out; dp = (struct ext2fs_direct *)buf; edp = (struct ext2fs_direct *)(buf + buf_size); for (; dp < edp; dp = (void *)((char *)dp + fs2h16(dp->e2d_reclen))) { const char *t; if (fs2h16(dp->e2d_reclen) <= 0) goto out; if (fs2h32(dp->e2d_ino) == 0) continue; if (dp->e2d_type >= NELEM(typestr) || !(t = typestr[dp->e2d_type])) { /* * This does not handle "old" * filesystems properly. On little * endian machines, we get a bogus * type name if the namlen matches a * valid type identifier. We could * check if we read namlen "0" and * handle this case specially, if * there were a pressing need... */ printf("bad dir entry\n"); goto out; } lsadd(&names, pattern, dp->e2d_name, strlen(dp->e2d_name), fs2h32(dp->e2d_ino), t); } fp->f_seekp += buf_size; } lsprint(names); out: lsfree(names); }
/* * Search a directory for a name and return its * inode number. */ static int search_directory(const char *name, int length, struct open_file *f, ino32_t *inumber_p) { struct file *fp = (struct file *)f->f_fsdata; struct mfs_sblock *fs = fp->f_fs; struct mfs_direct *dp; struct mfs_direct *dbuf; size_t buf_size; int namlen; int rc; fp->f_seekp = 0; while (fp->f_seekp < (off_t)fp->f_di.mdi_size) { rc = buf_read_file(f, (void *)&dbuf, &buf_size); if (rc) return rc; if (buf_size == 0) return EIO; /* XXX we assume, that buf_read_file reads an fs block and * doesn't truncate buffer. Currently i_size in MFS doesn't * the same as size of allocated blocks, it makes buf_read_file * to truncate buf_size. */ if (buf_size < fs->mfs_block_size) buf_size = fs->mfs_block_size; for (dp = dbuf; dp < &dbuf[NR_DIR_ENTRIES(fs)]; dp++) { char *cp; if (fs2h32(dp->mfsd_ino) == (ino32_t) 0) continue; /* Compute the length of the name */ cp = memchr(dp->mfsd_name, '\0', sizeof(dp->mfsd_name)); if (cp == NULL) namlen = sizeof(dp->mfsd_name); else namlen = cp - (dp->mfsd_name); if (namlen == length && !memcmp(name, dp->mfsd_name, length)) { /* found entry */ *inumber_p = fs2h32(dp->mfsd_ino); return 0; } } fp->f_seekp += buf_size; } return ENOENT; }
/* * Search a directory for a name and return its * i_number. * * Parameters: * inumber_p: out */ static int search_directory(char *name, struct open_file *f, ino_t *inumber_p) { struct file *fp = (struct file *)f->f_fsdata; struct direct *dp; struct direct *edp; char *buf; size_t buf_size; int namlen, length; int rc; length = strlen(name); fp->f_seekp = 0; while (fp->f_seekp < fp->f_di.di_size) { rc = buf_read_file(f, &buf, &buf_size); if (rc) return (rc); dp = (struct direct *)buf; edp = (struct direct *)(buf + buf_size); while (dp < edp) { if (dp->d_ino == (ino_t)0) goto next; if (dp->d_type == DT_WHT) goto next; #if BYTE_ORDER == LITTLE_ENDIAN if (fp->f_fs->fs_maxsymlinklen <= 0) namlen = dp->d_type; else #endif namlen = dp->d_namlen; if (namlen == length && !strcmp(name, dp->d_name)) { /* found entry */ *inumber_p = dp->d_ino; return (0); } next: dp = (struct direct *)((char *)dp + dp->d_reclen); } fp->f_seekp += buf_size; } return (ENOENT); }
int ufs2_readdir(struct open_file *f, char *name) { struct file *fp = (struct file *)f->f_fsdata; struct direct *dp, *edp; size_t buf_size; int rc, namlen; char *buf; if (name == NULL) fp->f_seekp = 0; else { /* end of dir */ if (fp->f_seekp >= fp->f_di.di_size) { *name = '\0'; return -1; } do { if ((rc = buf_read_file(f, &buf, &buf_size)) != 0) return rc; dp = (struct direct *)buf; edp = (struct direct *)(buf + buf_size); while (dp < edp && dp->d_ino == 0) dp = (struct direct *)((char *)dp + dp->d_reclen); fp->f_seekp += buf_size - ((u_int8_t *)edp - (u_int8_t *)dp); } while (dp >= edp); #if BYTE_ORDER == LITTLE_ENDIAN if (fp->f_fs->fs_maxsymlinklen <= 0) namlen = dp->d_type; else #endif namlen = dp->d_namlen; strncpy(name, dp->d_name, namlen + 1); fp->f_seekp += dp->d_reclen; } return 0; }
/* * Search a directory for a name and return its * inode number. */ static int search_directory(const char *name, int length, struct open_file *f, ino32_t *inumber_p) { struct file *fp = (struct file *)f->f_fsdata; struct direct *dp; struct direct *edp; char *buf; size_t buf_size; int namlen; int rc; fp->f_seekp = 0; while (fp->f_seekp < (off_t)fp->f_di.di_size) { rc = buf_read_file(f, &buf, &buf_size); if (rc) return rc; dp = (struct direct *)buf; edp = (struct direct *)(buf + buf_size); for (;dp < edp; dp = (void *)((char *)dp + dp->d_reclen)) { if (dp->d_reclen <= 0) break; if (dp->d_ino == (ino32_t)0) continue; #if BYTE_ORDER == LITTLE_ENDIAN if (fp->f_fs->fs_maxsymlinklen <= 0) namlen = dp->d_type; else #endif namlen = dp->d_namlen; if (namlen == length && !memcmp(name, dp->d_name, length)) { /* found entry */ *inumber_p = dp->d_ino; return 0; } } fp->f_seekp += buf_size; } return ENOENT; }
/* * Search a directory for a name and return its * inode number. */ static int search_directory(const char *name, int length, struct open_file *f, ino32_t *inumber_p) { struct file *fp = (struct file *)f->f_fsdata; struct ext2fs_direct *dp; struct ext2fs_direct *edp; char *buf; size_t buf_size; int namlen; int rc; fp->f_seekp = 0; /* XXX should handle LARGEFILE */ while (fp->f_seekp < (off_t)fp->f_di.e2di_size) { rc = buf_read_file(f, &buf, &buf_size); if (rc) return rc; dp = (struct ext2fs_direct *)buf; edp = (struct ext2fs_direct *)(buf + buf_size); for (; dp < edp; dp = (void *)((char *)dp + fs2h16(dp->e2d_reclen))) { if (fs2h16(dp->e2d_reclen) <= 0) break; if (fs2h32(dp->e2d_ino) == (ino32_t)0) continue; namlen = dp->e2d_namlen; if (namlen == length && !memcmp(name, dp->e2d_name, length)) { /* found entry */ *inumber_p = fs2h32(dp->e2d_ino); return 0; } } fp->f_seekp += buf_size; } return ENOENT; }
__compactcall void ufs_ls(struct open_file *f, const char *pattern) { struct file *fp = (struct file *)f->f_fsdata; char *buf; size_t buf_size; entry_t *names = 0, *n, **np; fp->f_seekp = 0; while (fp->f_seekp < (off_t)fp->f_di.di_size) { struct direct *dp, *edp; int rc = buf_read_file(f, &buf, &buf_size); if (rc) goto out; /* some firmware might use block size larger than DEV_BSIZE */ if (buf_size < UFS_DIRBLKSIZ) goto out; dp = (struct direct *)buf; edp = (struct direct *)(buf + buf_size); for (; dp < edp; dp = (void *)((char *)dp + dp->d_reclen)) { const char *t; if (dp->d_ino == 0) continue; if (dp->d_type >= NELEM(typestr) || !(t = typestr[dp->d_type])) { /* * This does not handle "old" * filesystems properly. On little * endian machines, we get a bogus * type name if the namlen matches a * valid type identifier. We could * check if we read namlen "0" and * handle this case specially, if * there were a pressing need... */ printf("bad dir entry\n"); goto out; } if (pattern && !fnmatch(dp->d_name, pattern)) continue; n = alloc(sizeof *n + strlen(dp->d_name)); if (!n) { printf("%d: %s (%s)\n", dp->d_ino, dp->d_name, t); continue; } n->e_ino = dp->d_ino; n->e_type = dp->d_type; strcpy(n->e_name, dp->d_name); for (np = &names; *np; np = &(*np)->e_next) { if (strcmp(n->e_name, (*np)->e_name) < 0) break; } n->e_next = *np; *np = n; } fp->f_seekp += buf_size; } if (names) { entry_t *p_names = names; do { n = p_names; printf("%d: %s (%s)\n", n->e_ino, n->e_name, typestr[n->e_type]); p_names = n->e_next; } while (p_names); } else { printf("not found\n"); } out: if (names) { do { n = names; names = n->e_next; dealloc(n, 0); } while (names); } }
static int cd9660_readdir(struct open_file *f, struct dirent *d) { struct file *fp = (struct file *)f->f_fsdata; struct iso_directory_record *ep; size_t buf_size, reclen, namelen; int error = 0; int lenskip; char *buf, *name; again: if (fp->f_off >= fp->f_size) return (ENOENT); error = buf_read_file(f, &buf, &buf_size); if (error) return (error); ep = (struct iso_directory_record *)buf; if (isonum_711(ep->length) == 0) { daddr_t blkno; /* skip to next block, if any */ blkno = fp->f_off / ISO_DEFAULT_BLOCK_SIZE; fp->f_off = (blkno + 1) * ISO_DEFAULT_BLOCK_SIZE; goto again; } if (fp->f_flags & F_RR) { if (fp->f_flags & F_ROOTDIR && fp->f_off == 0) lenskip = 0; else lenskip = fp->f_susp_skip; name = rrip_lookup_name(f, ep, lenskip, &namelen); } else name = NULL; if (name == NULL) { namelen = isonum_711(ep->name_len); name = ep->name; if (namelen == 1) { if (ep->name[0] == 0) name = "."; else if (ep->name[0] == 1) { namelen = 2; name = ".."; } } } reclen = sizeof(struct dirent) - (MAXNAMLEN+1) + namelen + 1; reclen = (reclen + 3) & ~3; d->d_fileno = isonum_733(ep->extent); d->d_reclen = reclen; if (isonum_711(ep->flags) & 2) d->d_type = DT_DIR; else d->d_type = DT_REG; d->d_namlen = namelen; bcopy(name, d->d_name, d->d_namlen); d->d_name[d->d_namlen] = 0; fp->f_off += isonum_711(ep->length); return (0); }