Bool MapDrv(U8 drv_let,CPrt *p) { drv_let=ToUpper(drv_let); if ('A'<=drv_let<='Z') { drv_to_prt[drv_let-'A']=p; p->drv_let=drv_let; return TRUE; } else return FALSE; } Bool Drv(U8 drv_let) { CPrt *p=Drv2Prt(drv_let); CBlkDev *bdev=p->bdev; BlkDevChk(bdev); if (p!=Fs->cur_prt) { if (bdev->flags & BDF_REMOVABLE && !(bdev->flags & BDF_INITIALIZED)) ChgDsk(Prt2Drv(p)); if (bdev->type==BDT_RAM) BlkDevInit(bdev); } Fs->cur_prt=p; Free(Fs->cur_dir); Fs->cur_dir=StrNew("/"); switch (p->type) { case PT_REDSEA: case PT_FAT32: case PT_ISO9660: return TRUE; default: PrintErr("File System Not Supported\n"); return FALSE; } } Bool Cd(U8 *dirname,Bool make_dirs=FALSE) {//Optionally, will create the directories if they don't exist. I64 maxlen,cur_dir_cluster=0; U8 *chg_to_buf,*new_cur_dir,*buf; CPrt *p; Bool result=TRUE; if (!*dirname) return TRUE; if (dirname[1]==':') { if (*dirname==':') { if (Fs->cur_prt->drv_let!=*sys_acct && !Drv(*dirname)) return FALSE; } else if (Fs->cur_prt!=Drv2Prt(*dirname) && !Drv(*dirname)) return FALSE; dirname+=2; } if (*dirname=='/' || !*dirname || !Fs->cur_dir) { Free(Fs->cur_dir); Fs->cur_dir=StrNew("/"); if (*dirname=='/') dirname++; } chg_to_buf=MStrUtil(dirname,SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS); maxlen=StrLen(Fs->cur_dir)+1+StrLen(chg_to_buf)+1; new_cur_dir=MAlloc(maxlen); buf=MAlloc(maxlen); StrCpy(new_cur_dir,Fs->cur_dir); while (*chg_to_buf && result) { StrFirstRem(chg_to_buf,"/",buf); if (!*buf) StrCpy(new_cur_dir,"/"); else if (!StrCmp(buf,"..")) { StrLastRem(new_cur_dir,"/"); if (!*new_cur_dir) StrCpy(new_cur_dir,"/"); } else if (StrCmp(buf,".") && *buf) { if (!StrCmp(buf,"HOME")) { result=Cd(sys_acct); Free(new_cur_dir); new_cur_dir=MAlloc(maxlen+StrLen(sys_acct)); StrCpy(new_cur_dir,sys_acct+2); } else { p=Fs->cur_prt; cur_dir_cluster=Name2DirCluster(p,new_cur_dir); switch (p->type) { case PT_REDSEA: result=RedSeaFSCd(buf,cur_dir_cluster); break; case PT_FAT32: result=FAT32Cd(buf,cur_dir_cluster); break; case PT_ISO9660: result=ISO1Cd(buf,cur_dir_cluster); break; default: PrintErr("File System Not Supported\n"); result=FALSE; } if (!result && make_dirs) { Free(Fs->cur_dir); Fs->cur_dir=StrNew(new_cur_dir); result=MkDir(buf); } if (result) { if (StrCmp(new_cur_dir,"/")) CatPrint(new_cur_dir,"/"); CatPrint(new_cur_dir,buf); } } } } Free(Fs->cur_dir); Fs->cur_dir=StrNew(new_cur_dir); Free(buf); Free(chg_to_buf); Free(new_cur_dir); return result; } U0 FileAccessDel(CFileAccess *fa) { CBlkDev *bdev; if (!fa) return; bdev=fa->old_prt->bdev; if (!(bdev->flags & BDF_INIT_IN_PROGRESS)) { if (fa->old_dir) { Drv(Prt2Drv(fa->old_prt)); Cd(fa->old_dir); } } else { Fs->cur_prt=fa->old_prt; Free(Fs->cur_dir); Fs->cur_dir=StrNew("/"); } Free(fa->old_dir); Free(fa->mask); Free(fa); } CFileAccess *FileAccessNew(U8 *_mask,Bool make_mask=FALSE,Bool make_dirs=FALSE,Bool no_mask=FALSE) { Bool valid=TRUE,old_silent; U8 *buf,*mask,*temp_mask; CFileAccess *fa=CAlloc(sizeof(CFileAccess)); mask=MStrUtil(_mask,SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS); temp_mask=mask; fa->old_dir=StrNew(Fs->cur_dir); fa->old_prt=Fs->cur_prt; if (*mask && mask[1]==':') { if (Fs->cur_prt!=Drv2Prt(*mask) && !Drv(*mask)) valid=FALSE; mask+=2; } if (StrMatch("HOME",mask) && Fs->cur_prt!=Drv2Prt(*sys_acct)) Drv(*sys_acct); fa->p=Fs->cur_prt; PrtChk(fa->p); buf=MAlloc(StrLen(mask)+2); StrCpy(buf,mask); fa->mask=MAlloc(StrLen(mask)+2); if (no_mask) *fa->mask=0; else StrLastRem(buf,"/",fa->mask); if (*mask=='/' && !*buf) StrCpy(buf,"/"); //If began with Dir, change to Dir. if (*buf && !Cd(buf,make_dirs)) valid=FALSE; if (valid && make_mask) { if (!*fa->mask) { Free(fa->mask); fa->mask=StrNew("*"); } else { if (!make_dirs || FileNameChk(fa->mask)) { old_silent=Silent(ON); //Try mask to see if Dir. If Dir, change to dir and set to "*". if (Cd(fa->mask,make_dirs)) { Free(fa->mask); fa->mask=StrNew("*"); } Silent(old_silent); } } } Free(buf); Free(temp_mask); if (!valid) { FileAccessDel(fa); fa=NULL; // throw('File'); } return fa; } CDirEntry *FilesFind(U8 *files_find_mask,I64 fuf_flags=0) { /* Flags: $LK,"FUF_RECURSE",A="MN:FUF_RECURSE"$ +r Recurse $LK,"FUF_SINGLE",A="MN:FUF_SINGLE"$ +s Single File (Optimization for one file in mask.) $LK,"FUF_FLATTEN_TREE",A="MN:FUF_FLATTEN_TREE"$ +f $BK,1$use with '+F'$BK,0$. Just use +F, probably. $LK,"FUF_JUST_DIRS",A="MN:FUF_JUST_DIRS"$ +D just directories $LK,"FUF_JUST_FILES",A="MN:FUF_JUST_FILES"$ +F just files (Flattens trees) $LK,"FUF_CLUSTER_ORDER",A="MN:FUF_CLUSTER_ORDER"$ +O sort by cluster (move head one direction) $LK,"FUF_JUST_TXT",A="MN:FUF_JUST_TXT"$ +T just text files : $LK,"FILEMASK_TXT",A="MN:FILEMASK_TXT"$ $LK,"FUF_JUST_SRC",A="MN:FUF_JUST_SRC"$ +S just src files : $LK,"FILEMASK_SRC",A="MN:FILEMASK_SRC"$ $LK,"FUF_JUST_AOT",A="MN:FUF_JUST_AOT"$ +A just aot files : $LK,"FILEMASK_AOT",A="MN:FILEMASK_AOT"$ $LK,"FUF_JUST_JIT",A="MN:FUF_JUST_JIT"$ +J just jit files : $LK,"FILEMASK_JIT",A="MN:FILEMASK_JIT"$ $LK,"FUF_JUST_GRA",A="MN:FUF_JUST_GRA"$ +G just graphic files : $LK,"FILEMASK_GRA",A="MN:FILEMASK_GRA"$ See $LK,"ST_FILE_UTIL_FLAGS",A="MN:ST_FILE_UTIL_FLAGS"$ when used in calling program taking text flags. */ CDirEntry *result; CFileAccess *fa; if (fuf_flags&~FUG_FILES_FIND) throw('FUF'); if (fuf_flags&FUF_SINGLE) { result=MAlloc(sizeof(CDirEntry)); if (!FileFind(files_find_mask,result)) { Free(result); return NULL; } } else if (fa=FileAccessNew(files_find_mask,TRUE)) { result=SysFilesFind(fa->mask,fuf_flags); FileAccessDel(fa); } else return NULL; return result; } Bool IsDir(U8 *dir_name) { U8 *mask=MPrint("%s/*",dir_name); Bool result,old_silent=Silent(ON); CFileAccess *fa; if (fa=FileAccessNew(mask)) { FileAccessDel(fa); result=TRUE; } else result=FALSE; Free(mask); Silent(old_silent); return result; } I64 Dir(U8 *files_find_mask="*",Bool full=FALSE) { I64 result; CFileAccess *fa; if (fa=FileAccessNew(files_find_mask,TRUE)) { result=Dir2(fa->mask,0,full); FileAccessDel(fa); return result; } else return 0; } I64 Del(U8 *files_find_mask,Bool print_msg=TRUE) { I64 result=0; CFileAccess *fa; if (fa=FileAccessNew(files_find_mask)) { switch (fa->p->type) { case PT_REDSEA: result=RedSeaFSFilesDel(fa->p,Fs->cur_dir,fa->mask,0,FALSE,print_msg); break; case PT_FAT32: result=FAT32FilesDel(fa->p,Fs->cur_dir,fa->mask,0,FALSE,print_msg); break; case PT_ISO9660: PrintErr("Not Writable\n"); break; default: PrintErr("File System Not Supported\n"); } FileAccessDel(fa); } return result; } U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL,Bool raw=FALSE) { CHashGeneric *temph; U8 *absname,*altname,*curname,*result=NULL; I64 i,size=0,attr=0; CFileAccess *fa; CArcCompress *ac; absname=FileNameAbs(filename); altname=ToggleZorNotZ(absname); if (!raw && ((temph=HashFind(absname,adam_task->hash_table,HTT_FILE))|| (temph=HashFind(altname,adam_task->hash_table,HTT_FILE)))) { size=temph->user_data1; result=MAlloc(size+1); MemCpy(result,temph->user_data0,size); result[size]=0; //Terminate attr=FileAttr(temph->str,attr); } else { for (i=0;i<2 && !result;i++) {//Try name, then altname if (!i) curname=absname; else curname=altname; if (fa=FileAccessNew(curname)) { switch (fa->p->type) { case PT_REDSEA: result=RedSeaFSFileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr); break; case PT_FAT32: result=FAT32FileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr); break; case PT_ISO9660: result=ISO1FileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr); break; default: PrintErr("File System Not Supported\n"); } FileAccessDel(fa); } } //Search parent directories. for (i=0;i<2 && !result;i++) {//Try name, then altname if (!i) curname=absname; else curname=altname; if (fa=FileAccessNew(curname)) { while (!result && StrCmp(Fs->cur_dir,"/")) { Cd(".."); switch (Fs->cur_prt->type) { case PT_REDSEA: result=RedSeaFSFileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr); break; case PT_FAT32: result=FAT32FileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr); break; case PT_ISO9660: result=ISO1FileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr); break; default: PrintErr("File System Not Supported\n"); } } FileAccessDel(fa); } } if (!result) { "%s ",filename; PrintErr("File not found.\n"); } if (result && !raw && attr & _ATTR_RESIDENT) HashGenericAdd(curname,HTT_FILE,AMAllocIdentical(result),size,0,adam_task); } if (result && !raw && attr & _ATTR_COMPRESSED) { ac=result; size=ac->expanded_size; result=ExpandBuf(ac); Free(ac); } if (_attr) *_attr=attr; if (_size) *_size=size; Free(absname); Free(altname); return result; } Bool FileFind(U8 *filename,CDirEntry *_de=NULL,I64 fuf_flags=0) { //$LK,"FUF_JUST_DIRS",A="MN:FUF_JUST_DIRS"$, $LK,"FUF_JUST_FILES",A="MN:FUF_JUST_FILES"$, $LK,"FUF_Z_OR_NOT_Z",A="MN:FUF_Z_OR_NOT_Z"$, $LK,"FUF_SCAN_PARENTS",A="MN:FUF_SCAN_PARENTS"$ //If you pass _de, you must Free(_de->full_name); I64 i,j,cur_dir_cluster; U8 *altname,*curname,*full_name=NULL; CDirEntry de; CFileAccess *fa; Bool result=FALSE; if (fuf_flags&~FUG_FILE_FIND) throw('FUF'); if (!filename) return FALSE; altname=ToggleZorNotZ(filename); if (fuf_flags&FUF_Z_OR_NOT_Z) j=2; else j=1; for (i=0;ip,Fs->cur_dir); switch (fa->p->type) { case PT_REDSEA: result=RedSeaFSFileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags); break; case PT_FAT32: result=FAT32FileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags); break; case PT_ISO9660: result=ISO1FileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags); break; default: PrintErr("File System Not Supported\n"); } if (result && _de) full_name=MPrint("%C:%s/%s",Fs->cur_prt->drv_let,Fs->cur_dir,de.name); FileAccessDel(fa); } } for (i=0;ip,Fs->cur_dir); while (!result && StrCmp(Fs->cur_dir,"/")) { Cd(".."); cur_dir_cluster=Name2DirCluster(fa->p,Fs->cur_dir); switch (fa->p->type) { case PT_REDSEA: result=RedSeaFSFileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags); break; case PT_FAT32: result=FAT32FileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags); break; case PT_ISO9660: result=ISO1FileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags); break; default: PrintErr("File System Not Supported\n"); } } if (result && _de) full_name=MPrint("%C:%s/%s",Fs->cur_prt->drv_let,Fs->cur_dir,de.name); FileAccessDel(fa); } } if (_de) { if (result) { MemCpy(_de,&de,sizeof(CDirEntry)); _de->full_name=full_name; } else MemSet(_de,0,sizeof(CDirEntry)); } Free(altname); return result; } I64 FileWrite(U8 *filename,U8 *fbuf, I64 size,CDate cdt=0,I64 attr=0,Bool raw=FALSE) { I64 c=0; CHashGeneric *temph; CFileAccess *fa; U8 *fbuf2,*absname=FileNameAbs(filename); if (fa=FileAccessNew(filename,FALSE,TRUE)) { attr=FileAttr(fa->mask,attr); if (attr&_ATTR_COMPRESSED && !raw) { fbuf=CompressBuf(fbuf,size); size=fbuf(CArcCompress *)->compressed_size; fbuf2=fbuf; } else fbuf2=NULL; if (!cdt) cdt=Now; switch (fa->p->type) { case PT_REDSEA: c=RedSeaFSFileWrite(fa->p,Fs->cur_dir,fa->mask,fbuf,size,cdt,attr); break; case PT_FAT32: c=FAT32FileWrite(fa->p,Fs->cur_dir,fa->mask,fbuf,size,cdt,attr); break; case PT_ISO9660: PrintErr("Not Writable\n"); break; default: PrintErr("File System Not Supported\n"); } if (temph=HashFind(absname,adam_task->hash_table,HTT_FILE)) { if (!raw && attr & _ATTR_RESIDENT) { Free(temph->user_data0); temph->user_data0=AMAllocIdentical(fbuf); temph->user_data1=size; } else HashRemDel(temph,adam_task->hash_table); } else if (!raw && attr & _ATTR_RESIDENT) HashGenericAdd(absname,HTT_FILE,AMAllocIdentical(fbuf),size,0,adam_task); Free(fbuf2); FileAccessDel(fa); } Free(absname); return c; }