Native/C

[gcc] simple_ftp client

aucd29 2013. 10. 2. 18:52


#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXBUF 1024    // 일반적으로 사용할 버퍼의 사이즈
#define SERVPORT 2121 // 서버의 포트넘버

int main(int argc, char *argv[])
{
FILE *fd;
char sendbuf[MAXBUF], recvbuf[MAXBUF], filename[256];
int activeSocket;
unsigned long filesize;
struct sockaddr_in remoteAddr, localAddr;
struct stat *fileStat;    // file의 용량을 알기 위해 사용할 구조체

if (argc < 2) {
    printf("Usage : simple_ftp_client SERVER_ADDRESS\n");
    exit(0);
}

// 소켓 및 각 변수들의 초기화
fileStat = (struct stat*)malloc(sizeof(struct stat));
activeSocket = socket(AF_INET, SOCK_STREAM, 0);
memset(fileStat, 0, sizeof(fileStat));
memset(recvbuf, 0, sizeof(char)*MAXBUF);
memset(filename, 0, sizeof(char)*256);
memset(&remoteAddr, 0, sizeof(remoteAddr));
remoteAddr.sin_family = AF_INET;
remoteAddr.sin_port = htons(SERVPORT);
inet_pton(AF_INET, argv[1], &remoteAddr.sin_addr);

// 서버에 연결요청
if ( connect(activeSocket, (struct sockaddr*)&remoteAddr, sizeof(remoteAddr)) < 0 ) {
    printf("Server was not excuted, so connection was failed.\n");
    exit(0);
}
printf("** Simple FTP Client...by Hwang, Seok-joong **\n");
printf(" (if you want the manual page, type \"man\".)\n");
printf("Server address : %s\n\n", argv[1]);
printf("[ftp_client]# ");
while(gets(sendbuf)) {
    if (strcmp(sendbuf, "man") == 0) {    //man page 출력
     printf("\n\tget filename : download file\n");
     printf("\tput filename : upload file\n");
     printf("\tls         : get list of files in the server\n");
     printf("\tls_local     : see list of files in the localhost\n");
     printf("\tman         : see this page\n");
     printf("\tbye or exit : quit client program\n\n");
    } else if (strcmp(sendbuf, "bye") == 0 || strcmp(sendbuf, "exit") == 0) {    //종료
     write(activeSocket, sendbuf, MAXBUF);
     printf("\tThank you, bye~\n");
     break;
    } else if (strcmp(sendbuf, "ls") == 0) {    //리스트를 보여주는 명령
     write(activeSocket, sendbuf, MAXBUF);
     read(activeSocket, recvbuf, MAXBUF);
     printf("%s", recvbuf);
    } else if (strncmp(sendbuf, "get ", 4) == 0) {    //파일 다운로드
     strncpy(filename, sendbuf+4, 256);
     write(activeSocket, sendbuf, MAXBUF);
     read(activeSocket, recvbuf, MAXBUF);
     if (strcmp(recvbuf, "ERROR") == 0) {
        printf("File does not exist with such name.\n");
     } else {
        read(activeSocket, recvbuf, MAXBUF);
        if((filesize = atol(recvbuf)) > 0) {
         char getbuf[filesize+1];
         printf("\tDownloading %s.....", filename);
         read(activeSocket, getbuf, filesize);
         fd = fopen(filename, "w+b");
         fwrite(getbuf, 1, filesize, fd);
         fclose(fd);
         printf("done!\n");
        }
     }
    } else if (strncmp(sendbuf, "put ", 4) == 0) {    //파일 업로드
     strncpy(filename, sendbuf+4, 256);
     if ( (fd=fopen(filename, "r+b")) == NULL ) {
        printf("File does not exist with such name.\n");
     } else {
        stat(filename, fileStat);
        write(activeSocket, sendbuf, MAXBUF);
        memset(sendbuf, 0, sizeof(char)*MAXBUF);
        sprintf(sendbuf, "%ld", (unsigned long)fileStat->st_size);
        write(activeSocket, sendbuf, MAXBUF);
        memset(sendbuf, 0, sizeof(char)*MAXBUF);
        fread(sendbuf, 1, (unsigned long)fileStat->st_size, fd);
        printf("\tUploading %s.....", filename);
        write(activeSocket, sendbuf, (unsigned long)fileStat->st_size);
        fclose(fd);
        printf("done!\n");
     }
    } else if (strcmp(sendbuf, "ls_local") == 0) {    //로컬호스트의 파일리스트
     fd = popen("ls", "r");
     fread(recvbuf, 1, MAXBUF, fd);
     printf("%s", recvbuf);
     pclose(fd);
    } else {
     printf("\tUnknown command. see man page.\n");
    }
    memset(sendbuf, 0, sizeof(char)*MAXBUF);
    memset(recvbuf, 0, sizeof(char)*MAXBUF);
    memset(filename, 0, sizeof(char)*256);
    printf("[ftp_client]# ");
}
close(activeSocket);
free(fileStat);
return 0;
}