fs.c 5.1 KB

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