diff options
author | Chris Johns <chrisj@rtems.org> | 2009-04-29 08:31:27 +0000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2009-04-29 08:31:27 +0000 |
commit | 07d6fd513f1c4d3c6905c880948671de1181fac2 (patch) | |
tree | 4dabf3fdd0b056bba7b0e9beb40f01277e5c2776 /cpukit/libfs/src/dosfs/msdos_create.c | |
parent | 2009-04-28 Chris Johns <chrisj@rtems.org> (diff) | |
download | rtems-07d6fd513f1c4d3c6905c880948671de1181fac2.tar.bz2 |
2009-04-29 Chris Johns <chrisj@rtems.org>
* libcsupport/include/rtems/libio.h: Add rtems_off64_t for
internal use. Update the internal off_t to the 64bit offset.
* libnetworking/lib/ftpfs.c, libnetworking/lib/tftpDriver.c,
libfs/src/nfsclient/src/nfs.c, libfs/src/imfs/imfs_fifo.c,
libfs/src/imfs/memfile.c, libfs/src/imfs/imfs_directory.c,
libfs/src/imfs/imfs.h, libfs/src/imfs/deviceio.c: Change off_t to
rtems_off64_t.
* libmisc/shell/main_msdosfmt.c: Add an info level so the format
code can tell the user what is happening. Add more options to
control the format configuration.
* libfs/src/dosfs/msdos_format.c: Add a print function to display
the format progress and print statements. Select a better default
cluster size depending on the size of the disk. This lowers the
size of the FAT on large disks. Read and maintain the MRB
partition information.
* libfs/src/dosfs/dosfs.h, libfs/src/dosfs/fat.h,
libfs/src/dosfs/fat_file.c, libfs/src/dosfs/fat_file.h,
libfs/src/dosfs/msdos.h, libfs/src/dosfs/msdos_conv.c,
libfs/src/dosfs/msdos_create.c, libfs/src/dosfs/msdos_file.c,
libfs/src/dosfs/msdos_handlers_dir.c,
libfs/src/dosfs/msdos_handlers_file.c,
libfs/src/dosfs/msdos_init.c, libfs/src/dosfs/msdos_initsupp.c,
libfs/src/dosfs/msdos_misc.c, libfs/src/dosfs/msdos_mknod.c: Add
long file name support. Change off_t to rtems_off64_t.
Diffstat (limited to 'cpukit/libfs/src/dosfs/msdos_create.c')
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_create.c | 135 |
1 files changed, 72 insertions, 63 deletions
diff --git a/cpukit/libfs/src/dosfs/msdos_create.c b/cpukit/libfs/src/dosfs/msdos_create.c index c790dd740f..bbdf137600 100644 --- a/cpukit/libfs/src/dosfs/msdos_create.c +++ b/cpukit/libfs/src/dosfs/msdos_create.c @@ -17,6 +17,7 @@ #include <errno.h> #include <assert.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <rtems/libio_.h> @@ -29,7 +30,14 @@ #include "msdos.h" /* msdos_creat_node -- - * Create a new node. If a new node is file, FAT 32 Bytes Directory + * Create a new node. Determine if the name is a long name. If long we to + * scan the directory to create a short entry. + * + * + + + + * If a new node is file, FAT 32 Bytes Directory * Entry Structure is initialized, free space is found in parent * directory and structure is written to the disk. In case of directory, * all above steps present and also new cluster is allocated for a @@ -48,52 +56,55 @@ * */ int -msdos_creat_node( - rtems_filesystem_location_info_t *parent_loc, - msdos_node_type_t type, - char *name, - mode_t mode, - const fat_file_fd_t *link_fd - ) +msdos_creat_node(rtems_filesystem_location_info_t *parent_loc, + msdos_node_type_t type, + const char *name, + int name_len, + mode_t mode, + const fat_file_fd_t *link_fd) { - int rc = RC_OK; - ssize_t ret = 0; - msdos_fs_info_t *fs_info = parent_loc->mt_entry->fs_info; - fat_file_fd_t *parent_fat_fd = parent_loc->node_access; - fat_file_fd_t *fat_fd = NULL; - time_t time_ret = 0; - uint16_t time_val = 0; - uint16_t date = 0; - fat_auxiliary_t aux; - char new_node [MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE]; - char dot_dotdot[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2]; - char link_node [MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE]; - uint32_t sec = 0; - uint32_t byte = 0; - - memset(new_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); + int rc = RC_OK; + ssize_t ret = 0; + msdos_fs_info_t *fs_info = parent_loc->mt_entry->fs_info; + fat_file_fd_t *parent_fat_fd = parent_loc->node_access; + fat_file_fd_t *fat_fd = NULL; + time_t time_ret = 0; + uint16_t time_val = 0; + uint16_t date = 0; + fat_dir_pos_t dir_pos; + msdos_name_type_t name_type; + char short_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE]; + char dot_dotdot[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2]; + char link_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE]; + uint32_t sec = 0; + uint32_t byte = 0; + + fat_dir_pos_init(&dir_pos); + + memset(short_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); memset(dot_dotdot, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2); - /* set up name */ - strncpy(MSDOS_DIR_NAME(new_node), name, MSDOS_NAME_MAX); + name_type = msdos_long_to_short (name, name_len, + MSDOS_DIR_NAME(short_node), + MSDOS_NAME_MAX); /* fill reserved field */ - *MSDOS_DIR_NT_RES(new_node) = MSDOS_RES_NT_VALUE; + *MSDOS_DIR_NT_RES(short_node) = MSDOS_RES_NT_VALUE; /* set up last write date and time */ time_ret = time(NULL); if ( time_ret == -1 ) return -1; - msdos_date_unix2dos(time_ret, &time_val, &date); - *MSDOS_DIR_WRITE_TIME(new_node) = CT_LE_W(time_val); - *MSDOS_DIR_WRITE_DATE(new_node) = CT_LE_W(date); + msdos_date_unix2dos(time_ret, &date, &time_val); + *MSDOS_DIR_WRITE_TIME(short_node) = CT_LE_W(time_val); + *MSDOS_DIR_WRITE_DATE(short_node) = CT_LE_W(date); /* initialize directory/file size */ - *MSDOS_DIR_FILE_SIZE(new_node) = MSDOS_INIT_DIR_SIZE; + *MSDOS_DIR_FILE_SIZE(short_node) = MSDOS_INIT_DIR_SIZE; - if (type == MSDOS_DIRECTORY){ - *MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_DIRECTORY; + if (type == MSDOS_DIRECTORY) { + *MSDOS_DIR_ATTR(short_node) |= MSDOS_ATTR_DIRECTORY; } else if (type == MSDOS_HARD_LINK) { /* @@ -105,51 +116,52 @@ msdos_creat_node( * read the original directory entry */ sec = fat_cluster_num_to_sector_num(parent_loc->mt_entry, - link_fd->info_cln); - sec += (link_fd->info_ofs >> fs_info->fat.vol.sec_log2); - byte = (link_fd->info_ofs & (fs_info->fat.vol.bps - 1)); + link_fd->dir_pos.sname.cln); + sec += (link_fd->dir_pos.sname.ofs >> fs_info->fat.vol.sec_log2); + byte = (link_fd->dir_pos.sname.ofs & (fs_info->fat.vol.bps - 1)); ret = _fat_block_read(parent_loc->mt_entry, - sec, byte, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE, + sec, byte, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE, link_node); if (ret < 0) { - return -1; + return -1; } /* * copy various attributes */ - *MSDOS_DIR_ATTR(new_node) =*MSDOS_DIR_ATTR(link_node); - *MSDOS_DIR_CRT_TIME_TENTH(new_node)=*MSDOS_DIR_CRT_TIME_TENTH(link_node); - *MSDOS_DIR_CRT_TIME(new_node) =*MSDOS_DIR_CRT_TIME(link_node); - *MSDOS_DIR_CRT_DATE(new_node) =*MSDOS_DIR_CRT_DATE(link_node); + *MSDOS_DIR_ATTR(short_node) =*MSDOS_DIR_ATTR(link_node); + *MSDOS_DIR_CRT_TIME_TENTH(short_node)=*MSDOS_DIR_CRT_TIME_TENTH(link_node); + *MSDOS_DIR_CRT_TIME(short_node) =*MSDOS_DIR_CRT_TIME(link_node); + *MSDOS_DIR_CRT_DATE(short_node) =*MSDOS_DIR_CRT_DATE(link_node); /* * copy/set "file size", "first cluster" */ - *MSDOS_DIR_FILE_SIZE(new_node) =*MSDOS_DIR_FILE_SIZE(link_node); + *MSDOS_DIR_FILE_SIZE(short_node) =*MSDOS_DIR_FILE_SIZE(link_node); - *MSDOS_DIR_FIRST_CLUSTER_LOW(new_node) = + *MSDOS_DIR_FIRST_CLUSTER_LOW(short_node) = *MSDOS_DIR_FIRST_CLUSTER_LOW(link_node); - *MSDOS_DIR_FIRST_CLUSTER_HI(new_node) = + *MSDOS_DIR_FIRST_CLUSTER_HI(short_node) = *MSDOS_DIR_FIRST_CLUSTER_HI(link_node); /* * set "archive bit" due to changes */ - *MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_ARCHIVE; + *MSDOS_DIR_ATTR(short_node) |= MSDOS_ATTR_ARCHIVE; /* * set "last access" date to today */ - *MSDOS_DIR_LAST_ACCESS_DATE(new_node) = CT_LE_W(date); + *MSDOS_DIR_LAST_ACCESS_DATE(short_node) = CT_LE_W(date); } else { /* regular file... */ - *MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_ARCHIVE; + *MSDOS_DIR_ATTR(short_node) |= MSDOS_ATTR_ARCHIVE; } /* * find free space in the parent directory and write new initialized * FAT 32 Bytes Directory Entry Structure to the disk */ - rc = msdos_get_name_node(parent_loc, NULL, &aux, new_node); + rc = msdos_get_name_node(parent_loc, true, name, name_len, + name_type, &dir_pos, short_node); if ( rc != RC_OK ) return rc; @@ -160,7 +172,7 @@ msdos_creat_node( if (type == MSDOS_DIRECTORY) { /* open new directory as fat-file */ - rc = fat_file_open(parent_loc->mt_entry, aux.cln, aux.ofs, &fat_fd); + rc = fat_file_open(parent_loc->mt_entry, &dir_pos, &fat_fd); if (rc != RC_OK) goto err; @@ -168,8 +180,6 @@ msdos_creat_node( * we opened fat-file for node we just created, so initialize fat-file * descritor */ - fat_fd->info_cln = aux.cln; - fat_fd->info_ofs = aux.ofs; fat_fd->fat_file_size = 0; fat_fd->fat_file_type = FAT_DIRECTORY; fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT; @@ -178,9 +188,9 @@ msdos_creat_node( * dot and dotdot entries are identical to new node except the * names */ - memcpy(DOT_NODE_P(dot_dotdot), new_node, + memcpy(DOT_NODE_P(dot_dotdot), short_node, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); - memcpy(DOTDOT_NODE_P(dot_dotdot), new_node, + memcpy(DOTDOT_NODE_P(dot_dotdot), short_node, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); memcpy(MSDOS_DIR_NAME(DOT_NODE_P(dot_dotdot)), MSDOS_DOT_NAME, MSDOS_NAME_MAX); @@ -253,9 +263,8 @@ error: fat_file_close(parent_loc->mt_entry, fat_fd); err: - /* mark 32bytes structure on the disk as free */ - msdos_set_first_char4file_name(parent_loc->mt_entry, aux.cln, aux.ofs, - 0xE5); + /* mark the used 32bytes structure on the disk as free */ + msdos_set_first_char4file_name(parent_loc->mt_entry, &dir_pos, 0xE5); return rc; } @@ -287,21 +296,21 @@ err: */ int msdos_file_link(rtems_filesystem_location_info_t *to_loc, - rtems_filesystem_location_info_t *par_loc, - const char *token + rtems_filesystem_location_info_t *par_loc, + const char *name ) { int rc = RC_OK; rtems_status_code sc = RTEMS_SUCCESSFUL; msdos_fs_info_t *fs_info = to_loc->mt_entry->fs_info; fat_file_fd_t *to_fat_fd = to_loc->node_access; - char new_name[ MSDOS_NAME_MAX + 1 ]; + const char *token; int len; /* * check spelling and format new node name */ - if (MSDOS_NAME != msdos_get_token(token, new_name, &len)) { + if (MSDOS_NAME != msdos_get_token(name, &token, &len)) { rtems_set_errno_and_return_minus_one(ENAMETOOLONG); } /* @@ -324,8 +333,8 @@ msdos_file_link(rtems_filesystem_location_info_t *to_loc, * create new directory entry as "hard link", * copying relevant info from existing file */ - rc = msdos_creat_node(par_loc,MSDOS_HARD_LINK,new_name,S_IFREG, - to_loc->node_access); + rc = msdos_creat_node(par_loc,MSDOS_HARD_LINK,name,len,S_IFREG, + to_loc->node_access); /* * set file size and first cluster number of old entry to 0 */ |