functions 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371
  1. #!/bin/sh
  2. ########################################################################
  3. #
  4. # Begin /etc/rc.d/functions
  5. #
  6. # Description : Run Level Control Functions
  7. # Forked from LFS for Milis Linux
  8. #
  9. #
  10. ########################################################################
  11. ## Environmental setup
  12. # Setup default values for environment
  13. umask 022
  14. export PATH="/bin:/usr/bin:/sbin:/usr/sbin"
  15. ## Set color commands, used via echo
  16. # Please consult `man console_codes for more information
  17. # under the "ECMA-48 Set Graphics Rendition" section
  18. #
  19. # Warning: when switching from a 8bit to a 9bit font,
  20. # the linux console will reinterpret the bold (1;) to
  21. # the top 256 glyphs of the 9bit font. This does
  22. # not affect framebuffer consoles
  23. NORMAL="\\033[0;39m" # Standard console grey
  24. SUCCESS="\\033[1;32m" # Success is green
  25. WARNING="\\033[1;33m" # Warnings are yellow
  26. FAILURE="\\033[1;31m" # Failures are red
  27. INFO="\\033[1;36m" # Information is light cyan
  28. BRACKET="\\033[1;34m" # Brackets are blue
  29. # Use a colored prefix
  30. BMPREFIX=" "
  31. SUCCESS_PREFIX="${SUCCESS} * ${NORMAL} "
  32. FAILURE_PREFIX="${FAILURE}*****${NORMAL} "
  33. WARNING_PREFIX="${WARNING} *** ${NORMAL} "
  34. SKIP_PREFIX="${INFO} S ${NORMAL}"
  35. SUCCESS_SUFFIX="${BRACKET}[${SUCCESS} OK ${BRACKET}]${NORMAL}"
  36. FAILURE_SUFFIX="${BRACKET}[${FAILURE} FAIL ${BRACKET}]${NORMAL}"
  37. WARNING_SUFFIX="${BRACKET}[${WARNING} WARN ${BRACKET}]${NORMAL}"
  38. SKIP_SUFFIX="${BRACKET}[${INFO} SKIP ${BRACKET}]${NORMAL}"
  39. BOOTLOG=/run/bootlog
  40. KILLDELAY=3
  41. SCRIPT_STAT="0"
  42. # Set any user specified environment variables e.g. HEADLESS
  43. [ -r /etc/sysconfig/rc.site ] && . /etc/sysconfig/rc.site
  44. # fix old service funcions path
  45. #sed -i "s/lib\/lsb\/init-functions/etc\/rc.d\/functions/g" /etc/rc.d/init.d/*
  46. ## Screen Dimensions
  47. # Find current screen size
  48. if [ -z "${COLUMNS}" ]; then
  49. COLUMNS=$(stty size)
  50. COLUMNS=${COLUMNS##* }
  51. fi
  52. # When using remote connections, such as a serial port, stty size returns 0
  53. if [ "${COLUMNS}" = "0" ]; then
  54. COLUMNS=80
  55. fi
  56. ## Measurements for positioning result messages
  57. COL=$((${COLUMNS} - 8))
  58. WCOL=$((${COL} - 2))
  59. ## Set Cursor Position Commands, used via echo
  60. SET_COL="\\033[${COL}G" # at the $COL char
  61. SET_WCOL="\\033[${WCOL}G" # at the $WCOL char
  62. CURS_UP="\\033[1A\\033[0G" # Up one line, at the 0'th char
  63. CURS_ZERO="\\033[0G"
  64. ################################################################################
  65. # start_daemon() #
  66. # Usage: start_daemon [-f] [-n nicelevel] [-p pidfile] pathname [args...] #
  67. # #
  68. # Purpose: This runs the specified program as a daemon #
  69. # #
  70. # Inputs: -f: (force) run the program even if it is already running. #
  71. # -n nicelevel: specify a nice level. See 'man nice(1)'. #
  72. # -p pidfile: use the specified file to determine PIDs. #
  73. # pathname: the complete path to the specified program #
  74. # args: additional arguments passed to the program (pathname) #
  75. # #
  76. # Return values (as defined by LSB exit codes): #
  77. # 0 - program is running or service is OK #
  78. # 1 - generic or unspecified error #
  79. # 2 - invalid or excessive argument(s) #
  80. # 5 - program is not installed #
  81. ################################################################################
  82. start_daemon()
  83. {
  84. local force=""
  85. local nice="0"
  86. local pidfile=""
  87. local pidlist=""
  88. local retval=""
  89. # Process arguments
  90. while true
  91. do
  92. case "${1}" in
  93. -f)
  94. force="1"
  95. shift 1
  96. ;;
  97. -n)
  98. nice="${2}"
  99. shift 2
  100. ;;
  101. -p)
  102. pidfile="${2}"
  103. shift 2
  104. ;;
  105. -*)
  106. return 2
  107. ;;
  108. *)
  109. program="${1}"
  110. break
  111. ;;
  112. esac
  113. done
  114. # Check for a valid program
  115. if [ ! -e "${program}" ]; then return 5; fi
  116. # Execute
  117. if [ -z "${force}" ]; then
  118. if [ -z "${pidfile}" ]; then
  119. # Determine the pid by discovery
  120. pidlist=`pidofproc "${1}"`
  121. retval="${?}"
  122. else
  123. # The PID file contains the needed PIDs
  124. # Note that by LSB requirement, the path must be given to pidofproc,
  125. # however, it is not used by the current implementation or standard.
  126. pidlist=`pidofproc -p "${pidfile}" "${1}"`
  127. retval="${?}"
  128. fi
  129. # Return a value ONLY
  130. # It is the init script's (or distribution's functions) responsibilty
  131. # to log messages!
  132. case "${retval}" in
  133. 0)
  134. # Program is already running correctly, this is a
  135. # successful start.
  136. return 0
  137. ;;
  138. 1)
  139. # Program is not running, but an invalid pid file exists
  140. # remove the pid file and continue
  141. rm -f "${pidfile}"
  142. ;;
  143. 3)
  144. # Program is not running and no pidfile exists
  145. # do nothing here, let start_deamon continue.
  146. ;;
  147. *)
  148. # Others as returned by status values shall not be interpreted
  149. # and returned as an unspecified error.
  150. return 1
  151. ;;
  152. esac
  153. fi
  154. # Do the start!
  155. nice -n "${nice}" "${@}"
  156. }
  157. ################################################################################
  158. # killproc() #
  159. # Usage: killproc [-p pidfile] pathname [signal] #
  160. # #
  161. # Purpose: Send control signals to running processes #
  162. # #
  163. # Inputs: -p pidfile, uses the specified pidfile #
  164. # pathname, pathname to the specified program #
  165. # signal, send this signal to pathname #
  166. # #
  167. # Return values (as defined by LSB exit codes): #
  168. # 0 - program (pathname) has stopped/is already stopped or a #
  169. # running program has been sent specified signal and stopped #
  170. # successfully #
  171. # 1 - generic or unspecified error #
  172. # 2 - invalid or excessive argument(s) #
  173. # 5 - program is not installed #
  174. # 7 - program is not running and a signal was supplied #
  175. ################################################################################
  176. killproc()
  177. {
  178. local pidfile
  179. local program
  180. local prefix
  181. local progname
  182. local signal="-TERM"
  183. local fallback="-KILL"
  184. local nosig
  185. local pidlist
  186. local retval
  187. local pid
  188. local delay="30"
  189. local piddead
  190. local dtime
  191. # Process arguments
  192. while true; do
  193. case "${1}" in
  194. -p)
  195. pidfile="${2}"
  196. shift 2
  197. ;;
  198. *)
  199. program="${1}"
  200. if [ -n "${2}" ]; then
  201. signal="${2}"
  202. fallback=""
  203. else
  204. nosig=1
  205. fi
  206. # Error on additional arguments
  207. if [ -n "${3}" ]; then
  208. return 2
  209. else
  210. break
  211. fi
  212. ;;
  213. esac
  214. done
  215. # Check for a valid program
  216. if [ ! -e "${program}" ]; then return 5; fi
  217. # Check for a valid signal
  218. check_signal "${signal}"
  219. if [ "${?}" -ne "0" ]; then return 2; fi
  220. # Get a list of pids
  221. if [ -z "${pidfile}" ]; then
  222. # determine the pid by discovery
  223. pidlist=`pidofproc "${1}"`
  224. retval="${?}"
  225. else
  226. # The PID file contains the needed PIDs
  227. # Note that by LSB requirement, the path must be given to pidofproc,
  228. # however, it is not used by the current implementation or standard.
  229. pidlist=`pidofproc -p "${pidfile}" "${1}"`
  230. retval="${?}"
  231. fi
  232. # Return a value ONLY
  233. # It is the init script's (or distribution's functions) responsibilty
  234. # to log messages!
  235. case "${retval}" in
  236. 0)
  237. # Program is running correctly
  238. # Do nothing here, let killproc continue.
  239. ;;
  240. 1)
  241. # Program is not running, but an invalid pid file exists
  242. # Remove the pid file.
  243. rm -f "${pidfile}"
  244. # This is only a success if no signal was passed.
  245. if [ -n "${nosig}" ]; then
  246. return 0
  247. else
  248. return 7
  249. fi
  250. ;;
  251. 3)
  252. # Program is not running and no pidfile exists
  253. # This is only a success if no signal was passed.
  254. if [ -n "${nosig}" ]; then
  255. return 0
  256. else
  257. return 7
  258. fi
  259. ;;
  260. *)
  261. # Others as returned by status values shall not be interpreted
  262. # and returned as an unspecified error.
  263. return 1
  264. ;;
  265. esac
  266. # Perform different actions for exit signals and control signals
  267. check_sig_type "${signal}"
  268. if [ "${?}" -eq "0" ]; then # Signal is used to terminate the program
  269. # Account for empty pidlist (pid file still exists and no
  270. # signal was given)
  271. if [ "${pidlist}" != "" ]; then
  272. # Kill the list of pids
  273. for pid in ${pidlist}; do
  274. kill -0 "${pid}" 2> /dev/null
  275. if [ "${?}" -ne "0" ]; then
  276. # Process is dead, continue to next and assume all is well
  277. continue
  278. else
  279. kill "${signal}" "${pid}" 2> /dev/null
  280. # Wait up to ${delay}/10 seconds to for "${pid}" to
  281. # terminate in 10ths of a second
  282. while [ "${delay}" -ne "0" ]; do
  283. kill -0 "${pid}" 2> /dev/null || piddead="1"
  284. if [ "${piddead}" = "1" ]; then break; fi
  285. sleep 0.1
  286. delay="$(( ${delay} - 1 ))"
  287. done
  288. # If a fallback is set, and program is still running, then
  289. # use the fallback
  290. if [ -n "${fallback}" -a "${piddead}" != "1" ]; then
  291. kill "${fallback}" "${pid}" 2> /dev/null
  292. sleep 1
  293. # Check again, and fail if still running
  294. kill -0 "${pid}" 2> /dev/null && return 1
  295. fi
  296. fi
  297. done
  298. fi
  299. # Check for and remove stale PID files.
  300. if [ -z "${pidfile}" ]; then
  301. # Find the basename of $program
  302. prefix=`echo "${program}" | sed 's/[^/]*$//'`
  303. progname=`echo "${program}" | sed "s@${prefix}@@"`
  304. if [ -e "/var/run/${progname}.pid" ]; then
  305. rm -f "/var/run/${progname}.pid" 2> /dev/null
  306. fi
  307. else
  308. if [ -e "${pidfile}" ]; then rm -f "${pidfile}" 2> /dev/null; fi
  309. fi
  310. # For signals that do not expect a program to exit, simply
  311. # let kill do its job, and evaluate kill's return for value
  312. else # check_sig_type - signal is not used to terminate program
  313. for pid in ${pidlist}; do
  314. kill "${signal}" "${pid}"
  315. if [ "${?}" -ne "0" ]; then return 1; fi
  316. done
  317. fi
  318. }
  319. ################################################################################
  320. # pidofproc() #
  321. # Usage: pidofproc [-p pidfile] pathname #
  322. # #
  323. # Purpose: This function returns one or more pid(s) for a particular daemon #
  324. # #
  325. # Inputs: -p pidfile, use the specified pidfile instead of pidof #
  326. # pathname, path to the specified program #
  327. # #
  328. # Return values (as defined by LSB status codes): #
  329. # 0 - Success (PIDs to stdout) #
  330. # 1 - Program is dead, PID file still exists (remaining PIDs output) #
  331. # 3 - Program is not running (no output) #
  332. ################################################################################
  333. pidofproc()
  334. {
  335. local pidfile
  336. local program
  337. local prefix
  338. local progname
  339. local pidlist
  340. local lpids
  341. local exitstatus="0"
  342. # Process arguments
  343. while true; do
  344. case "${1}" in
  345. -p)
  346. pidfile="${2}"
  347. shift 2
  348. ;;
  349. *)
  350. program="${1}"
  351. if [ -n "${2}" ]; then
  352. # Too many arguments
  353. # Since this is status, return unknown
  354. return 4
  355. else
  356. break
  357. fi
  358. ;;
  359. esac
  360. done
  361. # If a PID file is not specified, try and find one.
  362. if [ -z "${pidfile}" ]; then
  363. # Get the program's basename
  364. prefix=`echo "${program}" | sed 's/[^/]*$//'`
  365. if [ -z "${prefix}" ]; then
  366. progname="${program}"
  367. else
  368. progname=`echo "${program}" | sed "s@${prefix}@@"`
  369. fi
  370. # If a PID file exists with that name, assume that is it.
  371. if [ -e "/var/run/${progname}.pid" ]; then
  372. pidfile="/var/run/${progname}.pid"
  373. fi
  374. fi
  375. # If a PID file is set and exists, use it.
  376. if [ -n "${pidfile}" -a -e "${pidfile}" ]; then
  377. # Use the value in the first line of the pidfile
  378. pidlist=`/bin/head -n1 "${pidfile}"`
  379. # This can optionally be written as 'sed 1q' to repalce 'head -n1'
  380. # should LFS move /bin/head to /usr/bin/head
  381. else
  382. # Use pidof
  383. pidlist=`pidof "${program}"`
  384. fi
  385. # Figure out if all listed PIDs are running.
  386. for pid in ${pidlist}; do
  387. kill -0 ${pid} 2> /dev/null
  388. if [ "${?}" -eq "0" ]; then
  389. lpids="${lpids}${pid} "
  390. else
  391. exitstatus="1"
  392. fi
  393. done
  394. if [ -z "${lpids}" -a ! -f "${pidfile}" ]; then
  395. return 3
  396. else
  397. echo "${lpids}"
  398. return "${exitstatus}"
  399. fi
  400. }
  401. ################################################################################
  402. # statusproc() #
  403. # Usage: statusproc [-p pidfile] pathname #
  404. # #
  405. # Purpose: This function prints the status of a particular daemon to stdout #
  406. # #
  407. # Inputs: -p pidfile, use the specified pidfile instead of pidof #
  408. # pathname, path to the specified program #
  409. # #
  410. # Return values: #
  411. # 0 - Status printed #
  412. # 1 - Input error. The daemon to check was not specified. #
  413. ################################################################################
  414. statusproc()
  415. {
  416. local pidfile
  417. local pidlist
  418. if [ "${#}" = "0" ]; then
  419. echo "Usage: statusproc [-p pidfle] {program}"
  420. exit 1
  421. fi
  422. # Process arguments
  423. while true; do
  424. case "${1}" in
  425. -p)
  426. pidfile="${2}"
  427. shift 2
  428. ;;
  429. *)
  430. if [ -n "${2}" ]; then
  431. echo "Too many arguments"
  432. return 1
  433. else
  434. break
  435. fi
  436. ;;
  437. esac
  438. done
  439. if [ -n "${pidfile}" ]; then
  440. pidlist=`pidofproc -p "${pidfile}" $@`
  441. else
  442. pidlist=`pidofproc $@`
  443. fi
  444. # Trim trailing blanks
  445. pidlist=`echo "${pidlist}" | sed -r 's/ +$//'`
  446. base="${1##*/}"
  447. if [ -n "${pidlist}" ]; then
  448. /bin/echo -e "${INFO}${base} is running with Process" \
  449. "ID(s) ${pidlist}.${NORMAL}"
  450. else
  451. if [ -n "${base}" -a -e "/var/run/${base}.pid" ]; then
  452. /bin/echo -e "${WARNING}${1} is not running but" \
  453. "/var/run/${base}.pid exists.${NORMAL}"
  454. else
  455. if [ -n "${pidfile}" -a -e "${pidfile}" ]; then
  456. /bin/echo -e "${WARNING}${1} is not running" \
  457. "but ${pidfile} exists.${NORMAL}"
  458. else
  459. /bin/echo -e "${INFO}${1} is not running.${NORMAL}"
  460. fi
  461. fi
  462. fi
  463. }
  464. ################################################################################
  465. # timespec() #
  466. # #
  467. # Purpose: An internal utility function to format a timestamp #
  468. # a boot log file. Sets the STAMP variable. #
  469. # #
  470. # Return value: Not used #
  471. ################################################################################
  472. timespec()
  473. {
  474. STAMP="$(echo `date +"%b %d %T %:z"` `hostname`) "
  475. return 0
  476. }
  477. ################################################################################
  478. # log_success_msg() #
  479. # Usage: log_success_msg ["message"] #
  480. # #
  481. # Purpose: Print a successful status message to the screen and #
  482. # a boot log file. #
  483. # #
  484. # Inputs: $@ - Message #
  485. # #
  486. # Return values: Not used #
  487. ################################################################################
  488. log_success_msg()
  489. {
  490. /bin/echo -n -e "${BMPREFIX}${@}"
  491. /bin/echo -e "${CURS_ZERO}${SUCCESS_PREFIX}${SET_COL}${SUCCESS_SUFFIX}"
  492. # Strip non-printable characters from log file
  493. logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
  494. timespec
  495. /bin/echo -e "${STAMP} ${logmessage} OK" >> ${BOOTLOG}
  496. return 0
  497. }
  498. log_success_msg2()
  499. {
  500. /bin/echo -n -e "${BMPREFIX}${@}"
  501. /bin/echo -e "${CURS_ZERO}${SUCCESS_PREFIX}${SET_COL}${SUCCESS_SUFFIX}"
  502. echo " OK" >> ${BOOTLOG}
  503. return 0
  504. }
  505. ################################################################################
  506. # log_failure_msg() #
  507. # Usage: log_failure_msg ["message"] #
  508. # #
  509. # Purpose: Print a failure status message to the screen and #
  510. # a boot log file. #
  511. # #
  512. # Inputs: $@ - Message #
  513. # #
  514. # Return values: Not used #
  515. ################################################################################
  516. log_failure_msg()
  517. {
  518. /bin/echo -n -e "${BMPREFIX}${@}"
  519. /bin/echo -e "${CURS_ZERO}${FAILURE_PREFIX}${SET_COL}${FAILURE_SUFFIX}"
  520. # Strip non-printable characters from log file
  521. timespec
  522. logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
  523. /bin/echo -e "${STAMP} ${logmessage} FAIL" >> ${BOOTLOG}
  524. return 0
  525. }
  526. log_failure_msg2()
  527. {
  528. /bin/echo -n -e "${BMPREFIX}${@}"
  529. /bin/echo -e "${CURS_ZERO}${FAILURE_PREFIX}${SET_COL}${FAILURE_SUFFIX}"
  530. echo "FAIL" >> ${BOOTLOG}
  531. return 0
  532. }
  533. ################################################################################
  534. # log_warning_msg() #
  535. # Usage: log_warning_msg ["message"] #
  536. # #
  537. # Purpose: Print a warning status message to the screen and #
  538. # a boot log file. #
  539. # #
  540. # Return values: Not used #
  541. ################################################################################
  542. log_warning_msg()
  543. {
  544. /bin/echo -n -e "${BMPREFIX}${@}"
  545. /bin/echo -e "${CURS_ZERO}${WARNING_PREFIX}${SET_COL}${WARNING_SUFFIX}"
  546. # Strip non-printable characters from log file
  547. logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
  548. timespec
  549. /bin/echo -e "${STAMP} ${logmessage} WARN" >> ${BOOTLOG}
  550. return 0
  551. }
  552. log_skip_msg()
  553. {
  554. /bin/echo -n -e "${BMPREFIX}${@}"
  555. /bin/echo -e "${CURS_ZERO}${SKIP_PREFIX}${SET_COL}${SKIP_SUFFIX}"
  556. # Strip non-printable characters from log file
  557. logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
  558. /bin/echo "SKIP" >> ${BOOTLOG}
  559. return 0
  560. }
  561. ################################################################################
  562. # log_info_msg() #
  563. # Usage: log_info_msg message #
  564. # #
  565. # Purpose: Print an information message to the screen and #
  566. # a boot log file. Does not print a trailing newline character. #
  567. # #
  568. # Return values: Not used #
  569. ################################################################################
  570. log_info_msg()
  571. {
  572. /bin/echo -n -e "${BMPREFIX}${@}"
  573. # Strip non-printable characters from log file
  574. logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
  575. timespec
  576. /bin/echo -n -e "${STAMP} ${logmessage}" >> ${BOOTLOG}
  577. return 0
  578. }
  579. log_info_msg2()
  580. {
  581. /bin/echo -n -e "${@}"
  582. # Strip non-printable characters from log file
  583. logmessage=`echo "${@}" | sed 's/\\\033[^a-zA-Z]*.//g'`
  584. /bin/echo -n -e "${logmessage}" >> ${BOOTLOG}
  585. return 0
  586. }
  587. ################################################################################
  588. # evaluate_retval() #
  589. # Usage: Evaluate a return value and print success or failyure as appropriate #
  590. # #
  591. # Purpose: Convenience function to terminate an info message #
  592. # #
  593. # Return values: Not used #
  594. ################################################################################
  595. evaluate_retval()
  596. {
  597. local error_value="${?}"
  598. if [ ${error_value} = 0 ]; then
  599. log_success_msg2
  600. else
  601. log_failure_msg2
  602. fi
  603. }
  604. ################################################################################
  605. # check_signal() #
  606. # Usage: check_signal [ -{signal} | {signal} ] #
  607. # #
  608. # Purpose: Check for a valid signal. This is not defined by any LSB draft, #
  609. # however, it is required to check the signals to determine if the #
  610. # signals chosen are invalid arguments to the other functions. #
  611. # #
  612. # Inputs: Accepts a single string value in the form or -{signal} or {signal} #
  613. # #
  614. # Return values: #
  615. # 0 - Success (signal is valid #
  616. # 1 - Signal is not valid #
  617. ################################################################################
  618. check_signal()
  619. {
  620. local valsig
  621. # Add error handling for invalid signals
  622. valsig="-ALRM -HUP -INT -KILL -PIPE -POLL -PROF -TERM -USR1 -USR2"
  623. valsig="${valsig} -VTALRM -STKFLT -PWR -WINCH -CHLD -URG -TSTP -TTIN"
  624. valsig="${valsig} -TTOU -STOP -CONT -ABRT -FPE -ILL -QUIT -SEGV -TRAP"
  625. valsig="${valsig} -SYS -EMT -BUS -XCPU -XFSZ -0 -1 -2 -3 -4 -5 -6 -8 -9"
  626. valsig="${valsig} -11 -13 -14 -15"
  627. echo "${valsig}" | grep -- " ${1} " > /dev/null
  628. if [ "${?}" -eq "0" ]; then
  629. return 0
  630. else
  631. return 1
  632. fi
  633. }
  634. ################################################################################
  635. # check_sig_type() #
  636. # Usage: check_signal [ -{signal} | {signal} ] #
  637. # #
  638. # Purpose: Check if signal is a program termination signal or a control signal #
  639. # This is not defined by any LSB draft, however, it is required to #
  640. # check the signals to determine if they are intended to end a #
  641. # program or simply to control it. #
  642. # #
  643. # Inputs: Accepts a single string value in the form or -{signal} or {signal} #
  644. # #
  645. # Return values: #
  646. # 0 - Signal is used for program termination #
  647. # 1 - Signal is used for program control #
  648. ################################################################################
  649. check_sig_type()
  650. {
  651. local valsig
  652. # The list of termination signals (limited to generally used items)
  653. valsig="-ALRM -INT -KILL -TERM -PWR -STOP -ABRT -QUIT -2 -3 -6 -9 -14 -15"
  654. echo "${valsig}" | grep -- " ${1} " > /dev/null
  655. if [ "${?}" -eq "0" ]; then
  656. return 0
  657. else
  658. return 1
  659. fi
  660. }
  661. ################################################################################
  662. # wait_for_user() #
  663. # #
  664. # Purpose: Wait for the user to respond if not a headless system #
  665. # #
  666. ################################################################################
  667. wait_for_user()
  668. {
  669. # Wait for the user by default
  670. [ "${HEADLESS=0}" = "0" ] && read ENTER
  671. return 0
  672. }
  673. ################################################################################
  674. # is_true() #
  675. # #
  676. # Purpose: Utility to test if a variable is true | yes | 1 #
  677. # #
  678. ################################################################################
  679. is_true()
  680. {
  681. [ "$1" = "1" ] || [ "$1" = "yes" ] || [ "$1" = "true" ] || [ "$1" = "y" ] ||
  682. [ "$1" = "t" ]
  683. }
  684. # CUSTOM FUCTIONS
  685. # Description : Mount proc, sysfs, and run
  686. start_mountvirtfs(){
  687. # Make sure /run is available before logging any messages
  688. if ! mountpoint /run >/dev/null; then
  689. mount /run || failed=1
  690. fi
  691. mkdir -p /run/lock /run/shm
  692. chmod 1777 /run/shm /run/lock
  693. log_info_msg "Mounting virtual file systems: ${INFO}/run"
  694. if ! mountpoint /proc >/dev/null; then
  695. log_info_msg2 " ${INFO}/proc"
  696. mount -o nosuid,noexec,nodev /proc || failed=1
  697. fi
  698. if ! mountpoint /sys >/dev/null; then
  699. log_info_msg2 " ${INFO}/sys"
  700. mount -o nosuid,noexec,nodev /sys || failed=1
  701. fi
  702. if ! mountpoint /dev >/dev/null; then
  703. log_info_msg2 " ${INFO}/dev"
  704. mount -o mode=0755,nosuid /dev || failed=1
  705. fi
  706. ln -sfn /run/shm /dev/shm
  707. (exit ${failed})
  708. evaluate_retval
  709. }
  710. # Description: Loads modules listed in /etc/sysconfig/modules.
  711. start_load_modules(){
  712. # Assure that the kernel has module support.
  713. [ -e /proc/modules ] || return 0
  714. for FILE in /etc/sysconfig/modules /etc/sysconfig/modules.d/*.conf
  715. do
  716. [ ! -f $FILE ] && continue
  717. # Continue with next if there's no modules file or there are no
  718. # valid entries
  719. [ -r $FILE ] || continue
  720. egrep -qv '^($|#)' $FILE || continue
  721. log_info_msg "Loading modules:"
  722. break
  723. done
  724. for FILE in /etc/sysconfig/modules /etc/sysconfig/modules.d/*.conf
  725. do
  726. [ ! -f $FILE ] && continue
  727. [ -r $FILE ] || continue
  728. egrep -qv '^($|#)' $FILE || continue
  729. while read module args; do
  730. # Ignore comments and blank lines.
  731. case "$module" in
  732. ""|"#"*) continue ;;
  733. esac
  734. # Attempt to load the module, passing any arguments provided.
  735. modprobe ${module} ${args} >/dev/null
  736. # Print the module name if successful, otherwise take note.
  737. if [ $? -eq 0 ]; then
  738. log_info_msg2 " ${module}"
  739. else
  740. failedmod="${failedmod} ${module}"
  741. fi
  742. done < $FILE
  743. log_success_msg2
  744. done
  745. # fi
  746. # Print a message about successfully loaded modules on the correct line.
  747. # Print a failure message with a list of any modules that
  748. # may have failed to load.
  749. if [ -n "${failedmod}" ]; then
  750. log_failure_msg "Failed to load modules:${failedmod}"
  751. fi
  752. return 0
  753. }
  754. # Description: Sets the hostname of the machine and starts the loopback interface.
  755. start_localnet(){
  756. [ -r /etc/sysconfig/network ] && . /etc/sysconfig/network
  757. [ -r /etc/hostname ] && HOSTNAME=`cat /etc/hostname`
  758. log_info_msg "Bringing up the loopback interface..."
  759. ip addr add 127.0.0.1/8 label lo dev lo
  760. ip link set lo up
  761. evaluate_retval
  762. log_info_msg "Setting hostname to ${HOSTNAME}..."
  763. hostname ${HOSTNAME}
  764. evaluate_retval
  765. }
  766. stop_localnet(){
  767. log_info_msg "Bringing down the loopback interface..."
  768. ip link set lo down
  769. evaluate_retval
  770. }
  771. status_localnet(){
  772. echo "Hostname is: $(hostname)"
  773. ip link show lo
  774. }
  775. # Description: Mounts a tempfs on /dev and starts the udevd daemon. Device nodes are created as defined by udev.
  776. start_udev(){
  777. log_info_msg "Populating /dev with device nodes... "
  778. if ! grep -q '[[:space:]]sysfs' /proc/mounts; then
  779. log_failure_msg2
  780. msg="FAILURE:\n\nUnable to create "
  781. msg="${msg}devices without a SysFS filesystem\n\n"
  782. msg="${msg}After you press Enter, this system "
  783. msg="${msg}will be halted and powered off.\n\n"
  784. log_info_msg "$msg"
  785. log_info_msg "Press Enter to continue..."
  786. wait_for_user
  787. /etc/rc.d/init.d/halt stop
  788. fi
  789. # Udev handles uevents itself, so we don't need to have
  790. # the kernel call out to any binary in response to them
  791. [ -f /proc/sys/kernel/hotplug ] && echo > /proc/sys/kernel/hotplug
  792. # Start the udev daemon to continually watch for, and act on,
  793. # uevents
  794. /sbin/udevd --daemon --resolve-names=never
  795. # Now traverse /sys in order to "coldplug" devices that have
  796. # already been discovered
  797. /sbin/udevadm trigger --action=add --type=subsystems
  798. /sbin/udevadm trigger --action=add --type=devices
  799. /sbin/udevadm trigger --action=change --type=devices
  800. # Now wait for udevd to process the uevents we triggered
  801. if ! is_true "$OMIT_UDEV_SETTLE"; then
  802. /sbin/udevadm settle
  803. fi
  804. # If any LVM based partitions are on the system, ensure they
  805. # are activated so they can be used.
  806. if [ -x /sbin/vgchange ]; then /sbin/vgchange -a y >/dev/null; fi
  807. log_success_msg2
  808. }
  809. # Description: Mounts and unmounts swap partitions defined in /etc/fstab.
  810. start_swap(){
  811. log_info_msg "Activating all swap files/partitions..."
  812. swapon -a
  813. evaluate_retval
  814. }
  815. stop_swap(){
  816. log_info_msg "Deactivating all swap files/partitions..."
  817. swapoff -a
  818. evaluate_retval
  819. }
  820. status_swap(){
  821. log_success_msg "Retrieving swap status."
  822. swapon -s
  823. }
  824. # Description: Checks local filesystems before mounting.
  825. start_checkfs(){
  826. if [ -f /fastboot ]; then
  827. msg="/fastboot found, will omit "
  828. msg="${msg} file system checks as requested.\n"
  829. log_info_msg "${msg}"
  830. return 0
  831. fi
  832. # if system is live image then pass checkfs
  833. mount | grep "live-rw on /" > /dev/null
  834. [ ${?} -eq 0 ] && return 0
  835. log_info_msg "Mounting root file system in read-only mode... "
  836. mount -n -o remount,ro / >/dev/null
  837. if [ ${?} != 0 ]; then
  838. log_failure_msg2
  839. msg="\n\nCannot check root "
  840. msg="${msg}filesystem because it could not be mounted "
  841. msg="${msg}in read-only mode.\n\n"
  842. msg="${msg}After you press Enter, this system will be "
  843. msg="${msg}halted and powered off.\n\n"
  844. log_failure_msg "${msg}"
  845. log_info_msg "Press Enter to continue..."
  846. wait_for_user
  847. /etc/rc.d/init.d/halt stop
  848. else
  849. log_success_msg2
  850. fi
  851. if [ -f /forcefsck ]; then
  852. msg="/forcefsck found, forcing file"
  853. msg="${msg} system checks as requested."
  854. log_success_msg "$msg"
  855. options="-f"
  856. else
  857. options=""
  858. fi
  859. log_info_msg "Checking file systems..."
  860. # Note: -a option used to be -p; but this fails e.g. on fsck.minix
  861. if is_true "$VERBOSE_FSCK"; then
  862. fsck ${options} -a -A -C -T
  863. else
  864. fsck ${options} -a -A -C -T >/dev/null
  865. fi
  866. error_value=${?}
  867. if [ "${error_value}" = 0 ]; then
  868. log_success_msg2
  869. fi
  870. if [ "${error_value}" = 1 ]; then
  871. msg="\nWARNING:\n\nFile system errors "
  872. msg="${msg}were found and have been corrected.\n"
  873. msg="${msg} You may want to double-check that "
  874. msg="${msg}everything was fixed properly."
  875. log_warning_msg "$msg"
  876. fi
  877. if [ "${error_value}" = 2 -o "${error_value}" = 3 ]; then
  878. msg="\nWARNING:\n\nFile system errors "
  879. msg="${msg}were found and have been been "
  880. msg="${msg}corrected, but the nature of the "
  881. msg="${msg}errors require this system to be rebooted.\n\n"
  882. msg="${msg}After you press enter, "
  883. msg="${msg}this system will be rebooted\n\n"
  884. log_failure_msg "$msg"
  885. log_info_msg "Press Enter to continue..."
  886. wait_for_user
  887. reboot -f
  888. fi
  889. if [ "${error_value}" -gt 3 -a "${error_value}" -lt 16 ]; then
  890. msg="\nFAILURE:\n\nFile system errors "
  891. msg="${msg}were encountered that could not be "
  892. msg="${msg}fixed automatically.\nThis system "
  893. msg="${msg}cannot continue to boot and will "
  894. msg="${msg}therefore be halted until those "
  895. msg="${msg}errors are fixed manually by a "
  896. msg="${msg}System Administrator.\n\n"
  897. msg="${msg}After you press Enter, this system will be "
  898. msg="${msg}halted and powered off.\n\n"
  899. log_failure_msg "$msg"
  900. log_info_msg "Press Enter to continue..."
  901. wait_for_user
  902. /etc/rc.d/init.d/halt stop
  903. fi
  904. if [ "${error_value}" -ge 16 ]; then
  905. msg="FAILURE:\n\nUnexpected failure "
  906. msg="${msg}running fsck. Exited with error "
  907. msg="${msg} code: ${error_value}.\n"
  908. log_info_msg $msg
  909. return ${error_value}
  910. fi
  911. return 0
  912. }
  913. # Description: Remounts root filesystem read/write and mounts all remaining local filesystems defined in /etc/fstab on start.
  914. # Remounts root filesystem read-only and unmounts remaining filesystems on stop.
  915. start_mountfs(){
  916. log_info_msg "Remounting root file system in read-write mode..."
  917. mount --options remount,rw / >/dev/null
  918. evaluate_retval
  919. # Remove fsck-related file system watermarks.
  920. rm -f /fastboot /forcefsck
  921. # Make sure /dev/pts exists
  922. mkdir -p /dev/pts
  923. # This will mount all filesystems that do not have _netdev in
  924. # their option list. _netdev denotes a network filesystem.
  925. log_info_msg "Mounting remaining file systems..."
  926. mount --all --test-opts no_netdev >/dev/null
  927. evaluate_retval
  928. return $failed
  929. }
  930. stop_mountfs(){
  931. # Don't unmount virtual file systems like /run
  932. log_info_msg "Unmounting all other currently mounted file systems..."
  933. # Ensure any loop devies are removed
  934. losetup -D
  935. umount --all --detach-loop --read-only --types notmpfs,nosysfs,nodevtmpfs,noproc,nodevpts >/dev/null
  936. evaluate_retval
  937. # Make sure / is mounted read only (umount bug)
  938. mount --options remount,ro /
  939. # Make all LVM volume groups unavailable, if appropriate
  940. # This fails if swap or / are on an LVM partition
  941. #if [ -x /sbin/vgchange ]; then /sbin/vgchange -an > /dev/null; fi
  942. }
  943. # Description: On boot, system time is obtained from hwclock. The hardware clock can also be set on shutdown.
  944. oper_clock(){
  945. [ -z $1 ] && return 1
  946. local oper=$1
  947. [ -r /etc/sysconfig/clock ] && . /etc/sysconfig/clock
  948. case "${UTC}" in
  949. yes|true|1)
  950. CLOCKPARAMS="${CLOCKPARAMS} --utc"
  951. ;;
  952. no|false|0)
  953. CLOCKPARAMS="${CLOCKPARAMS} --localtime"
  954. ;;
  955. esac
  956. if [ "$oper" == "start" ];then
  957. [ ! -z $TZ ] && TIMEZONE=$TZ
  958. [ ! -z $TIMEZONE ] && ln -sf /usr/share/zoneinfo/$TIMEZONE /etc/localtime
  959. hwclock --hctosys ${CLOCKPARAMS} >/dev/null
  960. fi
  961. if [ "$oper" == "stop" ];then
  962. log_info_msg "Setting hardware clock..."
  963. hwclock --systohc ${CLOCKPARAMS} >/dev/null
  964. evaluate_retval
  965. fi
  966. }
  967. # Description: Cleans temporary directories /var/run, /var/lock, and optionally, /tmp.
  968. # cleanfs also creates /var/run/utmp and any files defined in /etc/sysconfig/createfiles.
  969. # Function to create files/directory on boot.
  970. create_files() {
  971. # Input to file descriptor 9 and output to stdin (redirection)
  972. exec 9>&0 < /etc/sysconfig/createfiles
  973. while read name type perm usr grp dtype maj min junk
  974. do
  975. # Ignore comments and blank lines.
  976. case "${name}" in
  977. ""|\#*) continue ;;
  978. esac
  979. # Ignore existing files.
  980. if [ ! -e "${name}" ]; then
  981. # Create stuff based on its type.
  982. case "${type}" in
  983. dir)
  984. mkdir "${name}"
  985. ;;
  986. file)
  987. :> "${name}"
  988. ;;
  989. dev)
  990. case "${dtype}" in
  991. char)
  992. mknod "${name}" c ${maj} ${min}
  993. ;;
  994. block)
  995. mknod "${name}" b ${maj} ${min}
  996. ;;
  997. pipe)
  998. mknod "${name}" p
  999. ;;
  1000. *)
  1001. log_warning_msg "\nUnknown device type: ${dtype}"
  1002. ;;
  1003. esac
  1004. ;;
  1005. *)
  1006. log_warning_msg "\nUnknown type: ${type}"
  1007. continue
  1008. ;;
  1009. esac
  1010. # Set up the permissions, too.
  1011. chown ${usr}:${grp} "${name}"
  1012. chmod ${perm} "${name}"
  1013. fi
  1014. done
  1015. # Close file descriptor 9 (end redirection)
  1016. exec 0>&9 9>&-
  1017. return 0
  1018. }
  1019. start_cleanfs(){
  1020. log_info_msg "Cleaning file systems:"
  1021. if [ "${SKIPTMPCLEAN}" = "" ]; then
  1022. log_info_msg2 " /tmp"
  1023. cd /tmp &&
  1024. find . -xdev -mindepth 1 ! -name lost+found -delete || failed=1
  1025. fi
  1026. > /var/run/utmp
  1027. if grep -q '^utmp:' /etc/group ; then
  1028. chmod 664 /var/run/utmp
  1029. chgrp utmp /var/run/utmp
  1030. fi
  1031. (return ${failed})
  1032. evaluate_retval
  1033. if egrep -qv '^(#|$)' /etc/sysconfig/createfiles 2>/dev/null; then
  1034. log_info_msg "Creating files and directories... "
  1035. create_files # Always returns 0
  1036. evaluate_retval
  1037. fi
  1038. return $failed
  1039. }
  1040. # Description: Replays any failed uevents that were skipped due to slow hardware initialization,
  1041. # and creates those needed device nodes
  1042. start_udev_retry(){
  1043. log_info_msg "Retrying failed uevents, if any..."
  1044. # As of udev-186, the --run option is no longer valid
  1045. #rundir=$(/sbin/udevadm info --run)
  1046. rundir=/run/udev
  1047. # From Debian: "copy the rules generated before / was mounted
  1048. # read-write":
  1049. for file in ${rundir}/tmp-rules--*; do
  1050. dest=${file##*tmp-rules--}
  1051. [ "$dest" = '*' ] && break
  1052. cat $file >> /etc/udev/rules.d/$dest
  1053. rm -f $file
  1054. done
  1055. # Re-trigger the uevents that may have failed,
  1056. # in hope they will succeed now
  1057. /bin/sed -e 's/#.*$//' /etc/sysconfig/udev_retry | /bin/grep -v '^$' | \
  1058. while read line ; do
  1059. for subsystem in $line ; do
  1060. /sbin/udevadm trigger --subsystem-match=$subsystem --action=add
  1061. done
  1062. done
  1063. # Now wait for udevd to process the uevents we triggered
  1064. if ! is_true "$OMIT_UDEV_RETRY_SETTLE"; then
  1065. /sbin/udevadm settle
  1066. fi
  1067. evaluate_retval
  1068. }
  1069. # Description: Sets up fonts and language settings for the user's local as defined by /etc/sysconfig/console.
  1070. start_console(){
  1071. [ -r /etc/sysconfig/console ] && . /etc/sysconfig/console
  1072. local failed=0
  1073. # See if we need to do anything
  1074. if [ -z "${KEYMAP}" ] && [ -z "${KEYMAP_CORRECTIONS}" ] &&
  1075. [ -z "${FONT}" ] && [ -z "${LEGACY_CHARSET}" ] &&
  1076. ! is_true "${UNICODE}"; then
  1077. return 0
  1078. fi
  1079. # There should be no bogus failures below this line!
  1080. log_info_msg "Setting up Linux console..."
  1081. # Figure out if a framebuffer console is used
  1082. [ -d /sys/class/graphics/fb0 ] && use_fb=1 || use_fb=0
  1083. # Figure out the command to set the console into the
  1084. # desired mode
  1085. is_true "${UNICODE}" &&
  1086. MODE_COMMAND="echo -en '\033%G' && kbd_mode -u" ||
  1087. MODE_COMMAND="echo -en '\033%@\033(K' && kbd_mode -a"
  1088. # On framebuffer consoles, font has to be set for each vt in
  1089. # UTF-8 mode. This doesn't hurt in non-UTF-8 mode also.
  1090. ! is_true "${use_fb}" || [ -z "${FONT}" ] ||
  1091. MODE_COMMAND="${MODE_COMMAND} && setfont ${FONT}"
  1092. # Apply that command to all consoles mentioned in
  1093. # /etc/inittab. Important: in the UTF-8 mode this should
  1094. # happen before setfont, otherwise a kernel bug will
  1095. # show up and the unicode map of the font will not be
  1096. # used.
  1097. for TTY in `grep '^[^#].*respawn:/sbin/agetty' /etc/inittab |
  1098. grep -o '\btty[[:digit:]]*\b'`
  1099. do
  1100. openvt -f -w -c ${TTY#tty} -- \
  1101. /bin/sh -c "${MODE_COMMAND}" || failed=1
  1102. done
  1103. # Set the font (if not already set above) and the keymap
  1104. [ "${use_fb}" == "1" ] || [ -z "${FONT}" ] || setfont $FONT || failed=1
  1105. [ -z "${KEYMAP}" ] ||
  1106. loadkeys ${KEYMAP} >/dev/null 2>&1 ||
  1107. failed=1
  1108. [ -z "${KEYMAP_CORRECTIONS}" ] ||
  1109. loadkeys ${KEYMAP_CORRECTIONS} >/dev/null 2>&1 ||
  1110. failed=1
  1111. # Convert the keymap from $LEGACY_CHARSET to UTF-8
  1112. [ -z "$LEGACY_CHARSET" ] ||
  1113. dumpkeys -c "$LEGACY_CHARSET" | loadkeys -u >/dev/null 2>&1 ||
  1114. failed=1
  1115. # If any of the commands above failed, the trap at the
  1116. # top would set $failed to 1
  1117. ( return $failed )
  1118. evaluate_retval
  1119. return $failed
  1120. }
  1121. # Description: Makes changes to the proc filesystem as defined in /etc/sysctl.conf. See 'man sysctl(8)'.
  1122. start_sysctl(){
  1123. if [ -f "/etc/sysctl.conf" ]; then
  1124. log_info_msg "Setting kernel runtime parameters..."
  1125. sysctl -q -p
  1126. evaluate_retval
  1127. fi
  1128. }
  1129. status_sysctl(){
  1130. sysctl -a
  1131. }
  1132. # Description: kernel cmdline parameter procesc
  1133. start_cmdline(){
  1134. log_info_msg "Setting cmdline parameters..."
  1135. log_info_msg "\n"
  1136. # Language settings
  1137. _language=$(cat /proc/cmdline | tr " " "\n" | grep -E "^LANGUAGE=.*" | cut -d'=' -f2)
  1138. if [ ! -z ${_language} ];then
  1139. cat > /etc/profile.d/i18n.sh << EOF
  1140. # Set up i18n variables
  1141. export LC_ALL=${_language}
  1142. export LANGUAGE=${_language}
  1143. export LANG=${_language}
  1144. EOF
  1145. sed -i 's;^LANG=.*;LANG='"$_language"';' /etc/environment
  1146. fi
  1147. # Keyboard settings / keymap is for console & keyboard is layout for X
  1148. _keymap=$(cat /proc/cmdline | tr " " "\n" | grep -E "^KEYMAP=.*" | cut -d'=' -f2)
  1149. _keyboard=$(cat /proc/cmdline | tr " " "\n" | grep -E "^KEYBOARD=.*" | cut -d'=' -f2)
  1150. if [ ! -z ${_keymap} ];then
  1151. sed -i 's;^KEYMAP=.*;KEYMAP='"$_keymap"';' /etc/sysconfig/rc.site
  1152. sed -i 's;^#KEYMAP=.*;KEYMAP='"$_keymap"';' /etc/sysconfig/rc.site
  1153. fi
  1154. [ ! -z ${_keyboard} ] && echo "${_keyboard}" > /root/.Xkbmap
  1155. return 0
  1156. }
  1157. # End /etc/rc.d/functions