Exemple #1
0
int chdir(const char *src)
{
    int rv;
    struct file *file;
    char cwd_buf[CURRENTDIR_MAX];

    if (this_fs->fs_ops->chdir)
	return this_fs->fs_ops->chdir(this_fs, src);

    /* Otherwise it is a "conventional filesystem" */
    rv = searchdir(src);
    if (rv < 0)
	return rv;

    file = handle_to_file(rv);
    if (file->inode->mode != DT_DIR) {
	_close_file(file);
	return -1;
    }

    put_inode(this_fs->cwd);
    this_fs->cwd = get_inode(file->inode);
    _close_file(file);

    /* Save the current working directory */
    realpath(cwd_buf, src, CURRENTDIR_MAX);

    /* Make sure the cwd_name ends in a slash, it's supposed to be a prefix */
    join_paths(this_fs->cwd_name, CURRENTDIR_MAX, cwd_buf, "/");

    return 0;
}
Exemple #2
0
__export int open_file(const char *name, int flags, struct com32_filedata *filedata)
{
    int rv;
    struct file *file;
    char mangled_name[FILENAME_MAX];

    dprintf("open_file %s\n", name);

    mangle_name(mangled_name, name);
    rv = searchdir(mangled_name, flags);

    if (rv < 0)
	return rv;

    file = handle_to_file(rv);

    if (file->inode->mode != DT_REG) {
	_close_file(file);
	return -1;
    }

    filedata->size	= file->inode->size;
    filedata->blocklg2	= SECTOR_SHIFT(file->fs);
    filedata->handle	= rv;

    return rv;
}
Exemple #3
0
void getfsbytes(com32sys_t *regs)
{
    int sectors;
    bool have_more;
    uint32_t bytes_read;
    char *buf;
    struct file *file;
    uint16_t handle;

    handle = regs->esi.w[0];
    file = handle_to_file(handle);

    sectors = regs->ecx.w[0] >> SECTOR_SHIFT(file->fs);

    buf = MK_PTR(regs->es, regs->ebx.w[0]);
    bytes_read = file->fs->fs_ops->getfssec(file, buf, sectors, &have_more);

    /*
     * If we reach EOF, the filesystem driver will have already closed
     * the underlying file... this really should be cleaner.
     */
    if (!have_more) {
	_close_file(file);
        regs->esi.w[0] = 0;
    }

    regs->ecx.l = bytes_read;
}
int AudioStreamPlaybackOGGVorbis::mix(int16_t* p_bufer,int p_frames) {

	if (!playing)
		return 0;

	int total=p_frames;
	while (true) {

		int todo = p_frames;

		if (todo==0 || todo<MIN_MIX) {
			break;
		}

		//printf("to mix %i - mix me %i bytes\n",to_mix,to_mix*stream_channels*sizeof(int16_t));

		#ifdef BIG_ENDIAN_ENABLED
		long ret=ov_read(&vf,(char*)p_bufer,todo*stream_channels*sizeof(int16_t), 1, 2, 1, &current_section);
		#else
		long ret=ov_read(&vf,(char*)p_bufer,todo*stream_channels*sizeof(int16_t), 0, 2, 1, &current_section);
		#endif

		if (ret<0) {

			playing = false;
			ERR_EXPLAIN("Error reading OGG Vorbis File: "+file);
			ERR_BREAK(ret<0);
		} else if (ret==0) { // end of song, reload?

			ov_clear(&vf);

			_close_file();

			if (!has_loop()) {

				playing=false;
				repeats=1;
				break;
			}

			f=FileAccess::open(file,FileAccess::READ);

			int errv = ov_open_callbacks(f,&vf,NULL,0,_ov_callbacks);
			if (errv!=0) {
				playing=false;
				break;; // :(
			}

			if (loop_restart_time) {
				bool ok = ov_time_seek(&vf,loop_restart_time)==0;
				if (!ok) {
					playing=false;
					//ERR_EXPLAIN("loop restart time rejected");
					ERR_PRINT("loop restart time rejected")
				}

				frames_mixed=stream_srate*loop_restart_time;
			} else {
Exemple #5
0
__export void close_file(uint16_t handle)
{
    struct file *file;

    if (handle) {
	file = handle_to_file(handle);
	_close_file(file);
    }
}
Exemple #6
0
void FileIODevice::send_data(const QByteArray &data)
{
    lock_file(true);
    _open_file(true);

    // At this point the settings file is ours for sole writing
    QT_IODevice::send_data(data);

    _close_file();
    unlock_file();
}
Exemple #7
0
void AudioStreamPlaybackOpus::_clear_stream() {
	if(!stream_loaded)
		return;

	op_free(opus_file);
	_close_file();

	stream_loaded=false;
	stream_channels=1;
	playing=false;
}
Exemple #8
0
QByteArray FileIODevice::receive_data()
{
    lock_file(false);
    _open_file(false);

    QByteArray ret = QT_IODevice::receive_data();

    _close_file();
    unlock_file();

    _last_update_time = QFileInfo(FileName()).lastModified();

    return ret;
}
Exemple #9
0
/*==============================================================================
 * - _ebook_cb_page()
 *
 * - when user release 'ebook' cbi, call this
 */
static OS_STATUS _ebook_cb_page (GUI_CBI *pCBI_ebook, GUI_COOR *pCoor)
{
    if (pCoor->x < gra_scr_w() / 2) {
        _show_page (PAGE_PREV);
    } else {
        if (pCoor->y >= ICON_SIZE || pCoor->x < (gra_scr_w () - ICON_SIZE)) {
            _show_page (PAGE_NEXT);
        } else {
            _close_file ();
        }
    }

    return OS_STATUS_OK;
}
Exemple #10
0
int AudioStreamPlaybackOpus::mix(int16_t* p_bufer,int p_frames) {
	if (!playing)
		return 0;

	int total=p_frames;

	while (true) {

		int todo = p_frames;

		if (todo==0 || todo<MIN_MIX) {
			break;
		}

		int ret=op_read(opus_file,(opus_int16*)p_bufer,todo*stream_channels,&current_section);
		if (ret<0) {
			playing = false;
			ERR_EXPLAIN("Error reading Opus File: "+file);
			ERR_BREAK(ret<0);
		} else if (ret==0) { // end of song, reload?
			op_free(opus_file);

			_close_file();

			f=FileAccess::open(file,FileAccess::READ);

			int errv = 0;
			opus_file = op_open_callbacks(f,&_op_callbacks,NULL,0,&errv);
			if (errv!=0) {
				playing=false;
				break; // :(
			}

			if (!has_loop()) {
				playing=false;
				repeats=1;
				break;
			}

			if (loop_restart_time) {
				bool ok = op_pcm_seek(opus_file, (loop_restart_time*osrate)+pre_skip)==0;
				if (!ok) {
					playing=false;
					ERR_PRINT("loop restart time rejected")
				}

				frames_mixed=(loop_restart_time*osrate)+pre_skip;
			} else {
Exemple #11
0
/* 
 * Open a directory
 */
__export DIR *opendir(const char *path)
{
    int rv;
    struct file *file;

    rv = searchdir(path, O_RDONLY|O_DIRECTORY);
    if (rv < 0)
	return NULL;

    file = handle_to_file(rv);

    if (file->inode->mode != DT_DIR) {
	_close_file(file);
	return NULL;
    }

    return (DIR *)file;
}
Exemple #12
0
size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors)
{
    bool have_more;
    size_t bytes_read;
    struct file *file;

    file = handle_to_file(*handle);
    bytes_read = file->fs->fs_ops->getfssec(file, buf, sectors, &have_more);

    /*
     * If we reach EOF, the filesystem driver will have already closed
     * the underlying file... this really should be cleaner.
     */
    if (!have_more) {
	_close_file(file);
	*handle = 0;
    }

    return bytes_read;
}
Exemple #13
0
void pm_load_high(com32sys_t *regs)
{
    struct fs_info *fs;
    uint32_t bytes;
    uint32_t zero_mask;
    bool have_more;
    uint32_t bytes_read;
    char *buf, *limit;
    struct file *file;
    uint32_t sector_mask;
    size_t pad;
    uint32_t retflags = 0;

    bytes     = regs->eax.l;
    zero_mask = regs->edx.w[0];
    buf       = (char *)regs->edi.l;
    limit     = (char *)(regs->ebp.l & ~zero_mask);
    file      = handle_to_file(regs->esi.w[0]);
    fs        = file->fs;

    sector_mask = SECTOR_SIZE(fs) - 1;

    while (bytes) {
	uint32_t sectors;
	uint32_t chunk;

	if (buf + SECTOR_SIZE(fs) > limit) {
	    /* Can't fit even one more sector in... */
	    retflags = EFLAGS_OF;
	    break;
	}

	chunk = bytes;

	if (regs->ebx.w[0]) {
	    call16((void (*)(void))(size_t)regs->ebx.w[0], &zero_regs, NULL);
	    chunk = min(chunk, MAX_CHUNK);
	}

	if (chunk > (((char *)limit - buf) & ~sector_mask))
	    chunk = ((char *)limit - buf) & ~sector_mask;

	sectors = (chunk + sector_mask) >> SECTOR_SHIFT(fs);
	bytes_read = fs->fs_ops->getfssec(file, buf, sectors, &have_more);

	if (bytes_read > chunk)
	    bytes_read = chunk;

	buf += bytes_read;
	bytes -= bytes_read;

	if (!have_more) {
	    /*
	     * If we reach EOF, the filesystem driver will have already closed
	     * the underlying file... this really should be cleaner.
	     */
	    _close_file(file);
	    regs->esi.w[0] = 0;
	    retflags = EFLAGS_CF;
	    break;
	}
    }

    pad = (size_t)buf & zero_mask;
    if (pad)
	memset(buf, 0, pad);

    regs->ebx.l = (size_t)buf;
    regs->edi.l = (size_t)buf + pad;
    set_flags(regs, retflags);
}
Exemple #14
0
int searchdir(const char *name, int flags)
{
    static char root_name[] = "/";
    struct file *file;
    char *path, *inode_name, *next_inode_name;
    struct inode *tmp, *inode = NULL;
    int symlink_count = MAX_SYMLINK_CNT;

    dprintf("searchdir: %s  root: %p  cwd: %p\n",
	    name, this_fs->root, this_fs->cwd);

    if (!(file = alloc_file()))
	goto err_no_close;
    file->fs = this_fs;

    /* if we have ->searchdir method, call it */
    if (file->fs->fs_ops->searchdir) {
	file->fs->fs_ops->searchdir(name, flags, file);

	if (file->inode)
	    return file_to_handle(file);
	else
	    goto err;
    }

    /* else, try the generic-path-lookup method */

    /* Copy the path */
    path = strdup(name);
    if (!path) {
	dprintf("searchdir: Couldn't copy path\n");
	goto err_path;
    }

    /* Work with the current directory, by default */
    inode = get_inode(this_fs->cwd);
    if (!inode) {
	dprintf("searchdir: Couldn't use current directory\n");
	goto err_curdir;
    }

    for (inode_name = path; inode_name; inode_name = next_inode_name) {
	/* Root directory? */
	if (inode_name[0] == '/') {
	    next_inode_name = inode_name + 1;
	    inode_name = root_name;
	} else {
	    /* Find the next inode name */
	    next_inode_name = strchr(inode_name + 1, '/');
	    if (next_inode_name) {
		/* Terminate the current inode name and point to next */
		*next_inode_name++ = '\0';
	    }
	}
	if (next_inode_name) {
	    /* Advance beyond redundant slashes */
	    while (*next_inode_name == '/')
		next_inode_name++;

	    /* Check if we're at the end */
	    if (*next_inode_name == '\0')
		next_inode_name = NULL;
	}
	dprintf("searchdir: inode_name: %s\n", inode_name);
	if (next_inode_name)
	    dprintf("searchdir: Remaining: %s\n", next_inode_name);

	/* Root directory? */
	if (inode_name[0] == '/') {
	    /* Release any chain that's already been established */
	    put_inode(inode);
	    inode = get_inode(this_fs->root);
	    continue;
	}

	/* Current directory? */
	if (!strncmp(inode_name, ".", sizeof "."))
	    continue;

	/* Parent directory? */
	if (!strncmp(inode_name, "..", sizeof "..")) {
	    /* If there is no parent, just ignore it */
	    if (!inode->parent)
		continue;

	    /* Add a reference to the parent so we can release the child */
	    tmp = get_inode(inode->parent);

	    /* Releasing the child will drop the parent back down to 1 */
	    put_inode(inode);

	    inode = tmp;
	    continue;
	}

	/* Anything else */
	tmp = inode;
	inode = this_fs->fs_ops->iget(inode_name, inode);
	if (!inode) {
	    /* Failure.  Release the chain */
	    put_inode(tmp);
	    break;
	}

	/* Sanity-check */
	if (inode->parent && inode->parent != tmp) {
	    dprintf("searchdir: iget returned a different parent\n");
	    put_inode(inode);
	    inode = NULL;
	    put_inode(tmp);
	    break;
	}
	inode->parent = tmp;
	inode->name = strdup(inode_name);
	dprintf("searchdir: path component: %s\n", inode->name);

	/* Symlink handling */
	if (inode->mode == DT_LNK) {
	    char *new_path;
	    int new_len, copied;

	    /* target path + NUL */
	    new_len = inode->size + 1;

	    if (next_inode_name) {
		/* target path + slash + remaining + NUL */
		new_len += strlen(next_inode_name) + 1;
	    }

	    if (!this_fs->fs_ops->readlink ||
		/* limit checks */
		--symlink_count == 0 ||
		new_len > MAX_SYMLINK_BUF)
		goto err_new_len;

	    new_path = malloc(new_len);
	    if (!new_path)
		goto err_new_path;

	    copied = this_fs->fs_ops->readlink(inode, new_path);
	    if (copied <= 0)
		goto err_copied;
	    new_path[copied] = '\0';
	    dprintf("searchdir: Symlink: %s\n", new_path);

	    if (next_inode_name) {
		new_path[copied] = '/';
		strcpy(new_path + copied + 1, next_inode_name);
		dprintf("searchdir: New path: %s\n", new_path);
	    }

	    free(path);
	    path = next_inode_name = new_path;

            /* Add a reference to the parent so we can release the child */
            tmp = get_inode(inode->parent);

            /* Releasing the child will drop the parent back down to 1 */
            put_inode(inode);

            inode = tmp;
	    continue;
err_copied:
	    free(new_path);
err_new_path:
err_new_len:
	    put_inode(inode);
	    inode = NULL;
	    break;
	}

	/* If there's more to process, this should be a directory */
	if (next_inode_name && inode->mode != DT_DIR) {
	    dprintf("searchdir: Expected a directory\n");
	    put_inode(inode);
	    inode = NULL;
	    break;
	}
    }
err_curdir:
    free(path);
err_path:
    if (!inode) {
	dprintf("searchdir: Not found\n");
	goto err;
    }

    file->inode  = inode;
    file->offset = 0;

    return file_to_handle(file);

err:
    dprintf("serachdir: error seraching file %s\n", name);
    _close_file(file);
err_no_close:
    return -1;
}
Exemple #15
0
int searchdir(const char *name)
{
    struct inode *inode = NULL;
    struct inode *parent = NULL;
    struct file *file;
    char *pathbuf = NULL;
    char *part, *p, echar;
    int symlink_count = MAX_SYMLINK_CNT;

    dprintf("searchdir: %s  root: %p  cwd: %p\n",
	    name, this_fs->root, this_fs->cwd);

    if (!(file = alloc_file()))
	goto err_no_close;
    file->fs = this_fs;

    /* if we have ->searchdir method, call it */
    if (file->fs->fs_ops->searchdir) {
	file->fs->fs_ops->searchdir(name, file);

	if (file->inode)
	    return file_to_handle(file);
	else
	    goto err;
    }

    /* else, try the generic-path-lookup method */

    parent = get_inode(this_fs->cwd);
    p = pathbuf = strdup(name);
    if (!pathbuf)
	goto err;

    do {
    got_link:
	if (*p == '/') {
	    put_inode(parent);
	    parent = get_inode(this_fs->root);
	}

	do {
	    inode = get_inode(parent);

	    while (*p == '/')
		p++;

	    if (!*p)
		break;

	    part = p;
	    while ((echar = *p) && echar != '/')
		p++;
	    *p++ = '\0';

	    if (part[0] == '.' && part[1] == '.' && part[2] == '\0') {
		if (inode->parent) {
		    put_inode(parent);
		    parent = get_inode(inode->parent);
		    put_inode(inode);
		    inode = NULL;
		    if (!echar) {
			/* Terminal double dots */
			inode = parent;
			parent = inode->parent ?
			    get_inode(inode->parent) : NULL;
		    }
		}
	    } else if (part[0] != '.' || part[1] != '\0') {
		inode = this_fs->fs_ops->iget(part, parent);
		if (!inode)
		    goto err;
		if (inode->mode == DT_LNK) {
		    char *linkbuf, *q;
		    int name_len = echar ? strlen(p) : 0;
		    int total_len = inode->size + name_len + 2;
		    int link_len;

		    if (!this_fs->fs_ops->readlink ||
			--symlink_count == 0       ||      /* limit check */
			total_len > MAX_SYMLINK_BUF)
			goto err;

		    linkbuf = malloc(total_len);
		    if (!linkbuf)
			goto err;

		    link_len = this_fs->fs_ops->readlink(inode, linkbuf);
		    if (link_len <= 0) {
			free(linkbuf);
			goto err;
		    }

		    q = linkbuf + link_len;

		    if (echar) {
			if (link_len > 0 && q[-1] != '/')
			    *q++ = '/';

			memcpy(q, p, name_len+1);
		    } else {
			*q = '\0';
		    }

		    free(pathbuf);
		    p = pathbuf = linkbuf;
		    put_inode(inode);
		    inode = NULL;
		    goto got_link;
		}

		inode->name = strdup(part);
		dprintf("path component: %s\n", inode->name);

		inode->parent = parent;
		parent = NULL;

		if (!echar)
		    break;

		if (inode->mode != DT_DIR)
		    goto err;

		parent = inode;
		inode = NULL;
	    }
	} while (echar);
    } while (0);

    free(pathbuf);
    pathbuf = NULL;
    put_inode(parent);
    parent = NULL;

    if (!inode)
	goto err;

    file->inode  = inode;
    file->offset = 0;

    return file_to_handle(file);

err:
    put_inode(inode);
    put_inode(parent);
    if (pathbuf)
	free(pathbuf);
    _close_file(file);
err_no_close:
    return -1;
}
Exemple #16
0
/*
 * Close a directory
 */
__export int closedir(DIR *dir)
{
    struct file *dd_dir = (struct file *)dir;
    _close_file(dd_dir);
    return 0;
}