int IMFS_mknod( const rtems_filesystem_location_info_t *parentloc, const char *name, size_t namelen, mode_t mode, dev_t dev ) { int rv = 0; IMFS_jnode_types_t type; IMFS_types_union info; IMFS_jnode_t *new_node; get_type_and_info_by_mode_and_dev( mode, dev, &type, &info ); new_node = IMFS_create_node( parentloc, type, name, namelen, mode, &info ); if ( new_node != NULL ) { IMFS_jnode_t *parent = parentloc->node_access; IMFS_mtime_ctime_update( parent ); } else { rv = -1; } return rv; }
int IMFS_symlink( rtems_filesystem_location_info_t *parent_loc, const char *link_name, const char *node_name ) { IMFS_types_union info; IMFS_jnode_t *new_node; char new_name[ IMFS_NAME_MAX + 1 ]; int i; /* * Remove any separators at the end of the string. */ IMFS_get_token( node_name, strlen( node_name ), new_name, &i ); /* * Duplicate link name */ info.sym_link.name = strdup(link_name); if (info.sym_link.name == NULL) { rtems_set_errno_and_return_minus_one(ENOMEM); } /* * Create a new link node. * * NOTE: Coverity CID 22 notes this as a resource leak. * While technically not a leak, it indicated that IMFS_create_node * was ONLY passed a NULL when we created the root node. We * added a new IMFS_create_root_node() so this path no longer * existed. The result was simpler code which should not have * this path. */ new_node = IMFS_create_node( parent_loc, IMFS_SYM_LINK, new_name, ( S_IFLNK | ( S_IRWXU | S_IRWXG | S_IRWXO )), &info ); if (new_node == NULL) { free(info.sym_link.name); rtems_set_errno_and_return_minus_one(ENOMEM); } return 0; }
int IMFS_mknod( const char *token, /* IN */ mode_t mode, /* IN */ dev_t dev, /* IN */ rtems_filesystem_location_info_t *pathloc /* IN/OUT */ ) { IMFS_token_types type = 0; IMFS_jnode_t *new_node; int result; char new_name[ IMFS_NAME_MAX + 1 ]; IMFS_types_union info; IMFS_get_token( token, strlen( token ), new_name, &result ); /* * Figure out what type of IMFS node this is. */ if ( S_ISDIR(mode) ) type = IMFS_DIRECTORY; else if ( S_ISREG(mode) ) type = IMFS_MEMORY_FILE; else if ( S_ISBLK(mode) || S_ISCHR(mode) ) { type = IMFS_DEVICE; rtems_filesystem_split_dev_t( dev, info.device.major, info.device.minor ); } else if (S_ISFIFO(mode)) type = IMFS_FIFO; else IMFS_assert( 0 ); /* * Allocate and fill in an IMFS jnode * * NOTE: Coverity Id 21 reports this as a leak. * While technically not a leak, it indicated that IMFS_create_node * was ONLY passed a NULL when we created the root node. We * added a new IMFS_create_root_node() so this path no longer * existed. The result was simpler code which should not have * this path. */ new_node = IMFS_create_node( pathloc, type, new_name, mode, &info ); if ( !new_node ) rtems_set_errno_and_return_minus_one( ENOMEM ); IMFS_update_ctime(new_node->Parent); IMFS_update_mtime(new_node->Parent); return 0; }
int IMFS_link( const rtems_filesystem_location_info_t *parentloc, const rtems_filesystem_location_info_t *targetloc, const char *name, size_t namelen ) { IMFS_types_union info; IMFS_jnode_t *new_node; IMFS_jnode_t *target; target = targetloc->node_access; info.hard_link.link_node = target; /* * Verify this node can be linked to. */ if ( target->st_nlink >= LINK_MAX ) rtems_set_errno_and_return_minus_one( EMLINK ); /* * Create a new link node. */ new_node = IMFS_create_node( parentloc, IMFS_HARD_LINK, name, namelen, ( S_IFLNK | ( S_IRWXU | S_IRWXG | S_IRWXO )), &info ); if ( !new_node ) rtems_set_errno_and_return_minus_one( ENOMEM ); /* * Increment the link count of the node being pointed to. */ target->reference_count++; target->st_nlink++; IMFS_update_ctime( target ); return 0; }
int IMFS_symlink( const rtems_filesystem_location_info_t *parentloc, const char *name, size_t namelen, const char *target ) { IMFS_types_union info; IMFS_jnode_t *new_node; /* * Duplicate link name */ info.sym_link.name = strdup(target); if (info.sym_link.name == NULL) { rtems_set_errno_and_return_minus_one(ENOMEM); } /* * Create a new link node. */ new_node = IMFS_create_node( parentloc, IMFS_SYM_LINK, name, namelen, ( S_IFLNK | ( S_IRWXU | S_IRWXG | S_IRWXO )), &info ); if (new_node == NULL) { free(info.sym_link.name); rtems_set_errno_and_return_minus_one(ENOMEM); } return 0; }
int IMFS_symlink( rtems_filesystem_location_info_t *parent_loc, const char *link_name, const char *node_name ) { IMFS_types_union info; IMFS_jnode_t *new_node; char new_name[ IMFS_NAME_MAX + 1 ]; int i; /* * Remove any separators at the end of the string. */ IMFS_get_token( node_name, new_name, &i ); info.sym_link.name = link_name; /* * Create a new link node. */ new_node = IMFS_create_node( parent_loc, IMFS_SYM_LINK, new_name, ( S_IFLNK | ( S_IRWXU | S_IRWXG | S_IRWXO )), &info ); if ( !new_node ) rtems_set_errno_and_return_minus_one( ENOMEM ); return 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; }
/* * rtems_tarfs_load * * Here we create the mountpoint directory and load the tarfs at * that node. Once the IMFS has been mounted, we work through the * tar image and perform as follows: * - For directories, simply call mkdir(). The IMFS creates nodes as * needed. * - For files, we make our own calls to IMFS eval_for_make and * create_node. */ int rtems_tarfs_load( char *mountpoint, uint8_t *tar_image, size_t tar_size ) { rtems_filesystem_location_info_t root_loc; rtems_filesystem_location_info_t loc; 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 status; status = rtems_filesystem_evaluate_path( mountpoint, strlen(mountpoint), 0, &root_loc, 0 ); if (status != 0) return -1; if (root_loc.ops != &IMFS_ops && root_loc.ops != &fifoIMFS_ops) return -1; /* * Create an IMFS node structure pointing to tar image memory. */ offset = 0; while (1) { 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 * * NOTE: Coverity Id 20 reports this as a leak. * While technically not a leak, it indicated that * IMFS_create_node was ONLY passed a NULL when we created the * root node. We added a new IMFS_create_root_node() so this * path no longer existed. The result was simpler code which * should not have this path. */ else if (linkflag == REGTYPE) { const char *name; loc = root_loc; if (IMFS_evaluate_for_make(filename, &loc, &name) == 0) { node = IMFS_create_node( &loc, IMFS_LINEAR_FILE, (char *)name, (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; } } return status; }
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; }