Ejemplo n.º 1
0
        EvaluateInternal()
        {
#if __MonoCS__
            if (this.IsPrebuilt)
            {
                return;
            }
            this.ReasonToExecute = null;
            var symlinkPath = this.GeneratedPaths[Key].ToString();
            var symlinkInfo = new Mono.Unix.UnixSymbolicLinkInfo(symlinkPath);
            if (!symlinkInfo.Exists)
            {
                this.ReasonToExecute = Bam.Core.ExecuteReasoning.FileDoesNotExist(this.GeneratedPaths[Key]);
                return;
            }
            var targetPath = symlinkInfo.ContentsPath;
            if (targetPath != System.IO.Path.GetFileName(this.SharedObject.GeneratedPaths[ConsoleApplication.Key].ToString()))
            {
                this.ReasonToExecute = Bam.Core.ExecuteReasoning.InputFileNewer(this.GeneratedPaths[Key], this.SharedObject.Macros[this.Macros["SymlinkUsage"].ToString()]);
                return;
            }
#else
            throw new System.NotSupportedException("Symbolic links not supported for shared objects on this platform");
#endif
        }
Ejemplo n.º 2
0
        public void Tar_GZip_With_Symlink_Entries()
        {
            var isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(
                System.Runtime.InteropServices.OSPlatform.Windows);

            using (Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "TarWithSymlink.tar.gz")))
                using (var reader = TarReader.Open(stream))
                {
                    List <string> names = new List <string>();
                    while (reader.MoveToNextEntry())
                    {
                        if (reader.Entry.IsDirectory)
                        {
                            continue;
                        }
                        reader.WriteEntryToDirectory(SCRATCH_FILES_PATH,
                                                     new ExtractionOptions()
                        {
                            ExtractFullPath   = true,
                            Overwrite         = true,
                            WriteSymbolicLink = (sourcePath, targetPath) =>
                            {
                                if (!isWindows)
                                {
                                    var link = new Mono.Unix.UnixSymbolicLinkInfo(sourcePath);
                                    if (File.Exists(sourcePath))
                                    {
                                        link.Delete();                          // equivalent to ln -s -f
                                    }
                                    link.CreateSymbolicLinkTo(targetPath);
                                }
                            }
                        });
                        if (!isWindows)
                        {
                            if (reader.Entry.LinkTarget != null)
                            {
                                var path = System.IO.Path.Combine(SCRATCH_FILES_PATH, reader.Entry.Key);
                                var link = new Mono.Unix.UnixSymbolicLinkInfo(path);
                                if (link.HasContents)
                                {
                                    // need to convert the link to an absolute path for comparison
                                    var target     = reader.Entry.LinkTarget;
                                    var realTarget = System.IO.Path.GetFullPath(
                                        System.IO.Path.Combine($"{System.IO.Path.GetDirectoryName(path)}",
                                                               target)
                                        );

                                    Assert.Equal(realTarget, link.GetContents().ToString());
                                }
                                else
                                {
                                    Assert.True(false, "Symlink has no target");
                                }
                            }
                        }
                    }
                }
        }
Ejemplo n.º 3
0
 private static bool CanPosix()
 {
     try             // https://stackoverflow.com/questions/19428170/detecting-symbolic-links-and-pipes-in-mono
     {
         Mono.Unix.UnixSymbolicLinkInfo info = new Mono.Unix.UnixSymbolicLinkInfo("/");
     }
     catch (TypeLoadException e)
     {
         return(false);
     }
     return(true);
 }
Ejemplo n.º 4
0
        }        // NormalizePath

        /// <summary>
        /// Returns the real path for a path containing a symbolic link
        /// </summary>
        /// <returns>
        /// A resolved path.
        /// </returns>
        /// <param name='path'>
        /// A path that may traverse a symbolic link.
        /// </param>
        /// <exception cref='ArgumentException'>
        /// Is thrown when path is empty.
        /// </exception>
        internal static string ResolveSymlink(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentException("Empty path not allowed", "path");
            }

            if (!(File.Exists(path) || Directory.Exists(path)))
            {
                return(path);
            }

#if !WINDOWS
            try {
                string[] chunks  = path.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);
                string   subpath = chunks[0];
                Mono.Unix.UnixSymbolicLinkInfo link;

                if (Path.IsPathRooted(path))
                {
                    subpath = Path.Combine(Path.GetPathRoot(path), subpath);
                }

                for (int i = 1; i < chunks.Length; ++i)
                {
                    link = new Mono.Unix.UnixSymbolicLinkInfo(subpath);
                    if (link.IsSymbolicLink)
                    {
                        subpath = link.GetContents().FullName;
                        --i;
                        continue;
                    }
                    subpath = Path.Combine(subpath, chunks[i]);
                }

                link = new Mono.Unix.UnixSymbolicLinkInfo(subpath);
                if (link.IsSymbolicLink)
                {
                    subpath = link.GetContents().FullName;
                }
                //			if (path != subpath)
                //				Console.WriteLine ("Subsituting {0} for {1}", subpath, path);
                path = subpath;
            } catch (Exception ex) {
                LoggingService.LogWarning(string.Format("Error checking symlink status for {0}", path), ex);
            }
#endif

            return(path);
        }
Ejemplo n.º 5
0
        AssignLinkTarget(
            TokenizedString path = null)
        {
#if __MonoCS__
            if (path == null)
            {
                var symlink = new Mono.Unix.UnixSymbolicLinkInfo(this.SourcePath.Parse());
                this.Macros["LinkTarget"] = Bam.Core.TokenizedString.CreateVerbatim(symlink.ContentsPath);
            }
            else
            {
                this.Macros["LinkTarget"] = path;
            }
#else
            throw new System.NotSupportedException("Unable to get symbolic link target on Windows");
#endif
        }
Ejemplo n.º 6
0
        AssignLinkTarget(
            TokenizedString path = null)
        {
#if __MonoCS__
            if (path == null)
            {
                var symlink = new Mono.Unix.UnixSymbolicLinkInfo(this.SourcePath.Parse());
                this.Macros["LinkTarget"] = Bam.Core.TokenizedString.CreateVerbatim(symlink.ContentsPath);
            }
            else
            {
                this.Macros["LinkTarget"] = path;
            }
#else
            throw new System.NotSupportedException("Unable to get symbolic link target on Windows");
#endif
        }
Ejemplo n.º 7
0
        // Needed so that UnixSymbolicLinkInfo doesn't have to
        // be JITted on windows
        private void Symlink_helper()
        {
            string path = TempFolder + DSC + "DIT.Symlink";
            string dir  = path + DSC + "dir";
            string link = path + DSC + "link";

            DeleteDir(path);

            try {
                Directory.CreateDirectory(path);
                Directory.CreateDirectory(dir);
                Mono.Unix.UnixSymbolicLinkInfo li = new Mono.Unix.UnixSymbolicLinkInfo(link);
                li.CreateSymbolicLinkTo(dir);

                DirectoryInfo   info = new DirectoryInfo(path);
                DirectoryInfo[] dirs = info.GetDirectories();
                Assert.AreEqual(2, dirs.Length, "#1");
            } finally {
                DeleteDir(path);
            }
        }
Ejemplo n.º 8
0
            internal static bool TryGetSymLinkTarget(string path, [NotNullWhen(true)] out string?target)
            {
                var symbolicLinkInfo = new Mono.Unix.UnixSymbolicLinkInfo(path);

                if (symbolicLinkInfo.IsSymbolicLink)
                {
                    var root = Path.GetDirectoryName(path);
                    if (root == null)
                    {
                        target = symbolicLinkInfo.ContentsPath;
                    }
                    else
                    {
                        target = Path.Combine(root, symbolicLinkInfo.ContentsPath);
                    }
                    return(true);
                }

                target = null;
                return(false);
            }
Ejemplo n.º 9
0
        Evaluate()
        {
            base.Evaluate();
            if (null != this.ReasonToExecute)
            {
                // a reason has been found already
                return;
            }
            if (this.IsPrebuilt)
            {
                return;
            }
            if (!this.BuildEnvironment.Platform.Includes(Bam.Core.EPlatform.Linux))
            {
                // symlinks only on Linux
                return;
            }
            if (this is Plugin)
            {
                // plugins don't have symlinks
                return;
            }
            var fullSONamePath = this.CreateTokenizedString("@dir($(0))/$(1)", this.GeneratedPaths[Key], this.Macros["SOName"]);
            var soName         = new Mono.Unix.UnixSymbolicLinkInfo(fullSONamePath.Parse());

            if (!soName.Exists)
            {
                this.ReasonToExecute = Bam.Core.ExecuteReasoning.FileDoesNotExist(fullSONamePath);
                return;
            }
            var fullLinkerNamePath = this.CreateTokenizedString("@dir($(0))/$(1)", this.GeneratedPaths[Key], this.Macros["LinkerName"]);
            var linkerName         = new Mono.Unix.UnixSymbolicLinkInfo(fullLinkerNamePath.Parse());

            if (!linkerName.Exists)
            {
                this.ReasonToExecute = Bam.Core.ExecuteReasoning.FileDoesNotExist(fullLinkerNamePath);
                return;
            }
        }
Ejemplo n.º 10
0
 /// <summary>
 /// returns the partition name (sdX format) from any by-xxxx value (by-path, by-uuid...)
 /// </summary>
 /// <param name='partitionName'>
 /// Partition name.
 /// </param>/
 private string GetPartitionFromPathOrUuid(string partitionName)
 {
     string[] disksBy = new string[] { "by-uuid", "by-path", "by-label", "by-id" };
     foreach (string byType in disksBy)
     {
         Mono.Unix.UnixDirectoryInfo byUuidParts = new Mono.Unix.UnixDirectoryInfo("/dev/disk/" + byType);
         foreach (Mono.Unix.Native.Dirent d in byUuidParts.GetEntries())
         {
             //Console.WriteLine ("______GetPartitionFromPathOrUuid looking cur entry="+d.d_name+", type="+d.d_type);
             if (d.d_type == 10 /*Mono.Unix.FileTypes.SymbolicLink*/)
             {
                 string partOnlyName = "";
                 if (partitionName.LastIndexOf("/") >= 0)
                 {
                     partOnlyName = partitionName.Substring(partitionName.LastIndexOf("/") + 1);
                 }
                 else if (partitionName.IndexOf("UUID=") == 0)
                 {
                     partOnlyName = partitionName.Replace("UUID=", "");
                 }
                 else
                 {
                     partOnlyName = partitionName;
                 }
                 //Console.WriteLine ("______GetPartitionFromPathOrUuid :d_name="+d.d_name+", partonlyname="+partOnlyName);
                 if (d.d_name == partOnlyName)
                 {
                     Mono.Unix.UnixSymbolicLinkInfo devLink = new Mono.Unix.UnixSymbolicLinkInfo(byUuidParts + "/" + d.d_name);
                     //Console.WriteLine ("______GetPartitionFromPathOrUuid : "+partitionName+" --> /dev/"+devLink.ContentsPath.Substring(devLink.ContentsPath.LastIndexOf('/')+1));
                     return("/dev/" + devLink.ContentsPath.Substring(devLink.ContentsPath.LastIndexOf('/') + 1));
                 }
             }
         }
     }
     // partition was probably referenced by its devics (/dev/sdXX) path, nothing to do
     return(partitionName);
 }
Ejemplo n.º 11
0
 static FilePath ResolveSymbolicLink(FilePath fileName)
 {
     if (fileName.IsEmpty)
     {
         return(fileName);
     }
     try {
         var alreadyVisted = new HashSet <FilePath> ();
         while (true)
         {
             if (alreadyVisted.Contains(fileName))
             {
                 LoggingService.LogError("Cyclic links detected: " + fileName);
                 return(FilePath.Empty);
             }
             alreadyVisted.Add(fileName);
             var linkInfo = new Mono.Unix.UnixSymbolicLinkInfo(fileName);
             if (linkInfo.IsSymbolicLink && linkInfo.HasContents)
             {
                 FilePath contentsPath = linkInfo.ContentsPath;
                 if (contentsPath.IsAbsolute)
                 {
                     fileName = linkInfo.ContentsPath;
                 }
                 else
                 {
                     fileName = fileName.ParentDirectory.Combine(contentsPath);
                 }
                 fileName = fileName.CanonicalPath;
                 continue;
             }
             return(ResolveSymbolicLink(fileName.ParentDirectory).Combine(fileName.FileName).CanonicalPath);
         }
     } catch (Exception) {
         return(fileName);
     }
 }
Ejemplo n.º 12
0
		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 ) );
			}
		}
Ejemplo n.º 13
0
        private async Task <IActionResult> PushDeployAsync(ZipDeploymentInfo deploymentInfo, bool isAsync,
                                                           HttpContext context)
        {
            var zipFilePath = Path.Combine(_environment.ZipTempPath, Guid.NewGuid() + ".zip");

            if (_settings.RunFromLocalZip())
            {
                await WriteSitePackageZip(deploymentInfo, _tracer);
            }
            else
            {
                var oryxManifestFile = Path.Combine(_environment.WebRootPath, "oryx-manifest.toml");
                if (FileSystemHelpers.FileExists(oryxManifestFile))
                {
                    _tracer.Step("Removing previous build artifact's manifest file");
                    FileSystemHelpers.DeleteFileSafe(oryxManifestFile);
                }

                try
                {
                    var nodeModulesSymlinkFile       = Path.Combine(_environment.WebRootPath, "node_modules");
                    Mono.Unix.UnixSymbolicLinkInfo i = new Mono.Unix.UnixSymbolicLinkInfo(nodeModulesSymlinkFile);
                    if (i.FileType == Mono.Unix.FileTypes.SymbolicLink)
                    {
                        _tracer.Step("Removing node_modules symlink");
                        // TODO: Add support to remove Unix Symlink File in DeleteFileSafe
                        // FileSystemHelpers.DeleteFileSafe(nodeModulesSymlinkFile);
                        FileSystemHelpers.RemoveUnixSymlink(nodeModulesSymlinkFile, TimeSpan.FromSeconds(5));
                    }
                }
                catch (Exception)
                {
                    // best effort
                }

                using (_tracer.Step("Writing zip file to {0}", zipFilePath))
                {
                    if (!string.IsNullOrEmpty(context.Request.ContentType) &&
                        context.Request.ContentType.Contains("multipart/form-data", StringComparison.OrdinalIgnoreCase))
                    {
                        FormValueProvider formModel;
                        using (_tracer.Step("Writing zip file to {0}", zipFilePath))
                        {
                            using (var file = System.IO.File.Create(zipFilePath))
                            {
                                formModel = await Request.StreamFile(file);
                            }
                        }
                    }
                    else if (deploymentInfo.ZipURL != null)
                    {
                        using (_tracer.Step("Writing zip file from packageUri to {0}", zipFilePath))
                        {
                            using (var httpClient = new HttpClient())
                                using (var fileStream = new FileStream(zipFilePath,
                                                                       FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
                                {
                                    var zipUrlRequest  = new HttpRequestMessage(HttpMethod.Get, deploymentInfo.ZipURL);
                                    var zipUrlResponse = await httpClient.SendAsync(zipUrlRequest);

                                    try
                                    {
                                        zipUrlResponse.EnsureSuccessStatusCode();
                                    }
                                    catch (HttpRequestException hre)
                                    {
                                        _tracer.TraceError(hre, "Failed to get file from packageUri {0}", deploymentInfo.ZipURL);
                                        throw;
                                    }

                                    using (var content = await zipUrlResponse.Content.ReadAsStreamAsync())
                                    {
                                        await content.CopyToAsync(fileStream);
                                    }
                                }
                        }
                    }
                    else
                    {
                        using (var file = System.IO.File.Create(zipFilePath))
                        {
                            await Request.Body.CopyToAsync(file);
                        }
                    }
                }

                deploymentInfo.RepositoryUrl = zipFilePath;
            }

            var result =
                await _deploymentManager.FetchDeploy(deploymentInfo, isAsync, UriHelper.GetRequestUri(Request), "HEAD");

            switch (result)
            {
            case FetchDeploymentRequestResult.RunningAynschronously:
                if (isAsync)
                {
                    // latest deployment keyword reserved to poll till deployment done
                    Response.GetTypedHeaders().Location =
                        new Uri(UriHelper.GetRequestUri(Request),
                                String.Format("/api/deployments/{0}?deployer={1}&time={2}", Constants.LatestDeployment,
                                              deploymentInfo.Deployer, DateTime.UtcNow.ToString("yyy-MM-dd_HH-mm-ssZ")));
                }

                return(Accepted());

            case FetchDeploymentRequestResult.ForbiddenScmDisabled:
                // Should never hit this for zip push deploy
                _tracer.Trace("Scm is not enabled, reject all requests.");
                return(Forbid());

            case FetchDeploymentRequestResult.ConflictAutoSwapOngoing:
                return(StatusCode(StatusCodes.Status409Conflict, Resources.Error_AutoSwapDeploymentOngoing));

            case FetchDeploymentRequestResult.Pending:
                // Shouldn't happen here, as we disallow deferral for this use case
                return(Accepted());

            case FetchDeploymentRequestResult.RanSynchronously:
                return(Ok());

            case FetchDeploymentRequestResult.ConflictDeploymentInProgress:
                return(StatusCode(StatusCodes.Status409Conflict, Resources.Error_DeploymentInProgress));

            case FetchDeploymentRequestResult.ConflictRunFromRemoteZipConfigured:
                return(StatusCode(StatusCodes.Status409Conflict, Resources.Error_RunFromRemoteZipConfigured));

            default:
                return(BadRequest());
            }
        }
Ejemplo n.º 14
0
		void BackupFile( string fp, string cp, string hp, string pn, string n, bool history )
		{
			string   fpn  = PathCombine( fp, n );
			string   cpn  = PathCombine( cp, n );

			FileInfo ffi  = FileInfo( fpn );
			FileInfo cfi  = FileInfo( cpn );
			if( (ffi == null) || (cfi == null) )
			{
				return;
			}
#if __MonoCS__
			{
				Mono.Unix.UnixSymbolicLinkInfo i = new Mono.Unix.UnixSymbolicLinkInfo( fpn );
				if( ! i.Exists || ! i.IsRegularFile )
				{
					LogReason( Reason.Skipped, fpn, false );
					return;
				}
			}
#endif
			if( ! cfi.Exists )
			{
				//..file does not exist in current, simply copy
				action( Action.File, n );
				LogReason( Reason.Created, pn, FileCopy( fpn, cpn, false ) );
				return;
			}
			/* ..check for file property changes
			 * The date of the file is adjusted to fit within the min and max dates the archive filesystem can support.
			 * The dates are checked to be within 1 second of each other to avoid slight inconsistencies at the millisecond level.
			 * The file length must match.
			 */
			if( 
				   DateCompare( DateAdjust( ffi.LastWriteTimeUtc ), DateAdjust( cfi.LastWriteTimeUtc ) )
				&& (ffi.Length == cfi.Length )
				)
			{
				//..file has not changed, ignore
				return;
			}
			action( Action.File, n );

			if( debug )
			{
				StringBuilder sbf = new StringBuilder();
				StringBuilder sbc = new StringBuilder();
				if( ffi.CreationTime      != cfi.CreationTime      ) { sbf.Append(  " CR[" + DisplayDate( ffi.CreationTime                ) + "]" ); sbc.Append(  " CR[" + DisplayDate( cfi.CreationTime                ) + "]" ); }
				if( ffi.CreationTimeUtc   != cfi.CreationTimeUtc   ) { sbf.Append( " CRU[" + DisplayDate( ffi.CreationTimeUtc             ) + "]" ); sbc.Append( " CRU[" + DisplayDate( cfi.CreationTimeUtc             ) + "]" ); }
				if( ffi.LastAccessTime    != cfi.LastAccessTime    ) { sbf.Append(  " LA[" + DisplayDate( ffi.LastAccessTime              ) + "]" ); sbc.Append(  " LA[" + DisplayDate( cfi.LastAccessTime              ) + "]" ); }
				if( ffi.LastAccessTimeUtc != cfi.LastAccessTimeUtc ) { sbf.Append( " LAU[" + DisplayDate( ffi.LastAccessTimeUtc           ) + "]" ); sbc.Append( " LAU[" + DisplayDate( cfi.LastAccessTimeUtc           ) + "]" ); }
				if( ffi.LastWriteTime     != cfi.LastWriteTime     ) { sbf.Append(  " LW[" + DisplayDate( ffi.LastWriteTime               ) + "]" ); sbc.Append(  " LW[" + DisplayDate( cfi.LastWriteTime               ) + "]" ); }
				if( ffi.LastWriteTimeUtc  != cfi.LastWriteTimeUtc  ) { sbf.Append( " LWU[" + DisplayDate( ffi.LastWriteTimeUtc            ) + "]" ); sbc.Append( " LWU[" + DisplayDate( cfi.LastWriteTimeUtc            ) + "]" ); }
				if( ffi.Length            != cfi.Length            ) { sbf.Append( " LEN[" +              ffi.Length            .ToString() + "]" ); sbc.Append( " LEN[" +              cfi.Length            .ToString() + "]" ); }
				if( ffi.Attributes        != cfi.Attributes        ) { sbf.Append(  " AT[" +              ffi.Attributes        .ToString() + "]" ); sbc.Append(  " AT[" +              cfi.Attributes        .ToString() + "]" ); }
				if( ffi.IsReadOnly        != cfi.IsReadOnly        ) { sbf.Append(  " RO[" +              ffi.IsReadOnly        .ToString() + "]" ); sbc.Append(  " RO[" +              cfi.IsReadOnly        .ToString() + "]" ); }
				Log( "" );
				LogStatus( "   file"  , sbf.ToString() );
				LogStatus( "  archive", sbc.ToString() );
			}

			//?? Is there a better way to do this combination that tests if a file can be copied first ??
			//..perhaps copy to a different file name first, move old file to history, rename copied file

			bool replace = false;

			//..move old file from current to history
			if( ! history )
			{
				//..remove old file from current

				if( ! FileDelete( cpn ) )
				{
					LogInfo( "Backup. failed to delete previous backup file" );
					replace = true;
				}
				//..copy file to current
				LogReason( Reason.Modified, pn, FileCopy( fpn, cpn, replace ) );
				return;
			}
			if( (hp == null) || ! DirectoryCreateDirectory( hp ) )
			{
				return;
			}
			//..move old file from current to history
			string hpn = PathCombine( hp, n );
#if CHECK_HISTORY_BUG
			if( File.Exists( hpn ) )
			{
				LogInfo( "Backup. file already exists in history [" + hpn + "], replacing" );
				FileDelete( hpn );
			}
#endif
			if( ! FileMove( cpn, hpn ) )
			{
				LogInfo( "Backup. failed moving current to history" );
				replace = true;
			}
			//..copy new file from folder to current
			if( ! FileCopy( fpn, cpn, replace ) )
			{
				LogReason( Reason.Skipped, pn, false );
				return;
			}
			LogReason( Reason.Modified, pn, true );
			return;
		}
Ejemplo n.º 15
0
		/// <summary>
		///		Copy a folder and all sub-folders as quickly as possible without
		///		checking their contents first.
		///		Before calling this function, make sure the destination folder
		///		does not already exist.
		/// </summary>
		bool CopyFolder( string path, bool include )
		{
			if( cancel ) { return include; }
			if( ! include && inc.MatchDirectory( path ) ) { include = true; }
			if(              exc.MatchDirectory( path ) ) { return false; }
			bool   rc = include;
			string cp = PathCombine( curr, path );
			if( ! include || DirectoryCreateDirectory( cp ) )
			{
				if( include )
				{
					LogReason( Reason.Created, DisplayDirectory( path ), true );
					rc = true;
				}
				string fp = PathCombine( fold, path );
				foreach( string n in ListDirectories( fp ) )
				{
					if( cancel ) { return rc; }
#if __MonoCS__
					{
						string fpn = PathCombine( fp, n );
						Mono.Unix.UnixSymbolicLinkInfo i = new Mono.Unix.UnixSymbolicLinkInfo( fpn );
						if( ! i.Exists || ! i.IsDirectory )
						{
							LogReason( Reason.Skipped, fpn, false );
							continue;
						}
					}
#endif
					rc |= CopyFolder( PathCombine( path, n ), include );
				}
				action( Action.Directory, path );
//				action( Action.File, "" );
				foreach( string n in ListFiles( fp ) )
				{
					if( cancel ) { return rc; }
#if __MonoCS__
					{
						string fpn = PathCombine( fp, n );
						Mono.Unix.UnixSymbolicLinkInfo i = new Mono.Unix.UnixSymbolicLinkInfo( fpn );
						if( ! i.Exists || ! i.IsRegularFile )
						{
							LogReason( Reason.Skipped, fpn, false );
							continue;
						}
					}
#endif
					string pn = PathCombine( path, n );
					if( (include || inc.MatchFile( pn )) && ! exc.MatchFile( pn ) )
					{
						if( include || DirectoryCreateDirectory( cp ) )
						{
							action( Action.File, n );
							LogReason( Reason.Created, pn, FileCopy( PathCombine( fp, n ), PathCombine( cp, n ), false ) );
							rc = true;
						}
					}
				}
			}
			return rc;
		}
Ejemplo n.º 16
0
		bool BackupCompareFolder( string path, bool include, bool history )
		{
			/* The 'include' flag indicates an item has specifically been included
			 * by a filter.
			 * The 'history' flag indicates an item has specifically been marked for
			 * a single backup only (no historical copies).
			 * If a folder is specifically excluded with a filter, then no further
			 * analysis is done on it.
			 * If the folder has not specifically been included or excluded, then a
			 * deeper analysis is done.  The folder and its descendants are scanned
			 * for files and folders which do match an include filter.
			 */
			if( ! include && inc.MatchDirectory( path ) ) { include = true ; }
			if(              exc.MatchDirectory( path ) ) { return    false; }
			if(   history && his.MatchDirectory( path ) ) { history = false; }

			if( cancel ) { return include; }
			string cp = PathCombine( curr, path );
			if( ! Directory.Exists( cp ) )
			{
				//..if directory doesn't exist in current, then the entire tree can simply be copied.
				return CopyFolder( path, include );
			}
			bool         rc = include;
			List<string> a  = new List<string>( ListDirectories( cp ) );
			string       fp = PathCombine( fold, path );
			string       hp = (hist == null) ? null : PathCombine( hist, path );
			foreach( string n in ListDirectories( fp ) )
			{
				if( cancel ) { return rc; }
				//..check each sub-directory in folder.
#if __MonoCS__
				{
					string fpn = PathCombine( fp, n );
					Mono.Unix.UnixSymbolicLinkInfo i = new Mono.Unix.UnixSymbolicLinkInfo( fpn );
					if( ! i.Exists || ! i.IsDirectory )
					{
						LogReason( Reason.Skipped, fpn, false );
						continue;
					}
				}
#endif
				if( BackupCompareFolder( PathCombine( path, n ), include, history ) )
				{
					foreach( string s in ListDirectories( cp, n ) )
					{
						a.Remove( s );
					}
					rc = true;
				}
			}
			action( Action.Directory, path );
//			action( Action.File, "" );
			if( a.Count > 0 )
			{
				//..move deleted, renamed or excluded directories from current to history.
				if( ! history || ((hp != null) && DirectoryCreateDirectory( hp )) )
				{
					foreach( string n in a )
					{
						if( cancel ) { return rc; }
						action( Action.File, DisplayDirectory( n ) );
						string pn = PathCombine( path, n );
						if( ! history || his.MatchDirectory( pn ) )
						{
							LogReason( Reason.Deleted, DisplayDirectory( pn ), DirectoryDelete( PathCombine( cp, n ), true ) );
						}
						else
						{
							LogReason( Reason.Deleted, DisplayDirectory( pn ), DirectoryMove( PathCombine( cp, n ), PathCombine( hp, n ) ) );
						}
					}
				}
			}

			a = new List<string>( ListFiles( cp ) );
			foreach( string n in ListFiles( fp ) )
			{
				if( cancel ) { return rc; }
				string  pn  = PathCombine( path, n );
				if( (include || inc.MatchFile( pn )) && ! exc.MatchFile( pn ) )
				{
					foreach( string s in ListFiles( cp, n ) )
					{
						a.Remove( s );
					}
					BackupFile( fp, cp, hp, pn, n, history && ! his.MatchFile( pn ) );
					rc = true;
				}
			}
			if( a.Count > 0 )
			{
				//..move deleted, renamed or excluded files from current to history.
				if( ! history || ((hp != null) && DirectoryCreateDirectory( hp )) )
				{
					foreach( string n in a )
					{
						if( cancel ) { return rc; }
						string pn = PathCombine( path, n );
						RemoveFile( cp, hp, pn, n, history && ! his.MatchFile( pn ) );
					}
				}
			}
			return rc;
		}
Ejemplo n.º 17
0
		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 ) );
			}
		}
Ejemplo n.º 18
0
            internal static bool IsSymbolicLink(string path)
            {
                var symbolicLinkInfo = new Mono.Unix.UnixSymbolicLinkInfo(path);

                return(symbolicLinkInfo.IsSymbolicLink);
            }
Ejemplo n.º 19
0
        static void WalkDirectoryTree(System.IO.DirectoryInfo root, Action <System.IO.FileInfo> action)
        {
            System.IO.FileInfo[]      files   = null;
            System.IO.DirectoryInfo[] subDirs = null;

            // First, process all the files directly under this folder
            try
            {
                files = root.GetFiles();
            }
            // This is thrown if even one of the files requires permissions greater
            // than the application provides.
            catch (UnauthorizedAccessException e)
            {
                DeniedFilesAccess.Add(e.Message);
            }

            catch (System.IO.DirectoryNotFoundException e)
            {
                Console.WriteLine(e.Message);
            }

            if (files != null)
            {
                foreach (System.IO.FileInfo fi in files)
                {
                    if (canPosix)
                    {
                        try                         // https://stackoverflow.com/questions/19428170/detecting-symbolic-links-and-pipes-in-mono
                        {
                            Mono.Unix.UnixSymbolicLinkInfo info = new Mono.Unix.UnixSymbolicLinkInfo(fi.FullName);
                            if (info.FileType != Mono.Unix.FileTypes.RegularFile && info.FileType != Mono.Unix.FileTypes.Directory)
                            {
                                continue;
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e);
                            continue;
                        }
                    }
                    if (LinuxPathsToIgnore.Any(x => fi.FullName.StartsWith(x)))
                    {
                        continue;
                    }

                    try
                    {
                        action(fi);
                    }
                    catch (UnauthorizedAccessException e)
                    {
                        DeniedFilesAccess.Add(fi.FullName);
                        continue;
                    }
                    catch (IOException e)
                    {
                        Console.WriteLine(e);
                        continue;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                        continue;
                    }
                }

                // Now find all the subdirectories under this directory.
                subDirs = root.GetDirectories();

                foreach (System.IO.DirectoryInfo dirInfo in subDirs)
                {
                    if (canPosix)
                    {
                        try                         // https://stackoverflow.com/questions/19428170/detecting-symbolic-links-and-pipes-in-mono
                        {
                            Mono.Unix.UnixSymbolicLinkInfo info = new Mono.Unix.UnixSymbolicLinkInfo(dirInfo.FullName);
                            if (info.FileType != Mono.Unix.FileTypes.RegularFile && info.FileType != Mono.Unix.FileTypes.Directory)
                            {
                                continue;
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e);
                            continue;
                        }
                    }
                    // Recursive call for each subdirectory.
                    WalkDirectoryTree(dirInfo, action);
                }
            }
        }
Ejemplo n.º 20
0
		// Needed so that UnixSymbolicLinkInfo doesn't have to
		// be JITted on windows
		private void Symlink_helper ()
		{
			string path = TempFolder + DSC + "DIT.Symlink";
			string dir = path + DSC + "dir";
			string link = path + DSC + "link";

			DeleteDir (path);

			try {
				Directory.CreateDirectory (path);
				Directory.CreateDirectory (dir);
				Mono.Unix.UnixSymbolicLinkInfo li = new Mono.Unix.UnixSymbolicLinkInfo (link);
				li.CreateSymbolicLinkTo (dir);

				DirectoryInfo info = new DirectoryInfo (path);
				DirectoryInfo[] dirs = info.GetDirectories ();
				Assert.AreEqual (2, dirs.Length, "#1");
			} finally {
				DeleteDir (path);
			}
		}
Ejemplo n.º 21
0
		void RecursiveDelete( FolderInfo folder, string path )
		{
			/* This method does not actually delete files, it merely counts the number of files
			 * moved from Current to History - as in, flagged for deletion
			 */
			try
			{
				string s = folder.Name + ":" + MatchPath.AbsoluteDirectoryPath( path ?? string.Empty );
				status.update.current = s;
				if( debug ) { Log( ".u.recursive delete [{0}]", s ); }

				//..check if cancelled
				if( IsCancelRequested )
				{
					throw new Exception( "Update cancelled." );
				}
				string hp = PathCombine( history, folder.Name, path );
				if( debug ) { Log( ".u.history path [{0}]", hp ); }
				try
				{
#if __MonoCS__
					{
						Mono.Unix.UnixSymbolicLinkInfo i = new Mono.Unix.UnixSymbolicLinkInfo( hp );
						if( ! i.Exists || ! i.IsDirectory )
						{
							return;
						}
					}
#endif
					if( ! DirectoryExists( hp ) )
					{
						if( debug ) { Log( ".u.history path does not exist" ); }
						return;
					}

					//..flag as deleted the number of files in the folder
					if( debug ) { Log( ".u.-----> files [{0}]", MatchPath.AbsoluteDirectoryPath( path ?? string.Empty ) ); }
					foreach( string n in Ctrl.ListFiles( hp ) )
					{
						string pn = PathCombine( path, n );
						if( debug ) { Log( ".u.file [{0}]", pn ); }
						LogStatus( StatusType.Deleted, folder.Name, path, n );
						Interlocked.Increment( ref status.update.deleted );
					}

					//..recurse into all subdirectories
					if( debug ) { Log( ".u.-----> directories [{0}]", MatchPath.AbsoluteDirectoryPath( path ?? string.Empty ) ); }
					foreach( string n in Ctrl.ListDirectories( hp ) )
					{
						string pn = PathCombine( path, n );
						if( debug ) { Log( ".u.directory [{0}]", pn ); }
						RecursiveDelete( folder, pn );
					}
				}
				catch( Exception ex )
				{
					ex.Data[ExHistoryPath] = hp;
					throw;
				}
			}
			catch( Exception ex )
			{
				ex.Data[ExPath] = path;
				throw;
			}
		}