Exemple #1
0
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);
}
Exemple #2
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;
}
Exemple #3
0
/*
 * 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;
}
Exemple #4
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);
}
Exemple #5
0
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);
}
Exemple #6
0
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);
}
Exemple #7
0
/*
 * 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);
}
Exemple #8
0
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);
}
Exemple #9
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;
}
Exemple #11
0
/*
 * 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);
}
Exemple #12
0
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;
}
Exemple #13
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;
}
Exemple #14
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 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;
}
Exemple #15
0
__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);
	}
}
Exemple #16
0
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);
}