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