├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── funceble ├── iana-domains-db ├── output ├── .gitignore ├── hosts │ ├── .gitignore │ ├── ACTIVE │ │ └── .gitignore │ ├── INACTIVE │ │ └── .gitignore │ └── INVALID │ │ └── .gitignore ├── logs │ ├── .gitignore │ ├── dateFormat │ │ └── .gitignore │ ├── noReferer │ │ └── .gitignore │ ├── percentage │ │ └── .gitignore │ └── whois │ │ └── .gitignore └── splited │ └── .gitignore └── tool /.gitignore: -------------------------------------------------------------------------------- 1 | # Temp Files 2 | *~ 3 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@funilrys.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Want to contribute ? Let us first thank you for your action!! 2 | 3 | :heart: :tada: :heart: :tada: 4 | ``` 5 | .___________. __ __ ___ .__ __. __ ___ _______. __ 6 | | || | | | / \ | \ | | | |/ / / | | | 7 | `---| |----`| |__| | / ^ \ | \| | | ' / | (----` | | 8 | | | | __ | / /_\ \ | . ` | | < \ \ | | 9 | | | | | | | / _____ \ | |\ | | . \ .----) | |__| 10 | |__| |__| |__| /__/ \__\ |__| \__| |__|\__\ |_______/ (__) 11 | ``` 12 | 13 | :heart: :tada: :heart: :tada: 14 | 15 | There are many ways to contribute here's few way about how to contribute! 16 | 17 | # Fix typography 18 | 19 | I'm not an English native speaker so you can help by fixing the typography in Wiki, README.md or even my comments under `funceble` and `tool`! 20 | 21 | If you plan to fix typography into `funceble` and or `tool` please be sure to read the [:warning: WARNING :warning:](https://github.com/funilrys/funceble/wiki/How-to-contribute%3F/#warning-warning-warning) part first. 22 | 23 | # Suggest new Features 24 | 25 | I like to get suggestion about things I didn't think about! So let me know your suggestion if it's possible and once it's implemented your name/nickname will be added in the [Special Thanks and Contributors](https://github.com/funilrys/funceble/wiki/Special-Thanks-and-Contributors) section! :smile: 26 | 27 | # Hack :smile: 28 | 29 | The best way to contribute is to hack funceble :smile:. Simply **send a new [Pull Request](https://github.com/funilrys/funceble/compare)** with your modifications after you **[forked](https://github.com/funilrys/funceble/pulls#fork-destination-box)** and edited the repository. 30 | 31 | Once done, let's talk about your modifications :+1::smile: !!! 32 | 33 | # :warning: WARNING :warning: 34 | 35 | - If you plan to **send a new [Pull Request](https://github.com/funilrys/funceble/compare)** all **contributions/modifications** must be done under **the `dev` or a new branch**. 36 | 37 | ## DO NOT FORGET 38 | 39 | - Sign your commit(s) with **"Signed-off by: FirstName LastName < email[at]service[dot]com >"** 40 | 41 | **AND/OR** 42 | 43 | - Sign your commit(s) with **PGP** _(Please read more [here](https://github.com/blog/2144-gpg-signature-verification))_. 44 | 45 | - :warning::warning: Every **contributions/modifications** which are under the `master` branch _(exception for minor changes)_ **will not be merged**. :warning::warning: 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Nissar Chababy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PLEASE CONSIDER THIS REPOSITORY AS ARCHIVED. 2 | If you want a more up to date script, please report to **[PyFunceble](https://github.com/funilrys/PyFunceble)** 3 | 4 | # Funceble 5 | 6 | > A script to check domains or IP accessibility. 7 | 8 | [![license](https://img.shields.io/github/license/funilrys/funceble.svg)](https://github.com/funilrys/funceble/blob/master/LICENSE) [![GitHub tag](https://img.shields.io/github/tag/funilrys/funceble.svg)](https://github.com/funilrys/funceble/tags) [![GitHub release](https://img.shields.io/github/release/funilrys/funceble.svg)](https://github.com/funilrys/funceble/releases/latest) 9 | 10 | [![GitHub issues open](https://img.shields.io/github/issues/funilrys/funceble.svg)]() [![GitHub closed issues](https://img.shields.io/github/issues-closed/funilrys/funceble.svg)](https://github.com/funilrys/) 11 | 12 | [![Github file size](https://img.shields.io/github/size/funilrys/funceble/funceble.svg)](https://github.com/funilrys/funceble/blob/master/funceble) 13 | 14 | The main idea was to create a script that can check if a given domain, a `hosts` file or a **list of domains** are/is **ACTIVE** or **INACTIVE**. And, in between, if wanted, **generate a `hosts` file** based on the results. 15 | 16 | Have any question? Fill a new issue and I'll do my best to answer as soon as possible. 17 | 18 | ## :book: Wiki as place to be :star2::star2::star2: 19 | 20 | Want to know more about **Funceble**? All information to know are under the [wiki](https://github.com/funilrys/funceble/wiki)! You can also contribute there if you want! :smile: 21 | 22 | You can get a copy of the wiki with the following: 23 | 24 | ```shell 25 | git clone https://github.com/funilrys/funceble.wiki.git 26 | ``` 27 | 28 | ## Main Features 29 | 30 | - Read an existing `hosts`file and check every domain present into it. 31 | - Generate `hosts` file 32 | 33 | - With custom IP 34 | - ONLY with **ACTIVE** domains 35 | 36 | - Show on screen 37 | 38 | - The status of a given domain is **ACTIVE**, **INACTIVE** or **INVALID** (live update) 39 | - The percentage of **ACTIVE**, **INACTIVE** and **INVALID** (at the end) 40 | 41 | - Save on single file 42 | 43 | - Result of execution (live update) 44 | - The percentage of **ACTIVE**, **INACTIVE** and **INVALID** (at the end) 45 | 46 | - Save on separated files (when needed) 47 | 48 | - **ACTIVE** domain 49 | - **INACTIVE** domain 50 | - **INVALID** domain 51 | 52 | ## Valuable links 53 | 54 | They updated their hosts file or blocklist with the help of [Funceble](https://github.com/funilrys/funceble/) or [dead-hosts](https://github.com/funilrys/dead-hosts). 55 | 56 | Repo / List Name | Author | Repository / Website | Raw 57 | ---------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- 58 | add.2o7Net | [Tomasz Przybył](https://github.com/FadeMind) | [Repository](https://github.com/FadeMind/hosts.extras/tree/master/add.2o7Net) | [Raw](https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.2o7Net/hosts) 59 | add.Dead | [Tomasz Przybył](https://github.com/FadeMind) | [Repository](https://github.com/FadeMind/hosts.extras/tree/master/add.Dead) | [Raw](https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.Dead/hosts) 60 | add.Risk | [Tomasz Przybył](https://github.com/FadeMind) | [Repository](https://github.com/FadeMind/hosts.extras/tree/master/add.Risk) | [Raw](https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.Risk/hosts) 61 | add.Spam | [Tomasz Przybył](https://github.com/FadeMind) | [Repository](https://github.com/FadeMind/hosts.extras/tree/master/add.Spam) | [Raw](https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.Spam/hosts) 62 | Badd-Boyz-Hosts | [Mitchell Krog](https://github.com/mitchellkrogza) | [Repository](https://github.com/mitchellkrogza/Badd-Boyz-Hosts) | [Raw](https://raw.githubusercontent.com/mitchellkrogza/Badd-Boyz-Hosts/master/PULL_REQUESTS/domains.txt) 63 | KADhosts | [KAD](https://github.com/azet12) | [Repository](https://github.com/azet12/KADhosts) | [Raw](https://raw.githubusercontent.com/azet12/KADhosts/master/KADhosts.txt) 64 | Nginx Ultimate Bad Bot & Referrer Spam Blocker | [Mitchell Krog](https://github.com/mitchellkrogza) | [Repository](https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/) | [Raw](https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-referrers.list) 65 | SpotifyAds | [Tomasz Przybył](https://github.com/FadeMind) | [Repository](https://github.com/FadeMind/hosts.extras/tree/master/SpotifyAds) | [Raw](https://raw.githubusercontent.com/FadeMind/hosts.extras/master/SpotifyAds/hosts) 66 | The Big List of Hacked Malware Web Sites | [Mitchell Krog](https://github.com/mitchellkrogza) | [Repository](https://github.com//mitchellkrogza/The-Big-List-of-Hacked-Malware-Web-Sites/) | [Raw](https://raw.githubusercontent.com/mitchellkrogza/The-Big-List-of-Hacked-Malware-Web-Sites/master/.dev-tools/_strip_domains/domains.txt) 67 | UncheckyAds | [Tomasz Przybył](https://github.com/FadeMind) | [Repository](https://github.com/FadeMind/hosts.extras/tree/master/UncheckyAds) | [Raw](https://raw.githubusercontent.com/FadeMind/hosts.extras/master/UncheckyAds/hosts) 68 | 69 | Your list or repository is not listed here? Fill a new issue [here](https://github.com/funilrys/funceble/issues/new?title=Please%20add%20my%20list%20or%20repository%20to%20the%20valuable%20links) :smile_cat: 70 | 71 | -------------------------------------------------------------------------------- 72 | 73 | # Special Thanks 74 | 75 | Thank you for your awesome `hosts` lists, support or contributions which helped _(and/or still help)_ me build this script. :smile: :+1: 76 | 77 | - Adam Warner - [@PromoFaux](https://github.com/PromoFaux) 78 | - Mitchell Krog - [@mitchellkrogza](https://github.com/mitchellkrogza) 79 | - [Pi-Hole](https://github.com/pi-hole/pi-hole) 80 | 81 | # Contributors 82 | 83 | Thank you for your awesome ideas or contributions which make or made funceble better!! :+1: :100: :1st_place_medal: 84 | 85 | - Mitchell Krog - [@mitchellkrogza](https://github.com/mitchellkrogza) 86 | 87 | - WaLLy3K - [@WaLLy3K](https://github.com/WaLLy3K) 88 | 89 | - xxcriticxx - [@xxcriticxx](https://github.com/xxcriticxx) 90 | 91 | -------------------------------------------------------------------------------- 92 | 93 | # Supporting the project 94 | 95 | [Funceble](https://github.com/funilrys/funceble) and [dead-hosts](https://github.com/funilrys/dead-hosts) are powered by :coffee:! 96 | 97 | This project helps you and or you like it? Why don't you buy me a cup of :coffee:? :smile_cat: 98 | 99 | [![Buy me a cup of coffee](https://img.shields.io/badge/Buy%20-me%20a%20cup%20of%20%E2%98%95-blue.svg)](https://www.paypal.me/funilrys/) 100 | 101 | -------------------------------------------------------------------------------- 102 | 103 | # `Hosts` files 104 | 105 | ## What is a hosts file? 106 | 107 | A hosts file, named `hosts` (with no file extension), is a plain-text file used by all operating systems to map hostnames to IP addresses. 108 | 109 | In most operating systems, the `hosts` file is preferential to `DNS`. Therefore if a domain is resolved by the `hosts` file, the request never leaves your computer. 110 | 111 | Having a smart `hosts` file goes a long way towards blocking malware, adware, ransomware, porn and other nuisance websites. 112 | 113 | A hosts file like this causes any lookups to any of the listed domains to resolve back to your localhost so it prevents any outgoing connections to the listed domains. 114 | 115 | ## Recommendations 116 | 117 | I'd personally recommend using [Steven's hosts](https://github.com/StevenBlack/hosts) or [Pi-Hole](https://github.com/pi-hole/pi-hole) which are in my opinion the best out there. 118 | 119 | -------------------------------------------------------------------------------- 120 | 121 | # License 122 | 123 | ``` 124 | MIT License 125 | 126 | Copyright (c) 2017 Nissar Chababy 127 | 128 | Permission is hereby granted, free of charge, to any person obtaining a copy 129 | of this software and associated documentation files (the "Software"), to deal 130 | in the Software without restriction, including without limitation the rights 131 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 132 | copies of the Software, and to permit persons to whom the Software is 133 | furnished to do so, subject to the following conditions: 134 | 135 | The above copyright notice and this permission notice shall be included in all 136 | copies or substantial portions of the Software. 137 | 138 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 139 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 140 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 141 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 142 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 143 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 144 | SOFTWARE. 145 | ``` 146 | -------------------------------------------------------------------------------- /funceble: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # _______ _ _______ _______ ______ _ _______ 4 | # ( ____ \|\ /|( ( /|( ____ \( ____ \( ___ \ ( \ ( ____ \ 5 | # | ( \/| ) ( || \ ( || ( \/| ( \/| ( ) )| ( | ( \/ 6 | # | (__ | | | || \ | || | | (__ | (__/ / | | | (__ 7 | # | __) | | | || (\ \) || | | __) | __ ( | | | __) 8 | # | ( | | | || | \ || | | ( | ( \ \ | | | ( 9 | # | ) | (___) || ) \ || (____/\| (____/\| )___) )| (____/\| (____/\ 10 | # |/ (_______)|/ )_)(_______/(_______/|/ \___/ (_______/(_______/ 11 | 12 | # Written by: @Funilrys, Nissar Chababy 13 | # Github : https://github.com/funilrys/funceble 14 | 15 | ################################ Contributors ################################## 16 | # - @mitchellkrogza, Mitchell Krog 17 | # - badreferslist: used along the construction of this script :) 18 | # @Source: https://git.io/vQPz8 19 | # - Idea of implementation of a timeout for whois 20 | # @Source: https://git.io/vQPz0 21 | # - @PromoFaux, Adam Warner with Pi-Hole 22 | # - Their blocking list is just awesome to test this script :) 23 | # - @WaLLy3K 24 | # - Idea of implementation of execution time 25 | # @Source: https://git.io/vQPzg 26 | ################################################################################ 27 | 28 | 29 | ################################# Temporary ####################################&& 30 | # Path to temporary file 31 | whoIs="/var/tmp/whois.$$" 32 | ################################################################################ 33 | ################################### Files ###################################### 34 | # IANA Root Zone Database file. 35 | # The file is a dump of the extensions this script can accept. 36 | # Source: https://www.iana.org/domains/root/db 37 | ianaDB="iana-domains-db" 38 | ################################################################################ 39 | ###############################  Text Format ################################### 40 | # Red Color 41 | red=$(tput setaf 1) 42 | 43 | # White Color 44 | white=$(tput setaf 7) 45 | 46 | # Cyan Color 47 | cyan=$(tput setaf 6) 48 | 49 | # Magenta Color 50 | magenta=$(tput setaf 5) 51 | 52 | # Bold 53 | bold=$(tput bold) 54 | 55 | # Disable formating 56 | normal=$(tput sgr0) 57 | ################################################################################ 58 | ################################## Status ###################################### 59 | # Valid domain status 60 | validStatus="ACTIVE" 61 | 62 | # Invalid domain status 63 | invalidStatus="INVALID" 64 | 65 | # Down domain status 66 | errorStatus="INACTIVE" 67 | ################################################################################ 68 | ################################## Outputs ##################################### 69 | # If noFiles=true, We don't any results files ==> Not applied to hosts file 70 | noFiles=false 71 | 72 | # Generate debug file under log 73 | # DO NOT USE THIS IF YOU DON'T KNOW HOW TO DEBUG FROM OUTPUTTED FILE 74 | debugUnknown=false 75 | 76 | # Defaut name for hosts file 77 | hostsDefault='hosts' 78 | 79 | # Output directory. 80 | # DO NOT FORGET '/' AT THE END 81 | outputDir='%%currentDir%%/output/' 82 | 83 | # hosts directory 84 | hostsDir=${outputDir}hosts/ 85 | 86 | # ACTIVE hosts directory 87 | activeHostsDir=${hostsDir}ACTIVE/ 88 | 89 | # INACTIVE hosts directory 90 | inactiveHostsDir=${hostsDir}INACTIVE/ 91 | 92 | # INVALID hosts directory 93 | invalidHostsDir=${hostsDir}INVALID/ 94 | 95 | # Output of log 96 | logOutput=${outputDir}'logs/' 97 | 98 | # Whois output 99 | whoisLogOutput=${logOutput}whois/ 100 | 101 | # Date output 102 | dateLogOutput=${logOutput}dateFormat/ 103 | 104 | # Percentages output 105 | percentageLogOutput=${logOutput}percentage/ 106 | 107 | # Output of execution Time log 108 | executionLog=${logOutput}execution.log 109 | 110 | # Ouput of no referer log 111 | noRefererLogOutput=${logOutput}noReferer/ 112 | 113 | # Output of inactive domain 114 | outputInactiveHost=${inactiveHostsDir}${hostsDefault} 115 | 116 | # Output of active domain 117 | outputActiveHost=${activeHostsDir}${hostsDefault} 118 | 119 | # Output of invalid domain 120 | outputInvalidHost=${invalidHostsDir}${hostsDefault} 121 | 122 | # Output of unified results 123 | outputUnifiedResult=${outputDir}/result.txt 124 | 125 | # Output of valid results 126 | outputValidResult=${outputDir}splited/active.txt 127 | 128 | # Output of invalid results 129 | outputInvalidResult=${outputDir}splited/invalid.txt 130 | 131 | # Output of error results 132 | outputErrorResult=${outputDir}splited/inactive.txt 133 | 134 | # Output of persentage log 135 | outputPercentageLog=${percentageLogOutput}percentage.txt 136 | ################################################################################ 137 | ############################## Default Values ################################## 138 | # IP for host file 139 | customIP='0.0.0.0' 140 | 141 | # Current Date 142 | currentDate=$(date) 143 | 144 | # Date if we append it to file 145 | fileNameDate=_${currentDate// /_} 146 | 147 | # Activate/Desactivate the generation of hosts file 148 | generateHosts=false 149 | 150 | # Output less data 151 | outputLess=false 152 | 153 | # Output unified file 154 | outputUnified=true 155 | 156 | # Output logs 157 | outputLogs=true 158 | 159 | # If set to true, we don't print anything 160 | quiet=false 161 | 162 | # If set to false, we generate only one file with the results 163 | splitFiles=false 164 | 165 | # IANA whois server. The following is there to give use the whois 166 | # host we have to call to get a (valid) response. 167 | # Note: Whois Server are different for each extension. 168 | whoisServer="whois.iana.org" 169 | 170 | # Regex to match 171 | regexCurrentDir='%%currentDir%%' 172 | 173 | # Show/hide execution time 174 | showExecutionTime=false 175 | 176 | # Link to script 177 | linkScript="https://github.com/funilrys/funceble" 178 | 179 | # Show/hide percentage 180 | showPercentage=true 181 | 182 | # Number of domain tested 183 | numberOfTested=0 184 | 185 | # Number of active 186 | numberOfActive=0 187 | 188 | # Number of domain which returns inactive 189 | numberOfInactive=0 190 | 191 | # Number of domain which returns invalid 192 | numberOfInvalid=0 193 | 194 | # Default seconds before timeout 195 | secondsBeforeTimeout=30 196 | 197 | # Version number 198 | versionNumber='1.4.0' 199 | ################################################################################ 200 | 201 | # _______ _ _______ __________________ _______ _ _______ 202 | # ( ____ \|\ /|( ( /|( ____ \\__ __/\__ __/( ___ )( ( /|( ____ \ 203 | # | ( \/| ) ( || \ ( || ( \/ ) ( ) ( | ( ) || \ ( || ( \/ 204 | # | (__ | | | || \ | || | | | | | | | | || \ | || (_____ 205 | # | __) | | | || (\ \) || | | | | | | | | || (\ \) |(_____ ) 206 | # | ( | | | || | \ || | | | | | | | | || | \ | ) | 207 | # | ) | (___) || ) \ || (____/\ | | ___) (___| (___) || ) \ |/\____) | 208 | # |/ (_______)|/ )_)(_______/ )_( \_______/(_______)|/ )_)\_______) 209 | 210 | ############################### Before Header ################################## 211 | # Used to print before header data. 212 | # @CalledBy getReferer 213 | ################################################################################ 214 | beforeHeader(){ 215 | # We get the file we're gonna print into 216 | local file="${1}" 217 | 218 | if [[ ! -f "${file}" ]] 219 | then 220 | printf "# File generated with %s\n" "${linkScript}" > ${file} 221 | printf "# Date of generation: %s\n" "${currentDate}" >> ${file} 222 | printf "\n" >> ${file} 223 | fi 224 | } 225 | 226 | ############################### Print Header ################################### 227 | # Used to print header if quiet=false and in files 228 | # @CalledBy getReferer 229 | ################################################################################ 230 | printHeader() 231 | { 232 | # type 233 | local type=${1} 234 | 235 | if [[ ${type} == 'Invalid' ]] 236 | then 237 | # Generation of header for invalid.txt 238 | printf "\n%-100s %-17s %-10s %-8s\n" "Domain" "Status" "Source" "Analyse Date" 239 | echo "---------------------------------------------------------------------------------------------------- ----------- ---------- ----------------------------" 240 | elif [[ ${type} == 'Error' ]] 241 | then 242 | # Generation of header for error.txt 243 | printf "\n%-100s %-35s %-17s %10s %-20s\n" "Domain" "WHOIS Server" "Status" "Source" "Analyse Date" 244 | echo "---------------------------------------------------------------------------------------------------- ----------------------------------- ----------- ---------- ----------------------------" 245 | elif [[ ${type} == 'Valid' ]] 246 | then 247 | # Generation of header for valid.txt 248 | printf "\n%-100s %-17s %-17s %-10s %-20s\n" "Domain" "Status" "Expiration Date" "Source" "Analyse Date" 249 | echo "---------------------------------------------------------------------------------------------------- ----------- ----------------- ---------- -------------------------------" 250 | elif [[ ${type} == 'Generic' ]] 251 | then 252 | # Generation of header 253 | printf "\n%-100s %-11s %-17s %-10s %-20s\n" "Domain" "Status" "Expiration Date" "Source" "Analyse Date" 254 | echo "---------------------------------------------------------------------------------------------------- ----------- ----------------- ---------- -------------------------------" 255 | elif [[ ${type} == 'Less' ]] 256 | then 257 | # Generation of header 258 | printf "\n%-100s %-11s %-10s\n" "Domain" "Status" "Source" 259 | echo "---------------------------------------------------------------------------------------------------- ----------- ----------" 260 | elif [[ ${type} == 'Percentage' ]] 261 | then 262 | # Generation of header 263 | printf "\n%-11s %-12s %-12s\n" "Status" "Percentage" "Numbers" 264 | echo "----------- ------------ -------------" 265 | fi 266 | } 267 | 268 | ################################# Prints ####################################### 269 | # Come with printHeader(). In charge to print data 270 | # 271 | # @CalledBy getReferer 272 | ################################################################################ 273 | prints() 274 | { 275 | # type 276 | local type=${1} 277 | 278 | local dateAn=$(date) 279 | 280 | if [[ ${type} == 'Invalid' ]] 281 | then 282 | # Print data for invalid.txt 283 | printf "%-100s %-17s %-8s %-8s\n" "${2}" "${invalidStatus}" "${3}" "${dateAn}" 284 | elif [[ ${type} == 'Error' ]] 285 | then 286 | # Print data for error.txt 287 | printf "%-100s %-35s %-17s %8s %-20s\n" "${2}" "${3}" "${errorStatus}" "${4}" "${dateAn}" 288 | elif [[ ${type} == 'Valid' ]] 289 | then 290 | # Print data for valid.txt 291 | printf "%-100s %-17s %-17s %-8s %-20s\n" "${2}" "${validStatus}" "${3}" "${4}" "${dateAn}" 292 | elif [[ ${type} == 'Generic' ]] 293 | then 294 | # Print data 295 | printf "%-100s %-11s %-17s %-10s %-20s\n" "${2}" "${3}" "${4}" "${5}" "${dateAn}" 296 | elif [[ ${type} == 'FullHosts' ]] 297 | then 298 | # Print host file 299 | printf "%s %s\n" "${customIP}" "${2}" 300 | elif [[ ${type} == 'Less' ]] 301 | then 302 | # Print data 303 | printf "%-100s %-11s %-10s\n" "${2}" "${3}" "${4}" 304 | elif [[ ${type} == 'Percentage' ]] 305 | then 306 | # We calcul the results 307 | percentage 'result' 'act' 308 | percentage 'result' 'ina' 309 | percentage 'result' 'inv' 310 | 311 | # We print data 312 | printf "%-11s %-12s %-12s\n" "ACTIVE" "${percentageOfActive}%" "${numberOfActive}" 313 | printf "%-11s %-12s %-12s\n" "INACTIVE" "${percentageOfInactive}%" "${numberOfInactive}" 314 | printf "%-11s %-12s %-12s\n" "INVALID" "${percentageOfInvalid}%" "${numberOfInvalid}" 315 | fi 316 | } 317 | 318 | 319 | ################################### Timeout #################################### 320 | # In charge to initiate a timeout for commands 321 | # 322 | # @CalledBy timeout, getExpirationDate 323 | ################################################################################ 324 | timeout (){ 325 | # type 326 | time=${1} 327 | 328 | # Create the temporary file 329 | touch ${whoIs} 330 | 331 | # start the command in a subshell in order to avoid problem with pipes 332 | command="/bin/bash -c \"${2}\"" 333 | 334 | expect -c "set echo \"-noecho\"; set timeout ${time}; spawn -noecho ${command}; expect timeout { exit 1 } eof { exit 0 }" 335 | } 336 | 337 | ############################# Generate Hosts File ############################## 338 | # In charge to print data into hosts file 339 | # 340 | # @CalledBy generateInvalidFile,generateErrorFile,generateValidFile 341 | ################################################################################ 342 | generateHostsFile() 343 | { 344 | # type 345 | local type=${1} 346 | 347 | if [[ ${generateHosts} == true ]] 348 | then 349 | if [[ ${type} == 'inactive' ]] 350 | then 351 | # We print / create the inactive file 352 | beforeHeader ${outputInactiveHost} 353 | prints 'FullHosts' "${domain}" >> ${outputInactiveHost} 354 | elif [[ ${type} == 'active' ]] 355 | then 356 | # We print / create active file 357 | beforeHeader ${outputActiveHost} 358 | prints 'FullHosts' "${domain}" >> ${outputActiveHost} 359 | elif [[ ${type} == 'invalid' ]] 360 | then 361 | # We print / create invalid file 362 | ((numberOfInvalid=${numberOfInvalid}+1)) 363 | beforeHeader ${outputInvalidHost} 364 | prints 'FullHosts' "${domain}" >> ${outputInvalidHost} 365 | fi 366 | fi 367 | } 368 | 369 | ########################### Generate Unified File ############################## 370 | # In charge to print data into result.txt 371 | # 372 | # @CalledBy generateInvalidFile,generateErrorFile,generateValidFile 373 | ################################################################################ 374 | generateUnifiedFile() 375 | { 376 | # type 377 | local type=${1} 378 | # status 379 | local status=${2} 380 | # expdate 381 | local expdate=${3} 382 | 383 | if [[ ${outputUnified} == true ]] 384 | then 385 | if [[ -f ${outputUnifiedResult} ]] 386 | then 387 | if [[ ${outputLess} == true ]] 388 | then 389 | # We save the domain and his data to the unified file 390 | prints "Less" "${domain}" "${status}" "${type}" >> ${outputUnifiedResult} 391 | else 392 | # We save the domain and his data to the unified file 393 | prints "Generic" "${domain}" "${status}" "${expdate}" "${type}" >> ${outputUnifiedResult} 394 | fi 395 | else 396 | if [[ ${outputLess} == true ]] 397 | then 398 | # We create header into and in between, create the file 399 | beforeHeader ${outputUnifiedResult} 400 | printHeader "Less" >> ${outputUnifiedResult} 401 | # We save the domain and his data to the unified file 402 | prints "Less" "${domain}" "${status}" "${type}" >> ${outputUnifiedResult} 403 | else 404 | # We create header into and in between, create the file 405 | beforeHeader ${outputUnifiedResult} 406 | printHeader "Generic" >> ${outputUnifiedResult} 407 | # We save the domain and his data to the unified file 408 | prints "Generic" "${domain}" "${status}" "${expdate}" "${type}" >> ${outputUnifiedResult} 409 | fi 410 | fi 411 | fi 412 | } 413 | 414 | ############################### Generate Invalid File ########################## 415 | # In charge to print data into invalid.txt 416 | # 417 | # @CalledBy errorHandle 418 | ################################################################################ 419 | generateInvalidFile() 420 | { 421 | # type 422 | local type=${1} 423 | 424 | # We generate the host file 425 | generateHostsFile 'invalid' 426 | percentage 'counter' 'inv' 427 | 428 | if [[ ${noFiles} == false && ${splitFiles} == true ]] 429 | then 430 | if [[ -f ${outputInvalidResult} ]] 431 | then 432 | if [[ ${outputLess} == true ]] 433 | then 434 | # We save the domain and his data 435 | prints "Less" "${domain}" "${invalidStatus}" "${type}" >> ${outputInvalidResult} 436 | else 437 | # We save the domain and his data 438 | prints "Invalid" "${domain}" "${type}" >> ${outputInvalidResult} 439 | fi 440 | else 441 | if [[ ${outputLess} == true ]] 442 | then 443 | # We create header into and in between, create the file 444 | beforeHeader ${outputInvalidResult} 445 | printHeader "Less" >> ${outputInvalidResult} 446 | # We save the domain and his data 447 | prints "${domain}" "${invalidStatus}" "${type}" >> ${outputInvalidResult} 448 | else 449 | # We create header into and in between, create the file 450 | beforeHeader ${outputInvalidResult} 451 | printHeader 'Invalid' >> ${outputInvalidResult} 452 | # We save the domain and his data 453 | prints "Invalid" "${domain}" "${type}" >> ${outputInvalidResult} 454 | fi 455 | fi 456 | elif [[ ${noFiles} == false ]] 457 | then 458 | # We generate the unified file 459 | generateUnifiedFile "${type}" "${invalidStatus}" "Unknown" 460 | fi 461 | } 462 | 463 | ################################# Generate Error File ########################## 464 | # In charge to print data into error.txt 465 | # 466 | # @CalledBy errorHandle 467 | ################################################################################ 468 | generateErrorFile() 469 | { 470 | # type 471 | local type=${1} 472 | 473 | # We generate the host file 474 | generateHostsFile 'inactive' 475 | 476 | percentage 'counter' 'ina' 477 | 478 | if [[ ${noFiles} == false && ${splitFiles} == true ]] 479 | then 480 | if [[ ${referer} == '' ]] 481 | then 482 | # We assign "Not Found" to prevent empty column in files 483 | referer='Not Found' 484 | fi 485 | 486 | if [[ -f ${outputErrorResult} ]] 487 | then 488 | # We save the domain and his data 489 | prints "Error" "${domain}" "${referer}" "${type}" >> ${outputErrorResult} 490 | else 491 | # We create header into and in between, create the file 492 | beforeHeader ${outputErrorResult} 493 | printHeader "Error" >> ${outputErrorResult} 494 | # We save the domain and his data 495 | prints "Error" "${domain}" "${referer}" "${type}" >> ${outputErrorResult} 496 | fi 497 | elif [[ ${noFiles} == false ]] 498 | then 499 | # We generate the unified files 500 | generateUnifiedFile "${type}" "${errorStatus}" "Unknown" 501 | fi 502 | } 503 | 504 | ############################ Generate Valid File ############################### 505 | # In charge to print data into error.txt 506 | # 507 | # @CalledBy getReferer, errorHandle 508 | ################################################################################ 509 | generateValidFile(){ 510 | # We get the expiration date 511 | # exp 512 | local exp=${1} 513 | # type 514 | local type=${2} 515 | 516 | # If empty, we change the data of ${exp} 517 | if [[ ${exp} == '' ]] 518 | then 519 | exp='Unknown' 520 | fi 521 | 522 | # If ${quiet} != false, we don't print anything 523 | if [[ ${quiet} == false ]] 524 | then 525 | if [[ ${outputLess} == true ]] 526 | then 527 | # We save domain and its data 528 | prints "Less" "${domain}" "${validStatus}" "${type}" 529 | else 530 | # We print domain and its data 531 | prints "Generic" "${domain}" "${validStatus}" "${exp}" "${type}" 532 | fi 533 | fi 534 | 535 | # we generate the host file 536 | generateHostsFile 'active' 537 | 538 | percentage 'counter' 'act' 539 | 540 | # We execute this only if ${noFiles} == false 541 | if [[ ${noFiles} == false && ${splitFiles} == true ]] 542 | then 543 | if [[ -f ${outputValidResult} ]] 544 | then 545 | if [[ ${outputLess} == true ]] 546 | then 547 | # We save domain and its data 548 | prints "Less" "${domain}" "${validStatus}" "${type}" >> ${outputValidResult} 549 | else 550 | # We save domain and its data 551 | prints "Valid" "${domain}" "${exp}" "${type}" >> ${outputValidResult} 552 | fi 553 | else 554 | if [[ ${outputLess} == true ]] 555 | then 556 | # We create a file and add header 557 | beforeHeader ${outputValidResult} 558 | printHeader "Less" >> ${outputValidResult} 559 | # We add domain and its data to file 560 | prints "Less" "${domain}" "${validStatus}" "${type}" >> ${outputValidResult} 561 | else 562 | # We create a file and add header 563 | beforeHeader ${outputValidResult} 564 | printHeader 'Valid' >> ${outputValidResult} 565 | 566 | # We add domain and its data to file 567 | prints "Valid" "${domain}" "${exp}" "${type}" >> ${outputValidResult} 568 | fi 569 | fi 570 | elif [[ ${noFiles} == false ]] 571 | then 572 | # We generate the unified file 573 | generateUnifiedFile "${type}" "${validStatus}" "${exp}" 574 | fi 575 | } 576 | 577 | ############################## Error Handle #################################### 578 | # Used to return issue status and issue url 579 | # 580 | # @CalledBy getReferer 581 | ################################################################################ 582 | errorHandle() 583 | { 584 | # We get/save the type 585 | # type 586 | local type=${1} 587 | # We create a variable to catch the case that domain don't pass lslookup 588 | local issueStatus='' 589 | 590 | # We set the current type 591 | sourceType="NSLOOKUP" 592 | 593 | # We save output of nslookup 594 | local lookup=$(nslookup ${domain}) 595 | regexNxDomain='NXDOMAIN' 596 | 597 | if [[ ${lookup} =~ ${regexNxDomain} ]] 598 | then 599 | # If domain is down 600 | issueStatus='Unknown' 601 | elif [[ ${issueStatus} == '' ]] 602 | then 603 | # If domain is up, We generate the valid/unified file 604 | generateValidFile "Unknown" "${sourceType}" 605 | return 1 606 | fi 607 | 608 | if [[ ${type} == 'Invalid' && ${issueStatus} == 'Unknown' ]] 609 | then 610 | # We assign the status 611 | local status="${invalidStatus}" 612 | 613 | # We generate the invalid/unified file 614 | generateInvalidFile "${sourceType}" 615 | elif [[ ${issueStatus} == 'Unknown' && ${type} == 'Error' || ${type} != 'Invalid' || ${type} != 'Valid' ]] 616 | then 617 | # We assign the status 618 | local status="${errorStatus}" 619 | 620 | # We generate the error/unified file 621 | generateErrorFile "${sourceType}" 622 | fi 623 | 624 | # If quiet != false, we don't print anything 625 | if [[ ${quiet} == false ]] 626 | then 627 | if [[ ${outputLess} == true ]] 628 | then 629 | # We print data to screen 630 | prints "Less" "${domain}" "${status}" "${sourceType}" 631 | else 632 | # We print data to screen 633 | prints "Generic" "${domain}" "${status}" "Unknown" "${sourceType}" 634 | fi 635 | fi 636 | } 637 | 638 | ############################## No Referers Log ################################# 639 | # Used to generate the logs 640 | # 641 | # @CalledBy getReferer 642 | ################################################################################ 643 | noRefererLog(){ 644 | if [[ ${outputLogs} == true ]] 645 | then 646 | # We save the output of the captured date into log directory 647 | printf "=%.0s" {1..100} >> ${noRefererLogOutput}.${domainExtension} 648 | printf "\nNo referer found for: %s domains\n" "${domainExtension}" >> ${noRefererLogOutput}.${domainExtension} 649 | printf "Tested domain: %s\n" "${initialDomain}" >> ${noRefererLogOutput}.${domainExtension} 650 | printf "=%.0s" {1..100} >> ${noRefererLogOutput}.${domainExtension} 651 | printf "\n" >> ${noRefererLogOutput}.${domainExtension} 652 | fi 653 | } 654 | 655 | ############################### Get Referer #################################### 656 | # Used to generate the report issue url 657 | # 658 | # @CalledBy getExpirationDate 659 | ################################################################################ 660 | getReferer(){ 661 | # initialDomain 662 | initialDomain=$(echo ${1} |awk '{print tolower($0)}') 663 | 664 | # We get the extension of the given domain 665 | domainExtension=${initialDomain##*.} 666 | # We get the list of allowed extensions 667 | validExtension=$(cat ${ianaDB}) 668 | 669 | # We check if the given domain extension is in our database file 670 | if [[ ${validExtension} =~ ${domainExtension} ]] 671 | then 672 | # We initiate this variable in order to know if ${domainExtension} pass 673 | # The cases 674 | notSupported=true 675 | 676 | # Special cases domains which don't have their whois server 677 | # registered to IANA. 678 | # cf. https://github.com/funilrys/funceble/issues?q=is%3Aissue+Not+Found+is%3Aclosed 679 | case ${domainExtension} in 680 | ga) 681 | # We can now use the domain 682 | domain=${initialDomain} 683 | # We assign the domain WHOIS referer server 684 | referer="whois.my.ga" 685 | # The Following is used to stop the execution of getExpirationDate 686 | # in case the domain is not valid. 687 | notSupported=false 688 | ;; 689 | za) 690 | # We can now use the domain 691 | domain=${initialDomain} 692 | # We assign the domain WHOIS referer server 693 | referer="whois.registry.net.za" 694 | # The Following is used to stop the execution of getExpirationDate 695 | # in case the domain is not valid. 696 | notSupported=false 697 | ;; 698 | bz) 699 | # We can now use the domain 700 | domain=${initialDomain} 701 | # We assign the domain WHOIS referer server 702 | referer="whois.afilias-grs.info" 703 | # The Following is used to stop the execution of getExpirationDate 704 | # in case the domain is not valid. 705 | notSupported=false 706 | ;; 707 | esac 708 | 709 | if [[ ${notSupported} == true ]] 710 | then 711 | # We get the host to call. 712 | # If extension have a host assigned, it's written if format 713 | # refer: whois.hello.world for example 714 | referer=$(whois -h "${whoisServer}" "${initialDomain}" | awk '/refer/{print $NF}') 715 | 716 | # regex to pass to have a valid referer 717 | regexWhois='(.*)whois(.*)' 718 | 719 | # We check if the format is valid 720 | if [[ ${referer} =~ ${regexWhois} ]] 721 | then 722 | # We can now use the domain 723 | domain=${initialDomain} 724 | 725 | # The Following is used to stop the execution of getExpirationDate 726 | # in case the domain is not valid. 727 | notSupported=false 728 | else 729 | # We empty the referer variable 730 | referer='' 731 | 732 | # We log the issue 733 | noRefererLog 734 | 735 | # We handle error & check if server is up 736 | errorHandle 'Error' 737 | fi 738 | fi 739 | else 740 | # We handle error & check if server is up 741 | errorHandle 'Invalid' 742 | fi 743 | } 744 | 745 | ################################## Whois Log ################################### 746 | # Used to generate the logs 747 | # 748 | # @CalledBy getExpirationDate 749 | ################################################################################ 750 | whoisLog(){ 751 | if [[ ${outputLogs} == true ]] 752 | then 753 | 754 | # We save the output of whois into log directory 755 | printf "=%.0s" {1..100} >> ${whoisLogOutput}${referer} 756 | printf "\n" >> ${whoisLogOutput}${referer} 757 | cat ${whoIs} >> ${whoisLogOutput}${referer} 758 | printf "\n" >> ${whoisLogOutput}${referer} 759 | printf "=%.0s" {1..100} >> ${whoisLogOutput}${referer} 760 | printf "\n" >> ${whoisLogOutput}${referer} 761 | fi 762 | } 763 | 764 | ############################## Date Format Log ################################# 765 | # Used to generate the logs 766 | # 767 | # @CalledBy formatDate 768 | ################################################################################ 769 | dateFormatlog(){ 770 | if [[ ${outputLogs} == true ]] 771 | then 772 | # We save the output of the captured date into log directory 773 | printf "=%.0s" {1..100} >> ${dateLogOutput}${referer} 774 | printf "\nExpiration Date:%s\n" "${expirationDate}" >> ${dateLogOutput}${referer} 775 | printf "=%.0s" {1..100} >> ${dateLogOutput}${referer} 776 | printf "\n" >> ${dateLogOutput}${referer} 777 | fi 778 | } 779 | 780 | ####################### Get (Domain) Expiration Date ########################### 781 | # Used to get the expiration date of a given domain. 782 | # 783 | # @CalledBy None 784 | ################################################################################ 785 | getExpirationDate(){ 786 | # domain 787 | # Domain given by user 788 | domain=${1} 789 | 790 | # We get the whois server referenced for the given domain 791 | getReferer ${domain} 792 | 793 | # Ensure that it's supported and not empty 794 | if [[ ${notSupported} == false && ${domain} != "" && ${referer} != "" ]] 795 | then 796 | # We call the whois server and save the result into ${whoIs} 797 | # cf. Default Values Section 798 | timeout ${secondsBeforeTimeout} "whois -h ${referer} ${domain} > ${whoIs}" 799 | 800 | # We get the content of the previously saved file 801 | local content=$(cat ${whoIs}) 802 | 803 | # Here's a list of words the ${content} have to match to get the 804 | # expiration date from the whois record of domain 805 | local toMatch=('expire:' 'expire on:' 'Expiry Date:' 'free-date' 'expires:' 'Expiration date:' 'Expiry date:' 'Expire Date:' 'renewal date:' 'Expires:' 'validity:' 'Expiration Date :' 'Expiry :' 'expires at:' 'domain_datebilleduntil:' 'Data de expiração \/ Expiration Date \(dd\/mm\/yyyy\):' 'Fecha de expiración \(Expiration date\):' '\[Expires on\]' 'Record expires on' 'status: OK-UNTIL' 'renewal:' 'expires............:' 'expire-date:' 'Exp date:' 'Valid-date' 'Expires On:' 'Fecha de vencimiento:' 'Expiration:.........' 'Fecha de Vencimiento:' 'Registry Expiry Date:' 'Expires on..............:' 'Expiration Time:' 'Expiration Date:' 'Expired:' "Date d'expiration:") 806 | 807 | for i in ${!toMatch[*]} 808 | do 809 | if [[ ${content} =~ ${toMatch[${i}]} ]] 810 | then 811 | # We get the expiration date 812 | if [[ ${toMatch[${i}]} == '\[Expires on\]' ]] 813 | then 814 | expirationDate=$(cat ${whoIs} | awk "/${toMatch[${i}]}/{print $NC}" | sed "s/\] /]:/") 815 | elif [[ ${toMatch[${i}]} == 'Record expires on' ]] 816 | then 817 | expirationDate=$(cat ${whoIs} | awk "/${toMatch[${i}]}/{print $NC}" | sed "s/on/on:/" | sed "s/\s(YYYY-MM-DD)//") 818 | else 819 | expirationDate=$(cat ${whoIs} | awk "/${toMatch[${i}]}/{print $NC}") 820 | fi 821 | 822 | expirationDate=${expirationDate#*:} 823 | expirationDate=$(echo -e "${expirationDate}" | sed -e 's/^[[:space:]]*//') 824 | 825 | # Regex to pass in order to be reconized as a date 826 | regexNumber='[0-9]' 827 | if [[ ${expirationDate} =~ ${regexNumber} ]] 828 | then 829 | # If it contain numbers, we format it 830 | formatDate 831 | 832 | # We set the current type 833 | sourceType="WHOIS" 834 | 835 | # We generate valid/unified file 836 | generateValidFile "${expirationDate}" "${sourceType}" 837 | return 1 838 | elif [[ ${expirationDate} == '' && ${debugUnknown} == true ]] 839 | then 840 | # In case expiration Date is empty we save the record so we 841 | # can debug it. 842 | # In case this happen please report issue to 843 | # https://github.com/funilrys/funceble/issues/new 844 | # So it can be fixed for everyone who use this script 845 | # 846 | # You can find the logs under output/logs/whois/ 847 | # or with the command `ls output/logs/whois/*` 848 | whoisLog 849 | fi 850 | elif [[ ${i} == $(( ${#toMatch[@]} - 1)) ]] 851 | then 852 | if [[ ${debugUnknown} == true ]] 853 | then 854 | # generate whois log file 855 | whoisLog 856 | fi 857 | # We handle error & check if server is up 858 | errorHandle 'Error' 859 | fi 860 | done 861 | fi 862 | } 863 | 864 | ################################ Date to Lower ################################# 865 | # Used to convert date to lower case 866 | # 867 | # @CalledBy formatDate 868 | ################################################################################ 869 | dateToLower(){ 870 | expirationDate=$(echo "${expirationDate}" | awk '{print tolower($0)}') 871 | } 872 | 873 | ############################# Get Month In English ############################# 874 | # Used to convert month from numeric to alphabetic 875 | # 876 | # @CalledBy formatDate 877 | ################################################################################ 878 | convertOrShortenMonth(){ 879 | local numericMonth=${1} 880 | 881 | case ${numericMonth} in 882 | 1|01|January) 883 | month='jan' 884 | ;; 885 | 2|02|February) 886 | month='feb' 887 | ;; 888 | 3|03|March) 889 | month='mar' 890 | ;; 891 | 4|04|April) 892 | month='apr' 893 | ;; 894 | 5|05|May) 895 | month='may' 896 | ;; 897 | 6|06|June) 898 | month='jun' 899 | ;; 900 | 7|07|July) 901 | month='jul' 902 | ;; 903 | 8|08|August) 904 | month='aug' 905 | ;; 906 | 9|09|September) 907 | month='sep' 908 | ;; 909 | 10|October) 910 | month='oct' 911 | ;; 912 | 11|November) 913 | month='nov' 914 | ;; 915 | 12|December) 916 | month='dec' 917 | ;; 918 | *) 919 | month='0' 920 | ;; 921 | esac 922 | } 923 | 924 | ############################# Convert 1 to 2 Digits ########################## 925 | # Used to convert one digit to two Digits numbers 926 | # e.g -> 1 ==> 01 927 | # 928 | # @CalledBy formatDate 929 | ################################################################################ 930 | convert1To2digits(){ 931 | local number="${1}" 932 | local monthOrDay="${2}" 933 | 934 | local validNumber=('1' '2' '3' '4' '5' '6' '7' '8' '9') 935 | local null='0' 936 | 937 | for i in ${!validNumber[*]} 938 | do 939 | if [[ ${number} == ${validNumber[${i}]} ]] 940 | then 941 | case "${monthOrDay}" in 942 | month) 943 | month=${null}${number} 944 | break 945 | ;; 946 | day) 947 | day=${null}${number} 948 | break 949 | ;; 950 | esac 951 | fi 952 | done 953 | } 954 | 955 | ################################ Format Date ################################### 956 | # Used to format date. We have to work with multiple date format from WHOIS 957 | # records so this function is in charge to create an unified format. 958 | # 959 | # @CalledBy getExpirationDate 960 | ################################################################################ 961 | formatDate() 962 | { 963 | # Date in format: 02-jan-2017 964 | local regex1='[0-9]{2}-[a-z]{3}-[0-9]{4}' 965 | # Date in format: 02.01.2017 // Month: jan 966 | local regex2='[0-9]{2}\.[0-9]{2}\.[0-9]{4}$' 967 | # Date in format: 02/01/2017 // Month: jan 968 | local regex3='[0-9]{2}\/[0-9]{2}\/[0-9]{4}' 969 | # Date in format: 2017-01-02 // Month: jan 970 | local regex4='[0-9]{4}-[0-9]{2}-[0-9]{2}$' 971 | # Date in format: 2017.01.02 // Month: jan 972 | local regex5='[0-9]{4}\.[0-9]{2}\.[0-9]{2}$' 973 | # Date in format: 2017/01/02 // Month: jan 974 | local regex6='[0-9]{4}\/[0-9]{2}\/[0-9]{2}$' 975 | # Date in format: 2017.01.02 15:00:00 976 | local regex7='[0-9]{4}\.[0-9]{2}\.[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}' 977 | # Date in format: 20170102 15:00:00 // Month: jan 978 | local regex8='[0-9]{8}\s[0-9]{2}:[0-9]{2}:[0-9]{2}' 979 | # Date in format: 2017-01-02 15:00:00 // Month: jan 980 | local regex9='[0-9]{4}-[0-9]{2}-[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}' 981 | # Date in format: 02.01.2017 15:00:00 // Month: jan 982 | local regex10='[0-9]{2}\.[0-9]{2}\.[0-9]{4}\s[0-9]{2}:[0-9]{2}:[0-9]{2}' 983 | # Date in format: 02-Jan-2017 15:00:00 UTC 984 | local regex11='[0-9]{2}-[A-Z]{1}[a-z]{2}-[0-9]{4}\s[0-9]{2}:[0-9]{2}:[0-9]{2}\s[A-Z]{1}.*' 985 | # Date in format: 2017/01/02 01:00:00 (+0900) // Month: jan 986 | local regex12='[0-9]{4}\/[0-9]{2}\/[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}\s\(.*\)' 987 | # Date in format: 2017/01/02 01:00:00 // Month: jan 988 | local regex13='[0-9]{4}\/[0-9]{2}\/[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}$' 989 | # Date in format: Mon Jan 02 15:00:00 GMT 2017 990 | local regex14='[a-zA-Z]{3}\s[a-zA-Z]{3}\s[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}\s[A-Z]{3}\s[0-9]{4}' 991 | # Date in format: Mon Jan 02 2017 992 | local regex15='[a-zA-Z]{3}\s[a-zA-Z]{3}\s[0-9]{2}\s[0-9]{4}' 993 | # Date in format: 2017-01-02T15:00:00 // Month: jan 994 | local regex16='[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$' 995 | # Date in format: 2017-01-02T15:00:00Z // Month: jan 996 | local regex17='[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}[A-Z].*' 997 | # Date in format: 2017-01-02T15:00:00+0200 // Month: jan 998 | local regex18='[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}[+-][0-9]{4}' 999 | # Date in format: 2017-01-02T15:00:00+0200.622265+03:00 // Month: jan 1000 | local regex19='[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9].*[+-][0-9]{2}:[0-9]{2}' 1001 | # Date in format: 2017-01-02T15:00:00+0200.622265 // Month: jan 1002 | local regex20='[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{6}$' 1003 | # Date in format: 2017-01-02T23:59:59.0Z // Month: jan 1004 | local regex21='[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9].*[A-Z]' 1005 | # Date in format: 02-01-2017 // Month: jan 1006 | local regex22='[0-9]{2}-[0-9]{2}-[0-9]{4}' 1007 | # Date in format: 2017. 01. 02. // Month: jan 1008 | local regex23='[0-9]{4}\.\s[0-9]{2}\.\s[0-9]{2}\.' 1009 | # Date in format: 2017-01-02T00:00:00+13:00 // Month: jan 1010 | local regex24='[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}[+-][0-9]{2}:[0-9]{2}' 1011 | # Date in format: 20170102 // Month: jan 1012 | local regex25='[0-9]{8}$' 1013 | # Date in format: 02-Jan-2017 1014 | local regex26='[0-9]{2}-[A-Z]{1}[a-z]{2}-[0-9]{4}$' 1015 | # Date in format: 02.1.2017 // Month: jan 1016 | local regex27='[0-9]{2}\.[0-9]{1}\.[0-9]{4}' 1017 | # Date in format: 02 Jan 2017 1018 | local regex28='[0-9]\s[A-Z]{1}[a-z]{2}\s[0-9]{4}' 1019 | # Date in format: 02-January-2017 1020 | local regex29='[0-9]{2}-[A-Z]{1}[a-z]*-[0-9]{4}' 1021 | # Date in format: 2017-Jan-05. 1022 | local regex30='[0-9]{4}-[A-Z]{1}[a-z]{2}-[0-9]{2}\.' 1023 | # Date in format: Mon Jan 02 15:00:00 2017 1024 | local regex31='[a-zA-Z]{3}\s[a-zA-Z]{3}\s[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}\s[0-9]{4}' 1025 | 1026 | if [[ "${expirationDate}" =~ ${regex1} || "${expirationDate}" =~ ${regex26} ]] 1027 | then 1028 | # We split the date 1029 | local day=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c2) 1030 | local year=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | tail -c4) 1031 | local month=$(echo "${expirationDate}" | tr -cd '[[:alpha:]]' | head -c3) 1032 | 1033 | # We assign the expiration date 1034 | expirationDate=${day}'-'${month}'-'${year} 1035 | 1036 | # We convert it to lower case 1037 | dateToLower 1038 | elif [[ "${expirationDate}" =~ ${regex30} ]] 1039 | then 1040 | # We split the date 1041 | local day=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | tail -c2) 1042 | local year=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c4) 1043 | local month=$(echo "${expirationDate}" | tr -cd '[[:alpha:]]') 1044 | 1045 | # We assign the expiration date 1046 | expirationDate=${day}'-'${month}'-'${year} 1047 | 1048 | # We convert it to lower case 1049 | dateToLower 1050 | elif [[ "${expirationDate}" =~ ${regex29} ]] 1051 | then 1052 | # We split the date 1053 | local day=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c2) 1054 | local year=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | tail -c4) 1055 | local month=$(echo "${expirationDate}" | tr -cd '[[:alpha:]]') 1056 | 1057 | # We convert the month 1058 | convertOrShortenMonth "${month}" 1059 | 1060 | # We assign the expiration date 1061 | expirationDate=${day}'-'${month}'-'${year} 1062 | 1063 | elif [[ "${expirationDate}" =~ ${regex11} ]] 1064 | then 1065 | # We split the date 1066 | local day=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c2) 1067 | local year=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c6 | tail -c4) 1068 | local month=$(echo "${expirationDate}" | tr -cd '[[:alpha:]]' | head -c3) 1069 | 1070 | # We assign the expiration date 1071 | expirationDate=${day}'-'${month}'-'${year} 1072 | 1073 | # We convert it to lower case 1074 | dateToLower 1075 | elif [[ "${expirationDate}" =~ ${regex2} || "${expirationDate}" =~ ${regex3} || "${expirationDate}" =~ ${regex10} || "${expirationDate}" =~ ${regex22} ]] 1076 | then 1077 | # We split the date 1078 | local day=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c2) 1079 | local month=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c4 | tail -c2) 1080 | local year=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c8 | tail -c4) 1081 | 1082 | # We convert the month 1083 | convertOrShortenMonth "${month}" 1084 | 1085 | # We assign the expiration date 1086 | expirationDate=${day}'-'${month}'-'${year} 1087 | elif [[ "${expirationDate}" =~ ${regex4} || "${expirationDate}" =~ ${regex5} || "${expirationDate}" =~ ${regex6} || "${expirationDate}" =~ ${regex7} || "${expirationDate}" =~ ${regex8} || "${expirationDate}" =~ ${regex9} || "${expirationDate}" =~ ${regex12} || "${expirationDate}" =~ ${regex13} || "${expirationDate}" =~ ${regex16} || "${expirationDate}" =~ ${regex17} || "${expirationDate}" =~ ${regex18} || "${expirationDate}" =~ ${regex19} || "${expirationDate}" =~ ${regex20} || "${expirationDate}" =~ ${regex21} || "${expirationDate}" =~ ${regex23} || "${expirationDate}" =~ ${regex24} || "${expirationDate}" =~ ${regex25} ]] 1088 | then 1089 | # We split the date 1090 | local year=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c4) 1091 | local month=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c6 |tail -c2) 1092 | local day=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c8 | tail -c2) 1093 | 1094 | # We convert the month 1095 | convertOrShortenMonth "${month}" 1096 | 1097 | # We assign the expiration date 1098 | expirationDate=${day}'-'${month}'-'${year} 1099 | elif [[ "${expirationDate}" =~ ${regex14} || "${expirationDate}" =~ ${regex15} || "${expirationDate}" =~ ${regex31} ]] 1100 | then 1101 | # We split the date 1102 | local day=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c2) 1103 | local month=$(echo "${expirationDate}" | tr -cd '[[:alpha:]]' | head -c6 | tail -c3) 1104 | local year=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | tail -c4) 1105 | 1106 | # We assign the expiration date 1107 | expirationDate=${day}'-'${month}'-'${year} 1108 | 1109 | # We convert it to lower case 1110 | dateToLower 1111 | elif [[ "${expirationDate}" =~ ${regex27} ]] 1112 | then 1113 | # We split the date 1114 | local day=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c2) 1115 | local month=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c3 | tail -c1) 1116 | local year=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | tail -c4) 1117 | 1118 | # We convert the month 1119 | convert1To2digits "${month}" "month" 1120 | 1121 | # We convert the month to alpha format 1122 | convertOrShortenMonth "${month}" 1123 | 1124 | # We assign the expiration date 1125 | expirationDate=${day}'-'${month}'-'${year} 1126 | 1127 | # We convert it to lower case 1128 | dateToLower 1129 | elif [[ "${expirationDate}" =~ ${regex28} ]] 1130 | then 1131 | # We split the date 1132 | local month=$(echo "${expirationDate}" | tr -cd '[[:alpha:]]' | head -c3) 1133 | local year=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | tail -c4) 1134 | local day=$(echo "${expirationDate}" | tr -cd '[[:digit:]]' | head -c4) 1135 | 1136 | # We get the last 2 digits of the day 1137 | local dayEnd=$(echo "${day}" | tr -cd '[[:digit:]]' | tail -c2) 1138 | 1139 | # We use 20 to check if it's a 1 or 2 digts day 1140 | # Case: 1141 | # 2 Jan 2017 1142 | # Result: 2201 1143 | # 02 Jan 2017-01 1144 | # Result: 0220 1145 | # So if the last 2 digts are not 20, it's a 1 digit day 1146 | # Hope that I don't have to update this in 100 years ! :) 1147 | if [[ ${dayEnd} == '20' ]] 1148 | then 1149 | local day=$(echo "${day}" | tr -cd '[[:digit:]]' | head -c2) 1150 | else 1151 | local day=$(echo "${day}" | tr -cd '[[:digit:]]' | head -c1) 1152 | 1153 | # We convert the day 1154 | convert1To2digits "${day}" "day" 1155 | fi 1156 | 1157 | # We assign the expiration date 1158 | expirationDate=${day}'-'${month}'-'${year} 1159 | 1160 | # We convert it to lower case 1161 | dateToLower 1162 | else 1163 | # We log that we did'nt match the date 1164 | dateFormatlog 1165 | fi 1166 | } 1167 | 1168 | ########################### Start Execution Time ############################### 1169 | # Used to catch the execution time 1170 | # 1171 | # @CalledBy main 1172 | ################################################################################ 1173 | startExecutionTime() 1174 | { 1175 | if [[ ${showExecutionTime} == true ]] 1176 | then 1177 | #We log the execution 1178 | echo "Execution Time log of" $(date) >> ${executionLog} 1179 | echo "----------------------------------------------------------------" >> ${executionLog} 1180 | # We get execution start time 1181 | executionStart=$(date +%s) 1182 | # We log the start time 1183 | printf "Start: %s\n" "${executionStart}" >> ${executionLog} 1184 | fi 1185 | } 1186 | 1187 | ########################### End Execution Time ############################### 1188 | # Used to catch the execution time 1189 | # 1190 | # @CalledBy main 1191 | ################################################################################ 1192 | endExecutionTime() 1193 | { 1194 | 1195 | if [[ ${showExecutionTime} == true ]] 1196 | then 1197 | # We get execution end time 1198 | executionEnd=$(date +%s) 1199 | # We log end time 1200 | printf "End: %s\n" "${executionEnd}" >> ${executionLog} 1201 | 1202 | # We get the difference between end and start 1203 | timeDifference=$(( ${executionEnd} - ${executionStart} )) 1204 | 1205 | # We get the hours 1206 | ((hours=${timeDifference}/3600)) 1207 | # We get the minutes 1208 | ((minutes=(${timeDifference}%3600)/60)) 1209 | # We get the seconds 1210 | ((seconds=${timeDifference}%60)) 1211 | 1212 | # We display + log message 1213 | printf "\n${magenta}Execution Time:${normal}\n" && printf "Execution Time:" >> ${executionLog} 1214 | printf "%02d:%02d:%02d\n \n" ${hours} ${minutes} ${seconds} && printf "%02d:%02d:%02d\n \n" ${hours} ${minutes} ${seconds} >> ${executionLog} 1215 | fi 1216 | } 1217 | 1218 | ################################# Percentage ################################### 1219 | # Used to increment the number of tested and number of inactive/invalid 1220 | # In between it's calculate the percentage 1221 | # 1222 | # @CalledBy main 1223 | ################################################################################ 1224 | percentage() 1225 | { 1226 | # We get type of the operation to do 1227 | local type="${1}" 1228 | # And the information to calculate (ina/inv) 1229 | local status="${2}" 1230 | 1231 | if [[ ${showPercentage} == true ]] 1232 | then 1233 | # We increment the number of tested 1234 | 1235 | if [[ ${type} == 'counter' && ${status} == 'ina' ]] 1236 | then 1237 | # We increment the number of inactive 1238 | ((numberOfTested=${numberOfTested}+1)) 1239 | ((numberOfInactive=${numberOfInactive}+1)) 1240 | elif [[ ${type} == 'counter' && ${status} == 'inv' ]] 1241 | then 1242 | # We increment the number of invalid 1243 | ((numberOfTested=${numberOfTested}+1)) 1244 | ((numberOfInvalid=${numberOfInvalid}+1)) 1245 | elif [[ ${type} == 'counter' && ${status} == 'act' ]] 1246 | then 1247 | # We increment the number of active 1248 | ((numberOfTested=${numberOfTested}+1)) 1249 | ((numberOfActive=${numberOfActive}+1)) 1250 | elif [[ ${type} == 'result' && ${status} == 'ina' ]] 1251 | then 1252 | # We calculate the percentage of inactive 1253 | ((percentageOfInactive=${numberOfInactive}*100/${numberOfTested})) 1254 | elif [[ ${type} == 'result' && ${status} == 'inv' ]] 1255 | then 1256 | # We calculate the percentage of invalid 1257 | ((percentageOfInvalid=${numberOfInvalid}*100/${numberOfTested})) 1258 | elif [[ ${type} == 'result' && ${status} == 'act' ]] 1259 | then 1260 | # We calculate the percentage of active 1261 | ((percentageOfActive=${numberOfActive}*100/${numberOfTested})) 1262 | fi 1263 | 1264 | if [[ ${type} == 'results' ]] 1265 | then 1266 | # We calculate the sum of 1267 | # ${percentageOfInvalid} && ${percentageOfInactive} 1268 | ((percentageOfInvaIna=${percentageOfInvalid}+${percentageOfInactive})) 1269 | fi 1270 | fi 1271 | } 1272 | 1273 | ############################## Check Hosts File ################################ 1274 | # Used to check if hosts file already exist. The main purpose of this function 1275 | # is to avoid collisions and overwritting 1276 | # 1277 | # @CalledBy Arguments Handle Section 1278 | ################################################################################ 1279 | checkHostsFiles() 1280 | { 1281 | if [[ -f ${outputActiveHost} || -f ${outputInvalidHost} || -f ${outputInactiveHost} ]] 1282 | then 1283 | # We append the date to the default values 1284 | outputActiveHost=${outputActiveHost}${fileNameDate} 1285 | outputInvalidHost=${outputInvalidHost}${fileNameDate} 1286 | outputInactiveHost=${outputInactiveHost}${fileNameDate} 1287 | fi 1288 | } 1289 | ################################## Main ######################################## 1290 | # Main function used to call other function 1291 | # 1292 | # @CalledBy Arguments Handle Section 1293 | ################################################################################ 1294 | main() 1295 | { 1296 | startExecutionTime 1297 | # We get the domain 1298 | domain=${1} 1299 | # We get the file 1300 | file=${2} 1301 | 1302 | if [[ "${domain}" != "" ]] 1303 | then 1304 | # We only print message if ${quiet} == false 1305 | if [[ ${quiet} == false ]] 1306 | then 1307 | if [[ ${outputLess} == true ]] 1308 | then 1309 | printHeader "Less" 1310 | else 1311 | printHeader "Generic" 1312 | fi 1313 | fi 1314 | 1315 | # We execute the getExpirationDate function 1316 | getExpirationDate "${domain}" 1317 | elif [[ ${file} != "" ]] 1318 | then 1319 | if [[ -f "${file}" && -r "${file}" ]] 1320 | then 1321 | # We only print message if ${quiet} == false 1322 | if [[ ${quiet} == false ]] 1323 | then 1324 | if [[ ${outputLess} == true ]] 1325 | then 1326 | printHeader "Less" 1327 | else 1328 | printHeader "Generic" 1329 | fi 1330 | fi 1331 | 1332 | # We read the list of the file and pass the domain (1 line = 1 domain) 1333 | # to getExpirationDate 1334 | while read domain 1335 | do 1336 | # In case the file contain comment or empty line we continue to 1337 | # the next line 1338 | case "${domain}" in 1339 | ''|\#*|*localhost*|local|broadcasthost) 1340 | continue 1341 | ;; 1342 | '127.0.0.1'*|'0.0.0.0'*) 1343 | domain=$(echo "${domain}"|cut -d ' ' -f2) 1344 | ;; 1345 | esac 1346 | 1347 | # We get the expiration date and check status in between 1348 | getExpirationDate "${domain}" 1349 | done < ${file} 1350 | else 1351 | # We exit in case file don't exit or is not readable 1352 | echo "File not found or unreadable" 1353 | exit 0 1354 | fi 1355 | else 1356 | # If domain is empty & file file don't exist we print usage 1357 | usage 1358 | fi 1359 | endExecutionTime 1360 | 1361 | if [[ ${showPercentage} == true ]] 1362 | then 1363 | # We print on screen the percentage and its header 1364 | beforeHeader ${outputPercentageLog} 1365 | printHeader 'Percentage' && printHeader 'Percentage' > ${outputPercentageLog} 1366 | prints 'Percentage' && prints 'Percentage' >> ${outputPercentageLog} 1367 | fi 1368 | } 1369 | 1370 | ################################## Usage ####################################### 1371 | # Help function 1372 | # 1373 | # @CalledBy main, Arguments Handle Section 1374 | ################################################################################ 1375 | usage() 1376 | { 1377 | echo "Usage: ${0} [ -a|--all ] [ -ex|--execution ] [ --help ] [ -h ] [ -ip ] [ -q|--quiet ] [ -n|--noFiles ] [ -p|--percentage ] [ -nl|--noLogs ] [ -nu|--noUnified ] [ --split ] [ -t|--timeout ]" 1378 | echo "" 1379 | echo " {[ -d domain-name.me ]} || {[ -f listOfDomainInAFile ]}" 1380 | echo "" 1381 | echo " --all -a Output all information on screen (${red}${bold}Must be before ${cyan}-d${normal} ${red}${bold}or ${cyan}-f${normal})" 1382 | echo " --domain -d Domain to analyze" 1383 | echo " --file -f File with a list of domains" 1384 | echo " --execution -ex Show the execution time (${red}${bold}Must be before ${cyan}-d${normal} ${red}${bold}or ${cyan}-f${normal})" 1385 | echo " --help Print this screen" 1386 | echo " -ip Change the ip to print in host file (${red}${bold}Must be before ${cyan}-d${normal} ${red}${bold}or ${cyan}-f${normal})" 1387 | echo " --host -h Activate the generation of hosts file (${red}${bold}Must be before ${cyan}-d${normal} ${red}${bold}or ${cyan}-f${normal})" 1388 | echo " --quiet -q Activate quiet mode (${red}${bold}Must be before ${cyan}-d${normal} ${red}${bold}or ${cyan}-f${normal})" 1389 | echo " --percentage -p Show the percentage of the results (${red}${bold}Must be before ${cyan}-d${normal} ${red}${bold}or ${cyan}-f${normal})" 1390 | echo " --noFiles -n Deactivate the production of output files (${red}${bold}Must be before ${cyan}-d${normal} ${red}${bold}or ${cyan}-f${normal})" 1391 | echo " --noLogs -nl Deactivate the production of logs files in case we encounter some errors (${red}${bold}Must be before ${cyan}-d${normal} ${red}${bold}or ${cyan}-f${normal})" 1392 | echo " --noUnified -nu Deactivate the production of result.txt as unified result under the output directory (${red}${bold}Must be before ${cyan}-d${normal} ${red}${bold}or ${cyan}-f${normal})" 1393 | echo " --split Split output files (${red}${bold}Must be before ${cyan}-d${normal} ${red}${bold}or ${cyan}-f${normal})" 1394 | echo " --timeout -t Seconds before timeout (${red}${bold}Must be before ${cyan}-d${normal} ${red}${bold}or ${cyan}-f${normal})" 1395 | echo " --version -v Show the current version of Funceble" 1396 | echo "" 1397 | echo "Examples:" 1398 | echo "" 1399 | echo " ${0} -d helloworld.com ${bold}OR${normal} ${0} --domain=helloworld.com" 1400 | echo " Search if ${cyan}helloworld.com${normal} is ${bold}ACTIVE${normal} or ${bold}not${normal}" 1401 | echo " Print the output in screen and under the ${cyan}output${normal} directory" 1402 | echo "" 1403 | echo " ${0} -f /home/helloworld/lists/badrefers.list ${bold}OR${normal} --file=/home/helloworld/lists/badrefers.list" 1404 | echo " Search if ${cyan}all domains${normal} under the file ${cyan}/home/helloworld/lists/badrefers.list${normal} are ${bold}ACTIVE${normal} or ${bold}not${normal}" 1405 | echo " Print the output in screen and under the ${cyan}output${normal} directory" 1406 | echo "" 1407 | echo " ${0} -h -f /home/helloworld/lists/badrefers.list ${bold}OR${normal} --file=/home/helloworld/lists/badrefers.list" 1408 | echo " Same as ${bold}${0} -f${normal}" 1409 | echo " Generate the ${cyan}hosts file${normal} under the ${cyan}output${normal} directory" 1410 | echo "" 1411 | echo " ${0} -q -f /home/helloworld/lists/badrefers.list ${bold}OR${normal} --file=/home/helloworld/lists/badrefers.list" 1412 | echo " Same as ${bold}${0} -f${normal}" 1413 | echo " Instead, it does not generate output on screen" 1414 | echo "" 1415 | } 1416 | 1417 | 1418 | ############################### Arguments Handle ############################### 1419 | # We use this part to get arguments from command line. 1420 | # 1421 | # @Requiredby All 1422 | ################################################################################ 1423 | if [[ ${outputDir} =~ ${regexCurrentDir} ]] 1424 | then 1425 | # We print the following to avoid the use of this script without 1426 | # dependencies check 1427 | printf "${bold}${red}Please run the installation script first. \nYou can run it with: %s\n" "${cyan}${PWD}/tool -i${normal}" 1428 | exit 0 1429 | else 1430 | while [ "$#" -gt 0 ]; do 1431 | case "$1" in 1432 | # We catch if we have to print all infos on screen 1433 | -a|-all) 1434 | outputLess=false 1435 | shift 1 1436 | ;; 1437 | 1438 | # We catch domain 1439 | -d) 1440 | main "${2}" '' 1441 | shift 2 1442 | ;; 1443 | 1444 | # We catch if we show the execution time 1445 | -ex|--execution) 1446 | showExecutionTime=true 1447 | quiet=false 1448 | shift 1 1449 | ;; 1450 | 1451 | # We catch file path 1452 | -f) 1453 | main '' "${2}" 1454 | shift 2 1455 | ;; 1456 | 1457 | # we catch if the user want to activate the creation of hosts file 1458 | -h|--host) 1459 | generateHosts=true 1460 | checkHostsFiles 1461 | shift 1 1462 | ;; 1463 | 1464 | --help) 1465 | usage 1466 | shift 1 1467 | ;; 1468 | 1469 | # We change the IP to print into the hosts file 1470 | -ip) 1471 | customIP="${2}" 1472 | shift 2 1473 | ;; 1474 | 1475 | # We catch if we can produce file or not 1476 | -n|--noFiles) 1477 | noFiles=true 1478 | quiet=false 1479 | shift 1 1480 | ;; 1481 | 1482 | # We catch if we need to deactivate the generation of 1483 | # output/logs/* 1484 | -nl|--noLogs) 1485 | outputLogs=false 1486 | shift 1 1487 | ;; 1488 | 1489 | # We catch if we need to active or deactivate the generation of 1490 | # output/result.txt 1491 | -nu|--noUnified) 1492 | outputUnified=false 1493 | shift 1 1494 | ;; 1495 | 1496 | # We catch if have to show or hide the percentages 1497 | -p|--percentage) 1498 | showPercentage=true 1499 | shift 1 1500 | ;; 1501 | 1502 | # Activation of quiet system 1503 | -q|--quiet) 1504 | quiet=true 1505 | noFiles=false 1506 | shift 1 1507 | ;; 1508 | 1509 | # We split the result into different file 1510 | --split) 1511 | splitFiles=true 1512 | noFiles=false 1513 | shift 1 1514 | ;; 1515 | 1516 | # We set the seconds before timeout 1517 | -t|--timeout) 1518 | secondsBeforeTimeout="${2}" 1519 | shift 2 1520 | ;; 1521 | 1522 | # We catch if we have to show the version number 1523 | -v|--version) 1524 | echo "Current Version: ${versionNumber}" 1525 | exit 1 1526 | ;; 1527 | 1528 | # catch the domain after --domain= for example: --domain=helloworld.com 1529 | # Will result only helloworld.com 1530 | --domain=*) 1531 | domainToCheck=${1#*=} 1532 | main "${domainToCheck}" '' 1533 | shift 1 1534 | ;; 1535 | 1536 | # catch the domain after --domain= for example: --file=lustUsedInDev/badreferers.list 1537 | # Will get the file lustUsedInDev/badreferers.list 1538 | --file=*) 1539 | fileToCheck=${1#*=} 1540 | main "" "${fileToCheck}" 1541 | shift 1 1542 | ;; 1543 | 1544 | # Output if option is unknown 1545 | -*) 1546 | echo "Unknown option: $1" >&2 1547 | exit 1 1548 | ;; 1549 | 1550 | # Output if no option is definied 1551 | *) 1552 | usage 1553 | exit 1 1554 | ;; 1555 | esac 1556 | done 1557 | fi 1558 | -------------------------------------------------------------------------------- /iana-domains-db: -------------------------------------------------------------------------------- 1 | aaa 2 | aarp 3 | abarth 4 | abb 5 | abbott 6 | abbvie 7 | abc 8 | able 9 | abogado 10 | abudhabi 11 | ac 12 | academy 13 | accenture 14 | accountant 15 | accountants 16 | aco 17 | active 18 | actor 19 | ad 20 | adac 21 | ads 22 | adult 23 | ae 24 | aeg 25 | aero 26 | aetna 27 | af 28 | afamilycompany 29 | afl 30 | africa 31 | ag 32 | agakhan 33 | agency 34 | ai 35 | aig 36 | aigo 37 | airbus 38 | airforce 39 | airtel 40 | akdn 41 | al 42 | alfaromeo 43 | alibaba 44 | alipay 45 | allfinanz 46 | allstate 47 | ally 48 | alsace 49 | alstom 50 | am 51 | americanexpress 52 | americanfamily 53 | amex 54 | amfam 55 | amica 56 | amsterdam 57 | an 58 | analytics 59 | android 60 | anquan 61 | anz 62 | ao 63 | aol 64 | apartments 65 | app 66 | apple 67 | aq 68 | aquarelle 69 | ar 70 | arab 71 | aramco 72 | archi 73 | army 74 | arpa 75 | art 76 | arte 77 | as 78 | asda 79 | asia 80 | associates 81 | at 82 | athleta 83 | attorney 84 | au 85 | auction 86 | audi 87 | audible 88 | audio 89 | auspost 90 | author 91 | auto 92 | autos 93 | avianca 94 | aw 95 | aws 96 | ax 97 | axa 98 | az 99 | azure 100 | ba 101 | baby 102 | baidu 103 | banamex 104 | bananarepublic 105 | band 106 | bank 107 | bar 108 | barcelona 109 | barclaycard 110 | barclays 111 | barefoot 112 | bargains 113 | baseball 114 | basketball 115 | bauhaus 116 | bayern 117 | bb 118 | bbc 119 | bbt 120 | bbva 121 | bcg 122 | bcn 123 | bd 124 | be 125 | beats 126 | beauty 127 | beer 128 | bentley 129 | berlin 130 | best 131 | bestbuy 132 | bet 133 | bf 134 | bg 135 | bh 136 | bharti 137 | bi 138 | bible 139 | bid 140 | bike 141 | bing 142 | bingo 143 | bio 144 | biz 145 | bj 146 | bl 147 | black 148 | blackfriday 149 | blanco 150 | blockbuster 151 | blog 152 | bloomberg 153 | blue 154 | bm 155 | bms 156 | bmw 157 | bn 158 | bnl 159 | bnpparibas 160 | bo 161 | boats 162 | boehringer 163 | bofa 164 | bom 165 | bond 166 | boo 167 | book 168 | booking 169 | boots 170 | bosch 171 | bostik 172 | boston 173 | bot 174 | boutique 175 | box 176 | bq 177 | br 178 | bradesco 179 | bridgestone 180 | broadway 181 | broker 182 | brother 183 | brussels 184 | bs 185 | bt 186 | budapest 187 | bugatti 188 | build 189 | builders 190 | business 191 | buy 192 | buzz 193 | bv 194 | bw 195 | by 196 | bz 197 | bzh 198 | ca 199 | cab 200 | cafe 201 | cal 202 | call 203 | calvinklein 204 | cam 205 | camera 206 | camp 207 | cancerresearch 208 | canon 209 | capetown 210 | capital 211 | capitalone 212 | car 213 | caravan 214 | cards 215 | care 216 | career 217 | careers 218 | cars 219 | cartier 220 | casa 221 | case 222 | caseih 223 | cash 224 | casino 225 | cat 226 | catering 227 | catholic 228 | cba 229 | cbn 230 | cbre 231 | cbs 232 | cc 233 | cd 234 | ceb 235 | center 236 | ceo 237 | cern 238 | cf 239 | cfa 240 | cfd 241 | cg 242 | ch 243 | chanel 244 | channel 245 | chase 246 | chat 247 | cheap 248 | chintai 249 | chloe 250 | christmas 251 | chrome 252 | chrysler 253 | church 254 | ci 255 | cipriani 256 | circle 257 | cisco 258 | citadel 259 | citi 260 | citic 261 | city 262 | cityeats 263 | ck 264 | cl 265 | claims 266 | cleaning 267 | click 268 | clinic 269 | clinique 270 | clothing 271 | cloud 272 | club 273 | clubmed 274 | cm 275 | cn 276 | co 277 | coach 278 | codes 279 | coffee 280 | college 281 | cologne 282 | com 283 | comcast 284 | commbank 285 | community 286 | company 287 | compare 288 | computer 289 | comsec 290 | condos 291 | construction 292 | consulting 293 | contact 294 | contractors 295 | cooking 296 | cookingchannel 297 | cool 298 | coop 299 | corsica 300 | country 301 | coupon 302 | coupons 303 | courses 304 | cr 305 | credit 306 | creditcard 307 | creditunion 308 | cricket 309 | crown 310 | crs 311 | cruise 312 | cruises 313 | csc 314 | cu 315 | cuisinella 316 | cv 317 | cw 318 | cx 319 | cy 320 | cymru 321 | cyou 322 | cz 323 | dabur 324 | dad 325 | dance 326 | data 327 | date 328 | dating 329 | datsun 330 | day 331 | dclk 332 | dds 333 | de 334 | deal 335 | dealer 336 | deals 337 | degree 338 | delivery 339 | dell 340 | deloitte 341 | delta 342 | democrat 343 | dental 344 | dentist 345 | desi 346 | design 347 | dev 348 | dhl 349 | diamonds 350 | diet 351 | digital 352 | direct 353 | directory 354 | discount 355 | discover 356 | dish 357 | diy 358 | dj 359 | dk 360 | dm 361 | dnp 362 | do 363 | docs 364 | doctor 365 | dodge 366 | dog 367 | doha 368 | domains 369 | doosan 370 | dot 371 | download 372 | drive 373 | dtv 374 | dubai 375 | duck 376 | dunlop 377 | duns 378 | dupont 379 | durban 380 | dvag 381 | dvr 382 | dz 383 | earth 384 | eat 385 | ec 386 | eco 387 | edeka 388 | edu 389 | education 390 | ee 391 | eg 392 | eh 393 | email 394 | emerck 395 | energy 396 | engineer 397 | engineering 398 | enterprises 399 | epost 400 | epson 401 | equipment 402 | er 403 | ericsson 404 | erni 405 | es 406 | esq 407 | estate 408 | esurance 409 | et 410 | etisalat 411 | eu 412 | eurovision 413 | eus 414 | events 415 | everbank 416 | exchange 417 | expert 418 | exposed 419 | express 420 | extraspace 421 | fage 422 | fail 423 | fairwinds 424 | faith 425 | family 426 | fan 427 | fans 428 | farm 429 | farmers 430 | fashion 431 | fast 432 | fedex 433 | feedback 434 | ferrari 435 | ferrero 436 | fi 437 | fiat 438 | fidelity 439 | fido 440 | film 441 | final 442 | finance 443 | financial 444 | fire 445 | firestone 446 | firmdale 447 | fish 448 | fishing 449 | fit 450 | fitness 451 | fj 452 | fk 453 | flickr 454 | flights 455 | flir 456 | florist 457 | flowers 458 | flsmidth 459 | fly 460 | fm 461 | fo 462 | foo 463 | food 464 | foodnetwork 465 | football 466 | ford 467 | forex 468 | forsale 469 | forum 470 | foundation 471 | fox 472 | fr 473 | free 474 | fresenius 475 | frl 476 | frogans 477 | frontdoor 478 | frontier 479 | ftr 480 | fujitsu 481 | fujixerox 482 | fun 483 | fund 484 | furniture 485 | futbol 486 | fyi 487 | ga 488 | gal 489 | gallery 490 | gallo 491 | gallup 492 | game 493 | games 494 | gap 495 | garden 496 | gb 497 | gbiz 498 | gd 499 | gdn 500 | ge 501 | gea 502 | gent 503 | genting 504 | george 505 | gf 506 | gg 507 | ggee 508 | gh 509 | gi 510 | gift 511 | gifts 512 | gives 513 | giving 514 | gl 515 | glade 516 | glass 517 | gle 518 | global 519 | globo 520 | gm 521 | gmail 522 | gmbh 523 | gmo 524 | gmx 525 | gn 526 | godaddy 527 | gold 528 | goldpoint 529 | golf 530 | goo 531 | goodhands 532 | goodyear 533 | goog 534 | google 535 | gop 536 | got 537 | gov 538 | gp 539 | gq 540 | gr 541 | grainger 542 | graphics 543 | gratis 544 | green 545 | gripe 546 | grocery 547 | group 548 | gs 549 | gt 550 | gu 551 | guardian 552 | gucci 553 | guge 554 | guide 555 | guitars 556 | guru 557 | gw 558 | gy 559 | hair 560 | hamburg 561 | hangout 562 | haus 563 | hbo 564 | hdfc 565 | hdfcbank 566 | health 567 | healthcare 568 | help 569 | helsinki 570 | here 571 | hermes 572 | hgtv 573 | hiphop 574 | hisamitsu 575 | hitachi 576 | hiv 577 | hk 578 | hkt 579 | hm 580 | hn 581 | hockey 582 | holdings 583 | holiday 584 | homedepot 585 | homegoods 586 | homes 587 | homesense 588 | honda 589 | honeywell 590 | horse 591 | hospital 592 | host 593 | hosting 594 | hot 595 | hoteles 596 | hotels 597 | hotmail 598 | house 599 | how 600 | hr 601 | hsbc 602 | ht 603 | htc 604 | hu 605 | hughes 606 | hyatt 607 | hyundai 608 | ibm 609 | icbc 610 | ice 611 | icu 612 | id 613 | ie 614 | ieee 615 | ifm 616 | iinet 617 | ikano 618 | il 619 | im 620 | imamat 621 | imdb 622 | immo 623 | immobilien 624 | in 625 | industries 626 | infiniti 627 | info 628 | ing 629 | ink 630 | institute 631 | insurance 632 | insure 633 | int 634 | intel 635 | international 636 | intuit 637 | investments 638 | io 639 | ipiranga 640 | iq 641 | ir 642 | irish 643 | is 644 | iselect 645 | ismaili 646 | ist 647 | istanbul 648 | it 649 | itau 650 | itv 651 | iveco 652 | iwc 653 | jaguar 654 | java 655 | jcb 656 | jcp 657 | je 658 | jeep 659 | jetzt 660 | jewelry 661 | jio 662 | jlc 663 | jll 664 | jm 665 | jmp 666 | jnj 667 | jo 668 | jobs 669 | joburg 670 | jot 671 | joy 672 | jp 673 | jpmorgan 674 | jprs 675 | juegos 676 | juniper 677 | kaufen 678 | kddi 679 | ke 680 | kerryhotels 681 | kerrylogistics 682 | kerryproperties 683 | kfh 684 | kg 685 | kh 686 | ki 687 | kia 688 | kim 689 | kinder 690 | kindle 691 | kitchen 692 | kiwi 693 | km 694 | kn 695 | koeln 696 | komatsu 697 | kosher 698 | kp 699 | kpmg 700 | kpn 701 | kr 702 | krd 703 | kred 704 | kuokgroup 705 | kw 706 | ky 707 | kyoto 708 | kz 709 | la 710 | lacaixa 711 | ladbrokes 712 | lamborghini 713 | lamer 714 | lancaster 715 | lancia 716 | lancome 717 | land 718 | landrover 719 | lanxess 720 | lasalle 721 | lat 722 | latino 723 | latrobe 724 | law 725 | lawyer 726 | lb 727 | lc 728 | lds 729 | lease 730 | leclerc 731 | lefrak 732 | legal 733 | lego 734 | lexus 735 | lgbt 736 | li 737 | liaison 738 | lidl 739 | life 740 | lifeinsurance 741 | lifestyle 742 | lighting 743 | like 744 | lilly 745 | limited 746 | limo 747 | lincoln 748 | linde 749 | link 750 | lipsy 751 | live 752 | living 753 | lixil 754 | lk 755 | loan 756 | loans 757 | locker 758 | locus 759 | loft 760 | lol 761 | london 762 | lotte 763 | lotto 764 | love 765 | lpl 766 | lplfinancial 767 | lr 768 | ls 769 | lt 770 | ltd 771 | ltda 772 | lu 773 | lundbeck 774 | lupin 775 | luxe 776 | luxury 777 | lv 778 | ly 779 | ma 780 | macys 781 | madrid 782 | maif 783 | maison 784 | makeup 785 | man 786 | management 787 | mango 788 | map 789 | market 790 | marketing 791 | markets 792 | marriott 793 | marshalls 794 | maserati 795 | mattel 796 | mba 797 | mc 798 | mcd 799 | mcdonalds 800 | mckinsey 801 | md 802 | me 803 | med 804 | media 805 | meet 806 | melbourne 807 | meme 808 | memorial 809 | men 810 | menu 811 | meo 812 | merckmsd 813 | metlife 814 | mf 815 | mg 816 | mh 817 | miami 818 | microsoft 819 | mil 820 | mini 821 | mint 822 | mit 823 | mitsubishi 824 | mk 825 | ml 826 | mlb 827 | mls 828 | mm 829 | mma 830 | mn 831 | mo 832 | mobi 833 | mobile 834 | mobily 835 | moda 836 | moe 837 | moi 838 | mom 839 | monash 840 | money 841 | monster 842 | montblanc 843 | mopar 844 | mormon 845 | mortgage 846 | moscow 847 | moto 848 | motorcycles 849 | mov 850 | movie 851 | movistar 852 | mp 853 | mq 854 | mr 855 | ms 856 | msd 857 | mt 858 | mtn 859 | mtpc 860 | mtr 861 | mu 862 | museum 863 | mutual 864 | mutuelle 865 | mv 866 | mw 867 | mx 868 | my 869 | mz 870 | na 871 | nab 872 | nadex 873 | nagoya 874 | name 875 | nationwide 876 | natura 877 | navy 878 | nba 879 | nc 880 | ne 881 | nec 882 | net 883 | netbank 884 | netflix 885 | network 886 | neustar 887 | new 888 | newholland 889 | news 890 | next 891 | nextdirect 892 | nexus 893 | nf 894 | nfl 895 | ng 896 | ngo 897 | nhk 898 | ni 899 | nico 900 | nike 901 | nikon 902 | ninja 903 | nissan 904 | nissay 905 | nl 906 | no 907 | nokia 908 | northwesternmutual 909 | norton 910 | now 911 | nowruz 912 | nowtv 913 | np 914 | nr 915 | nra 916 | nrw 917 | ntt 918 | nu 919 | nyc 920 | nz 921 | obi 922 | observer 923 | off 924 | office 925 | okinawa 926 | olayan 927 | olayangroup 928 | oldnavy 929 | ollo 930 | om 931 | omega 932 | one 933 | ong 934 | onl 935 | online 936 | onyourside 937 | ooo 938 | open 939 | oracle 940 | orange 941 | org 942 | organic 943 | orientexpress 944 | origins 945 | osaka 946 | otsuka 947 | ott 948 | ovh 949 | pa 950 | page 951 | pamperedchef 952 | panasonic 953 | panerai 954 | paris 955 | pars 956 | partners 957 | parts 958 | party 959 | passagens 960 | pay 961 | pccw 962 | pe 963 | pet 964 | pf 965 | pfizer 966 | pg 967 | ph 968 | pharmacy 969 | phd 970 | philips 971 | phone 972 | photo 973 | photography 974 | photos 975 | physio 976 | piaget 977 | pics 978 | pictet 979 | pictures 980 | pid 981 | pin 982 | ping 983 | pink 984 | pioneer 985 | pizza 986 | pk 987 | pl 988 | place 989 | play 990 | playstation 991 | plumbing 992 | plus 993 | pm 994 | pn 995 | pnc 996 | pohl 997 | poker 998 | politie 999 | porn 1000 | post 1001 | pr 1002 | pramerica 1003 | praxi 1004 | press 1005 | prime 1006 | pro 1007 | prod 1008 | productions 1009 | prof 1010 | progressive 1011 | promo 1012 | properties 1013 | property 1014 | protection 1015 | pru 1016 | prudential 1017 | ps 1018 | pt 1019 | pub 1020 | pw 1021 | pwc 1022 | py 1023 | qa 1024 | qpon 1025 | quebec 1026 | quest 1027 | qvc 1028 | racing 1029 | radio 1030 | raid 1031 | re 1032 | read 1033 | realestate 1034 | realtor 1035 | realty 1036 | recipes 1037 | red 1038 | redstone 1039 | redumbrella 1040 | rehab 1041 | reise 1042 | reisen 1043 | reit 1044 | reliance 1045 | ren 1046 | rent 1047 | rentals 1048 | repair 1049 | report 1050 | republican 1051 | rest 1052 | restaurant 1053 | review 1054 | reviews 1055 | rexroth 1056 | rich 1057 | richardli 1058 | ricoh 1059 | rightathome 1060 | ril 1061 | rio 1062 | rip 1063 | rmit 1064 | ro 1065 | rocher 1066 | rocks 1067 | rodeo 1068 | rogers 1069 | room 1070 | rs 1071 | rsvp 1072 | ru 1073 | rugby 1074 | ruhr 1075 | run 1076 | rw 1077 | rwe 1078 | ryukyu 1079 | sa 1080 | saarland 1081 | safe 1082 | safety 1083 | sakura 1084 | sale 1085 | salon 1086 | samsclub 1087 | samsung 1088 | sandvik 1089 | sandvikcoromant 1090 | sanofi 1091 | sap 1092 | sapo 1093 | sarl 1094 | sas 1095 | save 1096 | saxo 1097 | sb 1098 | sbi 1099 | sbs 1100 | sc 1101 | sca 1102 | scb 1103 | schaeffler 1104 | schmidt 1105 | scholarships 1106 | school 1107 | schule 1108 | schwarz 1109 | science 1110 | scjohnson 1111 | scor 1112 | scot 1113 | sd 1114 | se 1115 | search 1116 | seat 1117 | secure 1118 | security 1119 | seek 1120 | select 1121 | sener 1122 | services 1123 | ses 1124 | seven 1125 | sew 1126 | sex 1127 | sexy 1128 | sfr 1129 | sg 1130 | sh 1131 | shangrila 1132 | sharp 1133 | shaw 1134 | shell 1135 | shia 1136 | shiksha 1137 | shoes 1138 | shop 1139 | shopping 1140 | shouji 1141 | show 1142 | showtime 1143 | shriram 1144 | si 1145 | silk 1146 | sina 1147 | singles 1148 | site 1149 | sj 1150 | sk 1151 | ski 1152 | skin 1153 | sky 1154 | skype 1155 | sl 1156 | sling 1157 | sm 1158 | smart 1159 | smile 1160 | sn 1161 | sncf 1162 | so 1163 | soccer 1164 | social 1165 | softbank 1166 | software 1167 | sohu 1168 | solar 1169 | solutions 1170 | song 1171 | sony 1172 | soy 1173 | space 1174 | spiegel 1175 | spot 1176 | spreadbetting 1177 | sr 1178 | srl 1179 | srt 1180 | ss 1181 | st 1182 | stada 1183 | staples 1184 | star 1185 | starhub 1186 | statebank 1187 | statefarm 1188 | statoil 1189 | stc 1190 | stcgroup 1191 | stockholm 1192 | storage 1193 | store 1194 | stream 1195 | studio 1196 | study 1197 | style 1198 | su 1199 | sucks 1200 | supplies 1201 | supply 1202 | support 1203 | surf 1204 | surgery 1205 | suzuki 1206 | sv 1207 | swatch 1208 | swiftcover 1209 | swiss 1210 | sx 1211 | sy 1212 | sydney 1213 | symantec 1214 | systems 1215 | sz 1216 | tab 1217 | taipei 1218 | talk 1219 | taobao 1220 | target 1221 | tatamotors 1222 | tatar 1223 | tattoo 1224 | tax 1225 | taxi 1226 | tc 1227 | tci 1228 | td 1229 | tdk 1230 | team 1231 | tech 1232 | technology 1233 | tel 1234 | telecity 1235 | telefonica 1236 | temasek 1237 | tennis 1238 | teva 1239 | tf 1240 | tg 1241 | th 1242 | thd 1243 | theater 1244 | theatre 1245 | tiaa 1246 | tickets 1247 | tienda 1248 | tiffany 1249 | tips 1250 | tires 1251 | tirol 1252 | tj 1253 | tjmaxx 1254 | tjx 1255 | tk 1256 | tkmaxx 1257 | tl 1258 | tm 1259 | tmall 1260 | tn 1261 | to 1262 | today 1263 | tokyo 1264 | tools 1265 | top 1266 | toray 1267 | toshiba 1268 | total 1269 | tours 1270 | town 1271 | toyota 1272 | toys 1273 | tp 1274 | tr 1275 | trade 1276 | trading 1277 | training 1278 | travel 1279 | travelchannel 1280 | travelers 1281 | travelersinsurance 1282 | trust 1283 | trv 1284 | tt 1285 | tube 1286 | tui 1287 | tunes 1288 | tushu 1289 | tv 1290 | tvs 1291 | tw 1292 | tz 1293 | ua 1294 | ubank 1295 | ubs 1296 | uconnect 1297 | ug 1298 | uk 1299 | um 1300 | unicom 1301 | university 1302 | uno 1303 | uol 1304 | ups 1305 | us 1306 | uy 1307 | uz 1308 | va 1309 | vacations 1310 | vana 1311 | vanguard 1312 | vc 1313 | ve 1314 | vegas 1315 | ventures 1316 | verisign 1317 | versicherung 1318 | vet 1319 | vg 1320 | vi 1321 | viajes 1322 | video 1323 | vig 1324 | viking 1325 | villas 1326 | vin 1327 | vip 1328 | virgin 1329 | visa 1330 | vision 1331 | vista 1332 | vistaprint 1333 | viva 1334 | vivo 1335 | vlaanderen 1336 | vn 1337 | vodka 1338 | volkswagen 1339 | volvo 1340 | vote 1341 | voting 1342 | voto 1343 | voyage 1344 | vu 1345 | vuelos 1346 | wales 1347 | walmart 1348 | walter 1349 | wang 1350 | wanggou 1351 | warman 1352 | watch 1353 | watches 1354 | weather 1355 | weatherchannel 1356 | webcam 1357 | weber 1358 | website 1359 | wed 1360 | wedding 1361 | weibo 1362 | weir 1363 | wf 1364 | whoswho 1365 | wien 1366 | wiki 1367 | williamhill 1368 | win 1369 | windows 1370 | wine 1371 | winners 1372 | wme 1373 | wolterskluwer 1374 | woodside 1375 | work 1376 | works 1377 | world 1378 | wow 1379 | ws 1380 | wtc 1381 | wtf 1382 | xbox 1383 | xerox 1384 | xfinity 1385 | xihuan 1386 | xin 1387 | xn--0zwm56d 1388 | xn--11b4c3d 1389 | xn--11b5bs3a9aj6g 1390 | xn--1ck2e1b 1391 | xn--1qqw23a 1392 | xn--2scrj9c 1393 | xn--30rr7y 1394 | xn--3bst00m 1395 | xn--3ds443g 1396 | xn--3e0b707e 1397 | xn--3hcrj9c 1398 | xn--3oq18vl8pn36a 1399 | xn--3pxu8k 1400 | xn--42c2d9a 1401 | xn--45br5cyl 1402 | xn--45brj9c 1403 | xn--45q11c 1404 | xn--4gbrim 1405 | xn--54b7fta0cc 1406 | xn--55qw42g 1407 | xn--55qx5d 1408 | xn--5su34j936bgsg 1409 | xn--5tzm5g 1410 | xn--6frz82g 1411 | xn--6qq986b3xl 1412 | xn--80adxhks 1413 | xn--80akhbyknj4f 1414 | xn--80ao21a 1415 | xn--80aqecdr1a 1416 | xn--80asehdb 1417 | xn--80aswg 1418 | xn--8y0a063a 1419 | xn--90a3ac 1420 | xn--90ae 1421 | xn--90ais 1422 | xn--9dbq2a 1423 | xn--9et52u 1424 | xn--9krt00a 1425 | xn--9t4b11yi5a 1426 | xn--b4w605ferd 1427 | xn--bck1b9a5dre4c 1428 | xn--c1avg 1429 | xn--c2br7g 1430 | xn--cck2b3b 1431 | xn--cg4bki 1432 | xn--clchc0ea0b2g2a9gcd 1433 | xn--czr694b 1434 | xn--czrs0t 1435 | xn--czru2d 1436 | xn--d1acj3b 1437 | xn--d1alf 1438 | xn--deba0ad 1439 | xn--e1a4c 1440 | xn--eckvdtc9d 1441 | xn--efvy88h 1442 | xn--estv75g 1443 | xn--fct429k 1444 | xn--fhbei 1445 | xn--fiq228c5hs 1446 | xn--fiq64b 1447 | xn--fiqs8s 1448 | xn--fiqz9s 1449 | xn--fjq720a 1450 | xn--flw351e 1451 | xn--fpcrj9c3d 1452 | xn--fzc2c9e2c 1453 | xn--fzys8d69uvgm 1454 | xn--g2xx48c 1455 | xn--g6w251d 1456 | xn--gckr3f0f 1457 | xn--gecrj9c 1458 | xn--gk3at1e 1459 | xn--h2breg3eve 1460 | xn--h2brj9c 1461 | xn--h2brj9c8c 1462 | xn--hgbk6aj7f53bba 1463 | xn--hlcj6aya9esc7a 1464 | xn--hxt814e 1465 | xn--i1b6b1a6a2e 1466 | xn--imr513n 1467 | xn--io0a7i 1468 | xn--j1aef 1469 | xn--j1amh 1470 | xn--j6w193g 1471 | xn--jlq61u9w7b 1472 | xn--jvr189m 1473 | xn--jxalpdlp 1474 | xn--kcrx77d1x4a 1475 | xn--kgbechtv 1476 | xn--kprw13d 1477 | xn--kpry57d 1478 | xn--kpu716f 1479 | xn--kput3i 1480 | xn--l1acc 1481 | xn--lgbbat1ad8j 1482 | xn--mgb9awbf 1483 | xn--mgba3a3ejt 1484 | xn--mgba3a4f16a 1485 | xn--mgba7c0bbn0a 1486 | xn--mgbaakc7dvf 1487 | xn--mgbaam7a8h 1488 | xn--mgbab2bd 1489 | xn--mgbai9azgqp6j 1490 | xn--mgbayh7gpa 1491 | xn--mgbb9fbpob 1492 | xn--mgbbh1a 1493 | xn--mgbbh1a71e 1494 | xn--mgbc0a9azcg 1495 | xn--mgbca7dzdo 1496 | xn--mgberp4a5d4ar 1497 | xn--mgbgu82a 1498 | xn--mgbi4ecexp 1499 | xn--mgbpl2fh 1500 | xn--mgbt3dhd 1501 | xn--mgbtx2b 1502 | xn--mgbx4cd0ab 1503 | xn--mix891f 1504 | xn--mk1bu44c 1505 | xn--mxtq1m 1506 | xn--ngbc5azd 1507 | xn--ngbe9e0a 1508 | xn--ngbrx 1509 | xn--node 1510 | xn--nqv7f 1511 | xn--nqv7fs00ema 1512 | xn--nyqy26a 1513 | xn--o3cw4h 1514 | xn--ogbpf8fl 1515 | xn--p1acf 1516 | xn--p1ai 1517 | xn--pbt977c 1518 | xn--pgbs0dh 1519 | xn--pssy2u 1520 | xn--q9jyb4c 1521 | xn--qcka1pmc 1522 | xn--qxam 1523 | xn--rhqv96g 1524 | xn--rovu88b 1525 | xn--rvc1e0am3e 1526 | xn--s9brj9c 1527 | xn--ses554g 1528 | xn--t60b56a 1529 | xn--tckwe 1530 | xn--tiq49xqyj 1531 | xn--unup4y 1532 | xn--vermgensberater-ctb 1533 | xn--vermgensberatung-pwb 1534 | xn--vhquv 1535 | xn--vuq861b 1536 | xn--w4r85el8fhu5dnra 1537 | xn--w4rs40l 1538 | xn--wgbh1c 1539 | xn--wgbl6a 1540 | xn--xhq521b 1541 | xn--xkc2al3hye2a 1542 | xn--xkc2dl3a5ee0h 1543 | xn--y9a3aq 1544 | xn--yfro4i67o 1545 | xn--ygbi2ammx 1546 | xn--zckzah 1547 | xn--zfr164b 1548 | xperia 1549 | xxx 1550 | xyz 1551 | yachts 1552 | yahoo 1553 | yamaxun 1554 | yandex 1555 | ye 1556 | yodobashi 1557 | yoga 1558 | yokohama 1559 | you 1560 | youtube 1561 | yt 1562 | yun 1563 | za 1564 | zappos 1565 | zara 1566 | zero 1567 | zip 1568 | zippo 1569 | zm 1570 | zone 1571 | zuerich 1572 | zw 1573 | -------------------------------------------------------------------------------- /output/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !/logs/ 4 | !/hosts/ 5 | !/splited/ 6 | -------------------------------------------------------------------------------- /output/hosts/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !/ACTIVE/ 4 | !/INACTIVE/ 5 | !/INVALID/ 6 | -------------------------------------------------------------------------------- /output/hosts/ACTIVE/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /output/hosts/INACTIVE/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /output/hosts/INVALID/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /output/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !/whois/ 4 | !/dateFormat/ 5 | !/percentage/ 6 | !/noReferer/ 7 | -------------------------------------------------------------------------------- /output/logs/dateFormat/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /output/logs/noReferer/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /output/logs/percentage/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /output/logs/whois/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /output/splited/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tool: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # _______ _ _______ _______ ______ _ _______ 4 | # ( ____ \|\ /|( ( /|( ____ \( ____ \( ___ \ ( \ ( ____ \ 5 | # | ( \/| ) ( || \ ( || ( \/| ( \/| ( ) )| ( | ( \/ 6 | # | (__ | | | || \ | || | | (__ | (__/ / | | | (__ 7 | # | __) | | | || (\ \) || | | __) | __ ( | | | __) 8 | # | ( | | | || | \ || | | ( | ( \ \ | | | ( 9 | # | ) | (___) || ) \ || (____/\| (____/\| )___) )| (____/\| (____/\ 10 | # |/ (_______)|/ )_)(_______/(_______/|/ \___/ (_______/(_______/ 11 | 12 | # Written by: @Funilrys, Nissar Chababy 13 | 14 | ###############################  Text Format ################################### 15 | # Red Color 16 | red=$(tput setaf 1) 17 | 18 | # White Color 19 | white=$(tput setaf 7) 20 | 21 | # Cyan Color 22 | cyan=$(tput setaf 6) 23 | 24 | # Magenta Color 25 | magenta=$(tput setaf 5) 26 | 27 | # Bold 28 | bold=$(tput bold) 29 | 30 | # Disable formating 31 | normal=$(tput sgr0) 32 | ################################################################################ 33 | ################################## Outputs ##################################### 34 | # We get the current dir we're working on 35 | currentDir=${PWD}'/' 36 | 37 | # Output of log 38 | logOutput='output/logs/install.log' 39 | 40 | # New output directory 41 | outputDir="outputDir='${currentDir}output/'" 42 | 43 | # Funilrys 44 | funilrys="funilrys" 45 | ################################################################################ 46 | ############################## Default Values ################################## 47 | debug=false 48 | # The file name of the script 49 | script='funceble' 50 | 51 | # Script online versionFile 52 | onlineScript="https://raw.githubusercontent.com/${funilrys}/funceble/master/funceble" 53 | 54 | # Quiet mode 55 | quiet=false 56 | 57 | # We get the content of the script 58 | scriptContent=$(cat ${currentDir}${script} 2> ${logOutput}) 59 | 60 | # Default type 61 | executionType='installation' 62 | 63 | # Default seconds before timeout 64 | secondsBeforeTimeout=30 65 | 66 | # Version number 67 | versionNumber='1.4.0' 68 | ################################################################################ 69 | # We log the date 70 | date > ${logOutput} 71 | 72 | ################################# Delete/Uninstall ############################# 73 | # This part is the brain of the uninstallation logic 74 | # 75 | # @CalledBy Arguments Handle section 76 | ################################################################################ 77 | uninstall() 78 | { 79 | # We ask for confirmation 80 | read -e -p "Do you really want to uninstall everything ? [Y/N] " uninstallConfirmation 81 | 82 | # We log and show message 83 | printf "Deletion of funceble" && printf "Deletion of funceble" >> ${logOutput} 84 | 85 | # We filter the confirmation 86 | case "${uninstallConfirmation}" in 87 | y|Y) 88 | # We delete everything 89 | cd "$(dirname $(echo ${currentDir}))" 90 | rm -fR ${currentDir} && printf " ${cyan}✔${normal}\n\n" 91 | 92 | # We thank the user for using funceble 93 | printf "${bold}${green}Thank you for having used Funceble!!${normal}\n\n" 94 | printf "${bold}${green}You're not satisfied of Funceble?\nPlease let me know there: https://git.io/v7kAE ${normal}\n\n" 95 | exit 0 96 | ;; 97 | n|N|*) 98 | # We log and show on screen that we didn't delete anything 99 | printf " ${red}✘${normal}\n" && printf " ✘\n" >> ${logOutput} 100 | printf "\n\n${bold}${green}Thank you for keeping funceble!!${normal}\n\n" 101 | exit 0 102 | ;; 103 | esac 104 | } 105 | 106 | ################################## Usage ####################################### 107 | # Help function 108 | # 109 | # @CalledBy main, Arguments Handle Section 110 | ################################################################################ 111 | usage() 112 | { 113 | echo "Usage: ${0} [ -d|--debug ] [ --help ] [ -t|--timeout ]" 114 | echo "" 115 | echo " {[ -i|--installation ]} || {[ -p|--production ]} || {[ -u|--update ]}" 116 | echo " {[ --del ]}" 117 | echo "" 118 | echo " --debug -d Activate the debug mode with the installation (${red}${bold}Must be before ${cyan}-u${normal} ${red}${bold}or ${cyan}-i${normal})" 119 | echo " --del Uninstall funceble and all its components" 120 | echo " --help Print this screen" 121 | echo " --installation -i Execute the installation script" 122 | echo " --production -p Prepare the repository for production" 123 | echo " --timeout -t Set the default timeout in seconds (${red}${bold}Must be before ${cyan}-u${normal} ${red}${bold}or ${cyan}-i${normal})" 124 | echo " --update -u Update the script" 125 | echo " --version -v Show the current version of Funceble" 126 | echo "" 127 | } 128 | 129 | ################################## Script Exist ################################ 130 | # We check if the script exist 131 | # 132 | # @CalledBy installation 133 | ################################################################################ 134 | scriptExist() 135 | { 136 | local fileToInstall="${1}" 137 | 138 | # We log && print message 139 | if [[ ${quiet} == false ]] 140 | then 141 | # We log && print message 142 | printf 'Script exist' && printf 'Script exist' >> ${logOutput} 143 | fi 144 | if [[ -f "${fileToInstall}" ]] 145 | then 146 | if [[ ${quiet} == false ]] 147 | then 148 | # We log && print message 149 | printf " ${cyan}✔${normal}\n" && printf " ✔\n" >> ${logOutput} 150 | fi 151 | else 152 | if [[ ${quiet} == false ]] 153 | then 154 | # We log && print message 155 | printf " ${red}✘${normal}\n" && printf " ✘\n" >> ${logOutput} 156 | echo "The file ${fileToInstall} is not found" 157 | fi 158 | exit 0 159 | fi 160 | } 161 | 162 | ############################### Script Readable ################################ 163 | # We check if the script is readable 164 | # 165 | # @CalledBy installation 166 | ################################################################################ 167 | scriptReadable() 168 | { 169 | local fileToInstall="${1}" 170 | if [[ ${quiet} == false ]] 171 | then 172 | # We log && print message 173 | printf "Script readable" && printf "Script readable" >> ${logOutput} 174 | fi 175 | 176 | if [[ -r "${fileToInstall}" ]] 177 | then 178 | if [[ ${quiet} == false ]] 179 | then 180 | # We log && print message 181 | printf " ${cyan}✔${normal}\n" && printf " ✔\n" >> ${logOutput} 182 | fi 183 | else 184 | if [[ ${quiet} == false ]] 185 | then 186 | # We log && print message 187 | printf " ${red}✘${normal}\n" && printf " ✘\n" >> ${logOutput} 188 | echo "Impossible to read ${fileToInstall}" >> ${logOutput} 189 | fi 190 | exit 0 191 | fi 192 | } 193 | 194 | ############################# Script Executable ################################ 195 | # We check if the script is executable 196 | # 197 | # @CalledBy installation 198 | ################################################################################ 199 | scriptExecutable() 200 | { 201 | local fileToInstall="${1}" 202 | if [[ ${quiet} == false ]] 203 | then 204 | # We log && print message 205 | printf "Script executable" && printf "Script executable" >> ${logOutput} 206 | fi 207 | 208 | if [[ -x "${fileToInstall}" ]] 209 | then 210 | if [[ ${quiet} == false ]] 211 | then 212 | # We log && print message 213 | printf " ${cyan}✔${normal}\n" && printf " ✔\n" >> ${logOutput} 214 | fi 215 | else 216 | if [[ ${quiet} == false ]] 217 | then 218 | # We log && print message 219 | printf " ${red}✘${normal}\n" && printf " ✘\n" >> ${logOutput} 220 | echo "Please make sure that ${fileToInstall} is executable. You can execute 'chmod +x ${fileToInstall}' to make it executable" >> ${logOutput} 221 | fi 222 | exit 0 223 | fi 224 | } 225 | 226 | ############################### Command Exist ################################## 227 | # Check if a command exist 228 | # 229 | # @CalledBy awkInstalled, whoisInstalled, sedInstalled, sha512sumInstalled, 230 | # curlInstalled 231 | ################################################################################ 232 | commandexist() 233 | { 234 | local commandToCheck="${1}" 235 | 236 | if hash ${commandToCheck} 2>/dev/null 237 | then 238 | if [[ ${quiet} == false ]] 239 | then 240 | # We log && print message 241 | printf " ${cyan}✔${normal}\n" && printf " ✔\n" >> ${logOutput} 242 | fi 243 | 244 | else 245 | if [[ ${quiet} == false ]] 246 | then 247 | # We log && print message 248 | printf " ${red}✘${normal}\n" && printf " ✘\n" >> ${logOutput} 249 | echo "Please make sure that ${red}${commandToCheck}${normal} is installed in your system." 250 | fi 251 | exit 0 252 | fi 253 | } 254 | 255 | ############################# awk Installed #################################### 256 | # We check if awk is installed 257 | # 258 | # @CalledBy installation 259 | ################################################################################ 260 | awkInstalled() 261 | { 262 | if [[ ${quiet} == false ]] 263 | then 264 | # We log && print message 265 | printf "\n${bold}awk${normal} installed" && printf "awk installed" >> ${logOutput} 266 | fi 267 | 268 | commandexist 'awk' 269 | } 270 | 271 | ############################## curl Installed ################################## 272 | # We check if curl is installed 273 | # 274 | # @CalledBy installation 275 | ################################################################################ 276 | curlInstalled() 277 | { 278 | if [[ ${quiet} == false ]] 279 | then 280 | # We log && print message 281 | printf "${bold}curl${normal} installed" && printf "curl installed" >> ${logOutput} 282 | fi 283 | 284 | commandexist 'curl' 285 | } 286 | 287 | ############################## expect Installed ################################## 288 | # We check if expect is installed 289 | # 290 | # @CalledBy installation 291 | ################################################################################ 292 | expectInstalled() 293 | { 294 | if [[ ${quiet} == false ]] 295 | then 296 | # We log && print message 297 | printf "${bold}expect${normal} installed" && printf "expect installed" >> ${logOutput} 298 | fi 299 | 300 | commandexist 'expect' 301 | } 302 | 303 | ############################### nslookup Installed ################################ 304 | # We check if nslookup is installed 305 | # 306 | # @CalledBy installation 307 | ################################################################################ 308 | nslookupInstalled() 309 | { 310 | if [[ ${quiet} == false ]] 311 | then 312 | # We log && print message 313 | printf "${bold}nslookup${normal} installed" && printf "nslookup installed" >> ${logOutput} 314 | fi 315 | 316 | commandexist 'nslookup' 317 | 318 | } 319 | 320 | ################################# sed Installed ################################ 321 | # We check if sed is installed 322 | # 323 | # @CalledBy installation 324 | ################################################################################ 325 | sedInstalled() 326 | { 327 | if [[ ${quiet} == false ]] 328 | then 329 | # We log && print message 330 | printf "${bold}sed${normal} installed" && printf "sed installed" >> ${logOutput} 331 | fi 332 | 333 | commandexist 'sed' 334 | } 335 | 336 | ############################## sha512sum Installed ############################# 337 | # We check if sha512sum is installed 338 | # 339 | # @CalledBy installation 340 | ################################################################################ 341 | sha512sumInstalled() 342 | { 343 | if [[ ${quiet} == false ]] 344 | then 345 | # We log && print message 346 | printf "${bold}sha512sum${normal} installed" && printf "sha512sum installed" >> ${logOutput} 347 | fi 348 | 349 | commandexist 'sha512sum' 350 | } 351 | 352 | ############################### whois Installed ################################ 353 | # We check if whois is installed 354 | # 355 | # @CalledBy installation 356 | ################################################################################ 357 | whoisInstalled() 358 | { 359 | if [[ ${quiet} == false ]] 360 | then 361 | # We log && print message 362 | printf "${bold}whois${normal} installed" && printf "whois installed" >> ${logOutput} 363 | fi 364 | 365 | commandexist 'whois' 366 | 367 | } 368 | 369 | ################################## Debug ####################################### 370 | # This part is the debug section 371 | # 372 | # @CalledBy scriptsWorkDir 373 | ################################################################################ 374 | debug() 375 | { 376 | if [[ "${executionType}" == 'installation' ]] 377 | then 378 | if [[ ${debug} == true ]] 379 | then 380 | # Option if we want to debug 381 | regexDebug='debugUnknown=false' 382 | replaceBy="debugUnknown=true" 383 | sed -i "s|${regexDebug}|${replaceBy}|g" ${fileToInstall} 384 | fi 385 | elif [[ "${executionType}" == 'production' ]] 386 | then 387 | # Option if we want to debug 388 | regexDebug='debugUnknown=[a-z]*' 389 | replaceBy="debugUnknown=false" 390 | sed -i "s|${regexDebug}|${replaceBy}|g" ${fileToInstall} 391 | fi 392 | } 393 | 394 | ################################## Text Format ################################# 395 | # Only for production. 396 | # This part is used to fix changes to text format section 397 | # 398 | # @CalledBy scriptsWorkDir 399 | ################################################################################ 400 | textFormat() 401 | { 402 | if [[ "${executionType}" == 'production' ]] 403 | then 404 | # We list the variable we have to change 405 | variableToCatch=('red=.*' 'white=.*' 'cyan=.*' 'magenta=.*' 'bold=.*' 'normal=.*') 406 | # We list the replacement we have to do 407 | changeWith=('red=$(tput setaf 1)' 'white=$(tput setaf 7)' 'cyan=$(tput setaf 6)' 'magenta=$(tput setaf 5)' 'bold=$(tput bold)' 'normal=$(tput sgr0)') 408 | 409 | for i in ${!variableToCatch[*]} 410 | do 411 | # We get the color 412 | regexColor="${variableToCatch[${i}]}" 413 | 414 | # We get the replacement 415 | replaceBy="${changeWith[${i}]}" 416 | 417 | # We apply changes 418 | sed -i "s|${regexColor}|${replaceBy}|g" ${fileToInstall} 419 | done 420 | fi 421 | } 422 | 423 | ##################################### Status ################################### 424 | # Only for production. 425 | # This part is used to fix changes to status section 426 | # 427 | # @CalledBy scriptsWorkDir 428 | ################################################################################ 429 | status() 430 | { 431 | if [[ "${executionType}" == 'production' ]] 432 | then 433 | # We list the variable we have to change 434 | variableToCatch=('validStatus=.*' 'invalidStatus=.*' 'errorStatus=.*' 'secondsBeforeTimeout=[0-9].*') 435 | # We list the replacement we have to do 436 | changeWith=('validStatus="ACTIVE"' 'invalidStatus="INVALID"' 'errorStatus="INACTIVE"' "secondsBeforeTimeout=${secondsBeforeTimeout}") 437 | 438 | for i in ${!variableToCatch[*]} 439 | do 440 | # We get the color 441 | regexStatus="${variableToCatch[${i}]}" 442 | 443 | # We get the replacement 444 | replaceBy="${changeWith[${i}]}" 445 | 446 | # We apply changes 447 | sed -i "s|${regexStatus}|${replaceBy}|g" ${fileToInstall} 448 | done 449 | fi 450 | } 451 | 452 | ################################# Update IANA ################################## 453 | # Update iana-domains-db 454 | # 455 | # @CalledBy installation 456 | ################################################################################ 457 | updateIANA() 458 | { 459 | # We set the url where we get the needed informations 460 | local ianaURL="https://www.iana.org/domains/root/db" 461 | 462 | # Temporary file 463 | local curlIANA=/var/tmp/${funilrys}-iana 464 | 465 | # We delete old temporary files 466 | rm funilrys* &> /dev/null 467 | 468 | # We get a copy of the page 469 | curl -s ${ianaURL} -o ${curlIANA} 470 | 471 | while read -r line 472 | do 473 | # We get the valid domains extensions 474 | regex="(\/domains\/root\/db\/)(.*)(\.html)" 475 | 476 | if [[ "${line}" =~ ${regex} ]] 477 | then 478 | # We put it into a temporary file 479 | echo "${BASH_REMATCH[2]}" >> ${funilrys}_iana 480 | fi 481 | done < "${curlIANA}" 482 | 483 | # We move the generated file 484 | mv ${funilrys}_iana iana-domains-db 485 | } 486 | 487 | ############################## Script Work Dir ################################# 488 | # We install the working directory into the script 489 | # 490 | # @CalledBy installation 491 | ################################################################################ 492 | 493 | scriptsWorkDir() 494 | { 495 | if [[ ${quiet} == false ]] 496 | then 497 | if [[ "${executionType}" == 'installation' ]] 498 | then 499 | # We log && print message 500 | printf "\nInstallation of working directory" && printf "Installation of working directory" >> ${logOutput} 501 | elif [[ "${executionType}" == 'production' ]] 502 | then 503 | # We log && print message 504 | printf "\nDefault timeout: ${secondsBeforeTimeout} seconds" && printf "Default timeout: ${secondsBeforeTimeout} seconds" >> ${logOutput} 505 | printf "\nInstallation of default variables for production" && printf "Installation of default working directory for production" >> ${logOutput} 506 | fi 507 | fi 508 | 509 | regex="outputDir='.*\/output\/'" 510 | if [[ ${scriptContent} =~ ${regex} ]] 511 | then 512 | # We replace with the current working 513 | # directory an we print message 514 | if [[ "${executionType}" == 'production' ]] 515 | then 516 | outputDir="outputDir='%%currentDir%%/output/'" 517 | fi 518 | sed -i "s|${regex}|${outputDir}|g" ${fileToInstall} 519 | if [[ ${quiet} == false ]] 520 | then 521 | printf " ${cyan}✔${normal}\n \n" && printf " ✔\n" >> ${logOutput} 522 | fi 523 | 524 | # We run some important scripts 525 | debug 526 | textFormat 527 | status 528 | 529 | if [[ ${quiet} == false ]] 530 | then 531 | if [[ "${executionType}" == 'installation' ]] 532 | then 533 | echo "${bold}${cyan}The installation was successfully completed!${normal}" 534 | echo "You can now use the script with '${bold}./${script} [-OPTIONS]${normal}' or learn how to use it with '${green}${bold}./${script} --help${normal}'" 535 | printf '\n' 536 | elif [[ "${executionType}" == 'production' ]] 537 | then 538 | updateIANA 539 | echo "${bold}${cyan}The production logic was successfully completed!${normal}" 540 | echo "You can now distribute this repository." 541 | printf '\n' 542 | fi 543 | fi 544 | 545 | else 546 | if [[ ${quiet} == false ]] 547 | then 548 | if [[ "${executionType}" == 'installation' ]] 549 | then 550 | # We log && print message 551 | printf " ${red}✘${normal}\n" && printf " ✘\n" >> ${logOutput} 552 | echo "Impossible to finalize installation." 553 | elif [[ "${executionType}" == 'production' ]] 554 | then 555 | printf " ${red}✘${normal}\n" && printf " ✘\n" >> ${logOutput} 556 | echo "Impossible to finalize the poduction preparation." 557 | fi 558 | fi 559 | exit 0 560 | fi 561 | } 562 | 563 | ############################### Installation ################################### 564 | # This part is the brain of the installation system 565 | # 566 | # @CalledBy Arguments Handle section, update 567 | ################################################################################ 568 | installation() 569 | { 570 | local fileToInstall="${1}" 571 | quiet=${2} 572 | 573 | # We check the script 574 | scriptExist "${fileToInstall}" 575 | scriptReadable "${fileToInstall}" 576 | scriptExecutable "${fileToInstall}" 577 | 578 | # We check dependencies 579 | awkInstalled 580 | curlInstalled 581 | expectInstalled 582 | nslookupInstalled 583 | sedInstalled 584 | sha512sumInstalled 585 | whoisInstalled 586 | 587 | # We finalize installation 588 | scriptsWorkDir 589 | } 590 | 591 | ################################ checkVersion ################################## 592 | # This part is where we check the version 593 | # 594 | # @CalledBy update 595 | ################################################################################ 596 | checkVersion() 597 | { 598 | # We get the type 599 | type="${1}" 600 | 601 | if [[ "${type}" == 'get' ]] 602 | then 603 | # We download the script 604 | curl -s ${onlineScript} -o ${funilrys} 605 | # we give execution permission 606 | chmod +x ${funilrys} 607 | 608 | # We secretly execute a silent installation in the downloaded 609 | # script 610 | installation "${funilrys}" true 611 | fi 612 | 613 | # We get the sha512sum of the downloaded script 614 | local copiedVersion=$(sha512sum ${funilrys}|cut -d ' ' -f1) 615 | # We get the sha512sum of the already exist script 616 | local currentVersion=$(sha512sum ${currentDir}${script}|cut -d ' ' -f1) 617 | 618 | # We compare the versions 619 | if [[ ${currentVersion} == ${copiedVersion} ]] 620 | then 621 | # If the same == no need to update 622 | update=false 623 | else 624 | curlInstalled 625 | # If they are not the same == we need to update 626 | update=true 627 | fi 628 | } 629 | 630 | ################################## Download Script ############################# 631 | # We download the script 632 | # 633 | # @CalledBy update 634 | ################################################################################ 635 | downloadScript() 636 | { 637 | # We log && print message 638 | printf "\nDownload of the script" && printf "Download of the script" >> ${logOutput} 639 | 640 | # We check internet connection 641 | # If no internet connections are possible, we stop this script and 642 | # return a message error 643 | wget -q --tries=10 --timeout=20 --spider http://google.com 644 | 645 | if [[ $? != 0 ]]; then 646 | # We log && print message 647 | printf " ${red}✘${normal}\n" && printf " ✘\n" >> ${logOutput} 648 | echo "Impossible to update ${currentDir}${script}. Please report issue." >> ${logOutput} 649 | exit 0 650 | else 651 | # We save the online script into the existing one 652 | curl -s ${onlineScript} -o "${currentDir}${script}" 653 | # We log && print message 654 | printf " ${cyan}✔${normal}\n\n" && printf " ✔\n" >> ${logOutput} 655 | fi 656 | } 657 | 658 | ################################## Update ###################################### 659 | # This part is the brain of update 660 | # 661 | # @CalledBy Arguments Handle section 662 | ################################################################################ 663 | update() 664 | { 665 | if [[ -d ${currentDir}.git ]] 666 | then 667 | git pull 668 | else 669 | # We get the online version and compare versions 670 | checkVersion 'get' 671 | 672 | if [[ ${update} == true ]] 673 | then 674 | # We only need to execute if the versions are not the same 675 | 676 | downloadScript 677 | 678 | # We install the new script 679 | installation ${currentDir}${script} true 680 | # We log && print message 681 | printf "Checking Version" && printf "Checking Version" >> ${logOutput} 682 | 683 | # We check the version of the newly downloaded script 684 | checkVersion 685 | 686 | if [[ ${update} == false ]] 687 | then 688 | # If we don't need to update, here's the end 689 | # We log && print message 690 | printf " ${cyan}✔${normal}\n\n" && printf " ✔\n" >> ${logOutput} 691 | echo "${bold}${cyan}The update was successfully completed!${normal}" 692 | printf '\n' 693 | 694 | # We delete the temporary file and stop the script 695 | rm -f "${funilrys}" 696 | exit 1 697 | else 698 | # We log && print message 699 | printf " ${red}✘${normal}\n" && printf " ✘\n" >> ${logOutput} 700 | echo "Impossible to update ${currentDir}${script}. Please report issue." >> ${logOutput} 701 | exit 0 702 | fi 703 | else 704 | # We log && print message 705 | printf "No need to update.\n" && printf "No need to update." >> ${logOutput} 706 | rm -f "${funilrys}" 707 | exit 1 708 | fi 709 | fi 710 | } 711 | 712 | 713 | ############################### Arguments Handle ############################### 714 | # We use this part to get arguments from command line. 715 | # 716 | # @Requiredby All 717 | ################################################################################ 718 | while [ "$#" -gt 0 ]; do 719 | case "$1" in 720 | # We catch if we have to activate debug on installation 721 | -d|--debug) 722 | debug=true 723 | shift 1 724 | ;; 725 | # We catch if we have to uninstall everything 726 | --del) 727 | uninstall 728 | shift 1 729 | ;; 730 | # We catch if we have to show usage() 731 | -h|--help) 732 | usage 733 | shift 1 734 | ;; 735 | # We catch if we have to install only the script 736 | -i|--install) 737 | installation "${currentDir}${script}" false 738 | shift 1 739 | ;; 740 | -p|--production) 741 | executionType='production' 742 | installation "${currentDir}${script}" false 743 | shift 1 744 | ;; 745 | # We catch the default timeout we have to set 746 | -t|--timeout) 747 | secondsBeforeTimeout="${2}" 748 | shift 2 749 | ;; 750 | # We catch if we have to update the script 751 | -u|--update) 752 | update 753 | shift 1 754 | ;; 755 | # We catch if we have to show the version number 756 | -v|--version) 757 | echo "Current Version: ${versionNumber}" 758 | exit 1 759 | ;; 760 | -*) 761 | echo "Unknown option: $1" >&2 762 | exit 1 763 | ;; 764 | *) 765 | usage 766 | shift 1 767 | ;; 768 | esac 769 | done 770 | --------------------------------------------------------------------------------