FTP 服务器

原创 2016年08月30日 20:18:12
#include <ctype.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define DEBUG 1
#define MAXSIZE 512
#define CLIENT_PORT_ID 30020

struct command
{
    char arg[255];
    char code[5];
};

int socket_create(int port)
{
    int sockfd;
    int yes = 1;
    struct sockaddr_in sock_addr;

    if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
    {
        perror("socker() error");
        return -1;
    }

    sock_addr.sin_family = AF_INET;
    sock_addr.sin_port = htons(port);
    sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1)
    {
        close(sockfd);
        perror("socket() error");
        return -1;
    }

    if (bind(sockfd,(struct sockaddr *)&sock_addr,sizeof(sock_addr)) < 0)
    {
        close(sockfd);  
        perror("socket() error");
        return -1;
    }
    return sockfd;
}

int socket_accept(int sock_listen)
{
    int sockfd;
    struct sockaddr_in client_addr;
    socklen_t len = sizeof(client_addr);

    sockfd = accept(sock_listen,(struct sockaddr *)&client_addr,&len);

    if (sockfd < 0)
    {
        perror("socket() error");
        return -1;
    }
    return sockfd;
}

int socket_connect(int port, char *host)
{
    int sockfd;
    struct sockaddr_in dest_addr;
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if (sockfd < 0)
    {
        perror("sockrt() error");
        return -1;
    }

    memset(&dest_addr,0,sizeof(dest_addr));
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(port);
    dest_addr.sin_addr.s_addr = inet_addr(host);

    if (connect(sockfd,(struct sockaddr *)&dest_addr,sizeof(dest_addr)) < 0 )
    {
        perror("connect() error");
        return -1;
    }
    return sockfd;
}

int recv_data(int sockfd, char *buf, int bufsize)
{
    size_t num_bytes;
    memset(buf,0,bufsize);
    num_bytes = recv(sockfd,buf,bufsize,0);
    if (num_bytes < 0)
        return -1;
    return num_bytes;
}

int send_response(int sockfd,int rc)
{
    int conv = htonl(rc);
    if (send(sockfd,&conv,sizeof(conv),0) < 0)
    {
        perror("sending error");
        return -1;
    }
    return 0;
}

void trimstr(char *str, int n)
{
    int i;
    for(i = 0;i<n;i++)
    {
        if (isspace(str[i]))
        str[i] = 0;
        if (str[i] == '\n') 
        str[i] = 0;
    }
}

void read_input(char *buffer, int size)
{
    char *nl = NULL;
    memset(buffer,0,size);
    if ( fgets(buffer, size, stdin) != NULL )
    {
        nl = strchr(buffer,'\n');
        if (nl) *nl = '\0';
    }
}
//////////////////////////////////////
//server code start

void ftserve_retr(int sock_control,int sock_data,char *filename)
{
    FILE *fd = NULL;
    char data[MAXSIZE];
    size_t num_read;

    fd = fopen(filename,"r");

    if (!fd)
    {
        send_response(sock_control,550);
    }
    else
    {
        send_response(sock_control,150);
        do
        {
            num_read = fread(data,1,MAXSIZE,fd);

            if (num_read < 0)
            {
                printf("error in fread()\n");
            }

            if (send(sock_data,data,num_read,0) < 0)
                perror("error sending file\n");

        }while (num_read > 0);
        send_response(sock_control,226);
        fclose(fd);
    }
}

int ftserve_list(int sock_data,int sock_control)
{
    char data[MAXSIZE];
    size_t num_read;
    FILE *fd;

    int rs = system("ls -l | tail -n+2 > tmp.txt");

    if (rs < 0)
        exit(1);
    fd = fopen("tmp.txt","r");
    if (!fd)
        exit(1);
    fseek(fd,SEEK_SET,0);
    send_response(sock_control,1);

    memset(data,0,MAXSIZE);
    while ((num_read = fread(data,1,MAXSIZE,fd)) > 0)
    {
        if ((send(sock_data,data,num_read,0)) < 0)
            perror("error");
        memset(data,0,MAXSIZE);
    }
    fclose(fd);

    send_response(sock_control,226);
    return 0;
}

int ftserve_start_data_conn(int sock_control)
{
    char buf[2048];
    int wait,sock_data;

    if (recv(sock_control,&wait,sizeof(wait),0) < 0)
    {
        perror("Error waiting");
        return -1;
    }

    struct sockaddr_in client_addr;
    socklen_t len = sizeof(client_addr);

    getpeername(sock_control,(struct sockaddr*)&client_addr,&len);
    inet_ntop(AF_INET,&client_addr.sin_addr,buf,sizeof(buf));
    if ((sock_data = socket_connect(CLIENT_PORT_ID,buf)) < 0)
        return -1;
    return sock_data;
}

int ftserve_check_user(char *user,char *pass)
{   
    char username[MAXSIZE];
    char password[MAXSIZE];
    char *pch;
    char buf[MAXSIZE];
    char *line = NULL;
    size_t num_read;
    size_t len = 0;
    FILE* fd;
    int auth = 0;

    fd = fopen(".auth","r");
    if (fd == NULL)
    {
        perror("file not found");
        exit(1);
    }

    while ((num_read = getline(&line,&len,fd)) != -1)
    {
        memset(buf,0,MAXSIZE);
        strcpy(buf,line);

        pch = strtok(buf," ");
        strcpy(username,pch);

        if (pch != NULL)
        {
            pch = strtok(NULL," ");
            strcpy(password,pch);
        }

        trimstr(password, (int)strlen(password));

        if ((strcmp(user,username) == 0 ) && (strcmp(pass,password) == 0) )
        {
            auth = 1;
            break;
        }
    }
    free(line);
    fclose(fd);
    return auth;
}

int ftserve_login(int sock_control)
{
    char buf[MAXSIZE];
    char user[MAXSIZE];
    char pass[MAXSIZE];
    memset(user,0,sizeof(user));
    memset(pass,0,sizeof(pass));
    memset(buf,0,sizeof(buf));

    if ((recv_data(sock_control,buf,sizeof(buf))) == -1)
    {
        perror("recv error");
        exit(1);
    }

    int i = 5;
    int n = 0;
    while (buf[i] != 0)
        user[n++] = buf[i++];

    send_response(sock_control,331);

    memset(buf,0,MAXSIZE);
    if ((recv_data(sock_control,buf,sizeof(buf))) == -1)
    {
        perror("recv error\n");
        exit(1);
    }

    i = 5;
    n = 0;
    while (buf[i] != 0)
        pass[n++] = buf[i++];

    return (ftserve_check_user(user,pass));
}

int ftserve_recv_cmd(int sock_control,char *cmd,char *arg)
{
    int rc = 200;
    char buffer[MAXSIZE];

    memset(buffer,0,sizeof(buffer));
    memset(cmd,0,5);
    memset(arg,0,MAXSIZE);

    if ((recv_data(sock_control,buffer,sizeof(buffer))) == -1)
    {
        perror("recv error\n");
        return -1;
    }

    strncpy(cmd,buffer,4);
    char *tmp = buffer + 5;
    strcpy(arg, tmp);

    if (strcmp(cmd,"QUIT") == 0)
    {
        rc = 221;
    }
    else if (strcmp(cmd,"USER") == 0 || strcmp(cmd,"PASS") == 0 || strcmp(cmd,"LIST") == 0 || strcmp(cmd,"RETR") == 0)
        rc = 200;
    else
        rc = 502;

}

void ftserve_process(int sock_control)
{
    int sock_data;
    char cmd[5];
    char arg[MAXSIZE];

    send_response(sock_control,220);

    if (ftserve_login(sock_control) == 1)
        send_response(sock_control,230);
    else
    {
        send_response(sock_control,430);
        exit(0);
    }

    while (1)
    {
        int rc = ftserve_recv_cmd(sock_control, cmd, arg);

        if (rc < 0 || rc == 221)
            break;

        if (rc == 200)
        {
            if ((sock_data = ftserve_start_data_conn(sock_control)) < 0)
            {
                close(sock_control);
                exit(1);
            }

            if (strcmp(cmd,"LIST") == 0)
                ftserve_list(sock_data,sock_control);
            else if (strcmp(cmd,"RETR") == 0)
                ftserve_retr(sock_control, sock_data, arg);
            close(sock_data);
        }
    }

}

int main(int argc, char *argv[])
{
    int sock_listen,sock_control,port,pid;

    if (argc != 2)
    {
        printf("usage: ./ftpserve port\n");
        exit(0);
    }

    port = atoi(argv[1]);

    if ((sock_listen = socket_create(port)) < 0)
    {
        perror("socket error");
        exit(1);
    }

    while (1)
    {
        if ((sock_control = socket_accept(sock_listen)))
            break;

        if ((pid = fork()) < 0)
            perror("Fork error");
        else if(pid == 0)
        {
            close(sock_listen);
            ftserve_process(sock_control);
            close(sock_control);
            exit(0);
        }

        close(sock_control);
    }

    close(sock_listen);
    return 0;
}
版权声明:转载请注明出处。

ftp简单服务器

  • 2017年11月17日 15:19
  • 124KB
  • 下载

C#WinFrom程序的FTP服务器上传下载

  • 2017年11月23日 16:03
  • 68KB
  • 下载

搭建Linux/Ubuntu下的ProFTPd Ftp文件服务器 及其 MySQL虚拟用户验证、Quotatab磁盘限额

原创声明, 转帖请注明本文出处:leonidasFlames的专栏  本文地址:搭建Linux/Ubuntu下的ProFTPd Ftp文件服务器 及其 MySQL虚拟用户验证、Quotatab磁盘限...

简易ftp服务器

  • 2017年11月16日 15:49
  • 404KB
  • 下载

FTP、Syslog服务器、TFTP

  • 2017年11月13日 12:06
  • 245KB
  • 下载

FTP 与服务器的连接被重置的另类原因与另类解决【IP冲突】

公司在万网买了虚拟主机,今天用台式机连了上去传东西,还有一部分文件在另一台笔记本上,于是用笔记本也连了上去,传到一半问题来了,提示与服务器的连接被重置 但是,公司买的另外一个万网主机却能正常...

liunx ftp服务器搭建

  • 2016年06月14日 11:00
  • 747KB
  • 下载

Ubuntu中用vsftpd搭建FTP服务器笔记

网上关于使用linux下使用vsftpd搭建FTP的文章非常的多,大部分内容都差不多。还有诸如“我见过最好的vsftpd配置教程”、“史上最详细的vsftpd配置文件讲解”和“vsftpd入门专题”等...

Window server 2008 搭建FTP服务器

  • 2017年07月02日 03:15
  • 1.28MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:FTP 服务器
举报原因:
原因补充:

(最多只允许输入30个字)