尊重作者劳动成果,转载请注明出处,谢谢!
1. ftp.h
#ifndef ftp_H #define ftp_H #include "types.h" #include "socket.h" #ifdef __cplusplus extern "C" { #endif int ftp_login(const char *servIp, unsigned short port, const char *user, const char *password); boolean ftp_quit(int sockfd); boolean ftp_getCurrentDirectory(int sockfd, char *directory); boolean ftp_changDirectory(int sockfd, const char *directory); boolean ftp_changDirectoryUp(int sockfd); boolean ftp_createDirectory(int sockfd, const char *directory); boolean ftp_fileList(int sockfd); boolean ftp_download(int sockfd, const char *remoteFileName, const char *filePath); boolean ftp_upload(int sockfd, const char *remoteFileName, const char *filePath); #ifdef __cplusplus } #endif #endif
2. ftp.c
#include "ftp.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> static unsigned short strToHostAndPort(const char *str, char *host) { int addr[6]; sscanf(str, "%*[^(](%d,%d,%d,%d,%d,%d)", &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]); bzero(host, strlen(host)); sprintf(host, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); unsigned short port; port = addr[4] * 256 + addr[5]; return port; } static boolean recvAndCheck(int sockfd, const char *code) { char buf[1024] = {0}; int nrecv = recv(sockfd, buf, 1024, 0); if (nrecv <= 0) return False; printf("%s ", buf); return strncmp(buf, code, 3) == 0 ? True : False; } static boolean ftp_sendCommandWithResult(int sockfd, const char *cmd, const char *arg, const char *code, char *result) { if (sockfd == INVALID_SOCKET) return False; char *cmdBuf = (char *)malloc(strlen(cmd) + strlen(arg) + 10); sprintf(cmdBuf, "%s %s ", cmd, arg); int cmdBufSize = strlen(cmdBuf); int nsend = send(sockfd, cmdBuf, cmdBufSize, 0); free(cmdBuf); if (nsend != cmdBufSize) return False; char buf[1024] = {0}; int nrecv = recv(sockfd, buf, 1024, 0); printf("%s ", buf); if (nrecv <= 0) return False; if (result != NULL) strcpy(result, buf); return strncmp(buf, code, 3) == 0 ? True : False; } static boolean ftp_sendCommand(int sockfd, const char *cmd, const char *arg, const char *code) { return ftp_sendCommandWithResult(sockfd, cmd, arg, code, NULL); } //使用被动模式,并返回数据端口的文件描述符 static int ftp_uesPasvMode(int sockfd) { if (sockfd == INVALID_SOCKET) return False; char buf[1024] = {0}; //227 Entering Passive Mode (192,168,1,100,191,160). if (!ftp_sendCommandWithResult(sockfd, "PASV", "", "227", buf)) return False; char data_host[32] = {0}; unsigned short data_port; data_port = strToHostAndPort(buf, data_host); return createTcpClient(data_host, data_port); } //ftp登录 int ftp_login(const char *servIp, unsigned short port, const char *user, const char *password) { int sockfd = createTcpClient(servIp, port); if (sockfd == INVALID_SOCKET) return -1; //220 (vsFTPd 3.0.3) if (!recvAndCheck(sockfd, "220")) { close(sockfd); return INVALID_SOCKET; } //331 Please specify the password. if (!ftp_sendCommand(sockfd, "USER", user, "331")) { close(sockfd); return INVALID_SOCKET; } //230 Login successful. if (!ftp_sendCommand(sockfd, "PASS", password, "230")) { close(sockfd); return INVALID_SOCKET; } //200 Switching to Binary mode. if (!ftp_sendCommand(sockfd, "TYPE", "I", "200")) { close(sockfd); return INVALID_SOCKET; } return sockfd; } //ftp注销 boolean ftp_quit(int sockfd) { if (sockfd == INVALID_SOCKET) return False; //221 Goodbye. if (!ftp_sendCommand(sockfd, "QUIT", "", "221")) return False; close(sockfd); return True; } //ftp获取当前工作目录 boolean ftp_getCurrentDirectory(int sockfd, char *directory) { if (sockfd == INVALID_SOCKET) return False; //257 "/root" is the current directory char buf[1024]; if (!ftp_sendCommandWithResult(sockfd, "PWD", "", "257", buf)) return False; int i = 0; char *ptr = buf + 5; while (*ptr != '"') { directory[i++] = *ptr; ptr++; } directory[i] = '