Пример #1
0
int link( const char *path1, const char *path2 )
{
  int rv = 0;
  rtems_filesystem_eval_path_context_t ctx_1;
  rtems_filesystem_eval_path_context_t ctx_2;
  int eval_flags_1 = RTEMS_FS_FOLLOW_LINK;
  int eval_flags_2 = RTEMS_FS_FOLLOW_LINK
    | RTEMS_FS_MAKE
    | RTEMS_FS_EXCLUSIVE;
  const rtems_filesystem_location_info_t *currentloc_1 =
    rtems_filesystem_eval_path_start( &ctx_1, path1, eval_flags_1 );
  const rtems_filesystem_location_info_t *currentloc_2 =
    rtems_filesystem_eval_path_start( &ctx_2, path2, eval_flags_2 );

  rv = rtems_filesystem_location_exists_in_same_fs_instance_as(
    currentloc_1,
    currentloc_2
  );
  if ( rv == 0 ) {
    rv = (*currentloc_2->ops->link_h)(
      currentloc_2,
      currentloc_1,
      rtems_filesystem_eval_path_get_token( &ctx_2 ),
      rtems_filesystem_eval_path_get_tokenlen( &ctx_2 )
    );
  }

  rtems_filesystem_eval_path_cleanup( &ctx_1 );
  rtems_filesystem_eval_path_cleanup( &ctx_2 );

  return rv;
}
Пример #2
0
/**
 *  POSIX 1003.1b 5.5.6 - Set File Access and Modification Times
 */
int utime( const char *path, const struct utimbuf *times )
{
  int rv = 0;
  rtems_filesystem_eval_path_context_t ctx;
  int eval_flags = RTEMS_FS_FOLLOW_LINK;
  const rtems_filesystem_location_info_t *currentloc =
    rtems_filesystem_eval_path_start( &ctx, path, eval_flags );
  struct utimbuf now_times;

  if ( times == NULL ) {
    time_t now = time( NULL );

    now_times.actime = now;
    now_times.modtime = now;

    times = &now_times;
  }

  rv = (*currentloc->mt_entry->ops->utime_h)(
    currentloc,
    times->actime,
    times->modtime
  );

  rtems_filesystem_eval_path_cleanup( &ctx );

  return rv;
}
Пример #3
0
void rtems_filesystem_eval_path_cleanup_with_parent(
  rtems_filesystem_eval_path_context_t *ctx,
  rtems_filesystem_location_info_t *parentloc
)
{
  free_location(parentloc);
  rtems_filesystem_eval_path_cleanup(ctx);
}
Пример #4
0
int unmount( const char *path )
{
  int rv = 0;
  rtems_filesystem_eval_path_context_t ctx;
  int eval_flags = RTEMS_FS_FOLLOW_LINK;
  const rtems_filesystem_location_info_t *currentloc =
    rtems_filesystem_eval_path_start( &ctx, path, eval_flags );
  rtems_filesystem_mount_table_entry_t *mt_entry = currentloc->mt_entry;

  if ( rtems_filesystem_location_is_root( currentloc ) ) {
    if ( !contains_root_or_current_directory( mt_entry ) ) {
      const rtems_filesystem_operations_table *mt_point_ops =
        mt_entry->mt_point_node->location.mt_entry->ops;

      rv = (*mt_point_ops->unmount_h)( mt_entry );
      if ( rv == 0 ) {
        rtems_id self_task_id = rtems_task_self();
        rtems_filesystem_mt_entry_declare_lock_context( lock_context );

        rtems_filesystem_mt_entry_lock( lock_context );
        mt_entry->unmount_task = self_task_id;
        mt_entry->mounted = false;
        rtems_filesystem_mt_entry_unlock( lock_context );
      }
    } else {
      errno = EBUSY;
      rv = -1;
    }
  } else {
    errno = EACCES;
    rv = -1;
  }

  rtems_filesystem_eval_path_cleanup( &ctx );

  if ( rv == 0 ) {
    rtems_event_set out;
    rtems_status_code sc = rtems_event_receive(
      RTEMS_FILESYSTEM_UNMOUNT_EVENT,
      RTEMS_EVENT_ALL | RTEMS_WAIT,
      RTEMS_NO_TIMEOUT,
      &out
    );

    if ( sc != RTEMS_SUCCESSFUL ) {
      rtems_fatal_error_occurred( 0xdeadbeef );
    }
  }

  return rv;
}
Пример #5
0
int lchown( const char *path, uid_t owner, gid_t group )
{
  int rv;
  rtems_filesystem_eval_path_context_t ctx;
  int eval_flags = RTEMS_FS_FOLLOW_HARD_LINK;
  const rtems_filesystem_location_info_t *currentloc =
    rtems_filesystem_eval_path_start( &ctx, path, eval_flags );

  rv = rtems_filesystem_chown( currentloc, owner, group );

  rtems_filesystem_eval_path_cleanup( &ctx );

  return rv;
}
Пример #6
0
/**
 *  POSIX 1003.1b 5.6.4 - Change File Modes
 */
int chmod( const char *path, mode_t mode )
{
  int rv = 0;
  rtems_filesystem_eval_path_context_t ctx;
  int eval_flags = RTEMS_FS_FOLLOW_LINK;
  const rtems_filesystem_location_info_t *currentloc =
    rtems_filesystem_eval_path_start( &ctx, path, eval_flags );

  rv = rtems_filesystem_chmod( currentloc, mode );

  rtems_filesystem_eval_path_cleanup( &ctx );

  return rv;
}
Пример #7
0
int chdir( const char *path )
{
  int rv = 0;
  rtems_filesystem_eval_path_context_t ctx;
  int eval_flags = RTEMS_FS_PERMS_EXEC
    | RTEMS_FS_FOLLOW_LINK;
  rtems_filesystem_location_info_t pathloc;

  rtems_filesystem_eval_path_start( &ctx, path, eval_flags );
  rtems_filesystem_eval_path_extract_currentloc( &ctx, &pathloc );
  rv = rtems_filesystem_chdir( &pathloc );
  rtems_filesystem_eval_path_cleanup( &ctx );

  return rv;
}
Пример #8
0
int statvfs( const char *path, struct statvfs *buf )
{
  int rv = 0;
  rtems_filesystem_eval_path_context_t ctx;
  int eval_flags = RTEMS_FS_FOLLOW_LINK;
  const rtems_filesystem_location_info_t *currentloc =
    rtems_filesystem_eval_path_start( &ctx, path, eval_flags );

  memset( buf, 0, sizeof( *buf ) );

  rv = (*currentloc->ops->statvfs_h)( currentloc, buf );

  rtems_filesystem_eval_path_cleanup( &ctx );

  return rv;
}
Пример #9
0
ssize_t readlink( const char *path, char *buf, size_t bufsize )
{
  ssize_t rv = 0;
  rtems_filesystem_eval_path_context_t ctx;
  int eval_flags = RTEMS_FS_FOLLOW_HARD_LINK;
  const rtems_filesystem_location_info_t *currentloc =
    rtems_filesystem_eval_path_start( &ctx, path, eval_flags );
  const rtems_filesystem_operations_table *ops = currentloc->mt_entry->ops;
  rtems_filesystem_node_types_t type = (*ops->node_type_h)( currentloc );

  if ( type == RTEMS_FILESYSTEM_SYM_LINK ) {
    rv = (*ops->readlink_h)( currentloc, buf, bufsize );
  } else {
    rtems_filesystem_eval_path_error( &ctx, EINVAL );
    rv = -1;
  }

  rtems_filesystem_eval_path_cleanup( &ctx );

  return rv;
}
Пример #10
0
static int register_subordinate_file_system(
  rtems_filesystem_mount_table_entry_t *mt_entry,
  const char *target
)
{
  int rv = 0;
  rtems_filesystem_eval_path_context_t ctx;
  int eval_flags = RTEMS_FS_PERMS_RWX
    | RTEMS_FS_FOLLOW_LINK;
  rtems_filesystem_location_info_t *currentloc =
    rtems_filesystem_eval_path_start( &ctx, target, eval_flags );

  if ( !rtems_filesystem_location_is_instance_root( currentloc ) ) {
    rtems_filesystem_location_info_t targetloc;
    rtems_filesystem_global_location_t *mt_point_node;

    rtems_filesystem_eval_path_extract_currentloc( &ctx, &targetloc );
    mt_point_node = rtems_filesystem_location_transform_to_global( &targetloc );
    mt_entry->mt_point_node = mt_point_node;
    rv = (*mt_point_node->location.mt_entry->ops->mount_h)( mt_entry );
    if ( rv == 0 ) {
      rtems_filesystem_mt_lock();
      rtems_chain_append_unprotected(
        &rtems_filesystem_mount_table,
        &mt_entry->mt_node
      );
      rtems_filesystem_mt_unlock();
    } else {
      rtems_filesystem_global_location_release( mt_point_node );
    }
  } else {
    rtems_filesystem_eval_path_error( &ctx, EBUSY );
    rv = -1;
  }

  rtems_filesystem_eval_path_cleanup( &ctx );

  return rv;
}
Пример #11
0
int rtems_filesystem_chown(
  const char *path,
  uid_t owner,
  gid_t group,
  int eval_follow_link
)
{
  int rv = 0;
  rtems_filesystem_eval_path_context_t ctx;
  int eval_flags = eval_follow_link;
  const rtems_filesystem_location_info_t *currentloc =
    rtems_filesystem_eval_path_start( &ctx, path, eval_flags );

  rv = (*currentloc->ops->chown_h)(
    currentloc,
    owner,
    group
  );

  rtems_filesystem_eval_path_cleanup( &ctx );

  return rv;
}
Пример #12
0
/**
 * Get the file system data from the specific path. Checks to make sure the path is
 * pointing to a valid RFS file system.
 */
static int
rtems_rfs_get_fs (const char* path, rtems_rfs_file_system** fs)
{
  struct statvfs sb;
  int            rc;

  rc = statvfs (path, &sb);
  if (rc < 0)
  {
    printf ("error: cannot statvfs path: %s: (%d) %s\n",
            path, errno, strerror (errno));
    return -1;
  }

  if (sb.f_fsid != RTEMS_RFS_SB_MAGIC)
  {
    printf ("error: path '%s' is not on an RFS file system\n", path);
    return -1;
  }

#if __rtems__
  /*
   * Now find the path location on the file system. This will give the file
   * system data.
   */
  {
    rtems_filesystem_eval_path_context_t ctx;
    int eval_flags = RTEMS_FS_FOLLOW_LINK;
    const rtems_filesystem_location_info_t *currentloc =
      rtems_filesystem_eval_path_start (&ctx, path, eval_flags);
    *fs = rtems_rfs_rtems_pathloc_dev (currentloc);
    rtems_filesystem_eval_path_cleanup (&ctx);
  }
#endif

  return rc;
}
Пример #13
0
Файл: open.c Проект: AoLaD/rtems
static int do_open(
  rtems_libio_t *iop,
  const char *path,
  int oflag,
  mode_t mode
)
{
  int rv = 0;
  int fd = rtems_libio_iop_to_descriptor( iop );
  int rwflag = oflag + 1;
  bool read_access = (rwflag & _FREAD) == _FREAD;
  bool write_access = (rwflag & _FWRITE) == _FWRITE;
  bool make = (oflag & O_CREAT) == O_CREAT;
  bool exclusive = (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
  bool truncate = (oflag & O_TRUNC) == O_TRUNC;
  int eval_flags = RTEMS_FS_FOLLOW_LINK
    | (read_access ? RTEMS_FS_PERMS_READ : 0)
    | (write_access ? RTEMS_FS_PERMS_WRITE : 0)
    | (make ? RTEMS_FS_MAKE : 0)
    | (exclusive ?  RTEMS_FS_EXCLUSIVE : 0);
  rtems_filesystem_eval_path_context_t ctx;

  rtems_filesystem_eval_path_start( &ctx, path, eval_flags );

  if ( rtems_filesystem_eval_path_has_token( &ctx ) ) {
    create_regular_file( &ctx, mode );
  }

  if ( write_access ) {
    const rtems_filesystem_location_info_t *currentloc =
      rtems_filesystem_eval_path_get_currentloc( &ctx );
    mode_t type = rtems_filesystem_location_type( currentloc );

    if ( S_ISDIR( type ) ) {
      rtems_filesystem_eval_path_error( &ctx, EISDIR );
    }
  }

  iop->flags |= rtems_libio_fcntl_flags( oflag );
  rtems_filesystem_eval_path_extract_currentloc( &ctx, &iop->pathinfo );
  rtems_filesystem_eval_path_cleanup( &ctx );

  rv = (*iop->pathinfo.handlers->open_h)( iop, path, oflag, mode );

  if ( rv == 0 ) {
    if ( truncate ) {
      rv = ftruncate( fd, 0 );
      if ( rv != 0 ) {
        (*iop->pathinfo.handlers->close_h)( iop );
      }
    }

    if ( rv == 0 ) {
      rv = fd;
    } else {
      rv = -1;
    }
  }

  if ( rv < 0 ) {
    rtems_libio_free( iop );
  }

  return rv;
}
Пример #14
0
int IMFS_make_generic_node(
  const char *path,
  mode_t mode,
  const IMFS_node_control *node_control,
  void *context
)
{
  int rv = 0;

  mode &= ~rtems_filesystem_umask;

  switch (mode & S_IFMT) {
    case S_IFBLK:
    case S_IFCHR:
    case S_IFIFO:
    case S_IFREG:
      break;
    default:
      errno = EINVAL;
      rv = -1;
      break;
  }
  
  if ( rv == 0 ) {
    if ( node_control->imfs_type == IMFS_GENERIC ) {
      rtems_filesystem_eval_path_context_t ctx;
      int eval_flags = RTEMS_FS_FOLLOW_LINK
        | RTEMS_FS_MAKE
        | RTEMS_FS_EXCLUSIVE;
      const rtems_filesystem_location_info_t *currentloc =
        rtems_filesystem_eval_path_start( &ctx, path, eval_flags );

      if ( IMFS_is_imfs_instance( currentloc ) ) {
        IMFS_types_union info;
        IMFS_jnode_t *new_node;

        info.generic.context = context;
        new_node = IMFS_create_node_with_control(
          currentloc,
          node_control,
          rtems_filesystem_eval_path_get_token( &ctx ),
          rtems_filesystem_eval_path_get_tokenlen( &ctx ),
          mode,
          &info
        );

        if ( new_node != NULL ) {
          IMFS_jnode_t *parent = currentloc->node_access;

          IMFS_update_ctime( parent );
          IMFS_update_mtime( parent );
        } else {
          rv = -1;
        }
      } else {
        rtems_filesystem_eval_path_error( &ctx, ENOTSUP );
        rv = -1;
      }

      rtems_filesystem_eval_path_cleanup( &ctx );
    } else {
      errno = EINVAL;
      rv = -1;
    }
  }

  return rv;
}
Пример #15
0
int chroot( const char *path )
{
  int rv = 0;
  rtems_status_code sc = RTEMS_SUCCESSFUL;
  rtems_filesystem_eval_path_context_t ctx;
  int eval_flags = RTEMS_FS_PERMS_EXEC
    | RTEMS_FS_FOLLOW_LINK;
  rtems_filesystem_location_info_t loc;
  rtems_filesystem_global_location_t *new_current_loc;

  /*
   * We use the global environment for path evaluation.  This makes it possible
   * to escape from a chroot environment referencing an unmounted file system.
   */
  rtems_filesystem_eval_path_start_with_root_and_current(
    &ctx,
    path,
    eval_flags,
    &rtems_global_user_env.root_directory,
    &rtems_global_user_env.current_directory
  );

  rtems_filesystem_eval_path_extract_currentloc( &ctx, &loc );
  new_current_loc = rtems_filesystem_location_transform_to_global( &loc );
  if ( !rtems_filesystem_global_location_is_null( new_current_loc ) ) {
    rtems_filesystem_global_location_t *new_root_loc =
      rtems_filesystem_global_location_obtain( &new_current_loc );
    rtems_filesystem_node_types_t type =
      (*new_root_loc->location.mt_entry->ops->node_type_h)(
        &new_root_loc->location
      );

    if ( type == RTEMS_FILESYSTEM_DIRECTORY ) {
      sc = rtems_libio_set_private_env();
      if (sc == RTEMS_SUCCESSFUL) {
        rtems_filesystem_global_location_assign(
          &rtems_filesystem_root,
          new_root_loc
        );
        rtems_filesystem_global_location_assign(
          &rtems_filesystem_current,
          new_current_loc
        );
      } else {
        if (sc != RTEMS_UNSATISFIED) {
          errno = ENOMEM;
        }
        rv = -1;
      }
    } else {
      rtems_filesystem_location_error( &new_root_loc->location, ENOTDIR );
      rv = -1;
    }

    if ( rv != 0 ) {
      rtems_filesystem_global_location_release( new_root_loc );
    }
  } else {
    rv = -1;
  }

  rtems_filesystem_eval_path_cleanup( &ctx );

  if ( rv != 0 ) {
    rtems_filesystem_global_location_release( new_current_loc );
  }

  return rv;
}
Пример #16
0
int rtems_tarfs_load(
  const char *mountpoint,
  uint8_t *tar_image,
  size_t tar_size
)
{
   const char                       *hdr_ptr;
   char                             filename[100];
   char                             full_filename[256];
   int                              hdr_chksum;
   unsigned char                    linkflag;
   unsigned long                    file_size;
   unsigned long                    file_mode;
   int                              offset;
   unsigned long                    nblocks;
   int rv = 0;
   int eval_flags = RTEMS_FS_FOLLOW_LINK;
   rtems_filesystem_eval_path_context_t ctx;
   rtems_filesystem_location_info_t rootloc;
   rtems_filesystem_location_info_t *currentloc =
     rtems_filesystem_eval_path_start( &ctx, mountpoint, eval_flags );

   rtems_filesystem_eval_path_extract_currentloc( &ctx, &rootloc );
   rtems_filesystem_eval_path_set_flags(
     &ctx,
     RTEMS_FS_MAKE | RTEMS_FS_EXCLUSIVE
   );

   if ( !IMFS_is_imfs_instance( &rootloc ) ) {
     rv = -1;
   }

   /*
    * Create an IMFS node structure pointing to tar image memory.
    */
   offset = 0;
   while ( rv == 0 ) {
    if (offset + 512 > tar_size)
      break;

    /*
     * Read a header.
     */
    hdr_ptr = (char *) &tar_image[offset];
    offset += 512;
    if (strncmp(&hdr_ptr[257], "ustar", 5))
      break;

    strncpy(filename, hdr_ptr, MAX_NAME_FIELD_SIZE);
    filename[MAX_NAME_FIELD_SIZE] = '\0';

    linkflag   = hdr_ptr[156];
    file_mode  = _rtems_octal2ulong(&hdr_ptr[100], 8);
    file_size  = _rtems_octal2ulong(&hdr_ptr[124], 12);
    hdr_chksum = _rtems_octal2ulong(&hdr_ptr[148], 8);

    if (_rtems_tar_header_checksum(hdr_ptr) != hdr_chksum)
      break;

    /*
     * Generate an IMFS node depending on the file type.
     * - For directories, just create directories as usual.  IMFS
     *   will take care of the rest.
     * - For symbolic links, create as usual
     * - For files, create a file node with special tarfs properties.
     */
    if (linkflag == DIRTYPE) {
      int len;
      strncpy(full_filename, mountpoint, 255);
      if (full_filename[(len=strlen(full_filename))-1] != '/')
        strcat(full_filename, "/");
      ++len;
      strncat(full_filename, filename, 256-len-1);
      if ( mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO) != 0 ) {
        if (errno == EEXIST) {
          struct stat stat_buf;
          if ( stat(full_filename, &stat_buf) == 0 ) {
            if (  S_ISDIR(stat_buf.st_mode) ) {
              continue;
            } else {
              if ( unlink(full_filename) != -1 ) {
                if ( mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO) == 0 )
                  continue;
              }
            }
          }
        }
        rv = -1;
      }
    }

    /*
     * Create a LINEAR_FILE node
     */
    else if (linkflag == REGTYPE) {
      rtems_filesystem_location_free( currentloc );
      rtems_filesystem_location_clone( currentloc, &rootloc );
      rtems_filesystem_eval_path_set_path(
        &ctx,
        filename,
        strlen( filename )
      );
      rtems_filesystem_eval_path_continue( &ctx );

      if ( !rtems_filesystem_location_is_null( currentloc ) ) {
        IMFS_linearfile_t *linfile = (IMFS_linearfile_t *)
          IMFS_create_node(
            currentloc,
            &IMFS_node_control_linfile,
            sizeof( IMFS_file_t ),
            rtems_filesystem_eval_path_get_token( &ctx ),
            rtems_filesystem_eval_path_get_tokenlen( &ctx ),
            (file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG,
            NULL
          );

        if ( linfile != NULL ) {
          linfile->File.size = file_size;
          linfile->direct    = &tar_image[offset];
        }
      }

      nblocks = (((file_size) + 511) & ~511) / 512;
      offset += 512 * nblocks;
    }
    /*
     * Create a symbolic link
     */
    else if (linkflag == SYMTYPE) {
      const char *linkto = hdr_ptr + 157;
      int len;

      strncpy(full_filename, mountpoint, 255);
      if (full_filename[(len=strlen(full_filename))-1] != '/')
        strcat(full_filename, "/");
      ++len;
      strncat(full_filename, filename, 256-len-1);

      rv = symlink(linkto, full_filename);
    }
  }

  rtems_filesystem_location_free( &rootloc );
  rtems_filesystem_eval_path_cleanup( &ctx );

  return rv;
}
Пример #17
0
int rtems_tarfs_load(
  const char *mountpoint,
  uint8_t *tar_image,
  size_t tar_size
)
{
   const char                       *hdr_ptr;
   char                             filename[100];
   char                             full_filename[256];
   int                              hdr_chksum;
   unsigned char                    linkflag;
   unsigned long                    file_size;
   unsigned long                    file_mode;
   int                              offset;
   unsigned long                    nblocks;
   IMFS_jnode_t                    *node;
   int rv = 0;
   int eval_flags = RTEMS_FS_FOLLOW_LINK;
   rtems_filesystem_eval_path_context_t ctx;
   rtems_filesystem_location_info_t rootloc;
   rtems_filesystem_location_info_t *currentloc =
     rtems_filesystem_eval_path_start( &ctx, mountpoint, eval_flags );

   rtems_filesystem_eval_path_extract_currentloc( &ctx, &rootloc );
   rtems_filesystem_eval_path_set_flags(
     &ctx,
     RTEMS_FS_MAKE | RTEMS_FS_EXCLUSIVE
   );

   if (
     rootloc.mt_entry->ops != &IMFS_ops
       && rootloc.mt_entry->ops != &fifoIMFS_ops
   ) {
     rv = -1;
   }

   /*
    * Create an IMFS node structure pointing to tar image memory.
    */
   offset = 0;
   while ( rv == 0 ) {
    if (offset + 512 > tar_size)
      break;

    /*
     * Read a header.
     */
    hdr_ptr = (char *) &tar_image[offset];
    offset += 512;
    if (strncmp(&hdr_ptr[257], "ustar", 5))
      break;

    strncpy(filename, hdr_ptr, MAX_NAME_FIELD_SIZE);
    filename[MAX_NAME_FIELD_SIZE] = '\0';

    linkflag   = hdr_ptr[156];
    file_mode  = _rtems_octal2ulong(&hdr_ptr[100], 8);
    file_size  = _rtems_octal2ulong(&hdr_ptr[124], 12);
    hdr_chksum = _rtems_octal2ulong(&hdr_ptr[148], 8);

    if (_rtems_tar_header_checksum(hdr_ptr) != hdr_chksum)
      break;

    /*
     * Generate an IMFS node depending on the file type.
     * - For directories, just create directories as usual.  IMFS
     *   will take care of the rest.
     * - For files, create a file node with special tarfs properties.
     */
    if (linkflag == DIRTYPE) {
      strcpy(full_filename, mountpoint);
      if (full_filename[strlen(full_filename)-1] != '/')
        strcat(full_filename, "/");
      strcat(full_filename, filename);
      mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO);
    }
    /*
     * Create a LINEAR_FILE node
     */
    else if (linkflag == REGTYPE) {
      rtems_filesystem_location_free( currentloc );
      rtems_filesystem_location_clone( currentloc, &rootloc );
      rtems_filesystem_eval_path_set_path(
        &ctx,
        filename,
        strlen( filename )
      );
      rtems_filesystem_eval_path_continue( &ctx );

      if ( !rtems_filesystem_location_is_null( currentloc ) ) {
        node = IMFS_create_node(
          currentloc,
          IMFS_LINEAR_FILE,
          rtems_filesystem_eval_path_get_token( &ctx ),
          rtems_filesystem_eval_path_get_tokenlen( &ctx ),
          (file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG,
          NULL
        );
        node->info.linearfile.size   = file_size;
        node->info.linearfile.direct = &tar_image[offset];
      }

      nblocks = (((file_size) + 511) & ~511) / 512;
      offset += 512 * nblocks;
    }
  }

  rtems_filesystem_location_free( &rootloc );
  rtems_filesystem_eval_path_cleanup( &ctx );

  return rv;
}