Exemple #1
0
Fichier : disk.c Projet : jaw0/osj5
int
dkpart_bread(FILE *f, char *buf, int len, offset_t pos){
    struct DiskPart *dev;

    if(!f) return;
    dev = (struct DiskPart *)f->d;

    if( pos + len > dev->part_len ){
	kprintf("%s attempt to read past end of device (%d @%d)\n", dev->name, len, pos);
	return -1;
    }

    return fbread(dev->fdev, buf, len, pos + dev->part_offset);
}
Exemple #2
0
extern int fbread(struct fb *fb)
{
	fd_set fdset;
	struct timeval tv;
	int i, key;

	if(!fb->hw) return 0;
	if(fb->hw->nfds == -1) return 0;
	for(i=0; i<5; i++) {
		if(fb->hw->ms.micev[i]) {
			key = fb->hw->ms.micev[i];
			fb->hw->ms.micev[i] = 0;
			return key;
		}
	}
	tv.tv_sec = tv.tv_usec = 0;
	fdset = fb->hw->fdset;

	if(select(fb->hw->nfds+1, &fdset, 0, 0, &tv) > 0) {
		if(fb->hw->kb.fd != -1) {
			if(FD_ISSET(fb->hw->kb.fd, &fdset)) {
				return kbread(fb);
			}
		}
		if(fb->hw->ms.fd != -1) {
			if(FD_ISSET(fb->hw->ms.fd, &fdset)) {
				int btn, oldbtn, dx, dy;
				if((btn = msread(fb, &dx, &dy)) != -1) {
					if(dx != 0) fb->hw->ms.micev[0] = dx<<16 | MICE_DX;
					if(dy != 0) fb->hw->ms.micev[1] = dy<<16 | MICE_DY;
					oldbtn = fb->hw->ms.oldbtn;
					if((oldbtn & 0x1) && !(btn & 0x1)) fb->hw->ms.micev[2] = MICE_LEFT | 0x8000;
					if(!(oldbtn & 0x1) && (btn & 0x1)) fb->hw->ms.micev[2] = MICE_LEFT;
					if((oldbtn & 0x2) && !(btn & 0x2)) fb->hw->ms.micev[3] = MICE_RIGHT | 0x8000;
					if(!(oldbtn & 0x2) && (btn & 0x2)) fb->hw->ms.micev[3] = MICE_RIGHT;
					if((oldbtn & 0x4) && !(btn & 0x4)) fb->hw->ms.micev[4] = MICE_MIDDLE | 0x8000;
					if(!(oldbtn & 0x4) && (btn & 0x4)) fb->hw->ms.micev[4] = MICE_MIDDLE;
					fb->hw->ms.oldbtn = btn;
					return fbread(fb);
				}
			}
		}
	}
	return 0;
}
Exemple #3
0
static int i_read_binary_uchar(FILE *fpin, AN2KBDB *buf,
                               unsigned char *ouchar_val)
{
    unsigned char uchar_val;

    /* Read unsigned short bytes. */
    if(fbread(&uchar_val, sizeof(unsigned char), 1, fpin, buf) != 1) {
        fprintf(stderr, "ERROR : read_binary_uchar : "
                "read : uchar not read, at %ld: %s\n",
                fbtell(fpin, buf), SHORT_READ_ERR_MSG(fpin));
        return(-2);
    }

    *ouchar_val = uchar_val;

    /* Return normally. */
    return(0);
}
Exemple #4
0
Fichier : disk.c Projet : jaw0/osj5
int
dkpart_learn(struct Device_Conf *cf, const char *pfx, int dkno, FILE *fdev, offset_t blks){
    int i;

    // is this in the conf table?
    if( dkpart_configured(cf, pfx, dkno, -1, fdev, 0, blks)) return 0;

    // read part table
    char *buf = alloc(512);
    fbread(fdev, buf, DISK_BLOCK_SIZE, 0);

    // RSN - is this an mbr? check more

    if( ! is_an_mbr(buf) ){
        // entire disk
        // RSN - determine type from data or config table
        const char *fstype = "fatfs";

        dkpart_init(cf, pfx, dkno, 0, 0, blks, fdev, fstype, 0);
        free(buf, 512);
        return 0;
    }

    // init all partitions
    for(i=0; i<4; i++){
        offset_t start = mbr_val(buf, i, MBR_PART_STARTSEC_OFF);
        offset_t len   = mbr_val(buf, i, MBR_PART_NUMSEC_OFF);

        // configured ?
        if( dkpart_configured(cf, pfx, dkno, i, fdev, start, len)) continue;

        // use fs type in mbr
        const char *fstype = mbr_fs( buf[MBR_PART_START + i * MBR_PART_LEN + MBR_PART_TYPE_OFF] );

        if( fstype ){
            dkpart_init(cf, pfx, dkno, i, start, len, fdev, fstype, 0);
        }
        // else ?
    }

    free(buf, 512);
    return 0;
}
Exemple #5
0
/*
 * Local functions to do the actual reading or scanning work.
 */
static int i_read_binary_uint(FILE *fpin, AN2KBDB *buf, unsigned int *ouint_val)
{
    unsigned int uint_val;

    /* Read unsigned integer bytes. */
    if(fbread(&uint_val, sizeof(unsigned int), 1, fpin, buf) != 1) {
        fprintf(stderr, "ERROR : read_binary_uint : "
                "read : uint not read, at %ld: %s\n",
                fbtell(fpin, buf), SHORT_READ_ERR_MSG(fpin));
        return(-2);
    }

#ifdef __NBISLE__
    swap_uint_bytes(uint_val);
#endif

    *ouint_val = uint_val;

    /* Return normally. */
    return(0);
}
Exemple #6
0
void domkdir (int argc, char **argv)
{
	int	n;
	firqb	f;
	int	newclu;
	char	*p;
	word	link, ulink, alink, qlink;
	uattr	*u;
	ua_qt2	*q;

	if (argc == 0) {
		printf ("Usage: %s mkdir dir...\n", progname);
		return;
	}
	rmountrw ();
	if (sw.clusiz == NULL) {
		newclu = pcs;
		if (newclu > 16) newclu = 16;
	} else {
		newclu = strtol (sw.clusiz, &p, 10);
		if (newclu < 0) {
			newclu = -newclu;
			if (newclu < pcs) {
				newclu = pcs;
				if (newclu > 16) newclu = 16;
			}
		}
		if (*p != '\0' || (newclu < pcs && newclu < 16)
		    || newclu > 16 ||
		    (newclu & (-newclu)) != newclu) {
			rumountrw ();		/* dismount first */
			printf ("Invalid clustersize %s\n", sw.clusiz);
			return;
		}
	}
	for (n = 0; n < argc; n++) {
		if (!parse (argv[n], &f) || f.flags != f_ppn) {
			printf ("Invalid PPN %s\n", argv[n]);
			continue;
		}
		if (initfilescan (&f, gfdatrtbl)) {
			printf ("Directory [%d,%d] already exists\n", 
				f.cproj, f.cprog);
		} else {
			f.cproj = f.proj;	/* set up for makedir */
			f.cprog = f.prog;
			if (makedir (&f, newclu)) {
				if (sw.user != NULL) {
					fbread (curgfd + gfdatrtbl);
					link = fibufw[f.cprog];
					readlktbl (link);
					alink = use(gfdne,k)->ulnk;
					if ((ulink = getent ()) == 0)
					    printf ("No room to mark account as user account\n");
					else {
						readlk (ulink);
						u = use(uattr,k);
						u->ulnk = alink;
						u->uatyp = aa_pas;
						MARKF;
						if ((qlink = getent ()) == 0) {
							printf ("No room for second quota block\n");
							qlink = ulink;
						} else {
							readlk (qlink);
							q = use(ua_qt2,k);
							q->ulnk = ulink;
							q->uatyp = aa_qt2;
							q->a2_job = 255U;
							q->a2_rib = 4;
							q->a2_msg = 12;
							MARKF;
						}
						readlk (link);
						use(gfdne,k)->ulnk = qlink;
						MARKF;
					}
				}
				if (sw.verbose != NULL)
				printf ("Account [%d,%d] created\n", 
					f.proj, f.prog);
			}
		}
	}
	rumountrw ();
}
int32_t
ud_write_fid(struct ud_inode *dp, struct slot *slot, uint8_t *buf)
{
	struct udf_vfs *udf_vfsp;
	struct fbuf *lfbp;
	struct file_id *fid;
	int32_t error = 0;
	uint32_t lbsize, lbmask, count, old_count;


	ASSERT(slot->fbp);
	ASSERT(slot->ep);

	udf_vfsp = dp->i_udf;
	fid = slot->ep;
	lbsize = dp->i_udf->udf_lbsize;
	lbmask = dp->i_udf->udf_lbmask;

	if (((uint8_t *)fid >= buf) &&
		((uint8_t *)fid < &buf[udf_vfsp->udf_lbsize])) {


		if ((error = fbread(ITOV(dp),
			(offset_t)(slot->offset & ~lbmask),
			lbsize, S_WRITE, &lfbp)) != 0) {
			goto out;
		}


		/*
		 * We do not need to write the
		 * file name. So check if the entry
		 * does not cross a block boundary
		 * and write only required portions
		 */
		if (((slot->offset & lbmask) +
			sizeof (struct file_id)) > lbsize) {

			if ((slot->offset & lbmask) != 0) {
				old_count = lbsize -
					(slot->offset & lbmask);
				count = (slot->offset +
					sizeof (struct file_id)) &
					lbmask;
			} else {
				old_count = 0;
				count = sizeof (struct file_id);
			}

			bcopy(buf, lfbp->fb_addr +
				(slot->offset & lbmask), old_count);
			bcopy(buf + old_count,
				slot->fbp->fb_addr, count);

			error = ud_fbwrite(lfbp, dp);

			error = ud_fbwrite(slot->fbp, dp);
		} else {
			bcopy(buf, lfbp->fb_addr +
				(slot->offset & lbmask),
				sizeof (struct file_id));

			error = ud_fbwrite(lfbp, dp);

			fbrelse(slot->fbp, S_OTHER);
		}
	} else {
		if ((error = ud_fbwrite(slot->fbp, dp)) != 0) {
			fid->fid_flags &= ~FID_DELETED;
			ud_make_tag(dp->i_udf, &fid->fid_tag, UD_FILE_ID_DESC,
				SWAP_32(fid->fid_tag.tag_loc), FID_LEN(fid));
		}
	}
	slot->fbp = NULL;

out:
	return (error);
}
/*
 * Fix the FID_PARENT entry of the child directory so that it points
 * to the new parent directory instead of the old one.  Routine
 * assumes that dp is a directory and that all the inodes are on
 * the same file system.
 */
int
ud_dirfixdotdot(struct ud_inode *dp,
	struct ud_inode *opdp, struct ud_inode *npdp)
{
	int32_t err = 0;
	struct fbuf *fbp;
	struct file_id *fid;
	uint32_t loc, dummy, tbno;

	ud_printf("ud_dirfixdotdot\n");

	ASSERT(opdp->i_type == VDIR);
	ASSERT(npdp->i_type == VDIR);

	ASSERT(RW_WRITE_HELD(&npdp->i_rwlock));

	err = fbread(ITOV(dp), (offset_t)0,
			dp->i_udf->udf_lbsize, S_WRITE, &fbp);

	if (err || dp->i_nlink == 0 ||
		dp->i_size < sizeof (struct file_id)) {
		goto bad;
	}

	if ((err = ud_ip_off2bno(dp, 0, &tbno)) != 0) {
		goto bad;
	}

	fid = (struct file_id *)fbp->fb_addr;
	if ((ud_verify_tag_and_desc(&fid->fid_tag, UD_FILE_ID_DESC,
	    tbno,
	    1, dp->i_udf->udf_lbsize) != 0) ||
	    ((fid->fid_flags & (FID_DIR | FID_PARENT)) !=
	    (FID_DIR | FID_PARENT))) {
		err = ENOTDIR;
		goto bad;
	}

	loc = ud_xlate_to_daddr(dp->i_udf,
		SWAP_16(fid->fid_icb.lad_ext_prn),
		SWAP_32(fid->fid_icb.lad_ext_loc), 1, &dummy);
	ASSERT(dummy == 1);
	if (loc == npdp->i_icb_lbano) {
		goto bad;
	}

	/*
	 * Increment the link count in the new parent inode and force it out.
	 */
	if (npdp->i_nlink == MAXLINK) {
		err = EMLINK;
		goto bad;
	}

	npdp->i_nlink++;
	mutex_enter(&npdp->i_tlock);
	npdp->i_flag |= ICHG;
	mutex_exit(&npdp->i_tlock);
	ud_iupdat(npdp, 1);

	/*
	 * Rewrite the child FID_PARENT entry and force it out.
	 */
	dnlc_remove(ITOV(dp), "..");
	fid->fid_icb.lad_ext_loc = SWAP_32(npdp->i_icb_block);
	fid->fid_icb.lad_ext_prn = SWAP_16(npdp->i_icb_prn);
	ud_make_tag(npdp->i_udf, &fid->fid_tag,
		UD_FILE_ID_DESC, tbno, FID_LEN(fid));
	dnlc_enter(ITOV(dp), "..", ITOV(npdp));

	err = ud_fbwrite(fbp, dp);
	fbp = NULL;
	if (err != 0) {
		goto bad;
	}

	/*
	 * Decrement the link count of the old parent inode and force
	 * it out.  If opdp is NULL, then this is a new directory link;
	 * it has no parent, so we need not do anything.
	 */
	if (opdp != NULL) {
		rw_enter(&opdp->i_contents, RW_WRITER);
		if (opdp->i_nlink != 0) {
			opdp->i_nlink--;
			mutex_enter(&opdp->i_tlock);
			opdp->i_flag |= ICHG;
			mutex_exit(&opdp->i_tlock);
			ud_iupdat(opdp, 1);
		}
		rw_exit(&opdp->i_contents);
	}
	return (0);

bad:
	if (fbp) {
		fbrelse(fbp, S_OTHER);
	}
	return (err);
}
/*
 * 1. When we find a slot that belonged to a file which was deleted
 *      and is in the middle of the directory
 * 2. There is not empty slot available. The new entry
 *      will be at the end of the directory and fits in the same block.
 * 3. There is no empty slot available. The new
 *      entry will not fit the left over directory
 *      so we need to allocate a new block. If
 *      we cannot allocate a proximity block we need
 *      to allocate a new icb, and data block.
 */
int
ud_dirprepareentry(struct ud_inode *dp,
	struct slot *slotp, uint8_t *buf, struct cred *cr)
{
	struct fbuf *fbp;
	uint16_t old_dtype;
	int32_t error = 0;
	uint32_t entrysize, count, offset, tbno, old_size, off;
	struct file_id *fid;
	int32_t lbsize, lbmask, mask;

	ASSERT(RW_WRITE_HELD(&dp->i_rwlock));

	ASSERT((slotp->status == NONE) ||
		(slotp->status == FOUND));

	ud_printf("ud_dirprepareentry\n");
	lbsize = dp->i_udf->udf_lbsize;
	lbmask = dp->i_udf->udf_lbmask;
	mask = ~lbmask;

	fid = (struct file_id *)buf;
	entrysize = FID_LEN(fid);

	/*
	 * If we didn't find a slot, then indicate that the
	 * new slot belongs at the end of the directory.
	 * If we found a slot, then the new entry can be
	 * put at slotp->offset.
	 */
	if (slotp->status == NONE) {
		/*
		 * We did not find a slot, the next
		 * entry will be in the end of the directory
		 * see if we can fit the new entry inside
		 * the old block. If not allocate a new block.
		 */
		if (entrysize > slotp->size) {
			/*
			 * extend the directory
			 * size by one new block
			 */
			old_dtype = dp->i_desc_type;
			old_size = (uint32_t)dp->i_size;
			error = ud_bmap_write(dp, slotp->offset,
				blkoff(dp->i_udf, slotp->offset) + entrysize,
				0, cr);
			if (error != 0) {
				return (error);
			}
			if (old_dtype != dp->i_desc_type) {
				/*
				 * oops we changed the astrat
				 * of the file, we have to
				 * recaliculate tags
				 * fortunately we donot have more
				 * than one lbsize to handle here
				 */
				if ((error = ud_ip_off2bno(dp,
						0, &tbno)) != 0) {
					return (error);
				}
				if ((error = fbread(ITOV(dp), 0,
						dp->i_udf->udf_lbsize,
						S_WRITE, &fbp)) != 0) {
					return (error);
				}
				off = 0;
				while (off < old_size) {
					struct file_id *tfid;

					tfid = (struct file_id *)
						(fbp->fb_addr + off);

					ud_make_tag(dp->i_udf, &tfid->fid_tag,
					UD_FILE_ID_DESC, tbno, FID_LEN(tfid));

					off += FID_LEN(tfid);
				}
				if (error = ud_fbwrite(fbp, dp)) {
					return (error);
				}
			}
		} else {
			/* Extend the directory size */
			if (dp->i_desc_type != ICB_FLAG_ONE_AD) {
				ASSERT(dp->i_ext);
				dp->i_ext[dp->i_ext_used - 1].ib_count +=
						entrysize;
			}
		}
		dp->i_size += entrysize;
		dp->i_flag |= IUPD|ICHG|IATTCHG;
		ITIMES_NOLOCK(dp);
	} else if (slotp->status != FOUND) {
		cmn_err(CE_WARN, "status is not NONE/FOUND");
		return (EINVAL);
	}

	if ((error = ud_ip_off2bno(dp, slotp->offset, &tbno)) != 0) {
		return (error);
	}
	ud_make_tag(dp->i_udf, &fid->fid_tag,
			UD_FILE_ID_DESC, tbno, FID_LEN(fid));

	/*
	 * fbread cannot cross a
	 * MAXBSIZE boundary so handle it here
	 */
	offset = slotp->offset;
	if ((error = fbread(ITOV(dp), offset & mask, lbsize,
				S_WRITE, &fbp)) != 0) {
		return (error);
	}
	if ((offset & mask) != ((offset + entrysize) & mask)) {
		count = entrysize - ((offset + entrysize) & lbmask);
	} else {
		count = entrysize;
	}
	bcopy((caddr_t)buf, fbp->fb_addr + (offset & lbmask), count);

	if (error = ud_fbwrite(fbp, dp)) {
		return (error);
	}

	if (entrysize > count) {
		if ((error = fbread(ITOV(dp), (offset + entrysize) & mask,
				lbsize, S_WRITE, &fbp)) != 0) {
			return (error);
		}
		bcopy((caddr_t)(buf + count), fbp->fb_addr, entrysize - count);
		if (error = ud_fbwrite(fbp, dp)) {
			return (error);
		}
	}

	dp->i_flag |= IUPD|ICHG|IATTCHG;
	ITIMES_NOLOCK(dp);
	return (error);
}
/* ARGSUSED2 */
int
ud_dirmakedirect(struct ud_inode *ip,
	struct ud_inode *dp, struct cred *cr)
{
	int32_t err;
	uint32_t blkno, size, parent_len, tbno;
	struct fbuf *fbp;
	struct file_id *fid;
	struct icb_ext *iext;

	ud_printf("ud_dirmakedirect\n");

	ASSERT(RW_WRITE_HELD(&ip->i_contents));
	ASSERT(RW_WRITE_HELD(&dp->i_rwlock));

	parent_len = sizeof (struct file_id);

	if ((ip->i_desc_type != ICB_FLAG_ONE_AD) ||
		(parent_len > ip->i_max_emb)) {
		ASSERT(ip->i_ext);
		/*
		 * Allocate space for the directory we're creating.
		 */
		if ((err = ud_alloc_space(ip->i_vfs, ip->i_icb_prn,
				0, 1, &blkno, &size, 0, 0)) != 0) {
			return (err);
		}
		/*
		 * init with the size of
		 * directory with just the
		 * parent
		 */
		ip->i_size = sizeof (struct file_id);
		ip->i_flag |= IUPD|ICHG|IATTCHG;
		iext = ip->i_ext;
		iext->ib_prn = ip->i_icb_prn;
		iext->ib_block = blkno;
		iext->ib_count = ip->i_size;
		iext->ib_offset = 0;
		ip->i_ext_used = 1;
	} else {
		ip->i_size = sizeof (struct file_id);
		ip->i_flag |= IUPD|ICHG|IATTCHG;
	}

	ITIMES_NOLOCK(ip);

	/*
	 * Update the dp link count and write out the change.
	 * This reflects the ".." entry we'll soon write.
	 */
	if (dp->i_nlink == MAXLINK) {
		return (EMLINK);
	}
	dp->i_nlink++;
	dp->i_flag |= ICHG;
	ud_iupdat(dp, 1);

	/*
	 * Initialize directory with ".."
	 * Since the parent directory is locked, we don't have to
	 * worry about anything changing when we drop the write
	 * lock on (ip).
	 */
	rw_exit(&ip->i_contents);
	if ((err = fbread(ITOV(ip), (offset_t)0,
			ip->i_udf->udf_lbsize, S_WRITE, &fbp)) != 0) {
		rw_enter(&ip->i_contents, RW_WRITER);
		return (err);
	}

	bzero(fbp->fb_addr, ip->i_udf->udf_lbsize);

	fid = (struct file_id *)fbp->fb_addr;
	fid->fid_ver = SWAP_16(1);
	fid->fid_flags = FID_DIR | FID_PARENT;
	fid->fid_icb.lad_ext_len = SWAP_32(dp->i_udf->udf_lbsize);
	fid->fid_icb.lad_ext_loc = SWAP_32(dp->i_icb_block);
	fid->fid_icb.lad_ext_prn = SWAP_16(dp->i_icb_prn);

	/*
	 * fid_idlen, fid_iulen and fid_spec are zero
	 * due to bzero above
	 */

	if ((err = ud_ip_off2bno(ip, 0, &tbno)) == 0) {
		ud_make_tag(ip->i_udf, &fid->fid_tag,
			UD_FILE_ID_DESC, tbno, FID_LEN(fid));
	}

	err = ud_fbwrite(fbp, ip);
	rw_enter(&ip->i_contents, RW_WRITER);

	return (err);
}
int
ud_dircheckpath(int32_t blkno,
	struct ud_inode *target, struct cred *cr)
{
	int32_t err = 0;
	struct vfs *vfsp;
	struct udf_vfs *udf_vfsp;
	struct fbuf *fbp;
	struct file_id *fid;
	struct ud_inode *ip, *tip;
	uint16_t prn;
	uint32_t lbno, dummy, tbno;
	daddr_t parent_icb_loc;

	ud_printf("ud_dircheckpath\n");

	udf_vfsp = target->i_udf;
	ip = target;

	ASSERT(udf_vfsp != NULL);
	ASSERT(MUTEX_HELD(&target->i_udf->udf_rename_lck));
	ASSERT(RW_WRITE_HELD(&ip->i_rwlock));

	if (ip->i_icb_lbano == blkno) {
		err = EINVAL;
		goto out;
	}
	if (ip->i_icb_lbano == udf_vfsp->udf_root_blkno) {
		goto out;
	}

	/*
	 * Search back through the directory tree, using the PARENT entries
	 * Fail any attempt to move a directory into an ancestor directory.
	 */
	for (;;) {
		if ((err = fbread(ITOV(ip), 0,
			udf_vfsp->udf_lbsize, S_READ, &fbp)) != 0) {
			break;
		}

		if ((err = ud_ip_off2bno(ip, 0, &tbno)) != 0) {
			break;
		}
		fid = (struct file_id *)fbp->fb_addr;
		/* IS this a valid file_identifier */
		if (ud_verify_tag_and_desc(&fid->fid_tag,
		    UD_FILE_ID_DESC,
		    tbno,
		    1, udf_vfsp->udf_lbsize) != 0) {
			break;
		}
		if ((fid->fid_flags & FID_DELETED) != 0) {
			break;
		}
		if ((fid->fid_flags & FID_PARENT) == 0) {
			/*
			 * This cannot happen unless
			 * something is grossly wrong
			 * First entry has to be parent
			 */
			break;
		}
		prn = SWAP_16(fid->fid_icb.lad_ext_prn);
		lbno = SWAP_32(fid->fid_icb.lad_ext_loc);
		parent_icb_loc = ud_xlate_to_daddr(udf_vfsp,
				prn, lbno, 1, &dummy);
		ASSERT(dummy == 1);
		if (parent_icb_loc == blkno) {
			err = EINVAL;
			break;
		}
		vfsp = ip->i_vfs;
		udf_vfsp = ip->i_udf;
		if (parent_icb_loc == udf_vfsp->udf_root_blkno) {
			break;
		}
		if (fbp != NULL) {
			fbrelse(fbp, S_OTHER);
			fbp = NULL;
		}
		if (ip != target) {
			rw_exit(&ip->i_rwlock);
			VN_RELE(ITOV(ip));
		}

		/*
		 * Race to get the inode.
		 */
		if (err = ud_iget(vfsp, prn, lbno, &tip, NULL, cr)) {
			ip = NULL;
			break;
		}
		ip = tip;
		rw_enter(&ip->i_rwlock, RW_READER);
	}
	if (fbp) {
		fbrelse(fbp, S_OTHER);
	}
out:
	if (ip) {
		if (ip != target) {
			rw_exit(&ip->i_rwlock);
			VN_RELE(ITOV(ip));
		}
	}
	return (err);
}
Exemple #12
0
/* WILL FAIL IF FILE JUST OPENED
	 Movie info must have been read and we must be at mov offset */
static int bufferFrames(struct filebuffer * fb, struct framet * frames, int count)
{
	int curframe = 0;
	unsigned cur_off = 0;
	int doneBuff = 0;
	unsigned lastRead;
	aviChunkHdr hdr;
	unsigned char * frameptr;

	fb->startOff = ftell(fb->file);
	fb->globalOff = fb->startOff;
	fb->localOff = 0;
	fb->size = fread(fb->buffer, 1, VIDEO_FILEBUFFER_SIZE, fb->file);
	cur_off = fb->globalOff;

	while ((!doneBuff) && (curframe < count) && (fb->globalOff < fb->filesize)) {
		lastRead = fb->globalOff;

		if (fbread(&hdr, sizeof(hdr), fb)) {
			if (fourccCmp(hdr.ckID, "LIST")) {
				fbseek(fb, 4, SEEK_CUR);
			/*} else if ((fourccCmp(hdr.ckID, "00db") || (fourccCmp(hdr.ckID, "00dc")))) { */
			} else if ((fourccCmpLast2(hdr.ckID, "db")) || (fourccCmpLast2(hdr.ckID, "dc"))) {
				if (fb->localOff+hdr.ckSize > fb->size) {
					doneBuff = 1;
					fbseek(fb, -sizeof(hdr), SEEK_CUR);
				} else {
					frameptr = fb->buffer;
					frameptr += fb->localOff;
					frames[curframe].buffer = frameptr;
					frames[curframe].x = bitmapInfo.bmiHeader.biWidth;
					frames[curframe].y = bitmapInfo.bmiHeader.biHeight;
					frames[curframe].w = bitmapInfo.bmiHeader.biBitCount;
					curframe++;
					fbseek(fb, hdr.ckSize, SEEK_CUR);
				}
		/*	} else if ((fourccCmp(hdr.ckID, "01wb"))) {   */
			} else if ((fourccCmpLast2(hdr.ckID, "wb")) || (fourccCmpLast2(hdr.ckID, "wc"))) {

				if (fb->localOff+hdr.ckSize > fb->size) {
					doneBuff=1;
					fbseek(fb, -sizeof(hdr), SEEK_CUR);
				} else {
					if (video_useAudio)
					{	
						int lenavail = 0, lenavail2 = 0;
						
						lenavail = AUDIOBUFSIZE - audiowriteoff;
						if (lenavail <= 0)
							lenavail = 0;
						if (lenavail > hdr.ckSize)
							lenavail = hdr.ckSize;
						if (lenavail < hdr.ckSize)	
							lenavail2 = hdr.ckSize - lenavail;
						fbread(audiobuffer+audiowriteoff, lenavail, fb);
						audiowriteoff = (audiowriteoff + lenavail) % AUDIOBUFSIZE;	
	
						if (lenavail2 > 0)
						{
							fbread(audiobuffer, lenavail2, fb);
							audiowriteoff = lenavail2;
							fbseek(fb, -lenavail2, SEEK_CUR);
	
						}
						fbseek(fb, -lenavail, SEEK_CUR);	
	

					}	
					fbseek(fb, hdr.ckSize, SEEK_CUR);
				}
			} else {
				fbseek(fb, hdr.ckSize, SEEK_CUR);
			}
		} else {
			doneBuff=1;
		}
	}

	fseek(fb->file, fb->globalOff, SEEK_SET);

	return curframe;
}