ftp_client.anubis 5.22 KB
/*
 * 
 * User: David RENE
 * Date: 11/05/2007
 * Time: 22:34
 * (c) Calexium
 *
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
 
read calexium_lib/CXM_message_constants.anubis
read calexium_lib/net_services/CXM_generic_protocol.anubis
read calexium_lib/net_services/CXM_generic_client.anubis  //for get_ip
read system/message_queue.anubis
read system/message_transceiver.anubis
read system/muscle.anubis
read system/files.anubis
read tools/basis.anubis
read network/dns.anubis

define Maybe(One)
  receive_data
  (
    MessageQueue  mQ,
    WStream       fd,
    Int           so_far,
    Int           left_read
  )=
  //println("receive_data ");
          if mQ.get_next_received_Message(30) is
          {
            timeout   then  failure,
            closed    then  failure,
            msg(_msg) then 
      with last_block = if find_bool(_msg, "End") is {failure then false, success(r) then r},
      if find_raw(_msg, "Data") is
      {
        failure       then println("Can't find raw Data"); send_ACK_error(mQ, _CXM_FTP_DATA); failure,
        success(data) then
          if write(fd, data) is
          {
            failure       then println("Can't write into file"); send_ACK_error(mQ, _CXM_FTP_DATA);failure,
            success(len)  then 
              send_ACK_ok(mQ, _CXM_FTP_DATA);
              if last_block then
                println("File received successfully");
                //TODO this is a big hack, we must check if all data are sent from the mQ
                sleep(10000);
                success(unique)
              else
//                println("Bytes received : " + (so_far + len));
                receive_data(mQ, fd, so_far + len, left_read - len)
          }
      }
  }
  .
  
define Maybe(One)
  start_get_file_transtert
  (
    MessageQueue  mQ, 
    String        local_file, 
    Int           size
  )=
  make_directories(local_file);
  if file(local_file, new) is
  {
    failure     then println("Can't create \""+local_file+"\" file"); failure,
    success(fd) then  //the local file is open
    with start = message(_CXM_FTP_START_TRANSFERT),
      mQ.add_Message_to_send(start);
      receive_data(mQ, weaken(fd), 0, size)
  }
  .
  
define Maybe(One)
  get_file
  (
    MessageQueue  mQ,
    String        remote_file,
    String        local_file,
    Bool          ftp
  )=
  with get_file_msg = message(_CXM_FTP_GET_FILE),
  if add_string(get_file_msg, "FileName", remote_file) is
  {
    failure     then failure,
    success(_)  then 
    ( if ftp then
        println("get_file FTP_DIR");
        forget(add_bool(get_file_msg, "FTP_DIR", true))
      else
        unique
    );
    mQ.add_Message_to_send(get_file_msg);
    if wait_for_reply(mQ, _CXM_FTP_GET_FILE, 30) is
    {
      failure    then println("get_file failure");failure,
      timeout    then println("get_file timeout");failure,
      unknow_cmd then println("get_file unknow_cmd");failure,
      error      then println("get_file remote error msg");failure,
      error(c,m) then println("get_file remote error [" + c + "] msg '" + m + "'");failure,
      ok         then println("get_file ok");failure,
      ok_msg(msg)then  
        if find_int32(msg, "FileSize") is
        {
          failure       then println("file size not found"); failure,
          success(size) then println("file size "+size);
            start_get_file_transtert(mQ, local_file, to_Int(size))
        }
    }
  }.
  
  
define Bool
  request_for_service
  (
    MessageQueue queue
  )=
  with test_msg = message(_CXM_REQUEST_FOR_SERVICE),
  forget(add_int32(test_msg, "service", _CXM_FTP_SERVICE_ID));
  forget(add_int32(test_msg, "version", 1));
  queue.add_Message_to_send(test_msg);
  if queue.get_next_received_Message(30) is
  {
    timeout then println("request_for_service receive timeout");false,
    closed  then println("request_for_service socket closed");false,
    msg(msg)  then 
      if find_int32(msg, "STATUS") is
      {
        failure     then println("status not found");false,
        success(v)  then 
          if v = _CXM_OK then 
            true
          else
            false              
      }
  }.
  
public define Maybe(One)
  ftp_get_file
  (
    String  server,
    Word32  ip_port,
    String  remote_file,
    String  local_file,
    Bool    ftp,
  ) =
  if get_ip(server) is success(ip_adr) then
    if connect( ip_adr, ip_port) is
    {
      error(_)  then println("can't connect to ftp server"); failure,
      ok(conn)  then 
        with queue = create_MessageQueue("ftp_get_file"),
        message_transceiver(conn, queue);
        println("request for ftp service");
        if request_for_service(queue) then
          with result = get_file(queue, remote_file, local_file, ftp),
          queue.quit(unique);result
        else
          queue.quit(unique);
          println("Service not found");failure
    }
  else
    println("server "+server+" DNS error");failure
  .

  /* Exists for backward compatibility. 
   * The last argument set to false (no ftp directory on the remote, pickup on collection dir)
   */
    
public define Maybe(One)
  ftp_get_file
  (
    String  server,
    Word32  ip_port,
    String  remote_file,
    String  local_file,
  ) =
  ftp_get_file(server, ip_port, remote_file, local_file, false).