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