diff --git a/README.md b/README.md index a598f98..c37eff8 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ curl -L https://raw.github.com/alphabetum/hosts/master/hosts \ Usage: hosts hosts add [] + hosts block hosts disable ( | | ) hosts disabled hosts edit @@ -52,6 +53,7 @@ Usage: hosts show ( | | ) hosts search hosts remove ( | | ) [--force] + hosts unblock ``` For full usage, run: @@ -118,6 +120,15 @@ Print the entire contents of the /etc/hosts file. Search entries for a given search string. +###### `block ` + +Block a given hostname by adding new entries assigning it to `127.0.0.1` for +IPv4 and both `fe80::1%lo0` and `::1` for IPv6. + +###### `unblock ` + +Unblock a given hostname by removing its entries from the hosts file. + ## Tests To run the test suite, install [Bats](https://github.com/sstephenson/bats) and diff --git a/hosts b/hosts index 975b285..7dcb09f 100755 --- a/hosts +++ b/hosts @@ -596,6 +596,7 @@ Version: ${_VERSION} Usage: ${_ME} ${_ME} add [] + ${_ME} block ${_ME} disable ( | | ) ${_ME} disabled ${_ME} edit @@ -605,6 +606,7 @@ Usage: ${_ME} list [enabled | disabled | ] ${_ME} show ( | | ) ${_ME} remove ( | | ) [--force] + ${_ME} unblock ${_ME} -h | --help ${_ME} --version @@ -729,6 +731,29 @@ add() { fi } +# ----------------------------------------------------------------------- block + +desc "block" < + +Description: + Block a given hostname by adding new entries assigning it to \`127.0.0.1\` + for IPv4 and both \`fe80::1%lo0\` and \`::1\` for IPv6. +HEREDOC +block() { + if [[ -z "${1}" ]] + then + ${_ME} help block + exit 1 + fi + + ${_ME} add 127.0.0.1 "${1}" + # block IPv6 + ${_ME} add "fe80::1%lo0" "${1}" + ${_ME} add "::1" "${1}" +} + # --------------------------------------------------------------------- disable desc "disable" < + +Description: + Unblock a given hostname by removing its entries from the hosts file. +HEREDOC +unblock() { + if [[ -z "${1}" ]] + then + ${_ME} help unblock + exit 1 + fi + + ${_ME} remove 127.0.0.1 "${1}" --force + # unblock IPv6 + ${_ME} remove "fe80::1%lo0" "${1}" --force + ${_ME} remove "::1" "${1}" --force +} + ############################################################################### # Run Program ############################################################################### diff --git a/test/block.bats b/test/block.bats new file mode 100644 index 0000000..2d69132 --- /dev/null +++ b/test/block.bats @@ -0,0 +1,77 @@ +#!/usr/bin/env bats + +load test_helper + +# `hosts block` ################################################################# + +@test "\`block\` with no arguments exits with status 1." { + run "${_HOSTS}" block + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + [[ ${status} -eq 1 ]] +} + +@test "\`block\` with no argument does not change the hosts file." { + _original="$(cat "${HOSTS_PATH}")" + + run "${_HOSTS}" block + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + [[ "$(cat "${HOSTS_PATH}")" == "${_original}" ]] +} + +@test "\`block\` with no arguments prints help information." { + run "${_HOSTS}" block + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + [[ "${lines[0]}" == "Usage:" ]] + [[ "${lines[1]}" == " hosts block " ]] +} + +# `hosts block ` ################################################# + +@test "\`block \` exits with status 0." { + run "${_HOSTS}" block example.com + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + [[ ${status} -eq 0 ]] +} + +@test "\`block \` adds entries to the hosts file." { + _original="$(cat "${HOSTS_PATH}")" + + run "${_HOSTS}" block example.com + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + _compare "${_original}" "$(cat "${HOSTS_PATH}")" + _compare '127.0.0.1 example.com' "$(sed -n '11p' "${HOSTS_PATH}")" + [[ "$(cat "${HOSTS_PATH}")" != "${_original}" ]] + [[ "$(sed -n '11p' "${HOSTS_PATH}")" == "127.0.0.1 example.com" ]] +} + +@test "\`block \` prints feedback." { + run "${_HOSTS}" block example.com + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + [[ "${lines[0]}" == "Added:" ]] + [[ "${lines[1]}" == "127.0.0.1 example.com" ]] + [[ "${lines[2]}" == "Added:" ]] + [[ "${lines[3]}" == "fe80::1%lo0 example.com" ]] + [[ "${lines[4]}" == "Added:" ]] + [[ "${lines[5]}" == "::1 example.com" ]] +} + +# help ######################################################################## + +@test "\`help block\` exits with status 0." { + run "${_HOSTS}" help block + [[ ${status} -eq 0 ]] +} + +@test "\`help block\` prints help information." { + run "${_HOSTS}" help block + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + [[ "${lines[0]}" == "Usage:" ]] + [[ "${lines[1]}" == " hosts block " ]] +} diff --git a/test/unblock.bats b/test/unblock.bats new file mode 100644 index 0000000..a179ef9 --- /dev/null +++ b/test/unblock.bats @@ -0,0 +1,149 @@ +#!/usr/bin/env bats + +load test_helper + +# `hosts unblock` ################################################################# + +@test "\`unblock\` with no arguments exits with status 1." { + run "${_HOSTS}" unblock + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + [[ ${status} -eq 1 ]] +} + +@test "\`unblock\` with no argument does not change the hosts file." { + _original="$(cat "${HOSTS_PATH}")" + + run "${_HOSTS}" unblock + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + [[ "$(cat "${HOSTS_PATH}")" == "${_original}" ]] +} + +@test "\`unblock\` with no arguments prints help information." { + run "${_HOSTS}" unblock + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + [[ "${lines[0]}" == "Usage:" ]] + [[ "${lines[1]}" == " hosts unblock " ]] +} + +# `hosts unblock ` ############################################ + +@test "\`unblock \` exits with status 1." { + { + run "${_HOSTS}" block example.com + } + + run "${_HOSTS}" unblock example.net + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + [[ ${status} -eq 1 ]] +} + +@test "\`unblock \` prints error message." { + { + run "${_HOSTS}" block example.com + } + + run "${_HOSTS}" unblock example.net + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + [[ ${output} == "No matching records found." ]] +} + +# `hosts unblock ` ########################################### + +@test "\`unblock \` exits with status 0." { + { + run "${_HOSTS}" add 0.0.0.0 example.com + run "${_HOSTS}" block example.com + run "${_HOSTS}" add 127.0.0.1 example.net + } + + run "${_HOSTS}" unblock example.com + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + [[ ${status} -eq 0 ]] +} + +@test "\`unblock \` updates the hosts file." { + { + run "${_HOSTS}" add 0.0.0.0 example.com + run "${_HOSTS}" block example.com + run "${_HOSTS}" add 127.0.0.1 example.net + } + _original="$(cat "${HOSTS_PATH}")" + + run "${_HOSTS}" unblock example.com + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + _compare "${_original}" "$(cat "${HOSTS_PATH}")" + [[ "$(sed -n '11p' "${HOSTS_PATH}")" == "0.0.0.0 example.com" ]] + [[ "$(sed -n '12p' "${HOSTS_PATH}")" == "127.0.0.1 example.net" ]] + [[ "$(sed -n '13p' "${HOSTS_PATH}")" == "" ]] +} + +@test "\`unblock \` removes all matches." { + { + run "${_HOSTS}" add 0.0.0.0 example.com + run "${_HOSTS}" block example.com + run "${_HOSTS}" add 127.0.0.1 example.net + } + _original="$(cat "${HOSTS_PATH}")" + + run "${_HOSTS}" unblock example.com + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + _expected="\ +## +# Host Database +# +# localhost is used to configure the loopback interface +# when the system is booting. Do not change this entry. +## +127.0.0.1 localhost +255.255.255.255 broadcasthost +::1 localhost +fe80::1%lo0 localhost +0.0.0.0 example.com +127.0.0.1 example.net" + _compare "'${_expected}'" "'$(cat "${HOSTS_PATH}")'" + [[ "$(cat "${HOSTS_PATH}")" != "${_original}" ]] + [[ "$(cat "${HOSTS_PATH}")" == "${_expected}" ]] +} + +@test "\`unblock \` prints feedback." { + { + run "${_HOSTS}" add 0.0.0.0 example.com + run "${_HOSTS}" block example.com + run "${_HOSTS}" add 127.0.0.1 example.net + } + + run "${_HOSTS}" unblock example.com + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + _expected="\ +Removed: +127.0.0.1 example.com +Removed: +fe80::1%lo0 example.com +Removed: +::1 example.com" + [[ "${output}" == "${_expected}" ]] +} + +# help ######################################################################## + +@test "\`help unblock\` exits with status 0." { + run "${_HOSTS}" help unblock + [[ ${status} -eq 0 ]] +} + +@test "\`help unblock\` prints help information." { + run "${_HOSTS}" help unblock + printf "\${status}: %s\n" "${status}" + printf "\${output}: '%s'\n" "${output}" + [[ "${lines[0]}" == "Usage:" ]] + [[ "${lines[1]}" == " hosts unblock " ]] +}