Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:30

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2012, 2013 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 
0032 
0033 #include "tmacros.h"
0034 
0035 #include <errno.h>
0036 #include <fcntl.h>
0037 #include <dirent.h>
0038 
0039 #include <bsp.h>
0040 #include <rtems/io.h>
0041 #include <rtems/libio.h>
0042 #include <rtems/dosfs.h>
0043 #include <rtems/ramdisk.h>
0044 #include <rtems/libcsupport.h>
0045 #include <rtems/userenv.h>
0046 #include "image.h"
0047 #include "image_bin_le_singlebyte.h"
0048 #include "image_bin_le_multibyte.h"
0049 #include "files.h"
0050 
0051 #include <errno.h>
0052 
0053 const char rtems_test_name[] = "FSDOSFSNAME 1";
0054 
0055 #define PRINT_DISK_IMAGE 0
0056 
0057 #define MOUNT_DIR "/mnt"
0058 #define MOUNT_DIR_SIZE 4
0059 #define START_DIR_SIZE 4
0060 #define RAMDISK_PATH "/dev/rda"
0061 #define BLOCK_NUM 47
0062 #define BLOCK_SIZE 512
0063 #define VOLUME_LABEL "MyDisk"
0064 
0065 #define NUMBER_OF_DIRECTORIES 8
0066 #define NUMBER_OF_FILES 13
0067 #define NUMBER_OF_DIRECTORIES_INVALID 25
0068 #define NUMBER_OF_DIRECTORIES_DUPLICATED 3
0069 #define NUMBER_OF_MULTIBYTE_NAMES_DUPLICATED 2
0070 #define NUMBER_OF_FILES_DUPLICATED 2
0071 #define NUMBER_OF_NAMES_MULTIBYTE 10
0072 #define MAX_NAME_LENGTH ( 255 + 1 )
0073 #define MAX_NAME_LENGTH_INVALID ( 255 + 2 )
0074 #define MAX_DUPLICATES_PER_NAME 3
0075 static const char UTF8_BOM[] = {0xEF, 0xBB, 0xBF};
0076 #define UTF8_BOM_SIZE 3 /* Size of the UTF-8 byte-order-mark */
0077 
0078 #define BLOCK_SIZE 512
0079 
0080 static rtems_resource_snapshot            before_mount;
0081 
0082 static const msdos_format_request_param_t rqdata = {
0083   .OEMName             = "RTEMS",
0084   .VolLabel            = VOLUME_LABEL,
0085   .sectors_per_cluster = 2,
0086   .fat_num             = 0,
0087   .files_per_root_dir  = 0,
0088   .media               = 0,
0089   .quick_format        = true,
0090   .skip_alignment      = 0,
0091   .info_level          = 0
0092 };
0093 
0094 static const char                         DIRECTORY_NAMES[NUMBER_OF_DIRECTORIES]
0095 [MAX_NAME_LENGTH] = {
0096   "a dir",
0097   "Shortdir",
0098   "shrtdir",
0099   "shrt.dir",
0100   "long_conventional_dir",
0101   "long_conventional.dir",
0102   "LongConventionalDir",
0103   "This is a directory name with with 255 characters. The following numbers are aligned in that way, that the character 0 is the mentioned one. xxxxxx150xxxxxxx160xxxxxxx170xxxxxxx180xxxxxxx190xxxxxxx200xxxxxxx210xxxxxxx220xxxxxxx230xxxxxxx240xxxxxxx250xxxxx"
0104 };
0105 
0106 static const char DIRECTORY_NAMES_INVALID[
0107   NUMBER_OF_DIRECTORIES_INVALID][MAX_NAME_LENGTH_INVALID] = {
0108   "This is a directory name with with 256 characters. The following numbers are aligned in that way, that the character 0 is the mentioned one. xxxxxx150xxxxxxx160xxxxxxx170xxxxxxx180xxxxxxx190xxxxxxx200xxxxxxx210xxxxxxx220xxxxxxx230xxxxxxx240xxxxxxx250xxxxxx",
0109   ".",
0110   "..",
0111   "...",
0112   " ",
0113   "... ...",
0114   " ... ",
0115   "",
0116   "*",
0117   "/",
0118   ":",
0119   "<",
0120   ">",
0121   "?",
0122   "\\",
0123   "|",
0124   { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0125     10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
0126     20, 21, 22, 23, 24, 25, 26, 17, 28, 29, 30, 31},
0127   {127},
0128   "э*_то длинное имя",
0129   "э:_то длинное имя",
0130   "э<_то длинное имя",
0131   "э>_то длинное имя",
0132   "э?_то длинное имя",
0133   "э|_то длинное имя"
0134 };
0135 
0136 static const char NAMES_MULTIBYTE[
0137   NUMBER_OF_NAMES_MULTIBYTE][MAX_NAME_LENGTH] = {
0138   "đây là một tên tập tin dài",
0139   "Bu uzun bir dosya adı",
0140   "هذا هو اسم ملف طويل",
0141   "αυτό είναι ένα μεγάλο όνομα αρχείου",
0142   "это длинное имя",
0143   "гэта доўгае імя",
0144   "това е дълго име на файла",
0145   "这是一个长文件名",
0146   "shrtname",
0147   "long_conventional_name"
0148 };
0149 
0150 static const char NAMES_MULTIBYTE_IN_CODEPAGE_FORMAT[
0151   NUMBER_OF_NAMES_MULTIBYTE][MAX_NAME_LENGTH] = {
0152   "_\2030005~1._t",
0153   "bu0008~1.bir",
0154   "__000b~1.__",
0155   "__000f~1.__",
0156   "__0012~1.___",
0157   "__0015~1.___",
0158   "__0018~1.___",
0159   "__001a~1",
0160   "shrtname",
0161   "long_conventional_name"
0162 };
0163 
0164 static const char FILE_NAMES[NUMBER_OF_FILES][
0165   MAX_NAME_LENGTH] = {
0166   "a file",
0167   "shrtfile",
0168   "ShrtFle",
0169   "The quick brown.fox",
0170   "long_conventional_file",
0171   "This is a filename with with 255 characters. The following numbers are aligned in that way, that the character 0 is the mentioned one. xx140xxxxxxx150xxxxxxx160xxxxxxx170xxxxxxx180xxxxxxx190xxxxxxx200xxxxxxx210xxxxxxx220xxxxxxx230xxxxxxx240xxxxxxx250xxxxx",
0172   "+",
0173   ",",
0174   "a.a",
0175   ";",
0176   "=",
0177   "[",
0178   "]"
0179 };
0180 
0181 typedef struct {
0182   char name[MAX_NAME_LENGTH];
0183   unsigned int number_of_duplicates;
0184   char name_duplicates[MAX_DUPLICATES_PER_NAME][MAX_NAME_LENGTH];
0185 } name_duplicates;
0186 
0187 static const name_duplicates DIRECTORY_DUPLICATES[
0188   NUMBER_OF_DIRECTORIES_DUPLICATED] = {
0189   {
0190     "shrtdir",
0191     3,
0192     {
0193       "shrtdir",
0194       "SHRTDIR",
0195       "Shrtdir"
0196     }
0197   },
0198   {
0199     "Kurzdir",
0200     3,
0201     {
0202       "kurzdir",
0203       "KURZDIR",
0204       "Kurzdir"
0205     }
0206   },
0207   {
0208     "long_conventional_dir",
0209     3,
0210     {
0211       "long_conventional_dir",
0212       "LONG_CONVENTIONAL_DIR",
0213       "Long_conventional_dir"
0214     }
0215   }
0216 };
0217 
0218 static const name_duplicates MULTIBYTE_DUPLICATES[
0219   NUMBER_OF_MULTIBYTE_NAMES_DUPLICATED] = {
0220   {
0221     /* The angstroem encoded differently. These encodings might become short entries */
0222     {0xc3, 0x85}, /* '̊A' */
0223     2,
0224     {
0225       {0xc3, 0x85}, /* '̊A' */
0226       {0xe2, 0x84, 0xab} /* 'Å' */
0227     }
0228   },
0229 
0230   /* Again the angstroem encoded differently,
0231    * but this time with additional characters in order to enforce a long entry. */
0232   {
0233     {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', 0xc3,
0234      0x85},
0235     2,
0236     {
0237       {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', 0xc3,
0238        0x85},
0239       {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', 0xe2,
0240        0x84, 0xab}
0241     }
0242   }
0243 };
0244 
0245 
0246 static const name_duplicates FILES_DUPLICATES[NUMBER_OF_FILES_DUPLICATED] = {
0247   {
0248     "shrtfile",
0249     3,
0250     {
0251       "shrtfile",
0252       "SHRTFILE",
0253       "Shrtfile"
0254     }
0255   },
0256   {
0257     "long_conventional_file",
0258     3,
0259     {
0260       "long_conventional_file",
0261       "LONG_CONVENTIONAL_FILE",
0262       "Long_conventional_file"
0263     }
0264   }
0265 };
0266 
0267 static int path_is_directory( const char *path )
0268 {
0269   struct stat s_buf;
0270 
0271 
0272   if ( stat( path, &s_buf ) )
0273     return 0;
0274 
0275   return S_ISDIR( s_buf.st_mode );
0276 }
0277 
0278 static void delete_folder_tree( const char *directory_name )
0279 {
0280   DIR           *dp;
0281   struct dirent *ep;
0282   char           p_buf[1024] = {0};
0283   int            rc          = 0;
0284 
0285 
0286   dp = opendir( directory_name );
0287   rtems_test_assert( dp != NULL );
0288 
0289   while ( ( ep = readdir( dp ) ) != NULL && rc == 0 ) {
0290     if ( 0 != strcmp( ".", ep->d_name )
0291          && 0 != strcmp( "..", ep->d_name ) ) {
0292       snprintf( p_buf, sizeof( p_buf ), "%s/%s", directory_name, ep->d_name );
0293 
0294       if ( path_is_directory( p_buf ) ) {
0295         delete_folder_tree( p_buf );
0296         rc = rmdir( p_buf );
0297         rtems_test_assert( rc == 0 );
0298         rewinddir( dp );
0299       } else {
0300         rc = unlink( p_buf );
0301         rtems_test_assert( rc == 0 );
0302         rewinddir( dp );
0303       }
0304     }
0305   }
0306 
0307   rc = closedir( dp );
0308   rtems_test_assert( rc == 0 );
0309 }
0310 
0311 static void mount_device( const char *start_dir,
0312   const rtems_dosfs_mount_options    *mount_opts )
0313 {
0314   int rc;
0315 
0316   rc = mount(
0317     RAMDISK_PATH,
0318     MOUNT_DIR,
0319     "dosfs",
0320     RTEMS_FILESYSTEM_READ_WRITE,
0321     mount_opts );
0322   rtems_test_assert( rc == 0 );
0323 
0324   rc = mkdir( start_dir, S_IRWXU | S_IRWXG | S_IRWXO );
0325   rtems_test_assert( rc == 0 || ( rc == -1 && errno == EEXIST ) );
0326 }
0327 
0328 static void mount_device_with_defaults( const char *start_dir )
0329 {
0330   int rc;
0331 
0332 
0333   rc = msdos_format( RAMDISK_PATH, &rqdata );
0334   rtems_test_assert( rc == 0 );
0335 
0336   rtems_resource_snapshot_take( &before_mount );
0337 
0338   mount_device( start_dir, NULL );
0339 }
0340 
0341 static void mount_device_with_iconv(
0342   const char                *start_dir,
0343   rtems_dosfs_mount_options *mount_opts
0344 )
0345 {
0346   int                       rc;
0347 
0348   rc = msdos_format( RAMDISK_PATH, &rqdata );
0349   rtems_test_assert( rc == 0 );
0350 
0351   rtems_resource_snapshot_take( &before_mount );
0352 
0353   mount_opts->converter = rtems_dosfs_create_utf8_converter( "CP850" );
0354   rtems_test_assert( mount_opts->converter != NULL );
0355 
0356   mount_device( start_dir, mount_opts );
0357 }
0358 
0359 static void unmount_and_close_device( void )
0360 {
0361   int                     rc;
0362   rtems_resource_snapshot now;
0363   bool                    are_resources_freed;
0364 
0365 
0366   delete_folder_tree( MOUNT_DIR );
0367 
0368   rc = unmount( MOUNT_DIR );
0369   rtems_test_assert( rc == 0 );
0370 
0371   are_resources_freed = rtems_resource_snapshot_check( &before_mount );
0372 
0373   if ( !are_resources_freed )
0374     rtems_resource_snapshot_take( &now );
0375 
0376   rtems_test_assert( are_resources_freed );
0377 }
0378 
0379 /*
0380  * Simply create a few directories. These tests should all succeed
0381  */
0382 static void test_creating_directories(
0383   const char        *start_dir,
0384   const char        *directories,
0385   const unsigned int number_of_directories )
0386 {
0387   unsigned int   index;
0388   int            rc;
0389   char           dirname[MAX_NAME_LENGTH + strlen( start_dir ) + 1];
0390   DIR           *dirp;
0391   struct dirent *dp;
0392 
0393 
0394   for ( index = 0; index < number_of_directories; ++index ) {
0395     snprintf( dirname, sizeof( dirname ), "%s/%s", start_dir, directories
0396               + ( index * MAX_NAME_LENGTH ) );
0397     rc = mkdir( dirname, S_IRWXU | S_IRWXG | S_IRWXO );
0398     rtems_test_assert( rc == 0 );
0399   }
0400 
0401   dirp = opendir( start_dir );
0402   rtems_test_assert( NULL != dirp );
0403 
0404   index = 0;
0405   dp    = readdir( dirp );
0406   rtems_test_assert( dp != NULL );
0407   rtems_test_assert( 0 == strcmp( ".", dp->d_name ) );
0408 
0409   dp = readdir( dirp );
0410   rtems_test_assert( dp != NULL );
0411   rtems_test_assert( 0 == strcmp( "..", dp->d_name ) );
0412 
0413   dp = readdir( dirp );
0414   rtems_test_assert( dp != NULL );
0415 
0416   while ( dp != NULL ) {
0417     rtems_test_assert( 0
0418                        == strcmp( directories + ( index * MAX_NAME_LENGTH ),
0419                                   dp->d_name ) );
0420     ++index;
0421     dp = readdir( dirp );
0422   }
0423 
0424   rtems_test_assert( number_of_directories == index );
0425 
0426   rc = closedir( dirp );
0427   rtems_test_assert( rc == 0 );
0428 }
0429 
0430 /*
0431  * Try creating directories with invalid names.
0432  */
0433 static void test_creating_invalid_directories( void )
0434 {
0435   unsigned int index;
0436   int          rc;
0437   char         dirname[MAX_NAME_LENGTH_INVALID + MOUNT_DIR_SIZE + 1];
0438   int          len;
0439 
0440   for ( index = 0; index < NUMBER_OF_DIRECTORIES_INVALID; ++index ) {
0441     len = snprintf( dirname,
0442                     sizeof( dirname ),
0443                     "%s/%s",
0444                     MOUNT_DIR,
0445                     DIRECTORY_NAMES_INVALID[index] );
0446     rtems_test_assert( len < sizeof( dirname ) );
0447     rc = mkdir( dirname, S_IRWXU | S_IRWXG | S_IRWXO );
0448     rtems_test_assert( rc == -1 );
0449   }
0450 }
0451 
0452 /*
0453  * Try creating directories which do already exist
0454  * (although names may have different capitalization/encoding)
0455  */
0456 static void test_creating_duplicate_directories(
0457   const char            *start_dir,
0458   const name_duplicates *duplicates,
0459   const unsigned int     number_of_duplicates )
0460 {
0461   unsigned int index_dir;
0462   unsigned int index_duplicate;
0463   int          rc;
0464   char         dirname[MAX_NAME_LENGTH + MOUNT_DIR_SIZE + START_DIR_SIZE + 2];
0465 
0466 
0467   for ( index_dir = 0; index_dir < number_of_duplicates; ++index_dir ) {
0468     snprintf( dirname, sizeof( dirname ), "%s/%s", start_dir,
0469               duplicates[index_dir].name );
0470     rc = mkdir( dirname, S_IRWXU | S_IRWXG | S_IRWXO );
0471     rtems_test_assert( rc == 0 );
0472 
0473     for ( index_duplicate = 0;
0474           index_duplicate < duplicates[index_dir].number_of_duplicates;
0475           ++index_duplicate ) {
0476       snprintf( dirname, sizeof( dirname ), "%s/%s", start_dir,
0477                 duplicates[index_dir].name_duplicates[index_duplicate] );
0478       errno = 0;
0479       rc = mkdir( dirname, S_IRWXU | S_IRWXG | S_IRWXO );
0480       rtems_test_assert( rc == -1 );
0481       rtems_test_assert( errno == EEXIST );
0482     }
0483   }
0484 }
0485 
0486 /*
0487  * Try creating and opening files with valid names
0488  */
0489 static void test_handling_files(
0490   const char        *dirname,
0491   const char        *file_names,
0492   const unsigned int number_of_files )
0493 {
0494   unsigned int index;
0495   int          rc;
0496   char         filename[MAX_NAME_LENGTH * 2 + MOUNT_DIR_SIZE + START_DIR_SIZE
0497                         + 4];
0498   int          fd;
0499 
0500 
0501   for ( index = 0; index < number_of_files; ++index ) {
0502     snprintf(
0503       filename,
0504       sizeof( filename ) - 1,
0505       "%s/%s",
0506       dirname,
0507       file_names + index * MAX_NAME_LENGTH );
0508     fd = open( filename,
0509                O_RDWR | O_CREAT,
0510                S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
0511     rtems_test_assert( fd >= 0 );
0512 
0513     rc = close( fd );
0514     rtems_test_assert( rc == 0 );
0515 
0516     /* See if the file still exists and can be found */
0517     fd = open( filename, O_RDWR );
0518     rtems_test_assert( fd >= 0 );
0519 
0520     rc = close( fd );
0521     rtems_test_assert( rc == 0 );
0522   }
0523 }
0524 
0525 /*
0526  * Try to find (and open) all of the file names from an
0527  * array in a given directory
0528  */
0529 static void test_finding_files(
0530   const char        *dirname,
0531   const char        *file_names,
0532   const unsigned int number_of_files )
0533 {
0534   int            rc;
0535   DIR           *dir_stream;
0536   struct dirent *dp;
0537   int            fd;
0538   unsigned int   index_file;
0539   char           filename[MAX_NAME_LENGTH * 2 + MOUNT_DIR_SIZE
0540                           + START_DIR_SIZE + 4];
0541 
0542 
0543   dir_stream = opendir( dirname );
0544   rtems_test_assert( dir_stream != NULL );
0545 
0546   dp = readdir( dir_stream );
0547   rtems_test_assert( dp != NULL );
0548   rtems_test_assert( 0 == strcmp( ".", dp->d_name ) );
0549 
0550   dp = readdir( dir_stream );
0551   rtems_test_assert( dp != NULL );
0552   rtems_test_assert( 0 == strcmp( "..", dp->d_name ) );
0553 
0554   dp         = readdir( dir_stream );
0555   rtems_test_assert( dp != NULL );
0556   index_file = 0;
0557 
0558   while ( dp != NULL ) {
0559     rtems_test_assert( 0 == strcmp(
0560                          file_names + index_file * MAX_NAME_LENGTH,
0561                          dp->d_name ) );
0562 
0563     snprintf(
0564       filename,
0565       sizeof( filename ) - 1,
0566       "%s/%s",
0567       dirname,
0568       file_names + index_file * MAX_NAME_LENGTH );
0569 
0570     /* See if the file still exists and can be found */
0571     fd = open( filename, O_RDWR );
0572     rtems_test_assert( fd >= 0 );
0573 
0574     rc = close( fd );
0575     rtems_test_assert( rc == 0 );
0576 
0577     ++index_file;
0578     dp = readdir( dir_stream );
0579   }
0580 
0581   rtems_test_assert( number_of_files == index_file );
0582 
0583   rc = closedir( dir_stream );
0584   rtems_test_assert( rc == 0 );
0585 }
0586 
0587 /*
0588  * Try opening files which do already exist (with different capitalization in their names)
0589  */
0590 static void test_duplicated_files( const char *dirname,
0591   const name_duplicates                       *files_duplicated,
0592   const unsigned int                           number_of_files_duplicated )
0593 {
0594   unsigned int index_file;
0595   unsigned int index_duplicate;
0596   int          rc;
0597   char         filename[MAX_NAME_LENGTH + strlen( dirname ) + 1];
0598   int          fd;
0599 
0600 
0601   for ( index_file = 0; index_file < number_of_files_duplicated;
0602         ++index_file ) {
0603     snprintf( filename,
0604               sizeof( filename ) - 1,
0605               "%s/%s",
0606               dirname,
0607               files_duplicated[index_file].name );
0608     fd = open( filename,
0609                O_RDWR | O_CREAT,
0610                S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
0611     rtems_test_assert( fd >= 0 );
0612 
0613     rc = close( fd );
0614     rtems_test_assert( rc == 0 );
0615 
0616     for ( index_duplicate = 0;
0617           index_duplicate < files_duplicated[index_file].number_of_duplicates;
0618           ++index_duplicate ) {
0619       snprintf( filename,
0620                 sizeof( filename ) - 1,
0621                 "%s/%s",
0622                 dirname,
0623                 files_duplicated[index_file].name_duplicates[index_duplicate] );
0624       fd = open( filename, O_RDWR );
0625       rtems_test_assert( fd >= 0 );
0626 
0627       rc = close( fd );
0628       rtems_test_assert( rc == 0 );
0629 
0630       errno = 0;
0631       fd = open( filename, O_RDWR | O_CREAT | O_EXCL );
0632       rtems_test_assert( fd == -1 );
0633       rtems_test_assert( errno == EEXIST );
0634     }
0635 
0636     rc = remove( filename );
0637     rtems_test_assert( rc == 0 );
0638   }
0639 }
0640 
0641 /*
0642  * Open and read existing valid directories
0643  */
0644 static void test_handling_directories(
0645   const char        *start_dir,
0646   const char        *directory_names,
0647   const unsigned int number_of_directories,
0648   const char        *file_names,
0649   const unsigned int number_of_files )
0650 {
0651   unsigned int   index_directory;
0652   unsigned int   index_file;
0653   int            rc;
0654   DIR           *dir_stream;
0655   char           dirname[MAX_NAME_LENGTH * 2];
0656   struct dirent *dp;
0657 
0658 
0659   for ( index_directory = 0;
0660         index_directory < number_of_directories;
0661         ++index_directory ) {
0662     snprintf(
0663       dirname,
0664       sizeof( dirname ) - 1,
0665       "%s/%s",
0666       start_dir,
0667       directory_names + index_directory * MAX_NAME_LENGTH );
0668 
0669     test_handling_files(
0670       dirname,
0671       file_names,
0672       number_of_files );
0673 
0674     dir_stream = opendir( dirname );
0675     rtems_test_assert( dir_stream != NULL );
0676 
0677     dp = readdir( dir_stream );
0678     rtems_test_assert( dp != NULL );
0679     rtems_test_assert( 0 == strcmp( ".", dp->d_name ) );
0680 
0681     dp = readdir( dir_stream );
0682     rtems_test_assert( dp != NULL );
0683     rtems_test_assert( 0 == strcmp( "..", dp->d_name ) );
0684 
0685     dp         = readdir( dir_stream );
0686     rtems_test_assert( dp != NULL );
0687     index_file = 0;
0688 
0689     while ( dp != NULL ) {
0690       rtems_test_assert( 0 == strcmp(
0691                            file_names + index_file * MAX_NAME_LENGTH,
0692                            dp->d_name ) );
0693       ++index_file;
0694       dp = readdir( dir_stream );
0695     }
0696 
0697     rtems_test_assert( number_of_files == index_file );
0698 
0699     rc = closedir( dir_stream );
0700     rtems_test_assert( rc == 0 );
0701   }
0702 }
0703 
0704 /*
0705  * Try to find all sub-directories from an array
0706  * in a given start directory.
0707  * In addition try to find and open files
0708  * in these sub-directories.
0709  */
0710 static void test_finding_directories(
0711   const char        *start_dir,
0712   const char        *directory_names,
0713   const unsigned int number_of_directories,
0714   const char        *file_names,
0715   const unsigned int number_of_files )
0716 {
0717   unsigned int   index_directory;
0718   int            rc;
0719   DIR           *dir_stream;
0720   struct dirent *dp;
0721   char           dirname[MAX_NAME_LENGTH * 2];
0722 
0723 
0724   dir_stream = opendir( start_dir );
0725   rtems_test_assert( dir_stream != NULL );
0726 
0727   dp = readdir( dir_stream );
0728   rtems_test_assert( dp != NULL );
0729   rtems_test_assert( 0 == strcmp( ".", dp->d_name ) );
0730 
0731   dp = readdir( dir_stream );
0732   rtems_test_assert( dp != NULL );
0733   rtems_test_assert( 0 == strcmp( "..", dp->d_name ) );
0734 
0735   dp              = readdir( dir_stream );
0736   rtems_test_assert( dp != NULL );
0737   index_directory = 0;
0738 
0739   while ( dp != NULL ) {
0740     rtems_test_assert( 0 == strcmp(
0741                          directory_names + index_directory * MAX_NAME_LENGTH,
0742                          dp->d_name ) );
0743 
0744     snprintf(
0745       dirname,
0746       sizeof( dirname ) - 1,
0747       "%s/%s",
0748       start_dir,
0749       directory_names + index_directory * MAX_NAME_LENGTH );
0750 
0751     test_finding_files(
0752       dirname,
0753       file_names,
0754       number_of_files );
0755 
0756     ++index_directory;
0757     dp = readdir( dir_stream );
0758   }
0759 
0760   rtems_test_assert( number_of_directories == index_directory );
0761 
0762   rc = closedir( dir_stream );
0763   rtems_test_assert( rc == 0 );
0764 }
0765 
0766 #if (PRINT_DISK_IMAGE != 0)
0767 static void print_image(
0768   const char* include_guard,
0769   const char* image_name
0770 )
0771 {
0772   #define                   BYTES_PER_ROW     8
0773   int                       rc;
0774   int                       fd;
0775   ssize_t                   bytes_read;
0776   uint8_t                   buf[BLOCK_SIZE];
0777   unsigned int              index_block;
0778   unsigned int              index_row;
0779   unsigned int              index_column;
0780   unsigned int              index_buf;
0781 #ifdef SHOW_LINE_NUMBERS
0782   size_t                    index_row_start = 1;
0783 #endif /* SWOW_LINE_NUMBERS */
0784   size_t                    bytes_written   = 0;
0785   const size_t              DISK_SIZE       = BLOCK_SIZE * BLOCK_NUM;
0786   const unsigned int        ROWS_PER_BLOCK  = BLOCK_SIZE / BYTES_PER_ROW;
0787 
0788   printf ("/*\n"
0789           " *  Declarations for C structure representing a disk image\n"
0790           " *\n"
0791           " *  WARNING: Automatically generated by init.c -- do not edit!\n"
0792           " */\n"
0793           "#ifndef %s\n"
0794           "#define %s\n"
0795           "\n"
0796           "#include <sys/types.h>\n"
0797           "\n"
0798           "#ifdef __cplusplus\n"
0799           "extern \"C\" {\n"
0800           "#endif /* __cplusplus */\n"
0801           "\n"
0802           "static unsigned char %s[] = {\n",
0803           include_guard,
0804           include_guard,
0805           image_name);
0806   fd = open( RAMDISK_PATH, O_RDWR );
0807   rtems_test_assert( fd >= 0 );
0808 
0809   for ( index_block = 0; index_block < BLOCK_NUM; ++index_block )
0810   {
0811     bytes_read = read( fd, &buf[0], BLOCK_SIZE );
0812     rtems_test_assert( bytes_read = BLOCK_SIZE );
0813 
0814     index_buf = 0;
0815 
0816     for ( index_row = 0; index_row < ROWS_PER_BLOCK; ++index_row )
0817     {
0818       printf( "  " );
0819       for ( index_column = 0;
0820             index_column < BYTES_PER_ROW;
0821             ++index_column ) {
0822         printf("0x%02x", buf[index_buf]);
0823         ++bytes_written;
0824         ++index_buf;
0825         if ( bytes_written < DISK_SIZE ) {
0826           printf (", ");
0827         } else {
0828           printf ("  ");
0829         }
0830       }
0831 #ifdef SHOW_LINE_NUMBERS
0832       printf( "/* %6u - %6u */", index_row_start, bytes_written );
0833       index_row_start = bytes_written + 1;
0834 #endif /* SWOW_LINE_NUMBERS */
0835       printf( "\n" );
0836     }
0837   }
0838 
0839   rc = close( fd );
0840   rtems_test_assert( rc == 0 );
0841 
0842   printf ("};\n"
0843           "#ifdef __cplusplus\n"
0844           "}\n"
0845           "#endif /* __cplusplus */\n"
0846           "\n"
0847           "#endif /* %s */\n",
0848           include_guard);
0849 }
0850 #else /* PRINT_DISK_IMAGE */
0851 static void print_image(
0852   const char* include_guard,
0853   const char* image_name
0854 )
0855 {
0856   /* Nothing to be done */
0857 }
0858 #endif /* PRINT_DISK_IMAGE */
0859 
0860 
0861 static void compare_files(
0862   const char *file0,
0863   const char *file1
0864 )
0865 {
0866   struct stat  stat_buf[2];
0867   int          fd[2];
0868   unsigned int index;
0869   uint8_t      buf[2];
0870   ssize_t      bytes_read;
0871   int          rc;
0872 
0873   rc = stat( file0 , &stat_buf[0] );
0874   rtems_test_assert( rc == 0 );
0875   rc = stat( file1 , &stat_buf[1] );
0876   rtems_test_assert( rc == 0 );
0877 
0878   rtems_test_assert( stat_buf[0].st_size == stat_buf[1].st_size );
0879 
0880   fd[0] = open( file0, O_RDONLY );
0881   rtems_test_assert( fd[0] > 0 );
0882   fd[1] = open( file1, O_RDONLY );
0883   rtems_test_assert( fd[1] > 0 );
0884 
0885   for ( index = 0; index < stat_buf[0].st_size; ++index ) {
0886     bytes_read = read( fd[0], &buf[0], 1 );
0887     rtems_test_assert( bytes_read == 1 );
0888     bytes_read = read( fd[1], &buf[1], 1 );
0889     rtems_test_assert( bytes_read == 1 );
0890     rtems_test_assert( buf[0] == buf[1] );
0891   }
0892   rc = close( fd[0] );
0893   rtems_test_assert( rc == 0 );
0894   rc = close( fd[1] );
0895   rtems_test_assert( rc == 0 );
0896 }
0897 
0898 static void compare_directories(
0899   const char *dir0,
0900   const char *dir1)
0901 {
0902   int                       rc;
0903   DIR                      *dir_stream[2];
0904   struct dirent            *dp;
0905   struct stat               stat_buf[2];
0906   char                     *path[2];
0907   const unsigned int        PATH_LENGTH = 1024;
0908 
0909   path[0] = calloc( PATH_LENGTH, sizeof(char) );
0910   rtems_test_assert( path[0] != NULL );
0911   path[1] = calloc( PATH_LENGTH, sizeof(char) );
0912   rtems_test_assert( path[1] != NULL );
0913 
0914   dir_stream[0] = opendir( dir0 );
0915   rtems_test_assert( dir_stream[0] != NULL );
0916 
0917   dir_stream[1] = opendir( dir1 );
0918   rtems_test_assert( dir_stream[1] != NULL );
0919 
0920   dp = readdir( dir_stream[0] );
0921   rtems_test_assert( dp != NULL );
0922 
0923   while ( dp != NULL ) {
0924     rc = snprintf(path[0], PATH_LENGTH, "%s/%s", dir0, dp->d_name);
0925     rtems_test_assert( rc < PATH_LENGTH );
0926     rtems_test_assert( rc >= 0 );
0927     rc = snprintf(path[1], PATH_LENGTH, "%s/%s", dir1, dp->d_name);
0928     rtems_test_assert( rc < PATH_LENGTH );
0929     rtems_test_assert( rc >= 0 );
0930 
0931     rc = stat( path[0] , &stat_buf[0] );
0932     rtems_test_assert( rc == 0 );
0933 
0934     if (   ( strcmp( dp->d_name, "."  ) != 0)
0935         && ( strcmp( dp->d_name, ".." ) != 0) ) {
0936       if ( S_ISDIR( stat_buf[0].st_mode ) ) {
0937         compare_directories( path[0], path[1] );
0938       } else {
0939         compare_files( path[0], path[1] );
0940       }
0941     }
0942 
0943     dp = readdir( dir_stream[0] );
0944 
0945   }
0946   rc = closedir( dir_stream[0] );
0947   rtems_test_assert( rc == 0 );
0948 
0949   rc = closedir( dir_stream[1] );
0950   rtems_test_assert( rc == 0 );
0951 
0952   free (path[0]);
0953   free (path[1]);
0954 }
0955 
0956 static void compare_image(
0957   const char                      *mount_dir,
0958   const char                      *dev,
0959   const rtems_dosfs_mount_options *mount_opts )
0960 {
0961   #define MOUNT_DIR2 "/mnt2"
0962   int                       rc;
0963 
0964   rc = mount_and_make_target_path(
0965     dev,
0966     MOUNT_DIR2,
0967     RTEMS_FILESYSTEM_TYPE_DOSFS,
0968     RTEMS_FILESYSTEM_READ_WRITE,
0969     mount_opts );
0970   rtems_test_assert( rc == 0 );
0971 
0972   compare_directories(mount_dir, MOUNT_DIR2);
0973 
0974   rc = unmount( MOUNT_DIR2 );
0975   rtems_test_assert( rc == 0 );
0976 
0977   rc = rmdir( MOUNT_DIR2 );
0978   rtems_test_assert( rc == 0 );
0979 
0980 }
0981 /*
0982  * Test the compatibility with a genuine MS Windows FAT file system.
0983  */
0984 static void test_compatibility( void )
0985 {
0986   int                       rc;
0987   char                      diskpath[] = "/dev/rdd";
0988   rtems_dosfs_mount_options mount_opts;
0989   FILE                     *fp;
0990   int                       buffer;
0991   unsigned int              index_file = 0;
0992   unsigned int              index_char;
0993   unsigned int              offset;
0994   char                      content_buf[MAX_NAME_LENGTH + strlen( MOUNT_DIR )
0995                                         + 1];
0996   char                      file_path[MAX_NAME_LENGTH + strlen( MOUNT_DIR )
0997                                       + 1];
0998   DIR                      *dir_stream;
0999   struct dirent            *dp;
1000 
1001 
1002   mount_opts.converter = rtems_dosfs_create_utf8_converter( "CP850" );
1003   rtems_test_assert( mount_opts.converter != NULL );
1004 
1005   rc = mount_and_make_target_path(
1006     diskpath,
1007     MOUNT_DIR,
1008     RTEMS_FILESYSTEM_TYPE_DOSFS,
1009     RTEMS_FILESYSTEM_READ_WRITE,
1010     &mount_opts );
1011   rtems_test_assert( rc == 0 );
1012 
1013   dir_stream = opendir( MOUNT_DIR );
1014   rtems_test_assert( dir_stream != NULL );
1015 
1016   dp = readdir( dir_stream );
1017   rtems_test_assert( dp != NULL );
1018 
1019   while ( dp != NULL ) {
1020     index_char = 0;
1021 
1022     size_t len = strlen( filenames[index_file] );
1023 
1024     if ( filenames[index_file][len - 1] == '.' )
1025       rtems_test_assert( ( len - 1 ) == dp->d_namlen );
1026     else
1027       rtems_test_assert( len == dp->d_namlen );
1028 
1029     rtems_test_assert( 0
1030                        == memcmp( &filenames[index_file][0], &dp->d_name[0],
1031                                   dp->d_namlen ) );
1032 
1033     snprintf( file_path, sizeof( file_path ), "%s/%s", MOUNT_DIR,
1034               filenames[index_file] );
1035     fp = fopen( file_path, "r" );
1036     rtems_test_assert( fp != NULL );
1037 
1038     /* These files should contain their own file names. */
1039     while ( ( buffer = fgetc( fp ) ) != EOF ) {
1040       content_buf[index_char] = buffer;
1041       ++index_char;
1042     }
1043 
1044     if ( 0 == strncmp( content_buf, UTF8_BOM, UTF8_BOM_SIZE ) )
1045       offset = UTF8_BOM_SIZE;
1046     else
1047       offset = 0;
1048 
1049     rtems_test_assert( 0
1050                        == memcmp( filenames[index_file],
1051                                   &content_buf[offset],
1052                                   index_char - offset ) );
1053 
1054     rc = fclose( fp );
1055     rtems_test_assert( rc == 0 );
1056 
1057     ++index_file;
1058     dp = readdir( dir_stream );
1059   }
1060 
1061   rtems_test_assert( index_file == FILES_FILENAMES_NUMBER_OF );
1062 
1063   rc = closedir( dir_stream );
1064   rtems_test_assert( rc == 0 );
1065 
1066   rc = unmount( MOUNT_DIR );
1067   rtems_test_assert( rc == 0 );
1068 }
1069 
1070 static void test_end_of_string_matches( void )
1071 {
1072   int rc;
1073 
1074   rc = mkdir( MOUNT_DIR "/lib.beam", S_IRWXU | S_IRWXG | S_IRWXO );
1075   rtems_test_assert( rc == 0 );
1076 
1077   errno = 0;
1078   rc = unlink( MOUNT_DIR "/proc_lib.beam" );
1079   rtems_test_assert( rc == -1 );
1080   rtems_test_assert( errno == ENOENT );
1081 
1082   rc = unlink( MOUNT_DIR "/lib.beam" );
1083   rtems_test_assert( rc == 0 );
1084 }
1085 
1086 static void test_end_of_string_matches_2( void )
1087 {
1088   int rc;
1089   int fd;
1090 
1091   fd = open( MOUNT_DIR "/ets.beam", O_RDWR | O_CREAT,
1092              S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
1093   rtems_test_assert( fd >= 0 );
1094   rc = close( fd );
1095   rtems_test_assert( rc == 0 );
1096 
1097   fd = open( MOUNT_DIR "/sets.beam", O_RDWR | O_CREAT,
1098              S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
1099   rtems_test_assert( fd >= 0 );
1100   rc = close( fd );
1101   rtems_test_assert( rc == 0 );
1102 
1103   rc = unlink( MOUNT_DIR "/sets.beam" );
1104   rtems_test_assert( rc == 0 );
1105 
1106   rc = unlink( MOUNT_DIR "/ets.beam" );
1107   rtems_test_assert( rc == 0 );
1108 }
1109 
1110 static void test_full_8_3_name( void )
1111 {
1112   int rc;
1113 
1114   rc = mkdir( MOUNT_DIR "/txtvsbin.txt", S_IRWXU | S_IRWXG | S_IRWXO );
1115   rtems_test_assert( rc == 0 );
1116 
1117   rc = unlink( MOUNT_DIR "/txtvsbin.txt" );
1118   rtems_test_assert( rc == 0 );
1119 }
1120 
1121 static void test_dir_with_same_name_as_volume_label( void )
1122 {
1123   int  rc;
1124   DIR *dirp;
1125 
1126   rc = mkdir( MOUNT_DIR "/" VOLUME_LABEL, S_IRWXU | S_IRWXG | S_IRWXO );
1127   rtems_test_assert( rc == 0 );
1128 
1129   dirp = opendir( MOUNT_DIR "/" VOLUME_LABEL );
1130   rtems_test_assert( NULL != dirp );
1131 
1132   rc = closedir( dirp );
1133   rtems_test_assert( rc == 0 );
1134 
1135   rc = unlink( MOUNT_DIR "/" VOLUME_LABEL );
1136   rtems_test_assert( rc == 0 );
1137 }
1138 
1139 static void test_file_with_same_name_as_volume_label( void )
1140 {
1141   int rc;
1142   int fd;
1143 
1144   fd = open( MOUNT_DIR "/" VOLUME_LABEL, O_RDWR | O_CREAT,
1145              S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
1146   rtems_test_assert( fd >= 0 );
1147 
1148   rc = close( fd );
1149   rtems_test_assert( rc == 0 );
1150 
1151   fd = open( MOUNT_DIR "/" VOLUME_LABEL, O_RDWR );
1152   rtems_test_assert( fd >= 0 );
1153 
1154   rc = close( fd );
1155   rtems_test_assert( rc == 0 );
1156 
1157   rc = unlink( MOUNT_DIR "/" VOLUME_LABEL );
1158   rtems_test_assert( rc == 0 );
1159 }
1160 
1161 static void test_getcwd( void )
1162 {
1163   const char *dir_path = MOUNT_DIR "/somedir";
1164   char cwd_buf[128];
1165   char *cwd;
1166   int rc;
1167   rtems_status_code sc;
1168 
1169   sc = rtems_libio_set_private_env();
1170   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
1171 
1172   cwd = getcwd( cwd_buf, sizeof( cwd_buf ) );
1173   rtems_test_assert( cwd != NULL );
1174   rtems_test_assert( strcmp( cwd, "/" ) == 0 );
1175 
1176   rc = mkdir( dir_path, S_IRWXU | S_IRWXG | S_IRWXO );
1177   rtems_test_assert( rc == 0 );
1178 
1179   rc = chdir( dir_path );
1180   rtems_test_assert( rc == 0 );
1181 
1182   cwd = getcwd( cwd_buf, sizeof( cwd_buf ) );
1183   rtems_test_assert( cwd != NULL );
1184   rtems_test_assert( strcmp( cwd, dir_path ) == 0 );
1185 
1186   rc = chdir( "/" );
1187   rtems_test_assert( rc == 0 );
1188 
1189   rc = unlink( dir_path );
1190   rtems_test_assert( rc == 0 );
1191 
1192   cwd = getcwd( cwd_buf, sizeof( cwd_buf ) );
1193   rtems_test_assert( cwd != NULL );
1194   rtems_test_assert( strcmp( cwd, "/" ) == 0 );
1195 
1196   rtems_libio_use_global_env();
1197 }
1198 
1199 static void test_special_cases( void )
1200 {
1201   test_end_of_string_matches();
1202   test_end_of_string_matches_2();
1203   test_full_8_3_name();
1204   test_file_with_same_name_as_volume_label();
1205   test_dir_with_same_name_as_volume_label();
1206   test_getcwd();
1207 }
1208 
1209 /*
1210  * Main test method
1211  */
1212 static void test( void )
1213 {
1214   int  rc;
1215   char start_dir[MOUNT_DIR_SIZE + START_DIR_SIZE + 2];
1216   rtems_dosfs_mount_options mount_opts[2];
1217 
1218   rc = mkdir( MOUNT_DIR, S_IRWXU | S_IRWXG | S_IRWXO );
1219   rtems_test_assert( rc == 0 );
1220 
1221   snprintf( start_dir, sizeof( start_dir ), "%s/%s", MOUNT_DIR, "strt" );
1222 
1223   /*
1224    * Tests with code page 850 compatible directory and file names
1225    * and the code page 850 backwards compatible default mode mode of the
1226    * FAT file system
1227    */
1228   mount_device_with_defaults( start_dir );
1229 
1230   test_creating_duplicate_directories(
1231     &start_dir[0],
1232     &DIRECTORY_DUPLICATES[0],
1233     NUMBER_OF_DIRECTORIES_DUPLICATED );
1234 
1235   unmount_and_close_device();
1236 
1237   mount_device_with_defaults( start_dir );
1238 
1239   test_duplicated_files(
1240     MOUNT_DIR,
1241     FILES_DUPLICATES,
1242     NUMBER_OF_FILES_DUPLICATED );
1243 
1244   unmount_and_close_device();
1245 
1246   mount_device_with_defaults( start_dir );
1247 
1248   test_creating_invalid_directories();
1249 
1250   test_creating_directories(
1251     &start_dir[0],
1252     &DIRECTORY_NAMES[0][0],
1253     NUMBER_OF_DIRECTORIES );
1254 
1255   test_handling_directories(
1256     &start_dir[0],
1257     &DIRECTORY_NAMES[0][0],
1258     NUMBER_OF_DIRECTORIES,
1259     &FILE_NAMES[0][0],
1260     NUMBER_OF_FILES );
1261 
1262   compare_image(
1263     MOUNT_DIR,
1264     "/dev/rdb",
1265     NULL);
1266 
1267   test_special_cases();
1268 
1269   rc = unmount( MOUNT_DIR );
1270   rtems_test_assert( rc == 0 );
1271 
1272   /*
1273    * Again tests with code page 850 compatible directory and file names
1274    * but with multibyte string compatible conversion methods which use
1275    * iconv and utf8proc
1276    */
1277   mount_opts[0].converter = rtems_dosfs_create_utf8_converter( "CP850" );
1278   rtems_test_assert( mount_opts[0].converter != NULL );
1279 
1280   rc                     = mount(
1281     RAMDISK_PATH,
1282     MOUNT_DIR,
1283     "dosfs",
1284     RTEMS_FILESYSTEM_READ_WRITE,
1285     &mount_opts );
1286   rtems_test_assert( rc == 0 );
1287 
1288   test_finding_directories(
1289     &start_dir[0],
1290     &DIRECTORY_NAMES[0][0],
1291     NUMBER_OF_DIRECTORIES,
1292     &FILE_NAMES[0][0],
1293     NUMBER_OF_FILES );
1294   unmount_and_close_device();
1295 
1296   mount_device_with_iconv( start_dir, &mount_opts[0] );
1297   test_creating_invalid_directories();
1298 
1299   test_creating_duplicate_directories(
1300     &start_dir[0],
1301     &DIRECTORY_DUPLICATES[0],
1302     NUMBER_OF_DIRECTORIES_DUPLICATED );
1303 
1304   unmount_and_close_device();
1305 
1306   mount_device_with_iconv( start_dir, &mount_opts[0] );
1307 
1308   test_duplicated_files(
1309     MOUNT_DIR,
1310     FILES_DUPLICATES,
1311     NUMBER_OF_FILES_DUPLICATED );
1312 
1313   unmount_and_close_device();
1314 
1315   mount_device_with_iconv( start_dir, &mount_opts[0] );
1316 
1317   test_creating_directories(
1318     &start_dir[0],
1319     &DIRECTORY_NAMES[0][0],
1320     NUMBER_OF_DIRECTORIES );
1321 
1322   test_handling_directories(
1323     &start_dir[0],
1324     &DIRECTORY_NAMES[0][0],
1325     NUMBER_OF_DIRECTORIES,
1326     &FILE_NAMES[0][0],
1327     NUMBER_OF_FILES );
1328 
1329   mount_opts[1].converter = rtems_dosfs_create_utf8_converter( "CP850" );
1330   rtems_test_assert( mount_opts[1].converter != NULL );
1331 
1332   compare_image(
1333     MOUNT_DIR,
1334     "/dev/rdb",
1335     &mount_opts[1]);
1336 
1337   test_special_cases();
1338 
1339   rc = unmount( MOUNT_DIR );
1340   rtems_test_assert( rc == 0 );
1341 
1342   print_image(
1343       "IMAGE_BIN_LE_SINGLEBYTE_H_",
1344       "IMAGE_BIN_LE_SINGLEBYTE");
1345 
1346   rc = mount(
1347     RAMDISK_PATH,
1348     MOUNT_DIR,
1349     "dosfs",
1350     RTEMS_FILESYSTEM_READ_WRITE,
1351     NULL );
1352   rtems_test_assert( rc == 0 );
1353 
1354   unmount_and_close_device();
1355 
1356 
1357   /*
1358    * Tests with multibyte directory and file names and
1359    * with multibyte string compatible conversion methods which use
1360    * iconv and utf8proc
1361    */
1362   mount_device_with_iconv( start_dir, &mount_opts[0] );
1363 
1364   test_creating_duplicate_directories(
1365     &start_dir[0],
1366     &MULTIBYTE_DUPLICATES[0],
1367     NUMBER_OF_MULTIBYTE_NAMES_DUPLICATED );
1368 
1369   unmount_and_close_device();
1370 
1371   mount_device_with_iconv( start_dir, &mount_opts[0] );
1372 
1373   test_duplicated_files(
1374     MOUNT_DIR,
1375     &MULTIBYTE_DUPLICATES[0],
1376     NUMBER_OF_MULTIBYTE_NAMES_DUPLICATED );
1377 
1378   unmount_and_close_device();
1379 
1380   mount_device_with_iconv( start_dir, &mount_opts[0] );
1381 
1382   test_creating_directories(
1383     &start_dir[0],
1384     &NAMES_MULTIBYTE[0][0],
1385     NUMBER_OF_NAMES_MULTIBYTE );
1386 
1387   test_handling_directories(
1388     &start_dir[0],
1389     &NAMES_MULTIBYTE[0][0],
1390     NUMBER_OF_NAMES_MULTIBYTE,
1391     &NAMES_MULTIBYTE[0][0],
1392     NUMBER_OF_NAMES_MULTIBYTE );
1393 
1394   mount_opts[1].converter = rtems_dosfs_create_utf8_converter( "CP850" );
1395   rtems_test_assert( mount_opts[1].converter != NULL );
1396 
1397   compare_image(
1398     MOUNT_DIR,
1399     "/dev/rdc",
1400     &mount_opts[1]);
1401 
1402   test_special_cases();
1403 
1404   rc = unmount( MOUNT_DIR );
1405   rtems_test_assert( rc == 0 );
1406 
1407   print_image(
1408     "IMAGE_BIN_LE_MULTIBYTE_H_",
1409     "IMAGE_BIN_LE_MULTIBYTE");
1410 
1411   rc = mount(
1412     RAMDISK_PATH,
1413     MOUNT_DIR,
1414     "dosfs",
1415     RTEMS_FILESYSTEM_READ_WRITE,
1416     NULL );
1417   rtems_test_assert( rc == 0 );
1418 
1419   test_finding_directories(
1420     &start_dir[0],
1421     &NAMES_MULTIBYTE_IN_CODEPAGE_FORMAT[0][0],
1422     NUMBER_OF_NAMES_MULTIBYTE,
1423     &NAMES_MULTIBYTE_IN_CODEPAGE_FORMAT[0][0],
1424     NUMBER_OF_NAMES_MULTIBYTE );
1425 
1426   unmount_and_close_device();
1427 
1428   test_compatibility();
1429 }
1430 
1431 static void Init( rtems_task_argument arg )
1432 {
1433   TEST_BEGIN();
1434 
1435   test();
1436 
1437   TEST_END();
1438   rtems_test_exit( 0 );
1439 }
1440 
1441 rtems_ramdisk_config rtems_ramdisk_configuration [] = {
1442   { .block_size = BLOCK_SIZE, .block_num = BLOCK_NUM },
1443   { .block_size = BLOCK_SIZE, .block_num = BLOCK_NUM, .location = &IMAGE_BIN_LE_SINGLEBYTE[0] },
1444   { .block_size = BLOCK_SIZE, .block_num = BLOCK_NUM, .location = &IMAGE_BIN_LE_MULTIBYTE[0] },
1445   { .block_size = BLOCK_SIZE, .block_num = sizeof( image_bin ) / BLOCK_SIZE, .location = image_bin }
1446 };
1447 
1448 size_t rtems_ramdisk_configuration_size = RTEMS_ARRAY_SIZE(rtems_ramdisk_configuration);
1449 
1450 #define CONFIGURE_INIT_TASK_STACK_SIZE ( 1024 * 64 )
1451 #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
1452 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
1453 #define CONFIGURE_MAXIMUM_SEMAPHORES (2 * RTEMS_DOSFS_SEMAPHORES_PER_INSTANCE)
1454 #define CONFIGURE_APPLICATION_EXTRA_DRIVERS RAMDISK_DRIVER_TABLE_ENTRY
1455 
1456 #define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
1457 
1458 #define CONFIGURE_FILESYSTEM_DOSFS
1459 
1460 /* 2 RAM disk device files + 2 mount_dir + stdin + stdout + stderr +
1461  * 2 for open directories/files  + 4 * 2 for recursive tree compares*/
1462 #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS ( 7 + 2 + ( 4 * 2 ) )
1463 
1464 #define CONFIGURE_MAXIMUM_TASKS 1
1465 
1466 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
1467 
1468 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
1469 
1470 #define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
1471 
1472 #define CONFIGURE_INIT
1473 
1474 #include <rtems/confdefs.h>