From 8ec7abb551a23bdf47509189145885a364810006 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Thu, 4 Mar 2010 06:36:51 +0000 Subject: 010-03-04 Chris Johns * libcsupport/include/rtems/libio.h, libcsupport/src/_rename_r.c: Add a rename file op and have rename use it. * libfs/Makefile.am, libfs/src/dosfs/msdos_rename.c, libfs/src/imfs/imfs_rename.c: New files to support the rename file op. * libfs/src/imfs/imfs.h: Add rename interface. * libfs/src/imfs/imfs_init.c: Add rename handler. * libfs/src/imfs/miniimfs_init.c: Fix up ops struct. * libfs/src/dosfs/msdos.h: Add msdos_rename and remove msdos_file_link. * libfs/src/dosfs/msdos_create.c: Remove the link call. * libfs/src/dosfs/msdos_eval.c: Fix a path parsing bug. * libfs/src/dosfs/msdos_init.c: Add rename handler and clean up the struct naming. * libfs/src/rfs/rtems-rfs-link.c, libfs/src/rfs/rtems-rfs-link.h: Change the link call to allow linking of directories if told to and change the unlink to handle unlink directories that are not empty so rename can be supported. * libfs/src/rfs/rtems-rfs-rtems-dir.c: Fix the link/unlink calls. * libfs/src/rfs/rtems-rfs-rtems.c: Add a rename handler. Fix the link/unlink calls. * libfs/src/dosfs/msdos_dir.c, libfs/src/dosfs/msdos_format.c, libfs/src/dosfs/msdos_misc.c, httpd/asp.c, libfs/src/nfsclient/src/nfs.c: Work around a newlib warning when using the is*() family of calls. --- cpukit/libfs/src/dosfs/msdos.h | 11 ++--- cpukit/libfs/src/dosfs/msdos_create.c | 85 -------------------------------- cpukit/libfs/src/dosfs/msdos_dir.c | 4 +- cpukit/libfs/src/dosfs/msdos_eval.c | 4 +- cpukit/libfs/src/dosfs/msdos_format.c | 4 +- cpukit/libfs/src/dosfs/msdos_init.c | 39 +++++++-------- cpukit/libfs/src/dosfs/msdos_misc.c | 2 +- cpukit/libfs/src/dosfs/msdos_rename.c | 93 +++++++++++++++++++++++++++++++++++ 8 files changed, 123 insertions(+), 119 deletions(-) create mode 100644 cpukit/libfs/src/dosfs/msdos_rename.c (limited to 'cpukit/libfs/src/dosfs') diff --git a/cpukit/libfs/src/dosfs/msdos.h b/cpukit/libfs/src/dosfs/msdos.h index 260c4d7919..acbea3161e 100644 --- a/cpukit/libfs/src/dosfs/msdos.h +++ b/cpukit/libfs/src/dosfs/msdos.h @@ -259,6 +259,11 @@ int msdos_utime( time_t modtime /* IN */ ); +int msdos_rename(rtems_filesystem_location_info_t *old_parent_loc, + rtems_filesystem_location_info_t *old_loc, + rtems_filesystem_location_info_t *new_parent_loc, + const char *new_name); + int msdos_initialize_support( rtems_filesystem_mount_table_entry_t *temp_mt_entry, const rtems_filesystem_operations_table *op_table, @@ -323,12 +328,6 @@ msdos_dir_chmod( int msdos_file_rmnod(rtems_filesystem_location_info_t *parent_pathloc, /* IN */ rtems_filesystem_location_info_t *pathloc /* IN */); -int msdos_file_link( - rtems_filesystem_location_info_t *to_loc, - rtems_filesystem_location_info_t *pa_loc, - const char *token -); - int msdos_dir_open( rtems_libio_t *iop, /* IN */ const char *pathname, /* IN */ diff --git a/cpukit/libfs/src/dosfs/msdos_create.c b/cpukit/libfs/src/dosfs/msdos_create.c index a9d8dbaac3..bab4a63fa8 100644 --- a/cpukit/libfs/src/dosfs/msdos_create.c +++ b/cpukit/libfs/src/dosfs/msdos_create.c @@ -267,88 +267,3 @@ err: msdos_set_first_char4file_name(parent_loc->mt_entry, &dir_pos, 0xE5); return rc; } - -/* msdos_file_link -- - * Replacement for a file "link" operation. - * MSDOS FAT FS does not support links, but this call is needed to - * allow "rename" operations. The current NEWLIB rename performs a link - * from the old to the new name and then deletes the old filename. - * - * This pseudo-"link" operation will create a new directory entry, - * copy the file size and cluster information from the "old" - * to the "new" directory entry and then clear the file size and cluster - * info from the "old" filename, leaving this file as - * a valid, but empty entry. - * - * When this "link" call is part of a "rename" sequence, the "old" - * entry will be deleted in a subsequent "rmnod" call - * - * This function has been implemented by Thomas Doerfler, - * - * - * PARAMETERS: - * to_loc - node description for "existing" node - * par_loc - node description for "new" node - * token - name of new node - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set appropriately) - */ -int -msdos_file_link(rtems_filesystem_location_info_t *to_loc, - 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; - const char *token; - int len; - - /* - * check spelling and format new node name - */ - if (MSDOS_NAME != msdos_get_token(name, strlen(name), &token, &len)) { - rtems_set_errno_and_return_minus_one(ENAMETOOLONG); - } - /* - * verify, that the existing node can be linked to - * check that nodes are in same FS/volume? - */ - if (to_loc->mt_entry->fs_info != par_loc->mt_entry->fs_info) { - rtems_set_errno_and_return_minus_one(EXDEV); - } - /* - * lock volume - */ - 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); - - - /* - * create new directory entry as "hard link", - * copying relevant info from existing file - */ - 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 - */ - if (rc == RC_OK) { - to_fat_fd->fat_file_size = 0; - to_fat_fd->cln = FAT_EOF; - rc = msdos_set_first_cluster_num(to_loc->mt_entry, to_fat_fd); - if (rc == RC_OK) { - rc = msdos_set_file_size(par_loc->mt_entry, to_fat_fd); - } - } - /* - * FIXME: check error/abort handling - */ - rtems_semaphore_release(fs_info->vol_sema); - return rc; -} diff --git a/cpukit/libfs/src/dosfs/msdos_dir.c b/cpukit/libfs/src/dosfs/msdos_dir.c index 6fa3ddecf1..1bb5c73024 100644 --- a/cpukit/libfs/src/dosfs/msdos_dir.c +++ b/cpukit/libfs/src/dosfs/msdos_dir.c @@ -146,7 +146,7 @@ msdos_format_dirent_with_dot(char *dst,const char *src) src_tmp = src; len = i; while (i-- > 0) { - *dst++ = tolower(*src_tmp++); + *dst++ = tolower((int)(*src_tmp++)); } /* * find last non-blank character of extension @@ -165,7 +165,7 @@ msdos_format_dirent_with_dot(char *dst,const char *src) len += i + 1; /* extension + dot */ src_tmp = src + MSDOS_SHORT_BASE_LEN; while (i-- > 0) { - *dst++ = tolower(*src_tmp++); + *dst++ = tolower((int)(*src_tmp++)); len++; } } diff --git a/cpukit/libfs/src/dosfs/msdos_eval.c b/cpukit/libfs/src/dosfs/msdos_eval.c index a97c245ed0..b216af4d18 100644 --- a/cpukit/libfs/src/dosfs/msdos_eval.c +++ b/cpukit/libfs/src/dosfs/msdos_eval.c @@ -108,7 +108,7 @@ msdos_eval_path( while ((type != MSDOS_NO_MORE_PATH) && (type != MSDOS_INVALID_TOKEN)) { type = msdos_get_token(&pathname[i], pathnamelen, &token, &token_len); - pathnamelen += token_len; + pathnamelen -= token_len; i += token_len; fat_fd = pathloc->node_access; @@ -152,7 +152,7 @@ msdos_eval_path( rtems_semaphore_release(fs_info->vol_sema); return (*pathloc->ops->evalpath_h)(&(pathname[i-token_len]), - pathnamelen - token_len, + pathnamelen + token_len, flags, pathloc); } } diff --git a/cpukit/libfs/src/dosfs/msdos_format.c b/cpukit/libfs/src/dosfs/msdos_format.c index d424c54aa6..d2ec19b267 100644 --- a/cpukit/libfs/src/dosfs/msdos_format.c +++ b/cpukit/libfs/src/dosfs/msdos_format.c @@ -648,7 +648,7 @@ static int msdos_format_determine_fmt_params for (cnt = 0; cnt < (sizeof(fmt_params->OEMName)-1); cnt++) { - if (isprint(*from)) { + if (isprint((int)*from)) { *to++ = *from++; } else { @@ -679,7 +679,7 @@ static int msdos_format_determine_fmt_params for (cnt = 0; cnt < (sizeof(fmt_params->VolLabel)-1); cnt++) { - if (isprint(*from)) { + if (isprint((int)*from)) { *to++ = *from++; } else { diff --git a/cpukit/libfs/src/dosfs/msdos_init.c b/cpukit/libfs/src/dosfs/msdos_init.c index 89a3dac274..1e17bf9545 100644 --- a/cpukit/libfs/src/dosfs/msdos_init.c +++ b/cpukit/libfs/src/dosfs/msdos_init.c @@ -19,27 +19,24 @@ #include "msdos.h" const rtems_filesystem_operations_table msdos_ops = { - msdos_eval_path, - msdos_eval4make, -#if 0 - NULL, /* msdos_link */ -#else - msdos_file_link, /* msdos_link (pseudo-functionality) */ -#endif - msdos_file_rmnod, - msdos_node_type, - msdos_mknod, - NULL, /* msdos_chown */ - msdos_free_node_info, - NULL, - msdos_initialize, - NULL, - msdos_shut_down, /* msdos_shut_down */ - NULL, /* msdos_utime */ - NULL, - NULL, - NULL, - NULL + .evalpath_h = msdos_eval_path, + .evalformake_h = msdos_eval4make, + .link_h = NULL, + .unlink_h = msdos_file_rmnod, + .node_type_h = msdos_node_type, + .mknod_h = msdos_mknod, + .chown_h = NULL, + .freenod_h = msdos_free_node_info, + .mount_h = NULL, + .fsmount_me_h = msdos_initialize, + .unmount_h = NULL, + .fsunmount_me_h = msdos_shut_down, + .utime_h = NULL, + .eval_link_h = NULL, + .symlink_h = NULL, + .readlink_h = NULL, + .rename_h = msdos_rename, + .statvfs_h = NULL }; /* msdos_initialize -- diff --git a/cpukit/libfs/src/dosfs/msdos_misc.c b/cpukit/libfs/src/dosfs/msdos_misc.c index 003d2f57f4..4ab8e22b32 100644 --- a/cpukit/libfs/src/dosfs/msdos_misc.c +++ b/cpukit/libfs/src/dosfs/msdos_misc.c @@ -65,7 +65,7 @@ msdos_is_valid_name_char(const char ch) if (strchr(" +,;=[]", ch) != NULL) return MSDOS_NAME_LONG; - if ((ch == '.') || isalnum(ch) || + if ((ch == '.') || isalnum((int)ch) || (strchr("$%'-_@~`!(){}^#&", ch) != NULL)) return MSDOS_NAME_SHORT; diff --git a/cpukit/libfs/src/dosfs/msdos_rename.c b/cpukit/libfs/src/dosfs/msdos_rename.c new file mode 100644 index 0000000000..1ad625a251 --- /dev/null +++ b/cpukit/libfs/src/dosfs/msdos_rename.c @@ -0,0 +1,93 @@ +/* + * Routine to rename a MSDOS filesystem node + * + * Copyright (C) 2010 Chris Johns + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * @(#) $Id$ + * + */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "fat.h" +#include "fat_fat_operations.h" +#include "fat_file.h" + +#include "msdos.h" + +/* msdos_rename -- + * Rename the node by removing the exitsing directory entry and creating a + * new one. + * + * PARAMETERS: + * old_parent_loc - node description for the "old parent" node + * old_loc - node description for the "old" node + * new_parent_loc - node description for the "parent" node + * name - name of new node + * + * RETURNS: + * RC_OK on success, or -1 if error occured (errno set appropriately) + */ +int +msdos_rename(rtems_filesystem_location_info_t *old_parent_loc, + rtems_filesystem_location_info_t *old_loc, + rtems_filesystem_location_info_t *new_parent_loc, + const char *new_name) +{ + int rc = RC_OK; + rtems_status_code sc = RTEMS_SUCCESSFUL; + msdos_fs_info_t *fs_info = new_parent_loc->mt_entry->fs_info; + fat_file_fd_t *old_fat_fd = old_loc->node_access; + const char *token; + int len; + + /* + * check spelling and format new node name + */ + if (MSDOS_NAME != msdos_get_token(new_name, strlen(new_name), &token, &len)) { + rtems_set_errno_and_return_minus_one(ENAMETOOLONG); + } + /* + * lock volume + */ + 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); + + /* + * create new directory entry as "hard link", copying relevant info from + * existing file + */ + rc = msdos_creat_node(new_parent_loc, + MSDOS_HARD_LINK,new_name,len,S_IFREG, + old_fat_fd); + if (rc != RC_OK) + { + rtems_semaphore_release(fs_info->vol_sema); + return rc; + } + + /* + * mark file removed + */ + rc = msdos_set_first_char4file_name(old_loc->mt_entry, + &old_fat_fd->dir_pos, + MSDOS_THIS_DIR_ENTRY_EMPTY); + + rtems_semaphore_release(fs_info->vol_sema); + return rc; +} -- cgit v1.2.3