/* autosync by MarK - it's a tool that synchronizes two (or more?) directories on a harddrive - creates index file in the base drawer - saves changes */ CONST VER=1, REV=0 // v1.0 23.2.2009 // - create index files // - compare index files // - update indexed files to be uptodate // - verbose information // v2.0 // - mui // - commodity // - auto update (when a media is inserted) ENUM ARGS_SRC, ARGS_DST, ARGS_VERBOSE, ARGS_TEST CONST MAXDIRLEN=512 DEF src=NIL:PTR TO CHAR, dst=NIL:PTR TO CHAR, verbose=FALSE:L, test=FALSE:L, src_dir[MAXDIRLEN]:CHAR, dst_dir[MAXDIRLEN]:CHAR PROC main() DEF ra,args=[NIL,NIL,NIL,NIL]:PTR IF ra:=ReadArgs('SRC/A,DST,VERBOSE/S,TEST/S',args,NIL) IF args[ARGS_SRC] THEN src:=DupStr(args[ARGS_SRC]) IF args[ARGS_DST] THEN dst:=DupStr(args[ARGS_DST]) IF args[ARGS_VERBOSE] THEN verbose:=TRUE IF args[ARGS_TEST] THEN test:=TRUE IF verbose PrintF('autosync v\d.\d by MarK (\x5d)\n',VER,REV) ENDIF DEF src_index:PTR TO as_fib, dst_index:PTR TO as_fib stats_dirs:=1 stats_files:=0 IF src_index:=index(src,src_dir) // print_index(src_index) src_index:=sort_index(src_index) IF verbose PrintF( ' src: \s\n'+ ' dirs: \d\n'+ 'files: \d\n',src,stats_dirs,stats_files) ENDIF IFN dst PrintF('no destination entered, saving source index only\n') ELSE IF dst_index:=index(dst,dst_dir) dst_index:=sort_index(dst_index) compare_directories(src_index,dst_index,src_dir,dst_dir) free(dst_index) ENDIF ENDIF free(src_index) ENDIF IF dst THEN RemStr(dst) IF src THEN RemStr(src) FreeArgs(ra) ELSE PrintFault(IOErr(),'autosync') ENDPROC MODULE 'dos/dos', 'exec/memory' OBJECT as_fib OF FileInfoBlock next:PTR TO as_fib, sub:PTR TO as_fib DEF stats_dirs, stats_files PROC index(dir:PTR TO CHAR,storedirname=NIL:PTR TO CHAR)(PTR TO as_fib) DEF first=NIL:PTR TO as_fib,last=NIL:PTR TO as_fib,new:PTR TO as_fib DEF info:FileInfoBlock,lock,lockname[256]:CHAR IF lock:=Lock(dir,-2) IF storedirname THEN NameFromLock(lock,storedirname,MAXDIRLEN-1) IF Examine(lock,info) IF info.DirEntryType>0 WHILE ExNext(lock,info) EXITIFN new:=AllocVec(SIZEOF_as_fib,MEMF_PUBLIC|MEMF_CLEAR) IF last THEN last.next:=new IFN first THEN first:=new CopyMem(info,new,SIZEOF_FileInfoBlock) IF info.DirEntryType>0 NameFromLock(lock,lockname,255) AddPart(lockname,info.FileName,255) new.sub:=index(lockname) stats_dirs++ ELSE stats_files++ ENDIF last:=new ENDWHILE ELSE PrintFault(IOErr(),'autosync') ELSE PrintFault(IOErr(),'autosync') UnLock(lock) ELSE PrintFault(IOErr(),'autosync') ENDPROC first PROC free(fib:PTR TO as_fib) DEF next:PTR TO as_fib WHILE fib next:=fib.next IF fib.sub free(fib.sub) ENDIF FreeVec(fib) fib:=next ENDWHILE ENDPROC PROC sort_index(first:PTR TO as_fib)(PTR TO as_fib) DEF list:PTR TO PTR TO as_fib,fib:PTR TO as_fib,i,count // count all items fib:=first i:=0 WHILE fib i++ IF fib.sub THEN fib.sub:=sort_index(fib.sub) // sort all subdirectories fib:=.next ENDWHILE count:=i // PrintF('sorting \d items...\n',count) IF list:=AllocVec((count+1)*SIZEOF_PTR,MEMF_PUBLIC|MEMF_CLEAR) i:=0 fib:=first WHILE fib list[i]:=fib i++ fib:=.next ENDWHILE quicksort(0,count-1,list) i:=0 WHILE i>1] REPEAT IF CtrlC() THEN RETURN // WHILE a[i++]j IF l ',IF aa THEN aa.FileName ELSE '',IF bb THEN bb.FileName ELSE '') SELECT compare(aa,bb) CASE 1 PrintF('''\s'' must be stored in the ''\s'' directory\n',bb.FileName,src_dir) StrCopy(str,dst_dir) AddPart(str,bb.FileName,MAXDIRLEN-1) copy_item(str,src_dir,bb) bb:=.next CASE -1 PrintF('''\s'' must be stored in the ''\s'' directory\n',aa.FileName,dst_dir) StrCopy(str,src_dir) AddPart(str,aa.FileName,MAXDIRLEN-1) copy_item(str,dst_dir,aa) aa:=.next DEFAULT PrintF('OKAY') IF aa.DirEntryType>0 AddPart(src_dir,aa.FileName,MAXDIRLEN-1) AddPart(dst_dir,bb.FileName,MAXDIRLEN-1) PrintF('\n\tcmp \s x \s\n',src_dir,dst_dir) compare_directories(aa.sub,bb.sub,src_dir,dst_dir) PutByte(PathPart(dst_dir),0) PutByte(PathPart(src_dir),0) ENDIF aa:=.next bb:=.next ENDSELECT PrintF('\n') EXITIF CtrlC() ENDWHILE ENDPROC PROC copy_item(src:PTR TO CHAR,dst:PTR TO CHAR,fib=NIL:PTR TO as_fib) DEF info:FileInfoBlock,lock IF lock:=Lock(src,-2) IF Examine(lock,info) IF info.DirEntryType>0 // copy a directory copy_dir(src,dst,fib.sub) ELSE // copy a file copy_file(src,dst,fib) ENDIF ELSE PrintFault(IOErr(),'autosync') UnLock(lock) ELSE PrintFault(IOErr(),'autosync') ENDPROC PROC copy_file(src:PTR TO CHAR,dst:PTR TO CHAR,fib=NIL:PTR TO as_fib) DEF name[MAXDIRLEN]:STRING PrintF('copying file \s to \s\n',src,dst) StrCopy(name,dst) AddPart(name,FilePart(src),MAXDIRLEN-1) DEF sfh,dfh,mem:PTR TO CHAR,len,done=0,current IF fib len:=fib.Size ELSE len:=FileLength(src) ENDIF IF mem:=AllocVec(65536,MEMF_PUBLIC) IF sfh:=Open(src,MODE_OLDFILE) IF dfh:=Open(name,MODE_NEWFILE) WHILE (current:=Read(sfh,mem,65536))>0 EXITIF Write(dfh,mem,current)<>current done+=current EXITIF done>=len EXITIF CtrlC() ENDWHILE Close(dfh) ENDIF Close(sfh) ENDIF FreeVec(mem) ENDIF ENDPROC PROC copy_dir(src:PTR TO CHAR,dst:PTR TO CHAR,fib=NIL:PTR TO as_fib) DEF name[MAXDIRLEN]:STRING,lock,file[MAXDIRLEN]:STRING StrCopy(name,dst) AddPart(name,FilePart(src),MAXDIRLEN-1) PrintF('creating directory \s\n',name) IF lock:=CreateDir(name) WHILE fib StrCopy(file,src) AddPart(file,fib.FileName,MAXDIRLEN-1) copy_item(file,name,fib) fib:=.next ENDWHILE UnLock(lock) ENDIF ENDPROC