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

📄 ftp.c

📁 prozgui是一款Linxu下著名的下载工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** libprozilla - a download accelerator library Copyright (C) 2001 Kalum Somaratna This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA******************************************************************************//* FTP support. *//* $Id: ftp.c,v 1.43 2001/09/23 01:39:15 kalum Exp $ */#include "common.h"#include "prozilla.h"#include "connect.h"#include "misc.h"#include "url.h"#include "netrc.h"#include "debug.h"#include "ftpparse.h"#include "ftp.h"/* #define UNIMPLEMENTED_CMD(a)    ((a == 500) || (a == 502) || (a == 504)) */#define BUFFER_SIZE 2048/****************************************************************************** Return the numeric response of the FTP server by reading the first three characters in the buffer.******************************************************************************/static int ftp_get_return(const char *ftp_buffer){  char code[4];  strncpy(code, ftp_buffer, 3);  code[3] = '\0';  return atoi(code);}/****************************************************************************** ...******************************************************************************/static uerr_t ftp_get_reply(connection_t * connection){  int cont = 0;  int code;  response_line *srl;  /* FIXME Make the line variable dynamically allocated. */  /* Allocate the space in the buffer for the request. */  char szBuffer[BUFFER_SIZE];  char *strtok_saveptr = (char *) alloca(FTP_BUFFER_SIZE);  memset(szBuffer, 0, FTP_BUFFER_SIZE);  if (ftp_get_line(connection, szBuffer) != FTPOK)    return FTPERR;  if (!isdigit(*szBuffer))    return FTPERR;  if (*szBuffer == '\0')    return FTPERR;  code = ftp_get_return(szBuffer);  if (szBuffer[3] == '-')    cont = 1;  else    cont = 0;  (void) strtok_r(szBuffer, "\r\n", &strtok_saveptr);  srl = connection->serv_ret_lines = kmalloc(sizeof(response_line));  srl->line = kstrdup(szBuffer);  srl->next = 0;  /* Add the first line to the struct. */  while (cont)  {    if (ftp_get_line(connection, szBuffer) != FTPOK)      return FTPERR;    /* Server closed the connection. */    if (*szBuffer == '\0')      return FTPERR;    if ((ftp_get_return(szBuffer) == code) && (szBuffer[3] == ' '))      cont = 0;    (void) strtok_r(szBuffer, "\r\n", &strtok_saveptr);    proz_debug(_("Message = %s"), szBuffer);    srl->next = kmalloc(sizeof(response_line));    srl = srl->next;    srl->line = kstrdup(szBuffer);    srl->next = 0;  }  return FTPOK;}/****************************************************************************** ...******************************************************************************/int ftp_check_msg(connection_t * connection, int len){  int ret;  if ((ret = krecv(connection->ctrl_sock, connection->szBuffer, len,		   MSG_PEEK, &connection->ctrl_timeout)) == -1)  {    proz_debug(_("Error checking for FTP data: %s"), strerror(errno));    return ret;  }  return ret;}/****************************************************************************** ...******************************************************************************/int ftp_read_msg(connection_t * connection, int len){  int ret;  if ((ret = krecv(connection->ctrl_sock, connection->szBuffer, len, 0,		   &connection->ctrl_timeout)) == -1)  {    proz_debug(_("Error receiving FTP data: %s"), strerror(errno));    return ret;  }  return ret;}/****************************************************************************** ...******************************************************************************/uerr_t ftp_send_msg(connection_t * connection, const char *format, ...){  longstring command;  va_list args;  va_start(args, format);#ifdef HAVE_VSNPRINTF  vsnprintf(command, sizeof(command) - 1, format, args);  command[sizeof(command) - 1] = '\0';#else  vsprintf(command, format, args);#endif  va_end(args);  proz_debug(_("Sending:  %s"), command);  if ((ksend(connection->ctrl_sock, command, strlen(command), 0,	     &connection->ctrl_timeout)) == -1)  {    proz_debug(_("Error sending FTP data: %s"), strerror(errno));    return WRITEERR;  }  return FTPOK;}/****************************************************************************** ...******************************************************************************/uerr_t ftp_get_line(connection_t * connection, char *line){  int iLen, iBuffLen = 0, ret = 0;  char *szptr = line, ch;  connection->szBuffer = &ch;  while ((iBuffLen < BUFFER_SIZE)	 && ((ret = ftp_check_msg(connection, 1)) > 0))  {    /* Now get the full string. */    iLen = ftp_read_msg(connection, 1);    if (iLen != 1)      return FTPERR;    iBuffLen += iLen;    *szptr = ch;    szptr += iLen;    if (ch == '\n')      break;			/* We have a line -> return. */  }  /* Check for error returned in ftp_check_msg(). */  if (ret == -1)    return FTPERR;  /* FIXME Is this correct? Debug! */  *(szptr + 1) = '\0';  proz_debug(_("Received: %s"), line);  return FTPOK;}/****************************************************************************** ...******************************************************************************/uerr_t ftp_ascii(connection_t * connection){  uerr_t err;  err = ftp_send_msg(connection, "TYPE A\r\n");  if (err != FTPOK)    return err;  err = ftp_get_reply(connection);  if (err != FTPOK)    return err;  if (connection->serv_ret_lines->line[0] != '2')    return FTPUNKNOWNTYPE;  return FTPOK;}/****************************************************************************** ...******************************************************************************/uerr_t ftp_binary(connection_t * connection){  uerr_t err;  err = ftp_send_msg(connection, "TYPE I\r\n");  if (err != FTPOK)    return err;  err = ftp_get_reply(connection);  if (err != FTPOK)    return err;  if (connection->serv_ret_lines->line[0] != '2')    return FTPUNKNOWNTYPE;  return FTPOK;}/****************************************************************************** ...******************************************************************************/uerr_t ftp_port(connection_t * connection, const char *command){  uerr_t err;  err = ftp_send_msg(connection, command);  if (err != FTPOK)    return err;  err = ftp_get_reply(connection);  if (err != FTPOK)    return err;  if (connection->serv_ret_lines->line[0] != '2')    return FTPPORTERR;  return FTPOK;}/****************************************************************************** ...******************************************************************************/uerr_t ftp_list(connection_t * connection, const char *file){  uerr_t err;  err = ftp_send_msg(connection, "LIST %s\r\n", file);  if (err != FTPOK)    return err;  err = ftp_get_reply(connection);  if (err != FTPOK)    return err;  if (connection->serv_ret_lines->line[0] == '5')    return FTPNSFOD;  if (connection->serv_ret_lines->line[0] != '1')    return FTPERR;  return FTPOK;}/****************************************************************************** ...******************************************************************************/uerr_t ftp_retr(connection_t * connection, const char *file){  uerr_t err;  err = ftp_send_msg(connection, "RETR %s\r\n", file);  if (err != FTPOK)    return err;  err = ftp_get_reply(connection);  if (err != FTPOK)    return err;  if (connection->serv_ret_lines->line[0] == '5')    return FTPNSFOD;  if (connection->serv_ret_lines->line[0] != '1')    return FTPERR;  return FTPOK;}/****************************************************************************** ...******************************************************************************/uerr_t ftp_pasv(connection_t * connection, unsigned char *addr){  uerr_t err;  unsigned char *p;  int i;  err = ftp_send_msg(connection, "PASV\r\n");  if (err != FTPOK)    return err;  err = ftp_get_reply(connection);  proz_debug(_("FTP PASV Header = %s"), connection->serv_ret_lines->line);  if (err != FTPOK)    return err;  if (connection->serv_ret_lines->line[0] != '2')    return FTPNOPASV;  /* Parse it. */  p = (unsigned char *) connection->serv_ret_lines->line;  for (p += 4; *p && !isdigit(*p); p++);  if (!*p)    return FTPINVPASV;  for (i = 0; i < 6; i++)  {    addr[i] = 0;    for (; isdigit(*p); p++)      addr[i] = (*p - '0') + 10 * addr[i];    if (*p == ',')      p++;    else if (i < 5)    {      return FTPINVPASV;    }  }  return FTPOK;}/****************************************************************************** ...******************************************************************************/uerr_t ftp_rest(connection_t * connection, long bytes){  uerr_t err;  err = ftp_send_msg(connection, "REST %ld\r\n", bytes);  if (err != FTPOK)    return err;  err = ftp_get_reply(connection);  if (err != FTPOK)    return err;  if (connection->serv_ret_lines->line[0] != '3')    return FTPRESTFAIL;  return FTPOK;}/****************************************************************************** ...******************************************************************************/uerr_t ftp_cwd(connection_t * connection, const char *dir){  uerr_t err;  err = ftp_send_msg(connection, "CWD %s\r\n", dir);  if (err != FTPOK)    return err;  err = ftp_get_reply(connection);  if (err != FTPOK)    return err;  if (connection->serv_ret_lines->line[0] == '5')  {    /* Is it due to the file being not found? */    if (strstr(connection->serv_ret_lines->line, "o such file")	|| strstr(connection->serv_ret_lines->line, "o Such File")	|| strstr(connection->serv_ret_lines->line, "ot found")	|| strstr(connection->serv_ret_lines->line, "ot Found"))      return FTPNSFOD;  }  if (connection->serv_ret_lines->line[0] != '2')    return FTPCWDFAIL;  return FTPOK;}/****************************************************************************** Returns the current working directory in dir.******************************************************************************/uerr_t ftp_pwd(connection_t * connection, const char *dir){  uerr_t err;  char *r, *l;  char szBuffer[FTP_BUFFER_SIZE];  err = ftp_send_msg(connection, "PWD\r\n");  if (err != FTPOK)    return err;  err = ftp_get_reply(connection);  if (err != FTPOK)    return err;  if (connection->serv_ret_lines->line[0] == '5')    return FTPPWDERR;  if (connection->serv_ret_lines->line[0] != '2')    return FTPPWDFAIL;  if ((r = strrchr(connection->serv_ret_lines->line, '"')) != NULL)  {    l = strchr(connection->serv_ret_lines->line, '"');    if ((l != NULL) && (l != r))    {      *r = '\0';      ++l;      strcpy(dir, l);      *r = '"';    }  } else  {    if ((r = strchr(connection->serv_ret_lines->line, ' ')) != NULL)    {      *r = '\0';      strcpy(dir, szBuffer);      *r = ' ';    }  }  return FTPOK;}/****************************************************************************** Returns the size of the file in size, on error size will be -1.******************************************************************************/uerr_t ftp_size(connection_t * connection, const char *file, long *size){  uerr_t err;  *size = -1;  err = ftp_send_msg(connection, "SIZE %s\r\n", file);  if (err != FTPOK)    return err;  err = ftp_get_reply(connection);  if (err != FTPOK)    return err;  /* Now lets figure out what happened. */  if (connection->serv_ret_lines->line[0] == '2')  {    sscanf(connection->serv_ret_lines->line + 3, "%ld", size);    return FTPOK;  } else if (connection->serv_ret_lines->line[0] == '5')	/* An error occured. */  {    /* Is it due to the file being not found? */    if (strstr(connection->serv_ret_lines->line, "o such file")	|| strstr(connection->serv_ret_lines->line, "o Such File")	|| strstr(connection->serv_ret_lines->line, "ot found")	|| strstr(connection->serv_ret_lines->line, "ot Found"))      return FTPNSFOD;  }  return FTPSIZEFAIL;}/****************************************************************************** Connect to the given FTP server.******************************************************************************/uerr_t ftp_connect_to_server(connection_t * connection, const char *name,			     int port){  uerr_t err;  err = connect_to_server(&(connection->ctrl_sock), name, port,			  &connection->conn_timeout);  if (err != NOCONERROR)    return err;  err = ftp_get_reply(connection);  if (err != FTPOK)    return err;  if (connection->serv_ret_lines->line[0] != '2')    return FTPCONREFUSED;  return FTPOK;}/****************************************************************************** This function will call bind() to return a bound socket then the FTP server  will be connected with a port request and asked to connect.******************************************************************************/uerr_t ftp_get_listen_socket(connection_t * connection, int *listen_sock){  /* Get a fixed value. */  char command[MAX_MSG_SIZE];  int sockfd;  socklen_t len;  struct sockaddr_in TempAddr;  char *port, *ipaddr;  struct sockaddr_in serv_addr;  uerr_t err;  if (bind_socket(&sockfd) != BINDOK)    return LISTENERR;  len = sizeof(serv_addr);  if (getsockname(sockfd, (struct sockaddr *) &serv_addr, &len) < 0)  {    perror("getsockname");    close(sockfd);    return CONPORTERR;  }  /* Get hosts info. */  len = sizeof(TempAddr);  if (getsockname(connection->ctrl_sock, (struct sockaddr *) &TempAddr,		  &len) < 0)  {    perror("getsockname");    close(sockfd);    return CONPORTERR;  }  ipaddr = (char *) &TempAddr.sin_addr;  port = (char *) &serv_addr.sin_port;#define UC(b) (((int)b)&0xff)  sprintf(command, "PORT %d,%d,%d,%d,%d,%d\r\n", UC(ipaddr[0]),	  UC(ipaddr[1]), UC(ipaddr[2]), UC(ipaddr[3]), UC(port[0]),	  UC(port[1]));  err = ftp_port(connection, command);  if (err != FTPOK)    return err;  *listen_sock = sockfd;  return FTPOK;}/****************************************************************************** ...******************************************************************************/uerr_t ftp_login(connection_t * connection, const char *username,		 const char *passwd){  uerr_t err = FTPERR;  int ret_code = 220;  boolean logged_in = FALSE;

⌨️ 快捷键说明

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