Codebase list sysvinit / a0cb4da
New upstream version 2.97 Mark Hindley 3 years ago
12 changed file(s) with 683 addition(s) and 55 deletion(s). Raw diff Collapse all Expand all
+0
-16
contrib/TODO less more
0
1 There are several things on the wishlist. See also the "wishlist" bugs filed
2 against sysvinit in the debian bugs system (http://www.debian.org/Bugs/).
3
4 1. A special target for kbrequest, so that extra CHILDs are
5 created (each one needs its own utmp/wtmp bookkeeping)
6 2. Extend the initreq.h interface?
7 3. Add GNU last long options to last
8
9 4. Write all boot messages to a logfile
10 Problem: TIOCCONS ioctl redirects console output, it doesn't copy it.
11 I think this is not easily possible without kernel support.
12 I do not like the idea of booting with a pseudo tty as console and
13 a redirect process behind it writing to both the real console and a
14 logfile - too fragile.
15
0 #!/bin/sh
1 # sysd2v v0.3 -- systemd unit to sysvinit script converter
2 # Copyright (C) 2019 Trek http://www.trek.eu.org/devel/sysd2v
3 # distributed under the terms of the GNU General Public License 3
4
5
6 nl="
7 "
8
9 # read a systemd unit file and set variables named ini_{section}_{key}
10 # usage: read_unit filename instance
11 # filename service unit configuration file, '-' to read from stdin
12 # instance instance name for template units
13 read_unit()
14 {
15 filename=$1
16 instance=$2
17
18 if [ "$filename" != - ]
19 then
20 inifile_unit_name=${filename##*/}
21 inifile_unit_name=${inifile_unit_name%.*}
22 fi
23
24 rm_comm='/^[#;]/d'
25 concat=':l; /\\$/ { N; s/[[:space:]]*\\\n/ /; tl }'
26 subst_inst="s/%[Ii]/$instance/g"
27 unit=$(
28 cat "$filename" |
29 sed "$rm_comm" |
30 sed "$concat;$subst_inst"
31 )
32 section_list=$(
33 printf %s "$unit" |
34 sed -n 's/^\[\([[:alnum:]]\+\)\].*/\1/p'
35 )
36 oldifs=$IFS
37 IFS=$nl
38
39 for section in $section_list
40 do
41 get_sect='/^\['"$section"'\]/,/^\[.\+\]/'
42 key_list=$(
43 printf %s "$unit" |
44 sed -n "$get_sect"'s/^\([[:alnum:]]\+\)[[:space:]]*=.*/\1/p' |
45 sort -u
46 )
47
48 for key in $key_list
49 do
50 val=$(
51 printf %s "$unit" |
52 sed -n "$get_sect"'s/^'"$key"'[[:space:]]*=[[:space:]]*\(.*\)/\1/p'
53 )
54 var=$(
55 echo "${section}_$key" |
56 tr '[:upper:]' '[:lower:]'
57 )
58 eval ini_$var=\$val
59 [ -n "$debug" ] && echo "ini_$var=$val" >&2
60 done
61 done
62
63 IFS=$oldifs
64 }
65
66
67 # read a systemd configuration value and write its prefix to stdout
68 # usage: get_prefix val
69 # val systemd configuration value
70 get_prefix () { printf %s "$1" | sed -n 's/^\([-@:+!|]*\).*/\1/p'; }
71
72
73 # read a boolean value and returns true or false
74 # usage: is_true val
75 # val boolean value
76 is_true () { case "$1" in 1|[Oo][Nn]|[Tt]*|[Yy]*) true;; *) false; esac }
77
78
79 # read systemd services list and write LSB facilities to stdout
80 # usage: get_provides services
81 # services list of service units
82 get_provides ()
83 {
84 lst=
85 for dep in $1
86 do
87 lst=${lst:+$lst }${dep%.service}
88 done
89 printf %s "$lst"
90 }
91
92
93 # read systemd units list and write LSB facilities to stdout
94 # usage: get_depends dependencies [ignores]
95 # dependencies list of required units
96 # ignores facilities to ignore
97 get_depends ()
98 {
99 lst=
100 for dep in $1
101 do
102 d=
103 case $dep in
104 local-fs-pre.target) d=mountkernfs;;
105 time-sync.target) d=\$time;;
106 systemd-modules-load.service) d=kmod;;
107 local-fs.target|network-pre.target) d=\$local_fs;;
108 systemd-sysctl.service) d=procps;;
109 network.target|network-online.target|systemd-networkd.service)
110 d=\$network;;
111 nss-lookup.target) d=\$named;;
112 rpcbind.target|remote-fs-pre.target) d=\$portmap;;
113 remote-fs.target|sysinit.target|basic.target) d=\$remote_fs;;
114 syslog.service) d=\$syslog;;
115 boot-complete.target|multi-user.target|default.target) d=\$all;;
116 *.service) d=${dep%.service};;
117 *) echo "WARNING: unsupported target '$dep'" >&2
118 esac
119
120 ign=${2:+$2 }$lst
121 [ -z "$ign" -o -n "${ign%%*"$d"*}" ] &&
122 lst=${lst:+$lst }$d
123 done
124
125 printf %s "$lst"
126 }
127
128
129 # read LSB facilities list and write runlevel to stdout
130 # usage: get_runlevel facilities
131 # facilities list of required facilities
132 get_runlevel ()
133 {
134 case $1 in
135 *\$remote_fs*) echo 2 3 4 5;;
136 *) echo S
137 esac
138 }
139
140
141 # write a list of environment files to be executed
142 # usage: write_env list
143 # list files separated by newlines, with prefix (-)
144 write_env ()
145 {
146 oldifs=$IFS
147 IFS=$nl
148
149 for env in $1
150 do
151 pre=$(get_prefix "$env")
152 noerr=
153
154 [ -n "$pre" -a -z "${pre%%*-*}" ] && noerr="[ -r ${env#$pre} ] && "
155
156 printf '%s\n' "$noerr. ${env#$pre}"
157 done
158
159 IFS=$oldifs
160 }
161
162
163 # write an environment variable containing paths
164 # usage: write_path name prefix list
165 # name name of the environment variable
166 # prefix path prefix to append directories
167 # list paths separated by spaces or newlines
168 write_path ()
169 {
170 lst=
171 for dir in $3
172 do
173 lst=${lst:+$lst:}$2/$dir
174 done
175
176 [ -z "$3" ] || printf '%s=%s\n' $1 $lst
177 }
178
179
180 # write a list of directories to be created
181 # usage: write_install prefix list [user [group [mode]]]
182 # prefix path prefix to append directories
183 # list paths separated by spaces or newlines
184 # user user ownership
185 # group group ownership
186 # mode permission mode
187 write_install ()
188 {
189 for dir in $2
190 do
191 printf ' install -d %s%s/%s || return 2\n' \
192 "${3:+-o $3 }${4:+-g $4 }${5:+-m $5 }" "$1" "$dir"
193 done
194 }
195
196
197 # write a list of commands applying systemd executable prefixes
198 # usage: write_commands list [run [runpriv]]
199 # list commands separated by newlines, with prefixes (-@:+!)
200 # run command line to run each command (nice, chrt, ...)
201 # runpriv command line to set privileges (runuser, ...)
202 write_commands ()
203 {
204 oldifs=$IFS
205 IFS=$nl
206
207 for cmd in $1
208 do
209 pre=$(get_prefix "$cmd")
210 beg=$3
211 end=' || return 2'
212
213 if [ -n "$pre" ]
214 then
215 [ -z "${pre%%*-*}" ] && end=
216 [ -z "${pre%%*[+!]*}" ] && beg=
217 [ -z "${pre%%*[@:]*}" ] &&
218 echo "WARNING: unsupported exec prefix '$pre'" >&2
219 fi
220
221 printf ' %s\n' "$2$beg${cmd#$pre}$end"
222 done
223
224 IFS=$oldifs
225 }
226
227
228 # read a list of commands separated by newlines and write an override function
229 # usage: write_function name [commands]
230 # name function name (start_cmd, stop_cmd, ...)
231 # commands list of commands, read from stdin if omitted
232 write_function ()
233 {
234 lst=${2-$(cat)}
235
236 [ -n "$lst" ] || return
237 [ "$lst" = : ] && printf "do_${1}_override () :\n\n" && return
238
239 end=' true\n'
240 [ -z "${lst%%*|| return [0-9]}" -o -z "${lst%%*|| return \$?}" ] && end=
241 printf "do_${1}_override ()\n{\n%s\n$end}\n\n" "$lst"
242 }
243
244
245 # write an init-d-script file starting from the ini_* vars (see read_unit)
246 # usage: write_init servicename instance
247 # servicename name of the service provided
248 # instance instance name for template units
249 write_init ()
250 {
251 name=$1
252 instance=$2
253
254 if [ "${name%@}" != "$name" ]
255 then
256 name=$name$instance
257 fi
258
259 daemon_pre=$(get_prefix "$ini_service_execstart")
260 daemon=${ini_service_execstart#$daemon_pre}
261
262 if [ "${daemon%%[[:space:]]*}" != "$daemon" ]
263 then
264 daemon_args=${daemon#*[[:space:]]}
265 daemon=${daemon%%[[:space:]]*}
266 fi
267
268 pidfile=$ini_service_pidfile
269
270 if [ -n "$ini_service_user" ]
271 then
272 start_args="--user $ini_service_user"
273 [ -n "$daemon_pre" -a -z "${daemon_pre%%*[+!]*}" ] ||
274 start_args="$start_args --chuid $ini_service_user"
275 stop_args="--user $ini_service_user"
276 runprivstart="runuser -u $ini_service_user -- "
277 is_true "$ini_service_permissionsstartonly" || runpriv=$runprivstart
278 fi
279
280 cls=$ini_service_ioschedulingclass
281 pri=$ini_service_ioschedulingpriority
282 [ -n "$cls$pri" ] &&
283 start_args="$start_args --iosched ${cls:-best-effort}${pri:+:$pri}" &&
284 run="ionice ${cls:+-c $cls }${pri:+-n $pri }"
285
286 pol=$ini_service_cpuschedulingpolicy
287 pri=$ini_service_cpuschedulingpriority
288 [ -n "$pol$pri" ] &&
289 start_args="$start_args --procsched ${pol:-other}${pri:+:$pri}" &&
290 run="${run}chrt ${pol:+--$pol }${pri:-0} "
291
292 [ -n "$ini_service_nice" ] &&
293 start_args="$start_args --nicelevel $ini_service_nice" &&
294 run="${run}nice -n $ini_service_nice "
295
296 pre=$(get_prefix "$ini_service_workingdirectory")
297 workdir=${ini_service_workingdirectory#$pre}
298 [ "$workdir" = '~' ] && workdir=\~$ini_service_user
299 [ -n "$workdir" ] &&
300 start_args="$start_args --chdir $workdir" &&
301 chdir="${pre}cd $workdir"
302
303 if [ -z "${service_type:=$ini_service_type}" ]
304 then
305 if [ -n "$ini_service_busname" ]
306 then
307 service_type=dbus
308 elif [ -n "$ini_service_execstart" ]
309 then
310 service_type=simple
311 else
312 service_type=oneshot
313 fi
314 fi
315
316 if [ "$service_type" != forking ]
317 then
318 start_args="$start_args --background"
319 [ -z "$pidfile" -a "$ini_service_killmode" != none ] &&
320 start_args="$start_args --make-pidfile" &&
321 pidfile="/var/run/$name-sysd2v.pid"
322 fi
323
324 if [ "$service_type" = notify ]
325 then
326 start_args="$start_args --notify-await"
327 timeout=${ini_service_timeoutstartsec:-$ini_service_timeoutsec}
328 timeout=${timeout%s}
329 [ -n "${timeout#60}" ] &&
330 start_args="$start_args --notify-timeout $timeout"
331 [ -n "$timeout" -a -z "${timeout%%*[^0-9]*}" ] &&
332 echo "WARNING: unsupported timeout '$timeout'" >&2
333 elif [ "$service_type" = dbus ]
334 then
335 : TODO
336 fi
337
338 signal=${ini_service_killsignal#SIG}
339 timeout=${ini_service_timeoutstopsec:-$ini_service_timeoutsec}
340 timeout=${timeout%s}
341 [ -n "${signal#TERM}" -o -n "${timeout#90}" ] &&
342 stop_args="$stop_args --retry=${signal:-TERM}/${timeout:-90}/KILL/5"
343
344 limitnofile=$ini_service_limitnofile
345 [ "$limitnofile" = infinity ] && limitnofile=unlimited
346
347 need_install=$ini_service_runtimedirectory
348 need_install=$need_install$ini_service_statedirectory
349 need_install=$need_install$ini_service_cachedirectory
350 need_install=$need_install$ini_service_logsdirectory
351 need_install=$need_install$ini_service_configurationdirectory
352
353 need_do_start=$ini_service_execstartpre$ini_service_execstartpost
354 need_do_start=$need_do_start$need_install
355
356 execstop=$ini_service_execstop
357
358 if [ "$service_type" != oneshot ]
359 then
360 [ "$pidfile" = "/var/run/${daemon##*/}.pid" ] && unset pidfile
361 [ "$name" = "${daemon##*/}" ] && unset name
362
363 [ -n "$daemon_args" -a -z "${daemon_args%%*[\"\\]*}" ] &&
364 echo "WARNING: DAEMON_ARGS needs to be escaped" >&2
365 errcheck=' || return $?'
366
367 if [ -n "$daemon_pre" ]
368 then
369 [ -z "${daemon_pre%%*-*}" ] && errcheck=
370 [ -z "${daemon_pre%%*[@:]*}" ] &&
371 echo "WARNING: unsupported exec prefix '$daemon_pre'" >&2
372 fi
373
374 # TODO: test if already running before start (pretest="+do_status_cmd")
375 [ -n "$need_do_start" -o -z "$errcheck" ] &&
376 execstart="-+do_start_cmd$errcheck"
377
378 errcheck=' || return $?'
379 [ -n "$execstop" ] && errcheck=
380 [ -n "$execstop$ini_service_execstoppost" -a \
381 "$ini_service_killmode" != none ] &&
382 killstop="-do_stop_cmd$errcheck"
383
384 [ -n "$timeout" -a -z "${timeout%%*[^0-9]*}" ] &&
385 echo "WARNING: unsupported timeout '$timeout'" >&2
386 else
387 daemon=none
388 pidfile=none
389 : ${name:=SERVICE_NAME}
390 unset daemon_args start_args stop_args
391 execstart=$ini_service_execstart
392 runstart=$run
393 fi
394
395 need_do_start=$need_do_start$execstart
396 start_args=${start_args# }
397 stop_args=${stop_args# }
398
399 aliases=$(get_provides "$ini_install_alias")
400
401 [ -z "$ini_unit_defaultdependencies" ] ||
402 is_true "$ini_unit_defaultdependencies" &&
403 defdep=sysinit.target
404
405 req_start=$(get_depends "$ini_unit_requires $defdep")
406 should_start=$(get_depends "$ini_unit_wants $ini_unit_after" "$req_start")
407
408 default_start=$(get_runlevel "$req_start $should_start")
409 [ "$default_start" = S ] && default_stop='0 6' || default_stop='0 1 6'
410 [ -z "$execstop$ini_service_execstoppost" ] &&
411 [ "$service_type" = oneshot -o "$ini_service_killmode" = none ] &&
412 default_stop=
413
414 [ "$default_start" = S ] && ignore=\$remote_fs
415 start_before=$(get_depends "$ini_unit_requiredby $ini_install_wantedby
416 $ini_unit_before" "$req_start $should_start \$all $ignore")
417
418 cat <<EOF
419 #!/bin/sh
420 # Generated by sysd2v v0.3 -- http://www.trek.eu.org/devel/sysd2v
421 # kFreeBSD do not accept scripts as interpreters, using #!/bin/sh and sourcing.
422 if [ true != "\$INIT_D_SCRIPT_SOURCED" ] ; then
423 set "\$0" "\$@"; INIT_D_SCRIPT_SOURCED=true . /lib/init/init-d-script
424 fi
425 ### BEGIN INIT INFO
426 # Provides: ${name:-${daemon##*/}}${aliases:+ $aliases}
427 # Required-Start: $req_start
428 # Required-Stop: ${default_stop:+$req_start}
429 ${should_start:+# Should-Start: $should_start
430 ${default_stop:+# Should-Stop: $should_start
431 }}${start_before:+# X-Start-Before: $start_before
432 ${default_stop:+# X-Stop-After: $start_before
433 }}# Default-Start: $default_start
434 # Default-Stop: $default_stop
435 # Description: ${ini_unit_description:-SERVICE_DESCRIPTION}
436 ### END INIT INFO
437 EOF
438
439 if [ -n "$ini_service_environment$ini_service_environmentfile$need_install" ]
440 then
441 echo set -a
442 write_path RUNTIME_DIRECTORY /run "$ini_service_runtimedirectory"
443 write_path STATE_DIRECTORY /var/lib "$ini_service_statedirectory"
444 write_path CACHE_DIRECTORY /var/cache "$ini_service_cachedirectory"
445 write_path LOGS_DIRECTORY /var/log "$ini_service_logsdirectory"
446 write_path CONFIGURATION_DIRECTORY /etc \
447 "$ini_service_configurationdirectory"
448 printf '%s' "${ini_service_environment:+$ini_service_environment$nl}"
449 write_env "$ini_service_environmentfile"
450 printf 'set +a\n\n'
451 fi
452
453 cat <<EOF
454 ${name:+DESC=\"$name\"
455 }DAEMON=$daemon
456 ${daemon_args:+DAEMON_ARGS=\"$daemon_args\"
457 }${pidfile:+PIDFILE=$pidfile
458 }${start_args:+START_ARGS=\"$start_args\"
459 }${stop_args:+STOP_ARGS=\"$stop_args\"
460 }${limitnofile:+ulimit -n $limitnofile
461 }${ini_service_umask:+umask $ini_service_umask
462 }
463 EOF
464
465 if [ -n "$need_do_start" ]
466 then
467 {
468 write_install /run "$ini_service_runtimedirectory" \
469 "$ini_service_user" "$ini_service_group" \
470 "$ini_service_runtimedirectorymode"
471 write_install /var/lib "$ini_service_statedirectory" \
472 "$ini_service_user" "$ini_service_group" \
473 "$ini_service_statedirectorymode"
474 write_install /var/cache "$ini_service_cachedirectory" \
475 "$ini_service_user" "$ini_service_group" \
476 "$ini_service_cachedirectorymode"
477 write_install /var/log "$ini_service_logsdirectory" \
478 "$ini_service_user" "$ini_service_group" \
479 "$ini_service_logsdirectorymode"
480 write_install /etc "$ini_service_configurationdirectory" '' '' \
481 "$ini_service_configurationdirectorymode"
482 write_commands "$chdir"
483 write_commands "$ini_service_execstartpre" "$run" "$runpriv"
484 write_commands "$execstart" "$runstart" "$runprivstart"
485 write_commands "$ini_service_execstartpost" "$run" "$runpriv"
486 } | write_function start_cmd
487 else
488 [ "$service_type" = oneshot ] && write_function start :
489 fi
490
491 if [ -n "$execstop$ini_service_execstoppost" ]
492 then
493 {
494 write_commands "$chdir"
495 write_commands "$execstop" "$run" "$runpriv"
496 write_commands "$killstop"
497 write_commands "$ini_service_execstoppost" "$run" "$runpriv"
498 } | write_function stop_cmd
499 else
500 [ "$service_type" = oneshot -o "$ini_service_killmode" = none ] &&
501 write_function stop :
502 fi
503
504 if [ "$ini_service_execreload" = '/bin/kill -HUP $MAINPID' -a \
505 -z "$run$runpriv" ]
506 then
507 printf 'alias do_reload=do_reload_sigusr1\n\n'
508 elif [ -n "$ini_service_execreload" ]
509 then
510 {
511 write_commands "$chdir"
512 write_commands "$ini_service_execreload" "$run" "$runpriv"
513 } | write_function reload_cmd
514
515 cat <<"EOF"
516 do_reload ()
517 {
518 log_daemon_msg "Reloading $DESC configuration files" "$NAME"
519 MAINPID=$(cat $PIDFILE)
520 do_reload_cmd_override
521 log_end_msg $?
522 }
523 EOF
524 fi
525
526 [ "$service_type" = oneshot ] && write_function status :
527 }
528
529
530 # parse command line
531 while getopts di:n: opt
532 do
533 case $opt in
534 d) debug=1;;
535 i) instance=$OPTARG;;
536 n) name=$OPTARG;;
537 ?) printf "Usage: %s [-d] [-i instance] [-n servicename] [filename]\n" \
538 "$0"
539 exit 2;;
540 esac
541 done
542
543 : ${instance=INSTANCE_NAME}
544 shift $(($OPTIND - 1))
545
546
547 # convert unit file
548 read_unit "${1:--}" "$instance"
549 write_init "${name-$inifile_unit_name}" "$instance"
550
0 sysvinit (2.97) unreleased; urgency=low
1
2 * Check $(ROOT) filesystem for libcrypt instead of a hardcoded path to /usr.
3 Added logsave and readbootlog to list of files git ignores.
4 - Patches provided by Petr Ovtchenkov.
5
6 * Code clean-up and making sure we avoid freeing unused memory.
7 Patch provided by David Hoyer.
8
9 * Added shell script from Trek which converts systemd unit files
10 into init.d style scripts.
11
12 * Added patch from Didier Gaudin which allows init to load configuration
13 data from files stored in /etc/inittab.d/
14
15 * Added patch from William Shipley which allows shutdown time to be specified
16 in the format +hh:mm. This is in addition to the existing formats such as
17 hh:mm, +m, and "now".
18
19 * Fixed typos in manual pages. Submitted by Helge Kreutzmann.
20
21
022 sysvinit (2.96) released; urgency=low
123
224 [ Jesse Smith ]
5757 .sp
5858 .RE
5959 .SH NOTES
60 This script is not meant as startup script for daemons or somesuch.
60 This script is not meant as startup script for daemons or services.
6161 It has nothing to do with a \fIrc.local\fP style script. It's just
6262 a handler for things executed from \fB/etc/inittab\fP. Experimenting
6363 with this can make your system un(re)bootable.
6767 .SH AUTHOR
6868 Miquel van Smoorenburg ,<miquels@cistron.nl>
6969 .SH "SEE ALSO"
70 init(8), inittab(5).
70 inittab(5), init(8).
141141 absolute time in the format \fIhh:mm\fP, in which \fIhh\fP is the hour
142142 (1 or 2 digits) and \fImm\fP is the minute of the hour (in two digits).
143143 Second, it can be in the format \fB+\fP\fIm\fP, in which \fIm\fP is the
144 number of minutes to wait. The word \fBnow\fP is an alias for \fB+0\fP.
144 number of minutes to wait. Third, it can be in the format \fB+\fP\fIhh:mm\fP,
145 in which \fIhh:mm\fP is the number of hours and minutes to wait.
146 The word \fBnow\fP is an alias for \fB+0\fP.
145147 .PP
146148 If shutdown is called with a delay, it will create the advisory file
147149 .I /etc/nologin
33 init
44 killall5
55 last
6 logsave
67 mesg
8 readbootlog
79 runlevel
810 shutdown
911 sulogin
8989 endif
9090
9191 # Additional libs for GNU libc.
92 ifneq ($(wildcard /usr/lib*/libcrypt.*),)
92 ifneq ($(wildcard $(ROOT)/usr/lib*/libcrypt.*),)
9393 SULOGINLIBS += -lcrypt
9494 endif
9595
9696 # Additional libs for GNU libc / multiarch on Debian based systems.
97 ifneq ($(wildcard /usr/lib/*/libcrypt.*),)
97 ifneq ($(wildcard $(ROOT)/usr/lib/*/libcrypt.*),)
98 ifneq ($(findstring -lcrypt, $(SULOGINLIBS)), -lcrypt)
9899 SULOGINLIBS += -lcrypt
100 endif
99101 endif
100102
101103 all: $(BIN) $(SBIN) $(USRBIN)
200202 $(INSTALL_EXEC) $$i $(ROOT)/usr/bin/ ; \
201203 done
202204 # $(INSTALL_DIR) $(ROOT)/etc/
205 $(INSTALL_DIR) $(ROOT)/etc/inittab.d
203206 # $(INSTALL_EXEC) ../doc/initscript.sample $(ROOT)/etc/
204207 ln -sf halt $(ROOT)/sbin/reboot
205208 ln -sf halt $(ROOT)/sbin/poweroff
162162 struct utmp *utmp;
163163 time_t t;
164164 char term[UT_LINESIZE+ strlen(_PATH_DEV) + 1];
165 char line[81];
165 char line[256];
166166 char hostname[HOST_NAME_MAX+1];
167167 char *date, *p;
168168 char *user, *tty;
6262 #include <sys/ttydefaults.h>
6363 #include <sys/syslog.h>
6464 #include <sys/time.h>
65 /*
66 * inittab.d
67 */
68 #include <sys/types.h>
69 #include <dirent.h>
6570
6671 #ifdef WITH_SELINUX
6772 # include <selinux/selinux.h>
14301435 void read_inittab(void)
14311436 {
14321437 FILE *fp; /* The INITTAB file */
1438 FILE *fp_tab; /* The INITTABD files */
14331439 CHILD *ch, *old, *i; /* Pointers to CHILD structure */
14341440 CHILD *head = NULL; /* Head of linked list */
14351441 #ifdef INITLVL
14471453 int round; /* round 0 for SIGTERM, 1 for SIGKILL */
14481454 int foundOne = 0; /* No killing no sleep */
14491455 int talk; /* Talk to the user */
1450 int done = 0; /* Ready yet? */
1456 int done = -1; /* Ready yet? , 2 level : -1 nothing done, 0 inittab done, 1 inittab and inittab.d done */
1457 DIR *tabdir=NULL; /* the INITTAB.D dir */
1458 struct dirent *file_entry; /* inittab.d entry */
1459 char f_name[272]; /* size d_name + strlen /etc/inittad.d/ */
14511460
14521461 #if DEBUG
14531462 if (newFamily != NULL) {
14631472 if ((fp = fopen(INITTAB, "r")) == NULL)
14641473 initlog(L_VB, "No inittab file found");
14651474
1466 while(!done) {
1475 /*
1476 * Open INITTAB.D directory
1477 */
1478 if( (tabdir = opendir(INITTABD))==NULL)
1479 initlog(L_VB, "No inittab.d directory found");
1480
1481 while(done!=1) {
14671482 /*
14681483 * Add single user shell entry at the end.
14691484 */
1470 if (fp == NULL || fgets(buf, sizeof(buf), fp) == NULL) {
1471 done = 1;
1472 /*
1473 * See if we have a single user entry.
1474 */
1475 for(old = newFamily; old; old = old->next)
1476 if (strpbrk(old->rlevel, "S")) break;
1477 if (old == NULL)
1478 snprintf(buf, sizeof(buf), "~~:S:wait:%s\n", SULOGIN);
1479 else
1485 if(done == -1) {
1486 if (fp == NULL || fgets(buf, sizeof(buf), fp) == NULL) {
1487 done = 0;
1488 /*
1489 * See if we have a single user entry.
1490 */
1491 for(old = newFamily; old; old = old->next)
1492 if (strpbrk(old->rlevel, "S")) break;
1493 if (old == NULL)
1494 snprintf(buf, sizeof(buf), "~~:S:wait:%s\n", SULOGIN);
1495 else
1496 continue;
1497 }
1498 } /* end if( done==-1) */
1499 else if ( done == 0 ){
1500 /* parse /etc/inittab.d and read all .tab files */
1501 if(tabdir!=NULL){
1502 if( (file_entry = readdir(tabdir))!=NULL){
1503 /* ignore files not like *.tab */
1504 if (!strcmp(file_entry->d_name, ".") || !strcmp(file_entry->d_name, ".."))
1505 continue;
1506 if (strlen(file_entry->d_name) < 5 || strcmp(file_entry->d_name + strlen(file_entry->d_name) - 4, ".tab"))
1507 continue;
1508 /*
1509 * initialize filename
1510 */
1511 memset(f_name,0,sizeof(char)*272);
1512 snprintf(f_name,272,"/etc/inittab.d/%s",file_entry->d_name);
1513 initlog(L_VB, "Reading: %s",f_name);
1514 /*
1515 * read file in inittab.d only one entry per file
1516 */
1517 if ((fp_tab = fopen(f_name, "r")) == NULL)
1518 continue;
1519 /* read the file while the line contain comment */
1520 while( fgets(buf, sizeof(buf), fp_tab) != NULL) {
1521 for(p = buf; *p == ' ' || *p == '\t'; p++);
1522 if (*p != '#' && *p != '\n')
1523 break;
1524 }
1525 fclose(fp_tab);
1526 /* do some checks */
1527 if( buf == NULL )
1528 continue;
1529 if( strlen( p ) == 0 )
1530 continue;
1531 } /* end of readdir, all is done */
1532 else {
1533 done = 1;
1534 continue;
1535 }
1536 } /* end of if(tabdir!=NULL) */
1537 else {
1538 done = 1;
14801539 continue;
1481 }
1540 }
1541 } /* end of if ( done == 0 ) */
14821542 lineNo++;
14831543 /*
14841544 * Skip comments and empty lines
16291689 break;
16301690 }
16311691 }
1692
16321693 /*
16331694 * We're done.
16341695 */
16351696 if (fp) fclose(fp);
1697 if(tabdir) closedir(tabdir);
16361698
16371699 #ifdef __linux__
16381700 check_kernel_console();
512512 if (p->argv0) free(p->argv0);
513513 if (p->argv1) free(p->argv1);
514514 if (p->statname) free(p->statname);
515 free(p->pathname);
515 if (p->pathname) free(p->pathname);
516516 free(p);
517517 }
518518 plist = NULL;
561561 if (p->argv0) free(p->argv0);
562562 if (p->argv1) free(p->argv1);
563563 if (p->statname) free(p->statname);
564 free(p->pathname);
564 if (p->pathname) free(p->pathname);
565565 free(p);
566566 continue;
567567 }
577577
578578 /* Get session, startcode, endcode. */
579579 startcode = endcode = 0;
580 /*
581 if (sscanf(q, "%*c %*d %*d %d %*d %*d %*u %*u "
580 if (sscanf(q, "%10s %*d %*d %d %*d %*d %*u %*u "
582581 "%*u %*u %*u %*u %*u %*d %*d "
583582 "%*d %*d %*d %*d %*u %*u %*d "
584583 "%*u %lu %lu",
585 &p->sid, &startcode, &endcode) != 3) {
586 */
587 if (sscanf(q, "%10s %*d %*d %d %*d %*d %*u %*u "
588 "%*u %*u %*u %*u %*u %*d %*d "
589 "%*d %*d %*d %*d %*u %*u %*d "
590 "%*u %lu %lu",
591 process_status,
592 &p->sid, &startcode, &endcode) != 4) {
584 process_status,
585 &p->sid, &startcode, &endcode) != 4) {
593586
594587 p->sid = 0;
595588 nsyslog(LOG_ERR, "can't read sid from %s\n",
623616 if (p->argv0) free(p->argv0);
624617 if (p->argv1) free(p->argv1);
625618 if (p->statname) free(p->statname);
626 free(p->pathname);
619 if (p->pathname) free(p->pathname);
627620 free(p);
628621 continue;
629622 }
671664 if (p->argv0) free(p->argv0);
672665 if (p->argv1) free(p->argv1);
673666 if (p->statname) free(p->statname);
674 free(p->pathname);
667 if (p->pathname) free(p->pathname);
675668 free(p);
676669 continue;
677670 }
2626 #define SECURETTY "/etc/securetty" /* List of root terminals */
2727 #define SDALLOW "/etc/shutdown.allow" /* Users allowed to shutdown */
2828 #define INITTAB "/etc/inittab" /* Location of inittab */
29 #define INITTABD "/etc/inittab.d" /* Location of inittab.d directory */
2930 #define INIT "/sbin/init" /* Location of init itself. */
3031 #define NOLOGIN "/etc/nologin" /* Stop user logging in. */
3132 #define FASTBOOT "/fastboot" /* Enable fast boot. */
787787 wt = atoi(when);
788788 if (wt == 0 && when[0] != '0') usage();
789789 } else {
790 if (sscanf(when, "%d:%2d", &hours, &mins) != 2) usage();
790791 /* Time in hh:mm format. */
791 if (sscanf(when, "%d:%2d", &hours, &mins) != 2) usage();
792 if (hours > 23 || mins > 59) usage();
793 time(&t);
794 lt = localtime(&t);
795 wt = (60*hours + mins) - (60*lt->tm_hour + lt->tm_min);
796 if (wt < 0) wt += 1440;
792 if (when[0] == '+') {
793 /* Hours and minutes from now */
794 if (hours > 99999 || mins > 59) usage();
795 wt = (60*hours + mins);
796 if (wt < 0) usage();
797 } else {
798 /* Time of day */
799 if (hours > 23 || mins > 59) usage();
800 time(&t);
801 lt = localtime(&t);
802 wt = (60*hours + mins) - (60*lt->tm_hour + lt->tm_min);
803 if (wt < 0) wt += 1440;
804 }
797805 }
798806 /* Shutdown NOW if time == 0 */
799807 if (wt == 0) issue_shutdown(halttype);