?? tfs_with_appexit_support.c
字號:
return(flag);}/* tfslog(): This function is called by tfsadd(), tfsunlink() and tfsipmod() to write to a log file indicating that something in tfs has been changed. Note that the function can be called at any user level, but it must be able to modify the TFS_CHANGELOG_FILE that has "u3" flags. The user level must be temporarily upped to MAXUSRLEVEL for this.*/static voidtfslog(int action, char *string){ static char buf[TFS_CHANGELOG_SIZE]; TFILE *tfp; char *bp, *eol, *eob, *logaction, tbuf[32]; int newfsize, fsize, lsize, tfd, err, len, oulvl, tbuflen; switch(action) { case TFSLOG_ADD: case TFSLOG_DEL: /* Return here if the tfslog() call is on */ case TFSLOG_IPM: /* the TFS_CHANGELOG_FILE itself. */ if (!strcmp(string,TFS_CHANGELOG_FILE) || !changeLog) return; break; case TFSLOG_ON: if (changeLog == 1) return; changeLog = 1; break; case TFSLOG_OFF: if (changeLog == 0) return; changeLog = 0; break; } oulvl = setUserLevel(MAXUSRLEVEL,0); logaction = tfslogaction[action]; tfp = tfsstat(TFS_CHANGELOG_FILE); tfsGetAtime(0,tbuf,sizeof(tbuf)); tbuflen = strlen(tbuf); if (tfp) { tfd = tfsopen(TFS_CHANGELOG_FILE,TFS_RDONLY,0); fsize = tfsread(tfd,buf,TFS_CHANGELOG_SIZE); tfsclose(tfd,0); newfsize = (fsize+strlen(logaction)+strlen(string)+3); if (tbuflen) newfsize += tbuflen + 3; eob = buf + fsize; /* If newfsize is greater than the maximum size the file is */ /* allowed to grow, then keep removing the first line */ /* (oldest entry) until new size is within the limit... */ if (newfsize > TFS_CHANGELOG_SIZE) { lsize = 0; eol = buf; while ((newfsize-lsize) > TFS_CHANGELOG_SIZE) { while((*eol != '\r') && (*eol != '\n')) eol++; while((*eol == '\r') || (*eol == '\n')) eol++; lsize = eol-buf; } fsize -= lsize; newfsize -= lsize; eob -= lsize; memcpy(buf,eol,fsize); } if (tbuflen) sprintf(eob,"%s: %s @ %s\n",logaction,string,tbuf); else sprintf(eob,"%s: %s\n",logaction,string); err = tfsunlink(TFS_CHANGELOG_FILE); if (err < 0) printf("%s: %s\n",TFS_CHANGELOG_FILE, (char *)tfsctrl(TFS_ERRMSG,err,0)); err = tfsadd(TFS_CHANGELOG_FILE,0,"u3",buf,newfsize); if (err < 0) printf("%s: %s\n",TFS_CHANGELOG_FILE, (char *)tfsctrl(TFS_ERRMSG,err,0)); } else { if (tbuflen) len = sprintf(buf,"%s: %s @ %s\n",logaction,string,tbuf); else len = sprintf(buf,"%s: %s\n",logaction,string); err = tfsadd(TFS_CHANGELOG_FILE,0,"u3",buf,len); if (err < 0) printf("%s: %s\n",TFS_CHANGELOG_FILE, (char *)tfsctrl(TFS_ERRMSG,err,0)); } setUserLevel(oulvl,0);}/* validtfshdr(): Return 1 if the header pointed to by the incoming header pointer is valid. Else return 0. The header crc is calculated based on the hdrcrc and next members of the structure being zero. Note that if the file is deleted, then just ignore the crc and return 1.*/static intvalidtfshdr(hdr)struct tfshdr *hdr;{ struct tfshdr hdrcpy; ulong hdrcrc; /* A few quick checks... */ if (!hdr) /* Valid header pointer? */ return(0); if (hdr->flags == 0) /* Flags indicate that file is deleted. */ return(1); if (!(hdr->flags & TFS_AIPNOT)) /* Flags indicate taht file is in AIP */ return(1); /* state, so hdr crc will be bad. */ if (hdr->hdrsize == ERASED16) /* End of stored files. */ return(0); hdrcpy = *hdr; hdrcrc = hdr->hdrcrc; hdrcpy.hdrcrc = 0; hdrcpy.next = 0; if (crc32(&hdrcpy,TFSHDRSIZ) == hdrcrc) return(1); else return(0);}/* nextfp(): Used as a common means of retrieving the next file header pointer. It does some sanity checks based on the fact that all pointers must fall within the TFSSTART<->TFSEND memory range and since each file is placed just after the previous one in linear memory space, fp->next should always be greater than fp.*/static struct tfshdr *nextfp(fp)struct tfshdr *fp;{ if ((fp < (struct tfshdr *)TFSSTART) || (fp > (struct tfshdr *)TFSEND) || (fp->next < (struct tfshdr *)TFSSTART) || (fp->next > (struct tfshdr *)TFSEND) || (fp->next <= fp)) { printf("Bad TFS file hdr at: 0x%x\n",fp); return(0); } return(fp->next);}/* tfsflasherased(): Jump to the point in flash after the last file in TFS, then verify that all remaining flash that is dedicated to TFS is erased (0xff). If erased, return 1; else return 0.*/static inttfsflasherased(int verbose){ struct tfshdr *tfp; ulong *lp; if (verbose) printf("Flash after last TFS file... "); tfp = (struct tfshdr *)TFSSTART; while(validtfshdr(tfp)) tfp = nextfp(tfp); lp = (ulong *)tfp; while (lp < (ulong *)TFSEND) { if (*lp != ERASED32) { if (verbose) printf("not erased at 0x%x\n",lp); return(0); } lp++; } if (verbose) printf("ok\n"); return(1);}/* tfsld(): If the filename specified is AOUT, COFF or ELF, then load it.*/static inttfsld(char *name,int verbose,int verifyonly){ int err; struct tfshdr *fp; err = TFS_OKAY; fp = tfsstat(name); if (!fp) return (TFSERR_NOFILE); if (TFS_USRLVL(fp) > UserLevel) return(TFSERR_USERDENIED); if (fp->flags & (TFS_COFF | TFS_ELF | TFS_AOUT)) { if (fp->flags & TFS_COFF) err = tfsloadcoff(fp,verbose,0,verifyonly); else if (fp->flags & TFS_ELF) err = tfsloadelf(fp,verbose,0,verifyonly); else if (fp->flags & TFS_AOUT) err = tfsloadaout(fp,verbose,0,verifyonly); } else err = TFSERR_BADHDR; return(err);}/* listfilter(): If the incoming filename (fname) passes the incoming filter, then return 1; else return 0. Examples: if filter is "*.html" and fname is "index.html" return 1. if filter is "dir/*" and fname is "dir/abc" return 1. if filter is "dir/" and fname is "dir/abc" return 1. Notes: * If no asterisk is present, assume it is appended to the end of the filter; hence the filter is a prefix. * A valid filter will have the asterisk as either the first or last character of the filter. If first, assume filter is a suffix, if last (or none at all), assume filter is a prefix. * If there is an asterisk in the middle of the filter, it is chopped at the asterisk without warning.*/intlistfilter(char *filter,char *fname){ int flen; char *prefix, *suffix, *asterisk, *sp; if (!filter) /* No filter means match everything. */ return(1); flen = 0; prefix = suffix = (char *)0; asterisk = strchr(filter,'*'); if (asterisk == filter) { suffix = asterisk+1; flen = strlen(suffix); sp = fname + strlen(fname) - flen; if (!strcmp(suffix,sp)) return(1); } else { if (asterisk) *asterisk = 0; prefix = filter; flen = strlen(prefix); if (!strncmp(prefix,fname,flen)) return(1); } return(0);}/* tfsvlist(): verbose list... Display all files currently stored. Do not put them in alphabetical order; display them as they are physically listed in the file system. Display complete structure of file header for each file. Note1: This version of file listing is only called if "tfs -vv ls" or "tfs -vvv ls" is called. The first level of verbosity is handled by tfsqlist to simply display the "dot" files.*/static inttfsvlist(char *filter, int verbose,int more){ struct tfshdr *fp; int tot; char tbuf[32]; fp = (struct tfshdr *) TFSSTART; tot = 0; while(validtfshdr(fp)) { if ((fp->flags == 0) && (verbose < 3)) { fp = nextfp(fp); continue; } if (!listfilter(filter,TFS_NAME(fp))) { fp = nextfp(fp); continue; } if ((fp->flags & TFS_UNREAD) && (TFS_USRLVL(fp) > UserLevel)) { fp = nextfp(fp); continue; } if (fp->flags) printf(" Name: '%s'\n", fp->name); else printf(" Name: '%s' (deleted)\n", fp->name); printf(" Info: '%s'\n", fp->info); if (fp->flags) tfsprflags(fp->flags, 1); printf(" Addr: 0x%x (hdr @ 0x%x, nxtptr = 0x%x)\n", TFS_BASE(fp),fp,fp->next); printf(" Size: 0x%x (%d) bytes\n", fp->filsize, fp->filsize); if (TFS_TIME(fp) != TIME_UNDEFINED) printf(" Time: %s\n", tfsGetAtime(TFS_TIME(fp),tbuf,sizeof(tbuf))); printf("\n"); tot++; fp = nextfp(fp); if ((more) && ((tot % 2) == 0)) if (!More()) return(TFS_OKAY); } printf("\nTotal: %d accessible file%s.\n",tot,tot == 1 ? "" : "s"); printf("Memory Usage: %d bytes (%d bytes of that is dead space)\n", tfsmemuse(), tfsmemdead()); printf("TFS Address Range: 0x%x - 0x%x\n",TFSSTART,TFSEND); return (TFS_OKAY);}/* tfsqlist(): quiet list... Display list of files in alphabetical order. Display only the name and flag summary. Note: a file with a leading dot ('.') is invisible unless verbose is set.*/static inttfsqlist(char *filter, int verbose, int more){ extern char *strchr(); struct tfshdr *fp; char *name, fbuf[16], tbuf[32]; int idx, listed, plen, err; idx = listed = 0; if ((err = tfsreorder()) < 0) return(err); printf(" Name Size Location Flags\n"); while(fp = tfsAlist[idx]) { name = TFS_NAME(fp); if (((name[0] == '.') && (!verbose)) || (!listfilter(filter,name)) || ((fp->flags & TFS_UNREAD) && (TFS_USRLVL(fp) > UserLevel))) { idx++; continue; } printf(" %-23s %6d 0x%08x %s\n",TFS_NAME(fp),TFS_SIZE(fp), TFS_BASE(fp),tfsflagsbtoa(TFS_FLAGS(fp),fbuf)); idx++; listed++; if ((more) && ((listed % 12) == 0)) if (!More()) return(TFS_OKAY); } printf("\nTotal: %d accessible file%s.\n",listed,listed == 1 ? "" : "s"); return (TFS_OKAY);}/* tefmemuse(): Return the amount of FLASH that is currently being used by the file system.*/static longtfsmemuse(void){ struct tfshdr *fp; long tot; tot = 0; fp = (struct tfshdr *) TFSSTART; while(validtfshdr(fp)) { tot += TFSHDRSIZ; tot += fp->filsize; fp = nextfp(fp); } return(tot);}/* tfsmemdead(): Return the amount of memory space currently used by dead (deleted) files.*/static longtfsmemdead(void){ struct tfshdr *fp; long tot; tot = 0; fp = (struct tfshdr *) TFSSTART; while(validtfshdr(fp)) { if (fp->flags == 0) { tot += TFSHDRSIZ; tot += fp->filsize; } fp = nextfp(fp); } return(tot);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -