⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tfs_with_appexit_support.c

📁 flash文件系统实现
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -