#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <signal.h>
#include <string>
#include <iostream>
#include <errno.h>
using namespace std;
#define COMMAND_SIZE 100
#define BUF_SIZE 1000
#define END_SIGN "OK "
#define READY_SIGN "OK "
#define FILE_NAME_SIZE 100
#define PORT 8888
int readen(int fd, char *buf, int size){
int size1 = size;
while(1){
int num = read(fd, buf, size);
//buf[num] = 0;
size -= num;
buf += num;
if(0 == size){
break;
}
if(0 == strncmp(buf-strlen(END_SIGN), END_SIGN, strlen(END_SIGN))){
*(buf-strlen(END_SIGN)) = 0;
size += 2;
break;
}
}
return (size1-size);
}
void getFileName(char *cmd, char *fileName){
char *p = strstr(cmd, " ");
char *p1 = strstr(cmd, "\n ");
while( ' ' == *p)
p++;
strncpy(fileName, p, p1-p);
fileName[p1-p] = 0;
}
int initfd(char **argv){
int fd;
if((fd=socket(AF_INET,SOCK_STREAM,0))==-1){
printf( "socket error!e799bee5baa6e59b9ee7ad9431333239306566\n ");
exit(1);
}
struct sockaddr_in server;
bzero(&server, sizeof(server));
server.sin_family=AF_INET;
server.sin_port=htons(PORT);
in_addr temp;
inet_aton(argv[1], &temp);
server.sin_addr = temp;
if(connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr))==-1){
perror( "connect error!\n ");
exit(1);
}
return fd;
}
void localcommand(char *cmd){
char buf[BUF_SIZE];
FILE *fp = popen(cmd, "r ");
if(NULL == fp){
printf( "exec %s error!\n ", cmd);
return;
}
while(fgets(buf, BUF_SIZE, fp)){
printf(buf);
}
pclose(fp);
}
void getcommand(int fd, char *fileName){
char buf[BUF_SIZE];
FILE *fp = fopen(fileName, "w+b ");
if(NULL == fp){
printf( "open %s failed!\n ", fileName);
return;
}
while(1){
int num = readen(fd, buf, BUF_SIZE);
fwrite(buf, num, 1, fp);
printf( "the num is %d\n ", num);
if(BUF_SIZE != num)
break;
}
fclose(fp);
printf( "get finished\n ");
}
void putcommand(int fd, char *fileName){
char buf[BUF_SIZE];
//receive "OK "
int num = recv(fd, buf, strlen(END_SIGN), 0);
buf[num] = 0;
if(0 == strncmp(buf, "OK ", strlen( "OK "))){
FILE *fp = fopen(fileName, "rb ");
if(NULL == fp){
printf( "open %s failed!\n ", fileName);
return;
}
while(1){
long offset1 = ftell(fp);
fread(buf, BUF_SIZE, 1, fp);
long offset2 = ftell(fp);
int num = offset2 - offset1;
send(fd, buf, num, 0);
printf( "the num is %d\n ", num);
if(BUF_SIZE != num)
break;
}
send(fd, END_SIGN, strlen(END_SIGN), 0);
fclose(fp);
printf( "put finished\n ");
}
else{
printf( "server is not ready!\n ");
}
}
void lpcFtpCommand(int fd){
char buf[BUF_SIZE];
while(1){
int num = readen(fd, buf, BUF_SIZE);
printf( "%s\n ", buf);
if(BUF_SIZE != num)
break;
}
}
void requestftp(int fd){
char cmd[COMMAND_SIZE];
char buf[BUF_SIZE];
char fileName[FILE_NAME_SIZE];
while(1){
//input the command
printf( "myftp> ");
fgets(cmd, COMMAND_SIZE, stdin);
printf( "%s ", cmd);
//quit command
if(0 == strncmp(cmd, "bye\n ", strlen( "bye\n "))){
send(fd, cmd, strlen(cmd), 0);
printf( "connection closing!\n ");
break;
}
//ftp command
if(0 == strncmp(cmd, "!ls\n ", strlen( "!ls\n "))){
localcommand(cmd+1);
}
else if(0 == strncmp(cmd, "!pwd\n ", strlen( "!pwd\n "))){
localcommand(cmd+1);
}
else if(0 == strncmp(cmd, "!cd ", strlen( "!cd "))){
getFileName(cmd, fileName);
chdir(fileName);
localcommand( "ls\n ");
}
else if(0 == strncmp(cmd, "get ", strlen( "get "))){ //notice space
send(fd, cmd, strlen(cmd), 0);
getFileName(cmd, fileName);
getcommand(fd, fileName);
}
else if(0 == strncmp(cmd, "put ", strlen( "put "))){ //notice space
send(fd, cmd, strlen(cmd), 0);
getFileName(cmd, fileName);
putcommand(fd, fileName);
}
else if(0 == strncmp(cmd, "ls\n ", strlen( "ls\n "))){
send(fd, cmd, strlen(cmd), 0);
lpcFtpCommand(fd);
}
else if(0 == strncmp(cmd, "pwd\n ", strlen( "pwd\n "))){
send(fd, cmd, strlen(cmd), 0);
lpcFtpCommand(fd);
}
else if(0 == strncmp(cmd, "cd ", strlen( "cd "))){
send(fd, cmd, strlen(cmd), 0);
lpcFtpCommand(fd);
}
else{
printf( "?invalid command!\n ");
}
}
close(fd);
}
int main(int argc, char **argv){
//check the param
if(2 != argc){
printf( "myftp command is like: myftp 127.0.0.1\n ");
exit(0);
}
//create and connect socket
int fd = initfd(argv);
//deal with the comand, the endpoint is "bye "
requestftp(fd);
return 0;
}
