update ftpserver
This commit is contained in:
parent
fbf72cc60d
commit
6e16c5d504
|
@ -0,0 +1,194 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 AIIT Ubiquitous Team
|
||||||
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file: ftpserver.c
|
||||||
|
* @brief: an application of an FTP server running on Linux
|
||||||
|
* @version: 1.0
|
||||||
|
* @author: Ambrumf
|
||||||
|
* @date: 2023/10/11
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#define CMD_PORT 9970
|
||||||
|
#define BACKLOG_LEN 128
|
||||||
|
#define MAX_USERS 100
|
||||||
|
#define MAX_CONNECTION 100
|
||||||
|
#define UNLOGED_IN 0
|
||||||
|
#define LOGED_IN 1
|
||||||
|
struct User {
|
||||||
|
char username[50];
|
||||||
|
char password[50];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LoginStatus {
|
||||||
|
char *addr;
|
||||||
|
char username[50];
|
||||||
|
char password[50];
|
||||||
|
int login_status;//登录状态,0代表未登录 1代表已登录
|
||||||
|
};
|
||||||
|
|
||||||
|
struct User users[MAX_USERS];
|
||||||
|
struct LoginStatus login_list[MAX_CONNECTION];
|
||||||
|
|
||||||
|
int CheckPassword(int it){
|
||||||
|
for(int i=0;i<MAX_USERS;i++){
|
||||||
|
if(strcmp(login_list[it]->users[i]->username) == 0 && strcmp(login_list[it]->users[i]->password) == 0)return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *GetAddress(struct sockaddr_in addr) {
|
||||||
|
char *address_string = (char *)malloc(INET_ADDRSTRLEN + 10);
|
||||||
|
|
||||||
|
if (address_string == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char ipStr[INET_ADDRSTRLEN];
|
||||||
|
inet_ntop(AF_INET, &(addr.sin_addr), ipStr, sizeof(ipStr));
|
||||||
|
|
||||||
|
sprintf(address_string, "%s:%d", ipStr, ntohs(addr.sin_port));
|
||||||
|
return address_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *GetRespond(char *buf,int it) {
|
||||||
|
char * cmd-malloc(100);
|
||||||
|
char * data=malloc(100);
|
||||||
|
char * respond=malloc(100);
|
||||||
|
sscanf(buf,"%s %s",cmd,data);
|
||||||
|
if(strcmp(cmd,"USER")==0){
|
||||||
|
login_list[it]->login_status=LOGGED_IN;
|
||||||
|
strcpy(login_list[it]->username,data);
|
||||||
|
sprintf(respond,"331 %d login ok, send your password\n",data);
|
||||||
|
}
|
||||||
|
else if(strcmp(cmd,"PASS")==0){
|
||||||
|
login_list[it]->login_status=LOGGED_IN;
|
||||||
|
if(CheckPassword(it)){
|
||||||
|
sprintf(respond,"230 access granted, restrictions apply\n");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sprintf(respond,"530 password incorrect\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strcmp(cmd,"SIZE")==0){
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(strcmp(cmd,"PASV")==0){
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(strcmp(cmd,"RETR")==0){
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(strcmp(cmd,"STOR")==0){
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
respond = "500 syntax error\n";
|
||||||
|
}
|
||||||
|
return respond;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Init() {
|
||||||
|
memset(login_status,0,sizeof(login_status));
|
||||||
|
memset(users,0,sizeof(users));
|
||||||
|
|
||||||
|
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
printf("Failed to create socket\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in server_addr;
|
||||||
|
server_addr.sin_family = AF_INET;
|
||||||
|
server_addr.sin_port = htons(CMD_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 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
listen(fd, BACKLOG_LEN);
|
||||||
|
printf("Socket created, binding to port 9970\n");
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
struct sockaddr_in client_addr;
|
||||||
|
socklen_t len = sizeof(client_addr);
|
||||||
|
int cmd_fd = accept(fd, (struct sockaddr *)&client_addr, &len);
|
||||||
|
|
||||||
|
char *client_ip;
|
||||||
|
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;
|
||||||
|
for(int i=0;i<MAX_CONNECTION;i++){
|
||||||
|
if(strcmp(GetAddress(client_addr),login_list[it]->addr)){
|
||||||
|
it=i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (it==-1){
|
||||||
|
for(int i=0;i<MAX_CONNECTION;i++){
|
||||||
|
if(login_list[i]->login_status==0){
|
||||||
|
it=i;
|
||||||
|
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 len;
|
||||||
|
len = read(cmd_fd, buf, sizeof(buf));
|
||||||
|
|
||||||
|
if (len < 0) {
|
||||||
|
printf("Failed to read or client closed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
char *respond = GetRespond(buf, it);
|
||||||
|
write(cmd_fd, respond, strlen(respond));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertUser(char * username,char * password)
|
||||||
|
{
|
||||||
|
for(int i=0;i<MAX_USERS;i++){
|
||||||
|
if(strlen(users[i]->username)==0){
|
||||||
|
strcpy(users[i]->username,username);
|
||||||
|
strcpy(users[i]->password,password);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int main() {
|
||||||
|
InsertUser("frank","114514");
|
||||||
|
Init();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -12,6 +12,14 @@ http://license.coscl.org.cn/MulanPSL2
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file: test_ftpclinet.c
|
||||||
|
* @brief: a application of test ftpclient
|
||||||
|
* @version: 1.0
|
||||||
|
* @author: Ambrumf
|
||||||
|
* @date: 2023/10/11
|
||||||
|
*/
|
||||||
|
|
||||||
#include <transform.h>
|
#include <transform.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
Loading…
Reference in New Issue