A static site generator, written in C
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include <sys/stat.h>
  2. #include <sys/types.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <dirent.h>
  6. #include <errno.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "cms_build.h"
  10. #include "cms_err.h"
  11. #include "cms_files.h"
  12. #include "cms_util.h"
  13. #include "cms_page.h"
  14. #include "cms_post.h"
  15. #include <stdio.h>
  16. cms_err* cms_build_write_files(cms_page* root, char* path)
  17. {
  18. char* dirpath = cms_util_path_join(path, root->slug);
  19. if (dirpath == NULL)
  20. return cms_err_create(CMS_ERR_ALLOC, NULL);
  21. if (mkdir(dirpath, 077) == -1 && errno != EEXIST)
  22. return cms_err_from_std_err(errno);
  23. //Go through each post in the page, writing it to disk
  24. size_t i;
  25. for (i = 0; i < root->numposts; ++i)
  26. {
  27. cms_post post = root->posts[i];
  28. char* postdirpath = cms_util_path_join(dirpath, post.slug);
  29. if (postdirpath == NULL)
  30. return cms_err_create(CMS_ERR_ALLOC, NULL);
  31. if (mkdir(postdirpath, 0777) == -1 && errno != EEXIST)
  32. return cms_err_from_std_err(errno);
  33. char* filepath = cms_util_path_join(postdirpath, CMS_FILE_INDEX);
  34. if (postdirpath == NULL)
  35. return cms_err_create(CMS_ERR_ALLOC, NULL);
  36. int file = open(filepath, O_WRONLY | O_CREAT, 0777);
  37. if (file == -1)
  38. return cms_err_from_std_err(errno);
  39. write(file, post.html, strlen(post.html));
  40. close(file);
  41. free(filepath);
  42. free(postdirpath);
  43. }
  44. //Go through each sub in the page recursively
  45. for (i = 0; i < root->numsubs; ++i)
  46. {
  47. cms_page sub = root->subs[i];
  48. char* subdirpath = cms_util_path_join(dirpath, sub.slug);
  49. if (subdirpath == NULL)
  50. return cms_err_create(CMS_ERR_ALLOC, NULL);
  51. cms_build_write_files(&sub, subdirpath);
  52. free(subdirpath);
  53. }
  54. free(dirpath);
  55. return cms_err_create(CMS_ERR_NONE, NULL);
  56. }
  57. cms_err* cms_build_make_tree(cms_page* root, char* path, char* dirname)
  58. {
  59. struct dirent** namelist;
  60. int n = scandir(path, &namelist, 0, alphasort);
  61. if (n == -1)
  62. return cms_err_from_std_err(errno);
  63. struct dirent* ep;
  64. struct stat* st = malloc(sizeof(struct stat));
  65. if (st == NULL)
  66. return cms_err_create(CMS_ERR_ALLOC, NULL);
  67. for (int i = 0; i < n; ++i)
  68. {
  69. ep = namelist[i];
  70. if (ep->d_name[0] == '.')
  71. continue;
  72. char* entpath = cms_util_path_join(path, ep->d_name);
  73. stat(entpath, st);
  74. //Entry is directory, recurse
  75. if (S_ISDIR(st->st_mode))
  76. {
  77. cms_page* sub = cms_page_create();
  78. if (sub == NULL)
  79. return cms_err_create(CMS_ERR_ALLOC, NULL);
  80. cms_err* err;
  81. err = cms_build_make_tree(sub, entpath, ep->d_name);
  82. if (err)
  83. return err;
  84. err = cms_page_add_sub(root, sub);
  85. if (err)
  86. return err;
  87. }
  88. //Entry is the file which contains metadata
  89. //about a page, parse
  90. else if (strcmp(ep->d_name, CMS_FILE_PAGE) == 0)
  91. {
  92. char* content = cms_util_file_read(entpath);
  93. if (content == NULL)
  94. return cms_err_create(CMS_ERR_FILEREAD, entpath);
  95. cms_err* err = cms_page_parse(root, content, dirname);
  96. free(content);
  97. if (err)
  98. return err;
  99. }
  100. //Entry is a post, read it and add to page
  101. else
  102. {
  103. cms_post* post = cms_post_create();
  104. char* content = cms_util_file_read(entpath);
  105. if (content == NULL)
  106. return cms_err_create(CMS_ERR_FILEREAD, entpath);
  107. cms_err* err;
  108. err = cms_post_parse(post, content, ep->d_name);
  109. free(content);
  110. if (err)
  111. return err;
  112. err = cms_page_add_post(root, post);
  113. if (err)
  114. return err;
  115. }
  116. free(entpath);
  117. }
  118. free(st);
  119. free(namelist);
  120. return cms_err_create(CMS_ERR_NONE, NULL);
  121. }