private void DisableHostKeyCheckingForHost(string host) { string ssh_config_file_path = SparkleHelpers.CombineMore( SparklePaths.HomePath, ".ssh", "config"); string ssh_config = Environment.NewLine + "Host " + host + Environment.NewLine + "\tStrictHostKeyChecking no"; if (File.Exists(ssh_config_file_path)) { TextWriter writer = File.AppendText(ssh_config_file_path); writer.WriteLine(ssh_config); writer.Close(); } else { TextWriter writer = new StreamWriter(ssh_config_file_path); writer.WriteLine(ssh_config); writer.Close(); } UnixFileSystemInfo file_info = new UnixFileInfo(ssh_config_file_path); file_info.FileAccessPermissions = (FileAccessPermissions.UserRead | FileAccessPermissions.UserWrite); }
// Creates a .desktop entry in autostart folder to // start SparkleShare automatically at login public override void CreateStartupItem() { string autostart_path = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "autostart" ); string desktopfile_path = Path.Combine(autostart_path, "sparkleshare.desktop"); if (!Directory.Exists(autostart_path)) { Directory.CreateDirectory(autostart_path); } if (!File.Exists(desktopfile_path)) { try { File.WriteAllText(desktopfile_path, "[Desktop Entry]\n" + "Type=Application\n" + "Name=SparkleShare\n" + "Exec=sparkleshare start\n" + "Icon=folder-sparkleshare\n" + "Terminal=false\n" + "X-GNOME-Autostart-enabled=true\n" + "Categories=Network"); SparkleHelpers.DebugInfo("Controller", "Added SparkleShare to login items"); } catch (Exception e) { SparkleHelpers.DebugInfo("Controller", "Failed adding SparkleShare to login items: " + e.Message); } } }
// Creates a .desktop entry in autostart folder to // start SparkleShare automatically at login public override void EnableSystemAutostart() { string autostart_path = SparkleHelpers.CombineMore(SparklePaths.HomePath, ".config", "autostart"); string desktopfile_path = SparkleHelpers.CombineMore(autostart_path, "sparkleshare.desktop"); if (!File.Exists(desktopfile_path)) { if (!Directory.Exists(autostart_path)) { Directory.CreateDirectory(autostart_path); } TextWriter writer = new StreamWriter(desktopfile_path); writer.WriteLine("[Desktop Entry]\n" + "Type=Application\n" + "Name=SparkleShare\n" + "Exec=sparkleshare start\n" + "Icon=folder-sparkleshare\n" + "Terminal=false\n" + "X-GNOME-Autostart-enabled=true\n" + "Categories=Network"); writer.Close(); // Give the launcher the right permissions so it can be launched by the user UnixFileInfo file_info = new UnixFileInfo(desktopfile_path); file_info.Create(FileAccessPermissions.UserReadWriteExecute); SparkleHelpers.DebugInfo("Controller", "Created: " + desktopfile_path); } }
private void EnableHostKeyCheckingForHost(string host) { string ssh_config_file_path = SparkleHelpers.CombineMore( SparklePaths.HomePath, ".ssh", "config"); string ssh_config = Environment.NewLine + "Host " + host + Environment.NewLine + "\tStrictHostKeyChecking no"; if (File.Exists(ssh_config_file_path)) { StreamReader reader = new StreamReader(ssh_config_file_path); string current_ssh_config = reader.ReadToEnd(); reader.Close(); current_ssh_config = current_ssh_config.Remove( current_ssh_config.IndexOf(ssh_config), ssh_config.Length); bool has_some_ssh_config = new Regex(@"[a-z]").IsMatch(current_ssh_config); if (!has_some_ssh_config) { File.Delete(ssh_config_file_path); } else { TextWriter writer = new StreamWriter(ssh_config_file_path); writer.WriteLine(current_ssh_config); writer.Close(); UnixFileSystemInfo file_info = new UnixFileInfo(ssh_config_file_path); file_info.FileAccessPermissions = (FileAccessPermissions.UserRead | FileAccessPermissions.UserWrite); } } }
public SparkleSetupController() { string local_plugins_path = SparkleHelpers.CombineMore( Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "sparkleshare", "plugins"); if (Directory.Exists(local_plugins_path)) { foreach (string xml_file_path in Directory.GetFiles(local_plugins_path, "*.xml")) { Plugins.Add(new SparklePlugin(xml_file_path)); } } if (Directory.Exists(Program.Controller.PluginsPath)) { foreach (string xml_file_path in Directory.GetFiles(Program.Controller.PluginsPath, "*.xml")) { if (xml_file_path.EndsWith("own-server.xml")) { Plugins.Insert(0, new SparklePlugin(xml_file_path)); } else { Plugins.Add(new SparklePlugin(xml_file_path)); } } } SelectedPlugin = Plugins [0]; ChangePageEvent += delegate(PageType page, string [] warning) { this.previous_page = page; }; }
// Uploads the user's public key to the server public bool AcceptInvitation(string server, string folder, string token) { // The location of the user's public key for SparkleShare string public_key_file_path = SparkleHelpers.CombineMore(SparklePaths.HomePath, ".ssh", "sparkleshare." + UserEmail + ".key.pub"); if (!File.Exists(public_key_file_path)) { return(false); } StreamReader reader = new StreamReader(public_key_file_path); string public_key = reader.ReadToEnd(); reader.Close(); string url = "https://" + server + "/?folder=" + folder + "&token=" + token + "&pubkey=" + public_key; SparkleHelpers.DebugInfo("WebRequest", url); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); if (response.StatusCode == HttpStatusCode.OK) { response.Close(); return(true); } else { response.Close(); return(false); } }
public List <SparkleChangeSet> GetLog() { List <SparkleChangeSet> list = new List <SparkleChangeSet> (); foreach (SparkleRepoBase repo in Repositories) { List <SparkleChangeSet> change_sets = repo.GetChangeSets(50); if (change_sets != null) { list.AddRange(change_sets); } else { SparkleHelpers.DebugInfo("Log", "Could not create log for " + repo.Name); } } list.Sort((x, y) => (x.Timestamp.CompareTo(y.Timestamp))); list.Reverse(); if (list.Count > 100) { return(list.GetRange(0, 100)); } else { return(list.GetRange(0, list.Count)); } }
// Install the user's name and email and some config into // the newly cloned repository private void InstallConfiguration() { string repo_config_file_path = SparkleHelpers.CombineMore(TargetFolder, ".git", "config"); string config = File.ReadAllText(repo_config_file_path); string n = Environment.NewLine; config = config.Replace("[core]" + n, "[core]" + n + "\tquotepath = false" + n + // Show special characters in the logs "\tpackedGitLimit = 128m" + n + "\tautocrlf = false" + n + "\tsafecrlf = false" + n + "\tpackedGitWindowSize = 128m" + n); config = config.Replace("[remote \"origin\"]" + n, "[pack]" + n + "\tdeltaCacheSize = 128m" + n + "\tpackSizeLimit = 128m" + n + "\twindowMemory = 128m" + n + "[remote \"origin\"]" + n); // Be case sensitive explicitly to work on Mac config = config.Replace("ignorecase = true", "ignorecase = false"); // Ignore permission changes config = config.Replace("filemode = true", "filemode = false"); // Write the config to the file File.WriteAllText(repo_config_file_path, config); SparkleHelpers.DebugInfo("Fetcher", "Added configuration to '" + repo_config_file_path + "'"); }
// Creates the SparkleShare folder in the user's home folder public override bool CreateSparkleShareFolder() { if (!Directory.Exists(SparklePaths.SparklePath)) { Directory.CreateDirectory(SparklePaths.SparklePath); SparkleHelpers.DebugInfo("Controller", "Created '" + SparklePaths.SparklePath + "'"); string icon_file_path = SparkleHelpers.CombineMore(Defines.DATAROOTDIR, "icons", "hicolor", "48x48", "apps", "folder-sparkleshare.png"); string gvfs_command_path = SparkleHelpers.CombineMore(Path.VolumeSeparatorChar.ToString(), "usr", "bin", "gvfs-set-attribute"); // Add a special icon to the SparkleShare folder if (File.Exists(gvfs_command_path)) { Process process = new Process(); process.StartInfo.RedirectStandardOutput = true; process.StartInfo.UseShellExecute = false; process.StartInfo.FileName = "gvfs-set-attribute"; process.StartInfo.Arguments = SparklePaths.SparklePath + " metadata::custom-icon " + "file://" + icon_file_path; process.Start(); } return(true); } return(false); }
public override void EnableFetchedRepoCrypto(string password) { // Define the crypto filter in the config string repo_config_file_path = SparkleHelpers.CombineMore(TargetFolder, ".git", "config"); string config = File.ReadAllText(repo_config_file_path); string n = Environment.NewLine; config += "[filter \"crypto\"]" + n + "\tsmudge = openssl enc -d -aes-256-cbc -base64 -S " + this.crypto_salt + " -pass file:.git/password" + n + "\tclean = openssl enc -e -aes-256-cbc -base64 -S " + this.crypto_salt + " -pass file:.git/password" + n; File.WriteAllText(repo_config_file_path, config); // Pass all files through the crypto filter string git_attributes_file_path = SparkleHelpers.CombineMore( TargetFolder, ".git", "info", "attributes"); File.WriteAllText(git_attributes_file_path, "* filter=crypto"); // Store the password string password_file_path = SparkleHelpers.CombineMore(TargetFolder, ".git", "password"); File.WriteAllText(password_file_path, password.Trim()); }
public static Image GetImage(string name) { string image_path = SparkleHelpers.CombineMore(Defines.DATAROOTDIR, "sparkleshare", "pixmaps", name); return(new Image(image_path)); }
public override void CreateStartupItem() { // There aren't any bindings in MonoMac to support this yet, so // we call out to an applescript to do the job Process process = new Process(); process.EnableRaisingEvents = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.UseShellExecute = false; process.StartInfo.FileName = "osascript"; process.StartInfo.CreateNoWindow = true; string app_path = Path.GetDirectoryName(NSBundle.MainBundle.ResourcePath); app_path = Path.GetDirectoryName(app_path); process.StartInfo.Arguments = "-e 'tell application \"System Events\" to " + "make login item at end with properties {path:\"" + app_path + "\", hidden:false}'"; process.Exited += delegate { SparkleHelpers.DebugInfo("Controller", "Added " + app_path + " to login items"); }; try { process.Start(); } catch (Exception e) { SparkleHelpers.DebugInfo("Controller", "Failed adding " + app_path + " to login items: " + e.Message); } }
// Merges the fetched changes private void Rebase() { if (HasLocalChanges) { Add(); string commit_message = FormatCommitMessage(); Commit(commit_message); } SparkleGit git = new SparkleGit(LocalPath, "rebase FETCH_HEAD"); git.StartInfo.RedirectStandardOutput = false; git.Start(); git.WaitForExit(); if (git.ExitCode != 0) { SparkleHelpers.DebugInfo("Git", "[" + Name + "] Conflict detected, trying to get out..."); while (HasLocalChanges) { ResolveConflict(); } SparkleHelpers.DebugInfo("Git", "[" + Name + "] Conflict resolved"); OnConflictResolved(); } }
// Creates a folder in the user's home folder to store configuration private void CreateConfigurationFolders() { if (!Directory.Exists(SparklePaths.SparkleTmpPath)) { Directory.CreateDirectory(SparklePaths.SparkleTmpPath); } string config_path = SparklePaths.SparkleConfigPath; string local_icon_path = SparklePaths.SparkleLocalIconPath; if (!Directory.Exists(config_path)) { // Create a folder to store settings Directory.CreateDirectory(config_path); SparkleHelpers.DebugInfo("Config", "Created '" + config_path + "'"); // Create a folder to store the avatars Directory.CreateDirectory(local_icon_path); SparkleHelpers.DebugInfo("Config", "Created '" + local_icon_path + "'"); string notify_setting_file = SparkleHelpers.CombineMore(config_path, "sparkleshare.notify"); // Enable notifications by default if (!File.Exists(notify_setting_file)) { File.Create(notify_setting_file); } } }
private void ListPrivateKeys() { Process process = new Process() { EnableRaisingEvents = true }; process.StartInfo.WorkingDirectory = SparkleConfig.DefaultConfig.TmpPath; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.CreateNoWindow = true; process.StartInfo.FileName = "ssh-add"; process.StartInfo.Arguments = "-l"; process.Start(); // Reading the standard output HAS to go before // WaitForExit, or it will hang forever on output > 4096 bytes string keys_in_use = process.StandardOutput.ReadToEnd().Trim(); process.WaitForExit(); SparkleHelpers.DebugInfo("Auth", "The following keys will be available to SparkleShare: " + Environment.NewLine + keys_in_use); }
// Installs a launcher so the user can launch SparkleShare // from the Internet category if needed public override void InstallLauncher() { string apps_path = SparkleHelpers.CombineMore(SparklePaths.HomePath, ".local", "share", "applications"); string desktopfile_path = SparkleHelpers.CombineMore(apps_path, "sparkleshare.desktop"); if (!File.Exists(desktopfile_path)) { if (!Directory.Exists(apps_path)) { Directory.CreateDirectory(apps_path); } TextWriter writer = new StreamWriter(desktopfile_path); writer.WriteLine("[Desktop Entry]\n" + "Type=Application\n" + "Name=SparkleShare\n" + "Comment=Share documents\n" + "Exec=sparkleshare start\n" + "Icon=folder-sparkleshare\n" + "Terminal=false\n" + "Categories=Network;"); writer.Close(); // Give the launcher the right permissions so it can be launched by the user UnixFileInfo file_info = new UnixFileInfo(desktopfile_path); file_info.FileAccessPermissions = FileAccessPermissions.UserReadWriteExecute; SparkleHelpers.DebugInfo("Controller", "Created '" + desktopfile_path + "'"); } }
// Generates and installs an RSA keypair to identify this system public void GenerateKeyPair() { string keys_path = Path.GetDirectoryName(SparkleConfig.DefaultConfig.FullPath); string key_file_name = "sparkleshare." + CurrentUser.Email + ".key"; string key_file_path = Path.Combine(keys_path, key_file_name); if (File.Exists(key_file_path)) { SparkleHelpers.DebugInfo("Auth", "Keypair exists ('" + key_file_name + "'), leaving it untouched"); return; } else { if (!Directory.Exists(keys_path)) { Directory.CreateDirectory(keys_path); } } Process process = new Process() { EnableRaisingEvents = true }; process.StartInfo.WorkingDirectory = keys_path; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.FileName = "ssh-keygen"; process.StartInfo.CreateNoWindow = true; string computer_name = System.Net.Dns.GetHostName(); if (computer_name.EndsWith(".local")) { computer_name = computer_name.Replace(".local", ""); } process.StartInfo.Arguments = "-t rsa " + // crypto type "-P \"\" " + // password (none) "-C \"" + computer_name + "\" " + // key comment "-f " + key_file_name; // file name process.Start(); process.WaitForExit(); if (process.ExitCode == 0) { SparkleHelpers.DebugInfo("Auth", "Created keypair '" + key_file_name + "'"); } else { SparkleHelpers.DebugInfo("Auth", "Could not create keypair '" + key_file_name + "'"); } // Create an easily accessible copy of the public // key in the user's SparkleShare folder File.Copy(key_file_path + ".pub", Path.Combine(SparklePath, CurrentUser.Name + "'s link code.txt"), true); }
// Stages the made changes private void Add() { SparkleGit git = new SparkleGit(LocalPath, "add --all"); git.Start(); git.WaitForExit(); SparkleHelpers.DebugInfo("Git", "[" + Name + "] Changes staged"); }
// Gets the avatar for a specific email address and size public static string GetAvatar(string email, int size) { string avatar_path = SparkleHelpers.CombineMore(SparklePaths.SparkleLocalIconPath, size + "x" + size, "status"); if (!Directory.Exists(avatar_path)) { Directory.CreateDirectory(avatar_path); SparkleHelpers.DebugInfo("Config", "Created '" + avatar_path + "'"); } string avatar_file_path = SparkleHelpers.CombineMore(avatar_path, "avatar-" + email); if (File.Exists(avatar_file_path)) { return(avatar_file_path); } else { // Let's try to get the person's gravatar for next time WebClient web_client = new WebClient(); Uri uri = new Uri("http://www.gravatar.com/avatar/" + GetMD5(email) + ".jpg?s=" + size + "&d=404"); string tmp_file_path = SparkleHelpers.CombineMore(SparklePaths.SparkleTmpPath, email + size); if (!File.Exists(tmp_file_path)) { web_client.DownloadFileAsync(uri, tmp_file_path); web_client.DownloadFileCompleted += delegate { if (File.Exists(avatar_file_path)) { File.Delete(avatar_file_path); } FileInfo tmp_file_info = new FileInfo(tmp_file_path); if (tmp_file_info.Length > 255) { File.Move(tmp_file_path, avatar_file_path); } }; } // Fall back to a generic icon if there is no gravatar if (File.Exists(avatar_file_path)) { return(avatar_file_path); } else { return(null); } } }
public override void Stop() { try { this.git.Close(); this.git.Kill(); this.git.Dispose(); } catch (Exception e) { SparkleHelpers.DebugInfo("Fetcher", "Failed to dispose properly: " + e.Message); } }
new public void Start() { SparkleHelpers.DebugInfo("Cmd", "git " + StartInfo.Arguments); try { base.Start(); } catch (Exception e) { SparkleHelpers.DebugInfo("Cmd", "There's a problem running Git: " + e.Message); Environment.Exit(-1); } }
// Generates and installs an RSA keypair to identify this system public void GenerateKeyPair() { string keys_path = Path.GetDirectoryName(SparkleConfig.DefaultConfig.FullPath); string key_file_name = "sparkleshare." + UserEmail + ".key"; string key_file_path = Path.Combine(keys_path, key_file_name); if (File.Exists(key_file_path)) { SparkleHelpers.DebugInfo("Config", "Key already exists ('" + key_file_name + "'), " + "leaving it untouched"); return; } if (!Directory.Exists(keys_path)) { Directory.CreateDirectory(keys_path); } if (!File.Exists(key_file_name)) { Process process = new Process() { EnableRaisingEvents = true }; process.StartInfo.WorkingDirectory = keys_path; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.FileName = "ssh-keygen"; // -t is the crypto type // -P is the password (none) // -f is the file name to store the private key in process.StartInfo.Arguments = "-t rsa -P \"\" -f " + key_file_name; process.Start(); process.WaitForExit(); SparkleHelpers.DebugInfo("Config", "Created private key '" + key_file_name + "'"); SparkleHelpers.DebugInfo("Config", "Created public key '" + key_file_name + ".pub'"); // Add some restrictions to what the key can // do when uploaded to the server // string public_key = File.ReadAllText (key_file_path + ".pub"); // public_key = "no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty " + public_key; // File.WriteAllText (key_file_path + ".pub", public_key); // Create an easily accessible copy of the public // key in the user's SparkleShare folder File.Copy(key_file_path + ".pub", Path.Combine(SparklePath, UserName + "'s key.txt"), true); // Overwriting is allowed } }
// Commits the made changes private void Commit(string message) { SparkleGit git = new SparkleGit(LocalPath, "commit -m \"" + message + "\" " + "--author=\"" + SparkleConfig.DefaultConfig.User.Name + " <" + SparkleConfig.DefaultConfig.User.Email + ">\""); git.Start(); git.StandardOutput.ReadToEnd(); git.WaitForExit(); SparkleHelpers.DebugInfo("Commit", "[" + Name + "] " + message); }
private void StopSSH() { if (this.ssh_agent_pid == 0) { return; } try { Process.GetProcessById(this.ssh_agent_pid).Kill(); } catch (ArgumentException e) { SparkleHelpers.DebugInfo("SSH", "Could not stop ssh-agent: " + e.Message); } }
public SparkleInvite(string xml_file_path) { XmlDocument xml_document = new XmlDocument(); XmlNode node; string address = ""; string remote_path = ""; string accept_url = ""; string announcements_url = ""; string fingerprint = ""; try { xml_document.Load(xml_file_path); node = xml_document.SelectSingleNode("/sparkleshare/invite/address/text()"); if (node != null) { address = node.Value; } node = xml_document.SelectSingleNode("/sparkleshare/invite/remote_path/text()"); if (node != null) { remote_path = node.Value; } node = xml_document.SelectSingleNode("/sparkleshare/invite/accept_url/text()"); if (node != null) { accept_url = node.Value; } node = xml_document.SelectSingleNode("/sparkleshare/invite/announcements_url/text()"); if (node != null) { announcements_url = node.Value; } node = xml_document.SelectSingleNode("/sparkleshare/invite/fingerprint/text()"); if (node != null) { fingerprint = node.Value; } Initialize(address, remote_path, accept_url, announcements_url, fingerprint); } catch (XmlException e) { SparkleHelpers.DebugInfo("Invite", "Invalid XML: " + e.Message); return; } }
public SparkleWindow() : base("") { Title = "SparkleShare Setup"; BorderWidth = 0; IconName = "folder-sparkleshare"; Resizable = false; WindowPosition = WindowPosition.Center; SetSizeRequest(680, 440); DeleteEvent += delegate(object o, DeleteEventArgs args) { args.RetVal = true; Close(); }; HBox = new HBox(false, 6); VBox = new VBox(false, 0); Wrapper = new VBox(false, 0) { BorderWidth = 30 }; Buttons = CreateButtonBox(); VBox.PackStart(Wrapper, true, true, 0); VBox.PackStart(Buttons, false, false, 0); EventBox box = new EventBox(); Gdk.Color bg_color = new Gdk.Color(); Gdk.Color.Parse("#2e3336", ref bg_color); box.ModifyBg(StateType.Normal, bg_color); string image_path = SparkleHelpers.CombineMore(Defines.DATAROOTDIR, "sparkleshare", "pixmaps", "side-splash.png"); Image side_splash = new Image(image_path) { Yalign = 1 }; box.Add(side_splash); HBox.PackStart(box, false, false, 0); HBox.PackStart(VBox, true, true, 0); base.Add(HBox); }
public void ToggleNotifications() { string notify_setting_file_path = SparkleHelpers.CombineMore(SparklePaths.SparkleConfigPath, "sparkleshare.notify"); if (File.Exists(notify_setting_file_path)) { File.Delete(notify_setting_file_path); } else { File.Create(notify_setting_file_path); } }
private void WriteUserInfo(string user_name, string user_email) { string global_config_file_path = Path.Combine(SparklePaths.SparkleConfigPath, "config"); // Write the user's information to a text file TextWriter writer = new StreamWriter(global_config_file_path); writer.WriteLine("[user]\n" + "\tname = " + user_name + "\n" + "\temail = " + user_email); writer.Close(); SparkleHelpers.DebugInfo("Config", "Updated '" + global_config_file_path + "'"); }
// Git doesn't track empty directories, so this method // fills them all with a hidden empty file. // // It also prevents git repositories from becoming // git submodules by renaming the .git/HEAD file private void PrepareDirectories(string path) { try { foreach (string child_path in Directory.GetDirectories(path)) { if (SparkleHelpers.IsSymlink(child_path)) { continue; } if (child_path.EndsWith(".git")) { if (child_path.Equals(Path.Combine(LocalPath, ".git"))) { continue; } string HEAD_file_path = Path.Combine(child_path, "HEAD"); if (File.Exists(HEAD_file_path)) { File.Move(HEAD_file_path, HEAD_file_path + ".backup"); SparkleHelpers.DebugInfo("Git", "[" + Name + "] Renamed " + HEAD_file_path); } continue; } PrepareDirectories(child_path); } if (Directory.GetFiles(path).Length == 0 && Directory.GetDirectories(path).Length == 0 && !path.Equals(LocalPath)) { if (!File.Exists(Path.Combine(path, ".empty"))) { try { File.WriteAllText(Path.Combine(path, ".empty"), "I'm a folder!"); File.SetAttributes(Path.Combine(path, ".empty"), FileAttributes.Hidden); } catch { SparkleHelpers.DebugInfo("Git", "[" + Name + "] Failed adding empty folder " + path); } } } } catch (IOException e) { SparkleHelpers.DebugInfo("Git", "Failed preparing directory: " + e.Message); } }
public string GetAvatar(string email, int size) { string avatar_file_path = SparkleHelpers.CombineMore( Path.GetDirectoryName(SparkleConfig.DefaultConfig.FullPath), "icons", size + "x" + size, "status", "avatar-" + email); if (File.Exists(avatar_file_path)) { return(avatar_file_path); } else { return(null); } }