home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Exec 3 / CD_Magazyn_EXEC_nr_3.iso / Internet / Strony_WWW / Opus4.x / DOpus414JRsrc.lha / DirectoryOpus4 / Program / main18.c < prev    next >
C/C++ Source or Header  |  2000-02-25  |  20KB  |  561 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "dopus.h"
  32.  
  33. struct recurse {
  34.     struct recurse *last;
  35.     char *dir,*dest;
  36.     int data;
  37.     APTR data2;
  38.     APTR data3;
  39.     BPTR lock;
  40.     struct FileInfoBlock *info;
  41. };
  42.  
  43. struct recurse *current_recurse;
  44.  
  45. recursedir(fdir,fdest,dowhat,fdata)
  46. char *fdir,*fdest;
  47. int dowhat,fdata;
  48. {
  49.     BPTR mylock;
  50.     struct FileInfoBlock __aligned myfinfo;
  51.     struct FileInfoBlock __aligned enfinfo;
  52.     char *name,*dir,*dest,*dname,*ddir,*adir,*adest,*ndir,*ndest;
  53.     int suc,cont,ret,a,err,w1=1-data_active_window,adata,depth,b,rtry,data,*pstuff,blocks;
  54.     struct recpath *crec=NULL,*trec;
  55.     struct RecursiveDirectory
  56.         *cur_recurse,*addparent_recurse,*new_rec,*pos_rec,*cur_parent,
  57.         *cur_lastparent=NULL;
  58.     APTR data2=NULL,adata2=NULL,data3=NULL,adata3=NULL;
  59.     struct DOpusRemember *recurserem=NULL;
  60.     struct makedirlist *first_makedir=NULL;
  61.  
  62.     if (dowhat&R_STARDIR) {
  63.         rec_firstpath=NULL;
  64.         rec_pathkey=NULL;
  65.     }
  66.  
  67.     if (dowhat&R_GETNAMES) {
  68.         first_recurse=NULL;
  69.         recurse_dir_key=NULL;
  70.         cur_recurse=NULL;
  71.         addparent_recurse=NULL;
  72.     }
  73.  
  74.     data=fdata;
  75.  
  76.     current_recurse=NULL; ret=depth=0; recurse_max_depth=0;
  77.     dos_global_bytecount=0;
  78.     dos_global_copiedbytes=0;
  79.     dos_global_deletedbytes=0;
  80.     dos_global_blocksneeded=0;
  81.  
  82.     if (!(mylock=Lock(fdir,ACCESS_READ))) {
  83.         doerror(IoErr());
  84.         return(-1);
  85.     }
  86.     Examine(mylock,&myfinfo);
  87.  
  88.     if (!(name=LAllocRemember(&recurserem,2560,MEMF_CLEAR))) {
  89.         doerror(IoErr());
  90.         ret=-1;
  91.         goto goaway;
  92.     }
  93.     dir=name+512; dest=name+1024; dname=name+1536; ddir=name+2048;
  94.     if (fdir) strcpy(dir,fdir);
  95.     if (fdest) strcpy(dest,fdest);
  96.  
  97.     if (dowhat&R_COPY) {
  98.         strcpy(ddir,dest);
  99.         if (!(a=copymakedir(&recurserem,&first_makedir,dest,&myfinfo)) || a==-1) {
  100.             UnLock(mylock);
  101.             if (a==0) ret=-3;
  102.             else ret=-10;
  103.             goto goaway;
  104.         }
  105.     }
  106.     cont=ExNext(mylock,&myfinfo);
  107.  
  108.     FOREVER {
  109.         if (status_haveaborted) {
  110.             myabort();
  111.             ret=-10;
  112.             break;
  113.         }
  114.         if (!cont) {
  115.             if (current_recurse) {
  116.                 if (mylock) UnLock(mylock);
  117.                 strcpy(dname,dir);
  118.                 mylock=current_recurse->lock;
  119.                 CopyMem((char *)current_recurse->info,(char *)&myfinfo,sizeof(struct FileInfoBlock));
  120.                 strcpy(dir,current_recurse->dir);
  121.                 strcpy(dest,current_recurse->dest);
  122.                 data=current_recurse->data;
  123.                 data2=current_recurse->data2;
  124.                 data3=current_recurse->data3;
  125.                 current_recurse=current_recurse->last;
  126.  
  127.                 strcpy(name,dir);
  128.                 TackOn(name,myfinfo.fib_FileName,512);
  129.  
  130.                 if (dowhat&R_GETNAMES) {
  131.                     cur_recurse=(struct RecursiveDirectory *)data2;
  132.                     cur_lastparent=(struct RecursiveDirectory *)data3;
  133.                     addparent_recurse=NULL;
  134.                 }
  135.  
  136.                 if (dowhat&R_COPY) {
  137.                     strcpy(ddir,dest);
  138.                     if (config->copyflags©_DATE) {
  139.                         TackOn(ddir,myfinfo.fib_FileName,512);
  140.                         setdate(ddir,&myfinfo.fib_Date);
  141.                         strcpy(ddir,dest);
  142.                     }
  143.                 }
  144.  
  145.                 a=0;
  146.                 if (dowhat&R_COMMENT) {
  147.                     FOREVER {
  148.                         if (!(SetComment(name,dest))) {
  149.                             err=IoErr();
  150.                             doerror(err);
  151.                             a=checkerror(globstring[STR_COMMENTING],myfinfo.fib_FileName,err);
  152.                             if (a==1) continue;
  153.                         }
  154.                         break;
  155.                     }
  156.                     if (a==3) break;
  157.                 }
  158.  
  159.                 if (dowhat&R_PROTECT) {
  160.                     pstuff=(int *)data;
  161.                     b=getnewprot(myfinfo.fib_Protection,pstuff[0],pstuff[1]);
  162.                     FOREVER {
  163.                         if (!(SetProtection(name,b))) {
  164.                             err=IoErr();
  165.                             doerror(err);
  166.                             a=checkerror(globstring[STR_PROTECTING],myfinfo.fib_FileName,err);
  167.                             if (a==1) continue;
  168.                         }
  169.                         break;
  170.                     }
  171.                     if (a==3) break;
  172.                 }
  173.  
  174.                 if (dowhat&R_DATESTAMP) {
  175.                     FOREVER {
  176.                         if ((err=setdate(name,(struct DateStamp *)data))!=1) {
  177.                             doerror(err);
  178.                             a=checkerror(globstring[STR_DATESTAMPING],myfinfo.fib_FileName,err);
  179.                             if (a==1) continue;
  180.                         }
  181.                         break;
  182.                     }
  183.                     if (a==3) break;
  184.                 }
  185.  
  186.                 cont=ExNext(mylock,&myfinfo);
  187.  
  188.                 if (dowhat&R_DELETE && depth>0) {
  189.                     a=strlen(dname);
  190.                     if (a>0 && dname[a-1]=='/') dname[a-1]=0;
  191.                     if ((a=delfile(dname,BaseName(dname),globstring[STR_DELETING],
  192.                         glob_unprotect_all,1))==-1) {
  193.                         myabort();
  194.                         ret=-10;
  195.                         break;
  196.                     }
  197.                     if (a==2) glob_unprotect_all=1;
  198.                 }
  199.                 --depth;
  200.                 continue;
  201.             }
  202.             else break;
  203.         }
  204.         CopyMem((char *)&myfinfo,(char *)&enfinfo,sizeof(struct FileInfoBlock));
  205.  
  206.         strcpy(name,dir);
  207.         TackOn(name,enfinfo.fib_FileName,512);
  208.  
  209.         if (enfinfo.fib_DirEntryType>0) {
  210.             ++dos_global_blocksneeded;
  211.             if (enfinfo.fib_DirEntryType!=4) {
  212.                 adir=NULL;
  213.                 dofilename(name);
  214.                 if (dowhat&R_GETNAMES) {
  215.                     if (new_rec=LAllocRemember(&recurse_dir_key,sizeof(struct RecursiveDirectory),MEMF_CLEAR)) {
  216.                         strcpy(new_rec->name,enfinfo.fib_FileName);
  217.                         CopyMem((char *)&enfinfo.fib_Date,(char *)&new_rec->date,sizeof(struct DateStamp));
  218.                         if (addparent_recurse) {
  219.                             addparent_recurse->child=new_rec;
  220.                             cur_lastparent=addparent_recurse;
  221.                             cur_recurse=new_rec;
  222.                         }
  223.                         else if (!first_recurse) {
  224.                             first_recurse=new_rec;
  225.                             cur_recurse=new_rec;
  226.                         }
  227.                         else if (cur_recurse) {
  228.                             if (LStrCmpI(new_rec->name,cur_recurse->name)<0) {
  229.                                 if (first_recurse==cur_recurse) first_recurse=new_rec;
  230.                                 if (cur_lastparent && cur_lastparent->child==cur_recurse)
  231.                                     cur_lastparent->child=new_rec;
  232.                                 new_rec->next=cur_recurse;
  233.                                 cur_recurse=new_rec;
  234.                             }
  235.                             else {
  236.                                 pos_rec=cur_recurse;
  237.                                 FOREVER {
  238.                                     if (!pos_rec->next ||
  239.                                         (LStrCmpI(new_rec->name,pos_rec->next->name)<0)) {
  240.                                         new_rec->next=pos_rec->next;
  241.                                         pos_rec->next=new_rec;
  242.                                         break;
  243.                                     }
  244.                                     pos_rec=pos_rec->next;
  245.                                 }
  246.                             }
  247.                         }
  248.                         else cur_recurse=new_rec;
  249.                         cur_parent=new_rec;
  250.                     }
  251.                     adir=dir; adest=dest; ndir=name; ndest=dest;
  252.                     adata2=(APTR)cur_recurse;
  253.                     adata3=(APTR)cur_lastparent;
  254.                     addparent_recurse=cur_parent;
  255.                 }
  256.                 strcpy(dname,dest);
  257.                 if (dowhat&R_COPY) {
  258.  
  259.                     dotaskmsg(hotkeymsg_port,PROGRESS_UPDATE,-2,0,enfinfo.fib_FileName,1);
  260.  
  261.                     TackOn(dname,enfinfo.fib_FileName,512);
  262.                     adir=dir; adest=dest; adata=data; ndir=name; ndest=dname;
  263.                     strcpy(ddir,dname);
  264.                     if ((a=copymakedir(&recurserem,&first_makedir,ddir,&enfinfo))==-1) {
  265.                         ret=-10;
  266.                         break;
  267.                     }
  268.                     else if (a==0) adir=NULL;
  269.                 }
  270.                 if (dowhat&R_DELETE) {
  271.                     rtry=1;
  272. delloop:
  273.                     if (!DeleteFile(name)) {
  274.                         if (config->deleteflags&8 && rtry==1 && IoErr()==222) {
  275.                             rtry=0;
  276.                             SetProtection(name,0);
  277.                             goto delloop;
  278.                         }
  279.                         adir=dir; adest=dest; adata=data; ndir=name; ndest=dname;
  280.                     }
  281.                     else {
  282.                         if (config->dynamicflags&1) seename(data_active_window);
  283.                         adir=NULL;
  284.                     }
  285.                 }
  286.                 if (dowhat&R_HUNT || dowhat&R_SEARCH || dowhat&R_COMMENT ||
  287.                     dowhat&R_PROTECT || dowhat&R_DATESTAMP || dowhat&R_GETBYTES ||
  288.                     dowhat&R_STARDIR) {
  289.                     adir=dir; adest=dest; adata=data; ndir=name; ndest=dest;
  290.                     adata2=data2; adata3=data3;
  291.                 }
  292.                 if (adir) {
  293.                     if (!(addrecurse(&recurserem,adir,adest,adata,adata2,adata3,mylock,&enfinfo))) {
  294.                         cont=0;
  295.                         continue;
  296.                     }
  297.                     strcpy(dir,ndir);
  298.                     strcpy(dest,ndest);
  299.                     if (!(mylock=Lock(dir,ACCESS_READ))) {
  300.                         cont=0;
  301.                         continue;
  302.                     }
  303.                     Examine(mylock,&myfinfo);
  304.                     cont=ExNext(mylock,&myfinfo);
  305.                     ++depth;
  306.                     if (depth>recurse_max_depth) recurse_max_depth=depth;
  307.                     continue;
  308.                 }
  309.             }
  310.         }
  311.         cont=ExNext(mylock,&myfinfo);
  312.  
  313.         if (enfinfo.fib_DirEntryType<0) {
  314.             a=0;
  315.             dos_global_bytecount+=enfinfo.fib_Size;
  316.             if (dowhat&R_GETBYTES && data) {
  317.                 blocks=(enfinfo.fib_Size+(data-1))/data;
  318.                 dos_global_blocksneeded+=blocks+(blocks/72)+1;
  319.             }
  320.  
  321.             if (dowhat&R_GETNAMES) goto skipgetnam;
  322.             dofilename(name);
  323.             if (dowhat&R_STARDIR) {
  324.                 if ((trec=LAllocRemember(&rec_pathkey,sizeof(struct recpath),MEMF_CLEAR)) &&
  325.                     (trec->path=LAllocRemember(&rec_pathkey,(strlen(name)+1)-data,MEMF_CLEAR))) {
  326.                     trec->next=NULL;
  327.                     strcpy(trec->path,&name[data]);
  328.                     if (crec) crec->next=trec;
  329.                     crec=trec;
  330.                     if (!rec_firstpath) rec_firstpath=trec;
  331.                 }
  332.             }
  333.             if (!str_filter_parsed[0] ||
  334.                 LMatchPatternI(str_filter_parsed,enfinfo.fib_FileName)) {
  335.                 if (dowhat&R_COPY) {
  336.                     strcpy(dname,ddir);
  337.                     TackOn(dname,enfinfo.fib_FileName,512);
  338.  
  339.                     dotaskmsg(hotkeymsg_port,PROGRESS_UPDATE,-2,0,enfinfo.fib_FileName,1);
  340.  
  341.                     a=0;
  342.                     FOREVER {
  343.                         if (!(a=copyfile(name,dname,&err,-1,NULL,0))) {
  344.                             doerror(err);
  345.                             a=checkerror(globstring[STR_COPYING],enfinfo.fib_FileName,err);
  346.                             if (a==1) continue;
  347.                             if (a!=3) seename(data_active_window);
  348.                         }
  349.                         else if (a==-1) {
  350.                             myabort();
  351.                             a=3;
  352.                             break;
  353.                         }
  354.                         else {
  355.                             if (dowhat==R_COPY) {
  356.                                 if (config->copyflags©_ARC && !(enfinfo.fib_Protection&FIBF_ARCHIVE))
  357.                                     SetProtection(name,enfinfo.fib_Protection|FIBF_ARCHIVE);
  358.                             }
  359.                             dos_global_copiedbytes+=enfinfo.fib_Size;
  360.                         }
  361.                         if (config->dynamicflags&1) seename(data_active_window);
  362.                         break;
  363.                     }
  364.                     if (a==3) {
  365.                         ret=-10;
  366.                         break;
  367.                     }
  368.                     if (config->dynamicflags&1) {
  369.                         seename(data_active_window); seename(w1);
  370.                     }
  371.                 }
  372.                 if (dowhat&R_DELETE) {
  373.                     if ((a=delfile(name,enfinfo.fib_FileName,globstring[STR_DELETING],
  374.                         glob_unprotect_all,1))==-1) {
  375.                         myabort();
  376.                         ret=-10;
  377.                         break;
  378.                     }
  379.                     if (a==2) glob_unprotect_all=1;
  380.                     if (config->dynamicflags&1) seename(data_active_window);
  381.                     dos_global_deletedbytes+=enfinfo.fib_Size;
  382.                 }
  383.                 if (dowhat&R_COMMENT) {
  384.                     FOREVER {
  385.                         if (!(SetComment(name,dest))) {
  386.                             err=IoErr();
  387.                             doerror(err);
  388.                             a=checkerror(globstring[STR_COMMENTING],enfinfo.fib_FileName,err);
  389.                             if (a==1) continue;
  390.                         }
  391.                         break;
  392.                     }
  393.                     if (a==3) {
  394.                         ret=-10;
  395.                         break;
  396.                     }
  397.                 }
  398.                 if (dowhat&R_PROTECT) {
  399.                     pstuff=(int *)data;
  400.                     b=getnewprot(enfinfo.fib_Protection,pstuff[0],pstuff[1]);
  401.                     FOREVER {
  402.                         if (!(SetProtection(name,b))) {
  403.                             err=IoErr();
  404.                             doerror(err);
  405.                             a=checkerror(globstring[STR_PROTECTING],enfinfo.fib_FileName,err);
  406.                             if (a==1) continue;
  407.                         }
  408.                         break;
  409.                     }
  410.                     if (a==3) {
  411.                         ret=-10;
  412.                         break;
  413.                     }
  414.                 }
  415.                 if (dowhat&R_DATESTAMP) {
  416.                     FOREVER {
  417.                         if ((err=setdate(name,(struct DateStamp *)data))!=1) {
  418.                             err=IoErr();
  419.                             doerror(err);
  420.                             a=checkerror(globstring[STR_DATESTAMPING],enfinfo.fib_FileName,err);
  421.                             if (a==1) continue;
  422.                         }
  423.                         break;
  424.                     }
  425.                     if (a==3) {
  426.                         ret=-10;
  427.                         break;
  428.                     }
  429.                 }
  430.                 if (dowhat&R_HUNT) {
  431.                     suc=huntfile(enfinfo.fib_FileName,name,&a);
  432.                     ret+=a;
  433.                     if (suc) {
  434.                         if (suc==-1) {
  435.                             myabort();
  436.                             ret=-10;
  437.                         }
  438.                         else ret=suc;
  439.                         break;
  440.                     }
  441.                 }
  442.                 if (dowhat&R_SEARCH) {
  443.                     suc=filesearch(name,&a,0);
  444.                     ret+=a;
  445.                     busy();
  446.                     if (suc==2) {
  447.                         if (!simplerequest(globstring[STR_CONTINUE_WITH_SEARCH],
  448.                             globstring[STR_CONTINUE],str_cancelstring,NULL)) {
  449.                             okay();
  450.                             ret=-2;
  451.                             break;
  452.                         }
  453.                     }
  454. skipgetnam:
  455.                     if (suc==-1) {
  456.                         myabort();
  457.                         ret=-10;
  458.                         break;
  459.                     }
  460.                 }
  461.             }
  462.         }
  463.     }
  464.     if (mylock) UnLock(mylock);
  465.     while (current_recurse) {
  466.         UnLock(current_recurse->lock);
  467.         current_recurse=current_recurse->last;
  468.     }
  469.     if (first_makedir &&
  470.         dowhat==R_COPY &&
  471.         str_filter_parsed[0]) {
  472.  
  473.         struct makedirlist *last;
  474.  
  475.         last=first_makedir;
  476.         while (last->next) last=last->next;
  477.  
  478.         while (last) {
  479.             DeleteFile(last->path);
  480.             last=last->last;
  481.         }
  482.     }
  483. goaway:
  484.     if (recurserem) LFreeRemember(&recurserem);
  485.     return(ret);
  486. }
  487.  
  488. addrecurse(key,dir,dest,data,data2,data3,lock,info)
  489. struct DOpusRemember **key;
  490. char *dir,*dest;
  491. int data;
  492. APTR data2,data3;
  493. BPTR lock;
  494. struct FileInfoBlock *info;
  495. {
  496.     struct recurse *rec;
  497.  
  498.     if (!(rec=LAllocRemember(key,sizeof(struct recurse),MEMF_CLEAR)))
  499.         return(0);
  500.     if (current_recurse) rec->last=current_recurse;
  501.     else rec->last=NULL;
  502.     if (!(rec->dir=LAllocRemember(key,strlen(dir)+1,MEMF_CLEAR)) ||
  503.         !(rec->dest=LAllocRemember(key,strlen(dest)+1,MEMF_CLEAR)))
  504.         return(0);
  505.     strcpy(rec->dir,dir); strcpy(rec->dest,dest);
  506.     rec->data=data;
  507.     rec->data2=data2;
  508.     rec->data3=data3;
  509.     rec->lock=lock;
  510.     if (!(rec->info=LAllocRemember(key,sizeof(struct FileInfoBlock),0)))
  511.         return(0);
  512.     CopyMem((char *)info,(char *)rec->info,sizeof(struct FileInfoBlock));
  513.     current_recurse=rec;
  514.     return(1);
  515. }
  516.  
  517. copymakedir(key,first,dirname,finfo)
  518. struct DOpusRemember **key;
  519. struct makedirlist **first;
  520. char *dirname;
  521. struct FileInfoBlock *finfo;
  522. {
  523.     int exist,a,err;
  524.     BPTR mylock;
  525.  
  526.     exist=CheckExist(dirname,NULL);
  527.     if (exist<=0) {
  528. loop:
  529.         if (exist<0 || !(mylock=CreateDir(dirname))) {
  530.             if (exist<0) err=203;
  531.             else err=IoErr();
  532.             doerror(err);
  533.             a=checkerror(globstring[STR_CREATING],finfo->fib_FileName,err);
  534.             if (a==1) goto loop;
  535.             if (a==2) return(0);
  536.             return(-1);
  537.         }
  538.         if (mylock) {
  539.             struct makedirlist *list,*pos;
  540.  
  541.             UnLock(mylock);
  542.  
  543.             if (config->copyflags©_DATE) setdate(dirname,&finfo->fib_Date);
  544.             if (config->copyflags©_PROT) SetProtection(dirname,finfo->fib_Protection);
  545.             if (config->copyflags©_NOTE) SetComment(dirname,finfo->fib_Comment);
  546.  
  547.             if ((list=LAllocRemember(key,sizeof(struct makedirlist),MEMF_CLEAR)) &&
  548.                 (list->path=LAllocRemember(key,strlen(dirname)+1,0))) {
  549.                 strcpy(list->path,dirname);
  550.                 if (!(pos=*first)) *first=list;
  551.                 else {
  552.                     while (pos->next) pos=pos->next;
  553.                     pos->next=list;
  554.                     list->last=pos;
  555.                 }
  556.             }
  557.         }
  558.     }
  559.     return(1);
  560. }
  561.