main.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <sys/socket.h>
  5. #include <sys/un.h>
  6. #include <sys/wait.h>
  7. #include "util.h"
  8. #include "postprocess.h"
  9. static char socket_path[100];
  10. struct Job {
  11. pid_t pid;
  12. char burstdir[255];
  13. char target[255];
  14. int keep;
  15. };
  16. pid_t
  17. start_processing(struct Job job)
  18. {
  19. pid_t child_pid = fork();
  20. if (child_pid < 0) {
  21. err("fork failed");
  22. } else if (child_pid > 0) {
  23. // parent process
  24. return child_pid;
  25. } else {
  26. // child process
  27. postprocess_internal(job.burstdir, job.target, 1);
  28. exit(0);
  29. }
  30. return -1;
  31. }
  32. int
  33. listen_on_socket()
  34. {
  35. int sock;
  36. struct sockaddr_un addr;
  37. // Clean existing socket
  38. if (remove(socket_path) == -1 && errno != ENOENT) {
  39. err("could not clean up old socket");
  40. }
  41. // Make new unix domain socket to listen on
  42. sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
  43. if (sock < 0) {
  44. err("could not make socket fd");
  45. return 0;
  46. }
  47. memset(&addr, 0, sizeof(struct sockaddr_un));
  48. addr.sun_family = AF_UNIX;
  49. strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
  50. if (bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) < 0) {
  51. err("failed to bind socket");
  52. return 0;
  53. }
  54. if (listen(sock, 20) < 0) {
  55. err("failed to listen");
  56. return 0;
  57. }
  58. return sock;
  59. }
  60. int
  61. queue_job(struct Job job)
  62. {
  63. int sock;
  64. struct sockaddr_un addr;
  65. sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
  66. if (sock < 0) {
  67. err("could not make socket fd");
  68. return 0;
  69. }
  70. memset(&addr, 0, sizeof(struct sockaddr_un));
  71. addr.sun_family = AF_UNIX;
  72. strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
  73. if (connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) < 0) {
  74. err("failed to open socket");
  75. return 0;
  76. }
  77. if (write(sock, &job, sizeof(job)) < 0) {
  78. err("failed to write");
  79. return 0;
  80. }
  81. close(sock);
  82. return 1;
  83. }
  84. int
  85. listen_and_convert(int do_fork)
  86. {
  87. int sock, fd;
  88. struct sockaddr_un cli_addr;
  89. unsigned int clilen;
  90. struct Job job;
  91. if (do_fork == 1) {
  92. pid_t child_pid = fork();
  93. if (child_pid < 0) {
  94. err("fork failed");
  95. } else if (child_pid > 0) {
  96. usleep(1000000);
  97. // parent process
  98. return 1;
  99. }
  100. }
  101. clilen = sizeof(cli_addr);
  102. postprocess_setup();
  103. sock = listen_on_socket();
  104. while(1) {
  105. fd = accept(sock, (struct sockaddr *)&cli_addr, &clilen);
  106. if (fd < 0) {
  107. err("failed to accept");
  108. return 0;
  109. }
  110. if(read(fd, &job, sizeof(job)) < 0) {
  111. err("failed to read");
  112. return 0;
  113. }
  114. close(fd);
  115. start_processing(job);
  116. wait(NULL);
  117. }
  118. }
  119. void
  120. make_socket_path()
  121. {
  122. char fname[80];
  123. char *xdg_runtime_dir = getenv("XDG_RUNTIME_DIR");
  124. char *user = getenv("USER");
  125. snprintf(fname, sizeof(fname), "postprocessd-%s.sock", user);
  126. if (xdg_runtime_dir) {
  127. snprintf(socket_path, sizeof(socket_path), "%s/%s", xdg_runtime_dir, fname);
  128. } else {
  129. snprintf(socket_path, sizeof(socket_path), "/tmp/%s", fname);
  130. }
  131. }
  132. int
  133. main(int argc, char *argv[])
  134. {
  135. struct Job job;
  136. make_socket_path();
  137. if (argc == 4) {
  138. // Parse command line arguments into the job struct
  139. job.pid = 0;
  140. strncpy(job.burstdir, argv[1], sizeof(job.burstdir));
  141. strncpy(job.target, argv[2], sizeof(job.target));
  142. if (strcmp(argv[3], "0") == 0) {
  143. job.keep = 0;
  144. } else {
  145. job.keep = 1;
  146. }
  147. if(queue_job(job)) return 0;
  148. if(listen_and_convert(1))
  149. queue_job(job);
  150. } else if (argc == 2) {
  151. if (strcmp(argv[1], "--daemon") == 0) {
  152. listen_and_convert(0);
  153. }
  154. } else {
  155. printf("usage: %s burst-dir target-name keep\n", argv[0]);
  156. exit(1);
  157. }
  158. if(listen_and_convert(1))
  159. queue_job(job);
  160. return 0;
  161. }