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); }
/* * 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; }
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; }