autohosts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. #!/bin/bash
  2. VERSION=3.0.0
  3. # get the non-root user, so we can add the custom filters for them
  4. REGUSER=$(last | grep "logged in" | grep -o '^\S*' | head -1)
  5. # check os type for home directory path
  6. if [[ "$OSTYPE" != "darwin"* ]];
  7. then
  8. HOME_USER="/home/$REGUSER/autohosts/"
  9. AUTOHOSTS_PATH="/usr/bin/autohosts"
  10. else
  11. # macos
  12. HOME_USER="/Users/$REGUSER/autohosts/"
  13. AUTOHOSTS_PATH="/usr/local/bin/autohosts"
  14. fi
  15. # initialize reusable stuff, to make the terminal results prettier
  16. function croncheck() {
  17. crontab -l | grep -q 'autohosts' && EXIST=1 || EXIST=0
  18. }
  19. function green() {
  20. echo -e "\033[32m$1\033[0m"
  21. }
  22. function red() {
  23. echo -e "\033[0;31m$1\033[0m"
  24. }
  25. function brown() {
  26. echo -e "\033[0;33m$1\033[0m"
  27. }
  28. function purple() {
  29. echo -e "\033[0;35m$1\033[0m"
  30. }
  31. # append a notice to the terminal when an upstream list has been added
  32. function append() {
  33. green ">> $1 upstream successfully appended..."
  34. }
  35. # check for the existence of the upstream hosts file before downloading, to prevent malformed data
  36. function upstream(){
  37. # see if we're dealing with a linux-based distro or mac
  38. if [[ "$OSTYPE" != "darwin"* ]];
  39. then
  40. # not a mac, use wget
  41. if [[ "$(wget --spider "$1" 2>&1 | grep '200 OK')" ]];
  42. then
  43. # file exists! collect it
  44. wget "$1" -O ->> /etc/hosts
  45. append "$hosts_source"
  46. else
  47. logger -s "Autohosts update: $1 appears to be offline, skipping..."
  48. fi
  49. else
  50. # is a mac, use curl, no guarantee gnu tools are installed & unnecessary as a dependency, imo
  51. if [[ "$(curl -I "$1" 2>/dev/null | head -n 1 | cut -d$' ' -f2)" == '200' ]];
  52. then
  53. # file exists! collect it
  54. curl "$1" >> /etc/hosts
  55. append "$hosts_source"
  56. else
  57. logger -s "Autohosts update: $1 appears to be offline, skipping..."
  58. fi
  59. fi
  60. }
  61. if [[ $EUID -ne 0 ]]; then
  62. red "This script must be ran as root, or with sudo privileges."
  63. exit 1
  64. fi
  65. ### setup ###
  66. # if this is the first run, move to appropriate directory and set a config file
  67. if [ ! -e /etc/autohosts.conf ];
  68. then
  69. # move the script to /usr/bin so it can be executed as an alias
  70. if [ -f autohosts ] && [ ! -f "$AUTOHOSTS_PATH" ];
  71. then
  72. green "Creating an alias for autohosts.."
  73. cp autohosts "$AUTOHOSTS_PATH" && chmod +x "$AUTOHOSTS_PATH"
  74. fi
  75. # migrate custom filters file to the user's home directory
  76. if [ -f custom_filters ] && [ ! -d "$HOME_USER" ];
  77. then
  78. green "Creating custom filters for $REGUSER..."
  79. mkdir -p "$HOME_USER" && cp custom_filters "$HOME_USER"custom_filters && cp whitelist "$HOME_USER"whitelist
  80. green "Creating skeleton upstream file..."
  81. cp hosts_source "$HOME_USER" && chown "$REGUSER:$REGUSER" -R "$HOME_USER"
  82. fi
  83. # double-check to ensure we don't have a conflicting cron
  84. croncheck
  85. if [ "$EXIST" == 0 ];
  86. then
  87. # see if we are root or sudo; if sudo, we need to append sudo to the cron trigger
  88. if [ "$(whoami)" == "root" ] ; then
  89. CRON_PATH="$AUTOHOSTS_PATH"
  90. else
  91. CRON_PATH="sudo $AUTOHOSTS_PATH"
  92. fi
  93. # if no cronjob exists, create one
  94. crontab -l | { cat; echo "22 19 * * 0 $CRON_PATH > /dev/null 2>&1"; } | crontab -
  95. croncheck
  96. if [ "$EXIST" == 1 ];
  97. then
  98. green "Cronjob created..."
  99. else
  100. red "There was a problem creating the cronjob, you might have to create it manually!"
  101. fi
  102. fi
  103. purple "Setup is complete!"
  104. fi
  105. ### end setup ###
  106. purple "== UPDATING =="
  107. # check hosts_source for a list of preferred upstreams
  108. if [ -f "$HOME_USER"hosts_source ];
  109. then
  110. # start with a clean slate
  111. echo "" > /etc/hosts
  112. green "Obtaining hosts lists from preferred upstream sources..."
  113. # loop any hosts specified by the user in hosts_source and do an existence check
  114. for hosts_source in $(cat "$HOME_USER"hosts_source);
  115. do
  116. upstream "$hosts_source"
  117. done
  118. wait
  119. fi
  120. # courtesy check for localhost to prevent loopback breakage if a preferred upstream doesn't specify such
  121. if ! grep -q "127.0.0.1 localhost" /etc/hosts;
  122. then
  123. red "No upstream source has a courtesy entry for localhost! Adding one..."
  124. echo "127.0.0.1 localhost" >> /etc/hosts
  125. echo "255.255.255.255 broadcasthost" >> /etc/hosts
  126. fi
  127. # check for and include any custom filters
  128. if [ -e "$HOME_USER"custom_filters ];
  129. then
  130. green "Processing custom filters..."
  131. cat "$HOME_USER"'custom_filters' >> /etc/hosts
  132. else
  133. brown "No custom filters found at $HOME_USER""custom_filters, skipping..."
  134. fi
  135. # devdom: https://notabug.org/angela/devdom
  136. green "Checking if devdom is installed (will execute devdom hosts update, if so)"
  137. if [ -e /usr/bin/devdom ];
  138. then
  139. # devdom will echo a notice when ran
  140. devdom hosts
  141. else
  142. brown "Devdom is not installed; skipping Devdom hosts."
  143. fi
  144. # apply any whitelisted entries
  145. if [ -s "$HOME_USER"whitelist ];
  146. then
  147. for whitelist in $(cat "$HOME_USER"whitelist);
  148. do
  149. green "Checking for $whitelist.. whitelisting any match."
  150. if [[ "$OSTYPE" != "darwin"* ]];
  151. then
  152. sed -i "/$whitelist/d" /etc/hosts
  153. else
  154. # osx is weird and expects an extension to be called, so lets set to null
  155. sed -i '' "/$whitelist/d" /etc/hosts
  156. fi
  157. done
  158. wait
  159. fi
  160. # set a var that can be later referenced to see if the application has been configured already
  161. echo VERSION=$VERSION > /etc/autohosts.conf
  162. # if this is a mac, refresh the dns cache
  163. if [[ "$OSTYPE" == "darwin"* ]];
  164. then
  165. killall -HUP mDNSResponder
  166. fi
  167. purple "Hosts update complete!"