fs.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. fs.c -- File System support and support for ROM-based file systems.
  3. Copyright (c) All Rights Reserved. See details at the end of the file.
  4. */
  5. /********************************* Includes ***********************************/
  6. #include "goahead.h"
  7. /******************************** Local Data **********************************/
  8. #if ME_ROM
  9. /*
  10. Symbol table for web pages and files
  11. */
  12. static WebsHash romFs;
  13. static WebsRomIndex *lookup(WebsHash fs, char *path);
  14. #endif
  15. /*********************************** Code *************************************/
  16. PUBLIC int websFsOpen(void)
  17. {
  18. #if ME_ROM
  19. WebsRomIndex *wip;
  20. char name[ME_GOAHEAD_LIMIT_FILENAME];
  21. ssize len;
  22. error("---> websFsOpen, ME_ROM\n");
  23. romFs = hashCreate(WEBS_HASH_INIT);
  24. for (wip = websRomIndex; wip->path; wip++) {
  25. strncpy(name, wip->path, ME_GOAHEAD_LIMIT_FILENAME);
  26. len = strlen(name) - 1;
  27. if (len > 0 && (name[len] == '/' || name[len] == '\\')) {
  28. name[len] = '\0';
  29. }
  30. hashEnter(romFs, name, valueSymbol(wip), 0);
  31. }
  32. #endif
  33. return 0;
  34. }
  35. PUBLIC void websFsClose(void)
  36. {
  37. #if ME_ROM
  38. hashFree(romFs);
  39. #endif
  40. }
  41. PUBLIC int websOpenFile(cchar *path, int flags, int mode)
  42. {
  43. #if ME_ROM
  44. WebsRomIndex *wip;
  45. if ((wip = lookup(romFs, path)) == NULL) {
  46. return -1;
  47. }
  48. wip->pos = 0;
  49. return (int) (wip - websRomIndex);
  50. #else
  51. return open(path, flags, mode);
  52. #endif
  53. }
  54. PUBLIC void websCloseFile(int fd)
  55. {
  56. #if !ME_ROM
  57. if (fd >= 0) {
  58. close(fd);
  59. }
  60. #endif
  61. }
  62. PUBLIC int websStatFile(cchar *path, WebsFileInfo *sbuf)
  63. {
  64. #if ME_ROM
  65. WebsRomIndex *wip;
  66. assert(path && *path);
  67. if ((wip = lookup(romFs, path)) == NULL) {
  68. return -1;
  69. }
  70. memset(sbuf, 0, sizeof(WebsFileInfo));
  71. sbuf->size = wip->size;
  72. #if ME_ROM_TIME
  73. sbuf->mtime = ME_ROM_TIME;
  74. #else
  75. sbuf->mtime = 1;
  76. #endif
  77. if (wip->page == NULL) {
  78. sbuf->isDir = 1;
  79. }
  80. return 0;
  81. #else
  82. WebsStat s;
  83. int rc;
  84. #if ME_WIN_LIKE
  85. {
  86. ssize len = slen(path) - 1;
  87. char *p = sclone(path);
  88. if (p[len] == '/') {
  89. p[len] = '\0';
  90. } else if (p[len] == '\\') {
  91. p[len] = '\0';
  92. }
  93. rc = stat(p, &s);
  94. wfree(p);
  95. }
  96. #else
  97. rc = stat(path, &s);
  98. #endif
  99. if (rc < 0) {
  100. return -1;
  101. }
  102. sbuf->size = (ssize) s.st_size;
  103. sbuf->mtime = s.st_mtime;
  104. sbuf->isDir = s.st_mode & S_IFDIR;
  105. return 0;
  106. #endif
  107. }
  108. PUBLIC ssize websReadFile(int fd, char *buf, ssize size)
  109. {
  110. #if ME_ROM
  111. WebsRomIndex *wip;
  112. ssize len;
  113. assert(buf);
  114. assert(fd >= 0);
  115. wip = &websRomIndex[fd];
  116. len = min(wip->size - wip->pos, size);
  117. memcpy(buf, &wip->page[wip->pos], len);
  118. wip->pos += len;
  119. return len;
  120. #else
  121. return read(fd, buf, (uint) size);
  122. #endif
  123. }
  124. PUBLIC char *websReadWholeFile(cchar *path)
  125. {
  126. WebsFileInfo sbuf;
  127. char *buf;
  128. int fd;
  129. if (websStatFile(path, &sbuf) < 0) {
  130. return 0;
  131. }
  132. buf = walloc(sbuf.size + 1);
  133. if ((fd = websOpenFile(path, O_RDONLY, 0)) < 0) {
  134. wfree(buf);
  135. return 0;
  136. }
  137. websReadFile(fd, buf, sbuf.size);
  138. buf[sbuf.size] = '\0';
  139. websCloseFile(fd);
  140. return buf;
  141. }
  142. Offset websSeekFile(int fd, Offset offset, int origin)
  143. {
  144. #if ME_ROM
  145. WebsRomIndex *wip;
  146. Offset pos;
  147. assert(origin == SEEK_SET || origin == SEEK_CUR || origin == SEEK_END);
  148. assert(fd >= 0);
  149. wip = &websRomIndex[fd];
  150. if (origin != SEEK_SET && origin != SEEK_CUR && origin != SEEK_END) {
  151. errno = EINVAL;
  152. return -1;
  153. }
  154. if (fd < 0) {
  155. errno = EBADF;
  156. return -1;
  157. }
  158. pos = offset;
  159. switch (origin) {
  160. case SEEK_CUR:
  161. pos = wip->pos + offset;
  162. break;
  163. case SEEK_END:
  164. pos = wip->size + offset;
  165. break;
  166. default:
  167. break;
  168. }
  169. if (pos < 0) {
  170. errno = EBADF;
  171. return -1;
  172. }
  173. return (wip->pos = pos);
  174. #else
  175. return lseek(fd, (long) offset, origin);
  176. #endif
  177. }
  178. PUBLIC ssize websWriteFile(int fd, cchar *buf, ssize size)
  179. {
  180. #if ME_ROM
  181. error("Cannot write to a rom file system");
  182. return -1;
  183. #else
  184. return write(fd, buf, (uint) size);
  185. #endif
  186. }
  187. #if ME_ROM
  188. static WebsRomIndex *lookup(WebsHash fs, char *path)
  189. {
  190. WebsKey *sp;
  191. ssize len;
  192. if ((sp = hashLookup(fs, path)) == NULL) {
  193. if (path[0] != '/') {
  194. path = sfmt("/%s", path);
  195. } else {
  196. path = sclone(path);
  197. }
  198. len = slen(path) - 1;
  199. if (path[len] == '/') {
  200. path[len] = '\0';
  201. }
  202. if ((sp = hashLookup(fs, path)) == NULL) {
  203. wfree(path);
  204. return 0;
  205. }
  206. wfree(path);
  207. }
  208. return (WebsRomIndex*) sp->content.value.symbol;
  209. }
  210. #endif
  211. /*
  212. Copyright (c) Embedthis Software. All Rights Reserved.
  213. This software is distributed under commercial and open source licenses.
  214. You may use the Embedthis GoAhead open source license or you may acquire
  215. a commercial license from Embedthis Software. You agree to be fully bound
  216. by the terms of either license. Consult the LICENSE.md distributed with
  217. this software for full details and other copyrights.
  218. */