#!/bin/bash # Version 2.0, 2008-03-27 # # - Updated 2007-12-20 by David Szpunar (infotech.lakeviewchurch.org) # - Update versions of freetype, curl, php5 to match php5-install-prep.sh # - Updated 2007-12-16 by AskApache (www.askapache.com) # - Implemented functions to fetch the URI and decompress it # - Added a couple more error-checks # - Replaced wget with cURL # - Added more to help keep it from getting killed # - Updated to php-5.2.3, curl-7.17.1, freetype-2.3.5 # - Updated 2007-01-15 by Charles Wiltgen (charles@wiltgen.net) # - Make "nicer" to help keep it from getting killed by DreamHost # - Make less verbose to keep signal-to-noise level high # - Updated 2006-12-25 by Carl McDade (hiveminds.co.uk) # - Allow memory limit and freetype ### SHELL OPTIONS set +o noclobber # allowed to clobber files set +o noglob # globbing on set +o xtrace # change to - to enable tracing set +o verbose # change to - to enable verbose debugging set -e # abort on first error shopt -s extglob #shopt -s dotglob #shopt -s checkwinsize #set -o ignoreeof #set -o #set +o ############################################################################################################ ### ### SETTINGS ### ############################################################################################################ IDIR=${HOME}/doit GARBAGE=${IDIR}/trash PDIR=${IDIR}/php5 SDIR=${IDIR}/source DDIR=${IDIR}/dist LDIR=${IDIR}/logs TDIR=${IDIR}/tmp PACKAGES[0]=http://mirrors.usc.edu/pub/gnu/libiconv/libiconv-1.12.tar.gz CONFIGS[0]="--enable-extra-encodings" PACKAGES[1]=ftp://xmlsoft.org/libxml2/libxml2-2.6.32.tar.gz CONFIGS[1]="--with-iconv=${PDIR}" PACKAGES[2]=ftp://xmlsoft.org/libxslt/libxml2-2.6.32.tar.gz CONFIGS[2]="--with-libxml-prefix=${PDIR} --with-libxml-include-prefix=${PDIR}/include/ --with-libxml-libs-prefix=${PDIR}/lib/" PACKAGES[3]=http://www.zlib.net/zlib-1.2.3.tar.gz CONFIGS[3]="--shared" PACKAGES[4]=http://easynews.dl.sourceforge.net/sourceforge/mcrypt/libmcrypt-2.5.8.tar.gz CONFIGS[4]="--disable-posix-threads" PACKAGES[5]=http://internap.dl.sourceforge.net/sourceforge/mhash/mhash-0.9.9.tar.gz PACKAGES[6]=http://easynews.dl.sourceforge.net/sourceforge/freetype/freetype-2.3.5.tar.gz PACKAGES[7]=ftp://alpha.gnu.org/pub/gnu/libidn/libidn-1.6.tar.gz CONFIGS[7]="--with-iconv-prefix=${PDIR}" PACKAGES[8]=http://curl.haxx.se/download/curl-7.18.0.tar.gz CONFIGS[8]="--with-ssl=${PDIR} --with-zlib=${PDIR} --with-libidn=${PDIR} --disable-ldap --disable-ldaps --disable-ipv6 --enable-cookies --enable-crypto-auth" PACKAGES[9]=ftp://ftp.cac.washington.edu/imap/old/imap-2004g.tar.Z CONFIGS[9]="special" PACKAGES[10]=http://www.bzip.org/1.0.5/bzip2-1.0.5.tar.gz CONFIGS[10]="special" PACKAGES[11]=http://us.php.net/distributions/php-5.2.5.tar.gz CONFIGS[11]="--with-config-file-path=${PHPINI} \ --with-libxml-dir=${PDIR} \ --with-freetype-dir=${PDIR} \ --with-mhash=${PDIR} \ --with-mcrypt=${PDIR} \ --with-zlib-dir=${PDIR} \ --with-iconv=${PDIR} \ --with-curl=${PDIR} \ --with-imap=${PDIR} \ --with-bz2=${PDIR} \ --with-imap-ssl=/usr \ --with-ttf=/usr \ --with-openssl=/usr \ --with-jpeg-dir=/usr \ --with-png-dir=/usr \ --with-mysql=/usr \ --with-pdo-mysql \ --with-gd \ --without-pear \ --with-gettext \ --with-xml \ --with-mysqli \ --disable-ipv6 \ --disable-short-tags \ --disable-fastcgi \ --disable-debug \ --enable-force-cgi-redirect \ --enable-gd-native-ttf \ --enable-exif \ --enable-sockets \ --enable-wddx \ --enable-mbstring \ --enable-mbregex \ --enable-soap" DOMAIN= DOMAINROOT= CGIBIN= PHPINI= SETTINGS=${LDIR}/doit-settings.txt PID_FILE=${LDIR}/doit.pid OCRONTAB=${LDIR}/orig-crontab.txt NCRONTAB=${LDIR}/new-crontab.txt INSTALLER=${LDIR}/mass.sh INSTALLERL=${LDIR}/mass.txt MULTI=${LDIR}/multi.sh E_SUCCESS=0 E_YN=0 E_YES=251 E_NO=250 E_RETURN=65 C0= C1= C2= C3= C4= C5= C6= C7= C8= ############################################################################################################ ### ### FUNCTIONS ### ############################################################################################################ ################################## # # dreamhost_title # ################################## function dreamhost_title(){ # SET WINDOW TITLE AND COLORS IF CLIENT CAPABLE case ${TERM:-dummy} in xterm*|vt*|ansi|rxvt|gnome*) C0="\033[0m" C1="\033[1;30m" C2="\033[1;32m" C3="\033[0;32m" C4="\033[1;37m" C5="\033[0;36m" C6="\033[1;35m" C7="\033[0;37m" C8="\033[30;42m" echo -e "\033]0; DREAMHOST PHP5 PACKAGESTALLATION SCRIPT \007 "; ;; esac echo -e "${C1} __________________________________________________________________________ " echo -e "| ${C2} ___ __ __ __ ${C1} |" echo -e "| ${C2} / _ \_______ ___ ___ _ / // /__ ___ / /_ ${C1} |" echo -en "| ${C2} ";echo -n '/ // / __/ -_) _ `/ ` \/ _ / _ \(_->> ${C4}${1} ${C0} \n\n"; ;; "info") echo -e "=> ${1} "; ;; "item") echo -e "-> ${1} "; ;; esac } ################################## # # ok_continue # ################################## function ok_continue(){ echo -en "${C4} \n [ Press any key to continue ] ${C0} \n" read -t 1000 -n 1 ans } ################################## # # p_done # ################################## function p_done(){ sleep 1 echo -e "\n${C8} DONE ${C0} \n" sleep 1 } ################################## # # yes_no # ################################## function yes_no(){ local ans echo -en "${1} [y/n] " ; read -t 10000 -n 1 ans case "$ans" in n|N) E_YN=$NO ;; y|Y) E_YN=$E_YES ;; esac } ################################## # # do_sleep # ################################## function do_sleep () { echo -en "\n\n${C5}${4:-.}" while [ -f "$1" ] do sleep ${3:-3} echo -en "${4:-.}" done echo -e "${C0}" return 0 } ################################## # # get_settings # ################################## function get_settings(){ local p2 cha a2 F HOSTED_SITES if [ -f "$PID_FILE" ]; then print_message "Restarting after getting killed!" item else echo 'curl' > $PID_FILE fi if [ -f "$SETTINGS" ]; then OIFS=$IFS IFS=% while read DOMAIN DOMAINROOT CGIBIN PHPINI do DOMAIN=${DOMAIN} DOMAINROOT=${DOMAINROOT} CGIBIN=${CGIBIN} PHPINI=${PHPINI} done <${SETTINGS} IFS=$OIFS else HOSTED_SITES=$(cd ~/logs/;echo *.*;cd $OLDPWD) PS3="`echo -e '\n\n'`"; echo -e "" select v in ${HOSTED_SITES[@]} do DOMAIN="$v" F=$(sed = $(echo ~/logs/${DOMAIN}/http/e*[0-9g]) |sed -n "/${USER}\//p"|sed -e'1q;d' | sed -e 's/[^\/]*//') F=${F%,*} DOMAINROOT=${F%\/*} [ ! -d "$DOMAINROOT" ] && DOMAINROOT=${DOMAINROOT%\/*} CGIBIN=${DOMAINROOT}/cgi-bin PHPINI=${CGIBIN} break done while [ "$E_YN" != "$E_YES" ]; do for a in "DOMAINROOT" "CGIBIN" "PHPINI" do echo -en "\n (Enter for Default: ${!a} )\n ${a}:> "; read -e cha; echo [ ! -z "$cha" ] && eval "$var"=$cha; done yes_no "ARE THESE SETTINGS CORRECT" done fi echo "${DOMAIN}%${DOMAINROOT}%${CGIBIN}%${PHPINI}" > $SETTINGS } ################################## # # aa_speed_zombie # ################################## function aa_speed_zombie(){ print_message "INITIATING BACKGROUND PROCESSES" echo 'MAILTO=""' > $OCRONTAB print_message "SAVED ORIGINAL CRONTAB" item crontab -l &>/dev/null && crontab -l >> $OCRONTAB &>/dev/null print_message "DELETED CRONTAB" item crontab -r >/dev/null 2>&1 || echo -en print_message "CREATED NEW CRONTAB" item echo 'MAILTO=""'> $NCRONTAB echo "*/1 * * * * ${MULTI} ${SAFECRON} &>/dev/null" >> $NCRONTAB crontab $NCRONTAB &>/dev/null || echo p_done ### CREATE INSTALLATION SCRIPT echo "0" > $INSTALLERL exec 6>&1 ; exec > $INSTALLER echo "#!/bin/bash" echo "umask 022" echo "command ps \$1 &>/dev/null || crontab $OCRONTAB &>/dev/null" echo "pgrep -fl configure\\|make\\|gcc &>/dev/null && exit" echo "cd ${IDIR};renice 14 -p \$\$ &>/dev/null" echo "read CRONSTEP <${INSTALLERL}" echo "case \"\$CRONSTEP\" in" for theopts in $(seq 0 $((${#PACKAGES[@]} - 1))) do FN=$(basename ${PACKAGES[$theopts]}); MN=${FN/.tar.Z}; MN=${MN/.tar.gz}; VN=${MN#*-}; SN=${MN%-*} clogg=${LDIR}/C.log; mlogg=${LDIR}/M.log; mklogg=${LDIR}/MK.log a=$theopts let "a += 1" echo "\"$theopts\")" echo "cd ${SDIR}/${MN}"; case "${SN}" in 'bzip2') echo "nice -n 1 make install PREFIX=${PDIR} 1>&2 &>/dev/null && rm ${clogg} ${mlogg} ${mklogg}" ;; 'libmcrypt') echo "nice -n 2 ./configure --prefix=${PDIR} ${CONFIGS[$theopts]} 1>&2 &>/dev/null && rm ${clogg}" echo "nice -n 2 make 1>&2 &>/dev/null && rm ${mlogg}" echo "nice -n 2 make install 1>&2 &>/dev/null && rm ${mklogg} && echo \"$a\" > ${INSTALLERL}" echo "cd libltdl; nice -n 1 ./configure --prefix=${PDIR} --enable-ltdl-install 1>&2 &>/dev/null" echo "nice -n 1 make 1>&2 &>/dev/null" echo "nice -n 1 make install 1>&2 &>/dev/null && rm ${clogg} ${mlogg} ${mklogg}" ;; 'imap') echo "nice -n 1 make ldb 1>&2 &>/dev/null"; echo "cp c-client/c-client.a ${PDIR}/lib/libc-client.a && cp c-client/*.h ${PDIR}/include && rm ${clogg} ${mlogg} ${mklogg}" ;; 'php') echo "nice -n 2 ./configure --prefix=${PDIR} ${CONFIGS[$theopts]} 1>&2 &>/dev/null && rm ${clogg}" echo "nice -n 2 make 1>&2 &>/dev/null && rm ${mlogg}" echo "nice -n 2 make install 1>&2 &>/dev/null && rm ${mklogg} && echo \"$a\" > ${INSTALLERL}" echo "crontab -r || echo" echo "exit 0" ;; *) echo "nice -n 2 ./configure --prefix=${PDIR} ${CONFIGS[$theopts]} 1>&2 &>/dev/null && rm ${clogg}" echo "nice -n 2 make 1>&2 &>/dev/null && rm ${mlogg}" echo "nice -n 2 make install 1>&2 &>/dev/null && rm ${mklogg} && echo \"$a\" > ${INSTALLERL}" ;; esac echo ";;" done echo "esac" echo "exec \$0 \$1" echo "exit 0" exec 1>&6 6>&- chmod 744 $INSTALLER exec 6>&1 ; exec > $MULTI echo "#!/bin/bash" echo "umask 022" echo "pgrep -fl xargs\\|gzip\\|tar\\|cp &>/dev/null && exit" echo "declare -a URLS=( ${PACKAGES[@]} )" echo -e "DOMAIN=${DOMAIN}\nDOMAINROOT=${DOMAINROOT}\nCGIBIN=${CGIBIN}\nPHPINI=${PHPINI}" echo -e "IDIR=${IDIR}\nGARBAGE=${GARBAGE}\nPDIR=${PDIR}\nSDIR=${SDIR}\nDDIR=${DDIR}\nLDIR=${LDIR}\nTDIR=${TDIR}" echo -e "SETTINGS=${SETTINGS}\nPID_FILE=${PID_FILE}\nOCRONTAB=${OCRONTAB}\nNCRONTAB=${NCRONTAB}" echo -e "INSTALLER=${INSTALLER}\nINSTALLERL=${INSTALLERL}\nMULTI=${MULTI}" echo "renice 14 -p \$\$ &>/dev/null" echo "command ps \$1 &>/dev/null || crontab \$OCRONTAB &>/dev/null" echo "cd \$IDIR;read CRONSTEP <\$PID_FILE" echo "case \"\$CRONSTEP\" in" echo "\"curl\")" echo "cd \$DDIR;echo \${URLS[*]}|tr ' ' '\n'|xargs -P6 -iRL curl -s -S -e ';auto' -L -A 'Mozilla/5.0' --max-redirs 8 -O RL" echo "cd \$IDIR;rm \$LDIR/download.log && touch \$LDIR/download_done.log && echo \"gzip\" > \$PID_FILE && exec \$0 \$1" echo ";;" echo "\"gzip\")" echo "cd \$DDIR;echo *.*|tr ' ' '\n'|xargs -P6 -iAGZ gzip -df AGZ &>/dev/null" echo "cd \$IDIR;rm \$LDIR/gzip.log && touch \$LDIR/gzip_done.log && echo \"tar\" > \$PID_FILE && exec \$0 \$1" echo ";;" echo "\"tar\")" echo "cd \$SDIR;echo \$DDIR/*.tar|tr ' ' '\n'|xargs -P6 -iAGZ tar -xf AGZ" echo "cd \$IDIR;rm \$LDIR/tar.log && touch \$LDIR/tar_done.log && echo \"install\" > \$PID_FILE && exec \$0 \$1" echo ";;" echo "\"copy\")" echo "cd \$SDIR;echo \$DDIR/*.tar|tr ' ' '\n'|xargs -P6 -iAGZ tar -xf AGZ" echo "cd \$IDIR;rm \$LDIR/copy.log && touch \$LDIR/copy_done.log && echo \"install\" > \$PID_FILE && exec \$0 \$1" echo ";;" echo "\"install\")" echo "echo 'MAILTO=\"\"'> \$NCRONTAB" echo "echo \"*/1 * * * * \${INSTALLER} \$1 &>/dev/null\" >> \$NCRONTAB" echo "crontab \$NCRONTAB &>/dev/null && echo -en" echo "exec \${INSTALLER} \$1" echo ";;" echo "esac" echo "exit 0" exec 1>&6 6>&- chmod 744 $MULTI } ################################## # # aa_install # ################################## function aa_install () { local FN MN SN VN clogg mlogg mklogg # Push the install dir's bin directory into the path export PATH=${PDIR}/bin:$PATH for theopts in $(seq 0 $((${#PACKAGES[@]} - 1))) do FN=$(basename ${PACKAGES[$theopts]}); MN=${FN/.tar.Z}; MN=${MN/.tar.gz}; VN=${MN#*-}; SN=${MN%-*} [ ! -d "${SDIR}/${MN}" ] && echo "${SDIR}/${MN} not found" && exit 1 clogg=${LDIR}/C.log; mlogg=${LDIR}/M.log; mklogg=${LDIR}/MK.log touch $clogg $mlogg $mklogg print_message "Building ${SN} Version ${VN}" title [ ! ${SDIR}/${theopts}-${FN}.done.log ] || shift print_message "Configuring" info print_message "--prefix=${PDIR} ${CONFIGS[$theopts]}" item do_sleep ${clogg} 1 8 ":" 1 print_message "Making" info do_sleep ${mlogg} 1 6 ":" 1 print_message "Installing" info do_sleep ${mklogg} 1 4 ":" 1 && touch ${SDIR}/${theopts}-${FN}.done.log done } ################################## # # aa_unpack # ################################## function aa_unpack () { print_message "Stage 1 - gunzip\n" info echo "gzip" > $PID_FILE echo ${@##*/}|tr ' ' '\n'|xargs -iAURL echo -e "${C6}-> ${C7}AURL ${C0} " echo $$ > ${LDIR}/gzip.log [ -f "${LDIR}/gzip_done.log" ] || do_sleep ${LDIR}/gzip.log 1 3 ":" p_done echo -e "\n" print_message "Stage 2 - tar\n" info echo "tar" > $PID_FILE f=${@##*/};echo ${f//r.gz/r}|tr ' ' '\n'|xargs -iAURL echo -e "${C6}-> ${C7}AURL ${C0} " echo $$ > ${LDIR}/tar.log [ -f "${LDIR}/tar_done.log" ] || do_sleep ${LDIR}/tar.log 1 5 ":" p_done echo -e "\n" #echo -e "\n" #print_message "Stage 3 - copy\n" info #echo -e "${C6} $TDIR -> $SDIR ${C0}" #echo "copy" > $PID_FILE #echo $$ > ${LDIR}/copy.log #[ -f "${LDIR}/copy_done.log" ] || do_sleep ${LDIR}/copy.log 1 5 ":" #echo "install" > $PID_FILE #echo -e "\n" } ################################## # # aa_download # ################################## function aa_download () { echo "$@"|tr ' ' '\n'|xargs -iAURL echo -e "${C6}-> ${C7}AURL ${C0} " echo $$ > ${LDIR}/download.log [ -f "${LDIR}/download_done.log" ] || do_sleep ${LDIR}/download.log 1 2 ":" } ################################## # # exit_cleanup # ################################## function exit_cleanup(){ # RESET WINDOW TITLE case $TERM in xterm*|vt*|ansi|rxvt|gnome*) echo -e "\033]0;$USER@`hostname`: $HOME\007" ;; esac echo -e "${C0}" reset &>/dev/null [ -f "$OCRONTAB" ] && crontab $OCRONTAB &>/dev/null pkill -1 -f xargs\|curl\|gzip\|tar\|multi\|mass\|configure\|make\|gcc &>/dev/null || echo sleep 1 pkill -9 -f xargs\|curl\|gzip\|tar\|multi\|mass\|configure\|make\|gcc &>/dev/null || echo for avar in "$PDIR" "$OCRONTAB" "$NCRONTAB" "$MULTI" "$INSTALLERL" "$INSTALLER"; do [ -d $avar ] && mv $avar $GARBAGE/ &>/dev/null [ -f $avar ] && mv $avar $GARBAGE/ &>/dev/null done # KILL PROCESSES #ps aux #declare #set #pgrep -u $USER # |awk '{print $1}'|xargs -iJ kill -9 J # JOB TO DELETE UNNEEDED FILES #atq |awk '{print $1}'|xargs -iJ atrm J &>/dev/null #echo "nohup rm -rf ${GARBAGE}/ 1>&2 &>/dev/null 1>&2 &>/dev/null&" | at now + 3 hours 1>&2 &>/dev/null exit 65 } function aa_cleanup(){ pkill -9 tar\|multi\|xargs &>/dev/null || echo mkdir -p $GARBAGE $LDIR &>/dev/null touch ${LDIR}/cleanup.log for avar in "$PDIR" "$OCRONTAB" "$NCRONTAB" "$MULTI" "$INSTALLERL" "$INSTALLER"; do [ -d $avar ] && print_message "$avar sent to trash" item && mv $avar $GARBAGE/ &>/dev/null [ -f $avar ] && print_message "$avar sent to trash" item && mv $avar $GARBAGE/ &>/dev/null done print_message "Emptying Garbage" item nohup rm -rf $GARBAGE 1>&2 &>/dev/null && rm ${LDIR}/cleanup.log 1>&2 &>/dev/null 1>&2 &>/dev/null& do_sleep ${LDIR}/cleanup.log 1 1 ":" } ############################################################################################################ ### ### MAIN CODE ### ############################################################################################################ trap exit_cleanup SIGHUP SIGINT SIGTERM renice 19 -p $$ &>/dev/null SAFECRON=$$ mkdir -p $LDIR &>/dev/null dreamhost_title print_message "Configure Installation Settings" title get_settings p_done print_message "Cleaning up previous installations" title aa_cleanup p_done print_message "Creating Installation files" title for dirvar in "$IDIR" "$PDIR" "$SDIR" "$DDIR" "$LDIR" "$GARBAGE" "$TDIR"; do [ ! -d $dirvar ] && print_message "Created $dirvar" item && mkdir -p $dirvar &>/dev/null done p_done aa_speed_zombie print_message "Downloading required packages" title; aa_download ${PACKAGES[*]} p_done print_message "Unpacking downloaded files" title; aa_unpack ${PACKAGES[*]} p_done print_message "Initiating Compile Process" title; aa_install ${PACKAGES[*]} p_done mv $PID_FILE $GARBAGE/ &>/dev/null exit $? FN=$(basename ${PACKAGES[11]}); MN=${MN/.tar.gz}; print_message "Copying configuration file $PHPINI" title mkdir -p ${CGIBIN} cp ${SDIR}/${MN}/php.ini* ${CGIBIN} p_done print_message "Copying PHP CGI" title mkdir -p ${CGIBIN} chmod 0755 ${CGIBIN} cp ${PDIR}/bin/php ${CGIBIN}/php5-1.cgi p_done exit 0