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;idisplay[i]; for (i=0;idisplay[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); } }