#!/bin/bash
#-------------------------------------------------------------------------
##
## @Synopsis Frontend interface for dl_handlers
##
## This file contains functions for accessing download handlers.
## Download handlers handle the physical acquiring of files as opposed to
## the more abstract process of parsing and manipulating urls.
## A url handler will specify a download handler for a given url.
##
## dl handlers may call back to url handlers to have a url parsed
## it is up to the dl handler to interprit the results of the url
## parsing as it may be different for each type of url.
##
## dl handlers are responsible for connecting to the internet if they
## need to.
##
## WRITING NEW DL HANDLERS
## Current dl handlers only need a single function
## "dl_get_<handler>" This function takes the following arguments:
## $target
## $url_list      List of urls to get the target from
## $hints         Hints, these help the function determine what
##                type of thing it is downloading or other tunables.
## $dl_target     Name of variable in which to store the name of the
##                result directory or file
## $dl_type       Name of the variable in which to store the type of
##                thing downloaded
##
##
## The target parameter is advisory, it is a hint at what might be downloaded.
##
## The hints value is a list, values of interest to a particular
## dl_handler should be prefixed "dl_<handler>", the handler may define
## any hints which it see's necessary.
## There are also well defined hints: "tree" "file" these indicate that the
## type of thing being downloaded is probably a tree or file despite
## what we may think.
##
## The basic form of a dl handler's get function is simply a loop over each
## url until one successfully downloads, it should then set the target and
## type reference variable successfully.
##
## @Copyright Copyright 2002 by the Source Mage Team
## @Copyright Copyright 2005 by the Source Mage Team
##
#-------------------------------------------------------------------------

if ! [[ $DL_HANDLER_FILES ]] ; then
  DL_HANDLER_FILES=`ls $SGL_LIBRARY_MODULES/dl_handlers/dl_*[^~]`
  for  dl_handler_file  in  $DL_HANDLER_FILES;  do
    [  -x $dl_handler_file  ] && . $dl_handler_file
  done
fi


#-------------------------------------------------------------------------
##
## Download a specified group of urls, they are assumed to all be understood
## by the specified handler.
##
## @Param type	Name of handler
## The remainder of the arguments are target, url_list, hints, dl_target
## and dl_type. See above for information.
##
##
#-------------------------------------------------------------------------

function dl_get_bucket() {
  $STD_DEBUG
  local handler=$1
  local target=$2
  local url_list=$3
  local hints=$4
  local dl_target=$5
  local dl_type=$6

  if ! [[ "$handler" ]] ; then
    message "Missing handler, this is probably a sorcery bug"
    return 255
  elif ! misc_is_function dl_${handler}_get; then
    message "$handler is not a valid handler, this is probably a sorcery bug"
    return 255
  fi
  
  dl_${handler}_get "$target" "$url_list" "$hints" "$dl_target" "$dl_type"
  rc=$?
  if [[ $rc == 0 ]] ; then
    debug "libdownload" "dl_handler -- downloaded $url"
    eval debug "\$$dl_target \$$dl_type"
    return 0
  fi
  return 1
}

function dl_command_check() {
  local cmd
  smgl_which $1 cmd 
  if ! [[ $cmd ]] || ! test -x $cmd ; then
    message "${PROBLEM_COLOR}$cmd is not installed, please cast it..." \
            "${DEFAULT_COLOR}"
    return 1
  fi
}


#-------------------------------------------------------------------------
## this nonsense is to get us connected to the outside world
## it should eventually be a seperate, userdefinable script, with
## this as the default of course
#-------------------------------------------------------------------------
function dl_connect()  {

  [[ $INTERNET_AUTOCONNECT == on ]] || return 0

  debug "libdownload" "connect()"

  # We agree that while this lock is held, no other script will be
  # connecting or disconnecting internet service out from under us
  lock_resources internet signon
  for interface in $INTERNET_INTERFACES; do
    if ifconfig  |  grep  -q  "^$interface" ; then
      debug "libdownload" "connected through $interface"
      unlock_resources internet signon
      return
    fi
  done


  if $CONNECT_SCRIPT ; then
    message "${PROBLEM_COLOR}Cannot find or initiate network connection"
    message "${DEFAULT_COLOR}"
    message "Please setup your network connection."
    message "Try netconf if you use ethernet (with dsl), or see man pppd"
    message "for dialup.\n"
    message "If you still have trouble and have another way of getting"
    message "online, please come by #sourcemage on irc.freenode.net and" 
    message "someone will help you."
    return 1
  fi

  # Timeout in deciseconds to wait for Interface to come up.
  local TIMEOUT=30

  until  ifconfig  |  grep  -q  eth   ||
         ifconfig  |  grep  -q  atml   ||
         ifconfig  |  grep  -q  ppp   ||
         [  $TIMEOUT == 0  ]
  do
    sleep  10
    (( TIMEOUT-- ))
  done
  counter_up internet counter
  unlock_resources internet signon
}

#-------------------------------------------------------------------------
## this clever function disconnects us if we aren't downloading something
## the heuristic is rather poor.
#-------------------------------------------------------------------------
function dl_disconnect()  {

  [[ $INTERNET_AUTOCONNECT == on ]] || return 0

  local i_counter=/tmp/sorcery/i_counter

  # dont bother disconnecting if we didnt have to connect
  if test $(counter_check internet counter) -lt 1 ; then
    return
  fi

  counter_down internet counter
  disconnect_script /tmp/sorcery/disconnect.$$
  bash /tmp/sorcery/disconnect.$$ &
}



function disconnect_script() {
cat > $1 << EOF

. /etc/sorcery/config
# return if a script is already running
trylock_resources internet disconnect || exit
let i=0
#
# the following loop polls the "internet counter" counter
# if after some number of pollings the counter remains consistently 0
# assume that no one is going to use the connect and we disconnect
while :; do
  if trylock_resources internet signon &&
     test \$(counter_check internet counter) -lt 1 ; then
    let i++
    if test \$i -gt 10; then
      DISCONNECT=yes
      counter_reset internet counter
    fi
  else
    let i=0
  fi
  if [[ \$DISCONNECT ]] ; then
    \$DISCONNECT_SCRIPT
    rm $0
    unlock_resources internet signon
    exit $?
  else
    unlock_resources internet signon
  fi
  sleep 10
done
EOF
}

#---------------------------------------------------------------------
## This software is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This software is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this software; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#---------------------------------------------------------------------

