/* ls(): * Just list current set of files in TFS... */ void ls(void) { TFILE *tfp; tfp = (TFILE *)0; while((tfp = mon_tfsnext(tfp))) mon_printf("%s\n",TFS_NAME(tfp)); mon_printf("There are currently %d files in TFS\n", (int)mon_tfsctrl(TFS_FCOUNT,0,0)); }
int nandCmd(int argc,char *argv[]) { unsigned long addr; char *cmd, *dest, *src; int opt, len, rc; rc = 0; nandVerbose = 0; while((opt=getopt(argc,argv,"v")) != -1) { switch(opt) { case 'v': nandVerbose++; break; default: return(CMD_PARAM_ERROR); } } if(argc < optind+1) { return(CMD_PARAM_ERROR); } cmd = argv[optind]; if(nandVerbose) { printf("CMD: %s\n",cmd); } if(strcmp(cmd,"init") == 0) { nandInit(); } else if(strcmp(cmd,"info") == 0) { nandInfo(); } else if(strcmp(cmd,"erase") == 0) { if(argc != optind+3) { return(CMD_PARAM_ERROR); } addr = strtoul(argv[optind+1],0,0); len = (int)strtol(argv[optind+2],0,0); nandEraseChunk((char *)addr,len); } else if(strcmp(cmd,"write") == 0) { if(argc != optind+4) { return(CMD_PARAM_ERROR); } addr = strtoul(argv[optind+1],0,0); src = (char *)strtoul(argv[optind+2],0,0); len = (int)strtol(argv[optind+3],0,0); nandWriteChunk((char *)addr,src,len); } else if(strcmp(cmd,"read") == 0) { if(argc != optind+4) { return(CMD_PARAM_ERROR); } addr = strtoul(argv[optind+1],0,0); dest = (char *)strtoul(argv[optind+2],0,0); len = (int)strtol(argv[optind+3],0,0); nandReadChunk((char *)addr,dest,len); } #ifdef FLASHRAM_BASE else if(strcmp(cmd,"tfsload") == 0) { } else if(strcmp(cmd,"tfsstore") == 0) { } else if(strcmp(cmd,"tfserase") == 0) { } else if(strcmp(cmd, "tfsls") == 0) { int ftot; char *addr; TFILE tfshdr, *fp; ftot = 0; fp = &tfshdr; addr = (char *)BASE_OF_NAND; while(addr < (char *)END_OF_NAND) { char fbuf[32], *flags; if((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) { printf("nandReadChunk failed %d\n",rc); break; } if(fp->hdrsize == 0xffff) { break; } if(TFS_FILEEXISTS(fp)) { if(ftot == 0) { printf(" Name Size Offset Flags Info\n"); } ftot++; flags = tfsflagsbtoa(TFS_FLAGS(fp),fbuf); if((!flags) || (!fbuf[0])) { flags = " "; } printf(" %-23s %7ld 0x%08lx %-5s %s\n",TFS_NAME(fp), TFS_SIZE(fp),(unsigned long)(addr+TFSHDRSIZ), flags,TFS_INFO(fp)); } addr += TFS_SIZE(fp); addr += TFSHDRSIZ; while((long)addr & 0xf) { addr++; } } } else if(strcmp(cmd, "tfsrm") == 0) { char *addr; TFILE tfshdr, *fp; char *arg2 = argv[optind+1]; fp = &tfshdr; addr = (char *)BASE_OF_NAND; while(addr < (char *)END_OF_NAND) { if((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) { printf("nandReadChunk failed %d\n",rc); break; } if(fp->hdrsize == 0xffff) { printf("%s not found\n",arg2); break; } if(strcmp(TFS_NAME(fp),arg2) == 0) { if(TFS_FILEEXISTS(fp)) { fp->flags &= ~TFS_ACTIVE; if((rc = nandWriteChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) { printf(" write_hdr failed %d\n",rc); } break; } } addr += TFS_SIZE(fp); addr += TFSHDRSIZ; while((long)addr & 0xf) { addr++; } } } else if(strcmp(cmd, "tfsadd") == 0) { int size; long bflags; TFILE tfshdr, *fp; char *addr; char *src, *name, *info; char *arg2 = argv[optind+1]; char *arg3 = argv[optind+2]; char *arg4 = argv[optind+3]; char *icomma, *fcomma; info = ""; bflags = 0; name = arg2; addr = (char *)BASE_OF_NAND; /* The incoming arguments can be either just the filename (in which * case we assume the source is the file in TFS with the same name), * or the filename, source address and size... */ if(argc == optind+2) { // Just filename? if((fp = tfsstat(name)) == (TFILE *)0) { printf("File '%s' not in TFS\n",name); return(CMD_FAILURE); } name = fp->name; info = fp->info; bflags = fp->flags; size = fp->filsize; src = (char *)(fp + 1); fp = &tfshdr; memset((char *)fp,0,TFSHDRSIZ); } else if(argc == optind+4) { // Filename with addr and len // Extract flags and info fields (if any) from the name... fcomma = strchr(name,','); if(fcomma) { icomma = strchr(fcomma+1,','); if(icomma) { *icomma = 0; info = icomma+1; } *fcomma = 0; bflags = tfsctrl(TFS_FATOB,(long)(fcomma+1),0); } fp = &tfshdr; memset((char *)fp,0,TFSHDRSIZ); size = (int)strtol(arg4,0,0); src = (char *)strtoul(arg3,0,0); } else { return(CMD_PARAM_ERROR); } while(addr < (char *)END_OF_NAND) { if((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) { break; } if(fp->hdrsize == 0xffff) { unsigned long nextfileaddr; /* We're at the address in NAND where we can add the new * file, but first we need to make sure there's enough * room... */ if((TFSHDRSIZ + size + 16) >= ((char *)END_OF_NAND - addr)) { printf(" not enough space\n"); return(CMD_FAILURE); } /* Copy name and info data to header. */ strcpy(fp->name, name); strcpy(fp->info, info); fp->hdrsize = TFSHDRSIZ; fp->hdrvrsn = TFSHDRVERSION; fp->filsize = size; fp->flags = bflags; fp->flags |= (TFS_ACTIVE | TFS_NSTALE); fp->filcrc = crc32((unsigned char *)src,size); fp->modtime = tfsGetLtime(); #if TFS_RESERVED { int rsvd; for(rsvd=0; rsvd<TFS_RESERVED; rsvd++) { fp->rsvd[rsvd] = 0xffffffff; } } #endif fp->next = 0; fp->hdrcrc = 0; fp->hdrcrc = crc32((unsigned char *)fp,TFSHDRSIZ); nextfileaddr = NAND_TFSRAM_BASE - NAND_TFS_BASE + (long)addr + TFSHDRSIZ + size; if(nextfileaddr & 0xf) { nextfileaddr = (nextfileaddr | 0xf) + 1; } fp->next = (TFILE *)nextfileaddr; printf(" writing %s...\n",arg2); if((rc = nandWriteChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) { printf(" write_hdr failed %d\n",rc); } if((rc = nandWriteChunk(addr+TFSHDRSIZ,src,size)) < 0) { printf(" write_file failed %d\n",rc); } break; } if(strcmp(TFS_NAME(fp),arg2) == 0) { if(TFS_FILEEXISTS(fp)) { printf(" removing %s...\n",arg2); fp->flags &= ~TFS_ACTIVE; if((rc = nandWriteChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) { printf(" write_hdr failed %d\n",rc); } } } addr += TFS_SIZE(fp); addr += TFSHDRSIZ; while((long)addr & 0xf) { addr++; } } } else if(strcmp(cmd, "tfsstat") == 0) { char *addr, *oaddr; TFILE tfshdr, *fp; unsigned long meminuse, memdead; fp = &tfshdr; meminuse = memdead = 0; addr = (char *)BASE_OF_NAND; while(addr < (char *)END_OF_NAND) { if((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) { printf("nandReadChunk failed %d\n",rc); break; } if(fp->hdrsize == 0xffff) { break; } oaddr = addr; addr += TFS_SIZE(fp); addr += TFSHDRSIZ; while((long)addr & 0xf) { addr++; } if(TFS_FILEEXISTS(fp)) { meminuse += addr - oaddr; } else { memdead += addr - oaddr; } } printf("Total: 0x%x, used: 0x%x, dead: 0x%x, avail: 0x%x\n", SIZE_OF_NAND, meminuse, memdead, SIZE_OF_NAND - (meminuse + memdead)); } #endif else { return(CMD_PARAM_ERROR); } return(CMD_SUCCESS); }
int tfsscript(TFILE *fp,int verbose) { char lcpy[CMDLINESIZE], *sv; int tfd, lnsize, lno, verbosity, ignoreerror, cmdstat; tfd = tfsopen(fp->name,TFS_RDONLY,0); if (tfd < 0) return(tfd); lno = 0; /* If ScriptIsRunning is zero, then we know that this is the top-level * script, so we can initialize state here... */ if (ScriptIsRunning == 0) ReturnToDepth = 0; CurrentScriptfdTbl[++ScriptIsRunning] = tfd; while(1) { lno++; lnsize = tfsgetline(tfd,lcpy,CMDLINESIZE); if (lnsize == 0) /* end of file? */ break; if (lnsize < 0) { printf("tfsscript(): %s\n",tfserrmsg(lnsize)); 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; } ScriptExitFlag = 0; /* Execute the command line. * If the shell variable "SCRIPTVERBOSE" is set, then enable * verbosity for this command; else use what was passed in * the parameter list of the function. Note that the variable * is tested for each command so that verbosity can be enabled * or disabled within a script. * If the command returns a status that indicates that there was * some parameter error, then exit the script. */ sv = getenv("SCRIPTVERBOSE"); if (sv) verbosity = atoi(sv); else verbosity = verbose; if ((lcpy[0] == '-') || (getenv("SCRIPT_IGNORE_ERROR"))) ignoreerror = 1; else ignoreerror = 0; if (verbosity) printf("[%02d]: %s\n",lno,lcpy); cmdstat = tfsDocommand(lcpy[0] == '-' ? lcpy+1 : lcpy, 0); if (cmdstat != CMD_SUCCESS) { setenv("CMDSTAT","FAIL"); if (ignoreerror == 0) { printf("Terminating script '%s' at line %d\n", TFS_NAME(fp),lno); ScriptExitFlag = EXIT_SCRIPT; break; } } else { setenv("CMDSTAT","PASS"); } /* Check for exit flag. If set, then in addition to terminating the * script, clear the return depth here so that the "missing return" * warning is not printed. This is done because there is likely * to be a subroutine with an exit in it and this should not * cause a warning. */ if (ScriptExitFlag) { ReturnToDepth = 0; break; } /* If ScriptGotoTag is set, then attempt to reposition the line * pointer to the line that contains the tag. */ if (ScriptGotoTag) { int tlen; tlen = strlen(ScriptGotoTag); lno = 0; 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; tfsclose(tfd,0); return(TFS_OKAY); } lno++; if (!strncmp(lcpy,ScriptGotoTag,tlen) && (isspace(lcpy[tlen]) || (lcpy[tlen] == ':'))) { free(ScriptGotoTag); ScriptGotoTag = (char *)0; break; } } } /* After each line, poll ethernet interface. */ pollethernet(); } tfsclose(tfd,0); if (ScriptExitFlag & REMOVE_SCRIPT) tfsunlink(fp->name); if (ScriptIsRunning > 0) { ScriptIsRunning--; if ((ScriptIsRunning == 0) && (ReturnToDepth != 0)) { printf("Error: script is done, but return-to-depth != 0\n"); printf("(possible gosub/return imbalance)\n"); } } else { printf("Script run-depth error\n"); } /* If the EXECUTE_AFTER_EXIT flag is set (by exit -e), then automatically * start up the file specified in ExecuteAfterExit[]... */ if (ScriptExitFlag & EXECUTE_AFTER_EXIT) { char *argv[2]; argv[0] = ExecuteAfterExit; argv[1] = 0; ScriptExitFlag = 0; tfsrun(argv,0); } /* Upon completion of a script, clear the ScriptExitFlag variable so * that it is not accidentally applied to another script that may have * called this script. */ if ((ScriptExitFlag & EXIT_ALL_SCRIPTS) != EXIT_ALL_SCRIPTS) ScriptExitFlag = 0; return(TFS_OKAY); }