195 lines
4.7 KiB
HolyC
Executable File
195 lines
4.7 KiB
HolyC
Executable File
U0 HomeSet(U8 *dirname)
|
||
{//Change home directory.
|
||
dirname=DirNameAbs(dirname);
|
||
Free(blkdev.home_dir);
|
||
blkdev.home_dir=AStrNew(dirname);
|
||
Free(dirname);
|
||
}
|
||
|
||
Bool Cd(U8 *dirname=NULL,Bool make_dirs=FALSE)
|
||
{//Change directory. Optionally, make directories, too.
|
||
I64 maxlen,cur_dir_clus=0;
|
||
U8 *chg_to_buf,*new_cur_dir,*buf;
|
||
CDrv *dv;
|
||
Bool res=TRUE;
|
||
if (!dirname)
|
||
dirname="~";
|
||
else if (!*dirname)
|
||
return TRUE;
|
||
if (dirname[1]==':') {
|
||
if (*dirname==':') {
|
||
if (Fs->cur_dv!=Let2Drv(':') && !Drv(*dirname))
|
||
return FALSE;
|
||
} else if (Fs->cur_dv!=Let2Drv(*dirname) && !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 && res) {
|
||
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,"~")) {
|
||
Free(new_cur_dir);
|
||
new_cur_dir=MAlloc(StrLen(blkdev.home_dir+2)+1+StrLen(chg_to_buf)+1);
|
||
StrCpy(new_cur_dir,blkdev.home_dir+2);
|
||
if (Fs->cur_dv!=Let2Drv('~') && !Drv('~'))
|
||
return FALSE;
|
||
} else if (StrCmp(buf,".") && *buf) {
|
||
dv=Fs->cur_dv;
|
||
cur_dir_clus=Name2DirClus(dv,new_cur_dir);
|
||
switch (dv->fs_type) {
|
||
case FSt_REDSEA:
|
||
res=RedSeaCd(buf,cur_dir_clus);
|
||
break;
|
||
case FSt_FAT32:
|
||
res=FAT32Cd(buf,cur_dir_clus);
|
||
break;
|
||
default:
|
||
PrintErr("File System Not Supported\n");
|
||
res=FALSE;
|
||
}
|
||
if (!res && make_dirs) {
|
||
Free(Fs->cur_dir);
|
||
Fs->cur_dir=StrNew(new_cur_dir);
|
||
res=DirMk(buf);
|
||
}
|
||
if (res) {
|
||
if (StrCmp(new_cur_dir,"/"))
|
||
CatPrint(new_cur_dir,"/");
|
||
CatPrint(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 res;
|
||
}
|
||
|
||
Bool IsDir(U8 *dir_name)
|
||
{//Is a str a valid, existing Dir?
|
||
U8 *mask=MStrPrint("%s/*",dir_name);
|
||
Bool res,old_silent=Silent;
|
||
CDirContext *dirc;
|
||
if (dirc=DirContextNew(mask)) {
|
||
DirContextDel(dirc);
|
||
res=TRUE;
|
||
} else
|
||
res=FALSE;
|
||
Free(mask);
|
||
Silent(old_silent);
|
||
return res;
|
||
}
|
||
|
||
I64 Dir(U8 *files_find_mask,Bool full)
|
||
{//List directory.
|
||
CDirEntry *tmpde1=NULL,*tmpde2;
|
||
U8 *st;
|
||
CDateStruct ds;
|
||
I64 csize=0xFFFF,c=0xFFFF,res=0;
|
||
tmpde1=FilesFind(files_find_mask);
|
||
if (!(st=DirCur))
|
||
PrintErr("Invalid Drive\n");
|
||
else {
|
||
if (tmpde1) {
|
||
Free(st);
|
||
st=MAllocIdent(tmpde1->full_name);
|
||
StrLastRem(st,"/");
|
||
if (!st[2])
|
||
StrCpy(st+2,"/");
|
||
//Find max columns
|
||
tmpde2=tmpde1;
|
||
while (tmpde2) {
|
||
if (tmpde2->size>csize)
|
||
csize=tmpde2->size;
|
||
if (tmpde2->clus>c)
|
||
c=tmpde2->clus;
|
||
tmpde2=tmpde2->next;
|
||
}
|
||
csize=Bsr(csize)/4+1;
|
||
c=Bsr(c)/4+1;
|
||
|
||
"$$MA,T=\"Directory\",LM=\"PopUpCd;Dir;\n\"$$of%s\n",st;
|
||
if (full)
|
||
"__DATE____TIME__%*ts%*ts\n",
|
||
csize,"SIZE",c,"BLK";
|
||
else
|
||
"DATE_TIME_%*ts\n",csize,"SIZE";
|
||
while (tmpde1) {
|
||
tmpde2=tmpde1->next;
|
||
res++;
|
||
if (full)
|
||
"%D%T%0*tX%0*tX ",tmpde1->datetime,tmpde1->datetime,
|
||
csize,tmpde1->size,c,tmpde1->clus;
|
||
else {
|
||
Date2Struct(&ds,tmpde1->datetime+local_time_offset);
|
||
"%02d/%02d%02d:%02d%0*tX ",ds.mon,ds.day_of_mon,ds.hour,ds.min,
|
||
csize,tmpde1->size;
|
||
}
|
||
if (tmpde1->attr & RS_ATTR_DIR)
|
||
PutDirLink(tmpde1->name,tmpde1->full_name);
|
||
else
|
||
PutFileLink(tmpde1->name,tmpde1->full_name);
|
||
'\n';
|
||
DirEntryDel(tmpde1);
|
||
tmpde1=tmpde2;
|
||
}
|
||
} else
|
||
"No matching entries\n";
|
||
Free(st);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
Bool DirMk(U8 *filename,I64 entry_cnt=0)
|
||
{//Make directory. $LK,"Cd",A="MN:Cd"$() can also make directories.
|
||
//entry_cnt is for preallocating dir blks, leave it zero if you like.
|
||
U8 *name;
|
||
CDirContext *dirc;
|
||
Bool res=FALSE;
|
||
if (FileFind(filename,,FUF_JUST_DIRS))
|
||
return FALSE;
|
||
if (dirc=DirContextNew(filename)) {
|
||
if (*dirc->mask) {
|
||
if (!FileNameChk(dirc->mask))
|
||
PrintErr("Invalid FileName: \"%s\".\n",dirc->mask);
|
||
else {
|
||
"Make Directory:%s\n",filename;
|
||
name=MStrUtil(dirc->mask,
|
||
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
|
||
switch (dirc->dv->fs_type) {
|
||
case FSt_REDSEA:
|
||
res=RedSeaMkDir(dirc->dv,Fs->cur_dir,name,entry_cnt);
|
||
break;
|
||
case FSt_FAT32:
|
||
res=FAT32MkDir(dirc->dv,Fs->cur_dir,name,entry_cnt);
|
||
break;
|
||
default:
|
||
PrintErr("File System Not Supported\n");
|
||
}
|
||
Free(name);
|
||
}
|
||
}
|
||
DirContextDel(dirc);
|
||
}
|
||
return res;
|
||
}
|