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.

cms_util.c 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #include <fcntl.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <stddef.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include <dirent.h>
  8. #include <sys/stat.h>
  9. #include <sys/types.h>
  10. #include <errno.h>
  11. #include "cms_util.h"
  12. #include "cms_err.h"
  13. #include <stdio.h>
  14. int cms_util_file_exists(char* fname)
  15. {
  16. int f = open(fname, O_RDONLY);
  17. //The file doesn't exist if the open command returned the ENOENT error.
  18. if (f == -1 && errno == ENOENT)
  19. return 0;
  20. //If the open command succeeded, we want to close the file descriptor.
  21. else if (f != -1)
  22. close(f);
  23. return 1;
  24. }
  25. cms_err* cms_util_file_create(char* fname)
  26. {
  27. int f = open(fname, O_CREAT, 0777);
  28. close(f);
  29. if (f == -1)
  30. return cms_err_from_std_err(errno);
  31. else
  32. return cms_err_create(CMS_ERR_NONE, NULL);
  33. }
  34. cms_err* cms_util_file_copy(char* fname1, char* fname2)
  35. {
  36. int f1 = open(fname1, O_RDONLY);
  37. if (f1 == -1)
  38. return cms_err_from_std_err(errno);
  39. int f2 = open(fname2, O_WRONLY | O_CREAT, 0777);
  40. if (f1 == -1)
  41. return cms_err_from_std_err(errno);
  42. struct stat* st = malloc(sizeof(struct stat));
  43. if (st == NULL)
  44. return cms_err_create(CMS_ERR_ALLOC, NULL);
  45. fstat(f1, st);
  46. void* buf = malloc(st->st_size);
  47. if (buf == NULL)
  48. return cms_err_create(CMS_ERR_ALLOC, NULL);
  49. read(f1, buf, st->st_size);
  50. write(f2, buf, st->st_size);
  51. close(f1);
  52. close(f2);
  53. free(st);
  54. free(buf);
  55. return cms_err_create(CMS_ERR_NONE, NULL);
  56. }
  57. char* cms_util_file_read(char* fname)
  58. {
  59. int file = open(fname, O_RDONLY);
  60. if (file == -1)
  61. return NULL;
  62. struct stat* st = malloc(sizeof(struct stat));
  63. if (st == NULL)
  64. return NULL;
  65. fstat(file, st);
  66. char* buf = malloc(st->st_size + 1);
  67. if (buf == NULL)
  68. return NULL;
  69. read(file, buf, st->st_size + 1);
  70. buf[st->st_size] = '\0';
  71. close(file);
  72. free(st);
  73. return buf;
  74. }
  75. cms_err* cms_util_dir_copy_recursive(char* dir1, char* dir2)
  76. {
  77. if (mkdir(dir2, 0777) == -1 && errno != EEXIST)
  78. return cms_err_from_std_err(errno);
  79. DIR* dp = opendir(dir1);
  80. if (dp == NULL)
  81. return cms_err_from_std_err(errno);
  82. struct dirent* ep;
  83. struct stat* st = malloc(sizeof(struct stat));
  84. if (st == NULL)
  85. return cms_err_create(CMS_ERR_ALLOC, NULL);
  86. while ((ep = readdir(dp)) != NULL)
  87. {
  88. if (ep->d_name[0] == '.')
  89. continue;
  90. char* path1 = cms_util_path_join(dir1, ep->d_name);
  91. char* path2 = cms_util_path_join(dir2, ep->d_name);
  92. if (stat(path1, st) == -1)
  93. return cms_err_from_std_err(errno);
  94. if (S_ISDIR(st->st_mode))
  95. {
  96. cms_err* err = cms_util_dir_copy_recursive(path1, path2);
  97. free(path1);
  98. free(path2);
  99. if (err)
  100. return err;
  101. }
  102. else
  103. {
  104. cms_err* err = cms_util_file_copy(path1, path2);
  105. free(path1);
  106. free(path2);
  107. if (err)
  108. return err;
  109. }
  110. }
  111. closedir(dp);
  112. free(st);
  113. return cms_err_create(CMS_ERR_NONE, NULL);
  114. }
  115. char* cms_util_path_join(char* str1, char* str2)
  116. {
  117. if (str1 == NULL || str2 == NULL)
  118. return NULL;
  119. size_t len1 = strlen(str1);
  120. size_t len2 = strlen(str2);
  121. if (str1[len1 - 1] == '/')
  122. {
  123. len1 -= 1;
  124. }
  125. char* path = malloc((len1 + len2 + 2) * sizeof(char));
  126. if (path == NULL)
  127. cms_err_panic(cms_err_create(CMS_ERR_ALLOC, NULL));
  128. if (path == NULL)
  129. return NULL;
  130. memcpy(path, str1, len1); //First part
  131. path[len1] = '/'; //Separator
  132. memcpy(path + len1 + 1, str2, len2); //Second part
  133. path[len1 + len2 + 1] = '\0'; //Null terminator
  134. return path;
  135. }