main.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2021 Felix Fietkau <nbd@nbd.name>
  4. */
  5. #include <sys/wait.h>
  6. #include <stdio.h>
  7. #include <unistd.h>
  8. #include <stdint.h>
  9. #include <libubox/uloop.h>
  10. #include "qosify.h"
  11. static int usage(const char *progname)
  12. {
  13. fprintf(stderr, "Usage: %s [options]\n"
  14. "Options:\n"
  15. " -l <file> Load defaults from <file>\n"
  16. " -o only load program/maps without running as daemon\n"
  17. "\n", progname);
  18. return 1;
  19. }
  20. int qosify_run_cmd(char *cmd, bool ignore_error)
  21. {
  22. char *argv[] = { "sh", "-c", cmd, NULL };
  23. bool first = true;
  24. int status = -1;
  25. char buf[512];
  26. int fds[2];
  27. FILE *f;
  28. int pid;
  29. if (pipe(fds))
  30. return -1;
  31. pid = fork();
  32. if (!pid) {
  33. close(fds[0]);
  34. if (fds[1] != STDOUT_FILENO)
  35. dup2(fds[1], STDOUT_FILENO);
  36. if (fds[1] != STDERR_FILENO)
  37. dup2(fds[1], STDERR_FILENO);
  38. if (fds[1] > STDERR_FILENO)
  39. close(fds[1]);
  40. execv("/bin/sh", argv);
  41. exit(1);
  42. }
  43. if (pid < 0)
  44. return -1;
  45. close(fds[1]);
  46. f = fdopen(fds[0], "r");
  47. if (!f) {
  48. close(fds[0]);
  49. goto out;
  50. }
  51. while (fgets(buf, sizeof(buf), f) != NULL) {
  52. if (!strlen(buf))
  53. break;
  54. if (ignore_error)
  55. continue;
  56. if (first) {
  57. ULOG_WARN("Command: %s\n", cmd);
  58. first = false;
  59. }
  60. ULOG_WARN("%s%s", buf, strchr(buf, '\n') ? "" : "\n");
  61. }
  62. fclose(f);
  63. out:
  64. while (waitpid(pid, &status, 0) < 0)
  65. if (errno != EINTR)
  66. break;
  67. return status;
  68. }
  69. int main(int argc, char **argv)
  70. {
  71. const char *load_file = NULL;
  72. bool oneshot = false;
  73. int ch;
  74. while ((ch = getopt(argc, argv, "fl:o")) != -1) {
  75. switch (ch) {
  76. case 'f':
  77. break;
  78. case 'l':
  79. load_file = optarg;
  80. break;
  81. case 'o':
  82. oneshot = true;
  83. break;
  84. default:
  85. return usage(argv[0]);
  86. }
  87. }
  88. if (qosify_loader_init())
  89. return 2;
  90. if (qosify_map_init())
  91. return 2;
  92. if (qosify_map_load_file(load_file))
  93. return 2;
  94. if (oneshot)
  95. return 0;
  96. ulog_open(ULOG_SYSLOG, LOG_DAEMON, "qosify");
  97. uloop_init();
  98. if (qosify_ubus_init() ||
  99. qosify_iface_init())
  100. return 2;
  101. qosify_dns_init();
  102. uloop_run();
  103. qosify_ubus_stop();
  104. qosify_iface_stop();
  105. uloop_done();
  106. return 0;
  107. }