📄 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. */inttfsrunboot(){ 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. */inttfsreorder(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. */longtfstell(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 inttfscompare(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);}inttfsinit(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. */inttfsSpaceErased(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. */inttfsFtot(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. */inttfsFileIsOpened(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 longtfsunopen(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. */longtfsctrl(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 + -