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

📄 ftp-server-code.txt

📁 实现简单文件上传
💻 TXT
📖 第 1 页 / 共 3 页
字号:
  }   
  //not   root   dir,   we   can   convert   it   to   dos   driver   
  else     
  {   
  BOOL   bNotFound   =   FALSE;   
  BOOL   bIsDir   =   FALSE;   
  char   dosWildCard[MAX_PATH];   
  char   dosFullPath[MAX_PATH];   
  if(   unixFullPath[0]   ==   '/'   &&   strlen(unixFullPath)==2   )   
  {   
  bIsDir   =   TRUE;   
  sprintf(dosWildCard,   "%c:\\*.*",   unixFullPath[1]);   
  }   
  else   if(   UnixPathToDosPath(unixFullPath,   dosFullPath)   
  &&   ExistFileOrDirectory(dosFullPath)   )   
  {   
  if(   ExistFile(dosFullPath)   )   //it's   a   file   
  strcpy(dosWildCard,   dosFullPath);   
  else   //it's   a   directory   
  {   
  bIsDir   =   TRUE;   
  sprintf(dosWildCard,   "%s\\*.*",   dosFullPath);   
  }   
  }   
  else   
  bNotFound   =   TRUE;   
    
  if(   !bNotFound   )   
  {   
  WIN32_FIND_DATA   findData;   
  HANDLE   hFind   =   FindFirstFile(dosWildCard,   &findData);   
  if(   hFind   !=   INVALID_HANDLE_VALUE   )   
  {   
  do   
  {   
  //preparation   
  const   static   char*   monthStr[12]   =   {"Jan",   "Feb",   "Mar",   "Apr",   "May",   "Jun",   "Jul",   "Aug",   "Sep",   "Oct",   "Nov",   "Dec"};   
  char   item[MAX_PATH   +   100];   
  FILETIME   lft;   
  SYSTEMTIME   lt;   
  FileTimeToLocalFileTime(&findData.ftLastWriteTime,   &lft);   
  FileTimeToSystemTime(&lft,   &lt);   
    
  if(   bNameList   )   
  sprintf(item,   "%s\r\n",   findData.cFileName);   
  else   
  {   
  if(   (findData.dwFileAttributes   &   FILE_ATTRIBUTE_DIRECTORY)   ==   FILE_ATTRIBUTE_DIRECTORY   )   
  {   
  sprintf(item,   "drwxrwxrwx         1   owner         group   %12d   %s   %02d   %2d:%02d   %s\r\n",     
  findData.nFileSizeLow,   monthStr[lt.wMonth-1],   lt.wDay,   lt.wHour,   lt.wMinute,   findData.cFileName);   
  }   
  else   
  {   
  sprintf(item,   "-rwxrwxrwx         1   owner         group   %12d   %s   %02d   %2d:%02d   %s\r\n",     
  findData.nFileSizeLow,   monthStr[lt.wMonth-1],   lt.wDay,   lt.wHour,   lt.wMinute,   findData.cFileName);   
  }   
  }   
  fwrite(item,   1,   strlen(item),   fp);   
  }while(   FindNextFile(hFind,   &findData)   );   
  FindClose(hFind);   
  }   
  }   
  return   !bNotFound;   
  }   
  }   
    
    
  class   CFtpServer   
  {   
  public:   
  CFtpServer(SOCKET   sockCtrl,   BOOL*   pbShouldExit);   
  ~CFtpServer(){};   
  void   Run();   
  BOOL   OnCommand(const   char*   command);   
  private:   
  void   CFtpServer::ClearDataSockInfo();   
  SOCKET   CFtpServer::GetDataSocket();   
  private:   
  FTP_CONTROL_BLOCK   m_block;   
    
  SOCKET   m_sockDataListen;   
  enum   DATA_SOCKET_STATUS{DATA_SOCK_NONE,   DATA_SOCK_PORT,   DATA_SOCK_PASV}   m_dataSockStatus;   
  sockaddr_in   m_clientAddr;   
    
  SOCKET   m_sockCtrl;   
  BOOL   *m_pbShouldExit;   
  CCollectLine   m_lineMaker;   
  enum   FTP_SERVER_STATUS   {   SERVER_NEED_USER,   SERVER_NEED_PASS,   SERVER_NEED_ANY,   
  SERVER_NEED_RNTO}   m_status;   
  char   m_szUnixWorkDir[MAX_PATH];   
  char   m_szUnixRnfrName[MAX_PATH];   
  };   
    
  CFtpServer::CFtpServer(SOCKET   sockCtrl,   BOOL   *pbShouldExit)   
  :m_sockCtrl(sockCtrl),   m_pbShouldExit(pbShouldExit),   m_lineMaker(5000),   m_status(SERVER_NEED_USER)   
  {   
  //init   m_block   
  m_block.sockCtrl   =   sockCtrl;   
  m_block.sockData   =   INVALID_SOCKET;   
  strcpy(m_block.filename,   "");   
  m_block.translateType   =   TYPE_RETR;   
  m_block.dwStartPos   =   0;   
  m_block.bDeleteFileAfterCompletion   =   TRUE;   
  m_block.bAbort   =   FALSE;   
  m_block.bThreadExited   =   TRUE;   
    
  //init   m_dataSockStatus   
  m_sockDataListen   =   INVALID_SOCKET;   
  m_dataSockStatus   =   DATA_SOCK_NONE;   
  memset(&m_clientAddr,   0,   sizeof(m_clientAddr));   
    
  //init   work   directory   
  strcpy(m_szUnixWorkDir,   "/");   
  memset(m_szUnixRnfrName,   0,   sizeof(m_szUnixRnfrName));   
  }   
    
  void   CFtpServer::ClearDataSockInfo()   
  {   
  if(   m_block.sockData   !=   INVALID_SOCKET   )   
  {   
  shutdown(m_block.sockData,   SD_BOTH);   
  closesocket(m_block.sockData);   
  m_block.sockData   =   INVALID_SOCKET;   
  }   
    
  memset(&m_clientAddr,   0,   sizeof(m_clientAddr));   
  if(   m_sockDataListen   !=   INVALID_SOCKET   )   
  {   
  closesocket(m_sockDataListen);   
  m_sockDataListen   =   INVALID_SOCKET;   
  }   
    
  m_dataSockStatus   =   DATA_SOCK_NONE;   
  }   
    
  SOCKET   CFtpServer::GetDataSocket()   
  {   
  char   szError[MAX_SOCKET_ERROR_STRING];   
  if(   m_dataSockStatus   ==   DATA_SOCK_PORT   )   
  {   
  SOCKET   sockData   =   socket(AF_INET,   SOCK_STREAM,   0);   
  if(   sockData   !=   INVALID_SOCKET   )   
  {   
  if(   connect(sockData,   (sockaddr*)&m_clientAddr,   sizeof(m_clientAddr))   ==   0   )   
  return   sockData;   
  debug_printf("GetDataSocket():connect():error   code   %d\r\n",   WSAGetLastError());   
  closesocket(sockData);   
  }   
  m_dataSockStatus   =   DATA_SOCK_NONE;   
  return   INVALID_SOCKET;   
  }   
  else   if(   m_dataSockStatus   ==   DATA_SOCK_PASV   )   
  {   
  if(   m_sockDataListen   !=   INVALID_SOCKET   )   
  {   
  SOCKET   sockData   =   BlockingAccept(m_sockDataListen,   m_pbShouldExit,   szError);   
  closesocket(m_sockDataListen);   
  m_sockDataListen   =   INVALID_SOCKET;   
  m_dataSockStatus   =   DATA_SOCK_NONE;   
  return   sockData;   
  }   
  else   
  return   INVALID_SOCKET;   
  }   
  else   
  return   INVALID_SOCKET;   
  }   
    
  BOOL   CFtpServer::OnCommand(const   char*   command)   
  {   
  debug_printf("%s\r\n",   command);   
    
  char   line[FTP_MAX_LINE_BUFFER];   
  char   szError[MAX_SOCKET_ERROR_STRING];   
  BOOL   bReplyHasSend   =   FALSE;   
  BOOL   bShouldExit   =   FALSE;   
  BOOL   bCommandNotSupport   =   FALSE;   
    
  sprintf(line,   "500   command   not   supported\r\n");   
  if(   m_status   ==   SERVER_NEED_ANY   )   
  {   
  //access   control   commands   
  if(   memicmp(command,   "CWD",   3)   ==   0   )   
  {   
  char   param[MAX_PATH];   
  BOOL   bFailed   =   TRUE;   
  for(int   i=3;   '   '   ==   command[i];   i++)NULL;   //skip   white   space   
  strcpy(param,   command+i);   
  if(   strlen(param)>=2   &&   param[strlen(param)-1]   ==   '/'   )   
  param[strlen(param)-1]   =   0;   
  char   unixFullPath[MAX_PATH],   dosFullPath[MAX_PATH];   
  if(   GetFullUnixPath(param,   m_szUnixWorkDir,   unixFullPath)   )   
  {   
  int   length   =   strlen(unixFullPath);   
  if(   unixFullPath[0]   ==   '/'   &&   (   length   ==   1   ||   length   ==   2   )   )   
  {   
  bFailed   =   FALSE;   
  sprintf(line,   "250   work   dir   changed   to   %s\r\n",   unixFullPath);   
  }   
  else   
  {   
  if(   UnixPathToDosPath(   unixFullPath,   dosFullPath)     
  &&   ExistDirectory(dosFullPath)   )   
  {   
  bFailed   =   FALSE;   
  sprintf(line,   "250   work   dir   changed   to   %s\r\n",   unixFullPath);   
  }   
  }   
  }   
  if(   bFailed   )   
  sprintf(line,   "550   CWD   (   %s   )   failed\r\n",   param);   
  else   
  strcpy(m_szUnixWorkDir,   unixFullPath);   
  }   
  else   if(   memicmp(command,   "CDUP",   4)   ==   0   )   
  {   
  char   parentPath[MAX_PATH];   
  if(   GetParentUnixPath(m_szUnixWorkDir,   parentPath)   )   
  {   
  strcpy(m_szUnixWorkDir,   parentPath);   
  sprintf(line,   "250   work   dir   changed   to   %s\r\n",   m_szUnixWorkDir);   
  }   
  else   
  sprintf(line,   "550   parent   path   cannot   be   found\r\n");   
  }   
  else   if(   memicmp(command,   "REIN",   4)   ==   0   )   
  {   
  m_status   =   SERVER_NEED_USER;   
  sprintf(line,   "220   reintialize   succeed\r\n");   
  }   
  else   if(   memicmp(command,   "QUIT",   4)   ==   0   )   
  {   
  sprintf(line,   "221\r\n");   
  bShouldExit   =   TRUE;   
  }   
  //parameter   commands   
  else   if(   memicmp(command,   "PORT",   4)   ==   0   )   
  {   
  ClearDataSockInfo();   
    
  int   b1,b2,b3,b4,p1,p2;   
  int   cursor   =   4;   
  BOOL   bGotAddr   =   FALSE;   
  while(   command[cursor]   !=   0   )   
  {   
  if(   sscanf(command   +   cursor,   "%d,%d,%d,%d,%d,%d",   &b1,   &b2,   &b3,   &b4,   &p1,   &p2)   ==   6   )   
  {   
  bGotAddr   =   TRUE;   
  m_clientAddr.sin_family   =   AF_INET;   
  m_clientAddr.sin_port   =   htons((unsigned   short)(p1   *   256   +   p2));   
  m_clientAddr.sin_addr.S_un.S_un_b.s_b1   =   b1;   
  m_clientAddr.sin_addr.S_un.S_un_b.s_b2   =   b2;   
  m_clientAddr.sin_addr.S_un.S_un_b.s_b3   =   b3;   
  m_clientAddr.sin_addr.S_un.S_un_b.s_b4   =   b4;   
  m_dataSockStatus   =   DATA_SOCK_PORT;   
  sprintf(line,   "200   port   (%d,%d,%d,%d,%d,%d)   command   successful\r\n",   b1,   b2,   b3,   b4,   p1,   p2);   
  break;   
  }   
  else   
  cursor++;   
  }   
  if(   !bGotAddr   )   
  sprintf(line,   "500   cannot   extract   address   and   port   info   from   %s\r\n",   command);   
  }   
  else   if(   memicmp(command,   "PASV",   4)   ==   0   )   
  {   
  ClearDataSockInfo();   
  BOOL   bPasvSucceed   =   FALSE;   
  sockaddr_in   host;   
  int   namelen   =   sizeof(host);   
  getsockname(m_sockCtrl,   (sockaddr*)&host,   &namelen);   
  m_sockDataListen   =   socket(AF_INET,   SOCK_STREAM,   0);   
  if(   m_sockDataListen   !=   INVALID_SOCKET   )   
  {   
  //select   port   by   socket   implement   
  host.sin_port   =   0;   
  if(   bind(m_sockDataListen,   (sockaddr*)&host,   namelen)   !=   SOCKET_ERROR   )   
  {   
  if(   getsockname(m_sockDataListen,   (sockaddr*)&host,   &namelen)   !=   SOCKET_ERROR     
  &&   listen(m_sockDataListen,   SOMAXCONN)   !=   SOCKET_ERROR   )   
  {   
  m_dataSockStatus   =   DATA_SOCK_PASV;   
  bPasvSucceed   =   TRUE;   
  sprintf(line,   "227   Entering   Passive   Mode   (%d,%d,%d,%d,%d,%d)\r\n",     
  host.sin_addr.S_un.S_un_b.s_b1,   
  host.sin_addr.S_un.S_un_b.s_b2,   
  host.sin_addr.S_un.S_un_b.s_b3,   
  host.sin_addr.S_un.S_un_b.s_b4,   
  ntohs(host.sin_port)   /   0x100,   
  ntohs(host.sin_port)   %   0x100   );   
  }   
  }   
  }   
  if(   !bPasvSucceed   )   
  {   
  closesocket(m_sockDataListen);   
  m_sockDataListen   =   INVALID_SOCKET;   
  sprintf(line,   "421   cannot   open   a   listen   socket\r\n");   
  }   
  }   
  else   if(   memicmp(command,   "TYPE",   4)   ==   0   )   
  {   
  sprintf(line,   "200   %s   ok\r\n",   command);   
  }   
  else   if(   memicmp(command,   "STRU",   4)   ==   0   )   
  {   
  sprintf(line,   "200   %s   ok\r\n",   command);   
  }   
  else   if(   memicmp(command,   "MODE",   4)   ==   0   )   
  {   
  sprintf(line,   "200   %s   ok\r\n",   command);   
  }   
  //service   commands   
  else   if(   memicmp(command,   "RETR",   4)   ==   0     
  ||   memicmp(command,   "STOR",   4)   ==   0     
  ||     memicmp(command,   "APPE",   4)   ==   0   )   
  {   
  BOOL   bShouldStartTransfer   =   FALSE;   
  for(int   i=4;   '   '   ==   command[i];   i++)NULL;   //skip   white   space   
  char   unixFullPath[MAX_PATH],   dosFullPath[MAX_PATH];   

⌨️ 快捷键说明

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