📄 filesys.c
字号:
(dbl->flags & FSDIR_F_SUBDIR))
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1; /* image not writeable or file is still open or directory */
}
/* remove directory entry (delete the file) */
fs_removeDirEntry(rb, b);
SYS_MTASK_UNLOCK(fsTaskLock_g);
return 0;
}
/* Rename a file in a writable RAM-Drive.
*/
sint_t fsys_rename(const char *from, const char *to)
{
FSROOTBLOCK_t *rb;
FSDIRBLOCK_t *dbl;
u32_t b;
sint_t img;
char *fn;
if (fsInitialized_g == 0)
return -1;
if (fs_containWildcard(from) || fs_containWildcard(to))
return -1;
SYS_MTASK_LOCK(fsTaskLock_g);
fn = fs_validateFileName(from);
b = fs_findFile(&img, fn);
if (b == 0)
{
/* file 'from' not found */
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1;
}
rb = FSROOTBLOCK(img);
dbl = fs_getDirBlock(rb, b);
if (ISREADONLY(img) ||
fs_isFileOpened(fn, 0))
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1; /* image not writeable or file is still open */
}
#if FS_SUBDIRECTORIES
if (dbl->flags & FSDIR_F_SUBDIR)
{
if (fs_isDirEmpty(fn, NULL) <= 0)
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1; /* error or directory not empty */
}
}
#endif /* FS_SUBDIRECTORIES */
fn = fs_validateFileName(to);
if ((*fn == 0) || (sysStrlen(fn) >= rb->maxFilenameLength))
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1;
}
b = fs_findFile(&img, fn);
if (b != 0)
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1; /* there exist already a file with the name 'to' */
}
sysStrcpy(dbl->filename, fn);
SYS_MTASK_UNLOCK(fsTaskLock_g);
return 0;
}
/* Replace an old file by a new file.
*/
sint_t fsys_replace(const char *oldfile, const char *newfile)
{
FSROOTBLOCK_t *rb;
FSDIRBLOCK_t *dblo, *dbln;
u32_t b;
sint_t img;
char *fn;
if (fsInitialized_g == 0)
return -1;
if (fs_containWildcard(oldfile) || fs_containWildcard(newfile))
return -1;
SYS_MTASK_LOCK(fsTaskLock_g);
fn = fs_validateFileName(newfile);
if (*fn == 0)
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1;
}
b = fs_findFile(&img, fn);
if (b == 0)
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1; /* the file does not exist */
}
rb = FSROOTBLOCK(img);
if (ISREADONLY(img))
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1; /* the image is not writeable */
}
dbln = fs_getDirBlock(rb, b);
fn = fs_validateFileName(oldfile);
if (*fn == 0)
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1;
}
b = fs_findFile(&img, fn);
if (b == 0)
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1; /* the file does not exist */
}
rb = FSROOTBLOCK(img);
if (ISREADONLY(img))
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1; /* the image is not writeable */
}
dblo = fs_getDirBlock(rb, b);
/* rename new file to the name the old file has */
sysStrcpy(dbln->filename, dblo->filename);
if (!fs_isFileOpened(fn, 0))
{
/* delete the old file */
fs_removeDirEntry(rb, b);
}
else
{
/* The old file is yet in use.
* We mark the old file so it will
* be deleted as soon it is closed.
*/
dblo->flags |= FSDIR_F_IGNORE | FSDIR_F_DELONCLOSE;
}
SYS_MTASK_UNLOCK(fsTaskLock_g);
return 0;
}
/* Get some status information about a file.
*/
sint_t fsys_stat(const char *fname, struct fsys_stat *stat)
{
FSROOTBLOCK_t *rb;
FSDIRBLOCK_t *dbl;
sint_t img;
u32_t b;
if (fsInitialized_g == 0)
return -1;
SYS_MTASK_LOCK(fsTaskLock_g);
b = fs_findFile(&img, fs_validateFileName(fname));
if (b == 0)
{
/* file not found */
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1;
}
rb = FSROOTBLOCK(img);
dbl = fs_getDirBlock(rb, b);
stat->st_time = dbl->time;
stat->st_size = dbl->filesize;
stat->st_mode = (dbl->flags & FSDIR_F_SUBDIR) ? FSS_IFDIR :
(FSS_IFREG|FSS_IREAD| (ISREADONLY(img) ? 0 : FSS_IWRITE));
SYS_MTASK_UNLOCK(fsTaskLock_g);
return 0;
}
/* delete all files from a writeable image
*/
sint_t fsys_format(u32_t blocksize, u32_t maxFilenameLength)
{
sint_t img, rc = -1;
SYS_MTASK_LOCK(fsTaskLock_g);
/* find writeable image and format it */
img = fs_getWriteableImage();
if (img >= 0)
{
fs_closeAllFiles();
rc = fs_formatImage(img, blocksize, maxFilenameLength);
}
SYS_MTASK_UNLOCK(fsTaskLock_g);
return rc;
}
/* returns the free drive space in bytes
*/
u32_t fsys_free(void)
{
FSROOTBLOCK_t *rb;
sint_t img;
u32_t blocks, b;
SYS_MTASK_LOCK(fsTaskLock_g);
img = fs_getWriteableImage();
if (img < 0)
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return 0;
}
rb = FSROOTBLOCK(img);
b = rb->freeBlocksList;
blocks = 0;
while (b != 0)
{
blocks++;
b = fs_getBlock(rb, b)->nextBlock;
}
b = FS_DATABYTESPERBLOCK(rb) * blocks;
SYS_MTASK_UNLOCK(fsTaskLock_g);
return b;
}
/* shrink an image to minimum size
*/
u32_t fsys_shrinkImage(void *image)
{
FSROOTBLOCK_t *rb = (FSROOTBLOCK_t*) image;
u32_t b, lb, cb, c, s;
sint_t f = 0;
cb = rb->driveSize / rb->bytesPerBlock;
s = cb * rb->bytesPerBlock;
c = 0;
do
{
cb--;
lb = 0;
b = rb->freeBlocksList;
f = 0;
while (b != 0)
{
if (b == cb)
{
if (lb == 0)
{
rb->freeBlocksList = fs_getBlock(rb, b)->nextBlock;
}
else
{
fs_getBlock(rb, lb)->nextBlock = fs_getBlock(rb, b)->nextBlock;
}
c++;
f = 1;
break;
}
lb = b;
b = fs_getBlock(rb, b)->nextBlock;
}
}
while ((cb > 2) && (f != 0));
s -= c * rb->bytesPerBlock;
rb->driveSize = s;
return s;
}
/*-------------------------------------------------------------------------*/
/* find next file in the directory */
static s32_t fs_findnext(FSSEARCH_t *fs, struct fsys_finddata *fileinfo)
{
FSROOTBLOCK_t *rb;
FSDIRBLOCK_t *dbl;
sint_t i, joker, sl;
s32_t block;
if (fs->image < 0)
{
fs->image = -1;
fs->dirblock = 0;
rb = NULL;
}
else
{
rb = FSROOTBLOCK(fs->image);
}
for (i = 0; (fs->mask[i] != 0) && (fs->mask[i] != '*'); i++);
joker = (fs->mask[i] != 0) ? i : -1;
for (;;)
{
while ((fs->dirblock != 0) &&
(fs_getDirBlock(rb, fs->dirblock)->flags & FSDIR_F_DELETED))
{
fs->dirblock = fs_getDirBlock(rb, fs->dirblock)->firstFileBlock;
}
if (fs->dirblock == 0)
{
for (fs->image++; (fs->image < FS_MAXIMAGES) &&
(FSROOTBLOCK(fs->image) == NULL); fs->image++);
if (fs->image >= FS_MAXIMAGES)
{
fs->image = -1;
return -1;
}
rb = FSROOTBLOCK(fs->image);
fs->dirblock = rb->firstDirBlock;
continue;
}
dbl = fs_getDirBlock(rb, fs->dirblock);
block = (s32_t) fs->dirblock;
fs->dirblock = dbl->nextBlock;
sl = 0;
#if FS_SUBDIRECTORIES
i = (joker >= 0) ? joker : sysStrlen(fs->mask);
if (i < (sint_t)sysStrlen(dbl->filename))
{
for (; dbl->filename[i] != 0; i++)
{
if (dbl->filename[i] == '/')
{
sl = 1;
break;
}
}
}
#else /* FS_SUBDIRECTORIES */
if (dbl->flags & FSDIR_F_SUBDIR)
sl = 1;
#endif /* FS_SUBDIRECTORIES */
if ((sl == 0) &&
!(dbl->flags & FSDIR_F_IGNORE) && ((joker == 0) ||
((joker < 0) && (sysStricmp(dbl->filename, fs->mask) == 0)) ||
((joker >= 0) && (sysStrnicmp(dbl->filename, fs->mask, joker) == 0))))
break;
}
sysStrcpy(fileinfo->name, dbl->filename);
#if FS_SUBDIRECTORIES
i = sysStrlen(fileinfo->name);
while ((i > 0) && (fileinfo->name[i-1] != '/')) i--;
if (i > 0) sysStrcpy(fileinfo->name, fileinfo->name + i);
#endif /* FS_SUBDIRECTORIES */
fileinfo->size = dbl->filesize;
fileinfo->time = dbl->time;
fileinfo->attrib = (ISREADONLY(fs->image) ? FSA_RDONLY : 0) |
((dbl->flags & FSDIR_F_SUBDIR) ? FSA_SUBDIR : 0);
return block;
}
/* find first file. returns a handle on success or -1 on error */
sint_t fsys_findfirst(char *filespec, struct fsys_finddata *fileinfo)
{
sint_t i;
char *mask;
if ((filespec == NULL) || (fileinfo == NULL))
return -1;
SYS_MTASK_LOCK(fsTaskLock_g);
for (i = 0; (i < FS_MAXFILES) && (fsSearchList_g[i].image >= 0); i++);
mask = fs_validateFileName(filespec);
if ((i >= FS_MAXFILES) || (*mask == 0))
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1;
}
sysStrcpy(fsSearchList_g[i].mask, mask);
if (fs_findnext(&fsSearchList_g[i], fileinfo) < 0)
{
fsSearchList_g[i].image = -1;
i = -1;
}
SYS_MTASK_UNLOCK(fsTaskLock_g);
return i;
}
/* find next file. returns zero on success or -1 on error */
sint_t fsys_findnext(sint_t handle, struct fsys_finddata *fileinfo)
{
s32_t rc;
if (((uint_t) handle >= FS_MAXFILES) || (fileinfo == NULL))
return -1;
SYS_MTASK_LOCK(fsTaskLock_g);
if (fsSearchList_g[handle].image < 0)
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1;
}
rc = fs_findnext(&fsSearchList_g[handle], fileinfo);
SYS_MTASK_UNLOCK(fsTaskLock_g);
return (rc < 0) ? -1 : 0;
}
/* returns zero on success or -1 when no more files are matching */
sint_t fsys_findclose(sint_t handle)
{
struct fsys_finddata fileinfo;
sint_t rc;
if ((uint_t) handle >= FS_MAXFILES)
return -1;
rc = fsys_findnext(handle, &fileinfo);
SYS_MTASK_LOCK(fsTaskLock_g);
fsSearchList_g[handle].image = -1;
SYS_MTASK_UNLOCK(fsTaskLock_g);
return rc;
}
/*-------------------------------------------------------------------------*/
#if FS_SUBDIRECTORIES
/* make a new subdirectory */
sint_t fsys_mkdir(const char *pathname)
{
FSROOTBLOCK_t *rb;
sint_t l, img;
u32_t d;
SYS_MTASK_LOCK(fsTaskLock_g);
l = fsys_buildPathName(fnbuffer_g, pathname, "");
if (l < 0)
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1;
}
if ((l == 0) ||
((fnbuffer_g[0] == '/') && (fnbuffer_g[1] == 0)))
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1;
}
fnbuffer_g[l-1] = 0;
d = fs_newFile(&img, fnbuffer_g, 0);
if (d == 0)
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1;
}
rb = FSROOTBLOCK(img);
fs_getDirBlock(rb, d)->flags |= FSDIR_F_SUBDIR;
SYS_MTASK_UNLOCK(fsTaskLock_g);
return 0;
}
/* remove a subdirectory */
sint_t fsys_rmdir(const char *pathname)
{
FSROOTBLOCK_t *rb;
char *dirname;
sint_t img;
u32_t d;
SYS_MTASK_LOCK(fsTaskLock_g);
if (fs_isDirEmpty(pathname, &dirname) <= 0)
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1; /* error or directory not empty */
}
d = fs_findFile(&img, dirname);
rb = FSROOTBLOCK(img);
if ((d == 0) ||
!(fs_getDirBlock(rb, d)->flags & FSDIR_F_SUBDIR) ||
ISREADONLY(img))
{
SYS_MTASK_UNLOCK(fsTaskLock_g);
return -1; /* directory not valid */
}
fs_removeDirEntry(rb, d);
SYS_MTASK_UNLOCK(fsTaskLock_g);
return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -