📄 tfsapi.c
字号:
* Modify "in-place" a portion of a file in TFS. * This is a cheap and dirty way to modify a file... * The idea is that a file is created with a lot of writeable flash space * (data = 0xff). This function can then be called to immediately modify * blocks of space in that flash. It will not do any tfsunlink/tfsadd, and * it doesn't even require a tfsopen() tfsclose() wrapper. Its a fast and * efficient way to modify flash in the file system. * Arguments: * name = name of the file to be in-place-modified; * buf = new data to be written to flash; * offset = offset into file into which new data is to be written; * size = size of new data (in bytes). * * With offset of -1, set offset to location containing first 0xff value. * MONLIB NOTICE: this function is accessible through monlib.c. */inttfsipmod(char *name,char *buf,int offset,int size){ TFILE *fp; uchar *cp; fp = tfsstat(name); if (!fp) return (TFSERR_NOFILE); if (!(fp->flags & TFS_IPMOD)) return(TFSERR_NOTIPMOD); if (offset == -1) { cp = (uchar *)(TFS_BASE(fp)); for (offset=0;offset<fp->filsize;offset++,cp++) { if (*cp == 0xff) break; } } else if (offset < -1) return(TFSERR_BADARG); if ((offset + size) > fp->filsize) return(TFSERR_WRITEMAX); /* BUG fixed: 2/21/2001: * The (ulong *) cast was done prior to adding offset to the base. * This caused the offset to be quadrupled. */ if (tfsflashwrite((ulong *)(TFS_BASE(fp)+offset),(ulong *)buf,size) == -1) return (TFSERR_FLASHFAILURE); tfslog(TFSLOG_IPM,name); return(TFS_OKAY);}/* tfsopen(): * Open a file for reading or creation. If file is opened for writing, * then the caller must provide a RAM buffer pointer to be used for * the file storage until it is transferred to flash by tfsclose(). * Note that the "buf" pointer is only needed for opening a file for * creation or append (writing). * MONLIB NOTICE: this function is accessible through monlib.c. */inttfsopen(char *file,long flagmode,char *buf){ register int i; int errno, retval; long fmode; TFILE *fp; struct tfsdat *slot; errno = TFS_OKAY; fmode = flagmode & (TFS_RDONLY | TFS_APPEND | TFS_CREATE); /* See if file exists... */ fp = tfsstat(file); /* If file exists, do a crc32 on the data. * If the file is in-place-modifiable, then the only legal flagmode * is TFS_RDONLY. Plus, in this case, the crc32 test is skipped. */ if (fp) { if (!((fmode == TFS_RDONLY) && (fp->flags & TFS_IPMOD))) { if (crc32(TFS_BASE(fp),fp->filsize) != fp->filcrc) { retval = TFSERR_BADCRC; goto done; } } } /* This switch verifies... * - that the file exists if TFS_RDONLY or TFS_APPEND * - that the file does not exist if TFS_CREATE */ switch(fmode) { case TFS_RDONLY: /* Read existing file only, no change to file at all. */ if (!fp) errno = TFSERR_NOFILE; else { if ((fp->flags & TFS_UNREAD) && (TFS_USRLVL(fp) > getUsrLvl())) errno = TFSERR_USERDENIED; } break; case TFS_APPEND: /* Append to the end of the current file. */ if (!fp) errno = TFSERR_NOFILE; else { if (TFS_USRLVL(fp) > getUsrLvl()) errno = TFSERR_USERDENIED; } break; case TFS_CREATERM: /* Create a new file, allow tfsadd() to remove it */ break; /* if it exists. */ case TFS_CREATE: /* Create a new file, error if it exists. */ if (fp) errno = TFSERR_FILEEXISTS; break; case (TFS_APPEND|TFS_CREATE): /* If both mode bits are set, clear one */ if (fp) { /* based on the presence of the file. */ if (TFS_USRLVL(fp) > getUsrLvl()) errno = TFSERR_USERDENIED; fmode = TFS_APPEND; } else { fmode = TFS_CREATE; } break; default: errno = TFSERR_BADARG; break; } if (errno != TFS_OKAY) { retval = errno; goto done; } /* Find an empty slot... */ slot = tfsSlots; for (i=0;i<TFS_MAXOPEN;i++,slot++) { if (slot->offset == -1) break; } /* Populate the slot structure if a slot is found to be * available... */ if (i < TFS_MAXOPEN) { retval = i; slot->hwp = 0; slot->offset = 0; slot->flagmode = fmode; if (fmode & TFS_CREATE) { strncpy(slot->hdr.name,file,TFSNAMESIZE); slot->flagmode |= (flagmode & TFS_FLAGMASK); slot->base = (uchar *)buf; } else if (fmode & TFS_APPEND) { slot->hdr = *fp; if (tfsmemcpy(buf,(uchar *)(TFS_BASE(fp)), fp->filsize,0,0) != 0) { retval = TFSERR_MEMFAIL; goto done; } slot->flagmode = fp->flags; slot->flagmode |= TFS_APPEND; slot->base = (uchar *)buf; slot->hwp = fp->filsize; slot->offset = fp->filsize; } else { slot->base = (uchar *) (TFS_BASE(fp)); slot->hdr = *fp; } } else { retval = TFSERR_NOSLOT; }done: if (tfsTrace > 0) printf("tfsopen(%s,0x%lx,0x%lx)=%d\n",file,flagmode,(ulong)buf,retval); return(retval);}/* tfsclose(): * If the file was opened for reading only, then just close out the * entry in the tfsSlots table. If the file was opened for creation, * then add it to the tfs list. Note the additional argument is * only needed for tfsclose() of a newly created file. * info = additional text describing the file. * MONLIB NOTICE: this function is accessible through monlib.c. */inttfsclose(int fd,char *info){ int err; struct tfsdat *tdat; if (!info) info = ""; if (tfsTrace > 0) printf("tfsclose(%d,%s)\n",fd,info); if ((fd < 0) || (fd >= TFS_MAXOPEN)) return(TFSERR_BADARG); tdat = &tfsSlots[fd]; if (tdat->offset == -1) return(TFSERR_BADFD); /* Mark the file as closed by setting the offset to -1. * Note that this is done prior to potentially calling tfsadd() so * that tfsadd() will not think the file is opened and reject the add... */ tdat->offset = -1; /* If the file was opened for creation or append, then add it now. */ if (tdat->flagmode & (TFS_CREATE | TFS_APPEND)) { char buf[16]; err = tfsadd(tdat->hdr.name, info, tfsflagsbtoa(tdat->flagmode,buf), tdat->base, tdat->hwp); if (err != TFS_OKAY) { printf("%s: %s\n",tdat->hdr.name,tfserrmsg(err)); return(err); } } return(TFS_OKAY);}#else /* INCLUDE_TFSAPI */inttfstruncate(int fd, long len){ return(TFSERR_NOTAVAILABLE);}inttfseof(int fd){ return(TFSERR_NOTAVAILABLE);}inttfsread(int fd, char *buf, int cnt){ return(TFSERR_NOTAVAILABLE);}inttfswrite(int fd, char *buf, int cnt){ return(TFSERR_NOTAVAILABLE);}inttfsseek(int fd, int offset, int whence){ return(TFSERR_NOTAVAILABLE);}inttfsopen(char *file,long flagmode,char *buf){ return(TFSERR_NOTAVAILABLE);}inttfsclose(int fd,char *info){ return(TFSERR_NOTAVAILABLE);}inttfsgetline(int fd,char *buf,int max){ return(TFSERR_NOTAVAILABLE);}inttfsipmod(char *name,char *buf,int offset,int size){ return(TFSERR_NOTAVAILABLE);}#endif /* INCLUDE_TFSAPI else */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -