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

📄 ftp_client_proto.cc

📁 实现了poll/epoll/devpoll等C++封装
💻 CC
📖 第 1 页 / 共 2 页
字号:
					returnState();					/* success */					if (m_state == FCPS_RETR) {						DPRINT(("ftp_client_proto_t::giveInput::PASV: sending RETR\n"));						m_obuflen = sprintf(m_obuf, "RETR %s\r\n", m_fname);					}					break;				}				/* fall thru to error case */			}			/* fall thru to error case */		}		DPRINT(("ftp_client_proto_t::giveInput::PASV failed, %s\n", ibuf));		popState();		SETSTATE(FCPS_IDLE);		break;	case FCPS_RETR:		if ((status >= 100) && (status < 200)) {			DPRINT(("ftp_client_proto_t::giveInput::RETR in progress\n", ibuf));		} else if ((status >= 200) && (status < 300)) {			DPRINT(("ftp_client_proto_t::giveInput::RETR server finished, %s\n", ibuf));			SETSTATE(FCPS_IDLE);		} else {			DPRINT(("ftp_client_proto_t::giveInput::RETR failed, %s\n", ibuf));			SETSTATE(FCPS_IDLE);		}		break;	default:		DPRINT(("ftp_client_proto_t::giveInput: Unexpected input from server: '%s'\n", ibuf));		return EINVAL;		break;	}	return 0;}/*--------------------------------------------------------------------- Get the status of the last login, quit, cd, ls, or get call. If the operation is still in progress, returns 0. If the operation has succeeded, returns a value between 200 and 299. ASCII version of result is returned in given buffer, if buf != NULL.---------------------------------------------------------------------*/int ftp_client_proto_t::getStatus(char *buf, size_t buflen){	if ((m_state != FCPS_IDLE) && (m_state != FCPS_INIT))		return 0;	if (buf) {		strncpy(buf, m_response, buflen);		buf[buflen-1] = 0;	}	return m_status;}/*--------------------------------------------------------------------- Get the current null-terminated output line to the server and its length in bytes. The line is terminated by CR LF and a NUL; the length includes the CR LF but not the NUL. You may call it as many times as you like; it will return the same data.  This lets you retry a send.   After the send succeeds, call advanceOutput() to advance to the next  line of output. Returns NULL if no output is ready yet.---------------------------------------------------------------------*/const char *ftp_client_proto_t::getOutput(int *plen){	if (!isOutputReady())		return NULL;	DPRINT(("ftp_client_proto_t::getOutput: Sending '%s'\n", m_obuf));	if (plen)		*plen = m_obuflen;	return m_obuf;}/*--------------------------------------------------------------------- Advances to next line of output; then call getOutput() to get it. Returns 0 on success, Unix error code on error. In particular, returns EWOULDBLOCK if no more output is ready.---------------------------------------------------------------------*/int ftp_client_proto_t::advanceOutput(){	m_obuflen = 0;	return 0;}/*--------------------------------------------------------------------- Log in to the server.   Call getStatus() periodically until it returns nonzero to get whether this command succeeded.---------------------------------------------------------------------*/int ftp_client_proto_t::login(const char *username, const char *password){	if ((m_state != FCPS_INIT) && (m_state != FCPS_CONNECTED)) {		DPRINT(("ftp_client_proto_t::login: State %d not init or connected\n", m_state));		return EISCONN;	}	if (m_sent_user) {		DPRINT(("ftp_client_proto_t::login: already logged in?!\n"));		return EISCONN;	}	if (isOutputReady()) {		DPRINT(("ftp_client_proto_t::login: obuf not empty?!\n"));		return EWOULDBLOCK;	}	DPRINT(("ftp_client_proto_t::login(%s,%s)\n", username, password));	m_obuflen = sprintf(m_obuf, "USER %s\r\n", username);	strncpy(m_password, password, sizeof(m_password));	m_password[sizeof(m_password)-1] = 0;	if (m_state == FCPS_CONNECTED) {		SETSTATE(FCPS_USER);	} else {		// FCPS_INIT will go to FCPS_USER when it sees m_sent_user true		m_sent_user = true;	}	return 0;}/* other methods' implementations would go here, but haven't been written yet *//*--------------------------------------------------------------------- Log out from the server.  This triggers the QUIT command. Call getStatus() periodically until it returns nonzero to get whether this command succeeded.---------------------------------------------------------------------*/int ftp_client_proto_t::quit(){	/* unimplemented */	return ENOSYS;}/*--------------------------------------------------------------------- Change directories. If dir is "..", the CDUP command is used instead of CD. Call getStatus() periodically until it returns nonzero to get whether this command succeeded.---------------------------------------------------------------------*/int ftp_client_proto_t::cd(const char *dir){	if (m_state != FCPS_IDLE) {		DPRINT(("ftp_client_proto_t::cd: State %d not idle\n", m_state));		return EISCONN;	}	if (isOutputReady()) {		DPRINT(("ftp_client_proto_t::cd: obuf not empty?!\n"));		return EWOULDBLOCK;	}	if (strcmp("..", dir) == 0) {		m_obuflen = sprintf(m_obuf, "CDUP\r\n");	}  else {		m_obuflen = sprintf(m_obuf, "CWD %s\r\n", dir );	}	SETSTATE(FCPS_CWD);	return 0;}/**--------------------------------------------------------------------- Set the transfer type. Call getStatus() periodically until it returns nonzero to get whether this command succeeded, then parse the results out of the status  buffer.---------------------------------------------------------------------*/int ftp_client_proto_t::type(const char *ttype){	if (m_state != FCPS_IDLE) {		DPRINT(("ftp_client_proto_t::type: State %d not idle\n", m_state));		return EISCONN;	}	if (isOutputReady()) {		DPRINT(("ftp_client_proto_t::type: obuf not empty?!\n"));		return EWOULDBLOCK;	}	m_obuflen = sprintf(m_obuf, "TYPE %s\r\n", ttype );	SETSTATE(FCPS_TYPE);	return 0;}/*--------------------------------------------------------------------- Retrieve file size. Call getStatus() periodically until it returns nonzero to get whether this command succeeded, then parse the results out of the status  buffer.---------------------------------------------------------------------*/int ftp_client_proto_t::size(const char *fname){	if (m_state != FCPS_IDLE) {		DPRINT(("ftp_client_proto_t::size: State %d not idle\n", m_state));		return EISCONN;	}	if (isOutputReady()) {		DPRINT(("ftp_client_proto_t::size: obuf not empty?!\n"));		return EWOULDBLOCK;	}	m_obuflen = sprintf(m_obuf, "SIZE %s\r\n", fname );	SETSTATE(FCPS_SIZE);	return 0;}/**--------------------------------------------------------------------- List the given directory's contents.   dirname may be NULL. Result comes back on a data channel. Call getStatus() periodically until it returns nonzero to get whether this command succeeded.   If address is 0, PASV mode is used, and isPortReady() should be called periodically until it returns true and indicates where to connect to  to retrieve the directory listing. After retrieving the data from that address, continue calling getStatus() to get the success status message. If address is nonzero, PORT mode is used; it is assumed that a port is already listening on the given address for a connection.---------------------------------------------------------------------*/int ftp_client_proto_t::ls(const char *dirname, struct sockaddr_in *address){	/* unimplemented */	(void) dirname; (void) address;	return ENOSYS;}/*--------------------------------------------------------------------- Retrieve the given file's contents.  Result comes back on a data channel. Call getStatus() periodically until it returns nonzero to get whether this command succeeded.   If address is NULL, PASV mode is used, and isPortReady() should be called periodically until it returns true and indicates where to connect to  to retrieve the file. After retrieving the data from that address, continue calling getStatus() to get the success status message. If address is not NULL, PORT mode is used; it is assumed that a port is already listening on the given address for a connection. adr must be in network byte order.---------------------------------------------------------------------*/int ftp_client_proto_t::get(const char *fname, struct sockaddr_in *adr){	if (m_state != FCPS_IDLE) {		DPRINT(("ftp_client_proto_t::get: State %d not idle\n", m_state));		return EISCONN;	}	if (isOutputReady()) {		DPRINT(("ftp_client_proto_t::get: obuf not empty?!\n"));		return EWOULDBLOCK;	}	if (strlen(fname) >= ftp_client_proto_MAXFNAME) {		DPRINT(("ftp_client_proto_t::get: filename too long\n"));		return E2BIG;	}	strcpy(m_fname, fname);#define GETBYTE3(x) (((x) >> 24) & 255)#define GETBYTE2(x) (((x) >> 16) & 255)#define GETBYTE1(x) (((x) >> 8) & 255)#define GETBYTE0(x) ((x) & 255)	if (adr) {		DPRINT(("ftp_client_proto_t::get(%s,): telling server what port to connect to\n", fname));		int addr = ntohl(adr->sin_addr.s_addr);		short port = ntohs(adr->sin_addr.s_addr);		m_obuflen = sprintf(m_obuf, "PORT %d,%d,%d,%d,%d,%d\r\n", 			GETBYTE3(addr),			GETBYTE2(addr),			GETBYTE1(addr),			GETBYTE0(addr),			GETBYTE1(port),			GETBYTE0(port));		CALLSTATE(FCPS_PORT, FCPS_RETR);	} else {		DPRINT(("ftp_client_proto_t::get(%s,): requesting port from server\n", fname));		m_obuflen = sprintf(m_obuf, "PASV\r\n");		CALLSTATE(FCPS_PASV, FCPS_RETR);	}	return 0;}

⌨️ 快捷键说明

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