2 * --- T2-COPYRIGHT-NOTE-BEGIN ---
3 * This copyright note is auto-generated by scripts/Create-CopyPatch.
5 * T2 SDE: package/.../sysvinit/rc.c
6 * Copyright (C) 2004 - 2020 The T2 SDE Project
7 * Copyright (C) 1998 - 2003 ROCK Linux Project
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 ---
25 #include <sys/resource.h>
28 #include <sys/types.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",
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
) {
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"));
80 sprintf(env_TERM
, "TERM=%.50s", getenv("TERM"));
82 /* we never need argv[0] - skipt it */
85 /* Handle --nobtee option */
86 if ( argc
> 0 && !strcmp(*argv
, "--nobtee") ) {
91 /* Display help message */
95 " Run SystemV Init-Scripts with a clean environment and detached from\n"
98 " Usage: rc [ --nobtee ] <service> { start | stop | ... | help } [ script options ]\n");
102 " <service> might be one of:\n"
105 system("ls /etc/rc.d/init.d >&2");
108 fprintf(stderr
, "\n");
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 */
117 if ( pipe(btee_pipe
) ) {
118 perror("rc: Can't create pipe for btee");
122 dup2(btee_pipe
[0], 0);
125 execl("/sbin/btee", "btee", "a",
126 "/var/log/init.msg", NULL
);
127 perror("rc: Can't exec btee command");
130 dup2(btee_pipe
[1], 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;
160 if ( i
>= __SIGRTMIN
) continue;
163 if ( i
> SIGUNUSED
) continue;
165 if( signal(i
, SIG_DFL
) == SIG_ERR
) {
166 fprintf(stderr
, "rc: Can't reset signal #%d: "
167 "%s\n", i
, strerror(errno
) );
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
) );
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
189 i
= snprintf(command
, sizeof(command
), "%s%s",
190 strchr(*argv
, '/') ? "" : "/etc/rc.d/init.d/", *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");