update ftpserver
This commit is contained in:
parent
ffbf276607
commit
f5589fbaa4
|
@ -25,13 +25,18 @@
|
|||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define CMD_PORT 9970
|
||||
#define CMD_PORT 9971
|
||||
#define BACKLOG_LEN 128
|
||||
#define MAX_USERS 100
|
||||
#define MAX_CONNECTION 100
|
||||
#define UNLOGED_IN 0
|
||||
#define LOGED_IN 1
|
||||
|
||||
int off = 0;
|
||||
int fd_map[200];
|
||||
struct User {
|
||||
char username[50];
|
||||
char password[50];
|
||||
|
@ -41,34 +46,82 @@ struct LoginStatus {
|
|||
char *addr;
|
||||
char username[50];
|
||||
char password[50];
|
||||
int login_status;//登录状态,0代表未登录 1代表已登录
|
||||
int login_status;
|
||||
};
|
||||
|
||||
struct User users[MAX_USERS];
|
||||
struct LoginStatus login_list[MAX_CONNECTION];
|
||||
void GetFullAddress(char *client_id, char *client_ip, int client_port) {
|
||||
|
||||
void StartNewConnection(int data_fd,struct sockaddr_in client_addr);
|
||||
|
||||
void GetFullAddress(char* client_id, char* client_ip, int client_port) {
|
||||
memset(client_id, 0, sizeof(client_id));
|
||||
sprintf(client_id, "%s:%d", client_ip, client_port);
|
||||
}
|
||||
int CheckPassword(int it){
|
||||
for(int i=0;i<MAX_USERS;i++){
|
||||
if(strcmp(login_list[it].username,users[i].username) == 0 && strcmp(login_list[it].password,users[i].password) == 0)return 1;
|
||||
|
||||
int CheckPassword(int it) {
|
||||
for (int i = 0;i < MAX_USERS;i++) {
|
||||
if (strcmp(login_list[it].username, users[i].username) == 0 && strcmp(login_list[it].password, users[i].password) == 0)return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void StartDataConnection(int data_fd,struct sockaddr_in client_addr)
|
||||
{
|
||||
|
||||
char *GetRespond(char *buf,int it) {
|
||||
char * cmd=malloc(100);
|
||||
char * data=malloc(100);
|
||||
char * respond=malloc(100);
|
||||
sscanf(buf,"%s %s",cmd,data);
|
||||
}
|
||||
void *CreateDataSockt(void *arg) {
|
||||
|
||||
int *data = arg;
|
||||
int port = data[0];
|
||||
int cmd_fd = data[1];
|
||||
|
||||
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
printf("Failed to create socket\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct sockaddr_in server_addr;
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(port);
|
||||
server_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
int ret = bind(fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
|
||||
if (ret < 0) {
|
||||
printf("%d\n", ret);
|
||||
printf("Failed to bind socket\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
|
||||
listen(fd, BACKLOG_LEN);
|
||||
|
||||
struct sockaddr_in client_addr;
|
||||
socklen_t len = sizeof(client_addr);
|
||||
int data_fd = accept(fd, (struct sockaddr *)&client_addr, &len);
|
||||
|
||||
fd_map[cmd_fd] = data_fd;
|
||||
|
||||
StartDataConnection(data_fd, client_addr);
|
||||
|
||||
}
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* GetRespond(char* buf, int it,int *ret,int cmd_fd) {
|
||||
char * cmd = malloc(100);
|
||||
char * data = malloc(100);
|
||||
char* respond = malloc(100);
|
||||
printf("%s\n", buf);
|
||||
sscanf(buf, "%s %s", cmd, data);
|
||||
if(strcmp(cmd,"USER")==0){
|
||||
login_list[it].login_status=LOGED_IN;
|
||||
strcpy(login_list[it].username,data);
|
||||
sprintf(respond,"331 %s login ok, send your password\n",data);
|
||||
strcpy(login_list[it].username, data);
|
||||
sprintf(respond, "331 %s login ok, send your password\n", data);
|
||||
}
|
||||
else if(strcmp(cmd,"PASS")==0){
|
||||
login_list[it].login_status=LOGED_IN;
|
||||
strcpy(login_list[it].password, data);
|
||||
if(CheckPassword(it)){
|
||||
sprintf(respond,"230 access granted, restrictions apply\n");
|
||||
}
|
||||
|
@ -77,16 +130,66 @@ char *GetRespond(char *buf,int it) {
|
|||
}
|
||||
}
|
||||
else if(strcmp(cmd,"SIZE")==0){
|
||||
struct stat file_stat;
|
||||
|
||||
if (stat(data, &file_stat) == 0) {
|
||||
int size = file_stat.st_size;
|
||||
sprintf(respond, "213 %d", size);
|
||||
}
|
||||
else sprintf(respond, "550 file not found");
|
||||
}
|
||||
else if(strcmp(cmd,"PASV")==0){
|
||||
|
||||
else if (strcmp(cmd, "PASV") == 0) {
|
||||
off = (off + 1) % 15;
|
||||
int port = 9980 + off;
|
||||
sprintf(respond, "227 enter passive mode (8.140.53.225,%d,%d)", port / 256, port % 256);
|
||||
pthread_t thread;
|
||||
int arg[2];
|
||||
arg[0] = port;
|
||||
arg[1] = cmd_fd;
|
||||
pthread_create(&thread, NULL, CreateDataSockt, arg);
|
||||
*ret = 227;
|
||||
}
|
||||
else if(strcmp(cmd,"RETR")==0){
|
||||
else if (strcmp(cmd, "RETR") == 0) {
|
||||
char* dir=malloc(100);
|
||||
sprintf(dir, "/home/xiuos/wojiuguaji/%s", data);
|
||||
FILE* file = fopen(dir, "rb");
|
||||
if (file == NULL) {
|
||||
sprintf(respond, "550 failed to open file\n");
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
long file_size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
char* buff = (char*)malloc(file_size);
|
||||
|
||||
fread(buf, 1, file_size, file);
|
||||
write(fd_map[cmd_fd], buff, strlen(buff));
|
||||
|
||||
fclose(file);
|
||||
free(buff);
|
||||
free(dir);
|
||||
}
|
||||
else if(strcmp(cmd,"STOR")==0){
|
||||
else if (strcmp(cmd, "STOR") == 0) {
|
||||
char* dir=malloc(100);
|
||||
sprintf(dir, "/home/xiuos/wojiuguaji/%s", data);
|
||||
FILE* file = fopen(dir, "wb");
|
||||
if (file == NULL) {
|
||||
sprintf(respond, "550 failed to open file\n");
|
||||
}
|
||||
|
||||
char* buff = (char*)malloc(5000);
|
||||
|
||||
read(fd_map[cmd_fd], buff, sizeof(buff));
|
||||
fwrite(buff, 1, strlen(buff), file);
|
||||
|
||||
fclose(file);
|
||||
free(buff);
|
||||
free(dir);
|
||||
}
|
||||
else if(strcmp(cmd,"QUIT")==0){
|
||||
sprintf(respond, "221 connection close");
|
||||
*ret = 221;
|
||||
}
|
||||
else {
|
||||
respond = "500 syntax error\n";
|
||||
|
@ -94,9 +197,75 @@ char *GetRespond(char *buf,int it) {
|
|||
return respond;
|
||||
}
|
||||
|
||||
void *RecvSend(void *arg)
|
||||
{
|
||||
int* data = arg;
|
||||
int cmd_fd = data[0];
|
||||
int it = data[1];
|
||||
while (1)
|
||||
{
|
||||
char buf[100];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
int size;
|
||||
size = read(cmd_fd, buf, sizeof(buf));
|
||||
|
||||
if (size < 0) {
|
||||
printf("Failed to read or client closed\n");
|
||||
return NULL;
|
||||
}
|
||||
int* ret = malloc(sizeof(int));
|
||||
char* respond = GetRespond(buf, it,ret,cmd_fd);
|
||||
write(cmd_fd, respond, strlen(respond));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void StartNewConnection(int cmd_fd, struct sockaddr_in client_addr)
|
||||
{
|
||||
char client_ip[INET_ADDRSTRLEN];
|
||||
int client_port;
|
||||
inet_ntop(AF_INET, &(client_addr.sin_addr), client_ip, sizeof(client_ip));
|
||||
client_port = ntohs(client_addr.sin_port);
|
||||
printf("Client %s:%d connected.\n", client_ip, client_port);
|
||||
int it = -1;
|
||||
char client_id[50];
|
||||
for (int i = 0;i < MAX_CONNECTION;i++) {
|
||||
GetFullAddress(client_id, client_ip, client_port);
|
||||
if (strcmp(client_id, login_list[i].addr) == 0) {
|
||||
it=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (it == -1) {
|
||||
for(int i=0;i<MAX_CONNECTION;i++){
|
||||
if(login_list[i].login_status==0){
|
||||
it = i;
|
||||
strcpy(login_list[i].addr, client_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(it==-1){
|
||||
const char limit_exceeded[] = "530 connection limit exceeded.";
|
||||
write(cmd_fd, limit_exceeded, strlen(limit_exceeded));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(login_list[it].login_status == UNLOGED_IN){
|
||||
const char welcome[] = "220 welcome.";
|
||||
write(cmd_fd, welcome, strlen(welcome));
|
||||
}
|
||||
|
||||
pthread_t thread;
|
||||
|
||||
int arg[2];
|
||||
arg[0] = cmd_fd;
|
||||
arg[1] = it;
|
||||
pthread_create(&thread, NULL, RecvSend, arg);
|
||||
|
||||
}
|
||||
|
||||
int Init() {
|
||||
memset(login_list,0,sizeof(login_list));
|
||||
memset(users,0,sizeof(users));
|
||||
|
||||
for (int i = 0;i < MAX_CONNECTION;i++) {
|
||||
login_list[i].addr = (char*)malloc(50);
|
||||
strcpy(login_list[i].addr, "");
|
||||
|
@ -118,60 +287,21 @@ int Init() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
listen(fd, BACKLOG_LEN);
|
||||
printf("Socket created, binding to port 9970\n");
|
||||
|
||||
printf("Socket created, binding to port 9971\n");
|
||||
|
||||
while (1) {
|
||||
|
||||
listen(fd, BACKLOG_LEN);
|
||||
|
||||
struct sockaddr_in client_addr;
|
||||
socklen_t len = sizeof(client_addr);
|
||||
int cmd_fd = accept(fd, (struct sockaddr *)&client_addr, &len);
|
||||
|
||||
char client_ip[INET_ADDRSTRLEN];
|
||||
int client_port;
|
||||
inet_ntop(AF_INET, &(client_addr.sin_addr), client_ip, sizeof(client_ip));
|
||||
client_port = ntohs(client_addr.sin_port);
|
||||
printf("Client %s:%d connected.\n", client_ip, client_port);
|
||||
StartNewConnection(cmd_fd, client_addr);
|
||||
|
||||
int it = -1;
|
||||
char client_id[50];
|
||||
for (int i = 0;i < MAX_CONNECTION;i++) {
|
||||
GetFullAddress(client_id, client_ip, client_port);
|
||||
printf("%s\n", client_id);
|
||||
if (strcmp(client_id, login_list[it].addr) == 0) {
|
||||
it=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (it==-1){
|
||||
for(int i=0;i<MAX_CONNECTION;i++){
|
||||
if(login_list[i].login_status==0){
|
||||
it = i;
|
||||
strcpy(login_list[i].addr, client_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(it==-1){
|
||||
const char limit_exceeded[] = "530 connection limit exceeded.";
|
||||
write(cmd_fd, limit_exceeded, strlen(limit_exceeded));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(login_list[it].login_status == UNLOGED_IN){
|
||||
const char welcome[] = "220 welcome.";
|
||||
write(cmd_fd, welcome, strlen(welcome));
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
int size;
|
||||
size = read(cmd_fd, buf, sizeof(buf));
|
||||
|
||||
if (size < 0) {
|
||||
printf("Failed to read or client closed\n");
|
||||
}
|
||||
|
||||
char *respond = GetRespond(buf, it);
|
||||
write(cmd_fd, respond, strlen(respond));
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void InsertUser(char * username,char * password)
|
||||
|
@ -184,8 +314,10 @@ void InsertUser(char * username,char * password)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
InsertUser("frank","114514");
|
||||
memset(users,0,sizeof(users));
|
||||
InsertUser("frank", "114514");
|
||||
Init();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue