sitemap_cgi.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (c) 2018 Markus Hennecke <markus-hennecke@markus-hennecke.de>
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <sys/types.h>
  17. #include <err.h>
  18. #include <stdarg.h>
  19. #include <stdint.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <unistd.h>
  24. #include "filehelper.h"
  25. #include "sitemap.h"
  26. #ifndef CMS_CONTENT_DIR
  27. #error "Need CMS_CONTENT_DIR defined to compile"
  28. #endif
  29. #ifndef CMS_HOSTNAME
  30. #error "Need CMS_HOSTNAME defined to compile"
  31. #endif
  32. enum page {
  33. PAGE_SITEMAP,
  34. PAGE_SITEMAP_GZ,
  35. PAGE__MAX
  36. };
  37. const char *const pages[PAGE__MAX] = {
  38. "/sitemap.xml", /* PAGE_SITEMAP */
  39. "/sitemap.xml.gz", /* PAGE_SITEMAP_GZ */
  40. };
  41. static __dead void usage(void);
  42. __dead void
  43. usage(void)
  44. {
  45. extern char *__progname;
  46. dprintf(STDERR_FILENO, "usage: %s CMS_ROOT\n", __progname);
  47. exit(1);
  48. }
  49. int
  50. main(int argc, char **argv)
  51. {
  52. size_t size;
  53. char *out;
  54. size_t page = PAGE__MAX;
  55. int fd = STDOUT_FILENO;
  56. char *cms_root = CMS_CONTENT_DIR;
  57. if (argc > 2)
  58. usage();
  59. if (argc == 2) {
  60. if (argv[1][0] == '\0')
  61. errx(1, "Require abolute path as argument");
  62. cms_root = argv[1];
  63. }
  64. char *path_info = getenv("PATH_INFO");
  65. if (path_info == NULL || strlen(path_info) == 0) {
  66. page = 0;
  67. } else {
  68. for (page = 0; page < PAGE__MAX; ++page)
  69. if (strcmp(pages[page], path_info) == 0)
  70. break;
  71. }
  72. struct sitemap *sitemap = sitemap_new(cms_root, CMS_HOSTNAME);
  73. uint32_t mtime = sitemap_newest(sitemap, NULL);
  74. switch (page) {
  75. default:
  76. case PAGE_SITEMAP:
  77. out = sitemap_toxml(sitemap);
  78. size = strlen(out);
  79. break;
  80. case PAGE_SITEMAP_GZ:
  81. out = sitemap_toxmlgz(sitemap, &size, "sitemap.xml", mtime);
  82. break;
  83. }
  84. dprintf(fd, "Status: 200 OK\r\n");
  85. dprintf(fd, "Content-length: %zu\r\n", size);
  86. dprintf(fd, "Content-type: application/xml\r\n");
  87. if (page == PAGE_SITEMAP_GZ)
  88. dprintf(fd, "Content-encoding: x-gzip\r\n");
  89. dprintf(fd, "\r\n");
  90. write(fd, out, size);
  91. free(out);
  92. return EXIT_SUCCESS;
  93. }