Пример #1
0
/* Open a file or directory via selection */
uint32 iso_open_select(const char *fn, int mode, uint32 session_base_select) {
	uint32		fd;
	iso_dirent_t	*de;

	/* Make sure they don't want to open things as writeable */
	if ((mode & O_MODE_MASK) != O_RDONLY)
		return 0;
	
	/* Find a free file handle */
	for (fd=0; fd<MAX_ISO_FILES; fd++)
		if (fh[fd].first_extent == 0) {
			fh[fd].first_extent = -1;
			break;
		}
	if (fd >= MAX_ISO_FILES)
		return 0;
		
	/* For now we always do this, but it should eventually be set
	   up to detect the CD tray having been opened. */
	if (init_percd_select(session_base_select) < 0)
		return 0;
	
	/* Find the file we want */
	de = find_object_path(fn, (mode & O_DIR)?1:0, &root_dirent);
	if (!de) return 0;
	
	/* Fill in the file handle and return the fd */
	fh[fd].first_extent = iso_733(de->extent);
	fh[fd].dir = (mode & O_DIR)?1:0;
	fh[fd].ptr = 0;
	fh[fd].size = iso_733(de->size);
	
	return fd;
}
Пример #2
0
/* Locate an ISO9660 object anywhere on the disc, starting at the root,
   and expecting a fully qualified path name. This is analogous to find_object
   but it searches with the path in mind.

   fn:		object filename (relative to the passed directory)
   dir:		0 if looking for a file, 1 if looking for a dir
   dir_extent:	directory extent to start with
   dir_size:	directory size (in bytes)
   
   It will return a pointer to a transient dirent buffer (i.e., don't
   expect this buffer to stay around much longer than the call itself).
 */
static iso_dirent_t *find_object_path(const char *fn, int dir, iso_dirent_t *start) {
	char		*cur;

	/* If the object is in a sub-tree, traverse the trees looking
	   for the right directory */
	while ((cur = strchr(fn, '/'))) {
		if (cur != fn) {
			/* Note: trailing path parts don't matter since find_object
			   only compares based on the FN length on the disc. */
			start = find_object(fn, 1, iso_733(start->extent), iso_733(start->size));
			if (start == NULL) return NULL;
		}
		fn = cur + 1;
	}

	/* Locate the file in the resulting directory */
	if (*fn) {
		start = find_object(fn, dir, iso_733(start->extent), iso_733(start->size));
		return start;
	}
	else {
		if (!dir)
			return NULL;
		else
			return start;
	}
}
Пример #3
0
/* Initialize for GD-ROM */
static int init_percd_gdrom() {
	int		i;
	CDROM_TOC	toc;

	/* Start off with no cached blocks */
	bclear();
	
	/* Locate the root session */
	if ((i = cdrom_reinit()) != 0)
		return i;
	if ((i = cdrom_read_toc(&toc, 1)) != 0)
		return i;
	if (!(session_base = cdrom_locate_data_track(&toc, 1)))
		return -1;

	/* Grab and check the volume descriptor */	
	i = bread(session_base + 16 - 150);
	if (i < 0) return i;
	if (memcmp((char*)cache[i]->data, "\01CD001", 6)) {
		printf("fs_iso9660: disc is not iso9660\r\n");
		return -1;
	}

	/* Locate the root directory */
	memcpy(&root_dirent, cache[i]->data+156, sizeof(iso_dirent_t));
	root_extent = iso_733(root_dirent.extent);
	root_size = iso_733(root_dirent.size);
	
	return 0;
}
Пример #4
0
void read_dir(uint32 extent, uint32 size) {
	int		i;
	iso_dirent_t	*de;
	char		fn[32];
	
	while (size > 0) {
		int c = bread(extent);
		if (c < 0) return;
		
		for (i=0; i<2048 && i<size; ) {
			de = (iso_dirent_t*)(cache[c]->data + i);
			if (!de->length) break;

			strncpy(fn, de->name, de->name_len); fn[de->name_len] = 0;
			if (de->flags & 2)
				printf("%s\t\t<DIR>\n", fn);
			else
				printf("%s\t\t%d\n", fn, iso_733(de->size));
			
			i += de->length;
		}
		
		extent++;
		size -= 2048;
	}
}
Пример #5
0
/* Customized selective data location */
static int init_percd_select(uint32 session_base_select) {
	int		i;
	
	/* Start off with no cached blocks */
	bclear();
	
	/* Grab and check the volume descriptor */	
	i = bread(session_base_select + 16 - 150);
	if (i < 0) return i;
	if (memcmp((char*)cache[i]->data, "\01CD001", 6)) {
		printf("fs_iso9660: disc is not iso9660\r\n");
		return -1;
	}

	/* Locate the root directory */
	memcpy(&root_dirent, cache[i]->data+156, sizeof(iso_dirent_t));
	root_extent = iso_733(root_dirent.extent);
	root_size = iso_733(root_dirent.size);
	
	return 0;
}
Пример #6
0
/* Read a directory entry */
dirent_t *iso_readdir(uint32 fd) {
	int		c = 0;
	iso_dirent_t	*de = NULL;

	if (fd>=MAX_ISO_FILES || fh[fd].first_extent==0 || !fh[fd].dir)
		return NULL;

	/* Scan forwards until we find the next valid entry, an
	   end-of-entry mark, or run out of dir size. */
	while(fh[fd].ptr < fh[fd].size) {
		/* Get the current dirent block */
		c = bread(fh[fd].first_extent + fh[fd].ptr/2048);
		if (c < 0) return NULL;
	
		de = (iso_dirent_t *)(cache[c]->data + (fh[fd].ptr%2048));
		if (de->length) break;

		/* Skip to the next sector */
		fh[fd].ptr += 2048 - (fh[fd].ptr%2048);
	}
	if (fh[fd].ptr >= fh[fd].size) return NULL;
	
	/* If we're at the first, skip the two blank entries */
	if (!de->name[0]) {
		fh[fd].ptr += de->length;
		de = (iso_dirent_t *)(cache[c]->data + (fh[fd].ptr%2048));
		fh[fd].ptr += de->length;
		de = (iso_dirent_t *)(cache[c]->data + (fh[fd].ptr%2048));
		if (!de->length) return NULL;
	}

	
	/* Fill out the VFS dirent */
	strncpy(fh[fd].dirent.name, de->name, de->name_len);
	fh[fd].dirent.name[de->name_len] = 0;
	fn_postprocess(fh[fd].dirent.name);
	if (de->flags & 2)
		fh[fd].dirent.size = -1;
	else
		fh[fd].dirent.size = iso_733(de->size);
	
	fh[fd].ptr += de->length;
	
	return &fh[fd].dirent;
}