Subversion Repositories Kolibri OS

Rev

Rev 6725 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2. Kolibri OS port for gcc 5.4
  3.  
  4. Started by Siemargl @Nov 2016
  5.  
  6. Contains realisation of directory handling functions:
  7.     mkdir()
  8.     closedir()
  9.     opendir()
  10.     readdir()
  11.     rewinddir()
  12.  
  13.     !!non reentrant
  14. */
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <dirent.h>
  19. #include <errno.h>
  20. #include <sys/stat.h>
  21. #include <assert.h>
  22. #include "kos32sys1.h"
  23.  
  24. /* defined in newlib headers
  25. int     _EXFUN(mkdir,( const char *_path, mode_t __mode ));
  26.  
  27. struct dirent {
  28.   char d_namlen;
  29.   char d_name[256];
  30. };
  31.  
  32. typedef struct
  33. {
  34. //    struct systree_info2 fileinfo;
  35.     struct dirent entry;
  36. //    __u8 bdfeheader[0x20];
  37. //    struct bdfe_item bdfebase;
  38. //    __u8 bdfename[264];
  39. } DIR;
  40.  
  41. int     closedir(DIR *dirp);
  42. DIR *       opendir(const char *_dirname);
  43. struct dirent * readdir(DIR *_dirp);
  44. void      rewinddir(DIR *_dirp);
  45. */
  46.  
  47. static int32_t lastread_block = -1; // non reentrant, must me -1ed in closedir, or will assert
  48. static uint32_t lastread_dir_size;
  49. static DIR  lastread_dir;
  50.  
  51. DIR *opendir(const char *_dirname)
  52. {
  53.     assert(sizeof(struct fs_dirinfo) == 25);  // check struct aligment
  54.     assert(lastread_block == -1);
  55.  
  56.     struct fs_dirinfo di;
  57.     struct fs_dirheader dhead;
  58.  
  59.     memset(&di, 0, sizeof di);
  60.     di.ppath = (char*)_dirname;
  61.     di.retval = (uint32_t)&dhead;
  62.     int rc = sf_file(1, &di);  // read dir size
  63.     if(rc) {
  64.         fprintf(stderr, "Error reading dir size %s\n", _dirname);
  65.         errno = rc;
  66.         return NULL;
  67.     }
  68.     lastread_dir_size = dhead.totl_blocks;
  69.  
  70.     lastread_dir.entry.d_namlen = strlen(_dirname);
  71.     assert (lastread_dir.entry.d_namlen < sizeof(lastread_dir.entry.d_name));
  72.     strcpy(lastread_dir.entry.d_name, _dirname);
  73.  
  74.     return &lastread_dir;
  75. };
  76.  
  77.  
  78. int closedir(DIR *dirp)
  79. {
  80.     assert (lastread_block != -1);  // was opened
  81.  
  82.     if (!dirp || lastread_block == -1)
  83.     {
  84.         errno = EBADF;
  85.         return -1;
  86.     }
  87.     lastread_block = -1;
  88.     lastread_dir_size = 0;
  89.     lastread_dir.entry.d_namlen = 0;
  90.     lastread_dir.entry.d_name[0] = '\0';
  91.  
  92.     return 0;
  93. };
  94.  
  95.  
  96. struct dirent* readdir(DIR *dirp)
  97. {
  98.     assert (lastread_block != -1);  // was opened
  99.  
  100.     if (!dirp || lastread_block == -1)
  101.     {
  102.         errno = EBADF;
  103.         return NULL;
  104.     }
  105.     struct fs_dirinfo di;
  106.  
  107.     assert (lastread_block != -1);  // was opened
  108.  
  109.     char retdir[sizeof(struct fs_dirheader) + sizeof(struct fsBDFE)];   // 1 block w/cp866 encoding
  110.     struct fsBDFE *bdfe = (struct fsBDFE *)(retdir + sizeof(struct fs_dirheader));
  111.     memset(&di, 0, sizeof di);
  112.     di.ppath = dirp->entry.d_name;
  113.     di.retval = (uint32_t)retdir;
  114.     di.start = lastread_block;
  115.     di.size = 1;
  116.  
  117.     int rc = sf_file(1, &di);  // read dir
  118.     if(rc) {
  119.         fprintf(stderr, "Error %d reading dir item %s\n", rc, dirp->entry.d_name);
  120.         errno = rc;
  121.         return NULL;
  122.     }
  123.  
  124.     static struct dirent ent;
  125.     ent.d_namlen = strlen(bdfe->fname);
  126.     assert (ent.d_namlen < sizeof(ent.d_name));
  127.     strcpy(ent.d_name, bdfe->fname);
  128.     lastread_block++;
  129.  
  130.     return &ent;
  131. };
  132.  
  133.  
  134. void rewinddir(DIR *dirp)
  135. {
  136.     if (!dirp || lastread_block == -1)
  137.     {
  138.         return;
  139.     }
  140.  
  141.     lastread_block = 0;
  142. }
  143.  
  144.  
  145. int     mkdir(const char *_path, mode_t m)
  146. {
  147.     char   namebuffer[1050]; // need for save data after di!!!
  148.     struct fs_dirinfo *di = (struct fs_dirinfo *)namebuffer;
  149.  
  150. debug_board_printf("mkdir start (%s)\n", _path);
  151.     memset(di, 0, sizeof(struct fs_dirinfo));
  152.     //di.ppath = (char*)_path;  // dont work with 70.9
  153.     strcpy(di->path, _path);
  154.  
  155.     int rc = sf_file(9, di);  // creat dir
  156.     if(rc) {
  157.         fprintf(stderr, "Error %d creating dir item %s\n", rc, _path);
  158.         errno = rc;
  159.         return -1;
  160.     }
  161.  
  162. debug_board_printf("mkdir end (%s)\n", _path);
  163.     return 0;
  164. }
  165.  
  166. ////////////////////////////////////////////////////////////////////////////////////////
  167. void __attribute__ ((noinline)) debug_board_write_str(const char* str){
  168.   while(*str)
  169.     debug_board_write_byte(*str++);
  170. }
  171.  
  172. void __attribute__ ((noinline)) debug_board_printf(const char *format,...)
  173. {
  174.         va_list ap;
  175.         char log_board[300];
  176.  
  177.         va_start (ap, format);
  178.         vsnprintf(log_board, sizeof log_board, format, ap);
  179.         va_end(ap);
  180.         debug_board_write_str(log_board);
  181. }
  182.  
  183. __attribute__ ((noinline)) void trap(int n)
  184. {
  185.     // nothing todo, just see n in debugger. use "bp trap" command
  186.     __asm__ __volatile__(
  187.     "nop"
  188.     :
  189.     :"a"(n));
  190. }
  191.  
  192.  
  193.  
  194. /* tested example
  195. void* read_folderdata(char* name)
  196. {
  197.     struct fs_dirinfo di;
  198.     struct fs_dirheader dhead;
  199.     assert(sizeof di == 25);
  200.  
  201.     memset(&di, 0, sizeof di);
  202.     di.ppath = name;
  203.     di.retval = (uint32_t)&dhead;
  204.     int rc = sf_file(1, &di);  // read dir size
  205.     if(rc) {
  206.         debug_board_printf("Error reading dir size %s", name);
  207.         exit(1);
  208.     }
  209.     di.size = dhead.totl_blocks;
  210.  
  211.     char *retdir = malloc(sizeof dhead + dhead.totl_blocks * sizeof(struct fsBDFE));
  212.     if(!retdir) {
  213.         debug_board_printf("No memory for dir %s", name);
  214.         exit(1);
  215.     }
  216.     di.retval = (uint32_t)retdir;
  217.     rc = sf_file(1, &di);  // read dir
  218.     if(rc) {
  219.         debug_board_printf("Error 2 reading dir size %s", name);
  220.         exit(1);
  221.     }
  222.  
  223.     // manual clear mark flag (random junk in fname free space)
  224.     int i;
  225.     for (i = 0; i < dhead.totl_blocks; i++)
  226.         ((struct fsBDFE*)(retdir+32))[i].fname[259] = 0;
  227.  
  228.     debug_board_printf("Loaded dir [%s] etnries %d,\n first file [%s]\n", name, ((struct fs_dirheader*)(retdir))->curn_blocks, ((struct fsBDFE*)(retdir+32))->fname);
  229.  
  230.     return retdir;
  231. }
  232. */
  233.