file.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  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. * See file CREDITS for list of people who contributed to this
  10. * project.
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License as
  14. * published by the Free Software Foundation; either version 2 of
  15. * the License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  25. * MA 02111-1307 USA
  26. */
  27. #include <common.h>
  28. #include <config.h>
  29. #include <malloc.h>
  30. #include <fat.h>
  31. #include <linux/stat.h>
  32. #include <linux/time.h>
  33. #if defined(CONFIG_CMD_FAT)
  34. /* Supported filesystems */
  35. static const struct filesystem filesystems[] = {
  36. { file_fat_detectfs, file_fat_ls, file_fat_read, "FAT" },
  37. };
  38. #define NUM_FILESYS (sizeof(filesystems)/sizeof(struct filesystem))
  39. /* The filesystem which was last detected */
  40. static int current_filesystem = FSTYPE_NONE;
  41. /* The current working directory */
  42. #define CWD_LEN 511
  43. char file_cwd[CWD_LEN+1] = "/";
  44. const char *
  45. file_getfsname(int idx)
  46. {
  47. if (idx < 0 || idx >= NUM_FILESYS) return NULL;
  48. return filesystems[idx].name;
  49. }
  50. static void
  51. pathcpy(char *dest, const char *src)
  52. {
  53. char *origdest = dest;
  54. do {
  55. if (dest-file_cwd >= CWD_LEN) {
  56. *dest = '\0';
  57. return;
  58. }
  59. *(dest) = *(src);
  60. if (*src == '\0') {
  61. if (dest-- != origdest && ISDIRDELIM(*dest)) {
  62. *dest = '\0';
  63. }
  64. return;
  65. }
  66. ++dest;
  67. if (ISDIRDELIM(*src)) {
  68. while (ISDIRDELIM(*src)) src++;
  69. } else {
  70. src++;
  71. }
  72. } while (1);
  73. }
  74. int
  75. file_cd(const char *path)
  76. {
  77. if (ISDIRDELIM(*path)) {
  78. while (ISDIRDELIM(*path)) path++;
  79. strncpy(file_cwd+1, path, CWD_LEN-1);
  80. } else {
  81. const char *origpath = path;
  82. char *tmpstr = file_cwd;
  83. int back = 0;
  84. while (*tmpstr != '\0') tmpstr++;
  85. do {
  86. tmpstr--;
  87. } while (ISDIRDELIM(*tmpstr));
  88. while (*path == '.') {
  89. path++;
  90. while (*path == '.') {
  91. path++;
  92. back++;
  93. }
  94. if (*path != '\0' && !ISDIRDELIM(*path)) {
  95. path = origpath;
  96. back = 0;
  97. break;
  98. }
  99. while (ISDIRDELIM(*path)) path++;
  100. origpath = path;
  101. }
  102. while (back--) {
  103. /* Strip off path component */
  104. while (!ISDIRDELIM(*tmpstr)) {
  105. tmpstr--;
  106. }
  107. if (tmpstr == file_cwd) {
  108. /* Incremented again right after the loop. */
  109. tmpstr--;
  110. break;
  111. }
  112. /* Skip delimiters */
  113. while (ISDIRDELIM(*tmpstr)) tmpstr--;
  114. }
  115. tmpstr++;
  116. if (*path == '\0') {
  117. if (tmpstr == file_cwd) {
  118. *tmpstr = '/';
  119. tmpstr++;
  120. }
  121. *tmpstr = '\0';
  122. return 0;
  123. }
  124. *tmpstr = '/';
  125. pathcpy(tmpstr+1, path);
  126. }
  127. return 0;
  128. }
  129. int
  130. file_detectfs(void)
  131. {
  132. int i;
  133. current_filesystem = FSTYPE_NONE;
  134. for (i = 0; i < NUM_FILESYS; i++) {
  135. if (filesystems[i].detect() == 0) {
  136. strcpy(file_cwd, "/");
  137. current_filesystem = i;
  138. break;
  139. }
  140. }
  141. return current_filesystem;
  142. }
  143. int
  144. file_ls(const char *dir)
  145. {
  146. char fullpath[1024];
  147. const char *arg;
  148. if (current_filesystem == FSTYPE_NONE) {
  149. printf("Can't list files without a filesystem!\n");
  150. return -1;
  151. }
  152. if (ISDIRDELIM(*dir)) {
  153. arg = dir;
  154. } else {
  155. sprintf(fullpath, "%s/%s", file_cwd, dir);
  156. arg = fullpath;
  157. }
  158. return filesystems[current_filesystem].ls(arg);
  159. }
  160. long
  161. file_read(const char *filename, void *buffer, unsigned long maxsize)
  162. {
  163. char fullpath[1024];
  164. const char *arg;
  165. if (current_filesystem == FSTYPE_NONE) {
  166. printf("Can't load file without a filesystem!\n");
  167. return -1;
  168. }
  169. if (ISDIRDELIM(*filename)) {
  170. arg = filename;
  171. } else {
  172. sprintf(fullpath, "%s/%s", file_cwd, filename);
  173. arg = fullpath;
  174. }
  175. return filesystems[current_filesystem].read(arg, buffer, maxsize);
  176. }
  177. #endif