Advertisement
Guest User

Untitled

a guest
Apr 24th, 2019
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 50.70 KB | None | 0 0
  1. #!/bin/dash
  2. # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. #
  6. # NOTE: This script works in dash, but is not as featureful. Specifically,
  7. # dash omits readline support (history & command line editing). So we try
  8. # to run through bash if it exists, otherwise we stick to dash. All other
  9. # code should be coded to the POSIX standard and avoid bashisms.
  10. #
  11. # Please test that any changes continue to work in dash by running
  12. # '/build/$BOARD/bin/dash crosh --dash' before checking them in.
  13. # Disable path expansion at the command line. None of our builtins need or want
  14. # it, and it's safer/saner to disallow it in the first place.
  15. set -f
  16. # Don't allow SIGHUP to terminate crosh. This guarantees that even if the user
  17. # closes the crosh window, we make our way back up to the main loop, which gives
  18. # cleanup code in command handlers a chance to run.
  19. trap '' HUP
  20. # Do not let CTRL+C or CTRL+\ kill crosh itself. This does let the user kill
  21. # commands that are run by crosh (like `ping`).
  22. trap : INT QUIT
  23. # If it exists, use $DATA_DIR to define the $HOME location, as a first step
  24. # to entirely removing the use of $HOME. (Though HOME should be used as
  25. # fall-back when DATA_DIR is unset.)
  26. # TODO(keescook): remove $HOME entirely crbug.com/333031
  27. if [ "${DATA_DIR+set}" = "set" ]; then
  28. export HOME="${DATA_DIR}/user"
  29. fi
  30. IS_BASH=0
  31. try_bash() {
  32. # If dash was explicitly requested, then nothing to do.
  33. case " $* " in
  34. *" --dash "*) return 0;;
  35. esac
  36. # If we're already bash, then nothing to do.
  37. if type "history" 2>/dev/null | grep -q "shell builtin"; then
  38. IS_BASH=1
  39. return 0
  40. fi
  41. # Still here? Relaunch in bash.
  42. exec /bin/bash "$0" "$@"
  43. }
  44. try_bash "$@"
  45. INTRO_TEXT="Welcome to crosh, the Chrome OS developer shell.
  46. If you got here by mistake, don't panic! Just close this tab and carry on.
  47. Type 'help' for a list of commands.
  48. If you want to customize the look/behavior, you can use the options page.
  49. Load it by using the Ctrl+Shift+P keyboard shortcut.
  50. "
  51. # Gets set to "1" when in dev mode.
  52. CROSH_DEVMODE=
  53. # Gets set to "1" when running on removable media (e.g. USB stick).
  54. CROSH_REMOVABLE=
  55. CROSH_MODPATH="/usr/share/crosh"
  56. check_digits() {
  57. expr "$1" : '^[[:digit:]]*$' > /dev/null
  58. }
  59. # Load all modules found in the specified subdir.
  60. load_modules() {
  61. local subdir="$1"
  62. local dir="${CROSH_MODPATH}/${subdir}"
  63. local mod
  64. # Turn on path expansion long enough to find local modules.
  65. set +f
  66. for mod in "${dir}"/[0-9][0-9]-*.sh; do
  67. # Then turn path expansion back off.
  68. set -f
  69. if [ -e "${mod}" ]; then
  70. echo "Loading extra module: ${mod}"
  71. . "${mod}" || :
  72. fi
  73. done
  74. }
  75. load_extra_crosh() {
  76. # First load the common modules (board/project/etc... specific).
  77. load_modules "extra.d"
  78. # Load the removable modules, if the rootfs is on removable
  79. # media. e.g. It's a USB stick.
  80. if [ -z "${CROSH_REMOVABLE}" ]; then
  81. local src
  82. if [ -e /usr/share/misc/chromeos-common.sh ]; then
  83. . "/usr/share/misc/chromeos-common.sh" || exit 1
  84. src=$(get_block_dev_from_partition_dev "$(rootdev -s)")
  85. local removable="$(cat "/sys/block/${src#/dev/}/removable" 2>/dev/null)"
  86. if [ "${removable}" = "1" ]; then
  87. CROSH_REMOVABLE="1"
  88. fi
  89. fi
  90. fi
  91. if [ "${CROSH_REMOVABLE}" = "1" ]; then
  92. load_modules "removable.d"
  93. fi
  94. # Load the dev-mode modules, if in dev mode, or if forced.
  95. # This comes last so it can override any release modules.
  96. if [ -z "${CROSH_DEVMODE}" ]; then
  97. if type crossystem >/dev/null 2>&1; then
  98. crossystem "cros_debug?1"
  99. CROSH_DEVMODE=$((!$?))
  100. else
  101. echo "Could not locate 'crossystem'; assuming devmode is off."
  102. fi
  103. fi
  104. if [ "${CROSH_DEVMODE}" = "1" ]; then
  105. load_modules "dev.d"
  106. fi
  107. }
  108. shell_read() {
  109. local prompt="$1"
  110. shift
  111. if [ "$IS_BASH" -eq "1" ]; then
  112. # In bash, -e gives readline support.
  113. read -p "$prompt" -e "$@"
  114. else
  115. read -p "$prompt" "$@"
  116. fi
  117. }
  118. shell_history() {
  119. if [ "$IS_BASH" -eq "1" ]; then
  120. # In bash, the history builtin can be used to manage readline history
  121. history "$@"
  122. fi
  123. }
  124. shell_history_init() {
  125. # Do not set any HISTXXX vars until after security check below.
  126. local histfile="${HOME}/.crosh_history"
  127. # Limit the history to the last 100 entries to keep the file from growing
  128. # out of control (unlikely, but let's be safe).
  129. local histsize="100"
  130. # For security sake, let's clean up the file before we let the shell get a
  131. # chance to read it. Clean out any non-printable ASCII chars (sorry UTF8
  132. # users) as it's the easiest way to be sure. We limit to 4k to be sane.
  133. # We need a tempfile on the same device to avoid races w/multiple crosh
  134. # tabs opening at the same time.
  135. local tmpfile
  136. if ! tmpfile="$(mktemp "${histfile}.XXXXXX")"; then
  137. echo "warning: could not clean up history; ignoring it"
  138. return
  139. fi
  140. # Ignore cat errors in case it doesn't exist yet.
  141. cat "${histfile}" 2>/dev/null |
  142. tr -dc '[:print:]\t\n' |
  143. tail -n "${histsize}" |
  144. tail -c 4096 > "${tmpfile}"
  145. if ! mv "${tmpfile}" "${histfile}"; then
  146. echo "warning: could not clean up history; ignoring it"
  147. rm -f "${tmpfile}"
  148. return
  149. fi
  150. # Set this before any other history settings as some of them implicitly
  151. # operate on this file.
  152. HISTFILE="${histfile}"
  153. # Now we can limit the size of the history file.
  154. HISTSIZE=${histsize}
  155. HISTFILESIZE=${histsize}
  156. # Do not add entries that begin with a space, and dedupe sequential commands.
  157. HISTCONTROL="ignoreboth"
  158. # Initialize pseudo completion support. Do it before we load the user's
  159. # history so that new entries don't come after old ones.
  160. if [ ${IS_BASH} -eq 1 ]; then
  161. local f
  162. for f in $(registered_visible_commands); do
  163. # Do not add duplicates to avoid ballooning history.
  164. grep -qs "^${f} *$" "${HISTFILE}" || shell_history -s "${f}"
  165. done
  166. fi
  167. # Now load the user's history.
  168. shell_history -r "${HISTFILE}"
  169. }
  170. # Returns status 0 if the argument is a valid positive integer
  171. # (i.e. it's not the null string, and contains only digits).
  172. is_numeric() {
  173. ! echo "$1" | grep -qE '[^0-9]|^$'
  174. }
  175. # Prints the value corresponding to the passed-in field in the output from
  176. # dump_power_status.
  177. get_power_status_field() {
  178. local field="$1"
  179. dump_power_status | awk -v field="${field}" '$1 == field { print $2 }'
  180. }
  181. # Returns value of variable with given name.
  182. expand_var() {
  183. local var="$1"
  184. eval echo "\"\$${var}\""
  185. }
  186. # Determine whether the variable is set in the environment.
  187. var_is_set() {
  188. local var="$1"
  189. [ "$(expand_var "{${var}+set}")" = "set" ]
  190. }
  191. USAGE_help='[command]'
  192. HELP_help='
  193. Display general help, or details for a specific command.
  194. '
  195. cmd_help() (
  196. local cmd
  197. case $# in
  198. 0)
  199. local cmds="exit help help_advanced ping top"
  200. for cmd in ${cmds}; do
  201. cmd_help "${cmd}"
  202. done
  203. ;;
  204. 1)
  205. # The ordering and relationship of variables here is subtle.
  206. # Consult README.md for more details.
  207. cmd="$1"
  208. if ! registered_crosh_command "${cmd}"; then
  209. echo "help: unknown command '${cmd}'"
  210. return 1
  211. elif ! check_command_available "${cmd}"; then
  212. echo "help: command '${cmd}' is not available"
  213. return 1
  214. else
  215. # If the command has a custom help func, call it.
  216. if registered_crosh_command_help "${cmd}"; then
  217. # Make sure the output is at least somewhat close to our standardized
  218. # form below. We always want the program name first and a blank line
  219. # at the end. This way `help_advanced` isn't completely ugly.
  220. echo "${cmd}"
  221. # The sed statement trims the first & last lines if they're blank.
  222. "help_${cmd}" | sed -e '1{/^$/d}' -e '${/^$/d}'
  223. echo
  224. elif var_is_set "USAGE_${cmd}"; then
  225. # Only show this function if the usage strings are actually set.
  226. local usage="$(expand_var "USAGE_${cmd}")"
  227. local help="$(expand_var "HELP_${cmd}")"
  228. printf '%s %s %s\n\n' "${cmd}" "${usage}" "${help}"
  229. fi
  230. fi
  231. ;;
  232. *)
  233. help "too many arguments"
  234. return 1
  235. ;;
  236. esac
  237. )
  238. # Useful alias for commands to call us.
  239. help() {
  240. if [ $# -ne 0 ]; then
  241. printf 'ERROR: %s\n\n' "$*"
  242. fi
  243. # This is set by `dispatch` when a valid command has been found.
  244. if [ -n "${CURRENT_COMMAND}" ]; then
  245. cmd_help "${CURRENT_COMMAND}"
  246. fi
  247. }
  248. USAGE_help_advanced=''
  249. HELP_help_advanced='
  250. Display the help for more advanced commands, mainly used for debugging.
  251. '
  252. cmd_help_advanced() (
  253. local cmd
  254. if [ $# -ne 0 ]; then
  255. help "too many arguments"
  256. return 1
  257. fi
  258. for cmd in $(registered_visible_commands); do
  259. if check_command_available "${cmd}"; then
  260. cmd_help "${cmd}"
  261. fi
  262. done
  263. )
  264. # We move the trailing brace to the next line so that we avoid the style
  265. # checker from rejecting the use of braces. We cannot use subshells here
  266. # as we want the set the exit variable in crosh itself.
  267. # http://crbug.com/318368
  268. USAGE_exit=''
  269. HELP_exit='
  270. Exit crosh.
  271. '
  272. cmd_exit()
  273. {
  274. exit='y'
  275. }
  276. USAGE_set_time='[<time string>]'
  277. HELP_set_time='
  278. Sets the system time if the the system has been unable to get it from the
  279. network. The <time string> uses the format of the GNU coreutils date command.
  280. '
  281. cmd_set_time() (
  282. local spec="$*"
  283. if [ -z "${spec}" ]; then
  284. echo "A date/time specification is required."
  285. echo "E.g., set_time 10 February 2012 11:21am"
  286. echo "(Remember to set your timezone in Settings first.)"
  287. return
  288. fi
  289. local sec status
  290. sec=$(date +%s --date="${spec}" 2>&1)
  291. status=$?
  292. if [ ${status} -ne 0 -o -z "${sec}" ]; then
  293. echo "Unable to understand the specified time:"
  294. echo "${sec}"
  295. return
  296. fi
  297. local reply
  298. reply=$(dbus-send --system --type=method_call --print-reply \
  299. --dest=org.torproject.tlsdate /org/torproject/tlsdate \
  300. org.torproject.tlsdate.SetTime "int64:$((sec))" 2>/dev/null)
  301. status=$?
  302. if [ ${status} -ne 0 ]; then
  303. echo "Time not set. Unable to communicate with the time service."
  304. return
  305. fi
  306. # Reply format: <dbus response header>\n uint32 <code>\n
  307. local code
  308. code=$(echo "${reply}" | sed -n -E '$s/.*uint32 ([0-9]).*/\1/p')
  309. case "${code}" in
  310. 0)
  311. echo "Time has been set."
  312. ;;
  313. 1)
  314. echo "Requested time was invalid (too large or too small): ${sec}"
  315. ;;
  316. 2)
  317. echo "Time not set. Network time cannot be overriden."
  318. ;;
  319. 3)
  320. echo "Time not set. There was a communication error."
  321. ;;
  322. *)
  323. echo "An unexpected response was received: ${code}"
  324. echo "Details: ${reply}"
  325. esac
  326. )
  327. # Check if a particular Chrome feature is enabled.
  328. # Use the DBus method name as the parameter.
  329. is_chrome_feature_enabled() {
  330. local method="$1"
  331. local reply status
  332. reply=$(dbus-send --system --type=method_call --print-reply \
  333. --dest=org.chromium.ChromeFeaturesService \
  334. /org/chromium/ChromeFeaturesService \
  335. "org.chromium.ChromeFeaturesServiceInterface.${method}" \
  336. "string:${CROS_USER_ID_HASH}" 2>/dev/null)
  337. status=$?
  338. [ ${status} -eq 0 -a "${reply##* }" = "true" ]
  339. }
  340. imageloader() {
  341. # Default timeout 30 seconds.
  342. local timeout="--reply-timeout=30000"
  343. case $1 in
  344. --reply-timeout=*) timeout=$1; shift;;
  345. esac
  346. local method="$1"; shift
  347. dbus-send ${timeout} --system --type=method_call \
  348. --fixed --print-reply --dest=org.chromium.ComponentUpdaterService \
  349. /org/chromium/ComponentUpdaterService \
  350. "org.chromium.ComponentUpdaterService.${method}" "$@" \
  351. 2>&1 >/dev/null
  352. }
  353. HELP_vmc=''
  354. EXEC_vmc='/usr/bin/vmc'
  355. cmd_vmc() (
  356. if ! is_chrome_feature_enabled "IsCrostiniEnabled"; then
  357. echo "This command is not available."
  358. return 1
  359. fi
  360. vmc "$@"
  361. )
  362. help_vmc() (
  363. vmc --help
  364. )
  365. USAGE_vsh='<vm_name> [<container_name>]'
  366. HELP_vsh='
  367. Connect to a shell inside the VM <vm_name>, or to a shell inside the container
  368. <container_name> within the VM <vm_name>.
  369. '
  370. EXEC_vsh='/usr/bin/vsh'
  371. cmd_vsh() (
  372. if ! is_chrome_feature_enabled "IsCrostiniEnabled"; then
  373. echo "This command is not available."
  374. return 1
  375. fi
  376. if [ $# -ne 1 -a $# -ne 2 ]; then
  377. help "Missing vm_name"
  378. return 1
  379. fi
  380. local vm_name="$1"; shift
  381. if [ $# -eq 1 ]; then
  382. local container_name="$1"; shift
  383. vsh --vm_name="${vm_name}" --owner_id="${CROS_USER_ID_HASH}" \
  384. --target_container="${container_name}"
  385. else
  386. vsh --vm_name="${vm_name}" --owner_id="${CROS_USER_ID_HASH}" -- \
  387. LXD_DIR=/mnt/stateful/lxd \
  388. LXD_CONF=/mnt/stateful/lxd_conf
  389. fi
  390. )
  391. # Set the vars to pass the unittests ...
  392. USAGE_ssh=''
  393. HELP_ssh=''
  394. # ... then unset them to hide the command from "help" output.
  395. unset USAGE_ssh HELP_ssh
  396. cmd_ssh() (
  397. cat <<EOF
  398. The 'ssh' command has been removed. Please install the official SSH extension:
  399. https://chrome.google.com/webstore/detail/pnhechapfaindjhompbnflcldabbghjo
  400. EOF
  401. )
  402. USAGE_swap='[ enable <size (MB)> | disable | start | stop | status
  403. | set_margin <discard threshold (MB)> | set_extra_free <amount (MB)>
  404. | set_min_filelist <amount (MB)> ]'
  405. HELP_swap='
  406. Change kernel memory manager parameters
  407. (FOR EXPERIMENTS ONLY --- USE AT OWN RISK)
  408. "swap status" (also "swap" with no arguments) shows the values of various
  409. memory manager parameters and related statistics.
  410. The enable/disable options enable or disable compressed swap (zram)
  411. persistently across reboots, and take effect at the next boot. The enable
  412. option takes the size of the swap area (in megabytes before compression).
  413. If the size is omitted, the factory default is chosen.
  414. The start/stop options turn swap on/off immediately, but leave the settings
  415. alone, so that the original behavior is restored at the next boot.
  416. WARNING: if swap is in use, turning it off can cause the system to
  417. temporarily hang while the kernel frees up memory. This can take
  418. a long time to finish.
  419. The set_margin, set_min_filelist, and set_extra_free options change
  420. kernel parameters with similar names. The change is immediate and
  421. persistent across reboots. Using the string "default" as the value
  422. restores the factory default behavior.
  423. '
  424. cmd_swap() (
  425. local cmd="${1:-}"
  426. shift
  427. # Check the usage first.
  428. case "${cmd}" in
  429. enable)
  430. if [ $# -gt 1 ]; then
  431. help "${cmd} takes only one optional argument"
  432. return 1
  433. fi
  434. ;;
  435. disable|start|stop|status|"")
  436. if [ $# -ne 0 ]; then
  437. help "${cmd} takes no arguments"
  438. return 1
  439. fi
  440. ;;
  441. set_margin|set_extra_free|set_min_filelist)
  442. if [ $# -ne 1 ]; then
  443. help "${cmd} takes one argument"
  444. return 1
  445. fi
  446. ;;
  447. *)
  448. help "unknown option: ${cmd}"
  449. return 1
  450. ;;
  451. esac
  452. # Then actually process the request.
  453. case "${cmd}" in
  454. "enable")
  455. local size="${1:-default}"
  456. if [ "${size}" = "default" ]; then
  457. size=-1
  458. elif ! is_numeric "${size}"; then
  459. help "'${size}' is not a valid number"
  460. return 1
  461. fi
  462. debugd SwapEnable "int32:${size}" "boolean:false"
  463. ;;
  464. "disable")
  465. debugd SwapDisable "boolean:false"
  466. ;;
  467. "start")
  468. debugd SwapStartStop "boolean:true"
  469. ;;
  470. "stop")
  471. debugd SwapStartStop "boolean:false"
  472. ;;
  473. "set_margin"|"set_extra_free"|"set_min_filelist")
  474. local amount="$1"
  475. if [ "${amount}" = "default" ]; then
  476. # Special value requesting use of the factory default value.
  477. amount=-1
  478. elif ! is_numeric "${amount}"; then
  479. help "${cmd} takes a positive integer argument"
  480. return 1
  481. fi
  482. debugd SwapSetParameter "string:${cmd#set_}" "int32:${amount}"
  483. ;;
  484. "status"|"")
  485. debugd SwapStatus
  486. ;;
  487. esac
  488. )
  489. USAGE_time_info=''
  490. HELP_time_info='
  491. Returns the current synchronization state for the time service.
  492. '
  493. cmd_time_info() (
  494. echo "Last time synchronization information:"
  495. dbus-send --system --type=method_call --print-reply \
  496. --dest=org.torproject.tlsdate /org/torproject/tlsdate \
  497. org.torproject.tlsdate.LastSyncInfo 2>/dev/null |
  498. sed -n \
  499. -e 's/boolean/network-synchronized:/p' \
  500. -e 's/string/last-source:/p' \
  501. -e 's/int64/last-synced-time:/p'
  502. )
  503. USAGE_bt_console='[<agent capability>]'
  504. HELP_bt_console='
  505. Enters a Bluetooth debugging console. Optional argument specifies the
  506. capability of a pairing agent the console will provide; see the Bluetooth
  507. Core specification for valid options.
  508. '
  509. EXEC_bt_console='/usr/bin/bluetoothctl'
  510. cmd_bt_console() (
  511. "${EXEC_bt_console}" "${1:+--agent=$1}"
  512. )
  513. USAGE_newblue='<enable | disable>'
  514. HELP_newblue='Set the preference of enabling/disabling the use of Newblue
  515. Bluetooth stack. In order for the preference to take effect, please login as
  516. the owner account and go to chrome://flags to enable the "Newblue" flag and
  517. reboot the device.
  518. '
  519. cmd_newblue() (
  520. if [ $# -ne 1 ]; then
  521. help "unexpected number of argument"
  522. return 1
  523. fi
  524. local enabled
  525. case "$1" in
  526. enable)
  527. enabled="true"
  528. ;;
  529. disable)
  530. enabled="false"
  531. ;;
  532. *)
  533. help "unknown option $1"
  534. return 1
  535. ;;
  536. esac
  537. dbus-send --system --type=method_call --dest=org.bluez /org/bluez \
  538. org.chromium.BluetoothExperimental.SetNewblueEnabled "boolean:${enabled}"
  539. if [ $? -ne 0 ]; then
  540. echo "ERROR: setting newblue status failed"
  541. return 1
  542. fi
  543. )
  544. # Set the help string so crosh can discover us automatically.
  545. HELP_ff_debug=''
  546. EXEC_ff_debug='/usr/bin/ff_debug'
  547. cmd_ff_debug() (
  548. debugd_shill ff_debug "$@"
  549. )
  550. help_ff_debug() (
  551. cmd_ff_debug --help
  552. )
  553. # Set the help string so crosh can discover us automatically.
  554. HELP_wpa_debug=''
  555. EXEC_wpa_debug='/usr/bin/wpa_debug'
  556. cmd_wpa_debug() (
  557. debugd_shill wpa_debug "$@"
  558. )
  559. help_wpa_debug() (
  560. cmd_wpa_debug --help
  561. )
  562. USAGE_authpolicy_debug='<level>'
  563. HELP_authpolicy_debug='
  564. Set authpolicy daemon debugging level.
  565. <level> can be 0 (quiet), 1 (taciturn), 2 (chatty), or 3 (verbose).
  566. '
  567. cmd_authpolicy_debug() (
  568. if [ $# -ne 1 ]; then
  569. help "exactly one argument (level) accepted"
  570. return 1
  571. fi
  572. local level="$1"
  573. if ! check_digits "${level}"; then
  574. help "level must be a number"
  575. return 1
  576. fi
  577. local reply status
  578. reply=$(dbus-send --system --type=method_call --print-reply \
  579. --dest=org.chromium.AuthPolicy /org/chromium/AuthPolicy \
  580. "org.chromium.AuthPolicy.SetDefaultLogLevel" "int32:$1" 2>&1)
  581. status=$?
  582. if [ ${status} -ne 0 ]; then
  583. echo "ERROR: ${reply}"
  584. return 1
  585. fi
  586. # Reply format: <dbus response header>\n string "<error_message>"\n
  587. local error_message
  588. error_message=$(echo "${reply}" | sed -n -E '$s/.*string "(.*)"/\1/p')
  589. if [ "${error_message}" = "" ]; then
  590. echo "Successfully set debugging level to ${level}."
  591. if [ ${level} -gt 0 ]; then
  592. echo "Debug logs turned on for 30 minutes. Be sure to turn them off again"
  593. echo "when you are done, e.g. by rebooting the device or setting the"
  594. echo "level to 0. Authpolicy debugging info will be written into"
  595. echo "/var/log/authpolicy.log, and will be attached to the next Feedback"
  596. echo "report you send to Google. You may review these logs before sending"
  597. echo "them."
  598. else
  599. echo "Debug logs turned off."
  600. fi
  601. else
  602. help "${error_message}"
  603. fi
  604. )
  605. USAGE_set_arpgw='<true | false>'
  606. HELP_set_arpgw='
  607. Turn on extra network state checking to make sure the default gateway
  608. is reachable.
  609. '
  610. cmd_set_arpgw() (
  611. debugd_shill set_arpgw "$@"
  612. )
  613. USAGE_set_wake_on_lan='<true | false>'
  614. HELP_set_wake_on_lan='
  615. Enable or disable Wake on LAN for Ethernet devices. This command takes
  616. effect after re-connecting to Ethernet and is not persistent across system
  617. restarts.
  618. '
  619. cmd_set_wake_on_lan() (
  620. debugd_shill set_wake_on_lan "$@"
  621. )
  622. USAGE_wifi_power_save='< status | enable | disable >'
  623. HELP_wifi_power_save='
  624. Enable or disable WiFi power save mode. This command is not persistent across
  625. system restarts.
  626. '
  627. cmd_wifi_power_save() (
  628. case "$1" in
  629. "status"|"")
  630. debugd GetWifiPowerSave
  631. ;;
  632. "enable")
  633. debugd SetWifiPowerSave "boolean:true"
  634. ;;
  635. "disable")
  636. debugd SetWifiPowerSave "boolean:false"
  637. ;;
  638. *)
  639. help "unknown option: $1"
  640. return 1
  641. ;;
  642. esac
  643. )
  644. # Set the vars to pass the unittests ...
  645. USAGE_network_logging=''
  646. HELP_network_logging=''
  647. # ... then unset them to hide the command from "help" output.
  648. unset USAGE_network_logging HELP_network_logging
  649. cmd_network_logging() (
  650. cat <<EOF
  651. This command has been removed. Please use the Chrome page instead, and select
  652. your interface there:
  653. chrome://net-internals/#chromeos
  654. EOF
  655. )
  656. # Set the help string so crosh can discover us automatically.
  657. HELP_network_diag=''
  658. EXEC_network_diag='/usr/bin/network_diag'
  659. cmd_network_diag() (
  660. case " $* " in
  661. *" --no-log "*)
  662. debugd_shill network_diag "$@"
  663. ;;
  664. *)
  665. # Create a mostly unique filename. We won't care about clobbering existing
  666. # files here as this is a user generated request, and we scope the filename
  667. # to this specific use case.
  668. local downloads_dir="/home/user/${CROS_USER_ID_HASH}/Downloads"
  669. local timestamp="$(date +'%Y-%m-%d.%H-%M-%S')"
  670. local logname="network_diagnostics_${timestamp}.txt"
  671. local logpath="${downloads_dir}/${logname}"
  672. rm -f "${logpath}"
  673. echo "Saving output to Downloads under: ${logname}"
  674. debugd_shill network_diag "$@" | tee "${logpath}"
  675. ;;
  676. esac
  677. )
  678. help_network_diag() (
  679. debugd_shill network_diag --help
  680. )
  681. u2f_warning='
  682. ### IMPORTANT: The U2F feature is experimental and not suitable for
  683. ### general production use in its current form. The current
  684. ### implementation is still in flux and some features (including
  685. ### security-relevant ones) are still missing. You are welcome to
  686. ### play with this, but use at your own risk. You have been warned.
  687. '
  688. USAGE_u2f_flags='<u2f | g2f>[, user keys, verbose]'
  689. HELP_u2f_flags="
  690. ${u2f_warning}
  691. Set flags to override the second-factor authentication daemon configuration.
  692. u2f: Always enable the standard U2F mode even if not set in device policy.
  693. g2f: Always enable the U2F mode plus some additional extensions.
  694. user_keys: Enable user-specific keys.
  695. verbose: Increase the daemon logging verbosity in /var/log/messages.
  696. "
  697. cmd_u2f_flags() (
  698. echo "${u2f_warning}"
  699. debugd SetU2fFlags "string:$*"
  700. )
  701. debugd() {
  702. # Default timeout 30 seconds.
  703. local timeout="--reply-timeout=30000"
  704. case $1 in
  705. --reply-timeout=*) timeout=$1; shift;;
  706. esac
  707. local method="$1"; shift
  708. dbus-send ${timeout} --system --print-reply --fixed --dest=org.chromium.debugd \
  709. /org/chromium/debugd "org.chromium.debugd.$method" "$@"
  710. }
  711. # Run a debugd command for a long time and poll its output.
  712. # This expects Start & Stop methods.
  713. debugd_poll() (
  714. local methodbase="$1"; shift
  715. local pid fifo
  716. # Make sure we clean up the background process and temp files when the
  717. # user kills us with CTRL+C or CTRL+\.
  718. cleanup() {
  719. # Don't let the user kill us while cleaning up.
  720. trap : INT QUIT
  721. if [ -n "${pid}" ]; then
  722. if ! debugd "${methodbase}Stop" "string:${pid}"; then
  723. echo "warning: could not stop ${methodbase}"
  724. fi
  725. pid=''
  726. fi
  727. if [ -n "${fifo}" ]; then
  728. dir=$(dirname "${fifo}")
  729. rm -rf "${dir}"
  730. fifo=''
  731. fi
  732. }
  733. trap cleanup INT QUIT
  734. if ! fifo="$(mk_fifo)"; then
  735. # The mk_fifo command already showed a warning.
  736. return 1
  737. fi
  738. debugd "${methodbase}Start" "$@" 2>&1 >"${fifo}" &
  739. read pid < "${fifo}"
  740. # Background cat and block with `wait` to give debugd a chance to flush
  741. # output on trapped signal.
  742. cat "${fifo}" &
  743. wait $!
  744. cleanup
  745. )
  746. # Run a shill script via debugd.
  747. debugd_shill() {
  748. local script="$1"; shift
  749. local args="$(printf '%s,' "$@")"
  750. debugd_poll RunShillScript "fd:1" "string:${script}" "array:string:${args%,}"
  751. }
  752. USAGE_ping="[-4] [-6] [-c count] [-i interval] [-n] [-s packetsize] \
  753. [-W waittime] <destination>"
  754. HELP_ping='
  755. Send ICMP ECHO_REQUEST packets to a network host. If <destination> is "gw"
  756. then the next hop gateway for the default route is used.
  757. Default is to use IPv4 [-4] rather than IPv6 [-6] addresses.
  758. '
  759. cmd_ping() (
  760. local option="dict:string:variant:"
  761. local dest
  762. while [ $# -gt 0 ]; do
  763. # Do just enough parsing to filter/map options; we
  764. # depend on ping to handle final validation.
  765. case "$1" in
  766. -4) option="${option}v6,boolean:false," ;;
  767. -6) option="${option}v6,boolean:true," ;;
  768. -i) shift; option="${option}interval,int32:$1," ;;
  769. -c) shift; option="${option}count,int32:$1," ;;
  770. -W) shift; option="${option}waittime,int32:$1," ;;
  771. -s) shift; option="${option}packetsize,int32:$1," ;;
  772. -n) option="${option}numeric,boolean:true," ;;
  773. -b) option="${option}broadcast,boolean:true," ;;
  774. -*)
  775. help "unknown option: $1"
  776. return 1
  777. ;;
  778. *)
  779. if [ "${dest+set}" = "set" ]; then
  780. help "too many destinations specified"
  781. return 1
  782. fi
  783. dest="$1"
  784. ;;
  785. esac
  786. shift
  787. done
  788. if [ "${dest+set}" != "set" ]; then
  789. help "missing parameter: destination"
  790. return 1
  791. fi
  792. if [ "${dest}" = "gw" ]; then
  793. # Convenient shorthand for the next-hop gateway attached
  794. # to the default route; this means if you have a host named
  795. # "gw" then you'll need to specify a FQDN or IP address.
  796. dest=$(ip route show | awk '$1 == "default" { print $3 }')
  797. if [ -z "${dest}" ]; then
  798. echo "Cannot determine primary gateway; routing table is:"
  799. cmd_route
  800. return 1
  801. fi
  802. fi
  803. # Remove trailing comma in the options list if it exists.
  804. debugd_poll Ping "fd:1" "string:${dest}" "${option%,}"
  805. )
  806. USAGE_chaps_debug='[start|stop|<log_level>]'
  807. HELP_chaps_debug='
  808. Sets the chapsd logging level. No arguments will start verbose logging.
  809. '
  810. cmd_chaps_debug() (
  811. local level=${1:--2}
  812. if [ "$1" = "stop" ]; then
  813. level=0
  814. fi
  815. if [ "$1" = "start" ]; then
  816. level=-2
  817. fi
  818. /usr/bin/chaps_client --set_log_level=${level} 2> /dev/null
  819. if [ $? -eq 0 ]; then
  820. echo "Logging level set to ${level}."
  821. else
  822. echo "Failed to set logging level."
  823. fi
  824. )
  825. USAGE_route='[-4] [-6]'
  826. HELP_route='
  827. Display the routing tables.
  828. Default is to show IPv4 [-4] rather than IPv6 [-6] routes.
  829. '
  830. cmd_route() (
  831. local option="dict:string:variant:"
  832. while [ $# -gt 0 ]; do
  833. case $1 in
  834. -4) option="${option}v6,boolean:false," ;;
  835. -6) option="${option}v6,boolean:true," ;;
  836. *)
  837. help "unknown option: $1"
  838. return 1
  839. esac
  840. shift
  841. done
  842. debugd GetRoutes "${option%,}"
  843. )
  844. USAGE_tracepath='[-4] [-6] [-n] <destination>[/port]'
  845. HELP_tracepath='
  846. Trace the path/route to a network host.
  847. Default is to trace IPv4 [-4] rather than IPv6 [-6] targets.
  848. '
  849. cmd_tracepath() (
  850. local option="dict:string:variant:"
  851. local dest
  852. while [ $# -gt 0 ]; do
  853. # Do just enough parsing to filter/map options; we
  854. # depend on tracepath to handle final validation.
  855. case "$1" in
  856. -4) option="${option}v6,boolean:false," ;;
  857. -6) option="${option}v6,boolean:true," ;;
  858. -n) option="${option}numeric,boolean:true," ;;
  859. -*)
  860. help "unknown option: $1"
  861. return 1
  862. ;;
  863. *)
  864. if [ "${dest+set}" = "set" ]; then
  865. help "too many destinations specified"
  866. return 1
  867. fi
  868. dest="$1"
  869. ;;
  870. esac
  871. shift
  872. done
  873. if [ "${dest+set}" != "set" ]; then
  874. help "missing parameter: destination"
  875. return 1
  876. fi
  877. # Remove trailing comma in the options list if it exists.
  878. debugd_poll TracePath "fd:1" "string:${dest}" "${option%,}"
  879. )
  880. USAGE_top=''
  881. HELP_top='
  882. Run top.
  883. '
  884. cmd_top() (
  885. # -s is "secure" mode, which disables kill, renice, and change display/sleep
  886. # interval. Set HOME to /mnt/empty to make sure we don't parse any files in
  887. # the stateful partition. https://crbug.com/677934
  888. HOME="/mnt/empty" top -s
  889. )
  890. USAGE_modem='<command> [args...]'
  891. HELP_modem='
  892. Interact with the 3G modem. Run "modem help" for detailed help.
  893. '
  894. cmd_modem() (
  895. debugd_shill modem "$@"
  896. )
  897. USAGE_modem_set_carrier='carrier-name'
  898. HELP_modem_set_carrier='
  899. Configures the modem for the specified carrier.
  900. '
  901. cmd_modem_set_carrier() (
  902. debugd_shill modem set-carrier "$@"
  903. )
  904. USAGE_set_apn='[-c] [-n <network-id>] [-u <username>] [-p <password>] <apn>'
  905. HELP_set_apn='
  906. Set the APN to use when connecting to the network specified by <network-id>.
  907. If <network-id> is not specified, use the network-id of the currently
  908. registered network.
  909. The -c option clears the APN to be used, so that the default APN will be used
  910. instead.
  911. '
  912. cmd_set_apn() (
  913. debugd_shill set_apn "$@"
  914. )
  915. USAGE_set_cellular_ppp='[-c] [-u <username>] [-p <password>]'
  916. HELP_set_cellular_ppp='
  917. Set the PPP username and/or password for an existing cellular connection.
  918. If neither -u nor -p is provided, show the existing PPP username for
  919. the cellular connection.
  920. The -c option clears any existing PPP username and PPP password for an
  921. existing cellular connection.
  922. '
  923. cmd_set_cellular_ppp() (
  924. /usr/bin/set_cellular_ppp "$@"
  925. )
  926. USAGE_connectivity=''
  927. HELP_connectivity='
  928. Shows connectivity status. "connectivity help" for more details
  929. '
  930. cmd_connectivity() (
  931. /usr/bin/connectivity "$@"
  932. )
  933. USAGE_autest='[-scheduled]'
  934. HELP_autest='
  935. Trigger an auto-update. To fake a scheduled update check use -scheduled.
  936. '
  937. cmd_autest() (
  938. local omaha_url="autest"
  939. if [ "$1" = "-scheduled" ]; then
  940. # pretend that this is a scheduled check as opposed to an user-initiated
  941. # check for testing features that get enabled only on scheduled checks.
  942. omaha_url="autest-scheduled"
  943. fi
  944. echo "Calling update_engine_client with omaha_url = $omaha_url"
  945. /usr/bin/update_engine_client --omaha_url=$omaha_url
  946. )
  947. USAGE_p2p_update='[enable|disable] [--num-connections] [--show-peers]'
  948. HELP_p2p_update='
  949. Enables or disables the peer-to-peer (P2P) sharing of updates over the local
  950. network. This will both attempt to get updates from other peers in the
  951. network and share the downloaded updates with them. Run this command without
  952. arguments to see the current state. Additional switches will display number
  953. of connections and P2P peers.
  954. '
  955. cmd_p2p_update() (
  956. if [ "$1" = "" ]; then
  957. /usr/bin/update_engine_client -show_p2p_update
  958. fi
  959. while [ $# -gt 0 ]; do
  960. case "$1" in
  961. "enable")
  962. /usr/bin/update_engine_client -p2p_update=yes -show_p2p_update
  963. ;;
  964. "disable")
  965. /usr/bin/update_engine_client -p2p_update=no -show_p2p_update
  966. ;;
  967. "--num-connections")
  968. if p2p_check_enabled; then
  969. echo "Number of active p2p connections:"
  970. /usr/sbin/p2p-client --num-connections
  971. fi
  972. ;;
  973. "--show-peers")
  974. if p2p_check_enabled; then
  975. echo "Current p2p peers:"
  976. /usr/sbin/p2p-client --list-all
  977. fi
  978. ;;
  979. *)
  980. help "unknown option: $1"
  981. return 1
  982. ;;
  983. esac
  984. shift
  985. done
  986. )
  987. p2p_check_enabled() {
  988. if ! /usr/bin/update_engine_client -show_p2p_update 2>&1 \
  989. | grep -q "ENABLED"; then
  990. echo "Run \"p2p_update enable\" to enable peer-to-peer before" \
  991. "using this command."
  992. return 1
  993. fi
  994. }
  995. USAGE_rollback=''
  996. HELP_rollback='
  997. Attempt to rollback to the previous update cached on your system. Only
  998. available on non-stable channels and non-enterprise enrolled devices. Please
  999. note that this will powerwash your device.
  1000. '
  1001. cmd_rollback() (
  1002. if /usr/bin/update_engine_client --rollback; then
  1003. echo "Rollback attempt succeeded -- after a couple minutes you will" \
  1004. "get an update available and you should reboot to complete rollback."
  1005. else
  1006. echo "Rollback attempt failed. Check chrome://system for more information."
  1007. fi
  1008. )
  1009. USAGE_update_over_cellular='[enable|disable]'
  1010. HELP_update_over_cellular='
  1011. Enables or disables the auto updates over cellular networks. Run without
  1012. arguments to see the current state.
  1013. '
  1014. cmd_update_over_cellular() (
  1015. case "$1" in
  1016. "enable")
  1017. param="-update_over_cellular=yes"
  1018. echo "When available, auto-updates download in the background any time " \
  1019. "the computer is powered on. Note: this may incur additional " \
  1020. "cellular charges, including roaming and/or data charges, as per " \
  1021. "your carrier arrangement."
  1022. ;;
  1023. "disable")
  1024. param="-update_over_cellular=no"
  1025. ;;
  1026. "")
  1027. param=""
  1028. ;;
  1029. *)
  1030. help "unknown option: $1"
  1031. return 1
  1032. ;;
  1033. esac
  1034. /usr/bin/update_engine_client $param -show_update_over_cellular
  1035. )
  1036. USAGE_upload_crashes=''
  1037. HELP_upload_crashes='
  1038. Uploads available crash reports to the crash server.
  1039. '
  1040. cmd_upload_crashes() (
  1041. debugd UploadCrashes
  1042. echo "Check chrome://crashes for status updates"
  1043. )
  1044. USAGE_upload_devcoredumps='[enable|disable]'
  1045. HELP_upload_devcoredumps='
  1046. Enable or disable the upload of devcoredump reports.
  1047. '
  1048. cmd_upload_devcoredumps() (
  1049. case "$1" in
  1050. "enable")
  1051. debugd EnableDevCoredumpUpload
  1052. ;;
  1053. "disable")
  1054. debugd DisableDevCoredumpUpload
  1055. ;;
  1056. *)
  1057. help "unknown option: $1"
  1058. return 1
  1059. ;;
  1060. esac
  1061. )
  1062. USAGE_rlz='< status | enable | disable >'
  1063. HELP_rlz="
  1064. Enable or disable RLZ. See this site for details:
  1065. http://dev.chromium.org/developers/design-documents/extensions/\
  1066. proposed-changes/apis-under-development/rlz-api
  1067. "
  1068. cmd_rlz() (
  1069. local flag_file="$HOME/.rlz_disabled"
  1070. local enabled=1
  1071. local changed=0
  1072. if [ -r "${flag_file}" ]; then
  1073. enabled=0
  1074. fi
  1075. case "$1" in
  1076. "status")
  1077. if [ $enabled -eq 1 ]; then
  1078. echo "Currently enabled"
  1079. else
  1080. echo "Currently disabled"
  1081. fi
  1082. return
  1083. ;;
  1084. "enable")
  1085. if [ $enabled -eq 0 ]; then
  1086. changed=1
  1087. fi
  1088. rm -f "${flag_file}"
  1089. ;;
  1090. "disable")
  1091. if [ $enabled -eq 1 ]; then
  1092. changed=1
  1093. fi
  1094. touch "${flag_file}"
  1095. ;;
  1096. *)
  1097. help "unknown option: $1"
  1098. return 1
  1099. ;;
  1100. esac
  1101. if [ $changed -eq 1 ]; then
  1102. echo "You must reboot for this to take effect."
  1103. else
  1104. echo "No change."
  1105. fi
  1106. )
  1107. USAGE_syslog='<message>'
  1108. HELP_syslog='
  1109. Logs a message to syslog (the system log daemon).
  1110. '
  1111. cmd_syslog() (
  1112. logger -t crosh -- "$*"
  1113. )
  1114. mk_fifo() {
  1115. local dir fifo
  1116. # We want C-c to terminate the running test so that the UI stays the same.
  1117. # Therefore, create a fifo to direct the output of the test to, and have a
  1118. # subshell read from the fifo and emit to stdout. When the subshell ends (at a
  1119. # C-c), we stop the test and clean up the fifo.
  1120. # no way to mktemp a fifo, so make a dir to hold it instead
  1121. dir=$(mktemp -d "/tmp/crosh-test-XXXXXXXXXX")
  1122. if [ $? -ne 0 ]; then
  1123. echo "Can't create temporary directory"
  1124. return 1
  1125. fi
  1126. fifo="${dir}/fifo"
  1127. if ! mkfifo "${fifo}"; then
  1128. echo "Can't create fifo at ${fifo}"
  1129. return 1
  1130. fi
  1131. echo "${fifo}"
  1132. }
  1133. USAGE_storage_test_1=''
  1134. HELP_storage_test_1='
  1135. Performs a short offline SMART test.
  1136. '
  1137. cmd_storage_test_1() (
  1138. option="$1"
  1139. debugd Smartctl "string:abort_test" >/dev/null
  1140. test=$(debugd Smartctl "string:short_test")
  1141. if [ "$option" != "-v" ]; then
  1142. echo "$test" | sed -n '1p;2p'
  1143. echo ""
  1144. echo "$test" | grep "Please wait"
  1145. else
  1146. echo "$test"
  1147. fi
  1148. echo ""
  1149. while debugd Smartctl "string:capabilities" |
  1150. grep -q "of test remaining"; do
  1151. true
  1152. done
  1153. result=$(debugd Smartctl "string:selftest")
  1154. if [ "$option" != "-v" ]; then
  1155. echo "$result" | grep -e "Num" -e "# 1"
  1156. else
  1157. echo "$result"
  1158. fi
  1159. debugd Smartctl "string:abort_test" >/dev/null
  1160. )
  1161. USAGE_storage_test_2=''
  1162. HELP_storage_test_2='
  1163. Performs an extensive readability test.
  1164. '
  1165. cmd_storage_test_2() (
  1166. debugd_poll Badblocks "fd:1"
  1167. )
  1168. USAGE_memory_test=''
  1169. HELP_memory_test='
  1170. Performs extensive memory testing on the available free memory.
  1171. '
  1172. cmd_memory_test() (
  1173. # Getting total free memory in KB.
  1174. mem=$(cat /proc/meminfo | grep MemFree | tr -s " " | cut -d" " -f 2)
  1175. # Converting to MiB.
  1176. mem=$(($mem / 1024))
  1177. # Giving OS 200MB free memory before hogging the rest of it.
  1178. mem=$(($mem - 200))
  1179. debugd_poll Memtester "fd:1" "uint32:${mem}"
  1180. )
  1181. USAGE_battery_firmware='<info|check|update>'
  1182. HELP_battery_firmware='
  1183. info : Query battery info.
  1184. check : Check whether the AC adapter is connected.
  1185. Also check whether the battery firmware is the latest.
  1186. update : Trigger battery firmware update.
  1187. '
  1188. cmd_battery_firmware() (
  1189. option="$1"
  1190. case "${option}" in
  1191. info|check)
  1192. debugd --reply-timeout=$(( 10 * 60 * 1000 )) BatteryFirmware "string:${option}"
  1193. echo ""
  1194. ;;
  1195. update)
  1196. # Increased the reply-timeout to 10 min for Battery Firmware update process.
  1197. # Battery Firmware Update process time includes the following:
  1198. # 1 setup delay time before entery battery firmware update mode.
  1199. # 2 battery flash erase time.
  1200. # 3 data transfer time from AP to EC, and then to Batttery.
  1201. # 4 battery flash program/write time.
  1202. # 5 re-try time on errors.
  1203. # Note: take ~2 min on a success battery firmware update case.
  1204. echo ""
  1205. echo "================================================================================"
  1206. echo " Battery firmware update is in progress."
  1207. echo "================================================================================"
  1208. echo "Please DO NOT remove the power adapter cable, otherwise the update will fail."
  1209. echo ""
  1210. echo "To recover from a failed battery firmware update,"
  1211. echo " please plug in the power adapter cable, reboot and run this command again."
  1212. echo ""
  1213. echo "================================================================================"
  1214. echo ""
  1215. debugd --reply-timeout=$(( 10 * 60 * 1000 )) BatteryFirmware "string:${option}"
  1216. echo ""
  1217. ;;
  1218. *)
  1219. help "Unknown option: ${option}"
  1220. ;;
  1221. esac
  1222. )
  1223. USAGE_battery_test='[<test length>]'
  1224. HELP_battery_test='
  1225. Tests battery discharge rate for given number of seconds. Without an argument,
  1226. defaults to 300 seconds.
  1227. '
  1228. cmd_battery_test() (
  1229. local test_length="$1"
  1230. if [ -z "$test_length" ]; then
  1231. echo "No test length specified. Defaulting to 300 seconds."
  1232. test_length=300
  1233. fi
  1234. if ! check_digits "${test_length}"; then
  1235. echo "Invalid test length."
  1236. return 1
  1237. fi
  1238. if [ "$(get_power_status_field 'battery_present')" != '1' ]; then
  1239. echo "No battery found."
  1240. return 1
  1241. fi
  1242. if [ "$(get_power_status_field 'battery_discharging')" = '1' ]; then
  1243. local bat_status='discharging'
  1244. local bat_discharging=1
  1245. else
  1246. local bat_status='charging or full'
  1247. local bat_discharging=0
  1248. fi
  1249. local bat_pct="$(get_power_status_field 'battery_percent')"
  1250. local bat_full="$(get_power_status_field 'battery_charge_full')"
  1251. local bat_full_design="$(get_power_status_field 'battery_charge_full_design')"
  1252. local bat_health="$(echo "${bat_full}" "${bat_full_design}" | \
  1253. awk '{ printf "%.2f", 100.0 * $1 / $2 }')"
  1254. echo "Battery is ${bat_status} (${bat_pct}% left)"
  1255. echo "Battery health: ${bat_health}%"
  1256. if [ "${bat_discharging}" != '1' ]; then
  1257. echo "Please make sure the power supply is unplugged and retry the test."
  1258. return 1
  1259. fi
  1260. echo "Please wait..."
  1261. sleep "${test_length}"
  1262. local bat_after="$(get_power_status_field 'battery_percent')"
  1263. local bat_diff="$(echo "${bat_pct}" "${bat_after}" | \
  1264. awk '{ printf "%.2f", $1 - $2 }')"
  1265. echo "Battery discharged ${bat_diff}% in ${test_length} second(s)."
  1266. )
  1267. USAGE_dump_emk=''
  1268. HELP_dump_emk='
  1269. Show the EMK (Enterprise Machine Key).
  1270. '
  1271. cmd_dump_emk() (
  1272. /usr/sbin/cryptohome --action=tpm_attestation_key_status \
  1273. --name=attest-ent-machine
  1274. )
  1275. USAGE_enroll_status='[--mode] [--domain] [--realm] [--user]'
  1276. HELP_enroll_status='
  1277. Displays device enrollment information.
  1278. '
  1279. cmd_enroll_status() (
  1280. if [ "$1" = "" ]; then
  1281. if check_enterprise_mode; then
  1282. echo "Enrollment mode:"
  1283. /usr/sbin/cryptohome --action=install_attributes_get \
  1284. --name=enterprise.mode
  1285. else
  1286. echo "This device is not enterprise enrolled."
  1287. fi
  1288. fi
  1289. while [ $# -gt 0 ]; do
  1290. case "$1" in
  1291. "--mode")
  1292. if check_enterprise_mode; then
  1293. echo "Enrollment mode:"
  1294. /usr/sbin/cryptohome --action=install_attributes_get \
  1295. --name=enterprise.mode
  1296. else
  1297. echo "This device is not enterprise enrolled."
  1298. fi
  1299. ;;
  1300. "--domain")
  1301. if check_enterprise_mode; then
  1302. echo "Enrollment domain:"
  1303. /usr/sbin/cryptohome --action=install_attributes_get \
  1304. --name=enterprise.domain
  1305. else
  1306. echo "Enterprise enrollment domain not found."
  1307. fi
  1308. ;;
  1309. "--realm")
  1310. if check_enterprise_mode; then
  1311. echo "Enrollment realm:"
  1312. /usr/sbin/cryptohome --action=install_attributes_get \
  1313. --name=enterprise.realm
  1314. else
  1315. echo "Enterprise enrollment realm not found."
  1316. fi
  1317. ;;
  1318. "--user")
  1319. if check_enterprise_mode; then
  1320. echo "Enrollment user:"
  1321. /usr/sbin/cryptohome --action=install_attributes_get \
  1322. --name=enterprise.user
  1323. else
  1324. echo "Enterprise enrollment user not found."
  1325. fi
  1326. ;;
  1327. *)
  1328. help "unknown option: $1"
  1329. return 1
  1330. ;;
  1331. esac
  1332. shift
  1333. done
  1334. )
  1335. check_enterprise_mode() {
  1336. if ! /usr/sbin/cryptohome --action=install_attributes_get \
  1337. --name=enterprise.mode 2>&1 | grep -q "enterprise"; then
  1338. return 1
  1339. fi
  1340. }
  1341. USAGE_tpm_status=''
  1342. HELP_tpm_status='
  1343. Prints TPM (Trusted Platform Module) status information.
  1344. '
  1345. cmd_tpm_status() (
  1346. /usr/sbin/cryptohome --action=tpm_more_status
  1347. )
  1348. USAGE_cryptohome_status=''
  1349. HELP_cryptohome_status='
  1350. Get human-readable status information from cryptohomed.
  1351. '
  1352. cmd_cryptohome_status() (
  1353. if [ $# -eq 0 ]; then
  1354. /usr/sbin/cryptohome --action=status
  1355. else
  1356. help "too many arguments"
  1357. return 1
  1358. fi
  1359. )
  1360. USAGE_dmesg='[-d|-k|-r|-t|-u|-w|-x]'
  1361. HELP_dmesg='
  1362. Display kernel log buffer
  1363. '
  1364. cmd_dmesg() (
  1365. # We whitelist only a few options.
  1366. local opt
  1367. for opt in "$@"; do
  1368. if ! printf '%s' "${opt}" | grep -sqE '^-[dkrtuwx]+$'; then
  1369. help "unknown option: $*"
  1370. return 1
  1371. fi
  1372. done
  1373. dmesg "$@"
  1374. )
  1375. USAGE_free='[options]'
  1376. HELP_free='
  1377. Display free/used memory info
  1378. '
  1379. cmd_free() (
  1380. # All options are harmless, so pass them through.
  1381. free "$@"
  1382. )
  1383. USAGE_meminfo=''
  1384. HELP_meminfo='
  1385. Display detailed memory statistics
  1386. '
  1387. cmd_meminfo() (
  1388. if [ $# -eq 0 ]; then
  1389. cat /proc/meminfo
  1390. else
  1391. help "unknown option: $*"
  1392. return 1
  1393. fi
  1394. )
  1395. USAGE_uptime=''
  1396. HELP_uptime='
  1397. Display uptime/load info
  1398. '
  1399. cmd_uptime() (
  1400. if [ $# -eq 0 ]; then
  1401. uptime
  1402. else
  1403. help "unknown option: $*"
  1404. return 1
  1405. fi
  1406. )
  1407. USAGE_uname='[-a|-s|-n|-r|-v|-m|-p|-i|-o]'
  1408. HELP_uname='
  1409. Display system info
  1410. '
  1411. cmd_uname() (
  1412. # We whitelist only a few options.
  1413. local opt
  1414. for opt in "$@"; do
  1415. if ! printf '%s' "${opt}" | grep -sqE '^-[asnrvmpio]+$'; then
  1416. help "unknown option: $*"
  1417. return 1
  1418. fi
  1419. done
  1420. uname "$@"
  1421. )
  1422. USAGE_vmstat='[-a|-d|-f|-m|-n|-s|-w] [delay [count]]'
  1423. HELP_vmstat='
  1424. Report virtual memory statistics
  1425. '
  1426. cmd_vmstat() (
  1427. # We whitelist only a few options.
  1428. local opt
  1429. for opt in "$@"; do
  1430. if ! printf '%s' "${opt}" | grep -sqE '^(-[adfmnsw]+|[0-9]+)$'; then
  1431. help "unknown option: ${opt}"
  1432. return 1
  1433. fi
  1434. done
  1435. vmstat "$@"
  1436. )
  1437. EXEC_ccd_pass='/usr/sbin/gsctool'
  1438. HELP_ccd_pass="
  1439. When prompted, set or clear CCD password (use the word 'clear' to clear
  1440. the password).
  1441. "
  1442. USAGE_ccd_pass=''
  1443. cmd_ccd_pass() (
  1444. "${EXEC_ccd_pass}" -t -P
  1445. )
  1446. EXEC_verify_ro='/usr/share/cros/cr50-verify-ro.sh'
  1447. HELP_verify_ro="
  1448. Verify AP and EC RO firmware on a Chrome OS device connected over SuzyQ
  1449. cable, if supported by the device.
  1450. "
  1451. USAGE_verify_ro=''
  1452. cmd_verify_ro() (
  1453. local cr50_image="/opt/google/cr50/firmware/cr50.bin.prod"
  1454. local ro_db="/opt/google/cr50/ro_db"
  1455. if [ $# -ne 0 ]; then
  1456. help "too many arguments"
  1457. return 1
  1458. fi
  1459. if [ ! -f "${cr50_image}" -o ! -d "${ro_db}" ]; then
  1460. echo "This device can not be used for RO verification"
  1461. return 1
  1462. fi
  1463. debugd_poll UpdateAndVerifyFWOnUsb \
  1464. "fd:1" "string:${cr50_image}" "string:${ro_db}"
  1465. )
  1466. USAGE_c='<container name> [args]'
  1467. HELP_c='
  1468. Run a program inside a container
  1469. '
  1470. EXEC_c='/usr/bin/run_oci'
  1471. cmd_c() (
  1472. cleanup() {
  1473. trap : INT QUIT
  1474. debugd ContainerStopped
  1475. }
  1476. trap cleanup INT QUIT
  1477. local container="$1"
  1478. if [ -z "${container}" ]; then
  1479. echo "No container specified"
  1480. return 1
  1481. fi
  1482. shift
  1483. local mount_dir=$(/usr/bin/mount_extension_image --name="${container}")
  1484. if [ -z "${mount_dir}" ]; then
  1485. echo "Could not find container"
  1486. return 1
  1487. fi
  1488. debugd ContainerStarted
  1489. HOME=/home/user /usr/bin/run_oci \
  1490. --cgroup_parent=chronos_containers \
  1491. --bind_mount="/home/user/${CROS_USER_ID_HASH}/Downloads:/home/user" \
  1492. --bind_mount=/run/djfs:/dev \
  1493. run -c "${mount_dir}" "${container}" -- "$@"
  1494. cleanup
  1495. )
  1496. USAGE_evtest='evtest'
  1497. EXEC_evtest='/usr/bin/evtest'
  1498. HELP_evtest='
  1499. Run evtest in safe mode.
  1500. '
  1501. cmd_evtest() (
  1502. if [ $# -ne 0 ]; then
  1503. help "too many arguments"
  1504. return 1
  1505. else
  1506. # --safe is "safe" mode, which will only print limited info.
  1507. # We don't allow any other arguments now. Any attempt to enable more
  1508. # features should go through security review first.
  1509. "${EXEC_evtest}" --safe
  1510. fi
  1511. )
  1512. USAGE_alt_os='[-s SIZE_GB] enable | disable'
  1513. HELP_alt_os='Manage Alt OS mode'
  1514. EXEC_alt_os='/usr/bin/campfire-setup'
  1515. cmd_alt_os() (
  1516. local opt opt_size
  1517. while getopts "s:" opt; do
  1518. case "${opt}" in
  1519. s)
  1520. opt_size="${OPTARG}"
  1521. if ! is_numeric "${opt_size}"; then
  1522. help "'${opt_size}' is not a valid number"
  1523. fi
  1524. ;;
  1525. *)
  1526. help "unknown option: '${opt}'"
  1527. return 1
  1528. esac
  1529. done
  1530. shift $((OPTIND - 1))
  1531. local action="$1"
  1532. case "${action}" in
  1533. enable)
  1534. size="${opt_size:-40}"
  1535. if ! debugd CampfireEnableAltOS "int32:${size}"; then
  1536. echo "Failed to enable Alt OS."
  1537. return 1
  1538. fi
  1539. ;;
  1540. disable)
  1541. if ! debugd CampfireDisableAltOS; then
  1542. echo "Failed to disable Alt OS."
  1543. return 1
  1544. fi
  1545. ;;
  1546. *)
  1547. help "unknown action: '${action}'"
  1548. return 1
  1549. esac
  1550. )
  1551. substr() {
  1552. local str="$1"
  1553. local start="$2"
  1554. local end="$3"
  1555. start=$(expr "$start" + 1)
  1556. if [ ! -z "$end" ]; then
  1557. end=$(expr "$end" - 1)
  1558. fi
  1559. printf '%s' "${str}" | cut -c${start}-${end}
  1560. }
  1561. # Return true if the arg is a shell function.
  1562. is_shell_function() {
  1563. local func="$1"
  1564. type "${func}" 2>/dev/null | head -1 | grep -q 'function'
  1565. }
  1566. # Return all registered crosh commands intended for users.
  1567. # This will not include "hidden" commands that lack help as those are not yet
  1568. # meant for wider consumption, or they've been deprecated.
  1569. registered_visible_commands() {
  1570. # Remember: Use a form that works under POSIX shell. Since that does not
  1571. # offer any way of doing introspection on registered functions, we have to
  1572. # stick to probing the environment.
  1573. set | grep -o '^HELP_[^=]*' | sed -e 's:^HELP_::' -e 's:=$::' | sort
  1574. }
  1575. # Return true if the first arg is a valid crosh command.
  1576. registered_crosh_command() {
  1577. local command="$1"
  1578. is_shell_function "cmd_${command}"
  1579. }
  1580. # Return true if the specified command has a custom help function.
  1581. registered_crosh_command_help() {
  1582. local command="$1"
  1583. is_shell_function "help_${command}"
  1584. }
  1585. # Return true if the first arg is a command available on
  1586. # the system. We assume that all commands that do not
  1587. # define EXEC_<command> variable are always available. For
  1588. # commands that do define EXEC_<command> variable, we
  1589. # ensure that it contains name of a valid shell command.
  1590. check_command_available() {
  1591. local exec="$(expand_var "EXEC_$1")"
  1592. [ -z "${exec}" ] || command -v "${exec}" >/dev/null
  1593. }
  1594. dispatch() {
  1595. local line="$1"
  1596. local command=""
  1597. local params=""
  1598. local p
  1599. local space_pos="$(expr index "${line}" ' ')"
  1600. if [ "${space_pos}" = "0" ]; then
  1601. command=$line
  1602. else
  1603. command=$(substr "$line" "0" "$space_pos")
  1604. command=${command% *}
  1605. params=$(substr "$line" "$space_pos")
  1606. fi
  1607. if ! registered_crosh_command "${command}"; then
  1608. help "unknown command: ${command}"
  1609. elif ! check_command_available "${command}"; then
  1610. help "command '${command}' is not available"
  1611. else
  1612. # Only add valid commands to the history.
  1613. shell_history -s "$LINE_"
  1614. # See if --help was requested; if so, handle it directly so each command
  1615. # doesn't have to deal with it directly.
  1616. for p in ${params}; do
  1617. if [ "${p}" = "-h" -o "${p}" = "--help" ]; then
  1618. cmd_help "${command}"
  1619. return 0
  1620. fi
  1621. done
  1622. # Set CURRENT_COMMAND for the `help` helper.
  1623. CURRENT_COMMAND="${command}" "cmd_${command}" ${params}
  1624. fi
  1625. }
  1626. repl() {
  1627. echo "${INTRO_TEXT}"
  1628. if [ "$IS_BASH" != "1" ]; then
  1629. echo "Sorry, line editing and command history disabled due to" \
  1630. "shell limitations."
  1631. fi
  1632. # This will be set by the 'exit' command to tell us to quit.
  1633. local exit
  1634. # Create a colorized prompt to make it easier to see commands start/finish.
  1635. local prompt
  1636. prompt="$(printf '%bcrosh>%b ' '\001\033[1;33m\002' '\001\033[0m\002')"
  1637. while [ -z "${exit}" ]; do
  1638. if shell_read "${prompt}" LINE_; then
  1639. if [ ! -z "$LINE_" ]; then
  1640. dispatch "$LINE_"
  1641. fi
  1642. else
  1643. echo
  1644. return 1
  1645. fi
  1646. done
  1647. }
  1648. usage() {
  1649. if [ $# -ne 0 ]; then
  1650. # Send stdout below to stderr instead.
  1651. exec 1>&2
  1652. fi
  1653. cat <<EOF
  1654. Usage: crosh [options]
  1655. Options:
  1656. --dash Force running through dash.
  1657. --dev Force dev mode.
  1658. --removable Force removable (USB) mode.
  1659. --usb Same as above.
  1660. --help, -h Show this help string.
  1661. EOF
  1662. if [ $# -ne 0 ]; then
  1663. echo "ERROR: $*"
  1664. exit 1
  1665. else
  1666. exit 0
  1667. fi
  1668. }
  1669. main() {
  1670. # If we aren't installed, use local files for testing.
  1671. if [ ! -d "${CROSH_MODPATH}" ]; then
  1672. CROSH_MODPATH=$(dirname "$0")
  1673. echo "Loading from local paths instead: ${CROSH_MODPATH}"
  1674. fi
  1675. while [ $# -gt 0 ]; do
  1676. case $1 in
  1677. --dash)
  1678. # This was handled above in try_bash.
  1679. ;;
  1680. --dev)
  1681. CROSH_DEVMODE="1"
  1682. ;;
  1683. --removable|--usb)
  1684. CROSH_REMOVABLE="1"
  1685. ;;
  1686. --help|-h)
  1687. usage
  1688. ;;
  1689. *)
  1690. usage "Unknown option: $1"
  1691. ;;
  1692. esac
  1693. shift
  1694. done
  1695. load_extra_crosh
  1696. INPUTRC="${CROSH_MODPATH}/inputrc.crosh"
  1697. shell_history_init
  1698. repl
  1699. # Save the history after the clean exit.
  1700. shell_history -w "${HISTFILE}"
  1701. }
  1702. main "$@"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement