#help_index "File/Cmd Line (Typically);Cmd Line (Typically)" public U8 *DBlk(I64 blk, Bool write=FALSE) {//Dump disk block. Optionally, write. //If you set write to TRUE, the block will //be written when you press <ESC>. //See ::/Demo/Disk/DiskRaw.CC. U8 *buf = MAlloc(BLK_SIZE); BlkRead(Fs->cur_dv, buf, blk, 1); DocD(buf, BLK_SIZE); if (write) { "Edit and press <ESC> to write or <SHIFT-ESC>\n"; if (View) { "Write\n"; BlkWrite(Fs->cur_dv, buf, blk, 1); } } return buf; } public U8 *DClus(I64 c, Bool write=FALSE, I64 num=0) {//Dump disk clus. Optionally, write. //If you set write to TRUE, the clus will //be written when you press <ESC>. //See ::/Demo/Disk/DiskRaw.CC. //Do Dir("*",TRUE); to get clus numbers of files. U8 *buf = MAlloc(Fs->cur_dv->spc << BLK_SIZE_BITS); c = ClusNumNext(Fs->cur_dv, c, num); ClusRead(Fs->cur_dv, buf, c, 1); "Clus:%X\n", c; DocD(buf, Fs->cur_dv->spc << BLK_SIZE_BITS); if (write) { "Edit and press <ESC> to write or <SHIFT-ESC>\n"; if (View) { "Write\n"; ClusWrite(Fs->cur_dv, buf, c, 1); } } return buf; } public U8 *Dump(U8 *filename, Bool write=FALSE) {//Dump file. Optionally, write. //If you set write to TRUE, the file will //be written when you press <ESC>. U8 *buf; I64 size; if (buf = FileRead(filename,&size)) { DocD(buf, size); if (write) { "Edit and press <ESC> to write or <SHIFT-ESC>\n"; if (View) { "Write\n"; FileWrite(filename, buf, size); } } } return buf; } public Bool Copy(U8 *src_files_find_mask, U8 *dst_files_find_mask=".") {//Copy files. //If the name ends in ".Z", it will //be stored compressed. If not ".Z" //it will be stored uncompressed. Bool res = TRUE; CDirContext *dirc; CDirEntry *tmpde, *tmpde1; U8 *st; if (!(tmpde1 = FilesFind(src_files_find_mask, FUF_CLUS_ORDER))) return FALSE; if (IsDir(dst_files_find_mask)) { if (dirc = DirContextNew(dst_files_find_mask, TRUE)) { tmpde = tmpde1; while (tmpde) { if (!(tmpde->attr & RS_ATTR_DIR)) { st = FileNameAbs(tmpde->name); if (!CopySingle(tmpde->full_name, st)) res = FALSE; Free(st); } tmpde = tmpde->next; } DirContextDel(dirc); } DirTreeDel(tmpde1); return res; } else { DirTreeDel(tmpde1); return CopySingle(src_files_find_mask, dst_files_find_mask); } } public Bool Move(U8 *f1, U8 *f2) {//Move files from one location to another or rename. if (Copy(f1, f2)) { Del(f1); return TRUE; } return FALSE; } I64 CopyTree2(CDirEntry *tmpde, I64 src_dir_len, I64 dst_dir_len, U8 *dst_dir) { U8 *st; I64 res = 1; while (tmpde) { st = MAlloc(StrLen(tmpde->full_name) + dst_dir_len + 2); MemCopy(st, dst_dir, dst_dir_len); StrCopy(st + dst_dir_len, tmpde->full_name + src_dir_len); if (tmpde->attr & RS_ATTR_DIR) { DirMake(st, LinkedListCount(tmpde->sub)); res += CopyTree2(tmpde->sub, src_dir_len, dst_dir_len, dst_dir); } else if (CopySingle(tmpde->full_name, st)) res++; Free(st); tmpde = tmpde->next; } return res; } public I64 CopyTree(U8 *src_files_find_mask, U8 *dst_files_find_mask, Bool no_mask=TRUE) {//Copy directory tree. //Returns the count of copied files (not dirs). CDirContext *dirc; CDirEntry *tmpde = NULL; I64 res = 0, i1, i2; U8 *st1, *st2; st1 = DirNameAbs(src_files_find_mask); st2 = DirNameAbs(dst_files_find_mask); i1 = StrLen(st1); if (!StrNCompare(st1, st2, i1) && (st2[i1] == '/' || !st2[i1])) { Free(st1); Free(st2); return 0; } Free(st1); Free(st2); if (dirc = DirContextNew(src_files_find_mask, TRUE,, no_mask)) { tmpde = FilesFind(dirc->mask, FUF_RECURSE); st1 = DirCur; DirContextDel(dirc); i1 = StrLen(st1); if (i1 == 3) i1--; if (dirc = DirContextNew(dst_files_find_mask, TRUE, TRUE)) { st2 = DirCur; i2 = StrLen(st2); if (i2 == 3) i2--; res = CopyTree2(tmpde, i1, i2, st2); DirContextDel(dirc); Free(st2); } DirTreeDel(tmpde); Free(st1); } return res; } I64 DelTreeDirs(CDirEntry *tmpde1) { I64 res = 0; CDirEntry *tmpde2; while (tmpde1) { tmpde2 = tmpde1->next; if (tmpde1->attr & RS_ATTR_DIR) { if (tmpde1->sub) res += DelTreeDirs(tmpde1->sub); res += Del(tmpde1->full_name, TRUE, TRUE); } DirEntryDel(tmpde1); tmpde1 = tmpde2; } return res; } I64 DelTreeFiles(CDirEntry *tmpde1) { I64 res = 0; CDirEntry *tmpde2; while (tmpde1) { tmpde2 = tmpde1->next; if (tmpde1->attr & RS_ATTR_DIR) { if (tmpde1->sub) res += DelTreeFiles(tmpde1->sub); } else res += Del(tmpde1->full_name, FALSE, TRUE); DirEntryDel(tmpde1); tmpde1 = tmpde2; } return res; } public I64 DelTree(U8 *files_find_mask, U8 *fu_flags=NULL) {//Delete directory tree. I64 res = 0, fuf_flags = 0; FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), "+r"); FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), fu_flags); if (IsDir(files_find_mask)) { res = DelTreeDirs(FilesFind(files_find_mask, fuf_flags)); res += Del(files_find_mask, TRUE, TRUE); res += Del(files_find_mask, FALSE, TRUE); } else res = DelTreeFiles(FilesFind(files_find_mask, fuf_flags)); return res; } U0 TouchFile(U8 *filename, U8 *attr, CDate cdt=I64_MIN) { CDrive *drive = Letter2Drive(*filename); CDirEntry de; U8 *cur_dir = StrNew(filename), buf[STR_LEN]; if (FileFind(filename, &de, FUF_JUST_FILES)) { Free(de.full_name); if (!StrCompare(attr, "+?")) "%-48ts %s\n", filename, FlagsStrPrint(buf, Define("ST_FILE_ATTRS"), de.attr); else { StrFirstRemove(cur_dir, ":"); StrLastRemove(cur_dir, "/"); if (!*cur_dir) StrCopy(cur_dir, "/"); FlagsScan(&de.attr, Define("ST_FILE_ATTRS"), attr); if (cdt == I64_MIN) de.datetime = Now; else de.datetime = cdt; DirNew(drive, cur_dir, &de, FALSE); } } else PrintErr("File not found: \"%s\".\n", filename); Free(cur_dir); } public U0 Touch(U8 *files_find_mask="*", U8 *attr="+?", U8 *fu_flags=NULL, CDate cdt=I64_MIN) {/*Touch file attributes and DateTime. Default lists attributes. attr: "+?" =show current "+T" =resident RS_ATTR_READ_ONLY ST_FILE_ATTRS To Set DateL: Touch(filename,"",,datetime); */ I64 fuf_flags = 0; CDirEntry *tmpde, *tmpde1; FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), "+f+F"); FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), fu_flags); tmpde=tmpde1 = FilesFind(files_find_mask, fuf_flags); while (tmpde) { TouchFile(tmpde->full_name, attr, cdt); tmpde = tmpde->next; } DirTreeDel(tmpde1); }