tabannusi.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * This file is part of Tabannusi, a continuous build system.
  3. * Copyright (c) 2016 ali abdul ghani <alimiracle@riseup.net>
  4. * Tabannusi is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. * Tabannusi is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. * You should have received a copy of the GNU General Public License
  13. * along with Tabannusi. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include <stdio.h>
  16. #include <sys/types.h>
  17. #include <errno.h>
  18. #include <sys/stat.h>
  19. #include <stdlib.h>
  20. #include <fcntl.h>
  21. #include <syslog.h>
  22. #include <unistd.h>
  23. #include <signal.h>
  24. #include <pthread.h>
  25. #include <sys/ioctl.h>
  26. #include <string.h>
  27. int read_pid (char *pidfile)
  28. {
  29. FILE *f; /* var to read pid file */
  30. int pid; /* pid var */
  31. /* now we will open the file */
  32. if (!(f=fopen(pidfile,"r")))
  33. return 0;
  34. fscanf(f,"%d", &pid); /* read the file and put it in pid var */
  35. fclose(f);
  36. return pid;
  37. }
  38. /* check_pid
  39. *
  40. * Reads the pid using read_pid and looks up the pid in the process
  41. * table (using /proc) to determine if the process already exists. If
  42. * so 1 is returned, otherwise 0.
  43. */
  44. int check_pid (char *pidfile)
  45. {
  46. int pid = read_pid(pidfile); /* rede the pid from file and save it to var */
  47. /* Amazing ! _I_ am already holding the pid file... */
  48. if ((!pid) || (pid == getpid ()))
  49. return 0;
  50. /*
  51. * The 'standard' method of doing this is to try and do a 'fake' kill
  52. * of the process. If an ESRCH error is returned the process cannot
  53. * be found -- GW
  54. */
  55. /* But... errno is usually changed only on error.. */
  56. if (kill(pid, 0) & errno == ESRCH)
  57. return(0);
  58. return pid;
  59. }
  60. int write_pid (char *pidfile)
  61. {
  62. FILE *f;
  63. int fd;
  64. int pid;
  65. if ( ((fd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1)
  66. || ((f = fdopen(fd, "r+")) == NULL) ) {
  67. fprintf(stderr, "Can't open or create %s.\n", pidfile);
  68. return 0;
  69. }
  70. /* It seems to be acceptable that we do not lock the pid file
  71. * if we run under Solaris. In any case, it is highly unlikely
  72. * that two instances try to access this file.
  73. */
  74. #if HAVE_FLOCK
  75. if (flock(fd, LOCK_EX|LOCK_NB) == -1) {
  76. fscanf(f, "%d", pid);
  77. fclose(f);
  78. printf("Can't lock, lock is held by pid %d.\n", pid);
  79. return 0;
  80. }
  81. #endif
  82. pid = getpid();
  83. if (!fprintf(f,"%d\n", pid)) {
  84. char errStr[1024];
  85. printf("Can't write pid , %s.\n", errStr);
  86. close(fd);
  87. return 0;
  88. }
  89. fflush(f);
  90. #if HAVE_FLOCK
  91. if (flock(fd, LOCK_UN) == -1) {
  92. char errStr[1024];
  93. printf("Can't unlock pidfile %s, %s.\n", pidfile, errStr);
  94. close(fd);
  95. return 0;
  96. }
  97. #endif
  98. close(fd);
  99. return pid;
  100. }
  101. /* function run by Demon */
  102. void* runcmd (void* unused)
  103. {
  104. system("bash /bin/run.sh"); /* run bash file */
  105. return NULL;
  106. }
  107. int run()
  108. {
  109. pthread_t thread_id;
  110. /* Fork off the parent process */
  111. pid_t pid;
  112. pid = fork();
  113. /* If the pid is less than zero, something went wrong when forking */
  114. if (pid < 0)
  115. {
  116. /* Now we will tell the log server can't fork*/
  117. syslog(LOG_NOTICE, "Cant Fork\n");
  118. exit(EXIT_FAILURE);
  119. }
  120. /* If the pid we got back was greater than zero, then the clone was successful and we are the parent. */
  121. if (pid > 0)
  122. {
  123. exit(EXIT_SUCCESS);
  124. }
  125. /* If execution reaches this point we are the child */
  126. /* disassociating from the controlling terminal */
  127. #if HAVE_SETSID /* if your os have SETSID, use it */
  128. /* Creating a Unique Session ID (SID)*/
  129. if (setsid() < 0)
  130. {
  131. syslog(LOG_NOTICE, "I can't create a Unique Session ID ");
  132. exit(EXIT_FAILURE);
  133. }
  134. #elif defined(TIOCNOTTY) /* if the os dont have SETSID use IOCNOTTY*/
  135. int fd;
  136. fd = open("/dev/tty", O_RDWR);
  137. if (fd >= 0) {
  138. if (ioctl(fd, TIOCNOTTY, NULL) < 0)
  139. {
  140. syslog(LOG_NOTICE, "cant disassociate from the terminal");
  141. exit(EXIT_FAILURE);
  142. }
  143. close(fd);
  144. }
  145. #endif /* defined(TIOCNOTTY) */
  146. //catch/ignore signals
  147. signal(SIGCHLD,SIG_IGN);
  148. signal(SIGHUP,SIG_IGN);
  149. /* Fork off the parent process */
  150. pid_t pid1;
  151. pid1 = fork();
  152. /* If the pid1 is less than zero, something went wrong when forking */
  153. if (pid1 < 0)
  154. {
  155. /* Now we will tell the log server can't fork*/
  156. syslog(LOG_NOTICE, "Can't fork\n");
  157. exit(EXIT_FAILURE);
  158. }
  159. /* If the pid1 we got back was greater than zero, then the clone was successful and we are the parent. */
  160. if (pid1 > 0)
  161. {
  162. exit(EXIT_SUCCESS);
  163. }
  164. /* Now we will set the umask to zero */
  165. umask(0);
  166. /* Now we will Change the current working directory to root */
  167. chdir("/");
  168. /* Close all Files */
  169. close(STDIN_FILENO);
  170. close(STDOUT_FILENO);
  171. close(STDERR_FILENO);
  172. /* Now we will tell the log server it's ok now */
  173. syslog(LOG_NOTICE, "Successfully started daemon\n");
  174. /* close a connection to the syslog server */
  175. closelog();
  176. /* make new file to save last commit */
  177. FILE *fp = fopen("/tmp/q.txt", "ab+");
  178. fclose(fp);
  179. write_pid("/var/run/tabannusi.pid"); /* write pid to file */
  180. while (1)
  181. {
  182. /* run runcmd function in new thread */
  183. pthread_create (&thread_id, NULL, &runcmd, NULL);
  184. sleep(10);
  185. }
  186. }
  187. void start()
  188. {
  189. int scann = check_pid("/var/run/tabannusi.pid");
  190. puts("Starting tabannusi daemon:\n");
  191. if(scann!=0)
  192. {
  193. puts("tabannusi daemon already started\n");
  194. exit(1);
  195. }
  196. run();
  197. }
  198. void stop()
  199. {
  200. pid_t pid=read_pid("/var/run/tabannusi.pid");
  201. int scann = check_pid("/var/run/tabannusi.pid");
  202. puts("Stopping tabannusi daemon\n:");
  203. if(scann==0)
  204. {
  205. puts("tabannusi daemon is not running\n");
  206. exit(1);
  207. }
  208. kill(pid, SIGKILL);
  209. }
  210. void restart()
  211. {
  212. stop();
  213. start();
  214. }
  215. void usage(void) {
  216. fprintf(stderr, "Usage: tabannusi [options]\n");
  217. fputs("start\n" "restart\n" "stop\n", stderr);
  218. exit(1);
  219. }
  220. int main(int argc, char *argv[])
  221. {
  222. /* Open a connection to the syslog server */
  223. openlog(argv[0],LOG_NOWAIT|LOG_PID,LOG_USER);
  224. if(argc==1)
  225. {
  226. usage();
  227. }
  228. if (strcmp(argv[1], "start") == 0)
  229. {
  230. // do something
  231. start();
  232. }
  233. else if (strcmp(argv[1], "stop") == 0)
  234. {
  235. // do something else
  236. stop();
  237. }
  238. else if (strcmp(argv[1], "restart") == 0)
  239. {
  240. // do something else
  241. restart();
  242. }
  243. else
  244. {
  245. usage();
  246. }
  247. return 0;
  248. }