#help_index "File/Program Routines" U0 OFFlatten(LTDirEntry *tempm,LTDirEntry **a,I8 *i) { LTDirEntry *tempm1; while (tempm) { tempm1=tempm->next; if (tempm->attr<_ATTR_DIR) { OFFlatten(tempm->sub,a,i); LTDirEntryDel(tempm); } else { a[*i]=tempm; *i=*i+1; } tempm=tempm1; } } public I8 LTFileCnt(LTDirEntry *tempm) { I8 cnt=0; while (tempm) { if (tempm->attr<_ATTR_DIR) cnt+=LTFileCnt(tempm->sub); else cnt++; tempm=tempm->next; } return cnt; } I8 OFCompare(LTDirEntry *e1,LTDirEntry *e2) { return e1->cluster-e2->cluster; } public LTDirEntry **FilesOrder(LTDirEntry *tempm,I8 *_cnt=NULL) { //See ::/LT/Demo/Disk/OrderedIO.CPZ. I8 cnt=LTFileCnt(tempm),i=0; LTDirEntry **a=MAlloc(sizeof(LTDirEntry *)*cnt); OFFlatten(tempm,a,&i); QSortU8(a,cnt,&OFCompare); if (_cnt) *_cnt=cnt; return a; } #help_index "File/Cmd Line (Typically);Cmd Line (Typically)" public BoolI8 Copy(U1 *f1,U1 *f2=".") { BoolI1 result=TRUE; LTFileAccess *fa; LTDirEntry *tempm,*tempm1; U1 *st; if (!(tempm=FilesFind(f1,0))) return FALSE; if (IsDir(f2)) { fa=LTFileAccessNew(f2,TRUE); if (fa) { while (tempm) { tempm1=tempm->next; if (!(tempm->attr & LT_ATTR_DIR)) { st=FileNameAbs(tempm->name); if (!CopySingle(tempm->full_name,st)) result=FALSE; Free(st); } LTDirEntryDel(tempm); tempm=tempm1; } LTFileAccessDel(fa); } return result; } else return CopySingle(f1,f2); } public BoolI8 Move(U1 *f1,U1 *f2) { if (Copy(f1,f2)) { Del(f1); return TRUE; } return FALSE; } U8 PutCopyTree(LTDirEntry *tempm,U8 src_dir_len,U8 dst_dir_len,U1 *dst_dir) { U8 result=1; U1 *st; while (tempm) { st=MAlloc(StrLen(tempm->full_name)+dst_dir_len+2); MemCpy(st,dst_dir,dst_dir_len); StrCpy(st+dst_dir_len,tempm->full_name+src_dir_len); if (tempm->attr & LT_ATTR_DIR) { MkDir(st); result+=PutCopyTree(tempm->sub,src_dir_len,dst_dir_len,dst_dir); } else if (CopySingle(tempm->full_name,st)) result++; Free(st); tempm=tempm->next; } return result; } public U8 CopyTree(U1 *src_mask,U1 *dst_mask) { //returns count of copied files (not dirs) LTFileAccess *fa; LTDirEntry *tempm=NULL; U8 result=0,i1,i2; U1 *st1,*st2; st1=DirNameAbs(src_mask); st2=DirNameAbs(dst_mask); i1=StrLen(st1); if (!StrNCmp(st1,st2,i1) && (st2[i1]=='/' || !st2[i1]) ) { Free(st1); Free(st2); return 0; } Free(st1); Free(st2); fa=LTFileAccessNew(src_mask,TRUE); if (fa) { tempm=SysFilesFind(fa->mask,1<<FUf_RECURSE); st1=CurDir; LTFileAccessDel(fa); i1=StrLen(st1); if (i1==3) i1--; fa=LTFileAccessNew(dst_mask,TRUE,TRUE); if (fa) { st2=CurDir; i2=StrLen(st2); if (i2==3) i2--; result=PutCopyTree(tempm,i1,i2,st2); LTFileAccessDel(fa); Free(st2); } LTDirListDel(tempm); Free(st1); } return result; } U0 DelTreeDirs(LTDirEntry *tempm1) { LTDirEntry *tempm2; while (tempm1) { tempm2=tempm1->next; if (tempm1->attr & LT_ATTR_DIR) { if (tempm1->sub) DelTreeDirs(tempm1->sub); SysDel(tempm1->full_name,TRUE); } LTDirEntryDel(tempm1); tempm1=tempm2; } } U0 DelTreeFiles(LTDirEntry *tempm1) { LTDirEntry *tempm2; while (tempm1) { tempm2=tempm1->next; if (tempm1->attr & LT_ATTR_DIR) { if (tempm1->sub) DelTreeFiles(tempm1->sub); } else SysDel(tempm1->full_name,FALSE); LTDirEntryDel(tempm1); tempm1=tempm2; } } public U0 DelTree(U1 *mask) { if (IsDir(mask)) { DelTreeDirs(FilesFind(mask,1<<FUf_RECURSE)); SysDel(mask,TRUE); SysDel(mask,FALSE); } else DelTreeFiles(FilesFind(mask,1<<FUf_RECURSE)); } U0 TouchFile(U1 *filename,U1 *attr,LTDate dt=0) //Just one file { U1 *cur_dir=StrNew(filename); LTPartition *p=Drive2Partition(*filename); LTDirEntry de; U1 buf[64]; if (FileFind(filename,&de,FALSE,TRUE)) { if (!StrCmp(attr,"+?")) PrintF("%-32ts %s\r\n",filename,SPrintFFlags(buf,Define("ST_FILE_ATTRS"),de.attr)); else { StrFirstRem(cur_dir,":"); StrLastRem(cur_dir,"/"); if (!*cur_dir) StrCpy(cur_dir,"/"); GetFFlags(&de.attr,Define("ST_FILE_ATTRS"),attr); if (dt) de.datetime=dt; else de.datetime=GetCurTimeLTDate; LTDirEntryNew(p,cur_dir,&de,FALSE); } } else PutDefineErr("ST_FILE_NOT_FOUND"); } U0 TouchList(LTDirEntry *tempm1,U1 *attr,LTDate dt=0) { LTDirEntry *tempm2; while (tempm1) { tempm2=tempm1->next; if (tempm1->attr & LT_ATTR_DIR) { if (tempm1->sub) { coutln Define("ST_SCANNING_DIR"),tempm1->full_name; TouchList(tempm1->sub,attr,dt); } } else TouchFile(tempm1->full_name,attr,dt); LTDirEntryDel(tempm1); tempm1=tempm2; } } //Attr "+?" =show // "+T" = resident //flags "+r"=recurse public U0 Touch(U1 *wild,U1 *attr="+?",U1 *flags=NULL,LTDate dt=0) { U8 f=0; GetFFlags(&f,Define("ST_FILE_UTIL_FLAGS"),flags); TouchList(FilesFind(wild,f),attr,dt); } U8 FFList(LTDirEntry *tempm1) { U8 cnt=0; LTDirEntry *tempm2; while (tempm1) { tempm2=tempm1->next; if (tempm1->attr & LT_ATTR_DIR) { if (tempm1->sub) cnt+=FFList(tempm1->sub); } else { PutFileLink(tempm1->full_name); CrLf; cnt++; } LTDirEntryDel(tempm1); tempm1=tempm2; } return cnt; } public U8 FF(U1 *wild,U1 *flags=NULL) //Files Find //"+r"=recurse { U8 cnt=0,f=0; GetFFlags(&f,Define("ST_FILE_UTIL_FLAGS"),"+r"); GetFFlags(&f,Define("ST_FILE_UTIL_FLAGS"),flags); cnt+=FFList(FilesFind(wild,f)); return cnt; } public U0 SetDriveTextAttr(U1 drive_letter=0,U1 attr) { //This is to color the border text according to the current drive LTPartition *p; try { p=Drive2Partition(drive_letter); p->text_attr=attr; } catch Fs->catch_except=TRUE; } U0 PrintFDriveTextAttr(U1 drive_letter=0) { LTPartition *p=Drive2Partition(drive_letter); U1 fg=p->text_attr&0xF,bg=p->text_attr>>4; if (fg!=bg) PrintF("$$FG,%d$$$$BG,%d$$",fg,bg); } I8 LTFSUnusedDriveSpace(U1 drive_letter=0) { LTPartition *p=Drive2Partition(drive_letter); U8 result=0,i,l; U1 *bitmap; try { l=(p->size+p->spc-1)/p->spc; i=((l+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS; bitmap=MAlloc(i<<BLK_SIZE_BITS); RBlks(p,bitmap,p->map1,i); for (i=0;i<l;i++) if (!Bt(bitmap,i)) result++; Free(bitmap); } catch PartitionUnlock(p); return result*BLK_SIZE*p->spc; } I8 FAT32UnusedDriveSpace(U1 drive_letter=0) { LTPartition *p=Drive2Partition(drive_letter); U8 result=0,i,l; U4 *bitmap; try { l=(p->size+p->spc-1)/p->spc; i=(l*4+BLK_SIZE-1)>>BLK_SIZE_BITS; bitmap=MAlloc(i<<BLK_SIZE_BITS); RBlks(p,bitmap,p->map1,i); for (i=0;i<l;i++) if (!bitmap[i]) result++; Free(bitmap); } catch PartitionUnlock(p); return result*BLK_SIZE*p->spc; } public I8 UnusedDriveSpace(U1 drive_letter=0) { //returns size in bytes I8 result=0; LTPartition *p=Drive2Partition(drive_letter),*p_old=Fs->cur_partition; Drive(drive_letter); switch (p->type) { case PT_LT: result=LTFSUnusedDriveSpace(drive_letter); break; case PT_FAT32: result=FAT32UnusedDriveSpace(drive_letter); break; default: PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM"); } Drive(Partition2Drive(p_old)); return result; } #help_index "File/Program Routines" U8 TreeSizeFiles(LTDirEntry *tempm,U8 f,I8 round_to) { U8 result=0,i; while (tempm) { if (round_to) i=RoundUpU8(tempm->size,round_to); else i=tempm->size; if (tempm->attr<_ATTR_DIR) i+=TreeSizeFiles(tempm->sub,f,round_to); tempm->user_data=i; result+=i; tempm=tempm->next; } return result; } public U8 TreeSize(U1 *src_mask="/LT/*",U1 *flags=NULL,I8 round_to=0) //+r=recurse { //Does not include directory size of base directory, but //does include size of sub directories. U8 f=0,result=0; LTDirEntry *tempm1=NULL; GetFFlags(&f,Define("ST_FILE_UTIL_FLAGS"),"+r"); GetFFlags(&f,Define("ST_FILE_UTIL_FLAGS"),flags); if (tempm1=FilesFind(src_mask,f)) { result=TreeSizeFiles(tempm1,f,round_to); LTDirListDel(tempm1); } return result; } #help_index ""