file.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * file.c
  3. *
  4. * Mini "VFS" by Marcus Sundberg
  5. *
  6. * 2002-07-28 - rjones@nexus-tech.net - ported to ppcboot v1.1.6
  7. * 2003-03-10 - kharris@nexus-tech.net - ported to uboot
  8. *
  9. * SPDX-License-Identifier: GPL-2.0+
  10. */
  11. #include <common.h>
  12. #include <config.h>
  13. #include <malloc.h>
  14. #include <fat.h>
  15. #include <linux/stat.h>
  16. #include <linux/time.h>
  17. /* Supported filesystems */
  18. static const struct filesystem filesystems[] = {
  19. { file_fat_detectfs, file_fat_ls, file_fat_read, "FAT" },
  20. };
  21. #define NUM_FILESYS (sizeof(filesystems)/sizeof(struct filesystem))
  22. /* The filesystem which was last detected */
  23. static int current_filesystem = FSTYPE_NONE;
  24. /* The current working directory */
  25. #define CWD_LEN 511
  26. char file_cwd[CWD_LEN+1] = "/";
  27. const char *
  28. file_getfsname(int idx)
  29. {
  30. if (idx < 0 || idx >= NUM_FILESYS)
  31. return NULL;
  32. return filesystems[idx].name;
  33. }
  34. static void
  35. pathcpy(char *dest, const char *src)
  36. {
  37. char *origdest = dest;
  38. do {
  39. if (dest-file_cwd >= CWD_LEN) {
  40. *dest = '\0';
  41. return;
  42. }
  43. *(dest) = *(src);
  44. if (*src == '\0') {
  45. if (dest-- != origdest && ISDIRDELIM(*dest)) {
  46. *dest = '\0';
  47. }
  48. return;
  49. }
  50. ++dest;
  51. if (ISDIRDELIM(*src))
  52. while (ISDIRDELIM(*src)) src++;
  53. else
  54. src++;
  55. } while (1);
  56. }
  57. int
  58. file_cd(const char *path)
  59. {
  60. if (ISDIRDELIM(*path)) {
  61. while (ISDIRDELIM(*path)) path++;
  62. strncpy(file_cwd+1, path, CWD_LEN-1);
  63. } else {
  64. const char *origpath = path;
  65. char *tmpstr = file_cwd;
  66. int back = 0;
  67. while (*tmpstr != '\0') tmpstr++;
  68. do {
  69. tmpstr--;
  70. } while (ISDIRDELIM(*tmpstr));
  71. while (*path == '.') {
  72. path++;
  73. while (*path == '.') {
  74. path++;
  75. back++;
  76. }
  77. if (*path != '\0' && !ISDIRDELIM(*path)) {
  78. path = origpath;
  79. back = 0;
  80. break;
  81. }
  82. while (ISDIRDELIM(*path)) path++;
  83. origpath = path;
  84. }
  85. while (back--) {
  86. /* Strip off path component */
  87. while (!ISDIRDELIM(*tmpstr)) {
  88. tmpstr--;
  89. }
  90. if (tmpstr == file_cwd) {
  91. /* Incremented again right after the loop. */
  92. tmpstr--;
  93. break;
  94. }
  95. /* Skip delimiters */
  96. while (ISDIRDELIM(*tmpstr)) tmpstr--;
  97. }
  98. tmpstr++;
  99. if (*path == '\0') {
  100. if (tmpstr == file_cwd) {
  101. *tmpstr = '/';
  102. tmpstr++;
  103. }
  104. *tmpstr = '\0';
  105. return 0;
  106. }
  107. *tmpstr = '/';
  108. pathcpy(tmpstr+1, path);
  109. }
  110. return 0;
  111. }
  112. int
  113. file_detectfs(void)
  114. {
  115. int i;
  116. current_filesystem = FSTYPE_NONE;
  117. for (i = 0; i < NUM_FILESYS; i++) {
  118. if (filesystems[i].detect() == 0) {
  119. strcpy(file_cwd, "/");
  120. current_filesystem = i;
  121. break;
  122. }
  123. }
  124. return current_filesystem;
  125. }
  126. int
  127. file_ls(const char *dir)
  128. {
  129. char fullpath[1024];
  130. const char *arg;
  131. if (current_filesystem == FSTYPE_NONE) {
  132. printf("Can't list files without a filesystem!\n");
  133. return -1;
  134. }
  135. if (ISDIRDELIM(*dir)) {
  136. arg = dir;
  137. } else {
  138. sprintf(fullpath, "%s/%s", file_cwd, dir);
  139. arg = fullpath;
  140. }
  141. return filesystems[current_filesystem].ls(arg);
  142. }
  143. int file_read(const char *filename, void *buffer, int maxsize)
  144. {
  145. char fullpath[1024];
  146. const char *arg;
  147. if (current_filesystem == FSTYPE_NONE) {
  148. printf("Can't load file without a filesystem!\n");
  149. return -1;
  150. }
  151. if (ISDIRDELIM(*filename)) {
  152. arg = filename;
  153. } else {
  154. sprintf(fullpath, "%s/%s", file_cwd, filename);
  155. arg = fullpath;
  156. }
  157. return filesystems[current_filesystem].read(arg, buffer, maxsize);
  158. }