Exemple #1
0
void fs_cmd_ls(int argc, char** argv) {
	Volume* volume;
	io_func* io;

	if(argc < 2) {
		bufferPrintf("usage: %s <partition> <directory>\r\n", argv[0]);
		return;
	}

	io = bdev_open(parseNumber(argv[1]));
	if(io == NULL) {
		bufferPrintf("fs: cannot read partition!\r\n");
		return;
	}

	volume = openVolume(io);
	if(volume == NULL) {
		bufferPrintf("fs: cannot openHFS volume!\r\n");
		return;
	}

	if(argc > 2)
		hfs_ls(volume, argv[2]);
	else
		hfs_ls(volume, "/");

	closeVolume(volume);
	CLOSE(io);
}
Exemple #2
0
static int bdev_usb_reset(struct device *dev)
{
	const char *usb_filename;
	int hw_fd; /* Underlying hardware of the block device. */
	struct block_device *bdev = dev_bdev(dev);

	usb_filename = map_block_to_usb_dev(bdev->filename);
	if (!usb_filename)
		err(EINVAL, "Block device `%s' is not backed by a USB device",
			bdev->filename);

	hw_fd = open(usb_filename, O_WRONLY | O_NONBLOCK);
	free((void *)usb_filename);
	usb_filename = NULL;
	if (hw_fd < 0)
		err(errno, "Can't open device `%s'", usb_filename);

	assert(!close(bdev->fd));
	assert(!ioctl(hw_fd, USBDEVFS_RESET));
	assert(!close(hw_fd));
	bdev->fd = bdev_open(bdev->filename);
	if (bdev->fd < 0)
		err(errno, "Can't REopen device `%s'", bdev->filename);
	return 0;
}
Exemple #3
0
/* XXX Monitor the USB subsytem to know when the drive was unplugged and
 * plugged back to continue instead of waiting for a key.
 */
static int bdev_manual_reset(struct device *dev)
{
	struct block_device *bdev = dev_bdev(dev);
	assert(!close(bdev->fd));
	printf("Please unplug and plug back the USB drive, and press a key to continue...\n");
	getchar();
	bdev->fd = bdev_open(bdev->filename);
	if (bdev->fd < 0)
		err(errno, "Can't REopen device `%s'", bdev->filename);
	return 0;
}
Exemple #4
0
/*===========================================================================*
 *				fs_readsuper				     *
 *===========================================================================*/
int fs_readsuper() {

  cp_grant_id_t label_gid;
  size_t label_len;
  int r = OK;
  int readonly;

  fs_dev    = fs_m_in.REQ_DEV;
  label_gid = fs_m_in.REQ_GRANT;
  label_len = fs_m_in.REQ_PATH_LEN;
  readonly  = 1;			/* Always mount devices read only. */

  if (label_len > sizeof(fs_dev_label)) 
	return(EINVAL);

  r = sys_safecopyfrom(fs_m_in.m_source, label_gid, 0, (vir_bytes)fs_dev_label,
		       label_len);
  if (r != OK) {
	printf("ISOFS %s:%d safecopyfrom failed: %d\n", __FILE__, __LINE__, r);
	return(EINVAL);
  }

  /* Map the driver label for this major */
  bdev_driver(fs_dev, fs_dev_label);

  /* Open the device the file system lives on */
  if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT)) != OK) {
        return(EINVAL);
  }

  /* Read the superblock */
  r = read_vds(&v_pri, fs_dev);
  if (r != OK) {
	bdev_close(fs_dev);
	return(r);
  }

  /* Return some root inode properties */
  fs_m_out.RES_INODE_NR = ID_DIR_RECORD(v_pri.dir_rec_root);
  fs_m_out.RES_MODE = v_pri.dir_rec_root->d_mode;
  fs_m_out.RES_FILE_SIZE_LO = v_pri.dir_rec_root->d_file_size;
  fs_m_out.RES_UID = SYS_UID; /* Always root */
  fs_m_out.RES_GID = SYS_GID; /* operator */

  fs_m_out.RES_CONREQS = 1;	/* We can handle only 1 request at a time */

  return(r);
}
Exemple #5
0
void fs_cmd_extract(int argc, char** argv) {
	Volume* volume;
	io_func* io;

	if(argc < 4) {
		bufferPrintf("usage: %s <partition> <file> <location>\r\n", argv[0]);
		return;
	}

	io = bdev_open(parseNumber(argv[1]));
	if(io == NULL) {
		bufferPrintf("fs: cannot read partition!\r\n");
		return;
	}

	volume = openVolume(io);
	if(volume == NULL) {
		bufferPrintf("fs: cannot openHFS volume!\r\n");
		return;
	}

	HFSPlusCatalogRecord* record;

	record = getRecordFromPath(argv[2], volume, NULL, NULL);

	if(record != NULL) {
		if(record->recordType == kHFSPlusFileRecord) {
			uint8_t* buffer;
			uint32_t size = readHFSFile((HFSPlusCatalogFile*)record, &buffer, volume);
			uint32_t address = parseNumber(argv[3]);
			memcpy((uint8_t*)address, buffer, size);
			free(buffer);
			bufferPrintf("%d bytes of %s extracted to 0x%x\r\n", size, argv[2], address);
		} else {
			bufferPrintf("Not a file, record type: %x\r\n", record->recordType);
		}
	} else {
		bufferPrintf("No such file or directory\r\n");
	}
	
	free(record);

	closeVolume(volume);
	CLOSE(io);
}
Exemple #6
0
void fs_cmd_cat(int argc, char** argv) {
	Volume* volume;
	io_func* io;

	if(argc < 3) {
		bufferPrintf("usage: %s <partition> <file>\r\n", argv[0]);
		return;
	}

	io = bdev_open(parseNumber(argv[1]));
	if(io == NULL) {
		bufferPrintf("fs: cannot read partition!\r\n");
		return;
	}

	volume = openVolume(io);
	if(volume == NULL) {
		bufferPrintf("fs: cannot openHFS volume!\r\n");
		return;
	}

	HFSPlusCatalogRecord* record;

	record = getRecordFromPath(argv[2], volume, NULL, NULL);

	if(record != NULL) {
		if(record->recordType == kHFSPlusFileRecord) {
			uint8_t* buffer;
			uint32_t size = readHFSFile((HFSPlusCatalogFile*)record, &buffer, volume);
			buffer = realloc(buffer, size + 1);
			buffer[size] = '\0';
			bufferPrintf("%s\r\n", buffer);
			free(buffer);
		} else {
			bufferPrintf("Not a file, record type: %x\r\n", record->recordType);
		}
	} else {
		bufferPrintf("No such file or directory\r\n");
	}
	
	free(record);

	closeVolume(volume);
	CLOSE(io);
}
Exemple #7
0
/*===========================================================================*
 *				common_open				     *
 *===========================================================================*/
int common_open(char path[PATH_MAX], int oflags, mode_t omode)
{
/* Common code from do_creat and do_open. */
  int b, r, exist = TRUE, major_dev;
  dev_t dev;
  mode_t bits;
  struct filp *filp, *filp2;
  struct vnode *vp;
  struct vmnt *vmp;
  struct dmap *dp;
  struct lookup resolve;

  /* Remap the bottom two bits of oflags. */
  bits = (mode_t) mode_map[oflags & O_ACCMODE];
  if (!bits) return(EINVAL);

  /* See if file descriptor and filp slots are available. */
  if ((r = get_fd(0, bits, &(scratch(fp).file.fd_nr), &filp)) != OK) return(r);

  lookup_init(&resolve, path, PATH_NOFLAGS, &vmp, &vp);

  /* If O_CREATE is set, try to make the file. */
  if (oflags & O_CREAT) {
        omode = I_REGULAR | (omode & ALLPERMS & fp->fp_umask);
	vp = new_node(&resolve, oflags, omode);
	r = err_code;
	if (r == OK) exist = FALSE;	/* We just created the file */
	else if (r != EEXIST) {		/* other error */
		if (vp) unlock_vnode(vp);
		unlock_filp(filp);
		return(r);
	}
	else exist = !(oflags & O_EXCL);/* file exists, if the O_EXCL
					   flag is set this is an error */
  } else {
	/* Scan path name */
	resolve.l_vmnt_lock = VMNT_READ;
	resolve.l_vnode_lock = VNODE_OPCL;
	if ((vp = eat_path(&resolve, fp)) == NULL) {
		unlock_filp(filp);
		return(err_code);
	}

	if (vmp != NULL) unlock_vmnt(vmp);
  }

  /* Claim the file descriptor and filp slot and fill them in. */
  fp->fp_filp[scratch(fp).file.fd_nr] = filp;
  FD_SET(scratch(fp).file.fd_nr, &fp->fp_filp_inuse);
  filp->filp_count = 1;
  filp->filp_vno = vp;
  filp->filp_flags = oflags;

  /* Only do the normal open code if we didn't just create the file. */
  if (exist) {
	/* Check protections. */
	if ((r = forbidden(fp, vp, bits)) == OK) {
		/* Opening reg. files, directories, and special files differ */
		switch (vp->v_mode & S_IFMT) {
		   case S_IFREG:
			/* Truncate regular file if O_TRUNC. */
			if (oflags & O_TRUNC) {
				if ((r = forbidden(fp, vp, W_BIT)) != OK)
					break;
				truncate_vnode(vp, 0);
			}
			break;
		   case S_IFDIR:
			/* Directories may be read but not written. */
			r = (bits & W_BIT ? EISDIR : OK);
			break;
		   case S_IFCHR:
			/* Invoke the driver for special processing. */
			dev = (dev_t) vp->v_sdev;
			/* TTY needs to know about the O_NOCTTY flag. */
			r = dev_open(dev, who_e, bits | (oflags & O_NOCTTY));
			if (r == SUSPEND) suspend(FP_BLOCKED_ON_DOPEN);
			else vp = filp->filp_vno; /* Might be updated by
						   * dev_open/clone_opcl */
			break;
		   case S_IFBLK:

			lock_bsf();

			/* Invoke the driver for special processing. */
			dev = (dev_t) vp->v_sdev;
			r = bdev_open(dev, bits);
			if (r != OK) {
				unlock_bsf();
				break;
			}

			major_dev = major(vp->v_sdev);
			dp = &dmap[major_dev];
			if (dp->dmap_driver == NONE) {
				printf("VFS: block driver disappeared!\n");
				unlock_bsf();
				r = ENXIO;
				break;
			}

			/* Check whether the device is mounted or not. If so,
			 * then that FS is responsible for this device.
			 * Otherwise we default to ROOT_FS.
			 */
			vp->v_bfs_e = ROOT_FS_E; /* By default */
			for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp)
				if (vmp->m_dev == vp->v_sdev &&
				    !(vmp->m_flags & VMNT_FORCEROOTBSF)) {
					vp->v_bfs_e = vmp->m_fs_e;
				}

			/* Send the driver label to the file system that will
			 * handle the block I/O requests (even when its label
			 * and endpoint are known already), but only when it is
			 * the root file system. Other file systems will
			 * already have it anyway.
			 */
			if (vp->v_bfs_e != ROOT_FS_E) {
				unlock_bsf();
				break;
			}

			if (req_newdriver(vp->v_bfs_e, vp->v_sdev,
					dp->dmap_label) != OK) {
				printf("VFS: error sending driver label\n");
				bdev_close(dev);
				r = ENXIO;
			}
			unlock_bsf();
			break;

		   case S_IFIFO:
			/* Create a mapped inode on PFS which handles reads
			   and writes to this named pipe. */
			tll_upgrade(&vp->v_lock);
			r = map_vnode(vp, PFS_PROC_NR);
			if (r == OK) {
				if (vp->v_ref_count == 1) {
					vp->v_pipe_rd_pos = 0;
					vp->v_pipe_wr_pos = 0;
					if (vp->v_size != 0)
						r = truncate_vnode(vp, 0);
				}
				oflags |= O_APPEND;	/* force append mode */
				filp->filp_flags = oflags;
			}
			if (r == OK) {
				r = pipe_open(vp, bits, oflags);
			}
			if (r != ENXIO) {
				/* See if someone else is doing a rd or wt on
				 * the FIFO.  If so, use its filp entry so the
				 * file position will be automatically shared.
				 */
				b = (bits & R_BIT ? R_BIT : W_BIT);
				filp->filp_count = 0; /* don't find self */
				if ((filp2 = find_filp(vp, b)) != NULL) {
				    /* Co-reader or writer found. Use it.*/
				    fp->fp_filp[scratch(fp).file.fd_nr] = filp2;
				    filp2->filp_count++;
				    filp2->filp_vno = vp;
				    filp2->filp_flags = oflags;

				    /* v_count was incremented after the vnode
				     * has been found. i_count was incremented
				     * incorrectly in FS, not knowing that we
				     * were going to use an existing filp
				     * entry.  Correct this error.
				     */
				    unlock_vnode(vp);
				    put_vnode(vp);
				} else {
				    /* Nobody else found. Restore filp. */
				    filp->filp_count = 1;
				}
			}
			break;
		}
	}
  }

  unlock_filp(filp);

  /* If error, release inode. */
  if (r != OK) {
	if (r != SUSPEND) {
		fp->fp_filp[scratch(fp).file.fd_nr] = NULL;
		FD_CLR(scratch(fp).file.fd_nr, &fp->fp_filp_inuse);
		filp->filp_count = 0;
		filp->filp_vno = NULL;
		put_vnode(vp);
	}
  } else {
	r = scratch(fp).file.fd_nr;
  }

  return(r);
}
Exemple #8
0
/*===========================================================================*
 *				fs_readsuper				     *
 *===========================================================================*/
PUBLIC int fs_readsuper()
{
/* This function reads the superblock of the partition, gets the root inode
 * and sends back the details of them. Note, that the FS process does not
 * know the index of the vmnt object which refers to it, whenever the pathname
 * lookup leaves a partition an ELEAVEMOUNT error is transferred back
 * so that the VFS knows that it has to find the vnode on which this FS
 * process' partition is mounted on.
 */
  struct inode *root_ip;
  cp_grant_id_t label_gid;
  size_t label_len;
  int r = OK;
  int readonly, isroot;
  u32_t mask;

  fs_dev    = fs_m_in.REQ_DEV;
  label_gid = fs_m_in.REQ_GRANT;
  label_len = fs_m_in.REQ_PATH_LEN;
  readonly  = (fs_m_in.REQ_FLAGS & REQ_RDONLY) ? 1 : 0;
  isroot    = (fs_m_in.REQ_FLAGS & REQ_ISROOT) ? 1 : 0;

  if (label_len > sizeof(fs_dev_label))
	return(EINVAL);

  r = sys_safecopyfrom(fs_m_in.m_source, label_gid, 0,
		       (vir_bytes)fs_dev_label, label_len, D);
  if (r != OK) {
	printf("%s:%d fs_readsuper: safecopyfrom failed: %d\n",
	       __FILE__, __LINE__, r);
	return(EINVAL);
  }

  /* Map the driver label for this major. */
  bdev_driver(fs_dev, fs_dev_label);

  /* Open the device the file system lives on. */
  if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT)) != OK) {
        return(EINVAL);
  }

  /* Fill in the super block. */
  STATICINIT(superblock, 1);
  if (!superblock)
	panic("Can't allocate memory for superblock.");
  superblock->s_dev = fs_dev;	/* read_super() needs to know which dev */
  r = read_super(superblock);

  /* Is it recognized as a Minix filesystem? */
  if (r != OK) {
	superblock->s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(r);
  }

  if (superblock->s_rev_level != EXT2_GOOD_OLD_REV) {
	struct super_block *sp = superblock; /* just shorter name */
	mask = ~SUPPORTED_INCOMPAT_FEATURES;
	if (HAS_INCOMPAT_FEATURE(sp, mask)) {
		if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_COMPRESSION & mask))
			printf("ext2: fs compression is not supported by server\n");
		if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_FILETYPE & mask))
			printf("ext2: fs in dir filetype is not supported by server\n");
		if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_RECOVER & mask))
			printf("ext2: fs recovery is not supported by server\n");
		if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_JOURNAL_DEV & mask))
			printf("ext2: fs journal dev is not supported by server\n");
		if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_META_BG & mask))
			printf("ext2: fs meta bg is not supported by server\n");
		return(EINVAL);
	}
	mask = ~SUPPORTED_RO_COMPAT_FEATURES;
	if (HAS_RO_COMPAT_FEATURE(sp, mask)) {
		if (HAS_RO_COMPAT_FEATURE(sp, RO_COMPAT_SPARSE_SUPER & mask)) {
			printf("ext2: sparse super is not supported by server, \
				remount read-only\n");
		}
		if (HAS_RO_COMPAT_FEATURE(sp, RO_COMPAT_LARGE_FILE & mask)) {
			printf("ext2: large files are not supported by server, \
				remount read-only\n");
		}
		if (HAS_RO_COMPAT_FEATURE(sp, RO_COMPAT_BTREE_DIR & mask)) {
			printf("ext2: dir's btree is not supported by server, \
				remount read-only\n");
		}
		return(EINVAL);
	}
  }

  if (superblock->s_state == EXT2_ERROR_FS) {
	printf("ext2: filesystem wasn't cleanly unmounted previous time\n");
        superblock->s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }


  set_blocksize(superblock->s_block_size,
  	superblock->s_blocks_count,
	superblock->s_free_blocks_count,
	major(fs_dev));

  /* Get the root inode of the mounted file system. */
  if ( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NULL)  {
	printf("ext2: couldn't get root inode\n");
	superblock->s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }

  if (root_ip != NULL && root_ip->i_mode == 0) {
	printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__);
	put_inode(root_ip);
	superblock->s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }

  if (root_ip != NULL && (root_ip->i_mode & I_TYPE) != I_DIRECTORY) {
	printf("%s:%d root inode has wrong type, it's not a DIR\n",
		 __FILE__, __LINE__);
	put_inode(root_ip);
	superblock->s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }

  superblock->s_rd_only = readonly;
  superblock->s_is_root = isroot;

  if (!readonly) {
	superblock->s_state = EXT2_ERROR_FS;
	superblock->s_mnt_count++;
	superblock->s_mtime = clock_time();
	write_super(superblock); /* Commit info, we just set above */
  }

  /* Root inode properties */
  fs_m_out.RES_INODE_NR = root_ip->i_num;
  fs_m_out.RES_MODE = root_ip->i_mode;
  fs_m_out.RES_FILE_SIZE_LO = root_ip->i_size;
  fs_m_out.RES_UID = root_ip->i_uid;
  fs_m_out.RES_GID = root_ip->i_gid;

  fs_m_out.RES_CONREQS = 1;	/* We can handle only 1 request at a time */

  return(r);
}
Exemple #9
0
/*===========================================================================*
 *				common_open				     *
 *===========================================================================*/
PUBLIC int common_open(register int oflags, mode_t omode)
{
/* Common code from do_creat and do_open. */
  int b, r, exist = TRUE;
  dev_t dev;
  mode_t bits;
  struct filp *fil_ptr, *filp2;
  struct vnode *vp;
  struct vmnt *vmp;
  struct dmap *dp;

  /* Remap the bottom two bits of oflags. */
  bits = (mode_t) mode_map[oflags & O_ACCMODE];
  if (!bits) return(EINVAL);

  /* See if file descriptor and filp slots are available. */
  if ((r = get_fd(0, bits, &m_in.fd, &fil_ptr)) != OK) return(r);

  /* If O_CREATE is set, try to make the file. */
  if (oflags & O_CREAT) {
        omode = I_REGULAR | (omode & ALL_MODES & fp->fp_umask);
	vp = new_node(oflags, omode);
	r = err_code;
	if (r == OK) exist = FALSE; /* We just created the file */
	else if (r != EEXIST) return(r);  /* other error */ 
	else exist = !(oflags & O_EXCL);  /* file exists, if the O_EXCL
					     flag is set this is an error */
  } else {
	/* Scan path name */
	if ((vp = eat_path(PATH_NOFLAGS, fp)) == NULL) return(err_code);
  }

  /* Claim the file descriptor and filp slot and fill them in. */
  fp->fp_filp[m_in.fd] = fil_ptr;
  FD_SET(m_in.fd, &fp->fp_filp_inuse);
  fil_ptr->filp_count = 1;
  fil_ptr->filp_vno = vp;
  fil_ptr->filp_flags = oflags;

  /* Only do the normal open code if we didn't just create the file. */
  if(exist) {
	/* Check protections. */
	if ((r = forbidden(vp, bits)) == OK) {
		/* Opening reg. files, directories, and special files differ */
		switch (vp->v_mode & I_TYPE) {
		   case I_REGULAR:
		   	/* Truncate regular file if O_TRUNC. */
		   	if (oflags & O_TRUNC) {
		   		if ((r = forbidden(vp, W_BIT)) != OK)
		   			break;
		   		truncate_vnode(vp, 0);
		   	}
		   	break;
		   case I_DIRECTORY:
		   	/* Directories may be read but not written. */
		   	r = (bits & W_BIT ? EISDIR : OK);
		   	break;
		   case I_CHAR_SPECIAL:
			/* Invoke the driver for special processing. */
			dev = (dev_t) vp->v_sdev;
			/* TTY needs to know about the O_NOCTTY flag. */
			r = dev_open(dev, who_e, bits | (oflags & O_NOCTTY));
		   	if (r == SUSPEND) suspend(FP_BLOCKED_ON_DOPEN);
		   	break;
		   case I_BLOCK_SPECIAL:
			/* Invoke the driver for special processing. */
			dev = (dev_t) vp->v_sdev;
			r = bdev_open(dev, bits);
			if (r != OK) break;

			/* Check whether the device is mounted or not. If so,
			   then that FS is responsible for this device. Else
			   we default to ROOT_FS. */
			vp->v_bfs_e = ROOT_FS_E; /* By default */
			for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) 
				if (vmp->m_dev == vp->v_sdev) 
					vp->v_bfs_e = vmp->m_fs_e;

			/* Get the driver endpoint of the block spec device */
			dp = &dmap[major(vp->v_sdev)];

			/* Send the driver endpoint to the file system (even
			 * when known already).
			 */
			if ((r = req_newdriver(vp->v_bfs_e, vp->v_sdev,
					       dp->dmap_driver)) != OK) {
				printf("VFS: error sending driver endpoint\n");
				bdev_close(dev);
				r = ENXIO;
			}
			break;

		   case I_NAMED_PIPE:
			/* Create a mapped inode on PFS which handles reads
			   and writes to this named pipe. */
			r = map_vnode(vp);
			if (r == OK) {
				vp->v_pipe = I_PIPE;
				if (vp->v_ref_count == 1) {
					vp->v_pipe_rd_pos = 0;
					vp->v_pipe_wr_pos = 0;
					if (vp->v_size != 0)
						r = truncate_vnode(vp, 0);
				}
				oflags |= O_APPEND;	/* force append mode */
				fil_ptr->filp_flags = oflags;
			}
			if (r == OK) {
				r = pipe_open(vp, bits, oflags);
			}
			if (r != ENXIO) {
				/* See if someone else is doing a rd or wt on
				 * the FIFO.  If so, use its filp entry so the
				 * file position will be automatically shared.
				 */
				b = (bits & R_BIT ? R_BIT : W_BIT);
				fil_ptr->filp_count = 0; /* don't find self */
				if ((filp2 = find_filp(vp, b)) != NULL) {
					/* Co-reader or writer found. Use it.*/
					fp->fp_filp[m_in.fd] = filp2;
					filp2->filp_count++;
					filp2->filp_vno = vp;
					filp2->filp_flags = oflags;

					/* v_count was incremented after the
					 * vnode has been found. i_count was
					 * incremented incorrectly in FS, not
					 * knowing that we were going to use an
					 * existing filp entry.  Correct this
					 * error.
					 */
					put_vnode(vp);
				} else {
					/* Nobody else found. Restore filp. */
					fil_ptr->filp_count = 1;
				}
			} 
			break;
		}
	}
  }

  /* If error, release inode. */
  if (r != OK) {
	if (r == SUSPEND) return(r);		/* Oops, just suspended */
	fp->fp_filp[m_in.fd] = NULL;
  	FD_CLR(m_in.fd, &fp->fp_filp_inuse);
	fil_ptr->filp_count= 0;
	put_vnode(vp);     
	fil_ptr->filp_vno = NULL;
	return(r);
  }
  
  return(m_in.fd);
}
Exemple #10
0
/*===========================================================================*
 *				fs_readsuper				     *
 *===========================================================================*/
PUBLIC int fs_readsuper()
{
/* This function reads the superblock of the partition, gets the root inode
 * and sends back the details of them. Note, that the FS process does not
 * know the index of the vmnt object which refers to it, whenever the pathname 
 * lookup leaves a partition an ELEAVEMOUNT error is transferred back 
 * so that the VFS knows that it has to find the vnode on which this FS 
 * process' partition is mounted on.
 */
  struct inode *root_ip;
  cp_grant_id_t label_gid;
  size_t label_len;
  int r;
  int readonly, isroot;

  fs_dev    = (dev_t) fs_m_in.REQ_DEV;
  label_gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
  label_len = (size_t) fs_m_in.REQ_PATH_LEN;
  readonly  = (fs_m_in.REQ_FLAGS & REQ_RDONLY) ? 1 : 0;
  isroot    = (fs_m_in.REQ_FLAGS & REQ_ISROOT) ? 1 : 0;

  if (label_len > sizeof(fs_dev_label))
	return(EINVAL);

  r = sys_safecopyfrom(fs_m_in.m_source, label_gid, (vir_bytes) 0,
		       (vir_bytes) fs_dev_label, label_len, D);
  if (r != OK) {
	printf("MFS %s:%d safecopyfrom failed: %d\n", __FILE__, __LINE__, r);
	return(EINVAL);
  }

  /* Map the driver label for this major. */
  bdev_driver(fs_dev, fs_dev_label);

  /* Open the device the file system lives on. */
  if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT) ) != OK) {
        return(EINVAL);
  }
  
  /* Fill in the super block. */
  superblock.s_dev = fs_dev;	/* read_super() needs to know which dev */
  r = read_super(&superblock);

  /* Is it recognized as a Minix filesystem? */
  if (r != OK) {
	superblock.s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(r);
  }

  /* Remember whether we were mounted cleanly so we know what to
   * do at unmount time
   */
  if(superblock.s_flags & MFSFLAG_CLEAN)
	cleanmount = 1;

  /* clean check: if rw and not clean, switch to readonly */
  if(!(superblock.s_flags & MFSFLAG_CLEAN) && !readonly) {
	if(bdev_close(fs_dev) != OK)
		panic("couldn't bdev_close after found unclean FS");
	readonly = 1;

	if (bdev_open(fs_dev, R_BIT) != OK) {
		panic("couldn't bdev_open after found unclean FS");
		return(EINVAL);
  	}
	printf("MFS: WARNING: FS 0x%x unclean, mounting readonly\n", fs_dev);
  }
  
  set_blocksize(&superblock);
  
  /* Get the root inode of the mounted file system. */
  if( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NULL)  {
	printf("MFS: couldn't get root inode\n");
	superblock.s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }
  
  if(root_ip->i_mode == 0) {
	printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__);
	put_inode(root_ip);
	superblock.s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }

  superblock.s_rd_only = readonly;
  superblock.s_is_root = isroot;
  
  /* Root inode properties */
  fs_m_out.RES_INODE_NR = root_ip->i_num;
  fs_m_out.RES_MODE = root_ip->i_mode;
  fs_m_out.RES_FILE_SIZE_LO = root_ip->i_size;
  fs_m_out.RES_UID = root_ip->i_uid;
  fs_m_out.RES_GID = root_ip->i_gid;

  fs_m_out.RES_CONREQS = 1;	/* We can handle only 1 request at a time */

  /* Mark it dirty */
  if(!superblock.s_rd_only) {
	  superblock.s_flags &= ~MFSFLAG_CLEAN;
	  if(write_super(&superblock) != OK)
		panic("mounting: couldn't write dirty superblock");
  }

  return(r);
}
Exemple #11
0
void images_install(void* newData, size_t newDataLen, uint32_t newFourcc, uint32_t replaceFourcc) {
	ImageDataList* list = NULL;
	ImageDataList* cur = NULL;
	ImageDataList* toReplace = NULL;
    ImageDataList* verify = NULL;
    
	int isReplace = (replaceFourcc != newFourcc) ? TRUE : FALSE;
	int isUpgrade = FALSE;

	Image* curImage = imageList;
    
	while(curImage != NULL) {
		if(cur == NULL) {
			list = cur = verify = malloc(sizeof(ImageDataList));
		} else {
			cur->next = malloc(sizeof(ImageDataList));
			cur = cur->next;
		}

		bufferPrintf("Reading: ");
		print_fourcc(curImage->type);
		bufferPrintf(" (%d bytes)\r\n", curImage->padded);

		cur->type = curImage->type;
		cur->next = NULL;
		cur->data = malloc(curImage->padded);
		nor_read(cur->data, curImage->offset, curImage->padded);

		if(isReplace && cur->type == replaceFourcc) {
			isUpgrade = TRUE;
		} else if(cur->type == newFourcc) {
			toReplace = cur;
		}

		curImage = curImage->next;
	}

	if(!isUpgrade) {
		bufferPrintf("Performing installation... (%d bytes)\r\n", newDataLen);

		ImageDataList* ibox = malloc(sizeof(ImageDataList));
		ibox->type = replaceFourcc;
		ibox->data = toReplace->data;
		ibox->next = toReplace->next;

		toReplace->next = ibox;
		toReplace->data = images_inject_img3(toReplace->data, newData, newDataLen);
		images_change_type(ibox->data, ibox->type);
	} else {
		bufferPrintf("Performing upgrade... (%d bytes)\r\n", newDataLen);
		void* newIBoot = images_inject_img3(toReplace->data, newData, newDataLen);
		free(toReplace->data);
		toReplace->data = newIBoot;
	}

    //check for size and availability
    size_t newPaddedDataLen=0;
    size_t totalBytes=0;
    //if somebody can find how to get padded length for new ibot maybe this loop not needed
    while(verify != NULL) {
        cur = verify;
        verify = verify->next;
        AppleImg3RootHeader* header = (AppleImg3RootHeader*) cur->data;
        totalBytes += header->base.size;
        
        if(cur->type == newFourcc) {
            newPaddedDataLen = header->base.size;
        }
    }
    
    bufferPrintf("Total size to be written %d\r\n",totalBytes);
    if((ImagesStart + totalBytes) >= 0xfc000) {
        bufferPrintf("**ABORTED** Writing total image size: 0x%x, new ibot size: 0x%x at 0x%x would overflow NOR!\r\n", totalBytes, newPaddedDataLen,ImagesStart);
        images_rewind();
        images_release();
        images_setup();
        return;
    }
    
	bufferPrintf("Flashing...\r\n");

	images_rewind();
	while(list != NULL) {
		cur = list;
		list = list->next;
		AppleImg3RootHeader* header = (AppleImg3RootHeader*) cur->data;

		bufferPrintf("Flashing: ");
		print_fourcc(cur->type);
		bufferPrintf(" (%x, %d bytes)\r\n", cur->data, header->base.size);

		images_append(cur->data, header->base.size);

		free(cur->data);
		free(cur);
	}
	bufferPrintf("Flashing Complete, Free space after flashing %d\r\n",0xfc000-MaxOffset);

	images_release();
	images_setup();

    bufferPrintf("Configuring openiBoot settings...\r\n");
    
    Volume* volume;
    io_func* io;

    io = bdev_open(0);
    volume = openVolume(io);

    char buffer [sizeof(XSTRINGIFY(OPENIBOOT_VERSION))];
    strcpy(buffer, XSTRINGIFY(OPENIBOOT_VERSION));
    add_hfs(volume, (uint8_t*)buffer, sizeof(buffer), "/openiboot");

    closeVolume(volume);
    CLOSE(io);

    ftl_sync();
    
    if(!nvram_getvar("opib-temp-os")) {
    	nvram_setvar("opib-temp-os", "0");
    }
    
    if(!nvram_getvar("opib-default-os")) {
		nvram_setvar("opib-default-os", "1");
    }

    if(!nvram_getvar("opib-menu-timeout")) {
		nvram_setvar("opib-menu-timeout", "10000");
    }

    nvram_save();
    bufferPrintf("openiBoot installation complete.\r\n");
}
Exemple #12
0
void startScripting(char* loadedFrom)
{
	uint32_t size = 0;


	uint8_t* address = NULL;

	const char* partitionScript = nvram_getvar("partition-script"); /*get the partition where the script is in NVRAM*/
	const char* fileScript = nvram_getvar("file-script"); /*get the path to the file script in NVRAM*/
	const char* scriptingLinux = nvram_getvar("scripting-linux"); /*tells whether to run the script before booting linux. Accepted values : true or 1, anything else if false*/
	const char* scriptingOpeniboot = nvram_getvar("scripting-openiboot"); /*tells whether to run the script before launching openiboot console. Accepted values : true or 1, anything else if false*/

	//uint32_t numberOfLines = 1; /*number of lines in the script files - To be used with the next commented section of code for debug*/
	//bufferPrintf("partition-script %s\r\n",partitionScript);  /*For debug*/
	//bufferPrintf("file-script %s\r\n",fileScript);  /*For debug*/

	if(!partitionScript)
		return;

	if(!fileScript)
		return;

	/* ------ extracting the script file at address 0x09000000 ----- */
	if(strcmp(loadedFrom, "linux") == 0)
	{
		if(!scriptingLinux || (strcmp(scriptingLinux, "true") != 0 && strcmp(scriptingLinux, "1") != 0))
		{
			return; /* terminate the function if scripting is not asked*/
		}
	}

	if(strcmp(loadedFrom, "openiboot") == 0)
	{
		if(!scriptingOpeniboot || (strcmp(scriptingOpeniboot, "true") != 0 && strcmp(scriptingOpeniboot, "1") != 0))
		{
			return; /* terminate the function if scripting is not asked*/
		}
	}

	Volume* volume;
	io_func* io;
	io = bdev_open(parseNumber(partitionScript));
	if(io == NULL) {
		bufferPrintf("fs: cannot read partition!\r\n");
		return;
	}

	volume = openVolume(io);
	if(volume == NULL) {
		bufferPrintf("fs: cannot openHFS volume!\r\n");
		return;
	}

	HFSPlusCatalogRecord* record;
	char* name;
	record = getRecordFromPath(fileScript, volume, &name, NULL);
	if(record != NULL) {
		if(record->recordType == kHFSPlusFolderRecord)
		{
			bufferPrintf("this path is a folder, not a file\r\n");
			return;
		} else
		{
			size = readHFSFile((HFSPlusCatalogFile*)record, &address, volume);
			if(!address)
				return;
			//bufferPrintf("size = %d\r\n",size);  /*size of script file, used later*/
		}
	} else {
		bufferPrintf("No such file or directory\r\n");
		return;
	}

	closeVolume(volume);
	CLOSE(io);

	char* addrBOF = (char*) address; /* pointer on the begening of the file*/
	char* addrEOF = (char*) (address + size); /*pointer 1 byte after the file */
	char* addr; /*pointer on the current space on memory*/

#if 0
	//addrEOF = (void*)address+size+1;
	/* ----- counting how many lines are present in the script file by the '\n' -----  */
	addr = addrBOF;
	while(addr < addrEOF)
	{
		if(*addr=='\r'){
			numberOfLines++;
		}
		addr++;
	}
	bufferPrintf("number of lines : %d\r\n", numberOfLines);
#endif

	char* bufferLine = malloc(100);

	/* ----- extracting each line to the buffer -----*/
	addr = addrBOF;
	while(addr < addrEOF)
	{
		int charAt = 0;
		while((*addr != '\n') && (addr < addrEOF))
		{
			if(*addr != '\r')
			{
				bufferLine[charAt] = *addr;
				//bufferPrintf("reading char : %c\r\n",*addr);
				charAt++;
			}
			addr++;
		}

		bufferLine[charAt]='\0';

		bufferPrintf("\r\n%s\r\n", bufferLine);

		bufferLine[charAt]='\n';
		bufferLine[charAt + 1] = '\0';

		if(scriptCommand(bufferLine))
		{
			//bufferPrintf("command sent\r\n");
		}
		/*else { //error in command, function scriptCommand returned false
		}*/
		addr++;
	}

	free(bufferLine);
	free(address);
}
Exemple #13
0
/*===========================================================================*
 *				fs_readsuper				     *
 *===========================================================================*/
PUBLIC int fs_readsuper()
{
/* This function reads the superblock of the partition, gets the root inode
 * and sends back the details of them. Note, that the FS process does not
 * know the index of the vmnt object which refers to it, whenever the pathname 
 * lookup leaves a partition an ELEAVEMOUNT error is transferred back 
 * so that the VFS knows that it has to find the vnode on which this FS 
 * process' partition is mounted on.
 */
  struct inode *root_ip;
  cp_grant_id_t label_gid;
  size_t label_len;
  int r;
  endpoint_t driver_e;
  int readonly, isroot;

  fs_dev    = (dev_t) fs_m_in.REQ_DEV;
  label_gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
  label_len = (size_t) fs_m_in.REQ_PATH_LEN;
  readonly  = (fs_m_in.REQ_FLAGS & REQ_RDONLY) ? 1 : 0;
  isroot    = (fs_m_in.REQ_FLAGS & REQ_ISROOT) ? 1 : 0;

  if (label_len > sizeof(fs_dev_label))
	return(EINVAL);

  r = sys_safecopyfrom(fs_m_in.m_source, label_gid, (vir_bytes) 0,
		       (vir_bytes) fs_dev_label, label_len, D);
  if (r != OK) {
	printf("MFS %s:%d safecopyfrom failed: %d\n", __FILE__, __LINE__, r);
	return(EINVAL);
  }

  r = ds_retrieve_label_endpt(fs_dev_label, &driver_e);
  if (r != OK) {
	printf("MFS %s:%d ds_retrieve_label_endpt failed for '%s': %d\n",
		__FILE__, __LINE__, fs_dev_label, r);
	return(EINVAL);
  }

  /* Map the driver endpoint for this major */
  bdev_driver(fs_dev, driver_e);

  /* Open the device the file system lives on. */
  if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT) ) != OK) {
        return(EINVAL);
  }
  
  /* Fill in the super block. */
  superblock.s_dev = fs_dev;	/* read_super() needs to know which dev */
  r = read_super(&superblock);

  /* Is it recognized as a Minix filesystem? */
  if (r != OK) {
	superblock.s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(r);
  }

  set_blocksize(&superblock);
  
  /* Get the root inode of the mounted file system. */
  if( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NULL)  {
	printf("MFS: couldn't get root inode\n");
	superblock.s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }
  
  if(root_ip->i_mode == 0) {
	printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__);
	put_inode(root_ip);
	superblock.s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }

  superblock.s_rd_only = readonly;
  superblock.s_is_root = isroot;
  
  /* Root inode properties */
  fs_m_out.RES_INODE_NR = root_ip->i_num;
  fs_m_out.RES_MODE = root_ip->i_mode;
  fs_m_out.RES_FILE_SIZE_LO = root_ip->i_size;
  fs_m_out.RES_UID = root_ip->i_uid;
  fs_m_out.RES_GID = root_ip->i_gid;

  fs_m_out.RES_CONREQS = 1;	/* We can handle only 1 request at a time */

  return(r);
}
Exemple #14
0
/* XXX Test if it's a device, or a partition.
 * If a partition, warn user, and ask for confirmation before
 * going ahead.
 * Suggest how to call f3probe with the correct device name if
 * the block device is a partition.
 * Use udev to do these tests.
 * Make sure that no partition of the drive is mounted.
 */
struct device *create_block_device(const char *filename, enum reset_type rt)
{
	struct block_device *bdev;
	int block_size;

	bdev = malloc(sizeof(*bdev));
	if (!bdev)
		goto error;

	bdev->filename = strdup(filename);
	if (!bdev->filename)
		goto bdev;

	bdev->fd = bdev_open(filename);
	if (bdev->fd < 0) {
		if (errno == EACCES && getuid()) {
			fprintf(stderr, "Your username doesn't have access to device `%s'.\n"
				"Try to run this program as root:\n"
				"sudo f3probe %s\n",
				filename, filename);
		} else {
			err(errno, "Can't open device `%s'", filename);
		}
		goto filename;
	}

	if (!is_block_dev(bdev->fd)) {
		err(EINVAL, "File `%s' is not a block device", filename);
		goto fd;
	}

	switch (rt) {
	case RT_MANUAL:
		bdev->dev.reset	= bdev_manual_reset;
		break;
	case RT_USB_RESET:
		bdev->dev.reset = bdev_usb_reset;
		break;
	default:
		assert(0);
	}

	assert(!ioctl(bdev->fd, BLKGETSIZE64, &bdev->dev.size_byte));

	assert(!ioctl(bdev->fd, BLKBSZGET, &block_size));
	bdev->dev.block_order = ilog2(block_size);
	assert(block_size == (1 << bdev->dev.block_order));

	bdev->dev.read_block = bdev_read_block;
	bdev->dev.write_block = bdev_write_block;
	bdev->dev.free = bdev_free;

	return &bdev->dev;

fd:
	assert(!close(bdev->fd));
filename:
	free((void *)bdev->filename);
bdev:
	free(bdev);
error:
	return NULL;
}