Exemplo n.º 1
0
        // BackupProcessor constructor:
        /// <summary>Initializes a new <c>BackupProcessor</c> object to use the given configuration and user interface object.</summary>
        /// <param name="configuration">A <c>Configuration</c> object containing all the settings for this backup run.</param>
        /// <param name="userInterface">A <c>ConsoleOutput</c> object which can be used for output to the user.</param>
        public BackupProcessor(Configuration configuration, ConsoleOutput userInterface)
        {
            // Get and store the current operating system.
            systemType = Configuration.getSystemType();

            // Each OS has a different means of creating hard links. Set the hardLinker object to whichever type of linker is appropriate.
            if (systemType == Configuration.SystemType.Windows)
            {
                hardLinker = new WindowsLinker();
            }
            else if (systemType == Configuration.SystemType.Linux)
            {
                hardLinker = new LinuxLinker();
            }
            else
            {
                throw new NotImplementedException("Unsupported operating system.");
            }

            // Get and store the limits on use of old physical copies for creating new hard links.
            maxHardLinksPerFile          = configuration.MaxHardLinksPerFile;
            maxDaysBeforeNewFullFileCopy = configuration.MaxDaysBeforeNewFullFileCopy;

            // Get and store the source and destination info for the backup.
            sourcePaths = configuration.BackupSourcePaths;
            backupsDestinationRootPath = configuration.BackupDestinationPath;

            // Set up an empty list to contain any warnings generated during the backup process.
            backupProcessWarnings = new List <string>();

            // Store the user output object.
            this.userInterface = userInterface;
        }         // end BackupProcessor constructor
        public DataAccess(SystemType type)
        {
            SiteConfigurationElement connectionString = AppConfiguration.Current.GetConnectionString(type);
            if (connectionString == null) throw new System.Exception(string.Format("No connection string found for {0}", this.SystemType));

            this._Database = new Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase(connectionString.Value);
            //this._Database = DatabaseFactory.CreateDatabase(connectionString.Value);
            this._ExecutionTimeout = connectionString.ExecutionTimeout;
            this.SystemType = type;
        }
Exemplo n.º 3
0
        }         // end tryParseAsRule()

        // identifySwitch():
        /// <summary>Identifies which option switch, if any, the specified string corresponds to.</summary>
        /// <returns>
        /// An <c>OptionsProcessor.SwitchType</c> value corresponding to the switch indicated by the specified string
        /// (which may be <c>OptionsProcessor.SwitchType.NotASwitch</c> or <c>OptionsProcessor.SwitchType.UnrecognizedSwitch</c>
        /// if the string does not appear to be a switch at all, or does not match a valid one).
        /// </returns>
        /// <param name="argument">A <c>string</c> containing a command-line argument, to try to identify as indicating a command-line switch.</param>
        /// <param name="systemType">A <c>Configuration.SystemType</c> value indicating the operating system platform currently in use.</param>
        private static SwitchType identifySwitch(string argument, Configuration.SystemType systemType)
        {
            SwitchType type;             // Will contain the switch type ascertained by this function.

            // On Windows, allow a forward slash (/) to mark a command-line switch, which is common on that platform.
            // On Linux, we won't allow that since it is indistinguishable from the start of a path string.
            bool allowSlashSwitch = (systemType == Configuration.SystemType.Windows);

            if (argument == null)
            {
                type = SwitchType.NotASwitch;                 // Obviously a null string isn't a valid switch at all.
            }
            else
            {
                if (allowSlashSwitch && argument.Length > 1 && argument[0] == '/')
                {
                    // String starts with a forward slash, and has at least one character following the slash, and forward-slash switches are allowed,
                    // so grab the rest of the string after the slash and try to parse it as a switch name.
                    string switchName = argument.Substring(1);

                    // First try parsing it as a long switch name (e.g., "MaxHardLinkAge").
                    // If it isn't recognized as that, try parsing it as a short switch name (e.g., "MA").
                    type = parseSwitchText_long(switchName);
                    if (type == SwitchType.NotASwitch)
                    {
                        type = parseSwitchText_short(switchName);
                    }
                }
                else if (argument.Length > 2 && argument.Substring(0, 2) == "--")
                {
                    // String starts with "--" switch marker and has at least one character following that.
                    // "--" indicates a long switch name (e.g., "MaxHardLinkAge"), so parse it accordingly.
                    type = parseSwitchText_long(argument.Substring(2));
                }
                else if (argument.Length > 1 && argument[0] == '-')
                {
                    // String starts with "-" switch marker and has at least one character following that.
                    // "-" indicates a short switch name (e.g., "MA"), so parse it accordingly.
                    type = parseSwitchText_short(argument.Substring(1));
                }
                else
                {
                    type = SwitchType.NotASwitch;                     // String doesn't fit any pattern that indicates a switch.
                }
            }

            return(type);
        }         // end identifySwitch()
Exemplo n.º 4
0
        // getRuntimeConfiguration():
        /// <summary>Parses all the options specified on the command-line string.</summary>
        /// <returns>A <c>Configuration</c> object containing the run-time settings for this run of the application.</returns>
        /// <param name="args">An array of all the command-line arguments to parse.</param>
        /// <exception cref="ErrorManagement.OptionsException">
        ///     Thrown when needed parameters are missing, specified ones are invalid, or an error is encountered reading configuration info from a specified sources file.
        /// </exception>
        /// <exception cref="OutOfMemoryException">Thrown when memory runs out trying to read the specified sources file.</exception>
        public static Configuration getRuntimeConfiguration(string[] args)
        {
            // Variables for holding configuration setting values to be returned.
            int?                  maxDaysBeforeNewFullFileCopy = null;
            int?                  maxHardLinksPerFile          = null;
            List <string>         commandLineSourcePaths       = new List <string>();
            List <SourcePathInfo> sourcePaths = new List <SourcePathInfo>();
            string                sourcesFilePath = null, lastReadCommandLinePath = null, backupDestinationRootPath = null;

            // Find out what platform we are running on. This is so we can allow switches to be defined on the command line
            // with a forward slash ("/") on Windows. On Linux we'll require "-" or "--" versions of the switch, because
            // a string starting with "/" is indistinguishable from a file path.
            Configuration.SystemType systemType = Configuration.getSystemType();

            // Go through each argument and find out what it is.
            for (int i = 0; i < args.Length; i++)
            {
                // Get the current argument and identify whether it is a command line switch (e.g. "-MA") or a non-switch option.
                string     currentArgument = args[i];
                SwitchType argSwitchType   = identifySwitch(currentArgument, systemType);

                if (argSwitchType == SwitchType.UnrecognizedSwitch)
                {
                    // Seems to be a switch, but isn't a valid one.
                    throw new OptionsException($"Unrecognized switch: {currentArgument}");
                }
                else if (argSwitchType == SwitchType.NotASwitch)
                {
                    // This argument is not a switch. The only non-switch options are the source and destination paths for the backup.
                    // The last path specified is treated as the destination, and all others as sources.

                    // If there already was a path argument specified, the previous one was apparently a source, not the destination,
                    // and the destination should now be set to the newest path argument.
                    if (lastReadCommandLinePath != null)
                    {
                        commandLineSourcePaths.Add(lastReadCommandLinePath);
                    }
                    lastReadCommandLinePath = Path.GetFullPath(currentArgument);
                }
                else
                {
                    // Argument type is a recognized switch.
                    // Get the next argument, which provides the value for the option specified.
                    i++;
                    if (i >= args.Length || identifySwitch(args[i], systemType) != SwitchType.NotASwitch)
                    {
                        // There is no next argument. The switch needs a value specified, and there isn't one. Error.
                        throw new OptionsException($"Missing option value for switch {currentArgument}");
                    }
                    string optionValue = args[i];

                    if (argSwitchType == SwitchType.SourcesFile)
                    {
                        if (sourcesFilePath == null)
                        {
                            sourcesFilePath = optionValue;
                        }
                        else
                        {
                            throw new OptionsException($"Switch -SF / --SourcesFile specified more than once");                             // Same switch appeared more than once on the command line.
                        }
                    }
                    else if (argSwitchType == SwitchType.MaxDaysBeforeNewFullFileCopy)
                    {
                        if (maxDaysBeforeNewFullFileCopy == null)
                        {
                            maxDaysBeforeNewFullFileCopy = int.Parse(optionValue);
                        }
                        else
                        {
                            throw new OptionsException($"Switch -MA / --MaxHardLinkAge specified more than once");                             // Same switch appeared more than once on the command line.
                        }
                    }
                    else if (argSwitchType == SwitchType.MaxHardLinksPerPhysicalFile)
                    {
                        if (maxHardLinksPerFile == null)
                        {
                            maxHardLinksPerFile = int.Parse(optionValue);
                        }
                        else
                        {
                            throw new OptionsException($"Switch -ML / --MaxHhardLinksPerFile specified more than once");                             // Same switch appeared more than once on the command line.
                        }
                    }
                }         // end if/else if/else block on argSwitchType
            }             // end for (int i = 0; i < args.Length; i++)

            // Build the list of source paths and associated rules.
            foreach (string sourcePathString in commandLineSourcePaths)
            {
                sourcePaths.Add(new SourcePathInfo(sourcePathString, null));
            }

            // If a source paths file was specified, add all its source paths and rules to the list of source paths and rules.
            if (sourcesFilePath != null)
            {
                sourcePaths.AddRange(readSourcePathsFile(sourcesFilePath));                 // Any exception while reading this file we will just allow to bubble out to the caller.
            }
            // If two sources have the same name, the second one to be backed up will clobber the first one. Don't allow this.
            if (sourcePaths.GroupBy(source => source.getAllItems().First().RelativePath).Any(group => (group.Count() > 1)))
            {
                throw new OptionsException("Multiple backup source items have the same name. Back up parent directory instead or back them up to separate destinations.");
            }

            // If, when processing all the arguments, we never encountered a source path or destination path, it is an error.
            if (sourcePaths.Count < 1)
            {
                throw new OptionsException($"No backup source path specified");
            }
            if (lastReadCommandLinePath == null)
            {
                throw new OptionsException($"No backup destination path specified");
            }
            else
            {
                backupDestinationRootPath = lastReadCommandLinePath + (Path.EndsInDirectorySeparator(lastReadCommandLinePath) ? "" : Path.DirectorySeparatorChar.ToString());
            }

            // Assemble a Configuration object based on the specified options.
            // For optional arguments, if they are still null (and thus weren't specified), use the default values.
            Configuration config =
                new Configuration(
                    maxHardLinksPerFile ?? DefaultMaxHardLinksPerPhysicalFile,
                    maxDaysBeforeNewFullFileCopy ?? DefaultMaxDaysBeforeNewFullFileCopy,
                    sourcePaths,
                    backupDestinationRootPath);

            return(config);
        }         // end getRuntimeConfiguration()