예제 #1
0
파일: dir.c 프로젝트: dzavalishin/oskit
int ufs_check_dir_entry (const char * function,	struct inode * dir,
	struct ufs_dir_entry * de, struct buffer_head * bh, 
	unsigned long offset)
{
	struct super_block * sb;
	const char * error_msg;
	unsigned flags, swab;
	
	sb = dir->i_sb;
	flags = sb->u.ufs_sb.s_flags;
	swab = sb->u.ufs_sb.s_swab;
	error_msg = NULL;
			
	if (SWAB16(de->d_reclen) < UFS_DIR_REC_LEN(1))
		error_msg = "reclen is smaller than minimal";
	else if (SWAB16(de->d_reclen) % 4 != 0)
		error_msg = "reclen % 4 != 0";
	else if (SWAB16(de->d_reclen) < UFS_DIR_REC_LEN(ufs_get_de_namlen(de)))
		error_msg = "reclen is too small for namlen";
	else if (dir && ((char *) de - bh->b_data) + SWAB16(de->d_reclen) >
		 dir->i_sb->s_blocksize)
		error_msg = "directory entry across blocks";
	else if (dir && SWAB32(de->d_ino) > (sb->u.ufs_sb.s_uspi->s_ipg * sb->u.ufs_sb.s_uspi->s_ncg))
		error_msg = "inode out of bounds";

	if (error_msg != NULL)
		ufs_error (sb, function, "bad entry in directory #%lu, size %lu: %s - "
			    "offset=%lu, inode=%lu, reclen=%d, namlen=%d",
			    dir->i_ino, dir->i_size, error_msg, offset,
			    (unsigned long) SWAB32(de->d_ino),
			    SWAB16(de->d_reclen), ufs_get_de_namlen(de));
	
	return (error_msg == NULL ? 1 : 0);
}
예제 #2
0
파일: dir.c 프로젝트: dzavalishin/oskit
/*
 * This is blatantly stolen from ext2fs
 */
static int
ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
{
	struct inode *inode = filp->f_dentry->d_inode;
	int error = 0;
	unsigned long offset, lblk, blk;
	int i, stored;
	struct buffer_head * bh;
	struct ufs_dir_entry * de;
	struct super_block * sb;
	int de_reclen;
	unsigned flags, swab;

	sb = inode->i_sb;
	swab = sb->u.ufs_sb.s_swab;
	flags = sb->u.ufs_sb.s_flags;

	UFSD(("ENTER, ino %lu  f_pos %lu\n", inode->i_ino, (unsigned long) filp->f_pos))

	stored = 0;
	bh = NULL;
	offset = filp->f_pos & (sb->s_blocksize - 1);

	while (!error && !stored && filp->f_pos < inode->i_size) {
		lblk = (filp->f_pos) >> sb->s_blocksize_bits;
		/* XXX - ufs_bmap() call needs error checking */
		blk = ufs_bmap(inode, lblk);
		bh = bread (sb->s_dev, blk, sb->s_blocksize);
		if (!bh) {
			/* XXX - error - skip to the next block */
			printk("ufs_readdir: "
			       "dir inode %lu has a hole at offset %lu\n",
			       inode->i_ino, (unsigned long int)filp->f_pos);
			filp->f_pos += sb->s_blocksize - offset;
			continue;
		}

revalidate:
		/* If the dir block has changed since the last call to
		 * readdir(2), then we might be pointing to an invalid
		 * dirent right now.  Scan from the start of the block
		 * to make sure. */
		if (filp->f_version != inode->i_version) {
			for (i = 0; i < sb->s_blocksize && i < offset; ) {
				de = (struct ufs_dir_entry *)(bh->b_data + i);
				/* It's too expensive to do a full
				 * dirent test each time round this
				 * loop, but we do have to test at
				 * least that it is non-zero.  A
				 * failure will be detected in the
				 * dirent test below. */
				de_reclen = SWAB16(de->d_reclen);
				if (de_reclen < 1)
					break;
				i += de_reclen;
			}
			offset = i;
			filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
				| offset;
			filp->f_version = inode->i_version;
		}

		while (!error && filp->f_pos < inode->i_size
		       && offset < sb->s_blocksize) {
			de = (struct ufs_dir_entry *) (bh->b_data + offset);
			/* XXX - put in a real ufs_check_dir_entry() */
			if ((de->d_reclen == 0) || (ufs_get_de_namlen(de) == 0)) {
			/* SWAB16() was unneeded -- compare to 0 */
				filp->f_pos = (filp->f_pos &
				              (sb->s_blocksize - 1)) +
				               sb->s_blocksize;
				brelse(bh);
				return stored;
			}
			if (!ufs_check_dir_entry ("ufs_readdir", inode, de,
						   bh, offset)) {
				/* On error, skip the f_pos to the
				   next block. */
				filp->f_pos = (filp->f_pos &
				              (sb->s_blocksize - 1)) +
					       sb->s_blocksize;
				brelse (bh);
				return stored;
			}
			offset += SWAB16(de->d_reclen);
			if (de->d_ino) {
			/* SWAB16() was unneeded -- compare to 0 */
				/* We might block in the next section
				 * if the data destination is
				 * currently swapped out.  So, use a
				 * version stamp to detect whether or
				 * not the directory has been modified
				 * during the copy operation. */
				unsigned long version = inode->i_version;

				UFSD(("filldir(%s,%u)\n", de->d_name, SWAB32(de->d_ino)))
				UFSD(("namlen %u\n", ufs_get_de_namlen(de)))
				error = filldir(dirent, de->d_name, ufs_get_de_namlen(de),
						filp->f_pos, SWAB32(de->d_ino));
				if (error)
					break;
				if (version != inode->i_version)
					goto revalidate;
				stored ++;
			}
			filp->f_pos += SWAB16(de->d_reclen);
		}
		offset = 0;
		brelse (bh);
	}
	UPDATE_ATIME(inode);
	return 0;
}
예제 #3
0
struct GWaveform * loadWaveform(int file)
{
    struct GWaveform * wav = (struct GWaveform *)allocate(sizeof(struct GWaveform));
    rb->memset(wav, 0, sizeof(struct GWaveform));

    wav->name=readData(file, 7);
    printf("\nWAVE NAME = [%s]", wav->name);
    wav->fractions=readChar(file);
    wav->wavSize=readDWord(file);
    wav->startLoop=readDWord(file);
    wav->endLoop=readDWord(file);
    wav->sampRate=readWord(file);

    wav->lowFreq=readDWord(file);
    wav->highFreq=readDWord(file);
    wav->rootFreq=readDWord(file);

    wav->tune=readWord(file);

    wav->balance=readChar(file);
    wav->envRate=readData(file, 6);
    wav->envOffset=readData(file, 6);

    wav->tremSweep=readChar(file);
    wav->tremRate==readChar(file);
    wav->tremDepth=readChar(file);
    wav->vibSweep=readChar(file);
    wav->vibRate=readChar(file);
    wav->vibDepth=readChar(file);
    wav->mode=readChar(file);

    wav->scaleFreq=readWord(file);
    wav->scaleFactor=readWord(file);
    printf("\nScaleFreq = %d   ScaleFactor = %d   RootFreq = %d", wav->scaleFreq, wav->scaleFactor, wav->rootFreq);
    wav->res=readData(file, 36);
    wav->data=readData(file, wav->wavSize);

    wav->numSamples = wav->wavSize / 2;
    wav->startLoop = wav->startLoop >> 1;
    wav->endLoop = wav->endLoop >> 1;
    unsigned int a=0;

    /* half baked 8 bit conversion  UNFINISHED*/
    /*
    if(wav->mode & 1 == 0)  //Whoops, 8 bit
    {
        wav->numSamples = wav->wavSize;

        //Allocate a block for the rest of it
        //It should end up right after the previous one.
        wav->wavSize = wav->wavSize * 2;
        void * foo = allocate(wav->wavSize);


        for(a=0; a<1000; a++)
            printf("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!");


        for(a=wav->wavSize-1; a>0; a-=2)
        {

        }
    //  int b1=wf->data[s]+((wf->mode & 2) << 6);
    //  return b1<<8;
    }
    */


    /* Iriver needs byteswapping.. big endian, go figure. Gus files are little endian */

#if !defined(SIMULATOR)
    for(a=0; a<wav->numSamples; a++)
    {
        ((unsigned short *) wav->data)[a] = SWAB16(((unsigned short *) wav->data)[a]);
    }
#endif

    /*  Convert unsigned to signed by subtracting 32768 */
    if(wav->mode & 2)
    {
        for(a=0; a<wav->numSamples; a++)
            ((short *) wav->data)[a] = ((unsigned short *) wav->data)[a] - 32768;

    }

    return wav;
}