SparkleShare/SparkleLib/SparkleFetcherBase.cs

291 lines
8.9 KiB
C#
Raw Normal View History

// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// 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 3 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, see <http://www.gnu.org/licenses/>.
using System;
using System.IO;
2011-05-31 01:26:57 +00:00
using System.Text.RegularExpressions;
using System.Threading;
namespace SparkleLib {
// Sets up a fetcher that can get remote folders
public abstract class SparkleFetcherBase {
public delegate void StartedEventHandler ();
public delegate void FinishedEventHandler (string [] warnings);
public delegate void FailedEventHandler ();
2011-08-27 15:53:17 +00:00
public delegate void ProgressChangedEventHandler (double percentage);
public event StartedEventHandler Started;
public event FinishedEventHandler Finished;
public event FailedEventHandler Failed;
2011-08-27 15:53:17 +00:00
public event ProgressChangedEventHandler ProgressChanged;
2012-02-09 01:46:25 +00:00
public abstract bool Fetch ();
public abstract void Stop ();
2012-02-09 01:46:25 +00:00
public string TargetFolder;
public string RemoteUrl;
public string [] ExcludeRules;
public string [] Warnings;
2011-08-27 18:57:34 +00:00
private Thread thread;
2011-05-31 01:26:57 +00:00
public SparkleFetcherBase (string server, string remote_folder, string target_folder)
{
2012-02-09 01:46:25 +00:00
TargetFolder = target_folder;
RemoteUrl = server + "/" + remote_folder;
ExcludeRules = new string [] {
// gedit and emacs
"*~",
// Firefox and Chromium temporary download files
"*.part",
"*.crdownload",
// vi(m)
".*.sw[a-z]",
"*.un~",
"*.swp",
"*.swo",
// KDE
".directory",
// Mac OS X
".DS_Store",
"Icon?",
"._*",
".Spotlight-V100",
".Trashes",
// Omnigraffle
"*(Autosaved).graffle",
// Windows
"Thumbs.db",
"Desktop.ini",
// MS Office
"~*.tmp",
"~*.TMP",
"*~*.tmp",
"*~*.TMP",
"~*.ppt",
"~*.PPT",
"~*.pptx",
"~*.PPTX",
"~*.xls",
"~*.XLS",
"~*.xlsx",
"~*.XLSX",
"~*.doc",
"~*.DOC",
"~*.docx",
"~*.DOCX",
// CVS
"*/CVS/*",
".cvsignore",
"*/.cvsignore",
// Subversion
"/.svn/*",
"*/.svn/*",
// Mercurial
"/.hg/*",
"*/.hg/*",
"*/.hgignore",
// Bazaar
"/.bzr/*",
"*/.bzr/*",
"*/.bzrignore"
};
}
// Clones the remote repository
public void Start ()
{
2012-02-09 01:46:25 +00:00
SparkleHelpers.DebugInfo ("Fetcher", "[" + TargetFolder + "] Fetching folder: " + RemoteUrl);
if (Started != null)
Started ();
2012-02-09 01:46:25 +00:00
if (Directory.Exists (TargetFolder))
Directory.Delete (TargetFolder, true);
2012-02-09 01:46:25 +00:00
string host = GetHost (RemoteUrl);
2011-05-31 01:26:57 +00:00
if (String.IsNullOrEmpty (host)) {
if (Failed != null)
Failed ();
return;
}
DisableHostKeyCheckingForHost (host);
this.thread = new Thread (new ThreadStart (delegate {
if (Fetch ()) {
2011-05-31 01:26:57 +00:00
SparkleHelpers.DebugInfo ("Fetcher", "Finished");
EnableHostKeyCheckingForHost (host);
if (Finished != null)
Finished (Warnings);
2011-05-31 01:26:57 +00:00
} else {
2011-05-31 01:26:57 +00:00
SparkleHelpers.DebugInfo ("Fetcher", "Failed");
EnableHostKeyCheckingForHost (host);
if (Failed != null)
Failed ();
}
}));
this.thread.Start ();
}
public void Dispose ()
{
if (this.thread != null) {
this.thread.Abort ();
this.thread.Join ();
}
}
2011-08-27 15:53:17 +00:00
protected void OnProgressChanged (double percentage) {
if (ProgressChanged != null)
ProgressChanged (percentage);
}
2011-05-31 01:26:57 +00:00
private void DisableHostKeyCheckingForHost (string host)
{
2011-07-24 01:00:40 +00:00
string path = SparkleConfig.DefaultConfig.HomePath;
2011-05-31 01:26:57 +00:00
if (!(SparkleBackend.Platform == PlatformID.Unix ||
SparkleBackend.Platform == PlatformID.MacOSX)) {
path = Environment.ExpandEnvironmentVariables ("%HOMEDRIVE%%HOMEPATH%");
}
2011-06-14 13:48:18 +00:00
string ssh_config_path = Path.Combine (path, ".ssh");
string ssh_config_file_path = SparkleHelpers.CombineMore (path, ".ssh", "config");
string ssh_config = "\n# <SparkleShare>" +
"\nHost " + host +
"\n\tStrictHostKeyChecking no" +
"\n# </SparkleShare>";
2011-05-31 01:26:57 +00:00
2011-06-14 13:48:18 +00:00
if (!Directory.Exists (ssh_config_path))
Directory.CreateDirectory (ssh_config_path);
2011-05-31 01:26:57 +00:00
if (File.Exists (ssh_config_file_path)) {
TextWriter writer = File.AppendText (ssh_config_file_path);
writer.Write (ssh_config);
2011-05-31 01:26:57 +00:00
writer.Close ();
} else {
File.WriteAllText (ssh_config_file_path, ssh_config);
2011-05-31 01:26:57 +00:00
}
Chmod644 (ssh_config_file_path);
SparkleHelpers.DebugInfo ("Fetcher", "Disabled host key checking for " + host);
2011-05-31 01:26:57 +00:00
}
private void EnableHostKeyCheckingForHost (string host)
{
2011-07-24 01:00:40 +00:00
string path = SparkleConfig.DefaultConfig.HomePath;
if (SparkleBackend.Platform != PlatformID.Unix &&
SparkleBackend.Platform != PlatformID.MacOSX) {
path = Environment.ExpandEnvironmentVariables ("%HOMEDRIVE%%HOMEPATH%");
}
2011-05-31 01:26:57 +00:00
string ssh_config_file_path = SparkleHelpers.CombineMore (path, ".ssh", "config");
2011-05-31 01:26:57 +00:00
if (File.Exists (ssh_config_file_path)) {
string current_ssh_config = File.ReadAllText (ssh_config_file_path);
current_ssh_config = current_ssh_config.Trim ();
string [] lines = current_ssh_config.Split ('\n');
string new_ssh_config = "";
bool in_sparkleshare_section = false;
foreach (string line in lines) {
if (line.StartsWith ("# <SparkleShare>")) {
in_sparkleshare_section = true;
continue;
}
2011-05-31 01:26:57 +00:00
if (line.StartsWith ("# </SparkleShare>")) {
in_sparkleshare_section = false;
continue;
}
if (in_sparkleshare_section)
continue;
new_ssh_config += line + "\n"; // do not use Environment.NewLine because file is in unix format
}
2011-05-31 01:26:57 +00:00
2011-11-06 14:37:56 +00:00
if (string.IsNullOrEmpty (new_ssh_config.Trim ())) {
2011-05-31 01:26:57 +00:00
File.Delete (ssh_config_file_path);
} else {
File.WriteAllText (ssh_config_file_path, new_ssh_config.Trim ());
Chmod644 (ssh_config_file_path);
2011-05-31 01:26:57 +00:00
}
}
SparkleHelpers.DebugInfo ("Fetcher", "Enabled host key checking for " + host);
2011-05-31 01:26:57 +00:00
}
private string GetHost (string url)
{
Regex regex = new Regex (@"(@|://)([a-z0-9\.-]+)(/|:)");
2011-05-31 01:26:57 +00:00
Match match = regex.Match (url);
if (match.Success)
return match.Groups [2].Value;
else
return null;
}
private void Chmod644 (string file_path)
{
// Hack to be able to set the permissions on a file
// that OpenSSH still likes without resorting to Mono.Unix
FileInfo file_info = new FileInfo (file_path);
file_info.Attributes = FileAttributes.ReadOnly;
file_info.Attributes = FileAttributes.Normal;
}
}
}