templeos-info/public/Wb/Adam/ABlkDev/ADskA.HC

253 lines
6.4 KiB
HolyC
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 $LK,"::/Demo/Dsk/DskRaw.HC"$.
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 $LK,"::/Demo/Dsk/DskRaw.HC"$.
//Do $LK,"Dir",A="MN: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);
MemCpy(st,dst_dir,dst_dir_len);
StrCpy(st+dst_dir_len,tmpde->full_name+src_dir_len);
if (tmpde->attr & RS_ATTR_DIR) {
DirMk(st,LinkedLstCnt(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 (!StrNCmp(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;
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
ScanFlags(&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)
{
CDrv *dv=Let2Drv(*filename);
CDirEntry de;
U8 *cur_dir=StrNew(filename),buf[STR_LEN];
if (FileFind(filename,&de,FUF_JUST_FILES)) {
Free(de.full_name);
if (!StrCmp(attr,"+?"))
"%-48ts%s\n",filename,StrPrintFlags(buf,Define("ST_FILE_ATTRS"),de.attr);
else {
StrFirstRem(cur_dir,":");
StrLastRem(cur_dir,"/");
if (!*cur_dir)
StrCpy(cur_dir,"/");
ScanFlags(&de.attr,Define("ST_FILE_ATTRS"),attr);
if (cdt==I64_MIN)
de.datetime=Now;
else
de.datetime=cdt;
DirNew(dv,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
$LK,"RS_ATTR_READ_ONLY",A="MN:RS_ATTR_READ_ONLY"$ $LK,"ST_FILE_ATTRS",A="MN:ST_FILE_ATTRS"$
To Set DateL:
Touch(filename,"",,datetime);
*/
I64 fuf_flags=0;
CDirEntry *tmpde,*tmpde1;
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+f+F");
ScanFlags(&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);
}