home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / fm2000 / copy.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-04  |  27.4 KB  |  1,095 lines

  1. /*
  2.      Filemaster - Multitasking directory utility.
  3.      Copyright (C) 2000  Toni Wilen
  4.      
  5.      This program is free software; you can redistribute it and/or
  6.      modify it under the terms of the GNU General Public License
  7.      as published by the Free Software Foundation; either version 2
  8.      of the License, or (at your option) any later version.
  9.      
  10.      This program is distributed in the hope that it will be useful,
  11.      but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.      GNU General Public License for more details.
  14.      
  15.      You should have received a copy of the GNU General Public License
  16.      along with this program; if not, write to the Free Software
  17.      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19.  
  20. #include <exec/types.h>
  21. #include <exec/memory.h>
  22. #include <dos/dos.h>
  23. #include <proto/all.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include "fmnode.h"
  27. #include "child.h"
  28. #include "fmdos.h"
  29. #include "fmlocale.h"
  30. #include "fmgui.h"
  31.  
  32. extern struct FMConfig *fmconfig;
  33. extern struct FMMain fmmain;
  34. extern UBYTE nformatstring[];
  35.  
  36. struct CopyConfig {
  37.     unsigned overwrite:2;
  38.     unsigned comment:2;
  39.     unsigned flags:2;
  40.     unsigned freespace:2;
  41.     unsigned date:2;
  42.     unsigned update:2;
  43.     LONG bufsize;
  44. };
  45. struct DeleteConfig {
  46.     unsigned askdelete:2;
  47.     unsigned askdir:2;
  48.     unsigned protected:2;
  49.     unsigned update:2;
  50. };
  51.  
  52. WORD deletefile(struct FMList*,UBYTE*,struct DeleteConfig*,WORD);
  53. WORD deletedir(struct FMList*,UBYTE*,struct DelStr*,WORD);
  54. WORD deletefirst(struct FMList*,struct FMNode*,struct DelStr*);
  55.  
  56. WORD askcopyname(struct FMList*,UBYTE*,struct DelStr*);
  57. void copyroutine(struct CMenuConfig *cmc);
  58. WORD copyfile(struct FMList*,struct FMList*,UBYTE*,struct DelStr*);
  59. WORD copydir(struct FMList*,struct FMList*,UBYTE*,struct DelStr*,WORD flag);
  60. void copyflags(struct CopyConfig*,struct FMList*,struct FMList*,UBYTE*,UBYTE*);
  61.  
  62. WORD renamefile(struct FMList*,struct FMList*,UBYTE*);
  63.  
  64. WORD sizedir(struct FMList*,UBYTE*,struct DelStr*,LONG*);
  65.  
  66. WORD doubleabort(struct FMList*,struct FMList*);
  67.  
  68. struct DelStr *createtoken(struct FMList*);
  69. WORD dmatch(struct FileInfoBlock*,struct DelStr*);
  70. WORD askcontinue(struct FMList*);
  71.  
  72. void clearlisti(struct List*);
  73.  
  74. struct DelStr {
  75.     ULONG    filecnt;
  76.     ULONG    dircnt;
  77.     ULONG    bytecnt;
  78.     UBYTE    method;
  79.     UBYTE    owflag;
  80.     UBYTE    asflag;
  81.     UBYTE    allsubdelete;
  82.     struct    CopyConfig *cconfig;
  83.     struct    DeleteConfig *dconfig;
  84.     struct    Match match;
  85.     UBYTE    token1[1000];
  86.     UBYTE    token2[1000];
  87.     UBYTE    token3[500];
  88. };
  89.  
  90. // ********* COPY **************
  91.  
  92. void __saveds copyfiles(void)
  93. {
  94. struct ProcMsg *pm;
  95. struct CMenuConfig *cmc;
  96. pm=sinitproc();
  97. cmc=pm->cmc;
  98. copyroutine(cmc);
  99. deinitproc(pm);
  100. }
  101.  
  102. void copyroutine(struct CMenuConfig *cmc)
  103. {
  104. struct FMList *slist;
  105. struct FMList *dlist;
  106. struct FMNode *node;
  107. struct DelStr *delstr;
  108. WORD ret;
  109. UBYTE varaname[32];
  110. UBYTE aputxt[80];
  111.  
  112. priority(cmc);
  113. slist=fmmain.sourcedir;
  114. dlist=fmmain.destdir;
  115. if (!(setalloc(slist,1))) { initproc(0,0); return; }
  116. if (!(setalloc(dlist,1))) { setalloc(slist,0); initproc(0,0); return; }
  117. slist->pair=dlist;
  118. dlist->pair=slist;
  119. if (!(delstr=createtoken(slist))) {
  120.     initproc(slist,(UBYTE*)1);
  121.     goto delfailure1;
  122. }
  123. sformat(aputxt,getstring(MSG_COPYNAMESOURCE),cmc->label);
  124. initproc(slist,aputxt);
  125. sformat(aputxt,getstring(MSG_COPYNAMEDESTINATION),cmc->label);
  126. strcpy(dlist->workname,aputxt);
  127. if(cmc->cmenucount==COPYASCONFIG) delstr->method=1;
  128. delstr->cconfig=getconfig(cmc);
  129. if(!delstr->cconfig) goto delfailure1;
  130.  
  131. if(!sselected(slist,-1)) goto delfailure1;
  132. if(!(dlist->flags&LDIRLIST)) {
  133.     strcpymsg(slist->fmmessage1,MSG_MAIN_NODESTINATION);
  134.     goto delfailure1;
  135. }
  136. slist->flags|=LUPDATEMSG; dlist->flags|=LUPDATEMSG;
  137. sformatmsg(slist->fmmessage1,MSG_COPYING,0L,0L,0L);
  138. strcpy(dlist->fmmessage1,slist->fmmessage1);
  139. fmmessage(slist);
  140. fmmessage(dlist);
  141. for(node=slist->head;node->succ;node=node->succ) {
  142.     if(node->flags&NFILE && node->flags&NSELECTED) {
  143.         strcpy(varaname,NDFILE(node));
  144.         ret=copyfile(slist,dlist,varaname,delstr);
  145.         node->flags&=~NSELECTED;
  146.         outputlistline(slist,node);
  147.         disknode(dlist,varaname);
  148.         if (delstr->cconfig->update==0) outputlist(dlist);
  149.         if (!ret) goto delfailure1;
  150.         sformatmsg(slist->fmmessage1,MSG_COPYING,delstr->filecnt,delstr->dircnt,delstr->bytecnt);
  151.         strcpy(dlist->fmmessage1,slist->fmmessage1);
  152.     }
  153. }
  154. for(node=slist->head;node->succ;node=node->succ) {
  155.     if(node->flags&NDIRECTORY && node->flags&NSELECTED) {
  156.         strcpy(varaname,NDFILE(node));
  157.         ret=copydir(slist,dlist,varaname,delstr,0);
  158.         node->flags&=~NSELECTED;
  159.         outputlistline(slist,node);
  160.         disknode(dlist,varaname);
  161.         if(delstr->cconfig->update<=1) outputlist(dlist);
  162.         if (!ret) goto delfailure1;
  163.     }
  164. }
  165. sformatmsg(slist->fmmessage1,MSG_COPIED,delstr->filecnt,delstr->dircnt,delstr->bytecnt);
  166. slist->fmmessage2[0]=0;
  167. strcpy(dlist->fmmessage1,slist->fmmessage1);
  168. strcpy(dlist->fmmessage2,slist->fmmessage2);
  169. delfailure1:
  170. freemem(delstr);
  171. fmmessage(slist);
  172. fmmessage(dlist);
  173. csortlist(dlist);
  174. parselist(dlist,0);
  175. outputlist(slist);
  176. outputlist(dlist);
  177. updadirmeter(dlist);
  178. endproc(slist);
  179. }
  180.  
  181. WORD copydir(struct FMList *slist,struct FMList *dlist,UBYTE *dirname,struct DelStr *ds,WORD flag)
  182. {
  183. struct FileInfoBlock *fib;
  184. BPTR lock=0;
  185. WORD ret=0,ret2,ret3,dret,dflag=0;
  186. UBYTE name[32];
  187. UBYTE varaname[32];
  188. UBYTE path1[PATH],path2[PATH];
  189.  
  190. if (!doubleabort(slist,dlist)) return(0);
  191. fib=allocmem(sizeof(struct FileInfoBlock));
  192. if (!fib) return(0);
  193.  
  194. AddPart(slist->path,dirname,PATH);
  195. ret2=askcopyname(dlist,dirname,ds);
  196. AddPart(dlist->path,dirname,PATH);
  197. if(!ret2) goto dderr;
  198.  
  199. sformatmsg(slist->fmmessage1,MSG_COPYING,ds->filecnt,ds->dircnt,ds->bytecnt);
  200. strcpy(dlist->fmmessage1,slist->fmmessage1);
  201.  
  202. createretry:
  203. if (!(lock=CreateDir(dlist->path))) {
  204.     if(checkdoserr()!=203) {
  205.         ret3=dosrequestmsg(dlist,3,MSG_FMDOS_MAKEDIRERR,dirname);
  206.         if(ret3>0) goto createretry;
  207.         if(ret3<0) {
  208.             ret=-1;
  209.             goto dderr;
  210.         }
  211.     }
  212. }
  213. if (lock) UnLock(lock);
  214. lock=0;
  215. strcpy(path1,slist->path);
  216. strcpy(path2,dlist->path);
  217. *(PathPart(slist->path))=0;
  218. *(PathPart(dlist->path))=0;
  219. copyflags(ds->cconfig,slist,dlist,dirname,dirname);
  220. strcpy(slist->path,path1);
  221. strcpy(dlist->path,path2);
  222.  
  223. if (!(lock=fminitdirread(slist,fib,slist->path))) goto dderr;
  224. while(fmexnext(slist,lock,fib)>0) {
  225.     if(dflag) {
  226.         if (!deletefile(slist,name,ds->dconfig,1)) goto dderr;
  227.         dflag=0;
  228.     }
  229.     if(dmatch(fib,ds)) {
  230.         if (fib->fib_DirEntryType>0) {
  231.             strcpy(varaname,fib->fib_FileName);
  232.             dret=copydir(slist,dlist,varaname,ds,flag);
  233.             if(!dret) goto dderr;
  234.         } else {
  235.             strcpy(varaname,fib->fib_FileName);
  236.             dret=copyfile(slist,dlist,varaname,ds);
  237.             if(!dret) goto dderr;
  238.             sformatmsg(slist->fmmessage1,MSG_COPYING,ds->filecnt,ds->dircnt,ds->bytecnt);
  239.             strcpy(dlist->fmmessage1,slist->fmmessage1);
  240.         }
  241.     }
  242.     if (flag&&dret>0) {
  243.         strcpy(name,fib->fib_FileName);
  244.         dflag=1;
  245.     }
  246. }
  247. if(dflag) {
  248.     if (!deletefile(slist,name,ds->dconfig,1)) goto dderr;
  249. }
  250. ret=1;
  251. dderr:
  252. if(ret>0) ds->dircnt++;
  253. *(PathPart(slist->path))=0;
  254. *(PathPart(dlist->path))=0;
  255. UnLock(lock);
  256. freemem(fib);
  257. return(ret);
  258. }
  259.  
  260.  
  261. WORD copyfile(struct FMList *slist,struct FMList *dlist,UBYTE *name,struct DelStr *ds)
  262. {
  263. struct GUIBase *gb;
  264. struct FMHandle *hs=0;
  265. struct FMHandle *hd=0;
  266. struct FileInfoBlock *fib;
  267. LONG cnt,cnt2=0;
  268. WORD ret=0,nocont=0;
  269. UBYTE varaname[32];
  270. ULONG size,dstsize;
  271. BPTR lock=0,olock=0;
  272. LONG dstdate=0;
  273. //struct DeleteConfig dc;
  274. WORD c=0;
  275. UBYTE text[100];
  276. UBYTE date1[80],date2[80];
  277.  
  278. struct InfoData *id;
  279. LONG bytesperblock,alreadyblocks=0,freeblocks;
  280.  
  281. if (!doubleabort(slist,dlist)) return(0);
  282.  
  283. strcpy(varaname,name);
  284. if (hs=openfile(slist,varaname,OFBUFFER|(ds->cconfig->bufsize?ds->cconfig->bufsize:60000))) {
  285.     size=hs->size;
  286.  
  287.     sformatmsg(slist->fmmessage2,MSG_COPYING2,hs->filename,0L,hs->size);
  288.     strcpy(dlist->fmmessage2,slist->fmmessage2);
  289.  
  290.     if(askcopyname(dlist,name,ds)) {
  291.  
  292.         // freespace check
  293.     
  294.         fib=allocmem(sizeof(struct FileInfoBlock));
  295.         if(currentdir(dlist)) olock=Lock(name,SHARED_LOCK);
  296.         if(fib&&olock) {
  297.             if(fmexamine(dlist,olock,fib,name)) {
  298.                 alreadyblocks=fib->fib_NumBlocks;
  299.                 dstdate=dstolong(&fib->fib_Date);
  300.                 dstsize=fib->fib_Size;
  301.             }
  302.         }
  303.         freemem(fib);
  304.  
  305.         if(ds->cconfig->freespace) {
  306.             id=allocmem(sizeof(struct InfoData));
  307.             lock=fmlock(slist,dlist->path);
  308.             if(id&&lock&&Info(lock,id)) {
  309.                 bytesperblock=512;
  310.                 freeblocks=id->id_NumBlocks-id->id_NumBlocksUsed;
  311.                 if(id->id_DiskType==ID_DOS_DISK||id->id_DiskType==ID_INTER_DOS_DISK) bytesperblock=488;
  312.                 if(id->id_DiskType&0xffffff00==ID_DOS_DISK&0xffffff00)
  313.                     size+=((((size+bytesperblock)/bytesperblock)/72)*512);
  314.                 if(freeblocks) freeblocks+=alreadyblocks;
  315.                 if(freeblocks&&(freeblocks-1)*bytesperblock<=size) {
  316.                     gb=getguibase(slist->workname);
  317.                     sformatmsg(text,MSG_COPY_NOFREESPACE,name);
  318.                     reqinfo(gb,text,-1,guiCENTER);
  319.                     buttonbarmsg(gb,MSG_IGNORE,1,MSG_SKIP,2,MSG_CANCEL,0,0);
  320.                     c=quickreq(gb);
  321.                     if(!c) {
  322.                         ret=0;
  323.                         nocont=1;
  324.                         goto nocopy;
  325.                     }
  326.                     if(c==2) {
  327.                         ret=-1;
  328.                         goto nocopy;
  329.                     }
  330.                 }
  331.             }
  332.             if(lock) UnLock(lock);
  333.             lock=0;
  334.             freemem(id);
  335.         }
  336.  
  337.         size=hs->size;
  338.  
  339.         // overwrite check
  340.  
  341.         if(!ds->owflag&&ds->cconfig->overwrite&¤tdir(dlist)) {
  342.             if (olock) {
  343.                 gb=getguibase(slist->workname);
  344.                 longtodatestring(date1,hs->date);
  345.                 longtodatestring(date2,dstdate);
  346.                 sformatmsg(text,MSG_COPY_OVERWRITE,name,date1,hs->size,date2,dstsize);
  347.                 reqinfo(gb,text,-1,guiCENTER);
  348.                 buttonbarmsg(gb,MSG_YES,1,MSG_ALL,2,MSG_NO,3,MSG_CANCEL,0,0);
  349.                 c=quickreq(gb);
  350.                 if(!c) {
  351.                     ret=0;
  352.                     nocont=1;
  353.                     goto nocopy;
  354.                 }
  355.                 if(c==3) {
  356.                     ret=-1;
  357.                     goto nocopy;
  358.                 }
  359.                 if(c==2) {
  360.                     ds->owflag=1;
  361.                 }
  362.             }
  363.         }
  364.  
  365.         if(olock) UnLock(olock);
  366.         olock=0;
  367.  
  368.         if (hd=openfile(dlist,name,OFWRITE)) {
  369.             ret=1;
  370.             for(;;) {
  371.                 sformatmsg(slist->fmmessage2,MSG_COPYING2,hs->filename,cnt2,hs->size);
  372.                 strcpy(dlist->fmmessage2,slist->fmmessage2);
  373.                 cnt=readfile(hs);
  374.                 if(cnt<0) {
  375.                     ret=-1;
  376.                     break;
  377.                 }
  378.                 cnt2+=cnt;
  379.                 if (cnt==0) break;
  380.                 sformatmsg(slist->fmmessage2,MSG_COPYING2,hd->filename,cnt2,hs->size);
  381.                 strcpy(dlist->fmmessage2,slist->fmmessage2);
  382.                 if(!doubleabort(slist,dlist)) {
  383.                     ret=0;
  384.                     nocont=1;
  385.                     break;
  386.                 }
  387.                 if (cnt<0||writefile(hd,hs->buffer,cnt)!=cnt) {
  388.                     ret=-1;
  389.                     break;
  390.                 }
  391.             }
  392.             closefile(hd);
  393.             if(ret>0) copyflags(ds->cconfig,slist,dlist,varaname,name);
  394.         }
  395.     }
  396. nocopy:
  397. closefile(hs);
  398. }
  399. if(ret<=0) {
  400. /*
  401.     if(hd) {
  402.         dc.askdelete=0;
  403.         dc.askdir=0;        
  404.         dc.protected=0;
  405.         deletefile(dlist,name,&dc);
  406.     }
  407. */
  408.     if(!ret&&!ds->method&&!nocont) ret=askcontinue(slist);
  409. } else {
  410.     ds->filecnt++;
  411.     ds->bytecnt+=size;
  412. }
  413. if(olock) UnLock(olock);
  414. if(lock) UnLock(lock);
  415. return(ret);
  416. }
  417.  
  418. WORD askcopyname(struct FMList *list,UBYTE *txt,struct DelStr *ds)
  419. {
  420. struct GUIBase *gb;
  421. WORD ret=0,c;
  422.  
  423. if(!ds->method||ds->asflag) return(1);
  424.  
  425. gb=getguibase(list->workname);
  426. setconnectgroup(gb,1,0,0);
  427. reqinfomsg(gb,MSG_COPY_NEWNAME,100,guiUC|guiLEFT);
  428. reqstring(gb,100,txt,31);
  429. buttonbarmsg(gb,MSG_OK,1,MSG_ALL,2,MSG_CANCEL,0,0);
  430. c=quickreq(gb);
  431. if(c==1) {
  432.     ret=1;
  433. }
  434. if(c==2) {
  435.     ds->asflag=1;
  436.     ret=1;
  437. }
  438. return(ret);
  439. }
  440.  
  441. void copyflags(struct CopyConfig *cconfig,struct FMList *slist,struct FMList *dlist,UBYTE *sname,UBYTE *dname)
  442. {
  443. struct FileInfoBlock *fib;
  444.  
  445. fib=allocmem(sizeof(struct FileInfoBlock));
  446. if(!fib) return;
  447. if(cconfig->comment|cconfig->flags|cconfig->date) {
  448.     if(fmexaminefile(slist,fib,sname)) {
  449.         if(cconfig->comment&&fib->fib_Comment[0]) fmsetcomment(dlist,dname,fib->fib_Comment);
  450.         if(cconfig->flags&&fib->fib_Protection!=0x0f) fmsetprotection(dlist,dname,fib->fib_Protection);
  451.         if(cconfig->date) fmsetfiledate(dlist,dname,&fib->fib_Date);
  452.     }
  453. }
  454. freemem(fib);
  455. }
  456.  
  457. // ************ DELETE **************
  458.  
  459.  
  460. void __saveds deletefiles(void)
  461. {
  462. struct FMList *list;
  463. struct FMNode *node;
  464. struct FMNode *nxtnode;
  465. struct ProcMsg *pm;
  466. struct DelStr *delstr;
  467. WORD first=1;
  468. WORD apu1;
  469.  
  470. pm=sinitproc();
  471. priority(pm->cmc);
  472. list=fmmain.sourcedir;
  473. if (!(setalloc(list,1))) { initproc(0,0); return; }
  474. if (!(delstr=createtoken(list))) {
  475.     initproc(list,(UBYTE*)1);
  476.     goto delfailure1;
  477. }
  478. initproc(list,pm->cmc->label);
  479. delstr->dconfig=getconfig(pm->cmc);
  480. if(!delstr->dconfig) goto delfailure1;
  481. if(!sselected(list,-1)) goto delfailure1;
  482.  
  483. list->flags|=LUPDATEMSG;
  484. sformatmsg(list->fmmessage1,MSG_DELETING,0L,0L,0L);
  485. fmmessage(list);
  486. if (!currentdir(list)) goto delfailure1;
  487. for(node=list->head;node->succ;node=node->succ) {
  488.     if(node->flags&NFILE && node->flags&NSELECTED) {
  489.         if(first) {
  490.             if(!deletefirst(list,node,delstr)) goto delfailure1;
  491.             first=0;
  492.         }
  493.         nxtnode=node->pred;
  494.         apu1=deletefile(list,NDFILE(node),delstr->dconfig,0);
  495.         node->flags&=~NSELECTED;
  496.         if(!apu1) goto delfailure1;
  497.         if(apu1>0) {
  498.             delstr->filecnt++;
  499.             delstr->bytecnt+=node->numlen;
  500.             sformatmsg(list->fmmessage1,MSG_DELETING,delstr->filecnt,delstr->dircnt,delstr->bytecnt);
  501.             sformat(list->fmmessage2,"'%s'",NDFILE(node));
  502.             removenode(list,node);
  503.             node=nxtnode;
  504.         }
  505.         if(delstr->dconfig->update==0) outputlist(list);
  506.     }
  507. }
  508. for(node=list->head;node->succ;node=node->succ) {
  509.     if(node->flags&NDIRECTORY && node->flags&NSELECTED) {
  510.         if(first) {
  511.             if(!deletefirst(list,node,delstr)) goto delfailure1;
  512.             first=0;
  513.         }
  514.         nxtnode=node->pred;
  515.         apu1=deletedir(list,NDFILE(node),delstr,delstr->dconfig->askdir);
  516.         node->flags&=~NSELECTED;
  517.         if(!apu1) goto delfailure1;
  518.         if(apu1>0) {
  519.             if (!(apu1=deletefile(list,NDFILE(node),delstr->dconfig,0))) goto delfailure1;
  520.             if(apu1>0) {
  521.                 delstr->dircnt++;
  522.                 removenode(list,node);
  523.                 node=nxtnode;
  524.             }
  525.         }
  526.         if(delstr->dconfig->update<=1) outputlist(list);
  527.     }
  528. }
  529. sformatmsg(list->fmmessage1,MSG_DELETED,delstr->filecnt,delstr->dircnt,delstr->bytecnt);
  530. list->fmmessage2[0]=0;
  531. delfailure1:
  532. freemem(delstr);
  533. fmmessage(list);
  534. outputlist(list);
  535. updadirmeter(list);
  536. endproc(list);
  537. deinitproc(pm);
  538. }
  539.  
  540. WORD deletedir(struct FMList *list,UBYTE *dirname,struct DelStr *ds,WORD subdir)
  541. {
  542. struct GUIBase *gb;
  543. struct FileInfoBlock *fib=0;
  544. BPTR lock=0;
  545. WORD ret=0,flag=0,apu1,empty=0;
  546. UBYTE name[32];
  547. WORD c;
  548. UBYTE text[100];
  549.  
  550. AddPart(list->path,dirname,PATH);
  551. if (testabort(list)) {
  552.     if (askabort(list)) goto dderr;
  553. }
  554. sformatmsg(list->fmmessage1,MSG_DELETING,ds->filecnt,ds->dircnt,ds->bytecnt);
  555.  
  556. fib=allocmem(sizeof(struct FileInfoBlock));
  557. if (!fib) goto dderr;
  558.  
  559. if (!(currentdir(list))) goto dderr;
  560. if (!(lock=fminitdirread(list,fib,list->path))) goto dderr;
  561. while(fmexnext(list,lock,fib)>0) {
  562.     sformatmsg(list->fmmessage1,MSG_DELETING,ds->filecnt,ds->dircnt,ds->bytecnt);
  563.  
  564.     if(!empty&&subdir&&!ds->allsubdelete) {
  565.         empty=1;
  566.         sformat(list->fmmessage2,"'%s'",dirname);
  567.         gb=getguibase(list->workname);
  568.         sformatmsg(text,MSG_DELETE_ASKDIRECTORY,dirname);
  569.         reqinfo(gb,text,-1,guiCENTER);
  570.         buttonbarmsg(gb,MSG_YES,1,MSG_ALL,2,MSG_NO,3,MSG_CANCEL,0,0);
  571.         c=quickreq(gb);
  572.         if(!c) {
  573.             ret=0;
  574.             goto dderr;
  575.         }
  576.         if(c==3) {
  577.             ret=-1;
  578.             goto dderr;
  579.         }
  580.         if(c==2) {
  581.             ds->allsubdelete=1;
  582.         }
  583.     }
  584.  
  585.  
  586.     if(flag) {
  587.         apu1=deletefile(list,name,ds->dconfig,0);
  588.         flag=0;
  589.         if(!apu1) goto dderr;
  590.         if(apu1>0) ds->dircnt++;
  591.     }
  592.     if(dmatch(fib,ds)) {
  593.         if (fib->fib_DirEntryType>0) {
  594.             if (!(apu1=deletedir(list,fib->fib_FileName,ds,0))) goto dderr;
  595.             if(apu1==1) {
  596.                 strcpy(name,fib->fib_FileName);
  597.                 flag=1;
  598.             }
  599.         } else {
  600.             if (!(apu1=deletefile(list,fib->fib_FileName,ds->dconfig,0))) goto dderr;
  601.             if(apu1<0) {
  602.                 ret=-1;
  603.             } else {
  604.                 ds->filecnt++;
  605.                 ds->bytecnt+=fib->fib_Size;
  606.             }        
  607.         }
  608.     }
  609. }
  610. if(flag) {
  611.     sformat(list->fmmessage2,"'%s'",fib->fib_FileName);
  612.     apu1=deletefile(list,name,ds->dconfig,0);
  613.     if(!apu1) goto dderr;
  614.     if(apu1>0) ds->dircnt++;
  615. }
  616. if(!ret) ret=1;
  617. dderr:
  618. if (lock) UnLock(lock);
  619. freemem(fib);
  620. *(PathPart(list->path))=0;
  621. return(ret);
  622. }
  623.  
  624.  
  625. WORD deletefile(struct FMList *list,UBYTE *name,struct DeleteConfig *dc,WORD req)
  626. {
  627. WORD error;
  628. WORD ret=0;
  629.  
  630. dretry:
  631. if (testabort(list)) {
  632.     if (askabort(list)) goto dferr;
  633. }
  634. sformat(list->fmmessage2,"'%s'",name);
  635. if (!currentdir(list)) goto dferr;
  636. if (!DeleteFile(name)) {
  637.     outputlist(list);
  638.     error=checkdoserr();
  639.     if(error==222) {
  640.         if(dc->protected) {
  641.             if(!requestmsg(getstring(MSG_MAIN_AREYOUSURE),MSG_YES,MSG_NO,MSG_DELETE_DELPROTECTED,name)) {
  642.                 ret=-1;
  643.                 goto dferr;
  644.             }
  645.         }
  646.         do {
  647.             if(SetProtection(name,0)) goto dretry;
  648.         } while(dosrequestmsg(list,1,MSG_FMDOS_REMDELPROT,name));
  649.         goto dferr;
  650.     }
  651. delerr:    if(!req) {
  652.         ret=dosrequestmsg(list,3,MSG_FMDOS_DELETEERR,name);
  653.         if(ret>0) goto dretry;
  654.     } else {
  655.         if(ret<0) ret=0;
  656.     }
  657. } else {
  658.     ret=1;
  659. }
  660. dferr:
  661. return(ret);
  662. }
  663.  
  664. WORD deletefirst(struct FMList *list,struct FMNode *node,struct DelStr *ds)
  665. {
  666. if(ds->dconfig->askdelete) {
  667.     outputlistline(list,node);
  668.     return(requestmsg(getstring(MSG_MAIN_AREYOUSURE),MSG_YES,MSG_NO,MSG_DELETE_ASKDELETE));
  669. }
  670. return(1);
  671. }
  672.  
  673. /// **************** MOVE ****************
  674.  
  675. void __saveds movefiles(void)
  676. {
  677. struct ProcMsg *pm;
  678. struct FMList *slist;
  679. struct FMList *dlist;
  680. struct FMNode *node,*nxtnode;
  681. struct DelStr *delstr;
  682. LONG rename;
  683. WORD apu1;
  684. UBYTE *string=0;
  685. struct CopyConfig fakecconfig;
  686. struct DeleteConfig fakedconfig;
  687. struct CopyConfig *moveconfig;
  688. BPTR lock1=0,lock2=0;
  689. UBYTE varaname[32];
  690.  
  691. pm=sinitproc();
  692. priority(pm->cmc);
  693. slist=fmmain.sourcedir;
  694. dlist=fmmain.destdir;
  695. if (!(setalloc(slist,1))) { initproc(0,0); return; }
  696. if (!(setalloc(dlist,1))) { setalloc(slist,0); initproc(0,0); return; }
  697. slist->pair=dlist;
  698. dlist->pair=slist;
  699. if (!(delstr=createtoken(slist))) {
  700.     initproc(slist,(UBYTE*)1);
  701.     goto delfailure1;
  702. }
  703. initproc(slist,pm->cmc->label);
  704. moveconfig=getconfig(pm->cmc);
  705. if(!moveconfig) goto delfailure1;
  706. delstr->cconfig=&fakecconfig;
  707. delstr->dconfig=&fakedconfig;
  708. fakedconfig.askdelete=0;
  709. fakedconfig.askdir=0;
  710. fakedconfig.protected=0;
  711. fakecconfig.overwrite=moveconfig->overwrite;
  712. fakecconfig.comment=moveconfig->comment;
  713. fakecconfig.date=moveconfig->date;
  714. fakecconfig.flags=moveconfig->flags;
  715. fakecconfig.freespace=moveconfig->freespace;
  716. if(!sselected(slist,-1)) goto delfailure1;
  717. if(!(dlist->flags&LDIRLIST)) {
  718.     strcpymsg(slist->fmmessage1,MSG_MAIN_NODESTINATION);
  719.     goto delfailure1;
  720. }
  721. slist->flags|=LUPDATEMSG; dlist->flags|=LUPDATEMSG;
  722. sformatmsg(slist->fmmessage1,MSG_MOVING,0,string,0,string,0,string);
  723. strcpy(dlist->fmmessage1,slist->fmmessage1);
  724. fmmessage(slist);
  725. fmmessage(dlist);
  726. lock1=fmlock(slist,slist->path);
  727. lock2=fmlock(dlist,dlist->path);
  728. if(!lock1||!lock2) goto delfailure1;
  729. rename=SameLock(lock1,lock2);
  730. if (rename==LOCK_DIFFERENT) rename=0; else rename=1;
  731.  
  732. for(node=slist->head;node->succ;node=node->succ) {
  733.     if(node->flags&NFILE && node->flags&NSELECTED) {
  734.         nxtnode=node->pred;
  735.         strcpy(varaname,NDFILE(node));
  736.         if (rename) {
  737.             if (!(apu1=renamefile(slist,dlist,varaname))) goto delfailure1;
  738.             node->flags&=~NSELECTED;
  739.             disknode(dlist,varaname);
  740.             if(moveconfig->update==0) outputlist(dlist);
  741.             if(apu1>0) {
  742.                 delstr->filecnt++;
  743.                 delstr->bytecnt+=node->numlen;
  744.             }
  745.         } else {
  746.             apu1=copyfile(slist,dlist,varaname,delstr);
  747.             node->flags&=~NSELECTED;
  748.             disknode(dlist,varaname);
  749.             if(moveconfig->update==0) outputlist(dlist);
  750.             if(!apu1) goto delfailure1;
  751.             if(apu1>0) if(deletefile(slist,varaname,delstr->dconfig,1)<=0) goto delfailure1;
  752.         }
  753.         sformatmsg(slist->fmmessage1,MSG_MOVING,delstr->filecnt,string,delstr->dircnt,string,delstr->bytecnt,string);
  754.         strcpy(dlist->fmmessage1,slist->fmmessage1);
  755.         removenode(slist,node);
  756.         if(moveconfig->update==0) outputlist(slist);
  757.         node=nxtnode;
  758.     }
  759. }
  760. for(node=slist->head;node->succ;node=node->succ) {
  761.     if(node->flags&NDIRECTORY && node->flags&NSELECTED) {
  762.         nxtnode=node->pred;
  763.         strcpy(varaname,NDFILE(node));
  764.         if (rename) {
  765.             apu1=renamefile(slist,dlist,varaname);
  766.             node->flags&=~NSELECTED;
  767.             outputlistline(slist,node);
  768.             disknode(dlist,varaname);
  769.             if(moveconfig->update<=1) outputlist(dlist);
  770.             if(!apu1) goto delfailure1;
  771.             if (node->flags&(NDIRECTORY|NDEVICE|NASSIGN)) string="+";
  772.             if(apu1>0) delstr->dircnt++;
  773.         } else {
  774.             apu1=copydir(slist,dlist,varaname,delstr,1);
  775.             node->flags&=~NSELECTED;
  776.             outputlistline(slist,node);
  777.             disknode(dlist,varaname);
  778.             if(moveconfig->update<=1) outputlist(dlist);
  779.             if (!apu1) goto delfailure1;
  780.             apu1=deletefile(slist,NDFILE(node),delstr->dconfig,1);
  781.             if (!apu1) goto delfailure1;
  782.         }
  783.         sformatmsg(slist->fmmessage1,MSG_MOVING,delstr->filecnt,string,delstr->dircnt,string,delstr->bytecnt,string);
  784.         sformat(slist->fmmessage2,"'%s'",slist->path);
  785.         strcpy(dlist->fmmessage1,slist->fmmessage1);
  786.         strcpy(dlist->fmmessage2,slist->fmmessage2);
  787.         removenode(slist,node);
  788.         if(moveconfig->update<=1) outputlist(slist);
  789.         node=nxtnode;
  790.     }
  791. }
  792. sformatmsg(slist->fmmessage1,MSG_MOVED,delstr->filecnt,string,delstr->dircnt,string,delstr->bytecnt,string);
  793. slist->fmmessage2[0]=0;
  794. strcpy(dlist->fmmessage1,slist->fmmessage1);
  795. strcpy(dlist->fmmessage2,slist->fmmessage2);
  796. delfailure1:
  797. UnLock(lock1);
  798. UnLock(lock2);
  799. freemem(delstr);
  800. fmmessage(slist);
  801. fmmessage(dlist);
  802. csortlist(dlist);
  803. outputlist(slist);
  804. outputlist(dlist);
  805. updadirmeter(slist);
  806. updadirmeter(dlist);
  807. endproc(slist);
  808. deinitproc(pm);
  809. }
  810.  
  811. WORD renamefile(struct FMList *slist,struct FMList *dlist,UBYTE *name)
  812. {
  813. WORD ret=0;
  814.  
  815. AddPart(slist->path,name,PATH);
  816. AddPart(dlist->path,name,PATH);
  817. if(fmsetrename(slist,slist->path,dlist->path)) {
  818.     ret=1;
  819. } else {
  820.     ret=askcontinue(slist);
  821. }
  822. *(PathPart(slist->path))=0;
  823. *(PathPart(dlist->path))=0;
  824. return(ret);
  825. }
  826.  
  827. WORD doubleabort(struct FMList *slist,struct FMList *dlist)
  828. {
  829. if (testabort(slist)) {
  830.     if (askabort(slist)) return(0);
  831. }
  832. if (testabort(dlist)) {
  833.     if (askabort(dlist)) return(0);
  834. }
  835. return(1);
  836. }
  837.  
  838.  
  839. /// ************** DISKSIZE ******************
  840.  
  841. void __saveds disksize(void)
  842. {
  843. struct ProcMsg *pm;
  844. struct FMList *list;
  845. struct FMNode *node;
  846. struct DelStr *delstr;
  847. LONG dsize;
  848. WORD apu1;
  849.  
  850. pm=sinitproc();
  851. priority(pm->cmc);
  852. list=fmmain.sourcedir;
  853. if (!(setalloc(list,1))) { initproc(0,0); return; }
  854. if (!(delstr=createtoken(list))) {
  855.     initproc(list,(UBYTE*)1);
  856.     goto sizfailure1;
  857. }
  858. initproc(list,pm->cmc->label);
  859. if(!sselected(list,-1)) goto sizfailure1;
  860. sformatmsg(list->fmmessage1,MSG_DISKSIZING,0L,0L,0L);
  861. fmmessage(list);
  862. list->flags|=LUPDATEMSG;
  863. for(node=list->head;node->succ;node=node->succ) {
  864.     if(node->flags&NFILE&&node->flags&NSELECTED) {
  865.         delstr->filecnt++;
  866.         delstr->bytecnt+=node->numlen;
  867.         node->flags&=~NSELECTED;
  868.         sformatmsg(list->fmmessage1,MSG_DISKSIZING,delstr->filecnt,delstr->dircnt,delstr->bytecnt);
  869.         sformat(list->fmmessage2,"'%s'",list->path);
  870.         outputlistline(list,node);
  871.     }
  872. }
  873. for(node=list->head;node->succ;node=node->succ) {
  874.     if(node->flags&(NDIRECTORY|NASSIGN|NDEVICE)&&node->flags&NSELECTED) {
  875.         dsize=0;
  876.         apu1=sizedir(list,NDFILE(node),delstr,&dsize);
  877.         node->flags&=~NSELECTED;
  878.         if(apu1<=0) goto sizfailure1;
  879.         sformat(NDLENGTH(node),nformatstring,dsize);
  880.         outputlistline(list,node);
  881.     }
  882. }
  883. sformatmsg(list->fmmessage1,MSG_DISKSIZED,delstr->filecnt,delstr->dircnt,delstr->bytecnt);
  884. list->fmmessage2[0]=0;
  885. sizfailure1:
  886. freemem(delstr);
  887. fmmessage(list);    
  888. outputlist(list);
  889. endproc(list);
  890. }
  891.  
  892. WORD sizedir(struct FMList *list,UBYTE *name,struct DelStr *ds,LONG *dsize)
  893. {
  894. struct FileInfoBlock *fib;
  895. BPTR lock=0;
  896. WORD ret=0;
  897.  
  898. sformatmsg(list->fmmessage1,MSG_DISKSIZING,ds->filecnt,ds->dircnt,ds->bytecnt);
  899. if (testabort(list)) {
  900.     list->fmmessage2[0]=0;
  901.     fmmessage(list);
  902.     if (askabort(list)) return(-1);
  903. }
  904. if (!(fib=allocmem(sizeof(struct FileInfoBlock)))) return(0);
  905. AddPart(list->path,name,PATH);
  906. if (currentdir(list)) {
  907.     if (lock=fminitdirread(list,fib,list->path)) {
  908.         while(fmexnext(list,lock,fib)>0) {
  909.             if(dmatch(fib,ds)) {
  910.                 if (fib->fib_DirEntryType>0) {
  911.                     ret=sizedir(list,fib->fib_FileName,ds,dsize);
  912.                     if(ret<=0) goto dderr;
  913.                 } else {
  914.                     ds->filecnt++;
  915.                     ds->bytecnt+=fib->fib_Size;
  916.                     *dsize+=fib->fib_Size;
  917.                 }
  918.             }
  919.             sformatmsg(list->fmmessage1,MSG_DISKSIZING,ds->filecnt,ds->dircnt,ds->bytecnt);
  920.             sformat(list->fmmessage2,"'%s'",list->path);
  921.         }
  922.         UnLock(lock); lock=0;
  923.     }
  924. }
  925. ret=1;
  926. dderr:
  927. *(PathPart(list->path))=0;
  928. if (lock) UnLock(lock);
  929. freemem(fib);
  930. if(!ret) {
  931.     ret=askcontinue(list);
  932. } else {
  933.     ds->dircnt++;
  934. }
  935. return(ret);
  936. }
  937.  
  938. WORD dmatch(struct FileInfoBlock *fib,struct DelStr *ds)
  939. {
  940. struct FMNode *node;
  941. WORD ret=0;
  942.  
  943. node=allocnode();
  944. if(node) {
  945.     strcpy(NDFILE(node),fib->fib_FileName);
  946.     node->numprot=fib->fib_Protection;
  947.     node->numlen=fib->fib_Size;
  948.     node->numdate=dstolong(&fib->fib_Date);
  949.     node->flags=fib->fib_DirEntryType>0?NDIRECTORY:NFILE;
  950.     ret=checkmatch(ds->token1,ds->token2,ds->token3,node,&ds->match,0);
  951. }
  952. freevecpooled(node);
  953. return(ret);
  954. }
  955.  
  956. struct DelStr *createtoken(struct FMList *list)
  957. {
  958. struct DelStr *ds;
  959. UBYTE patname[PATTERN];
  960. UBYTE patflags[32];
  961. struct Match *match;
  962. UBYTE *ptr1,*ptr2;
  963.  
  964. ds=allocmem(sizeof(struct DelStr));
  965. match=getconfignumber(PARSECONFIG)->moreconfig;
  966. if(fmmain.kick<39&&match->mcase==1) {
  967.     ptr1=match->patname;
  968.     ptr2=patname;
  969.     while(*ptr1) *ptr2++=ToUpper(*ptr1++);
  970.     *ptr2=0;
  971. } else {
  972.     strcpy(patname,match->patname);
  973. }
  974. strcpy(patflags,match->patflags);
  975. CopyMem(match,&ds->match,sizeof(struct Match));
  976. ParsePatternNoCase(patname,ds->token1,1000);
  977. ParsePattern(patname,ds->token2,1000);
  978. ParsePatternNoCase(patflags,ds->token3,500);
  979. return(ds);
  980. }
  981.  
  982. WORD askcontinue(struct FMList *list)
  983. {
  984. WORD ret;
  985.  
  986. ret=requestmsg(getstring(MSG_MAIN_AREYOUSURE),MSG_YES,MSG_NO,MSG_MAIN_CONTINUE);
  987. if(ret) ret=-1;
  988. return(ret);
  989. }
  990.  
  991. void *copyconfigdefault(struct CMenuConfig *cmc)
  992. {
  993. struct CopyConfig *config;
  994. WORD ret;
  995.  
  996. ret=allocconfig(cmc,sizeof(struct CopyConfig));
  997. if(ret<0) return(cmc->moreconfig);
  998. if(!ret) return(0);
  999. config=(struct CopyConfig*)cmc->moreconfig;
  1000. config->bufsize=60000;
  1001. config->overwrite=1;
  1002. config->comment=1;
  1003. config->flags=1;
  1004. config->freespace=1;
  1005. return(cmc->moreconfig);
  1006. }
  1007.  
  1008. WORD copyconfig(struct GUIBase *gb,struct CMenuConfig *cmc)
  1009. {
  1010. WORD c;
  1011. WORD ov,co,fl,da,fr,upd;
  1012. LONG buf;
  1013. struct CopyConfig *config;
  1014.  
  1015. config=(struct CopyConfig*)copyconfigdefault(cmc);
  1016. if(!config) return(0);
  1017. upd=config->update;
  1018. setguigroup(gb,1,0);
  1019. reqinfomsg(gb,MSG_COPYMOVE_CONFIG_REFRESH,200,guiUC|guiLEFT);
  1020. reqinfomsg(gb,MSG_COPYMOVE_CONFIG_OVERWRITE,201,guiUC|guiLEFT);
  1021. reqinfomsg(gb,MSG_COPYMOVE_CONFIG_COMMENT,202,guiUC|guiLEFT);
  1022. reqinfomsg(gb,MSG_COPYMOVE_CONFIG_PROTECTION,203,guiUC|guiLEFT);
  1023. reqinfomsg(gb,MSG_COPYMOVE_CONFIG_DATE,204,guiUC|guiLEFT);
  1024. reqinfomsg(gb,MSG_COPYMOVE_CONFIG_CHECKFREESPACE,205,guiUC|guiLEFT);
  1025. reqinfomsg(gb,MSG_COPYMOVE_CONFIG_COPYBUFFER,206,guiUC|guiLEFT);
  1026. setguigroup(gb,2,0);
  1027. reqcyclemsg(gb,200,&upd,MSG_COPYMOVE_CONFIG_REFRESH1,MSG_COPYMOVE_CONFIG_REFRESH2,MSG_COPYMOVE_CONFIG_REFRESH3,0);
  1028. ov=config->overwrite;
  1029. reqcyclemsg(gb,201,&ov,MSG_COPYMOVE_CONFIG_OVERWRITE1,MSG_COPYMOVE_CONFIG_OVERWRITE2,0);
  1030. co=config->comment;
  1031. reqcycle2msg(gb,202,&co);
  1032. fl=config->flags;
  1033. reqcycle2msg(gb,203,&fl);
  1034. da=config->date;
  1035. reqcycle2msg(gb,204,&da);
  1036. fr=config->freespace;
  1037. reqcycle2msg(gb,205,&fr);
  1038. buf=config->bufsize;
  1039. reqinteger(gb,206,&buf,4000,99999999);
  1040. commandanswer(gb);
  1041. c=quickreq(gb);
  1042. config->overwrite=ov;
  1043. config->date=da;
  1044. config->comment=co;
  1045. config->flags=fl;
  1046. config->freespace=fr;
  1047. config->bufsize=buf;
  1048. config->update=upd;
  1049. return(c);
  1050. }
  1051.  
  1052. void *deleteconfigdefault(struct CMenuConfig *cmc)
  1053. {
  1054. struct DeleteConfig *config;
  1055. WORD ret;
  1056.  
  1057. ret=allocconfig(cmc,sizeof(struct DeleteConfig));
  1058. if(ret<0) return(cmc->moreconfig);
  1059. if(!ret) return(0);
  1060. config=(struct DeleteConfig*)cmc->moreconfig;
  1061. config->askdelete=1;
  1062. config->askdir=1;
  1063. return(cmc->moreconfig);
  1064. }
  1065.  
  1066. WORD deleteconfig(struct GUIBase *gb,struct CMenuConfig *cmc)
  1067. {
  1068. WORD c;
  1069. WORD adel,adir,prot,upd;
  1070. struct DeleteConfig *dc;
  1071.  
  1072. dc=getconfig(cmc);
  1073. upd=dc->update;
  1074. setguigroup(gb,1,0);
  1075. reqinfomsg(gb,MSG_COPYMOVE_CONFIG_REFRESH,200,guiUC|guiLEFT);
  1076. reqinfomsg(gb,MSG_DELETE_CONFIG_ASKDELETE,201,guiUC|guiLEFT);
  1077. reqinfomsg(gb,MSG_DELETE_CONFIG_ASKDIR,202,guiUC|guiLEFT);
  1078. reqinfomsg(gb,MSG_DELETE_CONFIG_DELPROT,203,guiUC|guiLEFT);
  1079. setguigroup(gb,2,0);
  1080. reqcyclemsg(gb,200,&upd,MSG_COPYMOVE_CONFIG_REFRESH1,MSG_COPYMOVE_CONFIG_REFRESH2,MSG_COPYMOVE_CONFIG_REFRESH3,0);
  1081. adel=dc->askdelete;
  1082. reqcycle2msg(gb,201,&adel);
  1083. adir=dc->askdir;
  1084. reqcycle2msg(gb,202,&adir);
  1085. prot=dc->protected;
  1086. reqcycle2msg(gb,203,&prot);
  1087. commandanswer(gb);
  1088. c=quickreq(gb);
  1089. dc->askdelete=adel;
  1090. dc->askdir=adir;
  1091. dc->protected=prot;
  1092. dc->update=upd;
  1093. return(c);
  1094. }
  1095.