⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpd.c

📁 ATmega103、ATmega128做的开发板web server源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************
* ftpd.c: File Transfer Protocol
* 
* Copyright (c) 2001 Atmel Corporation.
* All Rights Reserved.
*
* You are autorized to use, copy and distribute this software only at 
* a single site (the term "site" meaning a single company location). 
* This copyright notice must be included in any copy, modification 
* or portion of this software merged into another program.
* 
* This software is licenced solely for use with Atmel AVR micro 
* controller family. The software may not be modified to execute on 
* any other microcontroller architectures
*
* This software is provided "as is"; Without warranties either express
* or implied, including any warranty regarding merchantability, 
* fitness for a particular purpose or noninfringement. 
*
* In no event shall Atmel or its suppliers be liable for any special, 
* indirect,incidential or concequential damages resulting from the 
* use or inability to use this software.
*
* Revision history:
*
* January 17, 2001:   Version 1.0   Created by JB
* July 13, 2001		  Version 1.2     JB
* 					- Changed to IAR compiler V2.25
*					- Renamed flash file functions to avoid conflict with 
*					  standard file I/O names	
*					- Bug fixes in HTTP
*					- Speed optimization in TCP 
*
*
*******************************************************************/
#include "comp_a90.h"
#include "tcp.h"
#include "ffile.h"
#include "ftpd.h"
#include "config.h"

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <pgmspace.h>

extern unsigned int ticker;

FTPCONNECTION ftpconnection;                //Only one ftp connection is allowed.

/*constant strings, plased in flash*/
flash char FTP_WELCOME_MSG[]      ="220-Welcome to AVR Embedded web server.\r\n220 Please log in.\r\n";
flash char FTP_MAX_USERS[]        ="421 Maximum users is 1.\r\n";
flash char FTP_PASS_REQUEST[]     ="331 Password required for ";
flash char FTP_LOGGED_IN[]        ="230 User Logged in.\r\n";
flash char FTP_INCORRECT_LOGIN[]  ="530 Login incorrect.\r\n";
flash char FTP_GOODBYE[]          ="221 Goodbye.\r\n";
flash char FTP_BIN[]              ="200 Type set to I.\r\n";
flash char FTP_ASCII[]            ="200 Type set to A.\r\n";
flash char FTP_ERROR[]            ="500 command not understood.\r\n";
flash char FTP_PORT[]             ="200 PORT command successful.\r\n";
flash char FTP_PASS[]             ="257 \"/\" is current directory.\r\n";
flash char FTP_ACONN[]            ="150 ASCII data connection.\r\n";
flash char FTP_BCONN[]            ="150 Binary data connection.\r\n";
flash char FTP_ERR_DATA[]         ="425 Unable to open data connection.\r\n";
flash char FTP_ERR_DIR[]          ="500 Unable to read directory.\r\n";
flash char FTP_ERR_FILE[]         ="500 Unable to open file.\r\n";
flash char FTP_DELE[]             ="250 DELE command successful.\r\n";
flash char FTP_COMPLETE[]         ="226 Transfer complete.\r\n";

void ftpd(void)
{
  char inBuffer[FTP_BUFFERSIZE], outBuffer[FTP_BUFFERSIZE], tmp[14];
  char *ptr;
  unsigned int z,x,j;
  char user[10];
  char pass[10];
  SOCKET *socket;
  FTPCONNECTION *ftp;
  
  refresh();                                // Remove aborted connections.
  if (!TCPlistenPort(21, 0))                // Check if ftp has started to listen to port 21.
  {
    TCPpopen(21, 0);                        // If not, initialize and start listening.
    ftpconnection.state = ULOCKED;
    ftpconnection.datastate = UNUSED;
    ftpconnection.type =ASCII;
    ftpconnection.hisPort = 0;
    ftpconnection.hisIP0 = 0;
    ftpconnection.hisIP1 = 0;
    ftpconnection.dataPort = 0;
    ftpconnection.dataIP0 = 0;
    ftpconnection.dataIP1 = 0;
    ftpconnection.file = NULL;
    ftpconnection.dir = NULL;
    ftpconnection.lastAction = ticker;
    ftpconnection.username[0] = '\0';
    ftpconnection.password[0] = '\0';
  }
  ftp = &ftpconnection;
  socket = TCPfindSockets(21);                // Get a linked list of sockets on port 21.
  while (socket)                              // For every socket on port 21....
  {
    if ( !((socket->hisPort == ftpconnection.hisPort) && (socket->hisIP0 ==  ftpconnection.hisIP0) && 
         (socket->hisIP1 ==  ftpconnection.hisIP1)) )  //Check if this connection is new.
    {
      if ( (ftpconnection.state == ULOCKED) && (socket->state == OPEN) ) // If this is a new connection, state is open
      {	                                                                 // and there is no already established connection.
        ftp->state = USER;                                                
        ftp->hisIP0 = socket->hisIP0;
        ftp->hisIP1 = socket->hisIP1;
        ftp->hisPort = socket->hisPort;
        ftp->dataPort = 0;
        ftp->dataIP0 = 0;
        ftp->dataIP1 = 0;
        ftp->lastAction = ticker;
        ftp->controlSocket = socket;
    	TCPsend_P(socket, sizeof(FTP_WELCOME_MSG), FTP_WELCOME_MSG);    // Send a welcome message and wait for username.
      }
      else if (socket->state == OPEN) 
      {
        TCPsend_P(socket, sizeof(FTP_MAX_USERS), FTP_MAX_USERS);
        TCPclose(socket);
      }
    }
    else if (socket->state == HALF_CLOSED)
    {
      TCPclose(socket);
    }
    else if (TCPsize(socket) && (ftpconnection.state != DATA) && (socket->state == OPEN) ) // If this is an established connection
    {                                                                             // and there is new control data.    
      j=TCPreadln(socket, FTP_BUFFERSIZE, inBuffer, 1);           // Read one line
      if ( (inBuffer[j-1] == '\r') || (inBuffer[j-1] == '\n') )   // Check if EOL is present
      {
        ftp->lastAction = ticker;
        TCPbufferFlush(socket);             // remove from tcp buffer
        inBuffer[j] = '\0';                 // null terminate string.
        ptr = strtok(inBuffer, " \r\n");    // get command
        for (x=0;x<strlen(ptr);x++)         // convert to upper case.
        {
          ptr[x] = toupper(ptr[x]);
        }
        switch(ftp->state)
        {
        case(USER):
          if (!strcmp(ptr, "USER"))         // If state is user and command is user.
          {
            ptr = strtok(NULL, " \r\n");    // save username and ask for password.
            TCPsend_P(socket, sizeof(FTP_PASS_REQUEST), FTP_PASS_REQUEST);
            TCPsend(socket, strlen(ptr), ptr);
            TCPsend(socket, 3, ".\r\n");
            strncpy(ftp->username, ptr, 8);
            ftp->state = PASS;
          }
          break;
          
        case(PASS):
        
          if (!strcmp(ptr, "PASS"))         //If command is password, check if password is correct.
          {
            ptr = strtok(NULL, " \r\n");
            strncpy(ftp->password, ptr, 8);
            
            if(!(getOption("FTP\0","Password\0",pass) && getOption("FTP\0","Username\0",user)))
            {
              /*error while reading from server.ini, use default values*/
              strncpy(user,CONFIG_DEFAULT_FTP_USER,8);
              strncpy(pass,CONFIG_DEFAULT_FTP_PASS,8);	    
            }
            if(strcmp(pass,ftp->password) || strcmp(user,ftp->username)) //check if password is correct
                {
                  /*if password is incorrect refuse login*/
                  TCPsend_P(socket, sizeof(FTP_INCORRECT_LOGIN), FTP_INCORRECT_LOGIN);
                  TCPclose(socket);
                  closeFTP(ftp);
            }
            else
            {
              TCPsend_P(socket, sizeof(FTP_LOGGED_IN), FTP_LOGGED_IN);
              ftp->state = IDLE;
            }
          }
          break;
          
        case(IDLE):
        
          if (!strcmp(ptr, "QUIT")){          // Quit connection.
            TCPsend_P(socket, sizeof(FTP_GOODBYE), FTP_GOODBYE);
            TCPclose(socket);
            closeFTP(ftp);
          }
          else if(!strcmp(ptr, "TYPE"))       //Set transmission type.
          {
            ptr = strtok(NULL, " \r\n");
            *ptr = toupper(*ptr);
            if (*ptr == 'A')
            {
              ftp->type = ASCII;
              TCPsend_P(socket, sizeof(FTP_ASCII), FTP_ASCII);
            }
            else if (*ptr == 'I')
            {
              ftp->type = BINARY;
              TCPsend_P(socket, sizeof(FTP_BIN), FTP_BIN);
            }
            else
            {
              TCPsend_P(socket, sizeof(FTP_ERROR), FTP_ERROR);
              TCPclose(socket);
              closeFTP(ftp);
            }
          }
          else if(!strcmp(ptr, "PORT"))       // Get data connection IP address and port number.
          {
            ptr = strtok(NULL, ",");
            if (ptr)
            {
              ftp->dataIP0 = (atoi(ptr) << 8);
              ptr = strtok(NULL, ",");
              if (ptr)
              {
            ftp->dataIP0 |= atoi(ptr);
            ptr = strtok(NULL, ",");
            if(ptr)
            {
              ftp->dataIP1 = (atoi(ptr) << 8);
              ptr = strtok(NULL, ",");
              if(ptr)
              {
                ftp->dataIP1 |= atoi(ptr);
                ptr = strtok(NULL, ",");
                if(ptr)
                {
                  ftp->dataPort = (atoi(ptr) << 8);
                  ptr = strtok(NULL, " \r\n");
                  if(ptr)
                  {
                ftp->dataPort |= atoi(ptr);
                TCPsend_P(socket, sizeof(FTP_PORT), FTP_PORT);
                  }
                }
              }
            }
              }
            }
            if (!ptr)                         // Did not understand port command.
            {
              TCPsend_P(socket, sizeof(FTP_ERROR), FTP_ERROR);
              TCPclose(socket);
              closeFTP(ftp);
            }
          }
          else if (!strcmp(ptr, "PWD"))        //Show working directory.
          {
            TCPsend_P(socket, sizeof(FTP_PASS), FTP_PASS);
          }
          else if (!strcmp(ptr, "LIST") || !strcmp(ptr, "NLST"))  //Show directory listing
          {                                                       //NLST = Short listing, LIST = long listing
            if (ftp->type == ASCII)                               
            {
              TCPsend_P(socket, sizeof(FTP_ACONN), FTP_ACONN);          
            }
            else
            {
              TCPsend_P(socket, sizeof(FTP_BCONN), FTP_BCONN);
            }
            ftp->dataSocket = TCPaopen(ftp->dataPort, ftp->dataIP0, ftp->dataIP1, 20);  //Open data connection
            if (!ftp->dataSocket)
            {
              TCPsend_P(socket, sizeof(FTP_ERR_DATA), FTP_ERR_DATA);
            }
            else
            {
              ftp->dir = opendir();           //Open directory.
              if (ftp->dir)
              {
                ftp->state = DATA;
                if(!strcmp(ptr, "NLST"))
                {
                  ftp->datastate = DIRECTORY; //Send first line of short listing.
                  ptr = readdir(ftp->dir);
                }
                else
                { 
                  ftp->datastate = WDIRECTORY;
                  ptr = readwdir(ftp->dir);   //Send first line of long listing.
                }
                if (ptr)
                {
                  TCPsend(ftp->dataSocket, strlen(ptr), ptr);
                }
                else                          //If something don't work, close connection and directory.
                {
                  TCPclose(ftp->dataSocket);
                  TCPsend_P(socket, sizeof(FTP_ERR_DIR), FTP_ERR_DIR);
                  ftp->state = IDLE;
                  ftp->datastate = UNUSED;
                  ftp->dataPort = 0;
                  ftp->dataIP0 = 0;
                  ftp->dataIP1 = 0;
                  closedir(ftp->dir);
                }
              }
              else
              {
                    TCPsend_P(socket, sizeof(FTP_ERR_DIR), FTP_ERR_DIR);
              }
            }
          }
          else if(!strcmp(ptr, "RETR"))       //User asks for file.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -