📄 fatfs.c
字号:
/** Snixos Project version 1.0, 2003.6* (C) Copyright 2003,2004,2005 Jockeyson,KeqiangGao <Snallie@tom.com>* All Rights Reserved.* Distributed under the terms of the GNU General Public License.** This program is a free and open source software and you can redistribute * it and/or modify it under the terms of the GNU General Public License as* published by the Free Software Foundation. As no any liability is assumed * for any incidental or consequential damages in connection with the * information or program fragments contained herein,so any exception arised* is at your own risk. It is ABSOLUTELY WITHOUT ANY WARRANTY.* Bug report please send to Snallie@tom.com .*//* fatfs.c: implementation of FAT-like file system in RAM disk for Snixos Project Author : Snallie@tom.com Time : 2003.6*/#include "fatfs.h"#include "mem.h"#include "stdio.h"extern long tickcount;/* errno, global variable to save errno number while any error occured in operation */int errno;fileDescriptor fileDescriptors[OPEN_MAX];char *errstring[] = { "File name is too long\n", "File name is blank\n", "No such file\n", "Memory allocation error\n", "NO such file descriptor\n"};void initFileSystem(){ diskspace = (char *) malloc(BLKCOUNT * BLKSIZE * sizeof(char)); fat_tab = (int *) malloc(BLKCOUNT * sizeof(int)); dir_tab = (direntry *) malloc(ROOTSIZE * sizeof(direntry)); if (diskspace == NULL || fat_tab == NULL || dir_tab == NULL) { printf("malloc failed in initFileSystem\n"); return; } initfat_tab(fat_tab); initdir_tab(dir_tab);}void initfat_tab(int *fat){ int i; for (i = 0; i < BLKCOUNT; i++) *(fat + i) = VACANT_FAT_ITEM;}void initdir_tab(direntry * dir){ int i; for (i = 0; i < ROOTSIZE; i++) { (dir + i)->filename[0] = ERASED; (dir + i)->filename[1] = 0; (dir + i)->filesize = 0; (dir + i)->firstfat = 0; (dir + i)->datetime = 0; }}void listdir(direntry * dir){ int i, files = 0, sumOfSize = 0;; for (i = 0; i < ROOTSIZE; i++) { if ((dir + i)->filename[0] == (char) ERASED) continue; printf("%-18s\t%8d\t%5d\t%5d\n", (dir + i)->filename, (dir + i)->filesize, (dir + i)->firstfat, (dir + i)->datetime); sumOfSize += (dir + i)->filesize; files++; } printf("\n%d file(s) %d byte(s) occupied, %d byte(s) free\n\n", files, sumOfSize, BLKCOUNT * BLKSIZE - sumOfSize);}/*int seekfat(int *fat)purpose: seek the next vacant FAT allocation unit in fat_tabargument: the address of fat tablereturn: -1 indicate that no available allocation unit in FAT >=0 any positive number indicate a vacant FAT allocation unit retrieved*/int seekfat(int *fat){ int i; for (i = 0; i < BLKCOUNT && *(fat + i) != 0; i++); if (i >= BLKCOUNT) return -1; /* no vacant FAt allocation unit found */ else return i;}/* int wrdir_tab(direntry * dirs, char *fnames, int fsizes, int firstfat)purpose: write directory table with the arguments suppliedargument: dirs, the address directory table fnames, file name to be write to certain directory item fsizes, length of the file to be written to disk firstfat, the first FAT allocation unitreturn: 0, succeed in operation -1, error occured for there is no vacant directory item found in dir_tab -2, error occured for the length of file name exceeded the limit of FILE_NAME_LENGTH*/int wrdir_tab(direntry * dirs, char *fnames, int fsizes, int firstfat){ int i; int tm; i = seekdir_tab(dirs); if (i < 0) { printf("No vacant directory item\n"); return -1; } if ((strlen(fnames) - 1) > FILE_NAME_LENGTH) { printf("File name too long\n"); return -2; } strcpy((dirs + i)->filename, fnames); (dirs + i)->filesize = fsizes; (dirs + i)->firstfat = firstfat; time(&tm); (dirs + i)->datetime = tm; *(fat_tab + firstfat) = EOF_FAT_ITEM; return 0;}/*int seekdir_tab(direntry * dir)purpose: seek a vacant directory item in dir_tabargument: dir points to the address of dir_tabreturn: -1 indcate error occured for there is no vacant directory item in dir_tab >=0 indicate valid directory item found*/int seekdir_tab(direntry * dir){ int i; for (i = 0; i < ROOTSIZE && (dir + i)->filename[0] != (char) ERASED; i++); if (i >= ROOTSIZE) return -1; /* no vacant directory item found */ else return i;}/*int wrfile(char *fnames, char *bufs, int flen)purpose: create a disk file named fnames, bufs points to the data buffer saving data of fnames to be written to disk, flen is the length of data, what the bytes calculated from the beginning of bufs, to be written, return the bytes that have written to disk.arguments: fname, file name bufs, buffer that have saved the data to be writte to disk flen, how many bytes to be writte to disk started from the beginning of the buffer -bufsreturn: -1 error occured for there is already the file on the disk -2 error occured while write file indicating FAT table is full -3 error occured while write file indicating dir_tab is full -4 error occured while write file indicating no vacant directory item found in dir_tab >=0 bytes totally written to disk*/int wrfile(char *fnames, char *bufs, int flen){ int blks, firstfats, fats, nextfats, i = 0, tflen; direntry dirtmp; direntry *dirs = &dirtmp; tflen = flen; blks = flen / BLKSIZE; if (readdir(fnames, dirs)) { printf("File already exists!\n"); return -1; } firstfats = seekfat(fat_tab); if (firstfats < 0) { printf("wrfile: FAT table is full\n"); return -2; } fats = firstfats; *(fat_tab + fats) = EOF_FAT_ITEM; if (wrdir_tab(dir_tab, fnames, flen, firstfats) < 0) { return -3; /* No vacant directory item */ } for (i = 0; i < blks; i++) { /* wrsect(bufs + i * BLKSIZE, fats, ((flen=flen>>9)>BLKSIZE)?BLKSIZE:tflen%BLKSIZE); */ wrsect(bufs + i * BLKSIZE, fats, BLKSIZE); nextfats = seekfat(fat_tab); if (nextfats < 0) { printf("No vacant FAT entry\n"); /* remove the data that have been written partially */ readdir(fnames, dirs); freefat(dirs->firstfat); freedir(fnames); return -4; } /* printf("<i=%d nxt=%d cr=%d>%s",i,nextfats,fats,(i+1)%4?" ":"\n"); */ *(fat_tab + nextfats) = *(fat_tab + fats); *(fat_tab + fats) = nextfats; fats = nextfats; } wrsect(bufs + i * BLKSIZE, fats, flen % BLKSIZE); *(fat_tab + fats) = EOF_FAT_ITEM; /* end of file */ return tflen; /* return the actual size of that have written to disk */}/* void wrsect(char *data, int sectno, int bytes) write bytes bytes started from data to disk sector positioned by sectno*/void wrsect(char *data, int sectno, int bytes){ int i; for (i = 0; i < bytes; i++) { *(diskspace + sectno * BLKSIZE + i) = *(data + i); }}/* rdfile: read file named fnames and save its data to outputbuf return: -1: file dose not exist*/int rdfile(char *fnames, char *outputbuf){ int blks, firstfats, fats, nextfats, i, bytesRead, len, fsize, ptr = 0; direntry dirtmp; direntry *dirs = &dirtmp; char tmpbufs[BLKSIZE]; char *tmpbuf = tmpbufs; if (!readdir(fnames, dirs)) { printf("No such file %s!\n", fnames); return -1; /* file not exist in system */ } blks = dirs->filesize / BLKSIZE; firstfats = dirs->firstfat; nextfats = fats = firstfats; for (i = 0; i < blks; i++) { bytesRead = rdsect(fats, BLKSIZE, tmpbuf); memcpy(outputbuf + ptr, tmpbuf, bytesRead); ptr += bytesRead; nextfats = nextfat(fats); if (nextfats == EOF_FAT_ITEM) break; else fats = nextfats; } bytesRead = rdsect(fats, dirs->filesize % BLKSIZE, tmpbuf); memcpy(outputbuf + ptr, tmpbuf, bytesRead); ptr += bytesRead;}/* rdsect: read a sector from RAM disk and store the data to outputbuf return: the total bytes that read*/int rdsect(int sectno, int cnt, char *outputbuf){ int i; for (i = 0; i < cnt; i++) { *(outputbuf + i) = *(diskspace + sectno * BLKSIZE + i);/* printf("%c", *(diskspace + sectno * BLKSIZE + i)); */ } return i;}int nextfat(int prevfat){ return *(fat_tab + prevfat);}/*readdir: read directory to retrieve the info of fnamesreturn: 0 if no such file named fnames 1 if the file fnames exists in directory, and save its directory information to direntry *dirs*/int readdir(char *fnames, direntry * dirs){ int i; for (i = 0; i < ROOTSIZE && strcmp(fnames, (dir_tab + i)->filename); i++) { ; } if (i < ROOTSIZE) { strcpy(dirs->filename, (dir_tab + i)->filename); dirs->filesize = (dir_tab + i)->filesize; dirs->firstfat = (dir_tab + i)->firstfat; dirs->datetime = (dir_tab + i)->datetime; return 1; /* got it */ } else { return 0; /* no such file fnames */ }}/* int copyFile(char *srcFileName, char *dstFileName) copy source file to destination file */int copyFile(char *srcFileName, char *dstFileName){ direntry dirsrcs, dirs2s; direntry *dirsrc = &dirsrcs, *dirs2 = &dirs2s; char *tmpbuf; if (!readdir(srcFileName, dirsrc)) { printf("No such source file '%s' found\n", srcFileName); return -1; } if (readdir(dstFileName, dirs2)) { printf("destination file '%s' already exists\n", dstFileName); return -2; } tmpbuf = (char *) malloc(dirsrc->filesize * sizeof(char)); if (tmpbuf == NULL) { printf("malloc failed\n"); return; } rdfile(srcFileName, tmpbuf); wrfile(dstFileName, tmpbuf, dirsrc->filesize); free(tmpbuf);}/*void freefat(int firstfat) release the fat link started from firstfat in fat table */void freefat(int firstfat){ int i, j; j = firstfat;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -