Trivial Solutions The LoseThos 64-bit PC Operating System File:/LT/OSMain/Dsk/Dsk1b.CPZ This, and all LoseThos files, are public domain. Do whatever you like. God is watching; God is just; God is never out-done in generosity. He talks! LoseThos code compiles with the 64-bit LoseThos compiler/assembler I wrote. Boot the LoseThos CD and you can compile it. Not in Kansas anymore! Click here for preliminary compiler information you need. Project: OSMain BoolI64 MapDrv(U8 drv_let,LTPrt *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; } BoolI64 Drv(U8 drv_let) { LTPrt *p=Drv2Prt(drv_let); LTBlkDev *bdev=p->bdev; BlkDevChk(bdev); if (p!=Fs->cur_prt) { if ( bdev->flags & LTBDF_REMOVABLE && !(bdev->flags & LTBDF_INITIALIZED) ) ChgDsk(Prt2Drv(p)); if (bdev->type==LTBDT_RAM || bdev->type==LTBDT_NON_LT_FILE || bdev->type==LTBDT_TEMP_LT_FILE) BlkDevInit(bdev); } Fs->cur_prt=p; Free(Fs->cur_dir); Fs->cur_dir=StrNew("/"); switch (p->type) { case PT_LT: case PT_FAT32: case PT_ISO9660: return TRUE; default: PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM"); return FALSE; } } BoolI64 Cd(U8 *dirname,BoolI8 make_dirs=FALSE) {//Optionally, will create the directories if they don't exist. I64 maxlen; BoolI8 result=TRUE; U8 *chg_to_buf,*new_cur_dir,*buf; LTPrt *p; U64 cur_dir_cluster=0; if (!*dirname) return TRUE; if (dirname[1]==':') { if (*dirname==':') { if (Fs->cur_prt!=dft_prt) if (!Drv(*dirname)) return FALSE; } else { if (Fs->cur_prt!= Drv2Prt(*dirname)) if (!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,".")) { ; } else if (*buf) { if (!StrCmp(buf,"HOME")) { result=Cd(sys_home_dir); Free(new_cur_dir); new_cur_dir=MAlloc(maxlen+StrLen(sys_home_dir)); StrCpy(new_cur_dir,sys_home_dir+2); } else { p=Fs->cur_prt; cur_dir_cluster=Name2DirCluster(p,new_cur_dir); switch (p->type) { case PT_LT: result=LTFSCd(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: PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM"); 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,"/")) StrCat(new_cur_dir,"/"); StrCat(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 LTFileAccessDel(LTFileAccess *fa) { LTBlkDev *bdev; if (!fa) return; bdev=fa->old_prt->bdev; if (!(bdev->flags & LTBDF_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); } LTFileAccess *LTFileAccessNew(U8 *_mask,BoolI8 make_mask=FALSE,BoolI8 make_dirs=FALSE) { BoolI8 valid=TRUE; U8 *buf,*mask,*temp_mask; BoolI8 old_silent; LTFileAccess *fa=CAlloc(sizeof(LTFileAccess)); 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)) if (!Drv(*mask)) valid=FALSE; mask+=2; } if (StrStr(mask,"HOME")) { //TODO if (Fs->cur_prt!=Drv2Prt(*sys_home_dir)) Drv(*sys_home_dir); } fa->p=Fs->cur_prt; PrtChk(fa->p); buf=MAlloc(StrLen(mask)+2); StrCpy(buf,mask); fa->mask=MAlloc(StrLen(mask)+2); StrLastRem(buf,"/",fa->mask); if (*mask=='/' && !*buf) StrCpy(buf,"/"); if (*buf) if (!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); if (Cd(fa->mask,make_dirs)) { Free(fa->mask); fa->mask=StrNew("*"); } Silent(old_silent); } } } Free(buf); Free(temp_mask); if (!valid) { LTFileAccessDel(fa); fa=NULL; // throw(EXCEPT_FILE); } return fa; } LTDirEntry *FilesFind(U8 *files_find_mask,U64 fuf_flags=0) { /* Flags: FUF_RECURSE +r Recurse FUF_FLATTEN_TREE +f be sure to use this along with '+F'. FUF_JUST_DIRS +D just directories FUF_JUST_FILES +F just files FUF_JUST_TEXT_FILES +t just text files: TEXT_FILE_MASK FUF_JUST_SRC_FILES +s just src files : SRC_FILE_MASK See ST_FILE_UTIL_FLAGS when used in calling program taking text flags. */ LTDirEntry *result=NULL; LTFileAccess *fa=LTFileAccessNew(files_find_mask,TRUE); if (fa) { result=SysFilesFind(fa->mask,fuf_flags); LTFileAccessDel(fa); } return result; } BoolI64 IsDir(U8 *dir_name) { BoolI8 result=FALSE; U8 *mask=MSPrintF("%s/*",dir_name); BoolI8 old_silent=Silent(ON); LTFileAccess *fa=LTFileAccessNew(mask); if (fa) { result=TRUE; LTFileAccessDel(fa); } Free(mask); Silent(old_silent); return result; } U0 Dir(U8 *files_find_mask="*",BoolI8 full=FALSE) { LTFileAccess *fa; fa=LTFileAccessNew(files_find_mask,TRUE); if (fa) { DirLT(fa->mask,0,full); LTFileAccessDel(fa); } } U0 Del(U8 *files_find_mask,BoolI8 print_msg=TRUE) { LTFileAccess *fa=LTFileAccessNew(files_find_mask); if (fa) { switch (fa->p->type) { case PT_LT: LTFSFilesDel(fa->p,Fs->cur_dir,fa->mask,0,FALSE,print_msg); break; case PT_FAT32: FAT32FilesDel(fa->p,Fs->cur_dir,fa->mask,0,FALSE,print_msg); break; case PT_ISO9660: PutDefineErr("ST_NOT_WRITABLE"); break; default: PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM"); } LTFileAccessDel(fa); } } U8 *FileRead(U8 *filename,U64 *size=NULL,I64 *attr=NULL,BoolI8 raw=FALSE) { GenericHashEntry *temph; U8 *absname; U8 *result=NULL; I64 size2=0,attr2=0; LTFileAccess *fa; ArcCompressStruct *ac=NULL; if (attr) *attr=0; absname=FileNameAbs(filename); if (!raw && (temph=HashFind(absname,adam_task->hash_table,HTT_FILE))) { if (FileAttr(absname) & LT_ATTR_COMPRESSED) { ac=temph->user_data0; if (size) *size=ac->expanded_size; if (attr) *attr=FileAttr(absname,*attr); result=ExpandBuf(ac); } else { result=MAlloc(temph->user_data1+1); MemCpy(result,temph->user_data0,temph->user_data1); result[temph->user_data1]=0; //Terminate if (size) *size=temph->user_data1; } } else { fa=LTFileAccessNew(absname); if (fa) { switch (fa->p->type) { case PT_LT: result=LTFSFileRead(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac); break; case PT_FAT32: result=FAT32FileRead(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac); break; case PT_ISO9660: result=ISO1FileRead(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac); break; default: PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM"); } while (!result && StrCmp(Fs->cur_dir,"/")) { Cd(".."); switch (Fs->cur_prt->type) { case PT_LT: result=LTFSFileRead(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac); break; case PT_FAT32: result=FAT32FileRead(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac); break; case PT_ISO9660: result=ISO1FileRead(fa->p,Fs->cur_dir,fa->mask,&size2,&attr2,raw,&ac); break; default: PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM"); } } if (!result) { "%s ",filename; PutDefineErr("ST_FILE_NOT_FOUND"); } LTFileAccessDel(fa); } if (size) *size=size2; if (attr) *attr=attr2; if (!raw && attr2 & LT_ATTR_RESIDENT) HashGenericAdd(absname,HTT_FILE,AMAllocIdentical(ac),size2,0,adam_task); Free(ac); } Free(absname); return result; } U8 *TextFileRead(U8 *filename,U64 *attr=NULL) { return FileRead(filename,NULL,attr); } BoolI64 FileFind(U8 *filename,LTDirEntry *rde=NULL, BoolI8 dir_only=FALSE,BoolI8 file_only=FALSE,BoolI8 scan_parents=FALSE) { U64 cur_dir_cluster; BoolI8 result=FALSE; LTDirEntry de; LTFileAccess *fa=LTFileAccessNew(filename); if (fa) { cur_dir_cluster=Name2DirCluster(fa->p,Fs->cur_dir); switch (fa->p->type) { case PT_LT: result=LTFSFileFind(fa->p,cur_dir_cluster,fa->mask, &de,dir_only,file_only); break; case PT_FAT32: result=FAT32FileFind(fa->p,cur_dir_cluster,fa->mask, &de,dir_only,file_only); break; case PT_ISO9660: result=ISO1FileFind(fa->p,cur_dir_cluster,fa->mask, &de,dir_only,file_only); break; default: PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM"); } if (scan_parents) { while (!result && StrCmp(Fs->cur_dir,"/")) { Cd(".."); cur_dir_cluster=Name2DirCluster(fa->p,Fs->cur_dir); switch (fa->p->type) { case PT_LT: result=LTFSFileFind(fa->p,cur_dir_cluster,fa->mask, &de,dir_only,file_only); break; case PT_FAT32: result=FAT32FileFind(fa->p,cur_dir_cluster,fa->mask, &de,dir_only,file_only); break; case PT_ISO9660: result=ISO1FileFind(fa->p,cur_dir_cluster,fa->mask, &de,dir_only,file_only); break; default: PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM"); } } } LTFileAccessDel(fa); } if (result && rde) MemCpy(rde,&de,sizeof(LTDirEntry)); return result; } U64 FileSize(U8 *filename) { LTDirEntry de; if (FileFind(filename,&de)) return de.size; else return 0; } U64 FileWrite(U8 *filename,U8 *fbuf, U64 size,LTDate date=0,U64 attr=0,BoolI8 raw=FALSE) { U64 c=0; GenericHashEntry *temph; LTFileAccess *fa=LTFileAccessNew(filename,FALSE,TRUE); ArcCompressStruct *ac=NULL; U8 *absname=FileNameAbs(filename); if (fa) { switch (fa->p->type) { case PT_LT: c=LTFSFileWrite(fa->p,Fs->cur_dir,fa->mask, fbuf,size,date,attr,raw,&ac); break; case PT_FAT32: c=FAT32FileWrite(fa->p,Fs->cur_dir,fa->mask, fbuf,size,date,attr,raw,&ac); break; case PT_ISO9660: PutDefineErr("ST_NOT_WRITABLE"); break; default: PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM"); } if (temph=HashFind(absname,adam_task->hash_table,HTT_FILE)) { if (!raw && ac && attr & LT_ATTR_RESIDENT) { Free(temph->user_data0); temph->user_data0=AMAllocIdentical(ac); temph->user_data1=size; } else HashRemDel(temph,adam_task->hash_table); } else if (!raw && ac && attr & LT_ATTR_RESIDENT) HashGenericAdd(absname,HTT_FILE,AMAllocIdentical(ac),size,0,adam_task); Free(ac); LTFileAccessDel(fa); } Free(absname); return c; } U0 TextFileWrite(U8 *filename,U8 *st,U64 attr=0) { FileWrite(filename,st,StrLen(st),0,attr); }