home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 6
/
AACD06.ISO
/
AACD
/
Programming
/
DOpus4-GPL
/
Program
/
main18.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-01-27
|
14KB
|
566 lines
/*
Directory Opus 4
Original GPL release version 4.12
Copyright 1993-2000 Jonathan Potter
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
All users of Directory Opus 4 (including versions distributed
under the GPL) are entitled to upgrade to the latest version of
Directory Opus version 5 at a reduced price. Please see
http://www.gpsoft.com.au for more information.
The release of Directory Opus 4 under the GPL in NO WAY affects
the existing commercial status of Directory Opus 5.
*/
#include "DOpus.h"
struct recurse {
struct recurse *last;
char *dir,*dest;
int data;
APTR data2;
APTR data3;
BPTR lock;
struct FileInfoBlock *info;
};
struct makedirlist {
struct makedirlist *last,*next;
char *path;
};
struct recurse *current_recurse;
recursedir(fdir,fdest,dowhat,fdata)
char *fdir,*fdest;
int dowhat,fdata;
{
BPTR mylock;
struct FileInfoBlock __aligned myfinfo;
struct FileInfoBlock __aligned enfinfo;
char *name,*dir,*dest,*dname,*ddir,*adir,*adest,*ndir,*ndest;
int suc,cont,ret,a,err,w1=1-data_active_window,adata,depth,b,rtry,data,*pstuff,blocks;
struct recpath *crec=NULL,*trec;
struct RecursiveDirectory
*cur_recurse,*addparent_recurse,*new_rec,*pos_rec,*cur_parent,
*cur_lastparent=NULL;
APTR data2=NULL,adata2=NULL,data3=NULL,adata3=NULL;
struct DOpusRemember *recurserem=NULL;
struct makedirlist *first_makedir=NULL;
if (dowhat&R_STARDIR) {
rec_firstpath=NULL;
rec_pathkey=NULL;
}
if (dowhat&R_GETNAMES) {
first_recurse=NULL;
recurse_dir_key=NULL;
cur_recurse=NULL;
addparent_recurse=NULL;
}
data=fdata;
current_recurse=NULL; ret=depth=0; recurse_max_depth=0;
dos_global_bytecount=0;
dos_global_copiedbytes=0;
dos_global_deletedbytes=0;
dos_global_blocksneeded=0;
if (!(mylock=Lock(fdir,ACCESS_READ))) {
doerror(IoErr());
return(-1);
}
Examine(mylock,&myfinfo);
if (!(name=LAllocRemember(&recurserem,2560,MEMF_CLEAR))) {
doerror(IoErr());
ret=-1;
goto goaway;
}
dir=name+512; dest=name+1024; dname=name+1536; ddir=name+2048;
if (fdir) strcpy(dir,fdir);
if (fdest) strcpy(dest,fdest);
if (dowhat&R_COPY) {
strcpy(ddir,dest);
if (!(a=copymakedir(&recurserem,&first_makedir,dest,&myfinfo)) || a==-1) {
UnLock(mylock);
if (a==0) ret=-3;
else ret=-10;
goto goaway;
}
}
cont=ExNext(mylock,&myfinfo);
FOREVER {
if (status_haveaborted) {
myabort();
ret=-10;
break;
}
if (!cont) {
if (current_recurse) {
if (mylock) UnLock(mylock);
strcpy(dname,dir);
mylock=current_recurse->lock;
CopyMem((char *)current_recurse->info,(char *)&myfinfo,sizeof(struct FileInfoBlock));
strcpy(dir,current_recurse->dir);
strcpy(dest,current_recurse->dest);
data=current_recurse->data;
data2=current_recurse->data2;
data3=current_recurse->data3;
current_recurse=current_recurse->last;
strcpy(name,dir);
TackOn(name,myfinfo.fib_FileName,512);
if (dowhat&R_GETNAMES) {
cur_recurse=(struct RecursiveDirectory *)data2;
cur_lastparent=(struct RecursiveDirectory *)data3;
addparent_recurse=NULL;
}
if (dowhat&R_COPY) {
strcpy(ddir,dest);
if (config->copyflags©_DATE) {
TackOn(ddir,myfinfo.fib_FileName,512);
setdate(ddir,&myfinfo.fib_Date);
strcpy(ddir,dest);
}
}
a=0;
if (dowhat&R_COMMENT) {
FOREVER {
if (!(SetComment(name,dest))) {
err=IoErr();
doerror(err);
a=checkerror(globstring[STR_COMMENTING],myfinfo.fib_FileName,err);
if (a==1) continue;
}
break;
}
if (a==3) break;
}
if (dowhat&R_PROTECT) {
pstuff=(int *)data;
b=getnewprot(myfinfo.fib_Protection,pstuff[0],pstuff[1]);
FOREVER {
if (!(SetProtection(name,b))) {
err=IoErr();
doerror(err);
a=checkerror(globstring[STR_PROTECTING],myfinfo.fib_FileName,err);
if (a==1) continue;
}
break;
}
if (a==3) break;
}
if (dowhat&R_DATESTAMP) {
FOREVER {
if ((err=setdate(name,(struct DateStamp *)data))!=1) {
doerror(err);
a=checkerror(globstring[STR_DATESTAMPING],myfinfo.fib_FileName,err);
if (a==1) continue;
}
break;
}
if (a==3) break;
}
cont=ExNext(mylock,&myfinfo);
if (dowhat&R_DELETE && depth>0) {
a=strlen(dname);
if (a>0 && dname[a-1]=='/') dname[a-1]=0;
if ((a=delfile(dname,BaseName(dname),globstring[STR_DELETING],
glob_unprotect_all,1))==-1) {
myabort();
ret=-10;
break;
}
if (a==2) glob_unprotect_all=1;
}
--depth;
continue;
}
else break;
}
CopyMem((char *)&myfinfo,(char *)&enfinfo,sizeof(struct FileInfoBlock));
strcpy(name,dir);
TackOn(name,enfinfo.fib_FileName,512);
if (enfinfo.fib_DirEntryType>0) {
++dos_global_blocksneeded;
if (enfinfo.fib_DirEntryType!=4) {
adir=NULL;
dofilename(name);
if (dowhat&R_GETNAMES) {
if (new_rec=LAllocRemember(&recurse_dir_key,sizeof(struct RecursiveDirectory),MEMF_CLEAR)) {
strcpy(new_rec->name,enfinfo.fib_FileName);
CopyMem((char *)&enfinfo.fib_Date,(char *)&new_rec->date,sizeof(struct DateStamp));
if (addparent_recurse) {
addparent_recurse->child=new_rec;
cur_lastparent=addparent_recurse;
cur_recurse=new_rec;
}
else if (!first_recurse) {
first_recurse=new_rec;
cur_recurse=new_rec;
}
else if (cur_recurse) {
if (LStrCmpI(new_rec->name,cur_recurse->name)<0) {
if (first_recurse==cur_recurse) first_recurse=new_rec;
if (cur_lastparent && cur_lastparent->child==cur_recurse)
cur_lastparent->child=new_rec;
new_rec->next=cur_recurse;
cur_recurse=new_rec;
}
else {
pos_rec=cur_recurse;
FOREVER {
if (!pos_rec->next ||
(LStrCmpI(new_rec->name,pos_rec->next->name)<0)) {
new_rec->next=pos_rec->next;
pos_rec->next=new_rec;
break;
}
pos_rec=pos_rec->next;
}
}
}
else cur_recurse=new_rec;
cur_parent=new_rec;
}
adir=dir; adest=dest; ndir=name; ndest=dest;
adata2=(APTR)cur_recurse;
adata3=(APTR)cur_lastparent;
addparent_recurse=cur_parent;
}
strcpy(dname,dest);
if (dowhat&R_COPY) {
dotaskmsg(hotkeymsg_port,PROGRESS_UPDATE,-2,0,enfinfo.fib_FileName,1);
TackOn(dname,enfinfo.fib_FileName,512);
adir=dir; adest=dest; adata=data; ndir=name; ndest=dname;
strcpy(ddir,dname);
if ((a=copymakedir(&recurserem,&first_makedir,ddir,&enfinfo))==-1) {
ret=-10;
break;
}
else if (a==0) adir=NULL;
}
if (dowhat&R_DELETE) {
rtry=1;
delloop:
if (!DeleteFile(name)) {
if (config->deleteflags&8 && rtry==1 && IoErr()==222) {
rtry=0;
SetProtection(name,0);
goto delloop;
}
adir=dir; adest=dest; adata=data; ndir=name; ndest=dname;
}
else {
if (config->dynamicflags&1) seename(data_active_window);
adir=NULL;
}
}
if (dowhat&R_HUNT || dowhat&R_SEARCH || dowhat&R_COMMENT ||
dowhat&R_PROTECT || dowhat&R_DATESTAMP || dowhat&R_GETBYTES ||
dowhat&R_STARDIR) {
adir=dir; adest=dest; adata=data; ndir=name; ndest=dest;
adata2=data2; adata3=data3;
}
if (adir) {
if (!(addrecurse(&recurserem,adir,adest,adata,adata2,adata3,mylock,&enfinfo))) {
cont=0;
continue;
}
strcpy(dir,ndir);
strcpy(dest,ndest);
if (!(mylock=Lock(dir,ACCESS_READ))) {
cont=0;
continue;
}
Examine(mylock,&myfinfo);
cont=ExNext(mylock,&myfinfo);
++depth;
if (depth>recurse_max_depth) recurse_max_depth=depth;
continue;
}
}
}
cont=ExNext(mylock,&myfinfo);
if (enfinfo.fib_DirEntryType<0) {
a=0;
dos_global_bytecount+=enfinfo.fib_Size;
if (dowhat&R_GETBYTES && data) {
blocks=(enfinfo.fib_Size+(data-1))/data;
dos_global_blocksneeded+=blocks+(blocks/72)+1;
}
if (dowhat&R_GETNAMES) goto skipgetnam;
dofilename(name);
if (dowhat&R_STARDIR) {
if ((trec=LAllocRemember(&rec_pathkey,sizeof(struct recpath),MEMF_CLEAR)) &&
(trec->path=LAllocRemember(&rec_pathkey,(strlen(name)+1)-data,MEMF_CLEAR))) {
trec->next=NULL;
strcpy(trec->path,&name[data]);
if (crec) crec->next=trec;
crec=trec;
if (!rec_firstpath) rec_firstpath=trec;
}
}
if (!str_filter_parsed[0] ||
LMatchPatternI(str_filter_parsed,enfinfo.fib_FileName)) {
if (dowhat&R_COPY) {
strcpy(dname,ddir);
TackOn(dname,enfinfo.fib_FileName,512);
dotaskmsg(hotkeymsg_port,PROGRESS_UPDATE,-2,0,enfinfo.fib_FileName,1);
a=0;
FOREVER {
if (!(a=copyfile(name,dname,&err,-1,NULL,0))) {
doerror(err);
a=checkerror(globstring[STR_COPYING],enfinfo.fib_FileName,err);
if (a==1) continue;
if (a!=3) seename(data_active_window);
}
else if (a==-1) {
myabort();
a=3;
break;
}
else {
if (dowhat==R_COPY) {
if (config->copyflags©_ARC && !(enfinfo.fib_Protection&FIBF_ARCHIVE))
SetProtection(name,enfinfo.fib_Protection|FIBF_ARCHIVE);
}
dos_global_copiedbytes+=enfinfo.fib_Size;
}
if (config->dynamicflags&1) seename(data_active_window);
break;
}
if (a==3) {
ret=-10;
break;
}
if (config->dynamicflags&1) {
seename(data_active_window); seename(w1);
}
}
if (dowhat&R_DELETE) {
if ((a=delfile(name,enfinfo.fib_FileName,globstring[STR_DELETING],
glob_unprotect_all,1))==-1) {
myabort();
ret=-10;
break;
}
if (a==2) glob_unprotect_all=1;
if (config->dynamicflags&1) seename(data_active_window);
dos_global_deletedbytes+=enfinfo.fib_Size;
}
if (dowhat&R_COMMENT) {
FOREVER {
if (!(SetComment(name,dest))) {
err=IoErr();
doerror(err);
a=checkerror(globstring[STR_COMMENTING],enfinfo.fib_FileName,err);
if (a==1) continue;
}
break;
}
if (a==3) {
ret=-10;
break;
}
}
if (dowhat&R_PROTECT) {
pstuff=(int *)data;
b=getnewprot(enfinfo.fib_Protection,pstuff[0],pstuff[1]);
FOREVER {
if (!(SetProtection(name,b))) {
err=IoErr();
doerror(err);
a=checkerror(globstring[STR_PROTECTING],enfinfo.fib_FileName,err);
if (a==1) continue;
}
break;
}
if (a==3) {
ret=-10;
break;
}
}
if (dowhat&R_DATESTAMP) {
FOREVER {
if ((err=setdate(name,(struct DateStamp *)data))!=1) {
err=IoErr();
doerror(err);
a=checkerror(globstring[STR_DATESTAMPING],enfinfo.fib_FileName,err);
if (a==1) continue;
}
break;
}
if (a==3) {
ret=-10;
break;
}
}
if (dowhat&R_HUNT) {
suc=huntfile(enfinfo.fib_FileName,name,&a);
ret+=a;
if (suc) {
if (suc==-1) {
myabort();
ret=-10;
}
else ret=suc;
break;
}
}
if (dowhat&R_SEARCH) {
suc=filesearch(name,&a,0);
ret+=a;
busy();
if (suc==2) {
if (!simplerequest(globstring[STR_CONTINUE_WITH_SEARCH],
globstring[STR_CONTINUE],str_cancelstring,NULL)) {
okay();
ret=-2;
break;
}
}
skipgetnam:
if (suc==-1) {
myabort();
ret=-10;
break;
}
}
}
}
}
if (mylock) UnLock(mylock);
while (current_recurse) {
UnLock(current_recurse->lock);
current_recurse=current_recurse->last;
}
if (first_makedir &&
dowhat==R_COPY &&
str_filter_parsed[0]) {
struct makedirlist *last;
last=first_makedir;
while (last->next) last=last->next;
while (last) {
DeleteFile(last->path);
last=last->last;
}
}
goaway:
if (recurserem) LFreeRemember(&recurserem);
return(ret);
}
addrecurse(key,dir,dest,data,data2,data3,lock,info)
struct DOpusRemember **key;
char *dir,*dest;
int data;
APTR data2,data3;
BPTR lock;
struct FileInfoBlock *info;
{
struct recurse *rec;
if (!(rec=LAllocRemember(key,sizeof(struct recurse),MEMF_CLEAR)))
return(0);
if (current_recurse) rec->last=current_recurse;
else rec->last=NULL;
if (!(rec->dir=LAllocRemember(key,strlen(dir)+1,MEMF_CLEAR)) ||
!(rec->dest=LAllocRemember(key,strlen(dest)+1,MEMF_CLEAR)))
return(0);
strcpy(rec->dir,dir); strcpy(rec->dest,dest);
rec->data=data;
rec->data2=data2;
rec->data3=data3;
rec->lock=lock;
if (!(rec->info=LAllocRemember(key,sizeof(struct FileInfoBlock),0)))
return(0);
CopyMem((char *)info,(char *)rec->info,sizeof(struct FileInfoBlock));
current_recurse=rec;
return(1);
}
copymakedir(key,first,dirname,finfo)
struct DOpusRemember **key;
struct makedirlist **first;
char *dirname;
struct FileInfoBlock *finfo;
{
int exist,a,err;
BPTR mylock;
exist=CheckExist(dirname,NULL);
if (exist<=0) {
loop:
if (exist<0 || !(mylock=CreateDir(dirname))) {
if (exist<0) err=203;
else err=IoErr();
doerror(err);
a=checkerror(globstring[STR_CREATING],finfo->fib_FileName,err);
if (a==1) goto loop;
if (a==2) return(0);
return(-1);
}
if (mylock) {
struct makedirlist *list,*pos;
UnLock(mylock);
if (config->copyflags©_DATE) setdate(dirname,&finfo->fib_Date);
if (config->copyflags©_PROT) SetProtection(dirname,finfo->fib_Protection);
if (config->copyflags©_NOTE) SetComment(dirname,finfo->fib_Comment);
if ((list=LAllocRemember(key,sizeof(struct makedirlist),MEMF_CLEAR)) &&
(list->path=LAllocRemember(key,strlen(dirname)+1,0))) {
strcpy(list->path,dirname);
if (!(pos=*first)) *first=list;
else {
while (pos->next) pos=pos->next;
pos->next=list;
list->last=pos;
}
}
}
}
return(1);
}