Пример #1
0
/*
** Function used to init session structure
**
** IN:
**      FTPSRV_SESSION_STRUCT* session - session structure pointer
**      FTPSRV_STRUCT *server - pointer to server structure (needed for session parameters)
**      const int sock - socket handle used for communication with client
**
** OUT:
**      none
**
** Return Value: 
**      none
*/
static void ftpsrv_ses_init(FTPSRV_STRUCT *server, FTPSRV_SESSION_STRUCT *session, const int sock)
{
    if (server && session)
    {
        /* Some buffer of arbitrary size so we can get filesystem pointer */
        char      dev_name[16] = {0};

        /* Init session structure */
        session->control_sock = sock;
        session->connected = TRUE;
        session->auth_tbl = server->params.auth_table;
        session->root_dir = (char*) server->params.root_dir;
        session->cur_dir = RTCS_mem_alloc_zero(sizeof("\\"));
        session->cur_dir[0] = '\\';
        session->start_time = RTCS_time_get();

        _io_get_dev_for_path(dev_name, NULL, 16, session->root_dir, NULL);
        session->fs_ptr = _io_get_fs_by_name(dev_name);
        session->msg_queue = RTCS_mem_alloc_zero(sizeof(LWMSGQ_STRUCT) + FTPSRV_NUM_MESSAGES*sizeof(FTPSRV_TRANSFER_MSG)*sizeof(_mqx_max_type));
        if (session->msg_queue != NULL)
        {
            _lwmsgq_init(session->msg_queue, FTPSRV_NUM_MESSAGES, sizeof(FTPSRV_TRANSFER_MSG)/sizeof(_mqx_max_type));
        }
    }
}
Пример #2
0
uint32_t IGMP_init
   (
      void
   )
{ /* Body */
   uint32_t              error;
   IGMP_CFG_STRUCT_PTR  IGMP_cfg_ptr;

   /* alloc and init the configuration block */
   IGMP_cfg_ptr = RTCS_mem_alloc_zero(sizeof(IGMP_CFG_STRUCT));
   if (!IGMP_cfg_ptr) {
      return RTCSERR_IGMP_CFG;
   } /* Endif */

   /* register the configuration block */
   RTCS_setcfg(IGMP, IGMP_cfg_ptr);

   /* register the igmp protocol in the ip layer */
   IP_open(IPPROTO_IGMP, IGMP_service, NULL, &error);
   if (error != RTCS_OK) {
      return RTCSERR_IGMP_CFG;
   } /* Endif */

   /*
   ** When IGMP_init() is called, the only registered interface is the
   ** loopback interface, so we don't need to join the all-hosts group
   ** on any interface here.
   */

   return error;
} /* Endbody */
Пример #3
0
uint32_t RIP_init (void)
{ /* Body */
    RIP_CFG_STRUCT_PTR  cfg = RTCS_getcfg(RIP);
    uint32_t err;

    if (RTCS_getcfg(RIP)) return RTCS_OK;
    /* allocate the memory */
    cfg = RTCS_mem_alloc_zero(sizeof(*cfg));
    if (!cfg)  return RTCSERR_OUT_OF_MEMORY;
    /* bind the udp port */
    err = UDP_openbind_internal(IPPORT_RIP, RIP_service, &cfg->UCB);
    if (err){
        _mem_free(cfg);
        return err;
    }

    RTCS_setcfg(RIP, cfg);
    ROUTE_register(&RIP_routefn);

    /* Start the retransmission timer to start sending immediately */
    cfg->TIMER_PERIODIC.TIME    = 0;
    cfg->TIMER_PERIODIC.EVENT   = RIP_expire_periodic;
    cfg->TIMER_PERIODIC.PRIVATE = NULL;
    TCPIP_Event_add(&cfg->TIMER_PERIODIC);

    /* probe all the interfaces now to build the route table faster */
    err = RIP_send_req();

    return RTCS_OK;
} /* Endbody */
Пример #4
0
void TFTPSRV_task
   (
      void   *dummy,
      void   *creator
   )
{ /* Body */
   TFTPSRV_STATE_STRUCT_PTR   tftpsrv_ptr;
   sockaddr_in                laddr;
   uint32_t                    i, numtrans, timeout;
   uint32_t                    error;
   
   tftpsrv_ptr = RTCS_mem_alloc_zero(sizeof(TFTPSRV_STATE_STRUCT));
  
   if (tftpsrv_ptr == NULL) {
      RTCS_task_exit(creator, RTCSERR_OUT_OF_MEMORY);
   } /* Endif */

    TFTPSRV_task_id = RTCS_task_getid();
#ifdef __MQX__ 
   /* Set up exit handler and context so that we can clean up if the TFTP Server is terminated */
   _task_set_environment( _task_get_id(), (void *) tftpsrv_ptr );
   _task_set_exit_handler( _task_get_id(), TFTPSRV_Exit_handler );
#endif 

   tftpsrv_ptr->SRV_SOCK = socket(PF_INET, SOCK_DGRAM, 0);
   if (tftpsrv_ptr->SRV_SOCK == RTCS_SOCKET_ERROR) {
      RTCS_task_exit(creator, RTCSERR_OUT_OF_SOCKETS);
   } /* Endif */

   laddr.sin_family      = AF_INET;
   laddr.sin_port        = IPPORT_TFTP;
   laddr.sin_addr.s_addr = INADDR_ANY;

   error = bind(tftpsrv_ptr->SRV_SOCK, (const sockaddr *)&laddr, sizeof(laddr));
   if (error != RTCS_OK) {
      RTCS_task_exit(creator, error);
   } /* Endif */

   RTCS_task_resume_creator(creator, RTCS_OK);

   for (;;) {
      timeout = TFTPSRV_service_timer(tftpsrv_ptr);
      numtrans = tftpsrv_ptr->NUM_TRANSACTIONS;
      error = RTCS_selectset(&tftpsrv_ptr->SRV_SOCK, numtrans+1, timeout);
      if ((error == RTCS_OK) || (error == RTCS_SOCKET_ERROR)) {
         continue;
      } /* Endif */
      if (error == tftpsrv_ptr->SRV_SOCK) {
         /* New request, service it */
         TFTPSRV_service_request(tftpsrv_ptr);
      } else {
         for (i = 0; i < numtrans; i++) {
            if (error == tftpsrv_ptr->SOCKETS[i]) {
               TFTPSRV_service_transaction(tftpsrv_ptr, tftpsrv_ptr->TRANS_PTRS[i]);
               break;
            } /* Endif */
         } /* Endfor */
      } /* Endif */
   } /* Endfor */
} /* Endbody */
Пример #5
0
/*
** Function for session allocation
**
** IN:
**      FTPSRV_STRUCT *server - pointer to server structure (needed for session parameters).
**
** OUT:
**      none
**
** Return Value: 
**      FTPSRV_SESSION_STRUCT* - pointer to allocated session. Non-zero if allocation was OK, NULL otherwise
*/
static FTPSRV_SESSION_STRUCT* ftpsrv_ses_alloc(FTPSRV_STRUCT *server)
{
    FTPSRV_SESSION_STRUCT *session = NULL;

    if (server)
    {
        session = RTCS_mem_alloc_zero(sizeof(FTPSRV_SESSION_STRUCT));
        if (session)
        {
            session->buffer = RTCS_mem_alloc_zero(sizeof(char)*FTPSRV_BUF_SIZE);
        }
    }

    if (session && (session->buffer == NULL))
    {
        _mem_free(session);
        session = NULL;
    }
    return session;
}
Пример #6
0
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name  : ftpsrv_get_full_path
* Returned Value : char* full path of file (root directory + server root + path from parameter)
* Comments       : This function is used for translating relative path to absolute path 
*                  which is required for file operations in MFS. Returned string is allocated dynamically.
*               
* Usage:
*       
*END*---------------------------------------------------------------------*/
char* ftpsrv_get_full_path(FTPSRV_SESSION_STRUCT* session, char* path, uint32_t *wrong_path)
{
    uint32_t path_length = strlen(path);
    uint32_t root_length = strlen(session->root_dir);
    uint32_t cur_dir_length;
    char*    new_path;
    uint32_t index = 0;

    /* 
    ** If first character in the path is backslash, then the path is absolute in FTP root
    ** and current directory is not to be added to full path.
    */
    cur_dir_length = (path[0] != '\\') ? strlen(session->cur_dir) : 0;

    new_path = RTCS_mem_alloc_zero(path_length+root_length+cur_dir_length+2); /* +1 because of backslash and +1 for terminator */
    if (new_path == NULL)
    {
        return(new_path);
    }

    memmove(new_path, session->root_dir, root_length);
    index += root_length;

    if (cur_dir_length)
    {
        memmove(new_path+index, session->cur_dir, cur_dir_length);
        index += cur_dir_length;
        if (new_path[index-1] != '\\')
        {
            new_path[index++] = '\\';
        }
    }
    memmove(new_path+index, path, path_length);
    
    /* Resolve directory changing sequences. */
    rtcs_path_normalize(new_path);
    path_length = strlen(new_path);
    *wrong_path = FALSE;

    /* If there is not root directory in result, signalize error. */
    if ((path_length < root_length) || 
        (new_path[root_length] != '\\') || 
        strncmp(new_path, session->root_dir, root_length) != 0)
    {
        _mem_free(new_path);
        new_path = NULL;
        *wrong_path = TRUE;
    }
    return(new_path);
}
Пример #7
0
char* ftpsrv_get_relative_path(FTPSRV_SESSION_STRUCT* session, char* abs_path)
{
    uint32_t root_length = strlen(session->root_dir);
    uint32_t new_length = strlen(abs_path) - root_length;
    char*    rel_path;

    rel_path = RTCS_mem_alloc_zero(new_length+1);
    
    if (rel_path != NULL)
    {
        _mem_copy(abs_path+root_length, rel_path, new_length);
    }
    
    return(rel_path);
}
Пример #8
0
int32_t ftpsrv_user(FTPSRV_SESSION_STRUCT* session)
{
    char*    temp;
    uint32_t length;
    int32_t  retval = FTPSRV_ERROR;
    FTPSRV_AUTH_STRUCT* input = &session->auth_input;
    
    if (session->cmd_arg == NULL)
    {
        session->message = (char*) ftpsrvmsg_badsyntax;
        return(FTPSRV_ERROR);
    }

    length = strlen(session->cmd_arg) + 1;
    
    if ((input->uid) && (strlen(input->uid) >= length))
    {
        temp = input->uid;
    }
    else
    {
        if (input->uid != NULL)
        {
            _mem_free(input->uid);
            input->uid = NULL;
        }
        temp = RTCS_mem_alloc_zero(sizeof(char)*length);
    }

    if (temp != NULL)
    {
        _mem_copy(session->cmd_arg, temp, length - 1);
        input->uid = temp;
        session->message = (char*) ftpsrvmsg_need_password;
        session->auth_state = FTPSRV_USER;
        retval = FTPSRV_OK;
    }
    
    if (retval != FTPSRV_OK)
    {
        session->message = (char*) ftpsrvmsg_no_memory;
    }

    return(retval);
}
Пример #9
0
bool SOCK_Add_owner
   (
      SOCKET_STRUCT_PTR    socket_ptr,
      _rtcs_taskid         task_ptr
   )
{ /* Body */
#if RTCSCFG_SOCKET_OWNERSHIP
   SOCKET_OWNER_STRUCT_PTR owner_ptr, new_owner_ptr;
   uint32_t                 i;
   void                  **saved_ptr = NULL;

   owner_ptr = &socket_ptr->OWNERS;

   while (owner_ptr != NULL) {
      for (i=0;i<SOCKET_NUMOWNERS;i++) {
         if (owner_ptr->TASK[i] == task_ptr) {
            /* already here, just return */
            return TRUE;
         } else if ((owner_ptr->TASK[i] == 0) && (saved_ptr == NULL)) {
            saved_ptr = &owner_ptr->TASK[i];
         } /* Endif */
      } /* Endfor */
      owner_ptr = owner_ptr->NEXT;
   } /* Endwhile */

   if (saved_ptr != NULL) {
      *saved_ptr = task_ptr;
   } else {
      new_owner_ptr = RTCS_mem_alloc_zero(sizeof(SOCKET_OWNER_STRUCT));
      if (new_owner_ptr == NULL) {
         return FALSE;
      } /* Endif */

      _mem_set_type(new_owner_ptr, MEM_TYPE_SOCKET_OWNER_STRUCT);

      new_owner_ptr->TASK[0] = task_ptr;
      owner_ptr->NEXT = new_owner_ptr;
   } /* Endif */
   return TRUE;
#else
   return TRUE;
#endif
} /* Endbody */
Пример #10
0
uint32_t ICMP_init
   (
      void
   )
{ /* Body */
   ICMP_CFG_STRUCT_PTR  icmp_cfg_ptr;
   uint32_t              status = RTCS_OK;     /* return code */

   icmp_cfg_ptr = RTCS_mem_alloc_zero(sizeof(ICMP_CFG_STRUCT));
   if (icmp_cfg_ptr == NULL) {
      return RTCSERR_OUT_OF_MEMORY;
   }

   _mem_set_type(icmp_cfg_ptr, MEM_TYPE_ICMP_CFG_STRUCT);
   
   RTCS_setcfg(ICMP, icmp_cfg_ptr);

   IP_open(IPPROTO_ICMP, ICMP_service, NULL, &status);

   return status;

} /* Endbody */
Пример #11
0
_mqx_int _io_socket_open
   (
      MQX_FILE_PTR fd_ptr,
      char _PTR_  open_name_ptr,
      char _PTR_  flags_ptr
   )
{ /* Body */
   IO_SOCKET_PTR io_ptr;

   io_ptr = RTCS_mem_alloc_zero(sizeof(*io_ptr));
   if (io_ptr == NULL) {
      return MQX_OUT_OF_MEMORY;
   } /* Endif */
   
   _mem_set_type(io_ptr, MEM_TYPE_IO_SOCKET);
   
   fd_ptr->DEV_DATA_PTR = io_ptr;

   io_ptr->SOCKET = (uint_32)flags_ptr;

   return MQX_OK;

} /* Endbody */
Пример #12
0
HOSTENT_STRUCT  *DNS_query_resolver_task
   (
   unsigned char  *name,
   uint16_t     query_type
   )

{  /* Body */

   DNS_MESSAGE_HEADER_STRUCT        *message_head_ptr;
   DNS_MESSAGE_TAIL_STRUCT          *message_tail_ptr;
   HOSTENT_STRUCT                   *host_ptr = NULL;
   sockaddr_in                       addr;
   uint32_t                           local_sock;
   uint32_t                           qname_size;
   uint32_t                           buffer_size;
   uint16_t                           rlen;
   int32_t                            temp_size;
   int32_t                            error;
   unsigned char                            *temp_ptr;
   unsigned char                            *qname_ptr;
   unsigned char                            *buffer_ptr;



   /*
   ** If the size of this buffer is changed, also change the buffer size
   ** in the recvfrom() call near the bottom of this function
   */
   buffer_ptr = RTCS_mem_alloc_zero( DNS_MAX_UDP_MESSAGE_SIZE );
   if ( buffer_ptr == NULL ) {
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY,
                     0, 0, 0);
      return( NULL );
   }/* Endif */
   _mem_set_type(buffer_ptr, MEM_TYPE_DNS_UDP_MESSAGE);
   qname_ptr = buffer_ptr + sizeof( DNS_MESSAGE_HEADER_STRUCT );

   if ( query_type == DNS_A ) {
       error = DNS_is_dotted_domain_name( name, qname_ptr );
       if ( error == RTCSERR_DNS_INVALID_NAME ||
            error == RTCSERR_DNS_INVALID_LOCAL_NAME ) {
          _mem_free(buffer_ptr);
          return( NULL );
       }/* Endif */
   } else {
      if ( query_type == DNS_PTR ) {
         error = DNS_insert_IP_query( name, qname_ptr );
         if ( error == RTCSERR_DNS_INVALID_IP_ADDR ) {
            _mem_free(buffer_ptr);
            return( NULL );
         }/* Endif */
      } else {
         _mem_free(buffer_ptr);
         return( NULL );
      } /* Endif */
   } /* Endif */

   local_sock = socket(AF_INET, SOCK_DGRAM, 0);

   if ( local_sock == RTCS_HANDLE_ERROR ) {
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_OPEN_SOCKET,
                     0, 0, 0);
      _mem_free(buffer_ptr);
      return( NULL );
   }/* Endif */

   /* Local address  */
   addr.sin_family       = AF_INET;
   addr.sin_port         = 0;
   addr.sin_addr.s_addr  = INADDR_ANY;

   error =  bind(local_sock, &addr, sizeof(addr));
   if (error != RTCS_OK) {
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_BIND_SOCKET,
                     0, 0, 0);
      _mem_free(buffer_ptr);
      return( NULL );
   } /* Endif */

   /* set up buffer for sending query.   */
   message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT *)buffer_ptr;

   mqx_htons(message_head_ptr->ID, 0);
   mqx_htons(message_head_ptr->CONTROL, DNS_STANDARD_QUERY);
   mqx_htons(message_head_ptr->QDCOUNT, DNS_SINGLE_QUERY);
   mqx_htons(message_head_ptr->NSCOUNT, 0);
   mqx_htons(message_head_ptr->ARCOUNT, 0);
   mqx_htons(message_head_ptr->ANCOUNT, 0);

   qname_size = strlen((char *)qname_ptr );
   /* Need to include the last '\0' character as well */
   qname_size++;

   temp_ptr = buffer_ptr + sizeof( DNS_MESSAGE_HEADER_STRUCT )
                          + qname_size;

   message_tail_ptr = (DNS_MESSAGE_TAIL_STRUCT *)temp_ptr;

   mqx_htons(message_tail_ptr->QTYPE, query_type);
   mqx_htons(message_tail_ptr->QCLASS, DNS_IN);

   buffer_size = sizeof(DNS_MESSAGE_HEADER_STRUCT) + qname_size
                 + sizeof(DNS_MESSAGE_TAIL_STRUCT);

    /* Remote address, DNS_Resolver currently uses port 1024 */
   addr.sin_port        = DNS_RESOLVER_PORT;
   addr.sin_addr.s_addr = DNS_RESOLVER_IP_ADDR;

   rlen = sizeof(addr);

   /* Send the buffer to the resolver for making a query */
   error = sendto(local_sock, buffer_ptr, buffer_size, 0, &addr, rlen);
   if (error == RTCS_ERROR) {
      shutdown(local_sock, FLAG_ABORT_CONNECTION);
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_SEND_QUERY,
                     0, 0, 0);
      _mem_free(buffer_ptr);
      return( NULL );
   }/* Endif */

   /* Get the response from the resolver, if none received, return NULL */
   error = (uint32_t)RTCS_selectset( &local_sock, 1, DNS_QUERY_TIMEOUT );
   if ( !error || error == RTCS_ERROR ) {
      shutdown(local_sock, FLAG_ABORT_CONNECTION);
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_NO_RESPONSE_FROM_RESOLVER,
                     0, 0, 0);
      _mem_free(buffer_ptr);
      return( NULL );
   } /* Endif */

   temp_size = recvfrom(local_sock, buffer_ptr, DNS_MAX_UDP_MESSAGE_SIZE,
                        0, &addr, &rlen);
   if ( temp_size == RTCS_ERROR ) {
     shutdown(local_sock, FLAG_ABORT_CONNECTION);
     RTCS_log_error(ERROR_DNS, RTCSERR_DNS_PACKET_RECEPTION_ERROR,
                    0, 0, 0);
     _mem_free(buffer_ptr);
     return( NULL );
   }/* Endif */

   host_ptr = DNS_parse_UDP_response(buffer_ptr, name, query_type);
   shutdown(local_sock, FLAG_ABORT_CONNECTION);
   _mem_free(buffer_ptr);
   return( host_ptr );

} /* Endbody */
Пример #13
0
bool_t pmap_init
   (
      void
   )
{ /* Body */
   int_32                  sock;
   sockaddr_in             laddr;
   SVCXPRT_PTR             xprt;
   PMAPLIST_PTR            pml;

   /* create and bind a UDP socket */
   sock = socket(PF_INET, SOCK_DGRAM, 0);
   if (sock == (int_32)RTCS_SOCKET_ERROR) {
      fprintf(stderr, "portmap: error creating UDP socket\n");
      return FALSE;
   } /* Endif */

   _mem_zero(&laddr, sizeof(laddr));
   laddr.sin_family = AF_INET;
   laddr.sin_port = PMAPPORT;
   laddr.sin_addr.s_addr = 0;
   if (bind(sock, &laddr, sizeof(laddr)) != RTCS_OK) {
      fprintf(stderr, "portmap: error binding UDP socket, rec=%08X\n",
         RTCS_geterror(sock));
      return FALSE;
   } /* Endif */

   /* create a UDP transport*/
   xprt = svcudp_create(sock);
   if (xprt == NULL) {
      fprintf(stderr, "portmap: error creating UDP transport, rec=%08X\n",
         RTCS_geterror(sock));
      return FALSE;
   } /* Endif */

   /* create an entry for the UDP transport */
   pml = (PMAPLIST_PTR)RTCS_mem_alloc_zero(sizeof(PMAPLIST));
   if (pml == NULL) {
      fprintf(stderr, "portmap: error creating UDP entry, can't alloc memory\n");
      return FALSE;
   } /* Endif */
   pml->pml_map.pm_prog = PMAPPROG;
   pml->pml_map.pm_vers = PMAPVERS;
   pml->pml_map.pm_prot = IPPROTO_UDP;
   pml->pml_map.pm_port = PMAPPORT;
   pml->pml_next = pml_head;
   pml_head = pml;

   /* create, bind and connect a TCP socket */
   sock = socket(PF_INET, SOCK_STREAM, 0);
   if (sock == (int_32)RTCS_SOCKET_ERROR) {
      fprintf(stderr, "portmap: error creating TCP socket\n");
      return FALSE;
   } /* Endif */

   _mem_zero(&laddr, sizeof(laddr));
   laddr.sin_family = AF_INET;
   laddr.sin_port = PMAPPORT;
   laddr.sin_addr.s_addr = 0;

   if (bind(sock, &laddr, sizeof(laddr)) != RTCS_OK) {
      fprintf(stderr, "portmap: error binding TCP socket, rec=%08X\n",
         RTCS_geterror(sock));
      return FALSE;
   } /* Endif */

   if (listen(sock, 0) != RTCS_OK) {
      fprintf(stderr, "portmap: error on socket listen, rec=%08X\n",
         RTCS_geterror(sock));
      return FALSE;
   } /* Endif */

   /* create a TCP transport*/
   xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
   if (xprt == NULL) {
      fprintf(stderr, "portmap: error creating TCP transport, rec=%08X\n",
         RTCS_geterror(sock));
      return FALSE;
   } /* Endif */

   /* create an entry for the TCP transport */
   pml = (PMAPLIST_PTR)RTCS_mem_alloc_zero(sizeof(PMAPLIST));
   if (pml == NULL) {
      fprintf(stderr, "portmap: error creating TCP entry, task error=%08X\n",
         _task_get_error());
      return FALSE;
   } /* Endif */
   pml->pml_map.pm_prog = PMAPPROG;
   pml->pml_map.pm_vers = PMAPVERS;
   pml->pml_map.pm_prot = IPPROTO_TCP;
   pml->pml_map.pm_port = PMAPPORT;
   pml->pml_next = pml_head;
   pml_head = pml;

   /* register program */
   if (!svc_register(NULL, PMAPPROG, PMAPVERS, pmap_service, 0)) {
      fprintf(stderr, "portmap: error registering service\n");
      return FALSE;
   } /* Endif */

   return TRUE;
} /* Endbody */
Пример #14
0
/*
** Internal function for server parameters initialization
**
** IN:
**      FTPSRV_STRUCT* server - server structure pointer
**
**      FTPSRV_PARAM_STRUCT* params - pointer to user parameters if there are any
** OUT:
**      none
**
** Return Value: 
**      uint32_t      error code. FTPSRV_OK if everything went right, positive number otherwise
*/
static uint32_t ftpsrv_set_params(FTPSRV_STRUCT *server, FTPSRV_PARAM_STRUCT *params)
{
    char*   temp;

    server->params.port = IPPORT_FTP;
    #if RTCSCFG_ENABLE_IP4
    server->params.ipv4_address.s_addr = FTPSRVCFG_DEF_ADDR;
    server->params.af |= AF_INET;
    #endif
    #if RTCSCFG_ENABLE_IP6  
    server->params.ipv6_address = in6addr_any;
    server->params.ipv6_scope_id = 0;
    server->params.af |= AF_INET6;
    #endif
    server->params.max_ses = FTPSRVCFG_DEF_SES_CNT;
    server->params.root_dir = "mfs:";
    server->params.server_prio = FTPSRVCFG_DEF_SERVER_PRIO;
    server->params.auth_table = NULL;
    server->params.use_nagle = 0;

    /* If there is parameters structure copy nonzero values to server */
    if (params != NULL)
    {
        if (params->port)
            server->params.port = params->port;
        #if RTCSCFG_ENABLE_IP4
        if (params->ipv4_address.s_addr != 0)
            server->params.ipv4_address = params->ipv4_address;
        #endif
        #if RTCSCFG_ENABLE_IP6
        if (params->ipv6_address.s6_addr != NULL)
            server->params.ipv6_address = params->ipv6_address;
        if (params->ipv6_scope_id)
            server->params.ipv6_scope_id = params->ipv6_scope_id;
        #endif
        if (params->af)
            server->params.af = params->af;
        if (params->max_ses)
            server->params.max_ses = params->max_ses;
        if (params->root_dir)
        {
            server->params.root_dir = params->root_dir;
        }
        else
        {
            return(FTPSRV_ERROR);
        }
        if (params->server_prio)
            server->params.server_prio = params->server_prio;
        if (params->auth_table)
            server->params.auth_table = params->auth_table;
        if (params->use_nagle)
            server->params.use_nagle = params->use_nagle;
    }
    /* Allocate space for string parameters and copy them. */
    temp = RTCS_mem_alloc_zero(strlen(server->params.root_dir)+1);

    if (temp == NULL)
    {
        return(FTPSRV_ERROR);
    }
    _mem_copy(server->params.root_dir, temp, strlen(server->params.root_dir));
    server->params.root_dir = temp;

    return(FTPSRV_OK);
}
Пример #15
0
HOSTENT_STRUCT  *DNS_parse_UDP_response
   (
   unsigned char    *buffer_ptr,
   unsigned char    *name_ptr,
   uint16_t       query_type
   )

{  /* Body */

   DNS_MESSAGE_HEADER_STRUCT            *message_head_ptr = NULL;
   DNS_RESPONSE_RR_MIDDLE_STRUCT        *answer_middle;
   INTERNAL_HOSTENT_STRUCT              *host_ptr = &RTCS_HOST;
   unsigned char                                *answer_ptr;
   unsigned char                                *answer_tail;
   unsigned char                                *temp_ptr;
   uint16_t                               response_length, answer_type,
      name_size, number_of_answers, num_queries;
   uint32_t                               i, name_index = 0;
   uint32_t                               j = 0;
   uint32_t                               k = 0;
   uint32_t                               buffer_size;
   uint32_t                              *addr_ptr;
   bool                               unknown_answer_type = FALSE;

   message_head_ptr  = (DNS_MESSAGE_HEADER_STRUCT *)buffer_ptr;
   buffer_size       = sizeof(DNS_MESSAGE_HEADER_STRUCT);
   temp_ptr = buffer_ptr + sizeof( DNS_MESSAGE_HEADER_STRUCT );

   /* Zero the global HOSTENT_STRUCT */
   _mem_zero((char *)host_ptr, sizeof(INTERNAL_HOSTENT_STRUCT));

   /* Get the number of queries. */
   num_queries = mqx_ntohs(message_head_ptr->QDCOUNT);
   for (i = 0; i < num_queries; i++) {
      name_size = 0;
      while( (mqx_ntohc(temp_ptr) != '\0') &&
         name_size < DNS_MAX_CHARS_IN_NAME ) {
         name_size = name_size + mqx_ntohc(temp_ptr) + 1;
         temp_ptr  = temp_ptr  + mqx_ntohc(temp_ptr) + 1;
      } /* Endwhile */
      /* To include the terminating NULL char */
      name_size++;
      buffer_size += (name_size + sizeof(DNS_MESSAGE_TAIL_STRUCT));
      temp_ptr    += (1 + sizeof(DNS_MESSAGE_TAIL_STRUCT));
   } /* Endfor */

   number_of_answers = mqx_ntohs(message_head_ptr->ANCOUNT);
   if (number_of_answers > DNS_MAX_NAMES ) {
      number_of_answers = DNS_MAX_NAMES;
   } /* Endif */

   host_ptr->HOSTENT.h_aliases   = &host_ptr->ALIASES[0];
   host_ptr->HOSTENT.h_addr_list = (char **)&host_ptr->ADDRESSES[0];
   host_ptr->ADDRESSES[0]        = NULL;
   host_ptr->HOSTENT.h_name      = NULL;
   host_ptr->HOSTENT.h_length    = sizeof( _ip_address );

   for (i = 0; (i < number_of_answers) && (j < DNS_MAX_ADDRS) &&
       (k < DNS_MAX_NAMES); i++ )
   {
      answer_ptr = temp_ptr;
      name_size  = 0;

      while( (mqx_ntohc(temp_ptr) != '\0') &&
             name_size < DNS_MAX_CHARS_IN_NAME &&
             !(mqx_ntohc(temp_ptr) & DNS_COMPRESSED_NAME_MASK)) {
         name_size += mqx_ntohc(temp_ptr);
         temp_ptr += mqx_ntohc(temp_ptr) + 1;
      } /* Endwhile */

      if ( mqx_ntohc(temp_ptr) & DNS_COMPRESSED_NAME_MASK ) {
         temp_ptr++;
      }/* Endif */

      temp_ptr++;
      answer_middle   = (DNS_RESPONSE_RR_MIDDLE_STRUCT *)temp_ptr;
      response_length = mqx_ntohs(answer_middle->RDLENGTH);
      answer_type     = mqx_ntohs(answer_middle->TYPE);
      temp_ptr       += sizeof(DNS_RESPONSE_RR_MIDDLE_STRUCT);
      answer_tail     = temp_ptr;
      temp_ptr       += response_length;

      switch ( answer_type ) {

         case DNS_A:
            if ( host_ptr->HOSTENT.h_name == NULL ) {
               host_ptr->HOSTENT.h_name =
                  (char *)DNS_parse_answer_name_to_dotted_form(
                  buffer_ptr, answer_ptr, name_index );
               name_index++;
            } /* Endif */

            RTCS_HOST_ADDRS[j] = mqx_ntohl((unsigned char *)answer_tail);
            /*
            ** j is used in case BOTH CNAME and A data is received.  If CNAME
            ** answer is first, will write into wrong address space if using
            ** i.
            */
            host_ptr->ADDRESSES[j] = &RTCS_HOST_ADDRS[j];
            j++;
            /*
            ** This is to assure that the first IP address used is the first
            ** one that was given
            */
            host_ptr->IP_address = *host_ptr->ADDRESSES[0];
            break;

         case DNS_PTR:
            if (query_type == DNS_PTR) {
               if (host_ptr->HOSTENT.h_name != NULL) {
                  host_ptr->ALIASES[k] = host_ptr->HOSTENT.h_name;
                  k++;
               } /* Endif */
               host_ptr->HOSTENT.h_name =
                  (char *)DNS_parse_answer_name_to_dotted_form(
                  buffer_ptr, answer_tail, name_index );
               name_index++;
               addr_ptr = RTCS_mem_alloc_zero( sizeof( _ip_address ));
               if ( addr_ptr == NULL ) {
                  RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY,
                                 0, 0, 0);
                  return( NULL );
               }/* Endif */

               *addr_ptr = *((_ip_address *)name_ptr);
               host_ptr->ADDRESSES[j] = addr_ptr;
               j++;
               host_ptr->IP_address = *host_ptr->ADDRESSES[0];
            } else {
               host_ptr->ALIASES[k] = (char *)
                     DNS_parse_answer_name_to_dotted_form( buffer_ptr,
                     answer_tail, name_index );
               name_index++;
               k++;
            } /* Endif */
            break;

         case DNS_CNAME:
            /* the k is used for ALIASES as the j is used for ADDRESSES */
            host_ptr->ALIASES[k] = (char *)
               DNS_parse_answer_name_to_dotted_form(
               buffer_ptr, answer_tail, name_index );
            name_index++;
            k++;
            break;

         default:
            unknown_answer_type = TRUE;
      } /* Endswitch */

      if ( unknown_answer_type == TRUE ) {
         break;
      }/* Endif */

      host_ptr->ADDRESSES[j]       = NULL;
      host_ptr->ALIASES[k]         = NULL;
      host_ptr->HOSTENT.h_addrtype = mqx_ntohs(answer_middle->CLASS);

   } /* Endfor */

   if ( number_of_answers == 0 ) {
      return( NULL );
   } /* Endif */

   return( &RTCS_HOST.HOSTENT );

} /* Endbody */
Пример #16
0
HOSTENT_STRUCT_PTR RTCS_gethostbyname
   (
      char_ptr  name
   )
{  /* Body */
   INTERNAL_HOSTENT_STRUCT_PTR host_ptr;
   uint_32                     i;
   boolean                     name_found;
   boolean                     dotted_decimal;
   uint_32                     num_aliases = 0;
   uint_32                     host_index = 0;
   uint_32                     temp;

   /* allocate memory for HOSTENT_STRUCT */
   host_ptr = RTCS_mem_alloc_zero(sizeof(INTERNAL_HOSTENT_STRUCT));
   if ( host_ptr == NULL ) {
      return(NULL);
   }/* Endif */
   _mem_set_type(host_ptr, MEM_TYPE_HOSTENT_STRUCT);
   
   host_ptr->HOSTENT.h_aliases = &host_ptr->ALIASES[0];
   host_ptr->HOSTENT.h_addr_list = (char_ptr _PTR_)&host_ptr->ADDRESSES[0];

   /* assign address type and length */
   host_ptr->HOSTENT.h_addrtype = AF_INET;
   host_ptr->HOSTENT.h_length = 4;     /* IP addresses only used - 4 bytes */

   /* check to see if name is written in dotted decimal IP format */
   dotted_decimal = RTCS_get_dotted_address (name, &temp);

   if ( dotted_decimal == TRUE ) {
      /* assign the hostent struct from the dotted decimal IP name */
      host_ptr->HOSTENT.h_name = name;
      host_ptr->ALIASES[num_aliases] = NULL;
      host_ptr->IP_address = temp;
      host_ptr->ADDRESSES[0] = &host_ptr->IP_address;
      host_ptr->ADDRESSES[1] = NULL;
      name_found = TRUE;
   } else  {

      name_found = FALSE;

     /* search for the name in the hosts structure */
      while ( ((RTCS_Hosts_list[host_index]).ip_address != 0) && !name_found) {
      /*end of list hasn't been reached*/
         /* check the aliases for the name */
         i=0;
         while ( ((RTCS_Hosts_list[host_index]).aliases[i] != NULL) && !name_found) {
            if ( strcmp((RTCS_Hosts_list[host_index]).aliases[i],name) == 0 ) {
               name_found = TRUE;
            }/* Endif */
            ++i;
         } /* Endwhile */

         /* check the name field for the name */
         if ( strcmp((RTCS_Hosts_list[host_index]).host_name, name) == 0)  {
            name_found = TRUE;
         } /* Endif */

         if (name_found == TRUE ) { /* host name was found */

            host_ptr->HOSTENT.h_name = (RTCS_Hosts_list[host_index]).host_name;

            /* assign alias list */
            while ( (num_aliases < MAX_HOST_ALIASES)
                     && (RTCS_Hosts_list[host_index]).aliases[num_aliases] != NULL) {

               host_ptr->ALIASES[num_aliases] = (RTCS_Hosts_list[host_index]).aliases[num_aliases];
               ++num_aliases;
            } /* Endwhile */
            host_ptr->ALIASES[num_aliases] = NULL;

            /* assign addresses (in our case only one IP address is allowed) */

            host_ptr->ADDRESSES[0] = (uint_32_ptr)&((RTCS_Hosts_list[host_index]).ip_address);
            host_ptr->ADDRESSES[1] = NULL;
         } /* Endif */
         ++host_index;
      } /* Endwhile */
   }/* Endif */


   if ( !name_found ) {
      _mem_free(host_ptr);
      return( NULL );
   }/* Endif */

   return( &host_ptr->HOSTENT );

}/* EndBody */
Пример #17
0
/*
 * Allocate server structure, init sockets, etc.
 */
FTPSRV_STRUCT* ftpsrv_create_server(FTPSRV_PARAM_STRUCT* params)
{
    FTPSRV_STRUCT *server = NULL;
    uint32_t error;
    uint32_t error4 = FTPSRV_OK;
    uint32_t error6 = FTPSRV_OK;

    if ((server = _mem_alloc_system_zero(sizeof(FTPSRV_STRUCT))) == NULL)
    {
        return(NULL);
    }
    _mem_set_type(server, MEM_TYPE_FTPSRV_STRUCT);

    error = _lwsem_create(&server->tid_sem, 1);
    if (error != MQX_OK)
    {
        goto EXIT;
    }

    error = ftpsrv_set_params(server, params);
    if (error != FTPSRV_OK)
    {
        goto EXIT;
    }
    
    /* Allocate space for session pointers */
    server->session = RTCS_mem_alloc_zero(sizeof(FTPSRV_SESSION_STRUCT*) * server->params.max_ses);
    if (server->session == NULL)
    {
        goto EXIT;
    }

    /* Allocate space for session task IDs */
    server->ses_tid = RTCS_mem_alloc_zero(sizeof(_rtcs_taskid) * server->params.max_ses);
    if (server->ses_tid == NULL)
    {
        goto EXIT;
    }

    /* Init sockets. */
    if (params->af & AF_INET)
    {
        /* Setup IPv4 server socket */
        error4 = ftpsrv_init_socket(server, AF_INET);
    }
    if (params->af & AF_INET6)
    {
        /* Setup IPv6 server socket */
        error6 = ftpsrv_init_socket(server, AF_INET6);
    }

    if ((error4 != FTPSRV_OK) || (error6 != FTPSRV_OK))
    {
        ftpsrv_destroy_server(server);
        return(NULL);
    }
    server->run = 1;
    return(server);
    EXIT:
    ftpsrv_destroy_server(server);
    return(NULL);
}
Пример #18
0
void TFTPSRV_service_request
   (
      TFTPSRV_STATE_STRUCT_PTR   tftpsrv_ptr
         /* [IN/OUT] The TFTP Server state */
   )
{ /* Body */
   TFTP_TRANS_STRUCT_PTR   trans_ptr;
   sockaddr_in             sockaddr_t;
   int32_t                  pkt_len, i;
   uint32_t                 error;
   char                *filename, *filemode;
   uint16_t                 sockaddrlen, pkt_op;

   /* receive the datagram */
   sockaddrlen = sizeof(sockaddr_t);
   pkt_len = recvfrom(tftpsrv_ptr->SRV_SOCK, tftpsrv_ptr->BUFFER,
                      TFTP_MAX_MESSAGE_SIZE, 0, (sockaddr *)&sockaddr_t, &sockaddrlen);
   if (pkt_len == RTCS_ERROR) {
      return;
   } /* Endif */

   /* limit the number of concurrent transactions */
   if (tftpsrv_ptr->NUM_TRANSACTIONS >= TFTPSRV_MAX_TRANSACTIONS) {
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_busy, sockaddr_t);
      return;
   } /* Endif */

   /* parse the request; extract op, filename and filemode */
   i = 2;
   filename = (char *)tftpsrv_ptr->BUFFER + i;
   for (; i<pkt_len; i++) {
      if (tftpsrv_ptr->BUFFER[i] == '\0') break;
   } /* Endfor */
   i++;
   filemode = (char *)tftpsrv_ptr->BUFFER + i;
   for (; i<pkt_len; i++) {
      if (tftpsrv_ptr->BUFFER[i] == '\0') break;
   } /* Endfor */
   if (i >= pkt_len) {
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_op, sockaddr_t);
      return;
   } /* Endif */
   pkt_op = mqx_ntohs(tftpsrv_ptr->BUFFER);

   /* allocate state for the new transaction */
   trans_ptr = RTCS_mem_alloc_zero(sizeof(TFTP_TRANS_STRUCT));
   if (trans_ptr == NULL) {
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t);
      return;
   } /* Endif */
   _mem_set_type(trans_ptr, MEM_TYPE_TFTP_TRANS_STRUCT);
   
   /* validate the requested operation */
   switch (pkt_op) {
   case TFTPOP_RRQ:
      trans_ptr->RECV_OP = TFTPOP_ACK;
      trans_ptr->SEND_OP = TFTPOP_DATA;
      break;
   case TFTPOP_WRQ:
      trans_ptr->RECV_OP = TFTPOP_DATA;
      trans_ptr->SEND_OP = TFTPOP_ACK;
      break;
   default:
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_op, sockaddr_t);
      _mem_free(trans_ptr);
      return;
   } /* Endswitch */

   /* open the requested file */
   error = TFTPSRV_open_device(pkt_op, filename, filemode, &trans_ptr->TRANS_FILE_PTR);
   if (error) {
      switch (error) {
      case RTCS_EACCES:
         TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_accvio, sockaddr_t);
         break;
      case RTCS_ENOENT:
         TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_nofile, sockaddr_t);
         break;
      case RTCS_EEXIST:
         TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_exists, sockaddr_t);
         break;
      default:
         TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t);
         break;
      } /* Endswitch */
      _mem_free(trans_ptr);
      return;
   } /* Endif */

   /* create a socket for the new transaction */
   trans_ptr->SOCK = socket(PF_INET, SOCK_DGRAM, 0);
   if (trans_ptr->SOCK == RTCS_SOCKET_ERROR) {
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t);
      RTCS_io_close(trans_ptr->TRANS_FILE_PTR);
      _mem_free(trans_ptr);
      return;
   } /* Endif */

   trans_ptr->ADDR.sin_family      = sockaddr_t.sin_family;
   trans_ptr->ADDR.sin_port        = sockaddr_t.sin_port;
   trans_ptr->ADDR.sin_addr.s_addr = sockaddr_t.sin_addr.s_addr;

   sockaddr_t.sin_family      = AF_INET;
   sockaddr_t.sin_port        = 0;
   sockaddr_t.sin_addr.s_addr = INADDR_ANY;

   error = bind(trans_ptr->SOCK, (const sockaddr *)&sockaddr_t, sizeof(sockaddr_t));
   if (error != RTCS_OK) {
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t);
      shutdown(trans_ptr->SOCK, 0);
      RTCS_io_close(trans_ptr->TRANS_FILE_PTR);
      _mem_free(trans_ptr);
      return;
   } /* Endif */

   /* build the first packet */
   trans_ptr->BLOCK = 0;
   switch (trans_ptr->SEND_OP) {
   case TFTPOP_DATA:
      TFTPSRV_build_DATA(trans_ptr);
      break;
   case TFTPOP_ACK:
      TFTPSRV_build_ACK(trans_ptr);
      trans_ptr->EXIT = FALSE;
      break;
   } /* Endswitch */
   if (trans_ptr->SEND_SIZE < sizeof(TFTP_HEADER)) {
      TFTP_SEND(tftpsrv_ptr->SRV_SOCK, _tftp_error_srv, sockaddr_t);
      shutdown(trans_ptr->SOCK, 0);
      RTCS_io_close(trans_ptr->TRANS_FILE_PTR);
      _mem_free(trans_ptr);
      return;
   } /* Endif */

   /* send the first packet */
   TFTPSRV_timer_start(tftpsrv_ptr, trans_ptr, TFTP_timeout_init(&trans_ptr->XMIT_TIMER));
   TFTPSRV_send(trans_ptr);

   tftpsrv_ptr->SOCKETS[tftpsrv_ptr->NUM_TRANSACTIONS] = trans_ptr->SOCK;
   tftpsrv_ptr->TRANS_PTRS[tftpsrv_ptr->NUM_TRANSACTIONS] = trans_ptr;
   tftpsrv_ptr->NUM_TRANSACTIONS++;

} /* Endbody */
Пример #19
0
static void pmap_service
   (
      SVCREQ_PTR  req,
         /* [IN] - RPC request */
      SVCXPRT_PTR xprt
         /* [IN] - transport handle */
   )
{ /* Body */
   PMAP                 arg;
   uint_32              res;
   PMAPLIST_PTR         pml;
   PMAPLIST_PTR _PTR_   p;

   switch (req->rq_proc) {

   case PMAPPROC_NULL:
      svc_sendreply(xprt, xdr_void, NULL);
      break;

   case PMAPPROC_SET:
      if (!svc_getargs(xprt, (xdrproc_t)xdr_pmap, (caddr_t)&arg)) {
         svcerr_decode(xprt);
      } else {

         /*
         ** Scan list for existing (prog,vers,prot) entry.
         */
         res = FALSE;
         for (p = &pml_head; *p != NULL; p = &(*p)->pml_next) {
            if (((*p)->pml_map.pm_prog == arg.pm_prog)
             && ((*p)->pml_map.pm_vers == arg.pm_vers)
             && ((*p)->pml_map.pm_prot == arg.pm_prot)) {
               /*
               ** Found -- if the port matches, there's no work to be done.
               ** If the port doesn't match, we can't satisfy the request.
               ** Either way, we exit the loop and *p is non-NULL.
               */
               if ((*p)->pml_map.pm_port == arg.pm_port) {
                  res = TRUE;
               } /* Endif */
               break;
            } /* Endif */
         } /* Endfor */

         /*
         ** If there was no entry for (prog,vers,prot), create one
         ** at end of list.
         */
         if (*p == NULL) {
            pml = (PMAPLIST_PTR)RTCS_mem_alloc_zero(sizeof(PMAPLIST));
            if (pml != NULL) {
               pml->pml_map = arg;
               pml->pml_next = NULL;
               *p = pml;
               res = TRUE;
            } /* Endif */
         } /* Endif */

         /*
         ** Reply to client
         */
         svc_sendreply(xprt, (xdrproc_t)xdr_uint_32, (pointer)&res);
      } /* Endif */

      break;

   case PMAPPROC_UNSET:
      if (!svc_getargs(xprt, (xdrproc_t)xdr_pmap, (caddr_t)&arg)) {
         svcerr_decode(xprt);
      } else {

         /*
         ** Scan list for all (prog,vers) entries.
         */
         res = FALSE;
         for (p = &pml_head; *p != NULL;) {
            if (((*p)->pml_map.pm_prog == arg.pm_prog)
             && ((*p)->pml_map.pm_vers == arg.pm_vers)) {
               /*
               ** Found -- unlink and free it.
               */
               res = TRUE;
               pml = *p;
               *p = pml->pml_next;
               _mem_free(pml);
            } else {
               p = &(*p)->pml_next;
            } /* Endif */
         } /* Endfor */

         /*
         ** Reply to client
         */
         svc_sendreply(xprt, (xdrproc_t)xdr_uint_32, (pointer)&res);
      } /* Endif */

      break;

   case PMAPPROC_GETPORT:
      if (!svc_getargs(xprt, (xdrproc_t)xdr_pmap, (caddr_t)&arg)) {
         svcerr_decode(xprt);
      } else {

         /*
         ** Scan list for (prog,prot) entries.
         */
         res = 0;
         for (pml = pml_head; pml != NULL; pml = pml->pml_next) {
            if ((pml->pml_map.pm_prog == arg.pm_prog)
             && (pml->pml_map.pm_prot == arg.pm_prot)) {
               /*
               ** Found -- get the port, even if the version doesn't match.
               */
               res = pml->pml_map.pm_port;
               if (pml->pml_map.pm_vers == arg.pm_vers) {
                  break;
               } /* Endif */
            } /* Endif */
         } /* Endfor */

         /*
         ** Reply to client
         */
         svc_sendreply(xprt, (xdrproc_t)xdr_uint_32, (pointer)&res);
      } /* Endif */

      break;

   case PMAPPROC_DUMP:
      if (!svc_getargs(xprt, xdr_void, (caddr_t)NULL)) {
         svcerr_decode(xprt);
      } else {
         svc_sendreply(xprt, (xdrproc_t)xdr_pmaplist, (pointer)&pml_head);
      } /* Endif */
      break;

   default:
      svcerr_noproc(xprt);
      break;
   } /* Endswitch */

} /* Endbody */
Пример #20
0
int32_t ftpsrv_list(FTPSRV_SESSION_STRUCT* session)
{
    int32_t  length;
    char*    path;
    void*    dir_ptr;
    uint32_t sock;
    char*    dir_param;
    char*    full_path;
    char*    temp;
    uint32_t path_length;
    uint32_t wrong_path;

    if (session->cmd_arg == NULL)
    {
        path = "";
    }
    else
    {
        rtcs_url_decode(session->cmd_arg);
        path = rtcs_path_strip_delimiters(session->cmd_arg);
    }

    /* Translate relative path to absolute. */
    full_path = ftpsrv_get_full_path(session, path, &wrong_path);
    if (full_path == NULL)
    {
        if (wrong_path)
        {
            session->message = (char*) ftpsrvmsg_no_file;
        }
        else
        {
            session->message = (char*) ftpsrvmsg_no_memory;
        }
        return(FTPSRV_ERROR);
    }
    path_length = strlen(full_path);

    /* Allocate space for path + appendix, copy full path and add appendix to it. */
    /* This is required because MFS cannot list directories, only files. */
    temp = RTCS_mem_alloc_zero(path_length+sizeof(FTPSRV_PATH_APPENDIX)); 
    _mem_copy(full_path, temp, path_length);
    _mem_copy(FTPSRV_PATH_APPENDIX, temp+path_length, sizeof(FTPSRV_PATH_APPENDIX)-1);
    _mem_free(full_path);
    full_path = temp;

    /* Open directory. Unix format for LIST command, simple file list for NLIST. */
    if (!strcmp(session->command, "LIST"))
    {
        /* Unix */
        dir_param = "u*";
    }
    else
    {
        /* File list */
        dir_param = "f*";
    }

    /* Open directory, get list, cleanup and return. */
    dir_ptr = _io_mfs_dir_open(session->fs_ptr, full_path, dir_param);
    if (dir_ptr == NULL)
    {
        session->message = (char*) ftpsrvmsg_no_file;
        return(FTPSRV_ERROR);
    } 

    /* Send initialization message */
    ftpsrv_send_msg(session, ftpsrvmsg_opening_datacon);
    
    /* Open data connection */
    sock = ftpsrv_open_data_connection(session);
    if (sock == RTCS_SOCKET_ERROR)
    {
        session->message = (char*) ftpsrvmsg_locerr;
        _mem_free(full_path);
        _io_mfs_dir_close(dir_ptr);
        return(FTPSRV_ERROR);
    }

    /* Send data (directory listing). */
    while ((length = _io_mfs_dir_read(dir_ptr, session->buffer, FTPSRV_BUF_SIZE)) > 0)
    {
        /* If we are in root do not list "one level up" nor "current dir" link */
        if ((strstr(session->buffer, " .. ") || strstr(session->buffer, " . ")) && !strcmp(session->cur_dir, "\\"))
        {
            _mem_zero(session->buffer, length);
        }
        else
        {
            if (send(sock, session->buffer, length, 0) != length)
            { 
                ftpsrv_send_msg(session, ftpsrvmsg_writefail);
                break;
            }
        }
    }
    /* Cleanup */
    closesocket(sock);
    _io_mfs_dir_close(dir_ptr);
    _mem_free(full_path);

    session->message = (char*) ftpsrvmsg_trans_complete;
    return FTPSRV_OK;
}