You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
4.1 KiB
C++
197 lines
4.1 KiB
C++
#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;
|
|
}
|