?? tfs.c
字號:
register ushort *sto, *sfrom, *send;
count >>= 1;
sto = (ushort *)to;
sfrom = (ushort *)from;
send = sto + count;
while(sto < send) {
*sto = *sfrom;
if (*sto != *sfrom) {
err = 1;
break;
}
sto++;
sfrom++;
}
}
else {
end = to + count;
while(to < end) {
*to = *from;
if (*to != *from) {
err = 1;
break;
}
to++;
from++;
}
}
if (err) {
if (verbose)
printf(" failed\n");
return(TFSERR_MEMFAIL);
}
}
done:
if (verbose)
printf("\n");
return(TFS_OKAY);
}
/* struct tfsran:
Used by tfsrunboot only. No need to put this in tfs.h.
*/
struct tfsran {
char name[TFSNAMESIZE+1];
};
/* tfsrunboot():
* This function is called at monitor startup. It scans the list of
* files built by tfsreorder() and executes each file in the list that has
* the BRUN flag set. As each file is run its name is added to the
* ranlist[] table.
*
* After each file is run, there is a check made to see if the flash has
* been modified. If yes, then tfsreorder() is run again and we start
* over at the top of the list of files organized by tfsreorder(). As
* we step through the tfsAlist[] array, if the file has a BRUN flag set
* but it is already in the ranlist[] table, it is not run again.
*
* This scheme allows a file in the initial list of BRUN files to modify
* the file list without confusing the list of files that are to be run.
* Files (even new BRUN files) can be added to the list by some other BRUN
* file, and these new files will be run.
*/
int
tfsrunboot()
{
extern int pollConsole(char *);
static struct tfsran *ranlist;
char *argv[2];
int rancnt, aidx, ridx, err, fmodcnt;
/* The argv[] array is used by tfsrun(); argv[0] is name of file to be
* executed, argv[1] must be nulled to indicate no command line args
* passed to the BRUN file/script.
*/
argv[1] = (char *)0;
/* Keep a local copy of tfsFmodCount so that we can determine if flash
* was modified by one of the BRUN files executed.
*/
fmodcnt = tfsFmodCount;
/* Create list of file pointers (tfsAlist[]) in alphabetical order
* based on name...
*/
if ((err = tfsreorder()) < 0) {
printf("tfsrunboot() reorder1: %s\n",tfserrmsg(err));
return(-1);
}
/* Clear the ranlist pointer. This pointer is the base address of a
* list of file names that have been run.
*/
rancnt = 0;
ranlist = (struct tfsran *)0;
restartloop:
for (aidx=0;tfsAlist[aidx];aidx++) {
char fname[TFSNAMESIZE+1];
int alreadyran;
TFILE *fp;
struct tfsran *rp;
fp = tfsAlist[aidx];
strcpy(fname,TFS_NAME(fp));
/* If the file has no BRUN flag set, just continue. If a BRUN flag
* is set, then see if the file has already been run. If yes, then
* just continue; else run the file.
*/
alreadyran = 0;
if (fp->flags & (TFS_BRUN | TFS_QRYBRUN)) {
for(ridx=0;ridx<rancnt;ridx++) {
if (!strcmp(ranlist[ridx].name,fname)) {
alreadyran = 1;
break;
}
}
}
else
continue; /* No BRUN flag set. */
if (alreadyran) { /* BRUN flag set, but file has already */
continue; /* been run. */
}
err = TFS_OKAY;
argv[0] = fname;
/* At this point we know the file is a BRUN type, so just see if
* the query should precede the run...
*/
if (fp->flags & TFS_QRYBRUN) {
char query[TFSNAMESIZE+8];
sprintf(query,"%s?",fname);
if (pollConsole(query))
continue;
}
/* Increase the size of the ranlist[] table and add the file that
* is about to be run to that list...
*/
rancnt++;
rp = (struct tfsran*)realloc((char *)ranlist,
rancnt*sizeof(struct tfsran));
if (!rp) {
if (ranlist)
free((char *)ranlist);
printf("tfsrunboot() runlist realloc failure\n");
return(-1);
}
ranlist = rp;
strcpy(ranlist[rancnt-1].name,fname);
/* Run the executable... */
if ((err = tfsrun(argv,0)) != TFS_OKAY)
printf("%s: %s\n",fname,tfserrmsg(err));
/* If flash has been modified, then we must re-run tfsreorder() and
* start over...
*/
if (fmodcnt != tfsFmodCount) {
if ((err = tfsreorder()) < 0) {
printf("tfsrunboot() reorder2: %s\n",tfserrmsg(err));
return(err);
}
fmodcnt = tfsFmodCount;
goto restartloop;
}
}
if (ranlist)
free((char *)ranlist);
return(rancnt);
}
/* tfsreorder():
* Populate the tfsAlist[] array with the list of currently active file
* pointers, but put in alphabetical (lexicographical using strcmp()) order
* based on the filename.
* Note that after each file addition/deletion, this must be re-run.
*/
int
tfsreorder(void)
{
TFILE *fp;
TDEV *tdp;
int i, j, tot;
/* Determine how many valid files exist, and create tfsAlist array: */
tot = 0;
for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) {
fp = (TFILE *)tdp->start;
while(validtfshdr(fp)) {
if (TFS_FILEEXISTS(fp))
tot++;
fp = nextfp(fp,tdp);
}
}
/* If tfsAlist already exists, and is already big enough, then
* don't do any allocation; otherwise, create the array with one extra
* slot for a NULL pointer used elsewhere as an end-of-list indicator.
*/
if (tot > tfsAlistSize) {
tfsAlist = (TFILE **)realloc((char *)tfsAlist,
(tot+1) * sizeof(TFILE **));
if (!tfsAlist) {
tfsAlistSize = 0;
return(TFSERR_MEMFAIL);
}
tfsAlistSize = tot;
}
/* Clear the entire table (plus the extra one at the end): */
for(i=0;i<=tot;i++)
tfsAlist[i] = (TFILE *)0;
/* Populate tfsAlist[] with a pointer to each active file
* in flash as they exist in memory...
*/
i = 0;
for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) {
fp = (TFILE *)tdp->start;
while(validtfshdr(fp)) {
if (TFS_FILEEXISTS(fp)) {
tfsAlist[i++] = fp;
}
fp = nextfp(fp,tdp);
}
}
/* Now run a bubble sort on that list based on the lexicographical
* ordering returned by strcmp...
*/
for(i=1;i<tot;++i) {
for(j=tot-1;j>=i;--j) {
if (strcmp(TFS_NAME(tfsAlist[j-1]),TFS_NAME(tfsAlist[j])) > 0) {
fp = tfsAlist[j-1];
tfsAlist[j-1] = tfsAlist[j];
tfsAlist[j] = fp;
}
}
}
return(tot);
}
/* tfstell():
* Return the offset into the file that is specified by the incoming
* descriptor.
*/
long
tfstell(int fd)
{
if ((fd < 0) || (fd >= TFS_MAXOPEN))
return(TFSERR_BADARG);
return(tfsSlots[fd].offset);
}
/* tfscompare():
* Compare the content of the file specified by tfp with the content pointed
* to by the remaining arguments. If identical, return 0; else return -1.
*/
static int
tfscompare(TFILE *tfp,char *name, char *info, char *flags, uchar *src, int size)
{
char flgbuf[16];
/* Compare size, name, info field, flags and data: */
/* Size... */
if (TFS_SIZE(tfp) != size)
return(-1);
/* Name... */
if (strcmp(name,TFS_NAME(tfp)))
return(-1);
/* Info field... */
if (info) {
if (strcmp(info,TFS_INFO(tfp)))
return(-1);
}
else {
if (TFS_INFO(tfp)[0] != 0)
return(-1);
}
/* Flags... */
tfsflagsbtoa(TFS_FLAGS(tfp),flgbuf);
if (flags) {
if (strcmp(flags,flgbuf))
return(-1);
}
else if (flgbuf[0] != 0)
return(-1);
/* Data... */
if (memcmp(TFS_BASE(tfp),(char *)src,size))
return(-1);
return(0);
}
/* tfsinit():
* Clear out all the flash that is dedicated to the file system.
* This removes all currently stored files and erases the flash.
* MONLIB NOTICE: this function is accessible through monlib.c.
*/
int
_tfsinit(TDEV *tdpin)
{
int ret;
TDEV *tdp;
/* Step through the table of TFS devices and erase each sector... */
for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) {
if (!tdpin || (tdp == tdpin)) {
ret = tfsflasheraseall(tdp);
if (ret != TFS_OKAY)
return(ret);
}
}
return(TFS_OKAY);
}
int
tfsinit(void)
{
if (tfsTrace > 0)
printf("tfsinit()\n");
return(_tfsinit(0));
}
/* tfsSpaceErased():
* Return 0 if the space pointed to by the incoming arguments is not
* erased; else 1.
*/
int
tfsSpaceErased(uchar *begin,int size)
{
uchar *end;
end = begin+size;
while(begin < end) {
if (*begin != 0xff)
return(0);
begin++;
}
return(1);
}
/* tfsFtot():
* Return the number of files in a device, or all devices if tdpin is null.
*/
int
tfsFtot(TDEV *tdpin)
{
int ftot;
TFILE *fp;
TDEV *tdp;
ftot = 0;
for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) {
if (!tdpin || (tdpin == tdp)) {
fp = (TFILE *)tdp->start;
while (fp->hdrsize != ERASED16) {
ftot++;
fp = nextfp(fp,tdp);
}
}
}
return(ftot);
}
/* tfsFileIsOpened():
* Return 1 if file is currently opened; else 0.
*/
int
tfsFileIsOpened(char *name)
{
int i;
struct tfsdat *slot;
slot = tfsSlots;
for (i=0;i<TFS_MAXOPEN;i++,slot++) {
if ((slot->offset >= 0) && !strcmp(slot->hdr.name,name))
return(1);
}
return(0);
}
/* tfsunopen():
* If the incoming file descriptor is valid, mark that file as no-longer
* opened and return TFS_OKAY; else return TFSERR_BADARG.
* descriptor.
*/
static long
tfsunopen(int fd)
{
if ((fd < 0) || (fd >= TFS_MAXOPEN))
return(TFSERR_BADARG);
if (tfsSlots[fd].offset == -1)
return(TFSERR_BADARG);
tfsSlots[fd].offset = -1;
return(TFS_OKAY);
}
/* tfsctrl():
* Provides an ioctl-like interface to tfs.
* Requests supported:
* TFS_ERRMSG: Return error message (char *) corresponding to
* the incoming error number (arg1).
* TFS_MEMUSE: Return the total amount of memory currently in use by
* TFS.
* TFS_MEMAVAIL: Return the amount of memory currently avaialable for
* use in TFS.
* TFS_MEMDEAD: Return the amount of memory currently in use by
* dead files in TFS.
* TFS_DEFRAG: Mechanism for the application to issue
* a defragmentation request.
* Arg1: if 1, then reset after defrag is complete.
* Arg2: verbosity level.
* TFS_TELL: Return the offset into the file specified by the
* incoming file descriptor (arg1).
* TFS_FATOB: Return the binary equivalent of the TFS flags string
* pointed to by arg1.
* TFS_FBTOA: Return the string equivalent of the TFS flags (long)
* in arg1, destination buffer in arg2.
* TFS_UNOPEN: In TFS, a the data is not actually written to FLASH
* until the tfsclose() function is called. This argument
* to tfsctrl() allows a file to be opened and possibly
* written to, then unopened without actually modifying
* the FLASH. The value of arg1 file descriptor to
* apply the "unopen" to.
* TFS_TIMEFUNCS: This ctrl call is used to tell TFS what function
* to call for time information...
* Arg1 is a pointer to:
* (long)getLtime(void)
* - Get Long Time...
* Returns a long representation of time.
* Arg2 is a pointer to:
* (char *)getAtime(long tval,char *buf).
* - Get Ascii Time...
* If tval is zero, the buf is loaded with a string
* representing the current time;
* If tval is non-zero, then buf is loaded with a
* string conversion of the value of tval.
* Note that since it is up to these functions to
* make the conversion between binary version of time
* and ascii version, we don't define the exact meaning
* of the value returne by getBtime().
* TFS_DOCOMMAND: Allows the application to redefine the function
* that is called to process each line of a script.
* This is useful if the application has its own
* command interpreter, but wants to use the scripting
* facilities of the monitor.
* Arg1 is a pointer to the docommand function to be
* used instead of the standard;
* Arg2 is a pointer to a location into which the current
* docommand function pointer can be stored.
* If arg1 is 0, load standard docommand;
* if arg2 is 0, don't load old value.
* TFS_INITDEV: Allows the application to initialize one of TFS's
* devices. Arg1 is a pointer to the device name prefix.
* TFS_DEFRAGDEV: Allows the application to defrag one of TFS's
* devices. Arg1 is a pointer to the device name prefix.
* TFS_CHECKDEV: Allows the application to check one of TFS's
* devices. Arg1 is a pointer to the device name prefix.
*
*
* MONLIB NOTICE: this function is accessible through monlib.c.
*/
long
tfsctrl(int rqst,long arg1,long arg2)
{
long retval, flag;
TDEV *tdp;
TINFO tinfo;
if (tfsTrace > 0)
printf("tfsctrl(%d,0x%lx,0x%lx)\n",rqst,arg1,arg2);
switch(rqst) {
case TFS_ERRMSG:
retval = (long)tfserrmsg(arg1);
break;
case TFS_MEMUSE:
tfsmemuse(0,&tinfo,0);
retval = tinfo.memused;
break;
case TFS_MEMAVAIL:
tfsmemuse(0,&tinfo,0);
retval = tinfo.memfordata;
break;
case TFS_MEMDEAD:
tfsmemuse(0,&tinfo,0);
retval = tinfo.deadovrhd+tinfo.deaddata;
break;
case TFS_INITDEV:
tdp = gettfsdev_fromprefix((char *)arg1,0);
if (!tdp)
retval = TFSERR_BADARG;
else
retval = _tfsinit(tdp);
break;
case TFS_CHECKDEV:
tdp = gettfsdev_fromprefix((char *)arg1,0);
if (!tdp)
retval = TFSERR_BADARG;
else
retval = tfscheck(tdp,0);
break;
case TFS_DEFRAGDEV:
tdp = gettfsdev_fromprefix((char *)arg1,0);
if (!tdp)
retval = TFSERR_BADARG;
else
retval = tfsclean(0,0,0,0,tdp,0,0);
break;
case TFS_DEFRAG:
for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++)
tfsclean(0,0,0,0,tdp,(int)arg1,(int)arg2);
retval = 0;
break;
case TFS_UNOPEN:
retval = tfsunopen((int)arg1);
break;
case TFS_FATOB:
retval = tfsflagsatob((char *)arg1,&flag);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -