예제 #1
0
파일: ftp.c 프로젝트: maplefish/MICO
//------------------------------------
static void _ftp_deinit(uint8_t unreg)
{
  closeCmdSocket(unreg);
  free(ftpCmdSocket);
  ftpCmdSocket = NULL;
  closeDataSocket();
  free(ftpDataSocket);
  ftpDataSocket = NULL;
  
  free( pDomain4Dns);
  pDomain4Dns=NULL;
  free( ftpuser);
  ftpuser=NULL;
  free( ftppass);
  ftppass=NULL;
  free( ftpfile);
  ftpfile=NULL;
  free( recvBuf);
  recvBuf=NULL;
  free( recvDataBuf);
  recvDataBuf=NULL;
  free(ftpresponse);
  ftpresponse = NULL;
  if ((gL != NULL) & (unreg == 0)) ftp_log("[FTP end] FTP SESSION CLOSED.\r\n");
  status = FTP_NOT_CONNECTED;
}
예제 #2
0
bool YapClient::sendSyncCommand()
{
    char pktHeader[4] = { 0, 0, 0, 0 };
    uint16_t pktLen;
    char * ppp = 0;

    if (d->cmdPacket->length() == 0) {
        fprintf(stderr, "Command is empty\n");
        return false;
    }

    pktLen = 0;
    ::memset(pktHeader, 0, sizeof(pktHeader));

    pktLen = d->cmdPacket->length();
    pktLen = bswap_16(pktLen);
    ::memcpy(pktHeader, &pktLen, 2);
    pktHeader[3] = kPacketFlagSyncMask;

    if (!writeSocket(d->cmdSocketFd, pktHeader, 4))
        goto Detached;

    if (!writeSocket(d->cmdSocketFd, (char*) d->cmdBuffer, d->cmdPacket->length()))
        goto Detached;


    pktLen = 0;
    ::memset(pktHeader, 0, sizeof(pktHeader));

    if (!readSocketSync(d->cmdSocketFd, pktHeader, 4))
        goto Detached;

    ppp = ((char *)&pktHeader[0]);
    pktLen   = *((uint16_t*) ppp);
    pktLen   = bswap_16(pktLen);
    if (pktLen > kMaxMsgLen) {
        fprintf(stderr, "YAP: Message too large %u > %u\n", pktLen, kMaxMsgLen);
        goto Detached;
    }

    if (!readSocketSync(d->cmdSocketFd, (char*) d->replyBuffer, pktLen))
        goto Detached;

    d->replyPacket->reset();
    d->replyPacket->setReadTotalLength(pktLen);

    return true;

 Detached:

    serverDisconnected();
    closeMsgSocket();
    closeCmdSocket();

    return false;
}
예제 #3
0
YapClient::~YapClient()
{
    if(d->msgServerIoSource != NULL) {
        g_source_destroy(d->msgServerIoSource);
        d->msgServerIoSource = NULL;
    }
    if(d->msgServerIoChannel != NULL) {
        g_io_channel_unref(d->msgServerIoChannel);
        d->msgServerIoChannel = NULL;
    }
    if(d->msgServerSocketFd != -1) {
        close(d->msgServerSocketFd);
        d->msgServerSocketFd = -1;
    }

    if (d->msgServerSocketPostfix)
        free(d->msgServerSocketPostfix);

    ::unlink(d->msgServerSocketPath);

    closeMsgSocket();
    closeCmdSocket();

    // We use mainLoop != NULL as a test to tell whether we allocated a loop & context during init().
    // In the case where we're using the default main context, we never allocate a loop.
    if(d->mainLoop != NULL)
    {
        g_main_loop_unref(d->mainLoop);
        g_main_context_unref(d->mainCtxt);
    }

    delete d->msgPacket;
    delete d->cmdPacket;
    delete d->replyPacket;

    delete[] d->msgBuffer;
    delete[] d->cmdBuffer;
    delete[] d->replyBuffer;

    delete d;

    d = NULL;
}
예제 #4
0
void YapClient::ioCallback(GIOChannel* channel, GIOCondition condition)
{
    if (d == NULL) {
        fprintf(stderr, "YAP: ioCallback was executing on a null YapClientPrv!");
        return;
    }

    if (channel == d->msgServerIoChannel) {
        // Server connected to our message socket. Created a new msg socket for it

        struct sockaddr_un  socketAddr;
        socklen_t           socketAddrLen;

        memset(&socketAddr,    0, sizeof(socketAddr));
        memset(&socketAddrLen, 0, sizeof(socketAddrLen));

        d->msgSocketFd = ::accept(d->msgServerSocketFd, (struct sockaddr*) &socketAddr, &socketAddrLen);

        // Create a new io channel for the receiving messages from the server
        d->msgIoChannel = g_io_channel_unix_new(d->msgSocketFd);
        d->msgIoSource  = g_io_create_watch(d->msgIoChannel, (GIOCondition) (G_IO_IN | G_IO_HUP));

        g_source_set_callback(d->msgIoSource, (GSourceFunc) YapClientPriv::ioCallback, this, NULL);
        g_source_attach(d->msgIoSource, d->mainCtxt);
    }
    else if (channel == d->cmdIoChannel) {
        if (condition & G_IO_HUP) {
            g_message("YAP: Server disconnected command socket");
            closeMsgSocket();
            closeCmdSocket();
            serverDisconnected();
        }
    }
    else if (channel == d->msgIoChannel) {

        char pktHeader[4] = { 0, 0, 0, 0 };
        uint16_t pktLen = 0;
        char * ppp = 0;

        // We either got a message or a server disconnect
        if (condition & G_IO_HUP)
            goto Detached;

        // Get the packet header
        if (!readSocket(d->msgSocketFd, pktHeader, 4)) {
            fprintf(stderr, "YAP: Failed to read packet header\n");
            goto Detached;
        }

        ppp = ((char *)&pktHeader[0]);
        pktLen   = *((uint16_t*) ppp);
        pktLen   = bswap_16(pktLen);

        if (pktLen > kMaxMsgLen) {
            fprintf(stderr, "YAP: ERROR packet length too large: %u > %d\n", pktLen, kMaxMsgLen);
            goto Detached;
        }

        // Get the packet data
        if (!readSocket(d->msgSocketFd, (char*) d->msgBuffer, pktLen)) {
            fprintf(stderr, "YAP: Failed to read packet data of length: %d\n", pktLen);
            goto Detached;
        }

        d->msgPacket->reset();
        d->msgPacket->setReadTotalLength(pktLen);

        handleAsyncMessage(d->msgPacket);

        d->msgPacket->reset();
        d->msgPacket->setReadTotalLength(0);

        return;

    Detached:

        serverDisconnected();
        closeMsgSocket();
        closeCmdSocket();
    }
}
예제 #5
0
파일: ftp.c 프로젝트: maplefish/MICO
// ======= FTP thread handler =========
static void _thread_ftp(void*inContext)
{
  (void)inContext;

  fd_set readset, wrset;
  struct timeval_t t_val;
  int k;
  uint32_t timeout = 0;
  uint8_t recv_tmo = 0;

  t_val.tv_sec = 0;
  t_val.tv_usec = 5000;

  timeout = mico_get_time();
  ftp_log("\r\n[FTP trd] FTP THREAD STARTED\r\n");
  
  // *** First we have to get IP address and connect the cmd socket
  char pIPstr[16]={0};
  int err;
  k = 3;
  do {
    err = gethostbyname((char *)pDomain4Dns, (uint8_t *)pIPstr, 16);
    if (err != kNoErr) {
      k--;
      mico_thread_msleep(50);
    }
  }while ((err != kNoErr) && (k > 0));
  
  if ((err == kNoErr) && (ftpCmdSocket != NULL)) {
    ftpCmdSocket->addr.s_ip = inet_addr(pIPstr);
    ftpCmdSocket->clientFlag = NO_ACTION;

    free(pDomain4Dns);
    pDomain4Dns=NULL;

    // Connect socket!
    char ip[17];
    memset(ip, 0x00, 17);
    inet_ntoa(ip, ftpCmdSocket->addr.s_ip);
    ftp_log("[FTP cmd] Got IP: %s, connecting...\r\n", ip);

    struct sockaddr_t *paddr = &(ftpCmdSocket->addr);
    int slen = sizeof(ftpCmdSocket->addr);
    // _micoNotify will be called if connected
    connect(ftpCmdSocket->socket, paddr, slen);
  }
  else {
    ftp_log("[FTP dns] Get IP error\r\n");
    goto terminate;
  }

  if (recvBuf == NULL) {
    recvBuf = malloc(MAX_RECV_LEN+4);
    memset(recvBuf, 0, MAX_RECV_LEN+4);
  }
  recvLen = 0;

  // ===========================================================================
  // Main Thread loop
  while (1) {
    mico_thread_msleep(5);
        
    if (ftpCmdSocket == NULL) goto terminate;

    if ( ((mico_get_time() - timeout) > MAX_FTP_TIMEOUT) ||
         (((mico_get_time() - timeout) > 8000) && (!(status & FTP_LOGGED))) ) {
      // ** TIMEOUT **
      ftp_log("[FTP trd] Timeout\r\n");
      timeout = mico_get_time();
      
      if ((status & FTP_LOGGED))
        ftpCmdSocket->clientFlag = REQ_ACTION_QUIT;
      else
        ftpCmdSocket->clientFlag = REQ_ACTION_DISCONNECT;
    }

    // ========== stage #1, Check cmd socket action requests ===================
    
    //REQ_ACTION_DISCONNECT
    if (ftpCmdSocket->clientFlag == REQ_ACTION_DISCONNECT) {
      ftpCmdSocket->clientFlag = NO_ACTION;
      
      closeDataSocket();
      
      ftp_log("[FTP cmd] Socket disconnected\r\n");
      if (ftpCmdSocket->disconnect_cb != LUA_NOREF) {
        queue_msg_t msg;
        msg.L = gL;
        msg.source = onFTP;
        msg.para1 = 0;
        msg.para2 = ftpCmdSocket->disconnect_cb;
        mico_rtos_push_to_queue( &os_queue, &msg, 0);
      }
      closeCmdSocket(0);
      continue;
    }
    //REQ_ACTION_QUIT
    if (ftpCmdSocket->clientFlag == REQ_ACTION_QUIT) {
      if ((status & FTP_LOGGED)) {
        ftpCmdSocket->clientFlag = NO_ACTION;
        ftp_log("[FTP cmd] Quit command\r\n");
        if (_send("QUIT\r\n", 6) <= 0) {
          ftpCmdSocket->clientFlag = REQ_ACTION_DISCONNECT;
        }
      }
      else ftpCmdSocket->clientFlag = REQ_ACTION_DISCONNECT;
      continue;
    }

    if (!(status & FTP_CONNECTED)) continue;
    //--------------------------------------

    //REQ_ACTION_LIST, REQ_ACTION_RECV, REQ_ACTION_SEND
    else if ((ftpCmdSocket->clientFlag == REQ_ACTION_LIST) ||
             (ftpCmdSocket->clientFlag == REQ_ACTION_RECV) ||
             (ftpCmdSocket->clientFlag == REQ_ACTION_SEND)) {
      ftpCmdSocket->clientLastFlag = ftpCmdSocket->clientFlag;
      ftpCmdSocket->clientFlag = NO_ACTION;

      _send("PASV\r\n", 6);
    }
    //REQ_ACTION_DOLIST
    else if (ftpCmdSocket->clientFlag == REQ_ACTION_DOLIST) {
      ftpCmdSocket->clientFlag = NO_ACTION;

      int res;
      if (ftpfile != NULL) {
        char tmps[100];
        if (list_type == 1) sprintf(tmps,"NLST %s\r\n", ftpfile);
        else sprintf(tmps,"LIST %s\r\n", ftpfile);
        res = _send(&tmps[0], strlen(ftpfile)+7);
        free(ftpfile);
        ftpfile = NULL;
      }
      else {
        if (list_type == 1) res = _send("NLST\r\n", 6);
        else res = _send("LIST\r\n", 6);
      }
      if (res > 0) status |= FTP_LISTING;
      else {
        ftp_log("[FTP cmd] LIST command failed.\r\n");
      }
    }
    //REQ_ACTION_DORECV
    else if (ftpCmdSocket->clientFlag == REQ_ACTION_DORECV) {
      ftpCmdSocket->clientFlag = NO_ACTION;

      char tmps[100];
      sprintf(tmps,"RETR %s\r\n", ftpfile);
      int res = _send(&tmps[0], strlen(ftpfile)+7);
      if (res > 0) {
        status |= FTP_RECEIVING;
        file_status = 0;
      }
      else {
        ftp_log("[FTP cmd] RETR command failed.\r\n");
        file_status = -4;
      }
    }
    //REQ_ACTION_DOSEND
    else if (ftpCmdSocket->clientFlag == REQ_ACTION_DOSEND) {
      ftpCmdSocket->clientFlag = NO_ACTION;

      char tmps[100];
      if ((send_type & SEND_APPEND)) sprintf(tmps,"APPE %s\r\n", ftpfile);
      else sprintf(tmps,"STOR %s\r\n", ftpfile);
      int res = _send(&tmps[0], strlen(ftpfile)+7);
      if (res > 0) {
        file_status = 0;
      }
      else {
        ftp_log("[FTP cmd] STOR/APPE command failed.\r\n");
        file_status = -4;
      }
    }
    //REQ_ACTION_CHDIR
    else if (ftpCmdSocket->clientFlag == REQ_ACTION_CHDIR) {
      ftpCmdSocket->clientFlag = NO_ACTION;

      if (ftpfile != NULL) {
        char tmps[100];
        sprintf(tmps,"CWD %s\r\n", ftpfile);
        _send(&tmps[0], strlen(ftpfile)+6);
        free(ftpfile);
        ftpfile = NULL;
      }
      else {
        _send("PWD\r\n", 5);
      }
    }
    //REQ_ACTION_LOGGED
    else if (ftpCmdSocket->clientFlag == REQ_ACTION_LOGGED) {
      ftpCmdSocket->clientFlag=NO_ACTION;
      if (ftpCmdSocket->logon_cb != LUA_NOREF) {
        queue_msg_t msg;
        msg.L = gL;
        msg.source = onFTP;
        msg.para1 = 1;
        msg.para3 = NULL;
        msg.para2 = ftpCmdSocket->logon_cb;
        mico_rtos_push_to_queue( &os_queue, &msg, 0);
      }
    }
    //REQ_ACTION_LIST_RECEIVED
    else if (ftpCmdSocket->clientFlag == REQ_ACTION_LIST_RECEIVED) {
      ftpCmdSocket->clientFlag=NO_ACTION;
      if (ftpCmdSocket->list_cb != LUA_NOREF) {
        queue_msg_t msg;
        msg.L = gL;
        msg.source = onFTP;
        msg.para1 = recvDataLen;
        msg.para2 = ftpCmdSocket->list_cb;
        msg.para3 = (uint8_t*)malloc(recvDataLen+4);
        if (msg.para3 != NULL) memcpy((char*)msg.para3, recvDataBuf, recvDataLen);

        mico_rtos_push_to_queue( &os_queue, &msg, 0);
      }
    }
    //REQ_ACTION_RECEIVED
    else if (ftpCmdSocket->clientFlag == REQ_ACTION_RECEIVED) {
      ftpCmdSocket->clientFlag=NO_ACTION;
      if (ftpCmdSocket->received_cb != LUA_NOREF) {
        queue_msg_t msg;
        msg.L = gL;
        msg.source = onFTP;
        msg.para1 = file_status;
        msg.para3 = NULL;
        if (recv_type == RECV_TOSTRING) {
          msg.para3 = (uint8_t*)malloc(recvDataLen+4);
          if (msg.para3 != NULL) memcpy((char*)msg.para3, recvDataBuf, recvDataLen);
        }
        msg.para2 = ftpCmdSocket->received_cb;

        mico_rtos_push_to_queue( &os_queue, &msg, 0);
      }
    }
    //REQ_ACTION_SENT
    else if (ftpCmdSocket->clientFlag == REQ_ACTION_SENT) {
      ftpCmdSocket->clientFlag=NO_ACTION;
      if (ftpCmdSocket->sent_cb != LUA_NOREF) {
        queue_msg_t msg;
        msg.L = gL;
        msg.source = onFTP;
        msg.para1 = file_status;
        msg.para3 = NULL;
        msg.para2 = ftpCmdSocket->sent_cb;

        mico_rtos_push_to_queue( &os_queue, &msg, 0);
      }
    }

    // ========== stage 2, check data send =====================================
    if ((ftpDataSocket != NULL) && ((status & FTP_SENDING))) {
      FD_ZERO(&wrset);
      FD_SET(ftpDataSocket->socket, &wrset);
      // check socket state
      select(ftpDataSocket->socket+1, NULL, &wrset, NULL, &t_val);
      
      if (FD_ISSET(ftpDataSocket->socket, &wrset)) {
        int err;
        if ((send_type & SEND_STRING)) err = _sendString();
        else err = _sendFile();
        if (err != 0) {
          closeDataSocket();
          // close file;
          if (file_fd != FILE_NOT_OPENED) {
            SPIFFS_close(&fs,file_fd);
            file_fd = FILE_NOT_OPENED;
            ftp_log("\r\n[FTP dta] Data file closed\r\n");
          }
          data_done = 1;
          status &= ~FTP_SENDING;
          ftpCmdSocket->clientFlag = REQ_ACTION_SENT;
        }
        continue;
      }
    }

    // ========== stage 3, check receive&disconnect ============================
    FD_ZERO(&readset);
    // ** select sockets to monitor for receive or disconnect
    int maxfd = ftpCmdSocket->socket;
    FD_SET(ftpCmdSocket->socket, &readset);
    if ( (ftpDataSocket != NULL) && ((status & FTP_DATACONNECTED)) ) {
      if (ftpDataSocket->socket > maxfd) maxfd = ftpDataSocket->socket;
      FD_SET(ftpDataSocket->socket, &readset);
    }
    // ** check sockets state
    select(maxfd+1, &readset, NULL, NULL, &t_val);

    // ** Check COMMAND socket
    if (FD_ISSET(ftpCmdSocket->socket, &readset)) {
      // read received data to buffer
      int rcv_len;
      if ((MAX_RECV_LEN-recvLen) > 1) {
        rcv_len = recv(ftpCmdSocket->socket, (recvBuf+recvLen), MAX_RECV_LEN-recvLen-1, 0);
      }
      else { // buffer full, ignore received bytes
        char tmpb[16];
        rcv_len = recv(ftpCmdSocket->socket, &tmpb[0], 16, 0);
      }
      
      if (rcv_len <= 0) { // failed
        ftp_log("\r\n[FTP cmd] Disconnect!\r\n");
        ftpCmdSocket->clientFlag = REQ_ACTION_DISCONNECT;
        continue;
      }
      
      recvLen += rcv_len;
      _checkCmdResponse(); // leave only the last line in buffer
      timeout = mico_get_time();
      recv_tmo = 0;
    }

    // ** Check DATA socket
    if ( (ftpDataSocket != NULL) && ((status & FTP_DATACONNECTED)) ) {
      if (FD_ISSET(ftpDataSocket->socket, &readset)) {
        // read received data to buffer
        int rcv_len = recv(ftpDataSocket->socket, (recvDataBuf+recvDataLen), max_recv_datalen-recvDataLen-1, 0);

        if (rcv_len <= 0) { // failed
          if (!(status & (FTP_RECEIVING | FTP_LISTING))) {
            ftp_log("\r\n[FTP dta] Disconnect!\r\n");
            closeDataSocket();
            file_status = -9;
            data_done = 1;
          }
          continue;
        }
        else {
          if ((status & FTP_RECEIVING) && (recv_type == RECV_TOFILE)) {
            // === write received data to file ===
            recvDataLen = rcv_len;
            _saveData(0);
            recvDataLen = 0;
          }
          else if ((status & FTP_LISTING) || ((status & FTP_RECEIVING) && (recv_type == RECV_TOSTRING))) {
            if ((recvDataLen + rcv_len) < (max_recv_datalen-16)) recvDataLen += rcv_len;
            else recvDataLen = max_recv_datalen-16;
            *(recvDataBuf + recvDataLen) = '\0';
          }
        }
        timeout = mico_get_time();
        recv_tmo = 0;
      }
    }

    // ===== nothing received ==================================================
    recv_tmo++;
    if (recv_tmo < 10) continue;
    
    recv_tmo = 0;

    // == Check if something was received from Command socket ==
    if (recvLen > 0) {
      // == Analize response ===
      response();
      recvLen = 0;
      memset(recvBuf, 0, MAX_RECV_LEN);
    }

    // == Check if Data socket was receiving ==
    if ((status & (FTP_RECEIVING | FTP_LISTING))) {
      // Finish all operattions on data socket
      if ((status & FTP_RECEIVING) && (recv_type == RECV_TOFILE)) {
        _saveData(1);
        recvDataLen = 0;
      }
      else {
        if ((status & FTP_RECEIVING) && (recv_type == RECV_TOSTRING)) {
          file_status = recvDataLen;
        }
        ftp_log("[FTP dta] Data received (%d)\r\n", recvDataLen);
      }
      
      if ((status & FTP_LISTING)) {
        status &= ~FTP_LISTING;
        ftpCmdSocket->clientFlag = REQ_ACTION_LIST_RECEIVED;
      }
      if ((status & FTP_RECEIVING)) {
        status &= ~FTP_RECEIVING;
        ftpCmdSocket->clientFlag = REQ_ACTION_RECEIVED;
      }

      // Close data socket
      closeDataSocket();
      data_done = 1;
    }
  } // while

terminate:
  _ftp_deinit(0);
  ftp_log("\r\n[FTP trd] FTP THREAD TERMINATED\r\n");
  ftp_thread_is_started = false;
  mico_rtos_delete_thread( NULL );
}