📄 tfs_with_appexit_support.c
字号:
uchar *tspace;{ extern ulong APPLICATION_RAMSTART; uchar *tbuf; int delcnt, len, err, nfadd, retval, ilvl; struct tfshdr *fp; delcnt = retval = 0; /* First just see if there are any deleted files. */ /* If not, then our work is already done! */ fp = (struct tfshdr *) TFSSTART; while(validtfshdr(fp)) { if (!fp->flags) delcnt++; fp = nextfp(fp); } if (delcnt == 0) { if (verbose) printf("No cleanup necessary\n"); return(0); } printf("Reconstructing file system with %d dead file%s removed...\n", delcnt,delcnt>1 ? "s":""); /* From this point on, do not allow any interrupts. */ ilvl = intsoff(); if (usedefault) tspace = (uchar *)APPLICATION_RAMSTART; tbuf = tspace; fp = (struct tfshdr *)TFSSTART; nfadd = TFSSTART; while(validtfshdr(fp)) { if (fp->flags) { int i; /* If the file is currently opened, adjust the base address. */ for (i=0;i<TFS_MAXOPEN;i++) { if (fileslots[i].offset != -1) { if (fileslots[i].base == (uchar *)(TFS_BASE(fp))) { fileslots[i].base = (uchar *)TFSSTART; fileslots[i].base += (tbuf-tspace); fileslots[i].base += TFSHDRSIZ; } } } len = fp->filsize + TFSHDRSIZ; if (len % TFS_FSIZEMOD) len += TFS_FSIZEMOD - (len % TFS_FSIZEMOD); nfadd += len; err = tfsmemcpy(tbuf,fp,len,0,0); if (err != TFS_OKAY) { printf("clean: %s\n",tfserrmsg(err)); return(err); } ((struct tfshdr *)tbuf)->next = (struct tfshdr *)nfadd; tbuf += len; } fp = nextfp(fp); } tfsinit(); err = tfsflashwrite(TFSSTART,(uchar *)tspace,(tbuf-(uchar*)tspace)); if (err < 0) { printf("Flash re-write failed\n"); return(TFSERR_FLASHFAILURE); }done: if (reset) monrestart(INITIALIZE); intsrestore(ilvl); return(TFS_OKAY);}#endif/* tfscheck(): Basic TFS sanity check... Step through the file structures and make sure that crc of file data passes.*/static inttfscheck(verbose)int verbose;{ struct tfshdr *fp, *fp1; int corrupted; if (verbose) printf("File system check...\n"); corrupted = 0; fp = (struct tfshdr *) TFSSTART; while(validtfshdr(fp)) { if (fp->flags) { /* Skip test if file is removed. */ if (verbose) printf("%s...",fp->name); if ((!(fp->flags & TFS_IPMOD)) && (crc32(TFS_BASE(fp),fp->filsize) != fp->filcrc)) { printf("TFS crc check failure on '%s'\n", fp->name); corrupted = 1; } else if (verbose) printf(" ok\n"); } fp1 = nextfp(fp); if (!fp1) { corrupted = 1; break; } fp = fp1; } if (corrupted) { putchar(0x07); /* Keyboard beep */ printf("Corrupt File System\n"); return(TFSERR_CORRUPT); } if (tfsflasherased(1)) return(TFSERR_CORRUPT); return (TFS_OKAY);}static inttfscheckfile(name)char *name;{ struct tfshdr *fp; int corrupted; corrupted = 0; fp = (struct tfshdr *) TFSSTART; while(validtfshdr(fp)) { if ((fp->flags) && (!strcmp(name,fp->name)) && (!(fp->flags & TFS_IPMOD))) { if (crc32(TFS_BASE(fp),fp->filsize) != fp->filcrc) { printf("TFS crc check failure on '%s'\n", fp->name); corrupted = 1; } break; } fp = nextfp(fp); } if (corrupted) { putchar(0x07); /* Keyboard beep */ printf("Corrupt File System\n"); printf("Refer to User Manual for Instructions\n"); return(TFSERR_CORRUPT); } return(TFS_OKAY);}static voidtfsclear(){ int i; /* Clear the fileslot[] table indicating that no files are opened. */ for (i = 0; i < TFS_MAXOPEN; i++) fileslots[i].offset = -1; /* Init the time retrieval function pointers to their dummy values. */ tfsGetAtime = dummyAtime; tfsGetLtime = dummyLtime; /* Default to using standard docommand() within scripts. */ tfsDocommand = docommand;#if 0 /* Clear the in-a-script depth count ... */ tfsInaScript = 0; /* Clear the runbootDone flag so that autoboot will occur... */ tfsrunbootDone = 0; /* Flash modification count starts off at zero... */ tfsFmodCount = 0;#endif /* Start off with a buffer for 16 files. This is probably more than */ /* will be used, so it avoids reallocations in tfsreorder(). */ tfsAlistSize = 16; tfsAlist = (TFILE **)malloc((tfsAlistSize+1) * sizeof(TFILE **)); if (!tfsAlist) { printf("tfsclear(): tfsAlist allocation failed\n"); tfsAlistSize = 0; }}/* tfsaipcheck(): Called at startup to clean up any file that may be in AIP mode. A file is in AIP mode if it was in the process of being appended to and a power hit occurred. Refer to notes in tfsclose() for details. There are a few cases to be covered here... 1. there is no AIP file; so there is nothing to do. 2. there is an AIP file, but no other file with the same name... In this case, the AIP file must be copied to another file (with the TFS_AIP flag cleared) and the AIP file is deleted. 3. there is an AIP file and another file with the same name... In this case, the AIP file is simply deleted because the other file with the same name is newer.*/ static voidtfsaipcheck(){ int err; ulong flags; TFILE *tfp, *tfpa; char buf[16]; tfp = (struct tfshdr *) TFSSTART; tfpa = (struct tfshdr *)0; while(validtfshdr(tfp)) { if (tfp->flags) { if (tfpa) { if (!strcmp(TFS_NAME(tfp),TFS_NAME(tfpa))) { tfsunlink(TFS_NAME(tfpa)); return; } } else if (!(TFS_FLAGS(tfp) & TFS_AIPNOT)) { tfpa = tfp; } } tfp = nextfp(tfp); } if (tfpa) { flags = TFS_FLAGS(tfpa) | TFS_AIPNOT; err = tfsadd(TFS_NAME(tfpa),TFS_INFO(tfpa),tfsflagsbtoa(flags,buf), (char *)(TFS_BASE(tfpa)),TFS_SIZE(tfpa)); if (err != TFS_OKAY) printf("%s: %s\n",TFS_NAME(tfpa),tfserrmsg(err)); tfsunlink(TFS_NAME(tfpa)); }}/* tfsstartup(): Called at system startup.*/voidtfsstartup(){ tfsclear(); tfsfixup(3); tfsaipcheck();}/* tfsscript(): Treat the file as a list of commands that should be executed as monitor commands. Step through each line and execute it. If incoming fp is NULL, then assume this is being called by tfscontinue() and we are simply continuing the script from whereever we were earlier. Note that this function IS reentrant despite the fact that latestFp is static... Scripts can call other scripts that call other scripts (etc...) and that works fine because tfsscript() will just use more stack space but it eventually returns through the same function call tree. The purpose of latestFp is to keep track of the most recent file pointer so that it can be accessed again if the script called an binary executable that called mon_appexit() (which does NOT return through the function call tree). WARNING: This works because it makes the assumption that the binary executable DOES NOT call tfsscript().*/static inttfsscript(fp,verbose)struct tfshdr *fp;int verbose;{ static struct tfshdr *latestFp[8]; static int latestFd[8]; char lcpy[CMDLINESIZE]; int tfd, lnsize; /* A non-null value in fp is the norm. */ if (fp) { tfd = tfsopen(fp->name,TFS_RDONLY,0); if (tfd < 0) return(tfd); latestFp[tfsInaScript] = fp; latestFd[tfsInaScript++] = tfd;printf("tfsscript(in) %d fp=0x%x,fd=%d\n",tfsInaScript,fp,tfd); } else { fp = latestFp[tfsInaScript]; tfd = latestFd[tfsInaScript];printf("tfsscript(re-in) %d fp=0x%x,fd=%d\n",tfsInaScript,fp,tfd); } while(1) { lnsize = tfsgetline(tfd,lcpy,CMDLINESIZE); if (lnsize == 0) /* end of file? */ break; if ((lcpy[0] == '\r') || (lcpy[0] == '\n')) /* empty line? */ continue; lcpy[lnsize-1] = 0; /* Remove the newline */ /* Just in case the goto tag was set outside a script, */ /* clear it now. */ if (ScriptGotoTag) { free(ScriptGotoTag); ScriptGotoTag = (char *)0; } /* Execute the command line: */ tfsDocommand(lcpy,verbose); /* If ScriptGotoTag is set, then attempt to reposition the line */ /* pointer to the line that contains the tag. */ if (ScriptGotoTag) { char *lp; int tlen; tlen = strlen(ScriptGotoTag); tfsseek(tfd,0,TFS_BEGIN); while(1) { lnsize = tfsgetline(tfd,lcpy,CMDLINESIZE); if (lnsize == 0) { printf("Tag '%s' not found\n",ScriptGotoTag+2); free(ScriptGotoTag); ScriptGotoTag = (char *)0; return(TFS_OKAY); } if (!strncmp(lcpy,ScriptGotoTag,tlen)) { free(ScriptGotoTag); ScriptGotoTag = (char *)0; break; } } }#if INCLUDE_ETHERNET /* After each line, poll ethernet interface. */ pollethernet();#endif } tfsclose(tfd,0);printf("tfsscript(out) %d fp=0x%x,fd=%d\n",tfsInaScript,fp,tfd); tfsInaScript--; return(TFS_OKAY);}/* gototag(): Used with tfsscript to allow a command to adjust the pointer into the script that is currently being executed. It simply populates the "ScriptGotoTag" pointer with the tag that should be branched to next.*/voidgototag(tag)char *tag;{ if (ScriptGotoTag) free(ScriptGotoTag); ScriptGotoTag = malloc(strlen(tag)+8); sprintf(ScriptGotoTag,"# %s",tag);}/* tfscat(): Print each character of the file until NULL terminate. Replace each instance of CR or LF with CRLF.*/static voidtfscat(struct tfshdr *fp, int more){ int i, lcnt; char *cp; lcnt = 0; cp = (char *) (TFS_BASE(fp)); for(i=0;i<fp->filsize;i++) { if ((*cp == '\r') || (*cp == '\n')) { puts("\r\n"); lcnt++; if (lcnt == more) { if (More() == 0) break; lcnt = 0; } } else putchar(*cp); cp++; }}/* tfsexec: Treat the file as machine code that is COFF or ELF. */static inttfsexec(fp,verbose)int verbose;struct tfshdr *fp;{ int err, (*entry)(), octx; long address; if (fp->flags & TFS_COFF) er
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -