396 lines
10 KiB
Plaintext
396 lines
10 KiB
Plaintext
public I8 PopUpReplaceSkipAllCancelEdit(I1 *msg)
|
|
{
|
|
I8 i;
|
|
Ltf *l=LtfNew;
|
|
LtfPutS(l,msg);
|
|
LtfPutS(l,"$$CM +LX, 2,4$$$$BT, \"REPLACE\",0$$");
|
|
LtfPutS(l,"$$CM +LX, 22,0$$$$BT, \"SKIP\",1$$");
|
|
LtfPutS(l,"$$CM +LX, 2,4$$$$BT, \"ALL\",2$$");
|
|
LtfPutS(l,"$$CM +LX, 22,0$$$$BT, \"ABORT ALL\",3$$");
|
|
LtfPutS(l,"$$CM +LX, 2,4$$$$BT, \"EDIT\",4$$");
|
|
LtfPutS(l,"$$CM +LX, 22,0$$$$BT, \"ABORT FILE\",5$$");
|
|
LtfPutS(l,"$$CM +LX, 2,4$$$$BT, \"SKIP FILE\",6$$");
|
|
i=PopUpMenu(l);
|
|
LtfDel(l);
|
|
return i;
|
|
}
|
|
|
|
|
|
|
|
U8 GrepFile(I1 *pattern,I1 *name,U8 *flags,I1 *replace_text)
|
|
{
|
|
BoolU4 first_on_line,write_this_file=FALSE,cont=!Bt(flags,FUf_CANCEL);
|
|
I1 *src,*dst,*dst2,*name_buf=NULL;
|
|
U8 ss_flags;
|
|
Ltf *l=LtfRead(name, LTFF_PLAIN_TEXT_WITH_TABS | LTFF_NO_CURSOR);
|
|
LtfEntry *cl;
|
|
I8 i,j,plen,rlen,dlen;
|
|
U8 cnt=0;
|
|
|
|
ss_flags=(Bt(flags,FUf_IGNORE)) ? SS_IGNORE_CASE :0;
|
|
if (Bt(flags,FUf_LABEL))
|
|
ss_flags|=SS_WHOLE_LABELS;
|
|
|
|
plen=StrLen(pattern);
|
|
if (replace_text)
|
|
rlen=StrLen(replace_text);
|
|
cl=l->dummy.next;
|
|
while (cl!=l && cont) {
|
|
if (cl->btype==LTFT_TEXT) {
|
|
src=cl->display;
|
|
first_on_line=TRUE;
|
|
while (src && cont) {
|
|
if (src=SearchString(src,pattern,ss_flags)) {
|
|
cnt++;
|
|
if (first_on_line || Bt(flags,FUf_REPLACE)) {
|
|
first_on_line=FALSE;
|
|
PutFileLink(name,cl->y+1,TRUE);
|
|
name_buf=MSPrintF("%s,%d",name,cl->y+1);
|
|
PrintF(" %s\r\n",cl->display);
|
|
}
|
|
if (Bt(flags,FUf_REPLACE)) {
|
|
if (Bt(flags,FUf_ALL))
|
|
i=2;
|
|
else {
|
|
i=PopUpReplaceSkipAllCancelEdit("");
|
|
if (i==3) {
|
|
Bts(flags,FUf_CANCEL);
|
|
cont=FALSE;
|
|
write_this_file=FALSE;
|
|
} else if (i==2)
|
|
Bts(flags,FUf_ALL);
|
|
else if (i==5) {
|
|
cont=FALSE;
|
|
write_this_file=FALSE;
|
|
} else if (i==6)
|
|
cont=FALSE;
|
|
}
|
|
if (!i || i==2) {
|
|
dlen=StrLen(cl->display);
|
|
dst=MAlloc(dlen+1+rlen-plen);
|
|
dst2=dst;
|
|
j=src-cl->display;
|
|
for (i=0;i<j;i++)
|
|
*dst++=cl->display[i];
|
|
for (i=0;i<rlen;i++)
|
|
*dst++=replace_text[i];
|
|
src=dst;
|
|
for (i=j+plen;i<=dlen;i++)
|
|
*dst++=cl->display[i];
|
|
Free(cl->display);
|
|
cl->display=dst2;
|
|
PrintF("%12s,%04X*%s\r\n",name,cl->y+1,dst2);
|
|
write_this_file=TRUE;
|
|
} else {
|
|
src++;
|
|
if (i==4) {
|
|
Free(name_buf);
|
|
name_buf=NewString(l->filename.name);
|
|
l->flags&=~LTFF_NO_CURSOR;
|
|
l->cur_entry=cl;
|
|
l->cur_data_col=cl->min_col;
|
|
LtfWrite(l);
|
|
LtfDel(l);
|
|
PrintF("Wrote:%s\r\n",name_buf);
|
|
Edit(name_buf);
|
|
l=LtfRead(name_buf, LTFF_PLAIN_TEXT_WITH_TABS);
|
|
cl=l->cur_entry;
|
|
if (cl->last!=l) cl=cl->last;
|
|
src=NULL;
|
|
write_this_file=FALSE;
|
|
}
|
|
}
|
|
} else
|
|
src++;
|
|
Free(name_buf);
|
|
name_buf=NULL;
|
|
}
|
|
}
|
|
}
|
|
cl=cl->next;
|
|
}
|
|
if (write_this_file) {
|
|
LtfWrite(l);
|
|
PrintF("Wrote:%s\r\n",l->filename.name);
|
|
}
|
|
LtfDel(l);
|
|
return cnt;
|
|
}
|
|
|
|
U8 GrepList(I1 *pattern,LTDirEntry *tempm1,U8 *flags,I1 *replace_text)
|
|
{
|
|
U8 cnt=0;
|
|
LTDirEntry *tempm2;
|
|
|
|
while (tempm1 && !Bt(flags,FUf_CANCEL)) {
|
|
tempm2=tempm1->next;
|
|
if (tempm1->attr & LT_ATTR_DIR) {
|
|
if (tempm1->sub) {
|
|
PrintF("%S %s\r\n","ST_SCANNING_DIRECTORY",tempm1->full_name);
|
|
cnt+=GrepList(pattern,tempm1->sub,flags,replace_text);
|
|
}
|
|
} else
|
|
cnt+=GrepFile(pattern,tempm1->full_name,flags,replace_text);
|
|
DelLTDirEntry(tempm1);
|
|
tempm1=tempm2;
|
|
}
|
|
return cnt;
|
|
}
|
|
|
|
public U8 Grep(I1 *pattern,I1 *wild=TEXT_FILE_MASK,I1 *flags="+r+i+l",I1 *replace_text=NULL)
|
|
|
|
//This does not do regular expressions--my bad
|
|
//Anyway, it's good for searching and replacing.
|
|
//Let's say it stands for global replace ;-)
|
|
|
|
//"+r"=recurse
|
|
//"+i"=ignore case
|
|
//"+l"=whole labels only.
|
|
// This will check for a nonlabel character before
|
|
// and after. If you have a variable, "ll" and don't
|
|
// want to match words like "will" and "wallow", you
|
|
// set this flag and it will see that the characters
|
|
// before or after "ll" are label characters.
|
|
|
|
{
|
|
U8 cnt=0;
|
|
FlagsStruct f;
|
|
GetFFlags(&f,"ST_FILE_UTIL_FLAGS",flags);
|
|
AssignBit(&f.on,FUf_REPLACE,replace_text);
|
|
cnt+=GrepList(pattern,FindFiles(wild,&f.on),&f.on,replace_text);
|
|
return cnt;
|
|
}
|
|
|
|
public U8 FileOccurrences(I1 *pattern,I1 *wild=TEXT_FILE_MASK,I1 *flags="+r+i+l")
|
|
{
|
|
U8 cnt;
|
|
BoolU4 old_silent=Silent(TRUE);
|
|
cnt=Grep(pattern,wild,flags);
|
|
Silent(old_silent);
|
|
return cnt;
|
|
}
|
|
|
|
LTDirEntry MCFindMatch(LTDirEntry *pattern,LTDirEntry *list)
|
|
{
|
|
while (list) {
|
|
if (!StrCmp(pattern->name,list->name) &&
|
|
(pattern->attr&~LT_ATTR_RESIDENT)==
|
|
list->attr&~LT_ATTR_RESIDENT)
|
|
return list;
|
|
list=list->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void MergeChkList(LTDirEntry *m1,LTDirEntry *m2,U8 *fuf_flags,U8 *df_flags)
|
|
{
|
|
I8 i;
|
|
LTDirEntry *tempm2;
|
|
while (m1 && !(*df_flags & DF_ABORT_ALL_FILES)) {
|
|
if (!Bt(fuf_flags,FUf_JUST_TEXT_FILES) ||
|
|
IsTextFile(m1->name) ||
|
|
m1->attr & LT_ATTR_DIR) {
|
|
tempm2=MCFindMatch(m1,m2);
|
|
if (!tempm2)
|
|
coutln "Does Not Exist:",m1->full_name;
|
|
else {
|
|
if (m1->attr & LT_ATTR_DIR)
|
|
MergeChkList(m1->sub,tempm2->sub,fuf_flags,df_flags);
|
|
else {
|
|
i=m1->datetime-tempm2->datetime;
|
|
if (AbsI8(i)>LTDATE_FREQ*2) { //Filedates can shift due to conversion
|
|
coutln m1->full_name;
|
|
if (Bt(fuf_flags,FUf_DIFF)) {
|
|
if (IsTextFile(m1->full_name))
|
|
*df_flags=Diff(tempm2->full_name,m1->full_name,*df_flags);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
m1=m1->next;
|
|
}
|
|
}
|
|
|
|
public void MergeChk(
|
|
I1 *dst_mask="/LT/*",
|
|
I1 *src_mask="/LT/*",
|
|
I1 *flags="+r")
|
|
//+r=recurse
|
|
//+d=diff
|
|
//+t=just text files
|
|
{
|
|
U8 df_flags=0;
|
|
LTDirEntry *tempm1=NULL,*tempm2=NULL;
|
|
FlagsStruct f;
|
|
GetFFlags(&f,"ST_FILE_UTIL_FLAGS",flags);
|
|
coutln "WARNING:This is based strictly on file dates.";
|
|
tempm1=FindFiles(src_mask,&f.on);
|
|
tempm2=FindFiles(dst_mask,&f.on);
|
|
MergeChkList(tempm1,tempm2,&f.on,&df_flags);
|
|
DelLTDirList(tempm1);
|
|
DelLTDirList(tempm2);
|
|
}
|
|
|
|
|
|
I1 *red_st="$$FG RED$$",*green_st="$$FG GREEN$$";
|
|
|
|
void RmtMergeChkList(TssStruct *tss,LTChnl *chnl,LTDirEntry *m1,LTDirEntry *m2,U8 *fuf_flags,U8 *df_flags,I1 *cur_dir)
|
|
{
|
|
I8 i;
|
|
LTDirEntry *tempm2;
|
|
I1 *full_name,*c1,*c2;
|
|
while (m1 && !(*df_flags & DF_ABORT_ALL_FILES)) {
|
|
if (!Bt(fuf_flags,FUf_JUST_TEXT_FILES) ||
|
|
IsTextFile(m1->name) ||
|
|
m1->attr & LT_ATTR_DIR) {
|
|
tempm2=MCFindMatch(m1,m2);
|
|
if (!tempm2) {
|
|
coutln "Does Not Exist on Remote:",m1->name;
|
|
full_name=MAlloc(StrLen(cur_dir)+1+StrLen(m1->name)+1+1);
|
|
StrCpy(full_name,cur_dir);
|
|
StrCat(full_name,m1->name);
|
|
} else {
|
|
full_name=MAlloc(StrLen(cur_dir)+1+StrLen(tempm2->name)+1+1);
|
|
StrCpy(full_name,cur_dir);
|
|
StrCat(full_name,tempm2->name);
|
|
}
|
|
if (m1->attr & LT_ATTR_DIR) {
|
|
if (!tempm2) {
|
|
if (PopUpNoYes("MkDir on Remote?")) {
|
|
XTalk(tss,"MkDir(\"%s\");\r",full_name);
|
|
chnl->null_msg_cnt=0;
|
|
while (chnl->null_msg_cnt<2)
|
|
SwapInNext;
|
|
}
|
|
}
|
|
StrCat(full_name,"/");
|
|
RmtMergeChkList(tss,chnl,m1->sub,tempm2->sub,fuf_flags,df_flags,full_name);
|
|
} else {
|
|
if (tempm2) {
|
|
i=m1->datetime-tempm2->datetime;
|
|
if (AbsI8(i)>LTDATE_FREQ*2) { //Filedates can shift due to conversion
|
|
if (i<0) {
|
|
c1=red_st;
|
|
c2=green_st;
|
|
} else {
|
|
c1=green_st;
|
|
c2=red_st;
|
|
}
|
|
PrintF("%s%h2D %h4T$$FG$$ %s%h2D %h4T$$FG$$\r\n %s\r\n\r\n",
|
|
c1,m1->datetime.date,m1->datetime.time,
|
|
c2,tempm2->datetime.date,tempm2->datetime.time,
|
|
m1->full_name);
|
|
if (PopUpNoYes("Sync?")) {
|
|
if (i<0)
|
|
XTalk(tss,"RmtRqstRxFile(\"%s\",\"%s\");\r",
|
|
full_name,m1->full_name);
|
|
else
|
|
XTalk(tss,"RmtRqstTxFile(\"%s\",\"%s\");\r",
|
|
full_name,m1->full_name);
|
|
chnl->null_msg_cnt=0;
|
|
while (chnl->null_msg_cnt<2)
|
|
SwapInNext;
|
|
}
|
|
}
|
|
} else {
|
|
if (PopUpNoYes("Sync?")) {
|
|
XTalk(tss,"RmtRqstTxFile(\"%s\",\"%s\");\r",
|
|
full_name,m1->full_name);
|
|
chnl->null_msg_cnt=0;
|
|
while (chnl->null_msg_cnt<2)
|
|
SwapInNext;
|
|
}
|
|
}
|
|
}
|
|
Free(full_name);
|
|
}
|
|
m1=m1->next;
|
|
}
|
|
}
|
|
|
|
public void RmtMergeChkHost(I1 *dst_mask="/LT/*",I1 *flags="+r")
|
|
{
|
|
LTDirEntry *tempm;
|
|
U8 size;
|
|
U1 *buf;
|
|
FlagsStruct f;
|
|
GetFFlags(&f,"ST_FILE_UTIL_FLAGS",flags);
|
|
tempm=FindFiles(dst_mask,&f.on);
|
|
buf=FlattenLTDirTree(tempm,&size);
|
|
RmtRqstRxBuf(buf,size);
|
|
Free(buf);
|
|
DelLTDirList(tempm);
|
|
}
|
|
|
|
I1 *Progress1CB(Ltf *l,Ltf *user_data,LtfEntry *ll,TssStruct *mem_tss)
|
|
{
|
|
I1 *st=MAlloc(16,mem_tss);
|
|
SPrintF(st,"%08X",progress1);
|
|
return st;
|
|
}
|
|
|
|
public void RmtMergeChk(LTChnl *chnl,
|
|
I1 *dst_mask="/LT/*",
|
|
I1 *src_mask="/LT/*",
|
|
I1 *flags="+r+t")
|
|
//+r=recurse
|
|
//+d=diff
|
|
//+t=Just text files
|
|
{
|
|
U8 df_flags=0;
|
|
LTDirEntry *tempm1=NULL,*tempm2=NULL;
|
|
FlagsStruct f;
|
|
TssStruct *tss;
|
|
I1 *st,*st2;
|
|
Ltf *aux;
|
|
LtfEntry *ll;
|
|
|
|
if (!chnl || !chnl->type) return;
|
|
GetFFlags(&f,"ST_FILE_UTIL_FLAGS",flags);
|
|
coutln "WARNING:This is based strictly on file dates.";
|
|
if (tempm1=FindFiles(src_mask,&f.on)) {
|
|
tss=Spawn(&UserCmdLine);
|
|
while (!Bt(&tss->task_flags,TSSf_IDLE))
|
|
SwapInNext;
|
|
tss->window_top=Fs->window_top;
|
|
tss->window_bottom=(Fs->window_top+Fs->window_bottom)>>1-1;
|
|
Fs-> window_top=tss->window_bottom+3;
|
|
tss->window_right=Fs->window_right;
|
|
tss->window_left=Fs->window_left;
|
|
WindowToTop(Fs);
|
|
XTalk(tss,"TelnetGuestOpen(0x%08X);\r",chnl);
|
|
|
|
aux=tss->aux_ltf;
|
|
LtfPutS(aux,"$$CM+BY,0,0$$");
|
|
ll=LtfPutS(aux,"$$TX+DC+RD+LX+IV,\"00000000\"$$");
|
|
ll->display_cb=&Progress1CB;
|
|
|
|
XTalk(tss,"RmtMergeChkHost(\"%s\",\"%s\");\r",dst_mask,flags);
|
|
chnl->null_msg_cnt=0;
|
|
while (chnl->null_msg_cnt<2)
|
|
SwapInNext;
|
|
tempm2=UnflattenLTDirTree(chnl->rx_buf);
|
|
st =MAlloc(StrLen(dst_mask)+3);
|
|
st2=MAlloc(StrLen(dst_mask)+3);
|
|
StrCpy(st,dst_mask);
|
|
RemoveLastSeg(st,"/",st2);
|
|
if (!*st) {
|
|
Free(st);
|
|
st=NewString("./");
|
|
} else
|
|
StrCat(st,"/");
|
|
|
|
RmtMergeChkList(tss,chnl,tempm1,tempm2,&f.on,&df_flags,st);
|
|
Free(st);
|
|
Free(st2);
|
|
DelLTDirList(tempm1);
|
|
DelLTDirList(tempm2);
|
|
XTalkString(tss,"Msg(MSG_KEY_DOWN,CH_CTRLB,SCF_CTRL+SCF_ALT);");
|
|
Fs->window_top=tss->window_top;
|
|
Sleep(250); //allow shutdown of Guest channel
|
|
Kill(tss);
|
|
}
|
|
}
|
|
|
|
|