home *** CD-ROM | disk | FTP | other *** search
/ linuxmafia.com 2016 / linuxmafia.com.tar / linuxmafia.com / pub / linux / network / domain-check.ryan < prev    next >
Text File  |  2007-09-02  |  13KB  |  394 lines

  1. #!/bin/bash 
  2. #
  3. # Program: Domain Expiration Check <domain-check>
  4. #
  5. # Author: Matty < matty91 at gmail dot com >
  6. #
  7. # Current Version: 1.5
  8. #
  9. # Revision History:
  10. #
  11. #  Version 1.5
  12. #    Updated the license to allow redistribution and modification
  13. #
  14. #  Version 1.4
  15. #    Updated the documentation.
  16. #
  17. #  Version 1.3
  18. #    Gracefully Handle the case where the expiration data is unavailable
  19. #
  20. #  Version 1.2
  21. #    Added "-s" option to allow arbitrary registrars
  22. #
  23. #  Version 1.1
  24. #    Fixed issue with 'e' getopt string -- Pedro Alves
  25. #
  26. #  Version 1.0
  27. #    Initial Release
  28. #
  29. # Last Updated: 09-03-2007
  30. #
  31. # Purpose:
  32. #  domain-check checks to see if a domain has expired. domain-check
  33. #  can be run in interactive and batch mode, and provides faciltities 
  34. #  to alarm if a domain is about to expire.
  35. #
  36. # License:
  37. #  Copyright (C) 2007 Ryan Matteson <matty91 at gmail dot com>
  38. #  This program is free software; you can redistribute it and/or modify
  39. #  it under the terms of the GNU General Public License as published by
  40. #  the Free Software Foundation; either version 2 of the License, or
  41. #  (at your option) any later version.
  42. #
  43. #  This program is distributed in the hope that it will be useful,
  44. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  45. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  46. #  GNU General Public License for more details.
  47. #
  48. # Notes:
  49. #   Since each registrar provides expiration data in a unique format (if
  50. #   they provide it at all), domain-check is currently only able to
  51. #   processess expiration information for a subset of the available
  52. #   registrars.
  53. #
  54. # Requirements:
  55. #   Requires whois
  56. #
  57. # Installation:
  58. #   Copy the shell script to a suitable location
  59. #
  60. # Tested platforms:
  61. #  -- Solaris 9 using /bin/bash
  62. #  -- Solaris 10 using /bin/bash
  63. #  -- OS X 10.4.2 using /bin/sh
  64. #  -- OpenBSD using /bin/sh
  65. #  -- FreeBSD using /bin/sh
  66. #  -- Redhat advanced server 3.0MU3 using /bin/sh
  67. #
  68. # Usage:
  69. #  Refer to the usage() sub-routine, or invoke domain-check
  70. #  with the "-h" option.
  71. #
  72. # Example:
  73. #
  74. #  The first example will print the expiration date and registrar for prefetch.net:
  75. #
  76. #  $ domain-check.sh -d prefetch.net
  77. #
  78. #  Domain                              Registrar         Status   Expires     Days Left
  79. #  ----------------------------------- ----------------- -------- ----------- ---------
  80. #  prefetch.net                        INTERCOSMOS MEDIA Valid    13-feb-2006   64   
  81. #
  82. #  The second example prints the expiration date and registrar for the domains 
  83. #  listed in the file "domains":
  84. #
  85. #  $ domain-check.sh -f domains    
  86. #
  87. #  Domain                              Registrar         Status   Expires     Days Left
  88. #  ----------------------------------- ----------------- -------- ----------- ---------
  89. #  sun.com                             NETWORK SOLUTIONS Valid    20-mar-2010   1560 
  90. #  google.com                          EMARKMONITOR INC. Valid    14-sep-2011   2103 
  91. #  ack.com                             NETWORK SOLUTIONS Valid    09-may-2008   880  
  92. #  prefetch.net                        INTERCOSMOS MEDIA Valid    13-feb-2006   64   
  93. #  spotch.com                          GANDI             Valid    03-dec-2006   357  
  94. #
  95. #  The third example will e-mail the address admin@prefetch.net with the domains that
  96. #  will expire in 60-days or less:
  97. #
  98. #  $ domain-check -a -f domains -q -x 60 -e admin@prefetch.net  
  99. #
  100.  
  101. PATH=/bin:/usr/bin:/usr/local/bin:/usr/local/ssl/bin:/usr/sfw/bin ; export PATH
  102.  
  103. # Who to page when an expired domain is detected (cmdline: -e)
  104. ADMIN="sysadmin@mydomain.com"
  105.  
  106. # Number of days in the warning threshhold  (cmdline: -x)
  107. WARNDAYS=30
  108.  
  109. # If QUIET is set to TRUE, don't print anything on the console (cmdline: -q)
  110. QUIET="FALSE"
  111.  
  112. # Don't send emails by default (cmdline: -a)
  113. ALARM="FALSE"
  114.  
  115. # Whois server to use (cmdline: -s)
  116. WHOIS_SERVER="whois.internic.org"
  117.  
  118. # Location of system binaries
  119. AWK="/bin/awk"
  120. WHOIS="/bin/whois"
  121. DATE="/bin/date"
  122.  
  123. # Place to stash temporary files
  124. WHOIS_TMP="/var/tmp/whois.$$"
  125.  
  126. #############################################################################
  127. # Purpose: Convert a date from MONTH-DAY-YEAR to Julian format
  128. # Acknowledgements: Code was adapted from examples in the book
  129. #                   "Shell Scripting Recipes: A Problem-Solution Approach"
  130. #                   ( ISBN 1590594711 )
  131. # Arguments:
  132. #   $1 -> Month (e.g., 06)
  133. #   $2 -> Day   (e.g., 08)
  134. #   $3 -> Year  (e.g., 2006)
  135. #############################################################################
  136. date2julian() 
  137. {
  138.     if [ "${1} != "" ] && [ "${2} != ""  ] && [ "${3}" != "" ]
  139.     then
  140.          ## Since leap years add aday at the end of February, 
  141.          ## calculations are done from 1 March 0000 (a fictional year)
  142.          d2j_tmpmonth=$((12 * ${3} + ${1} - 3))
  143.         
  144.           ## If it is not yet March, the year is changed to the previous year
  145.           d2j_tmpyear=$(( ${d2j_tmpmonth} / 12))
  146.         
  147.           ## The number of days from 1 March 0000 is calculated
  148.           ## and the number of days from 1 Jan. 4713BC is added 
  149.           echo $(( (734 * ${d2j_tmpmonth} + 15) / 24 -  2 * ${d2j_tmpyear} + ${d2j_tmpyear}/4
  150.                         - ${d2j_tmpyear}/100 + ${d2j_tmpyear}/400 + $2 + 1721119 ))
  151.     else
  152.           echo 0
  153.     fi
  154. }
  155.  
  156. #############################################################################
  157. # Purpose: Convert a string month into an integer representation
  158. # Arguments:
  159. #   $1 -> Month name (e.g., Sep)
  160. #############################################################################
  161. getmonth() 
  162. {
  163.        LOWER=`tolower $1`
  164.               
  165.        case ${LOWER} in
  166.              jan) echo 1 ;;
  167.              feb) echo 2 ;;
  168.              mar) echo 3 ;;
  169.              apr) echo 4 ;;
  170.              may) echo 5 ;;
  171.              jun) echo 6 ;;
  172.              jul) echo 7 ;;
  173.              aug) echo 8 ;;
  174.              sep) echo 9 ;;
  175.              oct) echo 10 ;;
  176.              nov) echo 11 ;;
  177.              dec) echo 12 ;;
  178.                *) echo  0 ;;
  179.        esac
  180. }
  181.  
  182. #############################################################################
  183. # Purpose: Calculate the number of seconds between two dates
  184. # Arguments:
  185. #   $1 -> Date #1
  186. #   $2 -> Date #2
  187. #############################################################################
  188. date_diff() 
  189. {
  190.         if [ "${1}" != "" ] &&  [ "${2}" != "" ]
  191.         then
  192.                 echo $(expr ${2} - ${1})
  193.         else
  194.                 echo 0
  195.         fi
  196. }
  197.  
  198. ##################################################################
  199. # Purpose: Converts a string to lower case
  200. # Arguments:
  201. #   $1 -> String to convert to lower case
  202. ##################################################################
  203. tolower() 
  204. {
  205.      LOWER=`echo ${1} | tr [A-Z] [a-z]`
  206.      echo $LOWER
  207. }
  208.  
  209. ##################################################################
  210. # Purpose: Access whois data to grab the registrar and expiration date
  211. # Arguments:
  212. #   $1 -> Domain to check
  213. ##################################################################
  214. check_domain_status() 
  215. {
  216.     # Save the domain since set will trip up the ordering
  217.     DOMAIN=${1}
  218.  
  219.     # Invoke whois to find the domain registrar and expiration date
  220.     ${WHOIS} -h ${WHOIS_SERVER} "=${1}" > ${WHOIS_TMP}
  221.  
  222.     # Parse out the expiration date and registrar -- uses the last registrar it finds
  223.     REGISTRAR=`cat ${WHOIS_TMP} | ${AWK} -F: '/Registrar/ && $2 != ""  { REGISTRAR=substr($2,2,17) } END { print REGISTRAR }'`
  224.  
  225.     # If the Registrar is NULL, then we didn't get any data
  226.     if [ "${REGISTRAR}" = "" ]
  227.     then
  228.         prints "$DOMAIN" "Unknown" "Unknown" "Unknown" "Unknown"
  229.         return
  230.     fi
  231.  
  232.     # The whois Expiration data should resemble teh following: "Expiration Date: 09-may-2008"
  233.     DOMAINDATE=`cat ${WHOIS_TMP} | ${AWK} '/Expiration/ { print $NF }'`
  234.  
  235.     # Whois data should be in the following format: "13-feb-2006"
  236.     IFS="-"
  237.     set -- ${DOMAINDATE}
  238.     MONTH=$(getmonth ${2})
  239.     IFS=""
  240.  
  241.     # Convert the date to seconds, and get the diff between NOW and the expiration date
  242.     DOMAINJULIAN=$(date2julian ${MONTH} ${1#0} ${3})
  243.     DOMAINDIFF=$(date_diff ${NOWJULIAN} ${DOMAINJULIAN})
  244.  
  245.     if [ ${DOMAINDIFF} -lt 0 ]
  246.     then
  247.           if [ "${ALARM}" = "TRUE" ]
  248.           then
  249.                 echo "The domain ${DOMAIN} has expired!" \
  250.                 | ${MAIL} -s "Domain ${DOMAIN} has expired!" ${ADMIN}
  251.            fi
  252.  
  253.            prints ${DOMAIN} "Expired" "${DOMAINDATE}" "${DOMAINDIFF}" ${REGISTRAR}
  254.  
  255.     elif [ ${DOMAINDIFF} -lt ${WARNDAYS} ]
  256.     then
  257.            if [ "${ALARM}" = "TRUE" ]
  258.            then
  259.                     echo "The domain ${DOMAIN} will expire on ${DOMAINDATE}" \
  260.                     | ${MAIL} -s "Domain ${DOMAIN} will expire in ${WARNDAYS}-days or less" ${ADMIN}
  261.             fi
  262.             prints ${DOMAIN} "Expiring" "${DOMAINDATE}" "${DOMAINDIFF}" "${REGISTRAR}"
  263.      else
  264.             prints ${DOMAIN} "Valid" "${DOMAINDATE}"  "${DOMAINDIFF}" "${REGISTRAR}"
  265.      fi
  266. }
  267.  
  268. ####################################################
  269. # Purpose: Print a heading with the relevant columns
  270. # Arguments:
  271. #   None
  272. ####################################################
  273. print_heading()
  274. {
  275.         if [ "${QUIET}" != "TRUE" ]
  276.         then
  277.                 printf "\n%-35s %-17s %-8s %-11s %-5s\n" "Domain" "Registrar" "Status" "Expires" "Days Left"
  278.                 echo "----------------------------------- ----------------- -------- ----------- ---------"
  279.         fi
  280. }
  281.  
  282. #####################################################################
  283. # Purpose: Print a line with the expiraton interval
  284. # Arguments:
  285. #   $1 -> Domain
  286. #   $2 -> Status of domain (e.g., expired or valid)
  287. #   $3 -> Date when domain will expire
  288. #   $4 -> Days left until the domain will expire
  289. #   $5 -> Domain registrar
  290. #####################################################################
  291. prints()
  292. {
  293.     if [ "${QUIET}" != "TRUE" ]
  294.     then
  295.             MIN_DATE=$(echo $3 | ${AWK} '{ print $1, $2, $4 }')
  296.             printf "%-35s %-17s %-8s %-11s %-5s\n" "$1" "$5" "$2" "$MIN_DATE" "$4"
  297.     fi
  298. }
  299.  
  300. ##########################################
  301. # Purpose: Describe how the script works
  302. # Arguments:
  303. #   None
  304. ##########################################
  305. usage()
  306. {
  307.         echo "Usage: $0 [ -e email ] [ -x expir_days ] [ -q ] [ -a ] [ -h ]"
  308.         echo "          {[ -d domain_namee ]} || { -f domainfile}"
  309.         echo ""
  310.         echo "  -a               : Send a warning message through email "
  311.         echo "  -d domain        : Domain to analyze (interactive mode)"
  312.         echo "  -e email address : Email address to send expiration notices"
  313.         echo "  -f domain file   : File with a list of domains"
  314.         echo "  -h               : Print this screen"
  315.         echo "  -s whois server  : Whois sever to query for information"
  316.         echo "  -q               : Don't print anything on the console"
  317.         echo "  -x days          : Domain expiration interval (eg. if domain_date < days)"
  318.         echo ""
  319. }
  320.  
  321. ### Evaluate the options passed on the command line
  322. while getopts ae:f:hd:s:qx: option
  323. do
  324.         case "${option}"
  325.         in
  326.                 a) ALARM="TRUE";;
  327.                 e) ADMIN=${OPTARG};;
  328.                 d) DOMAIN=${OPTARG};;
  329.                 f) SERVERFILE=$OPTARG;;
  330.                 s) WHOIS_SERVER=$OPTARG;;
  331.                 q) QUIET="TRUE";;
  332.                 x) WARNDAYS=$OPTARG;;
  333.                 \?) usage
  334.                     exit 1;;
  335.         esac
  336. done
  337.  
  338. ### Check to see if the whois binary exists
  339. if [ ! -f ${WHOIS} ]
  340. then
  341.         echo "ERROR: The whois binary does not exist in ${WHOIS} ."
  342.         echo "  FIX: Please modify the \$WHOIS variable in the program header."
  343.         exit 1
  344. fi
  345.  
  346. ### Check to make sure a date utility is available
  347. if [ ! -f ${DATE} ]
  348. then
  349.         echo "ERROR: The date binary does not exist in ${DATE} ."
  350.         echo "  FIX: Please modify the \$DATE variable in the program header."
  351.         exit 1
  352. fi
  353.  
  354. ### Baseline the dates so we have something to compare to
  355. MONTH=$(${DATE} "+%m")
  356. DAY=$(${DATE} "+%d")
  357. YEAR=$(${DATE} "+%Y")
  358. NOWJULIAN=$(date2julian ${MONTH#0} ${DAY#0} ${YEAR})
  359.  
  360. ### Touch the files prior to using them
  361. touch ${WHOIS_TMP}
  362.  
  363. ### If a HOST and PORT were passed on the cmdline, use those values
  364. if [ "${DOMAIN}" != "" ]
  365. then
  366.         print_heading
  367.         check_domain_status "${DOMAIN}"
  368. ### If a file and a "-a" are passed on the command line, check all
  369. ### of the domains in the file to see if they are about to expire
  370. elif [ -f "${SERVERFILE}" ]
  371. then
  372.         print_heading
  373.         while read DOMAIN
  374.         do
  375.                 check_domain_status "${DOMAIN}"
  376.  
  377.         done < ${SERVERFILE}
  378.  
  379. ### There was an error, so print a detailed usage message and exit
  380. else
  381.         usage
  382.         exit 1
  383. fi
  384.  
  385. # Add an extra newline
  386. echo
  387.  
  388. ### Remove the temporary files
  389. rm -f ${WHOIS_TMP}
  390.  
  391. ### Exit with a success indicator
  392. exit 0
  393.  
  394.