mirror of https://github.com/minexew/Shrine.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
252 lines
6.3 KiB
252 lines
6.3 KiB
#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.\n"); |
|
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); |
|
}
|
|
|