void RecursiveCopy( FolderInfo folder, string path ) { try { string s = folder.Name + ":" + MatchPath.AbsoluteDirectoryPath( path ?? string.Empty ); status.update.current = s; if( debug ) { Log( ".u.recursive copy [{0}]", s ); } //..check if cancelled if( IsCancelRequested ) { throw new Exception( "Update cancelled." ); } if( ! folder.IsIncludedFolder( path ) ) { if( debug ) { Log( ".u.not included", path ); } return; } string fp = PathCombine( folder.Root, path ); if( debug ) { Log( ".u.folder path [{0}]", fp ); } try { #if __MonoCS__ { Mono.Unix.UnixSymbolicLinkInfo i = new Mono.Unix.UnixSymbolicLinkInfo( fp ); if( ! i.Exists || ! i.IsDirectory ) { return; } } #endif if( ! DirectoryExists( fp ) ) { throw new Exception( "Folder path does not exist." ); } string cp = PathCombine( current, folder.Name, path ); if( debug ) { Log( ".u.current path [{0}]", cp ); } try { if( debug ) { Log( ".u.create current directory" ); } DirectoryCreate( cp ); //..copy all included files at this level if( debug ) { Log( ".u.-----> files [{0}]", MatchPath.AbsoluteDirectoryPath( path ?? string.Empty ) ); } foreach( string n in Ctrl.ListFiles( fp ) ) { try { status.update.current = folder.Name + ":" + MatchPath.AbsoluteDirectoryPath( path ?? string.Empty ) + n; if( IsCancelRequested ) { throw new Exception( "Update cancelled." ); } string pn = PathCombine( path, n ); if( debug ) { Log( ".u.file [{0}]", pn ); } if( folder.IsIncludedFile( pn ) ) { if( debug ) { Log( ".u.is included" ); } string fpn = PathCombine( fp, n ); try { #if __MonoCS__ Mono.Unix.UnixSymbolicLinkInfo i = new Mono.Unix.UnixSymbolicLinkInfo( fpn ); if( i.Exists && i.IsRegularFile ) #endif { string cpn = PathCombine( cp, n ); try { if( debug ) { Log( ".u.copy folder file to current" ); } FileCopy( fpn, cpn ); LogStatus( StatusType.Created, folder.Name, path, n ); Interlocked.Increment( ref status.update.created ); } catch( Exception ex ) { ex.Data[ExCurrentFilename] = cpn; Log( "Update {0}", Except.ToString( ex, debug ) ); Interlocked.Increment( ref status.update.skipped ); LogStatus( StatusType.Skipped, folder.Name, path, n ); } } } catch( Exception ex ) { ex.Data[ExFolderFilename] = fpn; throw; } } } catch( Exception ex ) { ex.Data[ExFilename] = n; throw; } } //..recursively copy all subdirectories at this level if( debug ) { Log( ".u.-----> directories [{0}]", MatchPath.AbsoluteDirectoryPath( path ?? string.Empty ) ); } foreach( string n in Ctrl.ListDirectories( fp ) ) { string pn = PathCombine( path, n ); if( debug ) { Log( ".u.directory [{0}]", pn ); } RecursiveCopy( folder, pn ); } } catch( Exception ex ) { ex.Data[ExCurrentPath] = cp; throw; } } catch( Exception ex ) { ex.Data[ExFolderPath] = fp; throw; } } catch( Exception ex ) { ex.Data[ExPath] = path; Msg( "Update: {0}", Except.ToString( ex, debug ) ); } }
void ScanFolder( FolderInfo folder, string path ) { try { //..record current location string s = MatchPath.AbsoluteDirectoryPath( path ?? string.Empty ); status.scan.current = folder.Name + ":" + s; if( debug ) { Log( ".s.scan path [{0}]", s ); } Interlocked.Increment( ref status.scan.folders ); //..check if cancelled if( IsCancelRequested ) { throw new Exception( "Scan cancelled." ); } if( ! folder.IsIncludedFolder( path ) ) { if( debug ) { Log( " .s.not included" ); } return; } //..find out if folder path exists string fp = PathCombine( folder.Root, path ); if( debug ) { Log( ".s.folder path [{0}]", fp ); } try { #if __MonoCS__ { Mono.Unix.UnixSymbolicLinkInfo i = new Mono.Unix.UnixSymbolicLinkInfo( fp ); if( ! i.Exists || ! i.IsDirectory ) { return; } } #endif if( ! DirectoryExists( fp ) ) { throw new DirectoryNotFoundException( "Folder path does not exist." ); } //..find out if path exists in current string cp = PathCombine( current, folder.Name, path ); if( debug ) { Log( ".s.current path [{0}]", cp ); } try { if( ! DirectoryExists( cp ) ) { if( debug ) { Log( ".s.current path absent, copy everything" ); } //..when the folder does not exist in current, copy everything without comparing ScanQueue( ActionType.Copy, folder, path, null ); return; } List<string> a; //..scan files first if( debug ) { Log( ".s.-----> files [{0}]", MatchPath.AbsoluteDirectoryPath( path ?? string.Empty ) ); } a = new List<string>( Ctrl.ListFiles( cp ) ); foreach( string n in Ctrl.ListFiles( fp ) ) { try { if( IsCancelRequested ) { throw new Exception( "Scan cancelled." ); } Interlocked.Increment( ref status.scan.files ); string pn = PathCombine( path, n ); if( debug ) { Log( ".s.file [{0}]", pn ); } if( folder.IsIncludedFile( pn ) ) { if( debug ) { Log( ".s.is included" ); } string fpn = PathCombine( fp, n ); try { #if __MonoCS__ Mono.Unix.UnixSymbolicLinkInfo i = new Mono.Unix.UnixSymbolicLinkInfo( fpn ); if( i.Exists && i.IsRegularFile ) #endif { string cpn = PathCombine( cp, n ); try { FileInfo fi = new FileInfo( fpn ); FileInfo ci = new FileInfo( cpn ); if( debug ) { Log( ".s.compare folder file [{0}]\n with current [{1}]", fpn, cpn ); } if( ! ci.Exists || ! ctrl.FileDateMatches( fi.LastWriteTimeUtc, ci.LastWriteTimeUtc ) || (fi.Length != ci.Length) ) { if( debug ) { Log( ".s.file has changed" ); } ScanQueue( ActionType.Copy, folder, path, n ); } ListFilenameRemove( a, n ); } catch( Exception ex ) { ex.Data[ExFolderFilename ] = fpn; ex.Data[ExCurrentFilename] = cpn; Log( "Scan {0}", Except.ToString( ex, debug ) ); Interlocked.Increment( ref status.update.skipped ); LogStatus( StatusType.Skipped, folder.Name, path, n ); } } } catch( Exception ex ) { ex.Data[ExFolderFilename] = fpn; throw; } } } catch( Exception ex ) { ex.Data[ExFilename] = n; throw; } } if( a.Count > 0 ) { if( debug ) { Log( ".s.flag deleted files for removal" ); } foreach( string n in a ) { if( debug ) { Log( ".s.deleted file [{0}]", n ); } ScanQueue( ActionType.Delete, folder, path, n ); } } //..scan folders second if( debug ) { Log( ".s.-----> directories [{0}]", MatchPath.AbsoluteDirectoryPath( path ?? string.Empty ) ); } a = new List<string>( Ctrl.ListDirectories( cp ) ); foreach( string n in Ctrl.ListDirectories( fp ) ) { if( IsCancelRequested ) { throw new Exception( "Scan cancelled." ); } string pn = PathCombine( path, n ); if( debug ) { Log( ".s.directory [{0}]", pn ); } ScanFolder( folder, pn ); ListFilenameRemove( a, n ); } if( a.Count > 0 ) { if( debug ) { Log( ".s.flag deleted directories for removal" ); } foreach( string n in a ) { if( debug ) { Log( ".s.deleted directory [{0}]", n ); } ScanQueue( ActionType.Delete, folder, PathCombine( path, n ), null ); } } } catch( Exception ex ) { ex.Data[ExCurrentPath] = cp; throw; } } catch( Exception ex ) { ex.Data[ExFolderPath] = fp; throw; } } catch( Exception ex ) { ex.Data[ExPath] = path; Msg( "Scan: {0}", Except.ToString( ex, debug ) ); } }