logo

rc-status-page

Unnamed repository; edit this file 'description' to name the repository.

rc-status-page.c (2739B)


  1. // rc-status-page: Basic HTML status page based on OpenRC
  2. // Copyright © 2022 Haelwenn (lanodan) Monnier <contact+rc-status-page@hacktivis.me>
  3. // SPDX-License-Identifier: BSD-2-Clause
  4. #include <sys/queue.h> /* TAILQ_FOREACH() */
  5. #include <rc.h> /* rc_ / RC_ */
  6. #include <stdlib.h> /* printf */
  7. #include <errno.h> /* errno */
  8. #include <time.h> /* time(), gmtime(), strftime() */
  9. static RC_DEPTREE *deptree;
  10. static RC_STRINGLIST *types;
  11. RC_STRINGLIST *levels, *services;
  12. static void
  13. print_service(const char *service)
  14. {
  15. RC_SERVICE state = rc_service_state(service);
  16. char *status;
  17. if(state & RC_SERVICE_STOPPING) {
  18. status = "stopping";
  19. } else if(state & RC_SERVICE_STARTING) {
  20. status = "starting";
  21. } else if(state & RC_SERVICE_INACTIVE) {
  22. status = "inactive";
  23. } else if(state & RC_SERVICE_SCHEDULED) {
  24. status = "scheduled";
  25. } else if(state & RC_SERVICE_STARTED) {
  26. errno = 0;
  27. if (rc_service_daemons_crashed(service) && errno != EACCES) {
  28. status = "crashed";
  29. } else {
  30. status = "started";
  31. }
  32. } else {
  33. status = "stopped";
  34. }
  35. printf("\t<dt class=\"service-name\">%s</dt><dd class=\"service-%s\">%s</dd>\n", service, status, status);
  36. }
  37. static void
  38. print_services(const char *runlevel, RC_STRINGLIST *svcs)
  39. {
  40. RC_STRINGLIST *l = NULL;
  41. RC_STRING *s;
  42. char *r = NULL;
  43. if (!svcs) { return; }
  44. if (!deptree) { deptree = rc_deptree_load(); }
  45. if (!types) {
  46. types = rc_stringlist_new();
  47. rc_stringlist_add(types, "ineed");
  48. rc_stringlist_add(types, "iuse");
  49. rc_stringlist_add(types, "iafter");
  50. }
  51. if (!runlevel) { r = rc_runlevel_get(); }
  52. l = rc_deptree_depends(deptree, types, svcs, r ? r : runlevel, RC_DEP_STRICT | RC_DEP_TRACE | RC_DEP_START);
  53. free(r);
  54. if (!l) return;
  55. printf("<dl class=\"services\">\n");
  56. TAILQ_FOREACH(s, l, entries) {
  57. if (!rc_stringlist_find(svcs, s->value)) continue;
  58. if (!runlevel || rc_service_in_runlevel(s->value, runlevel)) print_service(s->value);
  59. }
  60. rc_stringlist_free(l);
  61. printf("</dl>\n");
  62. }
  63. int
  64. main() {
  65. RC_STRING *l;
  66. char timestamp[BUFSIZ];
  67. time_t now = time(NULL);
  68. struct tm *tm = gmtime(&now);
  69. static char *title = "Status page of hacktivis.me";
  70. strftime(timestamp, sizeof(timestamp), "%FT%TZ", tm);
  71. levels = rc_stringlist_new();
  72. rc_stringlist_add(levels, "hacktivism");
  73. printf("<html><head><link rel=stylesheet href=\"rc-status-page.css\"/><title>%s</title></head>\n", title);
  74. printf("<h1>%s</h1>\n", title);
  75. TAILQ_FOREACH(l, levels, entries) {
  76. services = rc_services_in_runlevel(l->value);
  77. print_services(l->value, services);
  78. }
  79. printf("<footer>Generated by <a href=\"https://hacktivis.me/git/rc-status-page\">rc-status-page</a> at %s</footer>", timestamp);
  80. printf("</body></html>\n");
  81. rc_stringlist_free(levels);
  82. return 0;
  83. }