解决一个擦除的bug
This commit is contained in:
204
Drivers/BSP/NET/lftpd/lftpd_io.c
Normal file
204
Drivers/BSP/NET/lftpd/lftpd_io.c
Normal file
@@ -0,0 +1,204 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "ff.h"
|
||||
#include "private/lftpd_io.h"
|
||||
|
||||
static int s_file_open = 0;
|
||||
static FIL s_ftp_file;
|
||||
|
||||
char *lftpd_io_canonicalize_path(const char *base, const char *name)
|
||||
{
|
||||
if (base == NULL) {
|
||||
base = "";
|
||||
}
|
||||
if (name == NULL) {
|
||||
name = "";
|
||||
}
|
||||
|
||||
char *path;
|
||||
if (name[0] == '/') {
|
||||
path = (char *)malloc(strlen(name) + 1);
|
||||
if (path == NULL) return NULL;
|
||||
strcpy(path, name);
|
||||
} else {
|
||||
size_t len = strlen(base) + 1 + strlen(name) + 1;
|
||||
path = (char *)malloc(len);
|
||||
if (path == NULL) return NULL;
|
||||
snprintf(path, len, "%s/%s", base, name);
|
||||
}
|
||||
|
||||
char *abs_path = (char *)malloc(strlen(path) + 2);
|
||||
if (abs_path == NULL) {
|
||||
free(path);
|
||||
return NULL;
|
||||
}
|
||||
abs_path[0] = '\0';
|
||||
|
||||
char *p = path;
|
||||
while (*p != '\0') {
|
||||
while (*p == '/') p++;
|
||||
if (*p == '\0') break;
|
||||
|
||||
char *seg_start = p;
|
||||
while (*p != '\0' && *p != '/') p++;
|
||||
|
||||
char saved = *p;
|
||||
*p = '\0';
|
||||
|
||||
if (strcmp(seg_start, ".") == 0) {
|
||||
/* ignore */
|
||||
} else if (strcmp(seg_start, "..") == 0) {
|
||||
char *slash = strrchr(abs_path, '/');
|
||||
if (slash != NULL) {
|
||||
*slash = '\0';
|
||||
}
|
||||
} else {
|
||||
strcat(abs_path, "/");
|
||||
strcat(abs_path, seg_start);
|
||||
}
|
||||
|
||||
*p = saved;
|
||||
}
|
||||
free(path);
|
||||
|
||||
if (strlen(abs_path) == 0) {
|
||||
strcpy(abs_path, "/");
|
||||
}
|
||||
|
||||
return abs_path;
|
||||
}
|
||||
|
||||
int lftpd_io_open_read(const char *path)
|
||||
{
|
||||
if (s_file_open) {
|
||||
return -1;
|
||||
}
|
||||
if (f_open(&s_ftp_file, path, FA_READ) != FR_OK) {
|
||||
return -1;
|
||||
}
|
||||
s_file_open = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lftpd_io_open_write(const char *path)
|
||||
{
|
||||
if (s_file_open) {
|
||||
return -1;
|
||||
}
|
||||
if (f_open(&s_ftp_file, path, FA_WRITE | FA_CREATE_ALWAYS) != FR_OK) {
|
||||
return -1;
|
||||
}
|
||||
s_file_open = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lftpd_io_read(int handle, void *buf, int len)
|
||||
{
|
||||
(void)handle;
|
||||
UINT br;
|
||||
if (f_read(&s_ftp_file, buf, (UINT)len, &br) != FR_OK) {
|
||||
return -1;
|
||||
}
|
||||
return (int)br;
|
||||
}
|
||||
|
||||
int lftpd_io_write(int handle, const void *buf, int len)
|
||||
{
|
||||
(void)handle;
|
||||
UINT bw;
|
||||
if (f_write(&s_ftp_file, buf, (UINT)len, &bw) != FR_OK) {
|
||||
return -1;
|
||||
}
|
||||
if ((int)bw != len) {
|
||||
return -1;
|
||||
}
|
||||
return (int)bw;
|
||||
}
|
||||
|
||||
void lftpd_io_close(int handle)
|
||||
{
|
||||
(void)handle;
|
||||
if (s_file_open) {
|
||||
f_close(&s_ftp_file);
|
||||
s_file_open = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int lftpd_io_stat(const char *path, uint32_t *p_size, int *p_is_dir)
|
||||
{
|
||||
FILINFO fno;
|
||||
|
||||
if (f_stat(path, &fno) != FR_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (p_size != NULL) {
|
||||
*p_size = (uint32_t)fno.fsize;
|
||||
}
|
||||
if (p_is_dir != NULL) {
|
||||
*p_is_dir = (fno.fattrib & AM_DIR) ? 1 : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lftpd_io_unlink(const char *path)
|
||||
{
|
||||
if (f_unlink(path) == FR_OK) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *lftpd_io_opendir(const char *path)
|
||||
{
|
||||
DIR *dp = (DIR *)malloc(sizeof(DIR));
|
||||
if (dp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (f_opendir(dp, path) != FR_OK) {
|
||||
free(dp);
|
||||
return NULL;
|
||||
}
|
||||
return (void *)dp;
|
||||
}
|
||||
|
||||
int lftpd_io_readdir(void *dp, char *name, int name_max, uint32_t *p_size, int *p_is_dir)
|
||||
{
|
||||
FILINFO fno;
|
||||
FRESULT fr;
|
||||
|
||||
while (1) {
|
||||
fr = f_readdir((DIR *)dp, &fno);
|
||||
if (fr != FR_OK || fno.fname[0] == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (fno.fname[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
strncpy(name, fno.fname, (size_t)(name_max - 1));
|
||||
name[name_max - 1] = '\0';
|
||||
|
||||
if (p_size != NULL) {
|
||||
*p_size = (uint32_t)fno.fsize;
|
||||
}
|
||||
if (p_is_dir != NULL) {
|
||||
*p_is_dir = (fno.fattrib & AM_DIR) ? 1 : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lftpd_io_closedir(void *dp)
|
||||
{
|
||||
if (dp != NULL) {
|
||||
f_closedir((DIR *)dp);
|
||||
free(dp);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user