OpenSDE Packages Database (without history before r20070)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
6.2 KiB

  1. /*
  2. * --- SDE-COPYRIGHT-NOTE-BEGIN ---
  3. * This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  4. *
  5. * Filename: package/.../sysvinit/rc.c
  6. * Copyright (C) 2007 The OpenSDE Project
  7. * Copyright (C) 2004 - 2006 The T2 SDE Project
  8. * Copyright (C) 1998 - 2003 Clifford Wolf
  9. *
  10. * More information can be found in the files COPYING and README.
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; version 2 of the License. A copy of the
  15. * GNU General Public License can be found in the file COPYING.
  16. * --- SDE-COPYRIGHT-NOTE-END ---
  17. */
  18. #include <errno.h>
  19. #include <grp.h>
  20. #include <sched.h>
  21. #include <signal.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <sys/resource.h>
  26. #include <sys/stat.h>
  27. #include <sys/time.h>
  28. #include <sys/types.h>
  29. #include <unistd.h>
  30. char env_PREVLEVEL[100]="PREVLEVEL=N";
  31. char env_RUNLEVEL[100]="RUNLEVEL=N";
  32. char env_TERM[100]="TERM=linux";
  33. char * clean_env[] = {
  34. "PATH=/bin:/usr/bin:/sbin:/usr/sbin",
  35. env_PREVLEVEL,
  36. env_RUNLEVEL,
  37. env_TERM,
  38. NULL
  39. };
  40. #ifndef __SIGRTMIN
  41. #define __SIGRTMIN 32
  42. #endif
  43. #ifndef __SIGRTMAX
  44. #define __SIGRTMAX (NSIG-1)
  45. #endif
  46. /* See bits/resource.h and asm/resource.h */
  47. struct rlimit rlim_cpu = { RLIM_INFINITY, RLIM_INFINITY };
  48. struct rlimit rlim_fsize = { RLIM_INFINITY, RLIM_INFINITY };
  49. struct rlimit rlim_data = { RLIM_INFINITY, RLIM_INFINITY };
  50. struct rlimit rlim_stack = { RLIM_INFINITY, RLIM_INFINITY };
  51. struct rlimit rlim_core = { RLIM_INFINITY, RLIM_INFINITY };
  52. struct rlimit rlim_rss = { RLIM_INFINITY, RLIM_INFINITY };
  53. struct rlimit rlim_nofile = { 1024, 1024 };
  54. struct rlimit rlim_as = { RLIM_INFINITY, RLIM_INFINITY };
  55. struct rlimit rlim_nproc = { 2048, 2048 };
  56. struct rlimit rlim_memlock = { RLIM_INFINITY, RLIM_INFINITY };
  57. struct rlimit rlim_locks = { RLIM_INFINITY, RLIM_INFINITY };
  58. #define GROUP_LIST_SIZE 1
  59. gid_t group_list[GROUP_LIST_SIZE] = { 0 };
  60. /* This prototypes are missing in unistd.h */
  61. int setresuid(uid_t ruid, uid_t euid, uid_t suid);
  62. int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
  63. /* The first (and only) field in sched_param is sched_priority */
  64. struct sched_param sp = { 0 };
  65. #define handle_error(a) if ( a == -1 ) { perror("rc: " #a); return 1; }
  66. int main(int argc, char ** argv) {
  67. char command[1024];
  68. int use_btee = 1;
  69. int btee_pipe[2];
  70. int i;
  71. /* Copy some environment variables to the new environment if set */
  72. if ( getenv("PREVLEVEL") )
  73. sprintf(env_PREVLEVEL, "PREVLEVEL=%.50s", getenv("PREVLEVEL"));
  74. if ( getenv("RUNLEVEL") )
  75. sprintf(env_RUNLEVEL, "RUNLEVEL=%.50s", getenv("RUNLEVEL"));
  76. if ( getenv("TERM") )
  77. sprintf(env_TERM, "TERM=%.50s", getenv("TERM"));
  78. /* we never need argv[0] - skipt it */
  79. argv++; argc--;
  80. /* Handle --nobtee option */
  81. if ( argc > 0 && !strcmp(*argv, "--nobtee") ) {
  82. use_btee = 0;
  83. argv++; argc--;
  84. }
  85. /* Display help message */
  86. if ( argc < 2 ) {
  87. fprintf(stderr,
  88. "\n"
  89. " Run SystemV Init-Scripts with a clean environment and detached from\n"
  90. " the terminal.\n"
  91. "\n"
  92. " Usage: rc [ --nobtee ] <service> { start | stop | ... | help } [ script options ]\n");
  93. }
  94. if ( argc == 0 ) {
  95. fprintf(stderr, "\n"
  96. " <service> might be one of:\n"
  97. "\n");
  98. fflush(stderr);
  99. system("ls /etc/rc.d/init.d >&2");
  100. }
  101. if ( argc < 2 ) {
  102. fprintf(stderr, "\n");
  103. return 1;
  104. }
  105. /* No btee when viewing the help screen for this service */
  106. if ( !strcmp(argv[1], "help") ) use_btee = 0;
  107. /* Forward output to a 'btee' process */
  108. if ( use_btee ) {
  109. if ( pipe(btee_pipe) ) {
  110. perror("rc: Can't create pipe for btee");
  111. return 1;
  112. }
  113. if ( fork() == 0 ) {
  114. dup2(btee_pipe[0], 0);
  115. close(btee_pipe[0]);
  116. close(btee_pipe[1]);
  117. execl("/sbin/btee", "btee", "a",
  118. "/var/log/init.msg", NULL);
  119. perror("rc: Can't exec btee command");
  120. return 1;
  121. } else {
  122. dup2(btee_pipe[1], 1);
  123. close(btee_pipe[0]);
  124. close(btee_pipe[1]);
  125. }
  126. }
  127. /* Set umask, process-group, nice-value and current directory */
  128. handle_error( umask(022) );
  129. handle_error( setpgid(0,0) );
  130. handle_error( setpriority(PRIO_PROCESS, 0, 0) );
  131. handle_error( chdir("/") );
  132. /* Set all ulimits */
  133. handle_error( setrlimit(RLIMIT_CPU, &rlim_cpu) );
  134. handle_error( setrlimit(RLIMIT_FSIZE, &rlim_fsize) );
  135. handle_error( setrlimit(RLIMIT_DATA, &rlim_data) );
  136. handle_error( setrlimit(RLIMIT_STACK, &rlim_stack) );
  137. handle_error( setrlimit(RLIMIT_CORE, &rlim_core) );
  138. handle_error( setrlimit(RLIMIT_RSS, &rlim_rss) );
  139. handle_error( setrlimit(RLIMIT_NOFILE, &rlim_nofile) );
  140. handle_error( setrlimit(RLIMIT_AS, &rlim_as) );
  141. handle_error( setrlimit(RLIMIT_NPROC, &rlim_nproc) );
  142. handle_error( setrlimit(RLIMIT_MEMLOCK, &rlim_memlock) );
  143. handle_error( setrlimit(RLIMIT_LOCKS, &rlim_locks) );
  144. /* Reset all signal handlers */
  145. for (i=1; i<NSIG; i++) {
  146. if ( i == SIGKILL ) continue;
  147. if ( i == SIGSTOP ) continue;
  148. if ( i >= __SIGRTMIN && i < SIGRTMIN ) continue;
  149. if( signal(i, SIG_DFL) == SIG_ERR ) {
  150. fprintf(stderr, "rc: Can't reset signal #%d: "
  151. "%s\n", i, strerror(errno) );
  152. return 1;
  153. }
  154. }
  155. /* Close all file-descriptors > 2 (1024 seams to be a good value -
  156. * linux/fs.h defines NR_OPEN to 1024*1024, which is too big ;-) */
  157. for (i=3; i<=1024; i++) close(i);
  158. /* Set user and group ids */
  159. handle_error( setgroups(GROUP_LIST_SIZE, group_list) );
  160. handle_error( setresuid(0, 0, 0) );
  161. handle_error( setresgid(0, 0, 0) );
  162. /* clear rt scheduling */
  163. handle_error( sched_setscheduler(0, SCHED_OTHER, &sp) );
  164. /* Run the command in a (non-interactive) login shell (i.e. read
  165. * /etc/profile) and send \004 after running the script if we are
  166. * using btee. */
  167. i = snprintf(command, sizeof(command), "%s%s",
  168. strchr(*argv, '/') ? "" : "/etc/rc.d/init.d/", *argv);
  169. argv++;
  170. while (*argv) /* copy args */
  171. i += snprintf(command+i, sizeof(command)-i, " %s", *argv++);
  172. i+=snprintf(command+i, sizeof(command)-i, " </dev/null 2>&1%s",
  173. use_btee ? "; echo -ne '\004'" : "");
  174. execle("/bin/bash", "-bash", "-l", "-c", command, NULL, clean_env);
  175. /* Oups! Can't exec the shell. */
  176. if ( use_btee ) write(1, "\004", 1);
  177. perror("rc: Can't execute shell for spawning init script");
  178. return 1;
  179. }