Exemplo n.º 1
0
/* msdos_find_node_by_cluster_num_in_fat_file --
 *     Find node with specified number of cluster in fat-file.
 *
 * PARAMETERS:
 *     mt_entry  - mount table entry
 *     fat_fd    - fat-file descriptor
 *     cl4find   - number of cluster to find
 *     paux      - identify a node location on the disk -
 *                 cluster num and offset inside the cluster
 *     dir_entry - placeholder for found node
 *
 * RETURNS:
 *     RC_OK on success, or error code if error occured
 *
 */
int msdos_find_node_by_cluster_num_in_fat_file(
    rtems_filesystem_mount_table_entry_t *mt_entry,
    fat_file_fd_t                        *fat_fd,
    uint32_t                              cl4find,
    fat_auxiliary_t                      *paux,
    char                                 *dir_entry
    )
{
    int              rc = RC_OK;
    ssize_t          ret = 0;
    msdos_fs_info_t *fs_info = mt_entry->fs_info;
    uint32_t         bts2rd = 0;
    uint32_t         i = 0, j = 0;

    if (FAT_FD_OF_ROOT_DIR(fat_fd) &&
       (fs_info->fat.vol.type & (FAT_FAT12 | FAT_FAT16)))
        bts2rd = fat_fd->fat_file_size;
    else
        bts2rd = fs_info->fat.vol.bpc;

    while ((ret = fat_file_read(mt_entry, fat_fd, j * bts2rd, bts2rd,
                                  fs_info->cl_buf)) != FAT_EOF)
    {
        if ( ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE )
            set_errno_and_return_minus_one( EIO );

        assert(ret == bts2rd);

        for (i = 0; i < bts2rd; i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
        {
            /* if this and all rest entries are empty - return not-found */
            if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
                MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY)
                return MSDOS_NAME_NOT_FOUND_ERR;

            /* have to look at the DIR_NAME as "raw" 8-bit data */
            /* if this entry is empty - skip it */
            if ((*(uint8_t *)MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
                MSDOS_THIS_DIR_ENTRY_EMPTY)
                continue;

            /* if get a non-empty entry - compare clusters num */
            if (MSDOS_EXTRACT_CLUSTER_NUM((fs_info->cl_buf + i)) == cl4find)
            {
                /* on success fill aux structure and copy all 32 bytes */
                rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM, j * bts2rd,
                                    &paux->cln);
                if (rc != RC_OK)
                    return rc;

                paux->ofs = i;
                memcpy(dir_entry, fs_info->cl_buf + i,
                       MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
                return RC_OK;
            }
        }
        j++;
    }
    return MSDOS_NAME_NOT_FOUND_ERR;
}
Exemplo n.º 2
0
ssize_t umsdos_file_read_kmem (	struct file *filp,
				char *buf,
				size_t count)
{
	ssize_t ret;
	mm_segment_t old_fs = get_fs ();

	set_fs (KERNEL_DS);
	MSDOS_I (filp->f_dentry->d_inode)->i_binary = 2;
	ret = fat_file_read (filp, buf, count, &filp->f_pos);
	set_fs (old_fs);
	return ret;
}
Exemplo n.º 3
0
/*
	Read a file into kernel space memory
*/
int umsdos_file_read_kmem(
	struct inode *inode,
	struct file *filp,
	char *buf,
	int count)
{
	int ret;
	int old_fs = get_fs();	
	set_fs (KERNEL_DS);
	ret = fat_file_read(inode,filp,buf,count);
	set_fs (old_fs);
	return ret;
}
Exemplo n.º 4
0
/* msdos_dir_is_empty --
 *     Check whether directory which correspondes to the fat-file descriptor is
 *     empty.
 *
 * PARAMETERS:
 *     mt_entry - mount table entry
 *     fat_fd   - fat-file descriptor
 *     ret_val  - placeholder for result
 *
 * RETURNS:
 *     RC_OK on success, or -1 if error occured
 *
 */
int
msdos_dir_is_empty(
    rtems_filesystem_mount_table_entry_t *mt_entry,
    fat_file_fd_t                        *fat_fd,
    rtems_boolean                        *ret_val
    )
{
    ssize_t          ret = 0;
    msdos_fs_info_t *fs_info = mt_entry->fs_info;
    uint32_t         j = 0, i = 0;

    /* dir is not empty */
    *ret_val = FALSE;

    while ((ret = fat_file_read(mt_entry, fat_fd, j * fs_info->fat.vol.bps,
                                  fs_info->fat.vol.bps,
                                  fs_info->cl_buf)) != FAT_EOF)
    {
        if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
            return -1;

        assert(ret == fs_info->fat.vol.bps);

        /* have to look at the DIR_NAME as "raw" 8-bit data */
        for (i = 0;
             i < fs_info->fat.vol.bps;
             i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
        {
            if (((*(uint8_t *)MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
                 MSDOS_THIS_DIR_ENTRY_EMPTY) ||
                (strncmp(MSDOS_DIR_NAME((fs_info->cl_buf + i)), MSDOS_DOT_NAME,
                         MSDOS_SHORT_NAME_LEN) == 0) ||
                (strncmp(MSDOS_DIR_NAME((fs_info->cl_buf + i)),
                         MSDOS_DOTDOT_NAME,
                         MSDOS_SHORT_NAME_LEN) == 0))
                continue;

            if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
                MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY)
            {
                *ret_val = TRUE;
                return RC_OK;
            }
            return RC_OK;
        }
        j++;
    }
    *ret_val = TRUE;
    return RC_OK;
}
Exemplo n.º 5
0
/*
 * Read a file into user space memory
 */
static ssize_t UMSDOS_file_read (
    struct file *filp,
    char *buf,
    size_t count,
    loff_t * ppos
)
{
    struct dentry *dentry = filp->f_dentry;
    struct inode *inode = dentry->d_inode;

    int ret = fat_file_read (filp, buf, count, ppos);

    /* We have to set the access time because msdos don't care */
    if (!IS_RDONLY (inode)) {
        inode->i_atime = CURRENT_TIME;
        mark_inode_dirty(inode);
    }
    return ret;
}
Exemplo n.º 6
0
/* msdos_file_read --
 *     This routine read from file pointed to by file control block into
 *     the specified data buffer provided by user
 *
 * PARAMETERS:
 *     iop    - file control block
 *     buffer - buffer  provided by user
 *     count  - the number of bytes to read
 *
 * RETURNS:
 *     the number of bytes read on success, or -1 if error occured (errno set
 *     appropriately)
 */
ssize_t
msdos_file_read(rtems_libio_t *iop, void *buffer, size_t count)
{
    ssize_t            ret = 0;
    rtems_status_code  sc = RTEMS_SUCCESSFUL;
    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
    fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;

    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
    if (sc != RTEMS_SUCCESSFUL)
        rtems_set_errno_and_return_minus_one(EIO);

    ret = fat_file_read(iop->pathinfo.mt_entry, fat_fd, iop->offset, count,
                        buffer);

    rtems_semaphore_release(fs_info->vol_sema);
    return ret;
}
Exemplo n.º 7
0
void handle_connection(mailbox_id_type *reply_mailbox_id)
{
    system_thread_name_set("Handling connection");

    message_parameter_type message_parameter;
    bool done = FALSE;
    bool mounted = FALSE;
    fat_info_type fat_info;
    ipc_structure_type ipc_structure;
    uint8_t *data;
    uint8_t **data_pointer = &data;
    unsigned int data_size = 16384;

    memory_allocate((void **) data_pointer, data_size);

    // Accept the connection.
    ipc_structure.output_mailbox_id = *reply_mailbox_id;
    if (ipc_connection_establish(&ipc_structure) != IPC_RETURN_SUCCESS)
    {
        return;
    }

    message_parameter.block = TRUE;

    while (!done)
    {
        message_parameter.data = data;
        message_parameter.protocol = IPC_PROTOCOL_FILE;
        message_parameter.message_class = IPC_CLASS_NONE;
        message_parameter.length = data_size;

        if (ipc_receive(ipc_structure.input_mailbox_id, &message_parameter, &data_size) != IPC_RETURN_SUCCESS)
        {
            continue;
        }

        switch (message_parameter.message_class)
        {
            // Read one or more directory entries.
            case IPC_FILE_DIRECTORY_ENTRY_READ:
            {
                if (mounted)
                {
                    file_directory_entry_read_type *directory_entry_read = (file_directory_entry_read_type *) data;

                    if (!fat_directory_entry_read(directory_entry_read, &fat_info))
                    {
                        directory_entry_read->entries = 0;
                    }
                    message_parameter.length =
                        sizeof(file_directory_entry_read_type) +
                        sizeof(file_directory_entry_type) *
                        directory_entry_read->entries ;
                    //          log_print_formatted (0, PACKAGE, "Successfully read %u entries",
                    //                               directory_entry_read->entries);
                    //          log_print_formatted (0, PACKAGE, "max: %u\n", directory_entry_read->entries);
                    ipc_send(ipc_structure.output_mailbox_id, &message_parameter);
                }
                break;
            }

            case IPC_FILE_GET_INFO:
            {
                if (mounted)
                {
                    file_verbose_directory_entry_type *directory_entry = (file_verbose_directory_entry_type *) data;

                    if (!fat_file_get_info(&fat_info, directory_entry))
                    {
                        return_type return_value = FILE_RETURN_FILE_ABSENT;

                        log_print_formatted(&log_structure, LOG_URGENCY_ERROR, "IPC_FILE_GET_INFO failed");
                        message_parameter.message_class = IPC_FILE_RETURN_VALUE;
                        message_parameter.data = &return_value;
                        message_parameter.length = sizeof(return_type);
                    }

                    ipc_send(ipc_structure.output_mailbox_id, &message_parameter);
                }
                break;
            }

            case IPC_FILE_MOUNT_VOLUME:
            {
                mailbox_id_type *mailbox = (mailbox_id_type *) data;

                fat_info.block_structure.output_mailbox_id = *mailbox;
                if (ipc_service_connection_request(&fat_info.block_structure) != IPC_RETURN_SUCCESS)
                {
                    break;
                }

                // Check if we have a FAT file system at this location.
                if (!detect_fat(&fat_info))
                {
                    log_print(&log_structure, LOG_URGENCY_ERROR, "No FAT filesystem detected.");
                    break;
                }

                mounted = TRUE;

                break;
            }

            case IPC_FILE_OPEN:
            {
                ipc_file_open_type *open = (ipc_file_open_type *) data;

                if (!fat_file_open(&fat_info, open))
                {
                    log_print(&log_structure, LOG_URGENCY_ERROR, "Failed to open file.");
                }

                ipc_send(ipc_structure.output_mailbox_id, &message_parameter);

                break;
            }

            case IPC_FILE_READ:
            {
                file_read_type *read = (file_read_type *) data;
                uint8_t *read_buffer;
                uint8_t **read_buffer_pointer = &read_buffer;

                memory_allocate((void **) read_buffer_pointer, read->bytes);

                if (!fat_file_read(&fat_info, read->file_handle, read_buffer, read->bytes))
                {
                    log_print(&log_structure, LOG_URGENCY_ERROR, "Failed to read from file.");
                }

                message_parameter.data = read_buffer;
                message_parameter.length = read->bytes;
#ifdef DEBUG
                log_print_formatted(&log_structure, LOG_URGENCY_DEBUG, "Sending %lu", read->bytes);
#endif
                ipc_send(ipc_structure.output_mailbox_id, &message_parameter);
                memory_deallocate((void **) read_buffer_pointer);
                break;
            }

            // Unsupported functions.
            case IPC_FILE_CLOSE:
            case IPC_FILE_SEEK:
            case IPC_FILE_WRITE:
            case IPC_FILE_ACL_READ:
            case IPC_FILE_ACL_WRITE:
            case IPC_FILE_UNMOUNT_VOLUME:
            default:
            {
                return_type return_value = IPC_RETURN_FILE_FUNCTION_UNSUPPORTED;

                message_parameter.data = &return_value;
                message_parameter.length = sizeof(return_type);

                ipc_send(ipc_structure.output_mailbox_id, &message_parameter);
                break;
            }
        }
    }
}
Exemplo n.º 8
0
/* msdos_find_name_in_fat_file --
 *     This routine is used in two ways: for a new mode creation (a) or for
 *     search the node which correspondes to the 'name' parameter (b).
 *     In case (a) name should be set up to NULL and 'name_dir_entry' should
 *     point to initialized 32 bytes structure described a new node.
 *     In case (b) 'name' should contain a valid string.
 *
 *     (a): reading fat-file corresponded to directory we are going to create
 *          node in. If found free slot write contents of name_dir_entry into
 *          it.
 *
 *     (b): reading fat-file corresponded to directory and trying to find slot
 *          with the name field == name parameter
 *
 * PARAMETERS:
 *     mt_entry       - mount table entry
 *     fat_fd         - fat-file descriptor
 *     name           - NULL or name to find
 *     paux           - identify a node location on the disk -
 *                      number of cluster and offset inside the cluster
 *     name_dir_entry - node to create/placeholder for found node
 *
 * RETURNS:
 *     RC_OK on success, or error code if error occured (errno set
 *     appropriately)
 *
 */
int msdos_find_name_in_fat_file(
    rtems_filesystem_mount_table_entry_t *mt_entry,
    fat_file_fd_t                        *fat_fd,
    char                                 *name,
    fat_auxiliary_t                      *paux,
    char                                 *name_dir_entry
    )
{
    int              rc = RC_OK;
    ssize_t          ret = 0;
    msdos_fs_info_t *fs_info = mt_entry->fs_info;
    uint32_t         i = 0, j = 0;
    uint32_t         bts2rd = 0;

    if (FAT_FD_OF_ROOT_DIR(fat_fd) &&
       (fs_info->fat.vol.type & (FAT_FAT12 | FAT_FAT16)))
        bts2rd = fat_fd->fat_file_size;
    else
        bts2rd = fs_info->fat.vol.bpc;

    while ((ret = fat_file_read(mt_entry, fat_fd, (j * bts2rd), bts2rd,
                                fs_info->cl_buf)) != FAT_EOF)
    {
        if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
            set_errno_and_return_minus_one(EIO);

        assert(ret == bts2rd);

        /* have to look at the DIR_NAME as "raw" 8-bit data */
        for (i = 0; i < bts2rd; i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
        {
            /* is the entry empty ? */
            if (((*(uint8_t *)MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
                 MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY) ||
                 ((*(uint8_t *)MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
                 MSDOS_THIS_DIR_ENTRY_EMPTY))
            {
                /* whether we are looking for an empty entry */
                if (name == NULL)
                {
                    /* get current cluster number */
                    rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM,
                                        j * bts2rd, &paux->cln);
                    if (rc != RC_OK)
                        return rc;

                    /* offset is computed in bytes */
                    paux->ofs = i;

                    /* write new node entry */
                    ret = fat_file_write(mt_entry, fat_fd, j * bts2rd + i,
                                         MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE,
                                         (uint8_t *)name_dir_entry);
                    if (ret != MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
                        return -1;

                    /*
                     * we don't update fat_file_size here - it should not
                     * increase
                     */
                    return RC_OK;
                }

                /*
                 * if name != NULL and there is no more entries in the
                 * directory - return name-not-found
                 */
                if (((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
                     MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY))
                    return MSDOS_NAME_NOT_FOUND_ERR;
            }
            else
            {
                /* entry not empty and name != NULL -> compare names */
                if (name != NULL)
                {
                    if (strncmp(MSDOS_DIR_NAME((fs_info->cl_buf + i)), name,
                                MSDOS_SHORT_NAME_LEN) == 0)
                    {
                        /*
                         * we get the entry we looked for - fill auxiliary
                         * structure and copy all 32 bytes of the entry
                         */
                        rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM,
                                            j * bts2rd, &paux->cln);
                        if (rc != RC_OK)
                            return rc;

                        /* offset is computed in bytes */
                        paux->ofs = i;
                        memcpy(name_dir_entry,(fs_info->cl_buf + i),
                               MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
                        return RC_OK;
                    }
                }
            }
        }
        j++;
    }
    return MSDOS_NAME_NOT_FOUND_ERR;
}
Exemplo n.º 9
0
/***********************************************************************
 *
 * Function: raw_load
 *
 * Purpose: Load a raw file from a source to memory
 *
 * Processing:
 *     See function.
 *
 * Parameters:
 *     fdata : Pointer to file data to fill
 *     addr  : Address to load data
 *     filename : Filename (sd cards only)
 *     src   : Data source
 *
 * Outputs: None
 *
 * Returns: TRUE if the file was loaded, otherwise FALSE
 *
 * Notes: None
 *
 **********************************************************************/
BOOL_32 raw_load(FILE_DATA_T *fdata,
                 UNS_32 addr,
                 UNS_8 *filename,
                 SRC_LOAD_T src) 
{
	UNS_32 rb, bytes = 0;
	UNS_8 ch, *ptr8 = (UNS_8 *) addr;
	BOOL_32 readloop, loaded = FALSE;

	if (src == SRC_TERM) 
	{
		term_dat_out_crlf(rawdl_msg);

		/* Read data from terminal until a break is encountered */
		while (term_break() == FALSE) 
		{
			if (term_dat_in(&ch, 1) > 0) 
			{
				bytes++;
				*ptr8 = ch;
				ptr8++;
			}
		}

		fdata->num_bytes = bytes;
		fdata->contiguous = TRUE;
		loaded = TRUE;
	}
	else if (src == SRC_NAND) 
	{
		/* Move image in NAND to memory */
		term_dat_out_crlf(rawnanddlns_msg);

	}
	else if (src == SRC_BLKDEV) 
	{
		/* Initialize FAT interface first */
		if (fat_init() == FALSE)
		{
			term_dat_out(blkdeverr_msg);
		}
		/* Try to open file */
		else if (fat_file_open(filename) == FALSE) 
		{
			term_dat_out_crlf(nofilmsg);
		}
		else 
		{
			fdata->num_bytes = 0;
			readloop = TRUE;
			while (readloop == TRUE) 
			{
				rb = fat_file_read(ptr8, 8);
				fdata->num_bytes += rb;
				ptr8 += 8;
				if (rb != 8) 
				{
					readloop = FALSE;
				}
			}
			fdata->contiguous = TRUE;
			loaded = TRUE;
		}

		fat_deinit();
	}

	return loaded;
}
Exemplo n.º 10
0
/***********************************************************************
 *
 * Function: readline
 *
 * Purpose: Read line with line feed
 *
 * Processing:
 *     See function.
 *
 * Parameters:
 *     data : Pointer to line data to fill
 *     src  : Data source
 *
 * Outputs: None
 *
 * Returns: TRUE if the line was loaded, otherwise FALSE
 *
 * Notes: None
 *
 **********************************************************************/
static BOOL_32 readline(UNS_8 *data,
                        SRC_LOAD_T src) 
{
	UNS_32 rb;
	int lastidx, idx;
	BOOL_32 linedone = FALSE, linegood = FALSE;

	lastidx = idx = 0;
	while (linedone == FALSE) 
	{
		switch (src) 
		{
			case SRC_TERM:
				/* Has a break occurred? */
				if (term_break() == TRUE) 
				{
					/* Exit now */
					linedone = TRUE;
				}
				else if (term_dat_in((data + idx), 1) > 0) 
				{
					idx++;
				}
				break;

			case SRC_NAND:
				/* Get a byte from the FLASH */
				/* Get a byte from the SD/MMC card */
				rb = stream_flash_read(&data [idx], 1);
				if (rb == 0) 
				{
					linedone = TRUE;
				}
				idx++;
				break;

			case SRC_BLKDEV:
				/* Get a byte from the SD/MMC card */
				rb = fat_file_read(&data [idx], 1);
				if (rb == 0) 
				{
					linedone = TRUE;
				}
				idx++;
				break;

			case SRC_NONE:
			default:
				return FALSE;
		}

		if (lastidx != idx) 
		{
			if (data [lastidx] == '\r') 
			{
				linedone = TRUE;
				linegood = TRUE;
				data [lastidx] = '\0';
			}

			lastidx = idx;
		}
	}

	data [idx] = '\0';
	str_upper_to_lower(data);
	return linegood;
}
Exemplo n.º 11
0
static ssize_t fat32fs_read(vfs_fd *vfd, void *buf, size_t count) {
	if (!vfd->private_data)
		return -1;
	return fat_file_read((fat_file *)vfd->private_data, buf, count);
}