示例#1
0
/*
 * IMFS_skip_separator
 *
 * Skip the separator in the path.
 */
static void IMFS_skip_separator (
   const char *path,       /* IN     */
   size_t     *len,        /* IN/OUT */
   int        *index       /* IN/OUT */
)
{
  while ( IMFS_is_separator( path[*index] ) && path[*index] && *len ) {
    ++(*index);
    --(*len);
  }
}
示例#2
0
int IMFS_evaluate_for_make(
  const char                         *path,       /* IN     */
  rtems_filesystem_location_info_t   *pathloc,    /* IN/OUT */
  const char                        **name        /* OUT    */
                           )
{
  int               i = 0;
  int               len;
  IMFS_token_types  type;
  char              token[ IMFS_NAME_MAX + 1 ];
  IMFS_jnode_t     *node;
  bool              done = false;
  size_t            pathlen;
  int               result;

  /*
   * This was filled in by the caller and is valid in the
   * mount table.
   */
  node = pathloc->node_access;

  /*
   * Get the path length.
   */
  pathlen = strlen( path );

  /*
   *  Evaluate all tokens until we are done or an error occurs.
   */

  while( !done ) {

    type = IMFS_get_token( &path[i], pathlen, token, &len );
    pathlen -= len;
    i +=  len;

    if ( !pathloc->node_access )
      rtems_set_errno_and_return_minus_one( ENOENT );

    /*
     * I cannot move out of this directory without execute permission.
     */

    if ( type != IMFS_NO_MORE_PATH )
      if ( node->type == IMFS_DIRECTORY )
        if ( !IMFS_evaluate_permission( pathloc, RTEMS_LIBIO_PERMS_SEARCH ) )
           rtems_set_errno_and_return_minus_one( EACCES );

    node = pathloc->node_access;

    switch( type ) {

      case IMFS_UP_DIR:
       /*
        *  Am I at the root of all filesystems? (chroot'ed?)
        */

       if ( pathloc->node_access == rtems_filesystem_root.node_access )
         break;       /* Throw out the .. in this case */


       /*
        * Am I at the root of this mounted filesystem?
        */

        if (pathloc->node_access == pathloc->mt_entry->mt_fs_root.node_access){

          /*
           *  Am I at the root of all filesystems?
           */

          if ( pathloc->node_access == rtems_filesystem_root.node_access ) {
            break;

          } else {
            *pathloc = pathloc->mt_entry->mt_point_node;
            return (*pathloc->ops->evalformake_h)( &path[i-len], pathloc, name );
          }
        } else {
          if ( !node->Parent )
            rtems_set_errno_and_return_minus_one( ENOENT );

          node = node->Parent;
        }

        pathloc->node_access = node;
        break;

      case IMFS_NAME:
        /*
         *  If we are at a link follow it.
         */

        if ( node->type == IMFS_HARD_LINK ) {

          result = IMFS_evaluate_link( pathloc, 0 );
          if ( result == -1 )
            return -1;

        } else if ( node->type == IMFS_SYM_LINK ) {

          result = IMFS_evaluate_link( pathloc, 0 );

          if ( result == -1 )
            return -1;
        }

        node = pathloc->node_access;
        if ( !node )
          rtems_set_errno_and_return_minus_one( ENOTDIR );

        /*
         * Only a directory can be decended into.
         */

        if ( node->type != IMFS_DIRECTORY )
          rtems_set_errno_and_return_minus_one( ENOTDIR );

        /*
         * Find the token name in the present location.
         */

        node = IMFS_find_match_in_dir( node, token );

        /*
         * If there is no node we have found the name of the node we
         * wish to create.
         */

        if ( ! node )
          done = true;
        else {
        if (( node->type == IMFS_DIRECTORY ) && ( node->info.directory.mt_fs != NULL )) {
            IMFS_skip_separator( path, &pathlen, &i);
            if ((path[i] != '.') || (path[i + 1] != '.')) {
              *pathloc = node->info.directory.mt_fs->mt_fs_root;
              return (*pathloc->ops->evalformake_h)( &path[i],
                                                     pathloc,
                                                     name );
            }
            i += 2;
            pathlen -= 2;
            node = node->Parent;
          }
          
          pathloc->node_access = node;
        }
        break;

      case IMFS_NO_MORE_PATH:
        rtems_set_errno_and_return_minus_one( EEXIST );
        break;

      case IMFS_INVALID_TOKEN:
        rtems_set_errno_and_return_minus_one( ENAMETOOLONG );
        break;

      case IMFS_CURRENT_DIR:
        break;
    }
  }

  *name = &path[ i - len ];

  /*
   * We have evaluated the path as far as we can.
   * Verify there is not any invalid stuff at the end of the name.
   */

  for( ; path[i] != '\0'; i++) {
    if ( !IMFS_is_separator( path[ i ] ) )
      rtems_set_errno_and_return_minus_one( ENOENT );
  }

  /*
   * Verify we can execute and write to this directory.
   */

  result = IMFS_Set_handlers( pathloc );

  /*
   * The returned node must be a directory
   */
  node = pathloc->node_access;
  if ( node->type != IMFS_DIRECTORY )
    rtems_set_errno_and_return_minus_one( ENOTDIR );

  /*
   * We must have Write and execute permission on the returned node.
   */

  if ( !IMFS_evaluate_permission( pathloc, RTEMS_LIBIO_PERMS_WX ) )
    rtems_set_errno_and_return_minus_one( EACCES );

  return result;
}
IMFS_token_types IMFS_get_token(
  const char       *path,
  int               pathlen,
  char             *token,
  int              *token_len
)
{
  register int i = 0;
  IMFS_token_types  type = IMFS_NAME;
  register char c;

  /*
   *  Copy a name into token.  (Remember NULL is a token.)
   */
  c = path[i];
  while ( (!IMFS_is_separator(c)) && (i < pathlen) && (i <= IMFS_NAME_MAX) ) {

     token[i] = c;

     if ( i == IMFS_NAME_MAX )
       return IMFS_INVALID_TOKEN;

     if ( !IMFS_is_valid_name_char(c) )
       type = IMFS_INVALID_TOKEN;

     c = path [++i];
  }

  /*
   *  Copy a seperator into token.
   */

  if ( i == 0 ) {
    token[i] = c;

    if ( (token[i] != '\0') && pathlen ) {
      i++;
      type = IMFS_CURRENT_DIR;
    } else {
      type = IMFS_NO_MORE_PATH;
    }
  } else if (token[ i-1 ] != '\0') {
    token[i] = '\0';
  }

  /*
   *  Set token_len to the number of characters copied.
   */

  *token_len = i;

  /*
   *  If we copied something that was not a seperator see if
   *  it was a special name.
   */

  if ( type == IMFS_NAME ) {
    if ( strcmp( token, "..") == 0 )
      type = IMFS_UP_DIR;
    else if ( strcmp( token, "." ) == 0 )
      type = IMFS_CURRENT_DIR;
  }

  return type;
}