#!/bin/sh

myname=`basename $0`

if [ -z "$GLOBUS_LOCATION" ] ; then 
  echo "GLOBUS_LOCATION is not set" 1>&2
  exit 1
fi
if [ -z "$NORDUGRID_LOCATION" ] ; then 
  echo "NORDUGRID_LOCATION is not set" 1>&2
  exit 1
fi

swap_dn () {
  __DN=$1
  _DN=
  while [ ! -z "${__DN}" ] ; do
    _DN=${__DN}
    __DN=`echo "${_DN}" | sed 's#^\([^/]*\)/\(.*\)#\2,\1#;t leave;s/.*//;:leave'`
  done
  echo ${_DN}
  unset _DN
  unset __DN
  return 0
}

fix_ldap_output ()
{
  sed 's/^ /^/' | \
  ( last_line= ; while true ; do 
     read -r line
     if [ $? != 0 ] ; then break ; fi
     first_char=`echo "$line" | head -c 1`
     if [ '^' = "$first_char" ] ; then
       last_line="$last_line`echo $line | sed 's/^[\^]//'`"
     else
       echo $last_line
       last_line="$line"
     fi       
  done ; echo $last_line ; ) 
}

get_rc_location () {
  # get the location specified or list
  _cmd="ldapsearch -LLL -H '$HOST' -Y GSI-GSSAPI -b '$COLLECTION' '(ObjectClass=GlobusReplicaLocation)' uc path"
  if [ -z "$VERBOSE" ] ; then _cmd="${_cmd} 2>/dev/null" ; fi
  _cmd="${_cmd} ; _ldapresult=\$? ; echo ; echo ldapresult: \${_ldapresult} ; echo"
  eval "${_cmd}" | fix_ldap_output | \
  {
    _ldapresult=0
    loc_fits=
    loc_urls=
    loc_compare="$1"
    if [ -z "$loc_compare" ] ; then loc_fits=1 ; fi
    loc_host=
    loc_path=
    loc_name=
    loc_url=
    while true ; do
      read line
      if [ "$?" -ne '0' ] ; then 
        if [ ! -z "$loc_host" ] && [ ! -z "$loc_name" ] ; then
          if [ ! -z `echo ${loc_host} | grep '^[^:]*://'` ] ; then
  	    loc_url="${loc_host}${loc_path} ${loc_name}"
	  else
	    loc_url="gsiftp://${loc_host}${loc_path} ${loc_name}"
	  fi
	fi
        if [ ! -z "$loc_fits" ] && [ ! -z "$loc_url" ] ; then
          loc_urls="${loc_urls}${loc_url} "
        fi
	if [ ! -z "$loc_compare" ] ; then
          loc_dn=`echo $line | sed 's/^[^:]*:\(.*\)/\1/;t leave;s/.*//;:leave'`
	  if [ -z "$rc_fits" ] ; then
  	    loc_fits=`echo "$loc_dn" | grep -i "$loc_compare"`
          fi
	fi
	break
      fi
      name=`echo $line | sed 's/^\([^:]*\):.*/\1/;t leave;s/.*//;:leave'`
      case "$name" in 
        dn )
	  if [ ! -z "$loc_host" ] && [ ! -z "$loc_name" ] ; then
	    if [ ! -z `echo ${loc_host} | grep '^[^:]*://'` ] ; then
  	      loc_url="${loc_host}${loc_path} ${loc_name}"
	    else
	      loc_url="gsiftp://${loc_host}${loc_path} ${loc_name}"
	    fi
	  fi
          if [ ! -z "$loc_fits" ] && [ ! -z "$loc_url" ] ; then
             loc_urls="${loc_urls}${loc_url} "
          fi
	  if [ ! -z "$loc_compare" ] ; then
            loc_dn=`echo $line | sed 's/^[^:]*:\(.*\)/\1/;t leave;s/.*//;:leave'`
	    if [ -z "$rc_fits" ] ; then
  	      loc_fits=`echo "$loc_dn" | grep -i "$loc_compare"`
            fi
	  fi
	  loc_host=
	  loc_path=
	  loc_url=
	  loc_name=`echo $line | sed 's/^[^:]*:[ ]*re=\([^,]*\).*/\1/;t leave;s/.*//;:leave'`
        ;;
        uc )
          loc_host=`echo $line | sed 's/^[^:]*: *\([^ ]*\).*/\1/;t leave;s/.*//;:leave'`
        ;;
        path )
          loc_path=`echo $line | sed 's/^[^:]*: *\(.*\)/\1/;t leave;s/.*//;:leave'`
	  if [ '/' != `echo $loc_path | head -c 1` ] && [ ! -z "$loc_path" ] ; then
	    loc_path="/$loc_path"
	  fi
        ;;
        ldapresult )
	  _ldapresult=`echo $line | sed 's/^[^:]*:\(.*\)/\1/;t leave;s/.*//;:leave'`
	;;
      esac
    done
    echo "$loc_urls"
    return ${_ldapresult}
  }
  _result=$?
  return ${_result}
}

get_rc_urls () {
  GIISES=`cat $NORDUGRID_LOCATION/etc/giislist 2>/dev/null`
  if [ -z "$GIISES" ] ; then
    echo "Do not know any GIIS to query about Replica Catalog" 1>&2
    return 1
  fi
  result=0
  rc_urls=
  rc_compare=$1
  for GIIS in $GIISES ; do
    GIIS_DN=`echo $GIIS | sed -e 's#^ldap://[^/]*/\(.*\)#\1#;t leave;s/.*//;:leave'`
    GIIS_URL=`echo $GIIS | sed -e 's#^\(ldap://[^/]*\)/.*#\1#;t leave;s/.*//;:leave'`
    if [ -z "GIIS_URL" ] ; then continue ; fi
    GIIS_DN=`swap_dn "$GIIS_DN"`
# need only one url
    if [ ! -z "$VERBOSE" ] ; then echo "Quering $GIIS_URL with $GIIS_DN" 1>&2 ; fi
    ldapsearch -LLL -x -H "$GIIS_URL" -b "$GIIS_DN" \
    '(ObjectClass=nordugrid-rc)' nordugrid-rc-baseurl nordugrid-rc-name \
    2>/dev/null | \
    fix_ldap_output | {
      rc_fits=
      if [ -z "$rc_compare" ] ; then rc_fits=1 ; fi
      rc_url=
      while true ; do
        read line
        if [ "$?" -ne '0' ] ; then 
          if [ ! -z "$rc_fits" ] ; then
            if [ ! -z "$rc_url" ] ; then
              if [ ! -z "$rc_urls" ] ; then
	        echo "Have more than one matching RC URLs" 1>&2
	        return 1
	      fi
	      rc_urls="$rc_url"
	      break
#            rc_urls="${rc_urls}${rc_url} "
	    fi
          fi
          break
        fi
        name=`echo $line | sed 's/^\([^:]*\):.*/\1/;t leave;s/.*//;:leave'`
        case "$name" in 
        dn )
	  if [ ! -z "$rc_fits" ] ; then
  	    if [ ! -z "$rc_url" ] ; then
  	      if [ ! -z "$rc_urls" ] ; then
	        echo "Have more than one matching RC URLs" 1>&2
	        return 1
	      fi
	      rc_urls="$rc_url"
	      break
#              rc_urls="${rc_urls}${rc_url} "
	    fi
	  fi
          rc_fits=
          if [ -z "$rc_compare" ] ; then rc_fits=1 ; fi
          rc_url=
	;;
        nordugrid-rc-baseurl )
          rc_url=`echo $line | sed 's/^[^:]*:\(.*\)/\1/;t leave;s/.*//;:leave'`
	  if [ -z "$rc_fits" ] ; then
  	    rc_fits=`echo "$rc_url" | grep -i "$rc_compare"`
          fi
        ;;
        nordugrid-rc-name )
          rc_name=`echo $line | sed 's/^[^:]*:\(.*\)/\1/;t leave;s/.*//;:leave'`
	  if [ -z "$rc_fits" ]  ; then
  	    rc_fits=`echo "$rc_name" | grep -i "$rc_compare"`
          fi
        ;;
        esac
      done
      echo "$rc_urls"
      return 0
    }
    result=$?
    if [ "$result" -eq 0 ] ; then break ; fi
  done
  return $result
}

create_logical_file () {
  echo "lfn: $LFN"
  _filesize=$1
  _filechecksum=$2
  _filemodifytime=$3
  if [ -z "${_filesize}" ] ; then _filesize=0 ; fi
  if [ -z "${_filechecksum}" ] ; then _filechecksum=0 ; fi
  if [ -z "${_filemodifytime}" ] ; then _filemodifytime=0 ; fi
  if [ -z "$VERBOSE" ] ; then ldapmodify -H $HOST -Y GSI-GSSAPI 1>/dev/null 2>/dev/null
  else ldapmodify -H $HOST -Y GSI-GSSAPI
  fi <<EOF
dn: $COLLECTION
add: filename
filename: $LFN
EOF
  result=$?
  if [ '20' -eq "$result" ] ; then 
    echo "Warning: Logical file(name) already exists. Trying to continue."
  elif [ '0' -ne "$result" ] ; then 
    echo "Error adding logical file: $result - cleaning..."
    delete_logical_file
    return 1
  fi
  # make sure LFROOT exists
  ldapadd -H $HOST -Y GSI-GSSAPI 1>/dev/null 2>/dev/null <<EOF
dn: fin=LFROOT,$COLLECTION
objectClass: top
objectClass: GlobusTop
objectClass: GlobusReplicaFileInfo
EOF
  result=$?
  if [ '68' -ne "$result" ] && [ '0' -ne "$result" ] ; then
    echo "Problems creating logical root: $result - cleaning..." 1>&2
    delete_logical_file
    return 1
  fi
  if [ -z "$VERBOSE" ] ; then ldapadd -H $HOST -Y GSI-GSSAPI 1>/dev/null 2>/dev/null
  else ldapadd -H $HOST -Y GSI-GSSAPI
  fi <<EOF
dn: rf=$LFN,fin=LFROOT,$COLLECTION
objectClass: top
objectClass: GlobusTop
objectClass: GlobusReplicaLogicalFile
size: ${_filesize}
filechecksum: ${_filechecksum}
modifytime: ${_filemodifytime}
filetype: file
EOF
  result=$?
  if [ '0' -ne "$result" ] ; then
    echo "Problems creating logical file description: $result - cleaning..." 1>&2
    delete_logical_file
    return 1
  fi
  return 0
}

delete_logical_file () {
  echo "lfn: $LFN"
  if [ -z "$VERBOSE" ] ; then
    ldapdelete -H $HOST -Y GSI-GSSAPI "rf=$LFN,fin=LFROOT,$COLLECTION" 1>/dev/null 2>/dev/null
  else
    ldapdelete -H $HOST -Y GSI-GSSAPI "rf=$LFN,fin=LFROOT,$COLLECTION"
  fi
  # allow 'does not exist'
  result=$?
  if [ '32' -ne "$result" ] && [ '0' -ne "$result" ] ; then
    echo "Problems deleteing logical file description: $result" 1>&2 ; return 1
  fi
  prevresult=$result
  if [ -z "$VERBOSE" ] ; then ldapmodify -H $HOST -Y GSI-GSSAPI 1>/dev/null 2>/dev/null
  else ldapmodify -H $HOST -Y GSI-GSSAPI 
  fi <<EOF
dn: $COLLECTION
delete: filename
filename: $LFN
EOF
  result=$?
  if [ '20' -eq "$result" ] || [ '16' -eq "$result" ] ; then 
    # maybe it was reparing
    if [ '0' -ne "$prevresult" ] ; then 
      echo "Logical file does not exist" ; return 1
    fi
  elif [ '0' -ne "$result" ] ; then echo "Error deleting logical file: $result" ; return 1 
  fi
  return 0
}

get_physical_parameters () {
  if [ -z "$1" ] ; then return 1 ; fi
  if [ ! -r "$1" ] ; then return 1 ; fi
  _params=`cksum "$1"`
  _params2=`stat -t "$1"`
  _params3=`date '+%s' -r "$1"`
  if [ -z "${_params}" ] ; then return 1 ; fi
  _filesize=`echo ${_params} | sed 's/[0-9]* \([0-9]*\) .*/\1/'`
  _filecheksum=`echo ${_params} | sed 's/\([0-9]*\) [0-9]* .*/\1/'`
  _timestamp=`echo ${_params2} | sed -e 's/\([0-9]*\)$/##\1##/' | sed 's/[^#]*##\([^#]*\).*/\1/'`
  _timestamp="${_params3}"
  echo "${_filesize} ${_filecheksum} ${_timestamp}"
  return 0
}

get_logical_file () {
  _cmd="ldapsearch -LLL -H '$HOST' -Y GSI-GSSAPI -b 'rf=$LFN,fin=LFROOT,$COLLECTION' '(ObjectClass=GlobusReplicaLogicalFile)' filechecksum size modifytime"
  if [ -z "$VERBOSE" ] ; then _cmd="${_cmd} 2>/dev/null" ; fi
  _cmd="${_cmd} ; _ldapresult=\$? ; echo ; echo ldapresult: \${_ldapresult} ; echo"
  eval "${_cmd}" | fix_ldap_output | \
  {
    _ldapresult=0
    _filesize=
    _filechecksum=
    while true ; do
      read line
      if [ "$?" -ne '0' ] ; then break ; fi
      name=`echo $line | sed 's/^\([^:]*\):.*/\1/;t leave;s/.*//;:leave'`
      case "$name" in 
        modifytime )
	  _modifytime=`echo $line | sed 's/^[^:]*: *\([^ ]*\).*/\1/;t leave;s/.*//;:leave'`
	;;
        filechecksum )
	  _filechecksum=`echo $line | sed 's/^[^:]*: *\([^ ]*\).*/\1/;t leave;s/.*//;:leave'`
	;;
        size )
	  _filesize=`echo $line | sed 's/^[^:]*: *\([^ ]*\).*/\1/;t leave;s/.*//;:leave'`
	;;
        ldapresult )
	  _ldapresult=`echo $line | sed 's/^[^:]*:\(.*\)/\1/;t leave;s/.*//;:leave'`
	;;
      esac
    done
    if [ ! -z "${_filesize}" ] && [ ! -z "${_filechecksum}" ] && [ ! -z "${_modifytime}" ] ; then
      echo "${_filesize} ${_filechecksum} ${_modifytime}"
    elif [ ! -z "${_filesize}" ] && [ ! -z "${_filechecksum}" ] ; then
      echo "${_filesize} ${_filechecksum}"
    else
      if [ "${_ldapresult}" -eq 0 ] ; then _ldapresult=1 ; fi
    fi
    return "${_ldapresult}"
  }
  _result=$?
  if [ '32' -eq "${_result}" ] ; then 
    # record not found 
    return 2
  fi
  if [ '0' -eq "${_result}" ] ; then 
    return 0
  fi
  return 1
}

create_location () {
  if [ -z "$VERBOSE" ] ; then
    ldapadd -H $HOST -c -Y GSI-GSSAPI 1>/dev/null 2>/dev/null
  else
    ldapadd -H $HOST -c -Y GSI-GSSAPI
  fi <<EOF
dn: re=$LOCATION_NAME,$COLLECTION
objectClass: top
objectClass: GlobusTop
objectClass: GlobusReplicaLocation
uc: $LOCATION_URL
EOF
#path: $LOCATION_PATH
#EOF
  result=$?
  if [ "$result" -eq '0' ] ; then
    return 0
  elif [ "$result" -eq '32' ] ; then
    echo "The collection does not exist" 1>&2
    return 1
  elif [ "$result" -eq '68' ] ; then
    echo "The location already exists" 1>&2
    return 1
  else
    echo "Error adding location: $result" 1>&2
    return 1
  fi
}

delete_physical_file () {
  _location=$1
  _lfn=$2
  if [ -z "$VERBOSE" ] ; then ldapmodify -H $HOST -Y GSI-GSSAPI 1>/dev/null 2>/dev/null
  else ldapmodify -H $HOST -Y GSI-GSSAPI
  fi <<EOF
dn: re=${_location},$COLLECTION
delete: filename
filename: ${_lfn}
EOF
  result=$?
  if [ "$result" -eq '20' ] ; then return 0
  elif [ "$result" -ne '0' ] ; then return 1
  fi
  if [ "$result" -eq '0' ] ; then
    return 0
  elif [ "$result" -eq '32' ] ; then
    echo "This files is missing at location" 1>&2
    return 1
  else
    echo "Error deleting file from location: $result" 1>&2
    return 1
  fi
}

create_physical_file () {
  _location=$1
  _lfn=$2
  if [ -z "$VERBOSE" ] ; then ldapmodify -H $HOST -Y GSI-GSSAPI 1>/dev/null 2>/dev/null
  else ldapmodify -H $HOST -Y GSI-GSSAPI
  fi <<EOF
dn: re=${_location},$COLLECTION
add: filename
filename: ${_lfn}
EOF
  result=$?
  if [ "$result" -eq '20' ] ; then return 0
  elif [ "$result" -ne '0' ] ; then return 1
  fi
  return 0
}

list_collection_files () {
  _cmd="ldapsearch -LLL -H '$HOST' -Y GSI-GSSAPI -b '$COLLECTION' '(ObjectClass=GlobusReplicaLogicalCollection)' filename"
  if [ -z "$VERBOSE" ] ; then _cmd="${_cmd} 2>/dev/null" ; fi
  eval "${_cmd}" | fix_ldap_output | grep '^filename\:' | sed 's/^filename\: *//'
}

list_locations () {
  _cmd="ldapsearch -LLL -H '$HOST' -Y GSI-GSSAPI -b '$COLLECTION' '(ObjectClass=GlobusReplicaLocation)' dn"
  if [ -z "$VERBOSE" ] ; then _cmd="${_cmd} 2>/dev/null" ; fi
  eval "${_cmd}" | fix_ldap_output | grep '^dn\:' | sed 's/^dn\: *re= *//' | sed 's/^\([^,]*\).*/\1/'
}

list_location_files () {
  _cmd="ldapsearch -LLL -H '$HOST' -Y GSI-GSSAPI -b 're=$LOCATION_NAME,$COLLECTION' '(ObjectClass=GlobusReplicaLocation)' filename"
  if [ -z "$VERBOSE" ] ; then _cmd="${_cmd} 2>/dev/null" ; fi
  eval "${_cmd}" | fix_ldap_output | grep '^filename\:' | sed 's/^filename\: *//'
}

delete_location () {
  if [ -z "$VERBOSE" ] ; then
    ldapdelete -H $HOST -c -Y GSI-GSSAPI "re=$LOCATION_NAME,$COLLECTION" 1>/dev/null 2>/dev/null
  else
    ldapdelete -H $HOST -c -Y GSI-GSSAPI "re=$LOCATION_NAME,$COLLECTION"
  fi  
  result=$?
  if [ "$result" -eq '0' ] ; then
    exit 0
  elif [ "$result" -eq '32' ] ; then
    echo "The location does not exist" 1>&2
    exit 1
  else
    echo "Error deleting location: $result" 1>&2
    exit 1
  fi
}

# main

HOST=
COLLECTION=
VERBOSE=
COLLECTION_NAME=
CATALOG_MATCH=
PFN=
LOCATION_NAME=

while [ $# -gt 0 ] ; do
  if [ ! X`echo "$1" | head -c 1` = 'X-' ] ; then break ; fi
  if [ X"$1" = 'X-h' ] ; then
    case "$myname" in
      rc-wrapper )
        echo "rc-add-location"
        echo "rc-delete-location"
        echo "rc-delete-logical"
        echo "rc-delete-physical"
        echo "rc-list"
        echo "rc-add-file"
        echo "rc-add-logical"
        echo "rc-add-physical"
        exit 0
    #  rc-add-logical
      ;;
      rc-add-logical )
        echo 'rc-add-logical [-v] {-g collection_URL|[-r substring] -c collection_name} [-s pfn] lfn [size checksum modifytime]'
      ;;
      rc-delete-logical )
        echo 'rc-delete-logical [-v] -g {collection_URL|[-r substring] -c collection_name} lfn'
      ;;
      rc-delete-physical )
        echo 'rc-delete-physical [-v] -g {collection_URL|[-r substring] -c collection_name} -l location_name lfn'
      ;;
      rc-add-location )
        echo 'rc-add-location [-v] {-g collection_URL|[-r substring] -c collection_name} [-l location_name] GridFTP_URL'
      ;;
      rc-add-file )
        echo 'rc-add-file [-v] {-g collection_URL|[-r substring] -c collection_name} [-s pfn] [-l location_name] lfn'
        echo '  Uploads file "pfn" to the location "location_name" with name "lfn"'
	echo ' and registers it in collection "collection_name". If "pfn" is missing,'
	echo ' it uses "lfn"'
      ;;
      rc-list )
        echo 'rc-list [-v] {-g collection_URL|[-r substring] -c collection_name} [-l location_name]'
      ;;
      rc-delete-location )
        echo 'rc-delete-location [-v] {-g collection_URL|[-r substring] -c collection_name} -l location_name'
      ;;
      rc-add-physical )
        echo 'rc-add-physical [-v] -g {collection_URL|[-r substring] -c collection_name} -l location_name lfn'
      ;;
    esac
    exit 0
  elif [ X"$1" = 'X-v' ] ; then
    VERBOSE=1 
  elif [ X"$1" = 'X-g' ] ; then
    HOST=$2
    if [ -z "$HOST" ] ; then echo 'Missing URL in -g' 1>&2 ; exit 1 ; fi
    COLLECTION=`echo $HOST | sed -e 's#^ldap://[^/]*/\(.*\)#\1#;t leave;s/.*//;:leave'`
    HOST=`echo $HOST | sed -e 's#^\(ldap://[^/]*\)/.*#\1#;t leave;s/.*//;:leave'`
    shift
  elif [ X"$1" = 'X-c' ] ; then
    COLLECTION_NAME=$2
    if [ -z "$COLLECTION_NAME" ] ; then echo 'Missing collection name in -c' 1>&2 ; exit 1 ; fi
    shift
  elif [ X"$1" = 'X-r' ] ; then
    CATALOG_MATCH=$2
    if [ -z "$CATALOG_MATCH" ] ; then echo 'Missing match string in -r' 1>&2 ; exit 1 ; fi
    shift
  elif [ X"$1" = 'X-s' ] ; then
    PFN=$2
    if [ -z "$PFN" ] ; then echo 'Missing pfn in -s' 1>&2 ; exit 1 ; fi
    shift
  elif [ X"$1" = 'X-l' ] ; then
    LOCATION_NAME=$2
    if [ -z "$LOCATION_NAME" ] ; then echo 'Missing location in -l' 1>&2 ; exit 1 ; fi
    shift
  else
    if [ $# -gt 1 ] ; then
      echo "Unknown option $1" 1>&2
      exit 1 
    fi
  fi
#  if [ $# -le 1 ] ; then break ; fi
  shift
done

if [ ! -z "$COLLECTION_NAME" ] && [ ! -z "$HOST" ] ; then
  echo "You can't provide RC URL and use substring match at the same time" 1>&2
  exit 1
fi
if [ -z "$HOST" ] ; then
  if [ -z "$COLLECTION_NAME" ] ; then
    echo "Collection name is required if full URL is not given" 1>&2
    exit 1
  fi
fi

if [ -z "$HOST" ] ; then
  HOST=`get_rc_urls "$CATALOG_MATCH"`
  if [ "$?" -ne '0' ] ; then exit 1 ; fi
  COLLECTION=`echo $HOST | sed -e 's#^ldap://[^/]*/\(.*\)#\1#;t leave;s/.*//;:leave'`
  HOST=`echo $HOST | sed -e 's#^\(ldap://[^/]*\)/.*#\1#;t leave;s/.*//;:leave'`
  if [ -z "$HOST" ] ; then
    echo "Missing RC URL" 1>&2
    exit 1
  fi
  COLLECTION="lc=$COLLECTION_NAME,$COLLECTION"
fi

echo "RC host: $HOST"
echo "collection: $COLLECTION"

case "$myname" in
  rc-add-logical )
    LFN=$1
    if [ -z "$LFN" ] ; then echo "Missing logical file name" 1>&2 ; exit 1 ; fi
    LOCAL_FILE="$2 $3 $4"
    if [ ! -z "$PFN" ] ; then
      if [ '/' != `echo "$PFN" | head -c 1` ] ; then PFN="$PWD/$PFN" ; fi
      LOCAL_FILE=`get_physical_parameters "$PFN"`
      result=$?
      if [ "$result" -ne 0 ] ; then 
        echo "There is no local file named $PFN" 1>&2 ; exit 1
      fi
    fi
    create_logical_file $LOCAL_FILE
  ;;
  rc-delete-logical )
    LFN=$1
    if [ -z "$LFN" ] ; then echo "Missing logical file name" 1>&2 ; exit 1 ; fi
    delete_logical_file
  ;;
  rc-delete-physical )
    LFN=$1
    if [ -z "$LOCATION_NAME" ] ; then echo "Missing location name" 1>&2 ; exit 1 ; fi
    if [ -z "$LFN" ] ; then echo "Missing logical file name" 1>&2 ; exit 1 ; fi
    locations=`get_rc_location "$LOCATION_NAME"`
    result=$?
    echo "Have locations: $locations"
    if [ "$result" -ne '0' ] ; then echo "Failed obtainig location information" 1>&2 ; exit 1 ; fi
    if [ -z "$locations" ] ; then echo "No locations found" 1>&2 ; exit 1 ; fi
    # try all locations
    is_name=
    for location in $locations ; do 
      if [ -z "$is_name" ] ; then
        is_name=1
	_url="${location}/${LFN}"
      else
        echo "Removing ${LFN} from ${_url} - not yes - do it Yourself"
        delete_physical_file "${location}" "$LFN"
      fi
    done
  ;;
  rc-add-location )
    LOCATION_URL=$1
    if [ -z "$LOCATION_URL" ] ; then echo "Missing location URL" 1>&2 ; exit 1 ; fi
    LOCATION_PATH=`echo $LOCATION_URL | sed -e 's#^[^:]*://[^/]*\(/.*\)#\1#;t leave;s/.*//;:leave'`
    LOCATION_HOST=`echo $LOCATION_URL | sed -e 's#^[^:]*://\([^/]*\)/.*#\1#;t leave;s/.*//;:leave'`
    if [ -z "$LOCATION_HOST" ] ; then echo "Missing host in location URL" 1>&2 ; exit 1 ; fi
    if [ -z "$LOCATION_NAME" ] ; then
      LOCATION_NAME="$LOCATION_HOST"
    fi
    echo "location: $LOCATION_NAME"
    create_location
  ;;
  rc-list )
    if [ -z "$LOCATION_NAME" ] ; then
      echo "Files:"
      list_collection_files
      echo "Locations:"
      list_locations
    else
      echo "Files in location $LOCATION_NAME:"
      list_location_files
    fi
  ;;
  rc-add-physical )
    LFN=$1
    if [ -z "$LFN" ] ; then echo "Missing logical file name" 1>&2 ; exit 1 ; fi
    if [ -z "$LOCATION_NAME" ] ; then
      echo "Name of the location is required" 1>&2
      exit 1
    fi
    create_physical_file "${LOCATION_NAME}" "$LFN"
  ;;
  rc-add-file )
    LFN=$1
    if [ -z "$LFN" ] ; then echo "Missing logical file name" 1>&2 ; exit 1 ; fi
    if [ -z "$PFN" ] ; then PFN="$LFN" ; fi
    # check if file exists
    if [ '/' != `echo "$PFN" | head -c 1` ] ; then PFN="$PWD/$PFN" ; fi
    EXIST_FILE=`get_logical_file`
    result=$?
    if [ "$result" -eq '0' ] ; then
      # has this file - check if parameters are the same
      LOCAL_FILE=`get_physical_parameters "$PFN"`
      result=$?
      if [ "$result" -ne 0 ] ; then 
        echo "There is no local file named $PFN" 1>&2 ; exit 1
      fi
      if [ X"$EXIST_FILE" != X"$LOCAL_FILE" ] ; then
        echo "$EXIST_FILE != $LOCAL_FILE"  
        echo "Logical file already exists and is not the same as physical one" 1>&2 ; exit 1
      fi
      # file is probably "good"
    elif [ "$result" -eq '2' ] ; then
      # no such logical file - create
      LOCAL_FILE=`get_physical_parameters "$PFN"`
      result=$?
      if [ "$result" -ne 0 ] ; then 
        echo "There is no local file named $PFN" 1>&2 ; exit 1
      fi
      if [ ! -z "$VERBOSE" ] ; then echo "Creating logical file" ; fi
      create_logical_file $LOCAL_FILE
      result=$?
      if [ "$result" -ne '0' ] ; then
        echo "Because creation of logical file failed, there is no sense to create physical one" 1>&2 ; exit 1
      fi
      # logical file exists
    else      
      echo "Failed to contact Replica Catalog about logical file" 1>&2 ; exit 1
    fi
    # it seems we have good logical file - now upload file to storage
    # first make sure to have necessary utility
    if [ ! -x "$GLOBUS_LOCATION/bin/globus-url-copy" ] ; then
      echo "Can't find globus-url-copy utility at $GLOBUS_LOCATION/bin" 1>&2 ; exit 1
    fi
    # now choose where to store file
    locations=`get_rc_location "$LOCATION_NAME"`
    result=$?
    echo "Have locations: $locations"
    if [ "$result" -ne '0' ] ; then echo "Failed obtainig location information" 1>&2 ; exit 1 ; fi
    if [ -z "$locations" ] ; then echo "No locations found" 1>&2 ; exit 1 ; fi
    # try all locations
    is_name=
    for location in $locations ; do 
      if [ -z "$is_name" ] ; then
        is_name=1
	_url="${location}/${LFN}"
      else
        echo "Uploading ${PFN} to ${_url}"
        ${GLOBUS_LOCATION}/bin/globus-url-copy '-vb' "file://${PFN}" "${_url}"
        result=$?
        if [ "$result" -eq '0' ] ; then break ; fi
      fi
    done
    if [ "$result" -ne '0' ] ; then echo "Failed to upload file to storage" ; exit 1 ; fi
    # add pfn nformation
    create_physical_file "${location}" "$LFN"
  ;;
  rc-delete-location )
    if [ -z "$LOCATION_NAME" ] ; then
      echo "Name of the location is required" 1>&2
      exit 1
    fi
    delete_location
  ;;
esac
