Add dependency check, fix some bugs, use more builtins and better practices, add colour to help output, update README for clarity, and remove the man page

This commit is contained in:
Kevin MacMartin 2015-02-02 08:31:09 -05:00
parent cbc6f7ed30
commit 6d7176688e
3 changed files with 150 additions and 213 deletions

View File

@ -1,28 +1,6 @@
# buildhosts #
# BuildHosts #
Build and maintain `/etc/hosts` while including lists imported from local and remote hosts list sources.
## Instructions ##
**Note:** All instructions should be performed as the **root** user or using the `sudo` command.
## Enable Remote Sources ##
1. The first time you run the `build` command, `/etc/hosts` will be moved to `/etc/hosts.core`, and the file `/etc/hosts.sources` will be created using the default sources list. The `/etc/hosts` file will then be generated by combining `/etc/hosts.core` and the resulting contents of the downloaded sources in `/etc/hosts.sources`.
2. You can now open `/etc/hosts.sources` and remove or comment out (by adding `#` in front) any sources you don't wish to use, as well as add new ones. Sources can remote (ie: `http://adaway.org/hosts.txt`) as well as local (ie: `file:///etc/hosts.d/mylist.txt`).
3. If you want to make any changes to the contents of what used to be `/etc/hosts`, you should now make them to `/etc/hosts.core`, and you'll need to rerun the `build` command to have them applied.
4. Once you're done customizing your configuration, run the `build` command again and the `/etc/hosts` file will be regenerated using the current list of sources and your up-to-date `/etc/hosts.core` file.
## Disable Remote Sources ##
1. To disable the configured hosts lists, run the `revert` command and `/etc/hosts.core` will be moved back to `/etc/hosts`.
* The `/etc/hosts.sources` file will continue to exist until it's manually deleted, and it will be used again the next time remote sources are enabled.
## Notes on /etc/hosts.sources ##
* On each line of `/etc/hosts.sources`, after `#` is commented/skipped.
* The `$HOSTS_SYSTEM` variable can be set to an alternative location to configure a different file to be used for `/etc/hosts`.
* Similarly, the `$HOSTS_CORE` and `$HOSTS_SOURCES` variables (which default to `$HOSTS_SYSTEM.core` and `$HOSTS_SYSTEM.sources` and will automatically change when `$HOSTS_SYSTEM` is changed), can be set to alternative locations to configure the use of different files.
Download and use custom hosts sources to build _/etc/hosts_
## Commands ##
@ -30,7 +8,24 @@ Build and maintain `/etc/hosts` while including lists imported from local and re
* `buildhosts revert`: remove lists imported from hosts list sources and restore `/etc/hosts`
* `buildhosts help`: display the help
**Note**: Colour output can be disabled by setting the variable `NOCOL=1`.
## Configure Hosts Sources ##
1. Running `buildhosts build` for the first time will move _/etc/hosts_ to _/etc/hosts.core_ and create _/etc/hosts.sources_ with a set of default hosts sources that focus on ad-blocking, and these will be downloaded before a new _/etc/hosts_ is then created using _/etc/hosts.core_ and the contents of the hosts sources.
2. Once this is finished, you can add/edit/delete or comment (lines starting with #) hosts sources in _/etc/hosts.sources_, and running `buildhosts build` again will re-create _/etc/hosts_ using your updated sources.
## Remove Hosts Sources ##
1. To disable the configured hosts lists and restore your original configuration, run `buildhosts revert` and `/etc/hosts.core` will be moved back to `/etc/hosts` (*/etc/hosts.sources* will need to be manually deleted).
## Environment Variables ##
These variables can be configured before running buildhosts to run with custom locations
* **HOSTS_DIR**: Directory containing the hosts file (default: _/etc/_)
* **HOSTS_SYSTEM**: The system hosts file (default: _$HOSTS_DIR/hosts_)
* **HOSTS_CORE**: The file containing the custom hosts configuration (default: _${HOSTS_SYSTEM}.core_)
* **HOSTS_SOURCES**: The file containing a list of hosts sources to download (default: _${HOSTS_SYSTEM}.sources_)
* **HOSTS_WHITELIST**: The file containing a list of domains to skip when parsing $HOSTS_SOURCES (default: _${HOSTS_SYSTEM}.whitelist_)
## Extra ##

View File

@ -1,179 +1,208 @@
#!/usr/bin/env bash
#
# buildhosts - Build and maintain /etc/hosts while including lists
# imported from local and remote hosts list sources
# BuildHosts: Download & use custom hosts sources to build /etc/hosts
#
# Instructions (as root):
# Written by Kevin MacMartin <prurigro@gmail.com>
#
# Enable Remote Sources
# 1. The first time you run the 'build' command, /etc/hosts will be
# moved to /etc/hosts.core, and the file /etc/hosts.sources will
# be created using the default sources list. The /etc/hosts file
# will then be generated by combining /etc/hosts.core and the
# resulting contents of downloaded sources in /etc/hosts.sources.
# 2. You can now open /etc/hosts.sources and remove or comment out
# (by adding # in front) any sources you don't wish to use, as
# well as add new ones. Sources can remote as well as local.
# 3. If you want to make any changes to the contents of what used to
# be /etc/hosts, you should now make them to /etc/hosts.core, and
# you'll need to rerun the 'build' command to have them applied.
# 4. Once you're done customizing your configuration, run the 'build'
# command again and the /etc/hosts file will be regenerated using
# the current list of sources and your up-to-date /etc/hosts.core
# file.
#
# Disable Remote Sources
# 1. To disable the configured hosts lists, run the 'revert' command
# and /etc/hosts.core will be moved back to /etc/hosts.
# * The /etc/hosts.sources file will continue to exist until it's
# manually deleted, and it will be used again the next time remote
# sources are enabled.
#
# Notes on /etc/hosts.sources
# * On each line of /etc/hosts.sources, after # is commented/skipped.
# * Colour output can be disabled by setting the variable NOCOL=1.
# * The $HOSTS_SYSTEM variable can be set to an alternative location
# to configure a different file to be used for /etc/hosts.
# * Similarly, the $HOSTS_CORE and $HOSTS_SOURCES variables (which
# default to $HOSTS_SYSTEM.core and $HOSTS_SYSTEM.sources and will
# automatically change if $HOSTS_SYSTEM is changed), can be set to
# alternative locations to configure the use of different files.
#
# by: Kevin MacMartin <prurigro@gmail.com>
# released under the MIT license
# Released under the MIT license
#
# Unset variables we don't expect
while read -r; do
[[ "$REPLY" =~ ^(HOSTS_DIR|HOSTS_SYSTEM|HOSTS_CORE|HOSTS_SOURCES|HOSTS_WHITELIST|UID|HOME|PATH|SHELL|TERM|PWD|SHLVL|_)= ]] \
|| unset ${REPLY/=*}
done < <(env)
# User variables
[[ -z "$HOSTS_SYSTEM" ]] && HOSTS_SYSTEM="/etc/hosts"
[[ -z "$HOSTS_CORE" ]] && HOSTS_CORE="${HOSTS_SYSTEM}.core"
[[ -z "$HOSTS_SOURCES" ]] && HOSTS_SOURCES="${HOSTS_SYSTEM}.sources"
[[ -z "$HOSTS_DIR" ]] \
&& HOSTS_DIR="/etc"
[[ -z "$HOSTS_SYSTEM" ]] \
&& HOSTS_SYSTEM="$HOSTS_DIR/hosts"
[[ -z "$HOSTS_CORE" ]] \
&& HOSTS_CORE="${HOSTS_SYSTEM}.core"
[[ -z "$HOSTS_SOURCES" ]] \
&& HOSTS_SOURCES="${HOSTS_SYSTEM}.sources"
[[ -z "$HOSTS_WHITELIST" ]] \
&& HOSTS_WHITELIST="${HOSTS_SYSTEM}.whitelist"
# Default list of sources (used to generate $HOSTS_SOURCES when it doesn't exist)
DEFAULT_SOURCES=(
default_sources=(
'https://adaway.org/hosts.txt'
'http://winhelp2002.mvps.org/hosts.txt'
'http://hosts-file.net/ad_servers.txt'
'http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&showintro=0&mimetype=plaintext'
)
script_dependencies=('curl' 'sed')
# Set the script name
BUILDHOSTS_SCRIPT="$(basename $0)"
script_name="${0//*\/}"
# Configure colours
if [[ "$NOCOL" -eq 1 ]]; then
HEADINGCOL="|"
if [ -t 1 ]; then
c_script='\e[1;35m'
c_category='\e[1;33m'
c_title='\e[1;34m'
c_text='\e[1;37m'
c_option='\e[1;31m'
c_divider='\e[1;30m'
c_heading='\e[1;40m'
c_success='\e[1;42m'
c_fail='\e[1;41m'
c_reset='\e[0m'
else
HEADINGCOL="\e[1;40m"
SUCCESSCOL="\e[1;42m"
FAILCOL="\e[1;41m"
RESETCOL="\e[0m"
c_heading='|'
fi
# Help function: display help text
function buildhosts_help(){
echo -e "${BUILDHOSTS_SCRIPT}: build /etc/hosts with your hosts list sources"
echo -e "\nusage: ${BUILDHOSTS_SCRIPT} [COMMAND]"
echo -e "\ncommands:"
echo -e " build: add hosts lists to /etc/hosts"
echo -e " revert: remove hosts lists from /etc/hosts"
echo -e " help: display this help"
[[ "$1" -eq 1 ]] && exit 0
printf "$c_text%s$c_reset%s\n" 'BuildHosts' ': Download and use custom hosts sources to build /etc/hosts'
printf "\n$c_title%s$c_reset\n" 'USAGE'
printf " $c_script%s$c_reset [$c_category%s$c_clear]\n" "$script_name" 'COMMAND'
printf "\n$c_title%s$c_reset\n" 'COMMANDS'
printf " $c_option%s$c_reset $c_divider| $c_text%s$c_clear\n" 'build' 'add hosts lists to /etc/hosts'
printf " $c_option%s$c_reset $c_divider| $c_text%s$c_clear\n" 'revert' 'remove hosts lists from /etc/hosts'
printf " $c_option%s$c_reset $c_divider| $c_text%s$c_clear\n" 'help' 'display this help'
[[ "$1" -eq 1 ]] \
&& exit 0
}
# Error function: display error then exit unsuccessfully
function buildhosts_error() {
echo -e "${HEADINGCOL} ${RESETCOL}${FAILCOL} ! ERROR:${RESETCOL}${FAILCOL} ${1}${RESETCOL}"
[[ "$2" -eq 1 ]] && echo && buildhosts_help
printf "$c_heading $c_fail%s$c_fail %s$c_reset\n" ' ! ERROR:' "$1" 2>&1
[[ "$2" -eq 1 ]] && {
printf '\n'
buildhosts_help
}
exit 1
}
function buildhosts_rootcheck() {
[[ $UID = 0 ]] \
|| buildhosts_error "$script_name must be run as root"
}
# The build function to generate or regenerate /etc/hosts using /etc/hosts.core and the list of sources
function buildhosts_build() {
# If $HOSTS_SOURCES doesn't exist, generate one using the default list of sources
if [[ ! -f "$HOSTS_SOURCES" ]]; then
echo -e "${HEADINGCOL} Generating Default Sources:${RESETCOL} ${HOSTS_SOURCES}"
echo '# file:///etc/hosts.d/localhostlist.txt' >> "$HOSTS_SOURCES"
echo '# http://domain.com/remotehostlist.txt' >> "$HOSTS_SOURCES"
for source in "${DEFAULT_SOURCES[@]}"; do
echo "$source" >> "$HOSTS_SOURCES"
# Fail if the user isn't root when $HOSTS_DIR or isn't writable
if [[ ! -w "$HOSTS_DIR" ]]; then
buildhosts_rootcheck
elif [ -f "$HOSTS_SYSTEM" ] && [ ! -w "$HOSTS_SYSTEM" ]; then
buildhosts_rootcheck
fi
printf "$c_heading %s$c_reset %s\n" 'Generating Default Sources:' "$HOSTS_SOURCES"
printf '%s\n' '# file:///etc/hosts.d/localhostlist.txt' >> "$HOSTS_SOURCES"
printf '%s\n' '# http://domain.com/remotehostlist.txt' >> "$HOSTS_SOURCES"
for source in "${default_sources[@]}"; do
printf '%s\n' "$source" >> "$HOSTS_SOURCES"
done
fi
# Fail if the /etc/hosts file isn't writable (and suggest using root)
[[ -w "$HOSTS_SYSTEM" ]] \
|| buildhosts_rootcheck
# Fail if $HOSTS_SOURCES contains no sources after trimming comments
[[ -n $(sed 's|^\ *#.*$||' "$HOSTS_SOURCES" | tr -d "\n") ]] || buildhosts_error "${HOSTS_SOURCES} doesn't contain any sources"
[[ -n $(sed 's|^\ *#.*$||' "$HOSTS_SOURCES" | tr -d "\n") ]] \
|| buildhosts_error "$HOSTS_SOURCES doesn't contain any sources"
# If $HOSTS_CORE doesn't exist and $HOSTS_SYSTEM does, move $HOSTS_SYSTEM to $HOSTS_CORE
if [ -f "$HOSTS_SYSTEM" -a ! -f "$HOSTS_CORE" ]; then
echo -e "${HEADINGCOL} Moving: ${RESETCOL} ${HOSTS_SYSTEM} to ${HOSTS_CORE}"
[[ -f "$HOSTS_SYSTEM" ]] && [[ ! -f "$HOSTS_CORE" ]] && {
printf "$c_heading %s $c_reset %s\n" 'Moving:' "$HOSTS_SYSTEM to $HOSTS_CORE"
cp "$HOSTS_SYSTEM" "$HOSTS_CORE"
fi
}
# Generate the hosts list using the URLs in the $HOSTS_SOURCES
unset TMPHOSTS
unset temp_hosts
while read -r source; do
if [[ -n "$source" ]]; then
echo -e "${HEADINGCOL} Downloading: ${RESETCOL} ${source}"
[[ -n "$source" ]] && {
printf "$c_heading %s $c_reset $source\n" 'Downloading:'
# Download the the current source into $SRCDATA and fail if the result is empty
SRCDATA=$(curl -C - -s "$source" | tr -d "\r")
[[ -n "$SRCDATA" ]] || buildhosts_error "Could not download list @ ${source}"
# Download the the current source into $source_data and fail if the result is empty
source_data=$(curl -C - -s "$source" | tr -d "\r")
[[ -n "$source_data" ]] \
|| buildhosts_error "Could not download list @ $source"
# If this isn't the first source, add a newline at the top
[[ -n "$TMPHOSTS" ]] && SRCDATA=$(echo -e "\n${SRCDATA}")
[[ -n "$temp_hosts" ]] \
&& source_data=$(printf '\n%s\n' "$source_data")
# Strip comments, then add the source to the end of $TMPHOSTS
TMPHOSTS=${TMPHOSTS}$(sed 's|\ *#.*$||' <<< "$SRCDATA")
fi
# Strip comments, then add the source to the end of $temp_hosts
temp_hosts=$temp_hosts$(sed 's|\ *#.*$||' <<< "$source_data")
}
done < <(sed 's|^\ *#.*$||' "$HOSTS_SOURCES")
# Sort and remove duplicates, change 0.0.0.0 to 127.0.0.1, and remove non-127.0.0.1 redirections
TMPHOSTS=$(sort -u < <(sed 's|\t| |;s|^\ *[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*|127\.0\.0\.1|;
s|^127\.0\.0\.1\ \ *localhost\ *$||;
s|^\ *[^1].*$||' <<< "$TMPHOSTS"))
temp_hosts=$(sort -u < <(sed 's|\t| |;s|^\ *[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*|127\.0\.0\.1|;
s|^127\.0\.0\.1\ \ *localhost\ *$||;
s|^\ *[^1].*$||' <<< "$temp_hosts"))
# Add the system hosts file to the hosts list and warn if $HOSTS_CORE is missing
echo -e "${HEADINGCOL} WRITING: ${RESETCOL} ${HOSTS_CORE} and $(wc -l <<< "$TMPHOSTS") host source entries to ${HOSTS_SYSTEM}"
printf "$c_heading %s $c_reset %s\n" 'WRITING:' "$HOSTS_CORE and $(wc -l <<< "$temp_hosts") host source entries to $HOSTS_SYSTEM"
[[ -f "$HOSTS_CORE" ]] \
&& TMPHOSTS=$(cat "$HOSTS_CORE")$(echo -e "\n\n# Generated Host List (${BUILDHOSTS_SCRIPT})")${TMPHOSTS} \
|| echo -e "${HEADINGCOL} ${RESETCOL}${FAILCOL} WARNING:${RESETCOL} core hosts file ${HOSTS_CORE} does not exist"
&& temp_hosts=$(<"$HOSTS_CORE")$(printf '\n\n%s\n' "# Generated Host List ($script_name)")$temp_hosts \
|| printf "$c_heading $c_fail %s$c_reset %s" 'WARNING:' "core hosts file $HOSTS_CORE does not exist"
# Write $TMPHOSTS to $HOSTS_SYSTEM if it's not empty
[[ -n "$TMPHOSTS" ]] && echo -e "$TMPHOSTS" > "$HOSTS_SYSTEM"
if [[ -n $(cat "$HOSTS_SYSTEM") ]]; then
echo -e "${HEADINGCOL} ${RESETCOL}${SUCCESSCOL} DONE! ${RESETCOL}"
# Exclude domains in the whitelist
[[ -f "$HOSTS_WHITELIST" ]] && {
while read -r; do
temp_hosts=$(sed '/^'$REPLY'/d' /etc/hosts <<< "$temp_hosts")
done <"$HOSTS_WHITELIST"
}
# Write $temp_hosts to $HOSTS_SYSTEM if it's not empty
[[ -n "$temp_hosts" ]] \
&& printf '%s\n' "$temp_hosts" > "$HOSTS_SYSTEM"
if [[ -n $(<"$HOSTS_SYSTEM") ]]; then
printf "$c_heading $c_success %s $c_reset\n" 'DONE!'
else
echo -e "${HEADINGCOL} ${RESETCOL}${FAILCOL} FAILED... ${RESETCOL} (reverting hosts file)"
cp "$MAINHOSTS" "$HOSTS_SYSTEM"
buildhosts_error "${HOSTS_SYSTEM} could not be created"
printf "$c_heading $c_fail %s $c_reset %s\n" 'FAILED...' '(reverting hosts file)'
cp "$HOSTS_CORE" "$HOSTS_SYSTEM"
buildhosts_error "$HOSTS_SYSTEM could not be created"
exit 1
fi
}
function buildhosts_revert() {
# Fail if $HOSTS_CORE doesn't exist
[[ -f "$HOSTS_CORE" ]] || buildhosts_error "${HOSTS_CORE} does not exist, cannot revert"
[[ -f "$HOSTS_CORE" ]] \
|| buildhosts_error "$HOSTS_CORE does not exist, cannot revert"
# Fail if $HOSTS_CORE is empty when all comments are removed
[[ -n $(sed 's|^\ *#.*$||' "$HOSTS_CORE" | tr -d "\n") ]] || buildhosts_error "${HOSTS_CORE} contains no information, cannot revert"
[[ -n $(sed 's|^\ *#.*$||' "$HOSTS_CORE" | tr -d '\n') ]] \
|| buildhosts_error "$HOSTS_CORE contains no information, cannot revert"
# Move $HOSTS_CORE to $HOSTS_SYSTEM
echo -e "${HEADINGCOL} MOVING:${RESETCOL} ${HOSTS_CORE} to ${HOSTS_SYSTEM}"
printf "$c_heading %s$c_reset %s\n" 'MOVING:' "$HOSTS_CORE to $HOSTS_SYSTEM"
mv "$HOSTS_CORE" "$HOSTS_SYSTEM" \
&& echo -e "${HEADINGCOL} ${RESETCOL}${SUCCESSCOL} DONE!${RESETCOL}" \
|| buildhosts_error "${HOSTS_CORE} could not be moved to ${HOSTS_SYSTEM}"
&& printf "$c_heading $c_success %s$c_reset\n" 'DONE!' \
|| buildhosts_error "$HOSTS_CORE could not be moved to $HOSTS_SYSTEM"
}
# Fail if the user isn't root
[[ $EUID -eq 0 ]] || buildhosts_error "${BUILDHOSTS_SCRIPT} must be run as root"
# Test for programs required by this script before running
for dep in ${script_dependencies[@]}; do
[[ $(type -P "$dep") ]] || {
[[ -n "$missing_dependencies" ]] \
&& missing_dependencies="$missing_dependencies,"
missing_dependencies="$missing_dependencies $dep"
}
done
[[ -n "$missing_dependencies" ]] \
&& buildhosts_error "Missing dependencies:$missing_dependencies"
# Fail if run with no commands
[[ -z "$1" ]] && echo -e "please run with a valid command\n" && buildhosts_help 1
[[ -z "$1" ]] \
&& buildhosts_error "A valid command must be provided" 1
case "$1" in
build|--build)
build)
buildhosts_build
;;
revert|--revert)
revert)
buildhosts_revert
;;
help|--help|-h)

View File

@ -1,87 +0,0 @@
.if !\n(.g \{\
. if !\w|\*(lq| \{\
. ds lq ``
. if \w'\(lq' .ds lq "\(lq
. \}
. if !\w|\*(rq| \{\
. ds rq ''
. if \w'\(rq' .ds rq "\(rq
. \}
.\}
.ie t .ds Tx \s-1T\v'.4n'\h'-.1667'E\v'-.4n'\h'-.125'X\s0
. el .ds Tx TeX
.de Id
. ds Yr \\$4
. substring Yr 0 3
. ds Mn \\$4
. substring Mn 5 6
. ds Dy \\$4
. substring Dy 8 9
. \" ISO 8601 date, complete format, extended representation
. ds Dt \\*(Yr-\\*(Mn-\\*(Dy
..
.TH BUILDHOSTS 1 \*(Dt "buildhosts (git)" "User Commands"
.hy 0
.
.SH "NAME"
.B buildhosts
.TP
build and maintain \fB/etc/hosts\fR while including lists imported from local and remote hosts list sources\.
.
.SH "SYNOPSIS"
.
.B buildhosts
.RI [COMMAND]
.
.SH "COMMANDS"
.
.P
\fBbuild\fR: generate \fB/etc/hosts\fR using \fB/etc/hosts\.core\fR and the configured sources
.P
.P
\fBrevert\fR: remove lists imported from hosts list sources and restore \fB/etc/hosts\fR
.P
.P
\fBhelp\fR: display the help
.P
.P
\fB**\fR Colour output can be disabled by setting the variable \fBNOCOL=1\fR
.
.SH "INSTRUCTIONS"
(All instructions should be performed as the \fBroot\fR user or using the \fBsudo\fR command)
.
.SS "Enable Remote Sources"
.P
\fB1\.\fR The first time you run the \fBbuild\fR command, \fB/etc/hosts\fR will be moved to \fB/etc/hosts\.core\fR, and the file \fB/etc/hosts\.sources\fR will be created using the default sources list\. The \fB/etc/hosts\fR file will then be generated by combining \fB/etc/hosts\.core\fR and the resulting contents of the downloaded sources in \fB/etc/hosts\.sources\fR\.
.P
\fB2\.\fR You can now open \fB/etc/hosts\.sources\fR and remove or comment out (by adding \fB#\fR in front) any sources you don\'t wish to use, as well as add new ones\. Sources can remote (ie: \fBhttp://adaway\.org/hosts\.txt\fR) as well as local (ie: \fBfile:///etc/hosts\.d/mylist\.txt\fR)\.
.P
\fB3\.\fR If you want to make any changes to the contents of what used to be \fB/etc/hosts\fR, you should now make them to \fB/etc/hosts\.core\fR, and you\'ll need to rerun the \fBbuild\fR command to have them applied\.
.P
\fB4\.\fR Once you\'re done customizing your configuration, run the \fBbuild\fR command again and the \fB/etc/hosts\fR file will be regenerated using the current list of sources and your up\-to\-date \fB/etc/hosts\.core\fR file\.
.SS "Disable Remote Sources"
.P
\fB1\.\fR To disable the configured hosts lists, run the \fBrevert\fR command and \fB/etc/hosts\.core\fR will be moved back to \fB/etc/hosts\fR\.
.P
\fB**\fR The \fB/etc/hosts\.sources\fR file will continue to exist until it\'s manually deleted, and it will be used again the next time remote sources are enabled\.
.SS "Notes on Hosts Sources"
.TP
On each line of \fB/etc/hosts\.sources\fR, after \fB#\fR is commented/skipped\.
.P
.P
The \fB$HOSTS_SYSTEM\fR variable can be set to an alternative location to configure a different file to be used for \fB/etc/hosts\fR\.
.P
.P
Similarly, the \fB$HOSTS_CORE\fR and \fB$HOSTS_SOURCES\fR variables (which default to \fB$HOSTS_SYSTEM\.core\fR and \fB$HOSTS_SYSTEM\.sources\fR and will automatically change when \fB$HOSTS_SYSTEM\fR is changed), can be set to alternative locations to configure the use of different files\.
.
.SH "CREDITS"
Written by Kevin MacMartin:
.
.IP "\(bu" 2
GitHub Projects \fIhttps://github\.com/prurigro\fR
.
.IP "\(bu" 2
Arch Linux AUR Packages \fIhttps://aur\.archlinux\.org/packages/?SeB=m&K=prurigro\fR
.
.SH "LICENSE"
Released under the MIT license \fIhttp://opensource\.org/licenses/MIT\fR\.