/// <summary> /// TODO /// </summary> /// <param name='path'> /// Path. /// </param> /// <param name='application'> /// Application. /// </param> /// <param name='fullfilename'> /// Fullfilename. /// </param> /// <param name='iconname'> /// Iconname. /// </param> /// <param name='applicationname'> /// Applicationname. /// </param> public static void createLauncherEntry(String path, String application, String fullfilename, String iconname, String applicationname) { TextWriter tw = new StreamWriter(fullfilename); tw.WriteLine("[Desktop Entry]"); tw.WriteLine("Name=" + applicationname); tw.WriteLine("Comment=" + applicationname); tw.WriteLine("Exec=" + path + application); tw.WriteLine("TryExec=" + path + application); tw.WriteLine("Icon=" + iconname); tw.WriteLine("Terminal=false"); tw.WriteLine("Type=Application"); tw.WriteLine("StartupNotify=true"); tw.Close(); //check the file permissions Mono.Unix.UnixFileInfo fi = new Mono.Unix.UnixFileInfo(fullfilename); if (fi.Exists) { if (!fi.FileAccessPermissions.HasFlag(Mono.Unix.FileAccessPermissions.UserExecute)) { fi.FileAccessPermissions = fi.FileAccessPermissions | Mono.Unix.FileAccessPermissions.UserExecute; } //Mono.Unix.FileAccessPermissions. } }
private void OnChanged(object source, FileSystemEventArgs e) { if (Filter.IsFiltered(Helpers.RuntimeString(), "Monitor", "File", "Path", e.FullPath)) { return; } // Inspect the file if (getFileDetails && e.ChangeType != WatcherChangeTypes.Deleted) { // Switch to using Mono here if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { var unixFileInfo = new Mono.Unix.UnixFileInfo(e.FullPath); var result = unixFileInfo.FileAccessPermissions.ToString(); WriteChange(e, result); return; } if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // Found this example but it isn't working on osx //FileSecurity fSecurity = File.GetAccessControl(e.FullPath); } } WriteChange(e); customChangeHandler?.Invoke(e); }
/// <summary> /// TODO /// </summary> /// <param name='path'> /// Path. /// </param> /// <param name='application'> /// Application. /// </param> /// <param name='fullfilename'> /// Fullfilename. /// </param> /// <param name='iconname'> /// Iconname. /// </param> /// <param name='applicationname'> /// Applicationname. /// </param> public static void createLauncherEntry(String path, String application, String fullfilename, String iconname, String applicationname) { TextWriter tw = new StreamWriter(fullfilename); tw.WriteLine("[Desktop Entry]"); tw.WriteLine("Name="+applicationname); tw.WriteLine("Comment="+applicationname); tw.WriteLine("Exec="+path+application); tw.WriteLine("TryExec="+path+application); tw.WriteLine("Icon="+iconname); tw.WriteLine("Terminal=false"); tw.WriteLine("Type=Application"); tw.WriteLine("StartupNotify=true"); tw.Close(); //check the file permissions Mono.Unix.UnixFileInfo fi = new Mono.Unix.UnixFileInfo(fullfilename); if (fi.Exists) { if (! fi.FileAccessPermissions.HasFlag(Mono.Unix.FileAccessPermissions.UserExecute)) { fi.FileAccessPermissions = fi.FileAccessPermissions | Mono.Unix.FileAccessPermissions.UserExecute; } //Mono.Unix.FileAccessPermissions. } }
public static void SetDirectoryPermissions(string path) { var folderInfo = new Mono.Unix.UnixFileInfo(path); folderInfo.FileAccessPermissions = Mono.Unix.FileAccessPermissions.AllPermissions; folderInfo.Refresh(); }
protected void on_TagEntry_activate(object sender, EventArgs args) { if (this.findThread != null) { this.stopThread = true; this.findThread.Join(); this.findThread = null; } this.store.Clear(); this.stopThread = false; this.store = new ListStore(typeof(string), typeof(Gdk.Pixbuf), typeof(BooruImage), typeof(float)); //store.SetSortColumnId(3, SortType.Descending); this.ImageThumbView.Model = store; this.Spinner.Active = true; System.IO.Directory.CreateDirectory("/home/kolrabi/x/extract/" + TagEntry.Text); var start = new ThreadStart(() => { var reader = this.db.QueryImagesWithTags(TagEntry.Text.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)); var readerColumns = new Dictionary <string, int> (); for (int i = 0; i < reader.FieldCount; i++) { readerColumns [reader.GetName(i)] = i; } while (reader.Read() && !this.stopThread) { string path = reader.GetString(readerColumns ["path"]); object md5obj = reader.GetValue(readerColumns ["md5sum"]); float elo = reader.GetFloat(readerColumns ["elo"]); int votes = reader.GetInt32(readerColumns ["votes"]); byte[] md5blob = (byte[])md5obj; var data = new BooruImageData(MD5Helper.BlobToMD5(md5blob), path, elo, votes); var image = new BooruImage(data, this.db); try { var info = new Mono.Unix.UnixFileInfo(data.Path); info.CreateSymbolicLink("/home/kolrabi/x/extract/" + TagEntry.Text + "/" + data.MD5 + System.IO.Path.GetExtension(data.Path)); //System.IO.File.Copy(data.Path, "/home/kolrabi/x/extract/" + TagEntry.Text + "/"+data.MD5+System.IO.Path.GetExtension(data.Path)); } catch (Exception ex) { Console.WriteLine("Could not copy " + data.Path + ": " + ex.Message); } Gtk.Application.Invoke((s, a) => { this.store.AppendValues(data.Path + "\n" + string.Join(" ", image.Tags), null, image, data.ELO); }); } Gtk.Application.Invoke((s, a) => { this.Spinner.Active = false; }); }); this.findThread = new Thread(start); this.findThread.Start(); }
/// <summary> /// Mac-specific implementation. /// </summary> /// <param name="programPath">Program path.</param> static partial void VerifyIsExecutable(string programPath) { var unixFileInfo = new Mono.Unix.UnixFileInfo(programPath); if (!unixFileInfo.CanAccess(Mono.Unix.Native.AccessModes.X_OK)) { var message = string.Format(System.Globalization.CultureInfo.CurrentCulture, Resources.Strings.NoExecutePermissions_Format, programPath); throw new System.InvalidOperationException(message); } }
public void TestWriteValidFile() { var fileName = Guid.NewGuid().ToString(); var fileContent = Guid.NewGuid().ToString(); File.WriteAllText(mountPoint + fileName, fileContent, Encoding.UTF8); var actualContent = File.ReadAllText(mountPoint + fileName, Encoding.UTF8); actualContent.Should().Be(fileContent); var unixFileInfo = new Mono.Unix.UnixFileInfo("test.txt"); }
public static IObservable <Stream> SafeOpenFileAsync(string path, FileMode mode, FileAccess access, FileShare share, IScheduler scheduler = null) { scheduler = scheduler ?? RxApp.TaskpoolScheduler; var ret = new AsyncSubject <Stream>(); Observable.Start(() => { try { var createModes = new[] { FileMode.Create, FileMode.CreateNew, FileMode.OpenOrCreate, }; #if !WINRT // NB: We do this (even though it's incorrect!) because // throwing lots of 1st chance exceptions makes debugging // obnoxious, as well as a bug in VS where it detects // exceptions caught by Observable.Start as Unhandled. if (!createModes.Contains(mode) && !File.Exists(path)) { ret.OnError(new FileNotFoundException()); return; } #endif #if SILVERLIGHT Observable.Start(() => new FileStream(path, mode, access, share, 4096), scheduler).Select(x => (Stream)x).Subscribe(ret); #elif MONO && !XAMARIN_MOBILE Observable.Start(() => { var ufi = new Mono.Unix.UnixFileInfo(path); return(ufi.Open(mode, access)); }, scheduler).Cast <Stream>().Subscribe(ret); #elif WINRT StorageFile.GetFileFromPathAsync(path).ToObservable() .SelectMany(x => x.OpenAsync(access == FileAccess.Read ? FileAccessMode.Read : FileAccessMode.ReadWrite).ToObservable()) .Select(x => x.AsStream()) .Subscribe(ret); #else Observable.Start(() => new FileStream(path, mode, access, share, 4096, false), scheduler).Cast <Stream>().Subscribe(ret); #endif } catch (Exception ex) { ret.OnError(ex); } }, scheduler); return(ret); }
protected override void Run() { var filesBasePath = Path.Combine(Path.GetDirectoryName(typeof(VSCodeDebuggerSession).Assembly.Location), "CoreClrAdaptor"); var fileInfo = new Mono.Unix.UnixFileInfo(Path.Combine(filesBasePath, "OpenDebugAD7")); var allExecutePermissions = (Mono.Unix.FileAccessPermissions.UserExecute | Mono.Unix.FileAccessPermissions.OtherExecute | Mono.Unix.FileAccessPermissions.GroupExecute); if ((fileInfo.FileAccessPermissions & allExecutePermissions) == allExecutePermissions) { return; //We already set } foreach (var file in Directory.GetFiles(filesBasePath, "*", SearchOption.AllDirectories)) { fileInfo = new Mono.Unix.UnixFileInfo(file); fileInfo.FileAccessPermissions = fileInfo.FileAccessPermissions | allExecutePermissions; } }
public static IObservable <FileStream> SafeOpenFileAsync(string path, FileMode mode, FileAccess access, FileShare share, IScheduler scheduler = null) { scheduler = scheduler ?? RxApp.TaskpoolScheduler; var ret = new AsyncSubject <FileStream>(); Observable.Start(() => { try { var createModes = new[] { FileMode.Create, FileMode.CreateNew, FileMode.OpenOrCreate, }; // NB: We do this (even though it's incorrect!) because // throwing lots of 1st chance exceptions makes debugging // obnoxious, as well as a bug in VS where it detects // exceptions caught by Observable.Start as Unhandled. if (!createModes.Contains(mode) && !File.Exists(path)) { ret.OnError(new FileNotFoundException()); return; } #if SILVERLIGHT Observable.Start(() => new FileStream(path, mode, access, share, 4096), scheduler).Subscribe(ret); #elif MONO Observable.Start(() => { var ufi = new Mono.Unix.UnixFileInfo(path); return(ufi.Open(mode, access)); }, scheduler).Cast <Stream>().Subscribe(ret); #else Observable.Start(() => new FileStream(path, mode, access, share, 4096, true), scheduler).Subscribe(ret); #endif } catch (Exception ex) { ret.OnError(ex); } }, scheduler); return(ret); }
/// <summary> /// Creates a symlink /// </summary> /// <param name="target">Link target</param> /// <param name="source">The relative path of the new link being created</param> public void MakeSymlink(string target, string source) { OperatingSystem os = Environment.OSVersion; switch (os.Platform) { case PlatformID.Win32NT: case PlatformID.Win32S: case PlatformID.Win32Windows: // Windows: we use CreateSymbolicLink from kernel32.dll int flag = Directory.Exists(target) ? UnsafeNativeMethods.SYMLINK_FLAG_DIRECTORY : 0; UnsafeNativeMethods.CreateSymbolicLink(source, target, flag); break; case PlatformID.MacOSX: case PlatformID.Unix: // Linux, macOS on Mono: use Mono.Posix Mono.Unix.UnixFileInfo f = new Mono.Unix.UnixFileInfo(target); f.CreateSymbolicLink(String.Format("\"{0}{1}{2}\"", RootDirectory, Path.DirectorySeparatorChar, source)); return; /** * // Linux, macOS on plain .NET: we run the ln command directly * Process p = new Process(); * p.StartInfo.UseShellExecute = false; * p.StartInfo.RedirectStandardOutput = true; * p.StartInfo.FileName = "ln"; * * StringBuilder sbArgs = new StringBuilder(@"-s ", 512); * sbArgs.AppendFormat("\"{0}\"", target); * sbArgs.Append(' '); * sbArgs.AppendFormat("\"{0}{1}{2}\"", RootDirectory, Path.DirectorySeparatorChar, source); * * p.StartInfo.Arguments = sbArgs.ToString(); * * p.Start(); * * // Read the output stream first and then wait. * string output = p.StandardOutput.ReadToEnd(); * /**/ break; } }
public bool HasPermission(FileSystemRights permissionFlag) { // // Windows if (Environment.OSVersion.Platform == PlatformID.Win32NT) { var fileInfo = new FileInfo(FullPath); var fileSecurity = fileInfo.GetAccessControl(); var usersSid = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null); var rules = fileSecurity.GetAccessRules(true, true, usersSid.GetType()).OfType <FileSystemAccessRule>(); return(rules.Where(r => r.FileSystemRights.HasFlag(permissionFlag)).Any()); } // // Linux AccessModes accessMode = 0; if (permissionFlag.HasFlag(FileSystemRights.Read)) { accessMode |= AccessModes.R_OK; } if (permissionFlag.HasFlag(FileSystemRights.Write)) { accessMode |= AccessModes.W_OK; } if (permissionFlag.HasFlag(FileSystemRights.ExecuteFile)) { accessMode |= AccessModes.X_OK; } var unixFileInfo = new Mono.Unix.UnixFileInfo(FullPath); return(unixFileInfo.CanAccess(accessMode)); }
private void OnChanged(object source, FileSystemEventArgs e) { if (InvalidFile(e.FullPath)) { return; } // Inspect the file if (getFileDetails && e.ChangeType != WatcherChangeTypes.Deleted) { // Switch to using Mono here if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { var unixFileInfo = new Mono.Unix.UnixFileInfo(e.FullPath); var result = unixFileInfo.FileAccessPermissions.ToString(); WriteChange(e, result); return; } // @TODO: Fix Windows and MacOS Inspection } WriteChange(e); customChangeHandler?.Invoke(e); }
public static string GetPathDetails(FileSystemInfo fs, string name) { string pathname = fs.FullName; #if !__MonoCS__ bool isDir = Directory.Exists(pathname); #else bool isDir = (fs.Attributes & System.IO.FileAttributes.Directory) != 0; #endif char d = isDir ? 'd' : '-'; string last = fs.LastWriteTime.ToString("MMM dd yyyy HH:mm"); string user = string.Empty; string group = string.Empty; string links = null; string permissions = "rwx"; long size = 0; #if __MonoCS__ Mono.Unix.UnixFileSystemInfo info; if (isDir) { info = new Mono.Unix.UnixDirectoryInfo(pathname); } else { info = new Mono.Unix.UnixFileInfo(pathname); } char ur = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.UserRead) != 0 ? 'r' : '-'; char uw = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.UserWrite) != 0 ? 'w' : '-'; char ux = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.UserExecute) != 0 ? 'x' : '-'; char gr = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.GroupRead) != 0 ? 'r' : '-'; char gw = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.GroupWrite) != 0 ? 'w' : '-'; char gx = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.GroupExecute) != 0 ? 'x' : '-'; char or = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.OtherRead) != 0 ? 'r' : '-'; char ow = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.OtherWrite) != 0 ? 'w' : '-'; char ox = (info.FileAccessPermissions & Mono.Unix.FileAccessPermissions.OtherExecute) != 0 ? 'x' : '-'; permissions = string.Format("{0}{1}{2}{3}{4}{5}{6}{7}{8}", ur, uw, ux, gr, gw, gx, or, ow, ox); user = info.OwnerUser.UserName; group = info.OwnerGroup.GroupName; links = info.LinkCount.ToString(); size = info.Length; if (info.IsSymbolicLink) { d = 's'; } #else if (isDir) { user = Directory.GetAccessControl(fs.FullName).GetOwner( typeof(System.Security.Principal.NTAccount)).ToString(); DirectoryInfo di = fs as DirectoryInfo; size = di.GetFileSystemInfos().Length; } else { user = File.GetAccessControl(fs.FullName).GetOwner( typeof(System.Security.Principal.NTAccount)).ToString(); FileInfo fi = fs as FileInfo; size = fi.Length; string[] execs = new string[] { "exe", "bat", "msi" }; char x = execs.Contains(fi.Extension.ToLower()) ? 'x' : '-'; char w = !fi.IsReadOnly ? 'w' : '-'; permissions = string.Format("r{0}{1}", w, x); } #endif string data = string.Format("{0}{1} {2,4} {3,8} {4,8} {5,9} {6,23} {7}", d, permissions, links, user, group, size, last, name); return(data); }
public static bool BuildPackage (IProgressMonitor monitor, MonoMacProject project, ConfigurationSelector conf, MonoMacPackagingSettings settings, FilePath target) { string bundleKey = settings.BundleSigningKey; string packageKey = settings.PackageSigningKey; if (settings.SignBundle || (settings.CreatePackage && settings.SignPackage)) { var identities = Keychain.GetAllSigningIdentities (); if (string.IsNullOrEmpty (bundleKey)) { bundleKey = identities.FirstOrDefault (k => k.StartsWith (MonoMacPackagingSettingsWidget.APPLICATION_PREFIX)); if (string.IsNullOrEmpty (bundleKey)) { monitor.ReportError ("Did not find default app signing key", null); return false; } else if (!identities.Any (k => k == bundleKey)) { monitor.ReportError ("Did not find app signing key in keychain", null); return false; } } if (string.IsNullOrEmpty (packageKey)) { packageKey = identities.FirstOrDefault (k => k.StartsWith (MonoMacPackagingSettingsWidget.INSTALLER_PREFIX)); if (string.IsNullOrEmpty (packageKey)) { monitor.ReportError ("Did not find default package signing key", null); return false; } else if (!identities.Any (k => k == packageKey)) { monitor.ReportError ("Did not find package signing key in keychain", null); return false; } } } if (project.NeedsBuilding (conf)) { BuildResult res = project.Build (monitor, conf); if (res.ErrorCount > 0) { foreach (BuildError e in res.Errors) monitor.ReportError (e.ToString (), null); monitor.ReportError (GettextCatalog.GetString ("The project failed to build."), null); return false; } } var cfg = (MonoMacProjectConfiguration) project.GetConfiguration (conf); FilePath tempDir = "/tmp/monomac-build-" + DateTime.Now.Ticks; FilePath workingApp = tempDir.Combine (cfg.AppDirectory.FileName); try { //user will have agreed to overwrite when they picked the target if (Directory.Exists (target)) Directory.Delete (target, true); else if (File.Exists (target)) File.Delete (target); monitor.BeginTask (GettextCatalog.GetString ("Creating app bundle"), 0); var files = Directory.GetFiles (cfg.AppDirectory, "*", SearchOption.AllDirectories); HashSet<string> createdDirs = new HashSet<string> (); foreach (FilePath f in files) { var rel = f.ToRelative (cfg.AppDirectory); var parentDir = rel.ParentDirectory; if (settings.IncludeMono) { if (parentDir.IsNullOrEmpty || parentDir == "." || parentDir == "Contents/MacOS") continue; var ext = rel.Extension; if (ext == ".mdb" || ext == ".exe" || ext == ".dll") continue; } if (monitor.IsCancelRequested) return false; if (createdDirs.Add (parentDir)) Directory.CreateDirectory (workingApp.Combine (parentDir)); monitor.Log.WriteLine (rel); File.Copy (f, workingApp.Combine (rel)); } monitor.EndTask (); if (settings.IncludeMono) { monitor.BeginTask (GettextCatalog.GetString ("Merging Mono into app bundle"), 0); var args = new ProcessArgumentBuilder (); switch (settings.LinkerMode){ case MonoMacLinkerMode.LinkNone: args.Add ("--nolink"); break; case MonoMacLinkerMode.LinkFramework: args.Add ("--linksdkonly"); break; case MonoMacLinkerMode.LinkAll: // nothing break; } args.Add ("-o"); args.AddQuoted (tempDir); args.Add ("-n"); args.AddQuoted (cfg.AppName); var assemblies = project.GetReferencedAssemblies (conf, true); foreach (var a in assemblies) { args.Add ("-a"); args.AddQuoted (a); } args.AddQuoted (cfg.CompiledOutputName); string mmpPath = Mono.Addins.AddinManager.CurrentAddin.GetFilePath ("mmp"); //FIXME: workaround for Mono.Addins losing the executable bit during packaging var mmpInfo = new Mono.Unix.UnixFileInfo (mmpPath); if ((mmpInfo.FileAccessPermissions & Mono.Unix.FileAccessPermissions.UserExecute) == 0) mmpInfo.FileAccessPermissions |= Mono.Unix.FileAccessPermissions.UserExecute; var psi = new ProcessStartInfo (mmpPath, args.ToString ()); if (MacBuildUtilities.ExecuteBuildCommand (monitor, psi) != 0) { monitor.ReportError ("Merging Mono failed", null); return false; } var plistFile = workingApp.Combine ("Contents", "Info.plist"); var plistDoc = new PlistDocument (); plistDoc.LoadFromXmlFile (plistFile); ((PlistDictionary)plistDoc.Root)["MonoBundleExecutable"] = cfg.CompiledOutputName.FileName; plistDoc.WriteToFile (plistFile); monitor.EndTask (); } //TODO: verify bundle details if for app store? if (settings.SignBundle) { monitor.BeginTask (GettextCatalog.GetString ("Signing app bundle"), 0); // Sign any dynamic libraries, before we sign the bundle var dylibs = Directory.GetFiles (workingApp, "*.dylib", SearchOption.AllDirectories); foreach (var dylib in dylibs){ if (!Sign (monitor, bundleKey, dylib)) return false; } if (!Sign (monitor, bundleKey, workingApp)) return false; monitor.EndTask (); } if (settings.CreatePackage) { monitor.BeginTask (GettextCatalog.GetString ("Creating installer"), 0); var args = new ProcessArgumentBuilder (); args.Add ("--component"); args.AddQuoted (workingApp); args.Add ("/Applications"); if (settings.SignPackage) { args.Add ("--sign"); args.AddQuoted (packageKey); } if (!settings.ProductDefinition.IsNullOrEmpty) { args.Add ("--product"); args.AddQuoted (settings.ProductDefinition); } args.AddQuoted (target); var psi = new ProcessStartInfo ("productbuild", args.ToString ()); try { if (MacBuildUtilities.ExecuteBuildCommand (monitor, psi) != 0) { monitor.ReportError ("Package creation failed", null); return false; } } catch (System.ComponentModel.Win32Exception) { monitor.ReportError ("productbuild not found", null); return false; } monitor.EndTask (); } else { Directory.Move (workingApp, target); } } finally { try { if (Directory.Exists (tempDir)) Directory.Delete (tempDir, true); } catch (Exception ex) { LoggingService.LogError ("Error removing temp directory", ex); } } return true; }
public static void Extract(this ZipArchive archive, string directoryName) { foreach (ZipArchiveEntry entry in archive.Entries) { string path = Path.Combine(directoryName, entry.FullName); if (entry.Length == 0 && (path.EndsWith("/", StringComparison.Ordinal) || path.EndsWith("\\", StringComparison.Ordinal))) { // Extract directory FileSystemHelpers.CreateDirectory(path); } else { FileInfoBase fileInfo = FileSystemHelpers.FileInfoFromFileName(path); if (!fileInfo.Directory.Exists) { fileInfo.Directory.Create(); } using (Stream zipStream = entry.Open(), fileStream = fileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) { zipStream.CopyTo(fileStream); } bool createSymLink = false; string originalFileName = string.Empty; if (!OSDetector.IsOnWindows()) { try { using (Stream fs = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { byte[] buffer = new byte[10]; fs.Read(buffer, 0, buffer.Length); fs.Close(); var str = System.Text.Encoding.Default.GetString(buffer); if (str.StartsWith("../")) { string fullPath = Path.GetFullPath(str); if (fullPath.StartsWith(directoryName)) { createSymLink = true; originalFileName = fullPath; } } } } catch (Exception ex) { throw new Exception("Could not identify symlinks in zip file : " + ex.ToString()); } } fileInfo.LastWriteTimeUtc = entry.LastWriteTime.ToUniversalTime().DateTime; if (createSymLink) { try { fileInfo.Delete(); Mono.Unix.UnixFileInfo unixFileInfo = new Mono.Unix.UnixFileInfo(originalFileName); unixFileInfo.CreateSymbolicLink(path); } catch (Exception ex) { throw new Exception("Could not create symlinks : " + ex.ToString()); } } } } }
public async static Task CheckForUpdatesAsync() { Utils.WriteLog("Checking for updates..."); try { if (Program.UserConfiguration != null) { Program.UserConfiguration.LastUpdateCheck = DateTime.UtcNow; Program.SaveConfig(); } var currentVersion = Program.IaBakVersion; var latestVersion = JsonConvert.DeserializeObject <UpdateCheckInfo>(await Utils.httpClient.GetStringAsync("https://iabak.shaman.io/latest-version.json")); if (Version.Parse(latestVersion.LatestVersion) <= currentVersion) { Utils.WriteLog("No updates found."); return; } Utils.WriteLog("Downloading update..."); var url = Environment.OSVersion.Platform switch { PlatformID.Win32NT => latestVersion.LatestVersionUrlWindowsX64, PlatformID.Unix => latestVersion.LatestVersionUrlLinuxX64, _ => throw new Exception("OS not supported: " + Environment.OSVersion.Platform) }; var location = Utils.GetApplicationPath(); var tempPath = Path.Combine(Path.GetTempPath(), "update-" + Path.GetFileName(location)); using var ms = new MemoryStream(); using (var stream = await Utils.httpClient.GetStreamAsync(url)) { await stream.CopyToAsync(ms); } ms.Seek(0, SeekOrigin.Begin); using (var zip = new ZipArchive(ms, ZipArchiveMode.Read)) { using var entry = zip.Entries.OrderByDescending(x => x.Length).First().Open(); using var temp = File.Create(tempPath); await entry.CopyToAsync(temp); } Utils.WriteLog("Replacing old executable..."); if (Environment.OSVersion.Platform == PlatformID.Win32NT) { File.Move(location, location + "." + DateTime.UtcNow.ToString("yyyyMMdd-HHmmss") + ".old"); File.Move(tempPath, location); } else { var chmod = new Mono.Unix.UnixFileInfo(location).FileAccessPermissions; new Mono.Unix.UnixFileInfo(tempPath).FileAccessPermissions = chmod; File.Move(tempPath, location, true); } Program.singleInstanceLock.Close(); var psi = new ProcessStartInfo(location); foreach (var item in Environment.GetCommandLineArgs().Skip(1)) { psi.ArgumentList.Add(item); } var ps = Process.Start(psi); ps.WaitForExit(); Environment.Exit(ps.ExitCode); } catch (Exception ex) { Utils.WriteLog("An error occured while checking for updates: " + Utils.GetMessageForException(ex)); } }
public static string CollectFilePermissionInformation(string filePath) { var bldr = new StringBuilder(); try { if (SIL.PlatformUtilities.Platform.IsWindows) { var currentUser = System.Security.Principal.WindowsIdentity.GetCurrent(); bldr.AppendLine($"current user is {currentUser.Name}"); var principal = new System.Security.Principal.WindowsPrincipal(currentUser); bool isInRoleWithAccess = false; bool accessDenied = false; bool accessAllowed = false; System.Security.AccessControl.FileSystemRights accessRights = System.Security.AccessControl.FileSystemRights.Write; var acl = File.GetAccessControl(filePath); var rules = acl.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount)); var sid = acl.GetOwner(typeof(System.Security.Principal.SecurityIdentifier)); var acct = sid.Translate(typeof(System.Security.Principal.NTAccount)) as System.Security.Principal.NTAccount; if (acct != null) { bldr.AppendLine($"owner of \"{filePath}\" is {acct.Value}"); } var fileAttributes = RobustFile.GetAttributes(filePath); bldr.AppendLine($"{filePath} current ReadOnly attribute of {filePath} is {(fileAttributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly}"); foreach (System.Security.AccessControl.AuthorizationRule rule in rules) { var fsAccessRule = rule as System.Security.AccessControl.FileSystemAccessRule; if (fsAccessRule == null) { continue; } if ((fsAccessRule.FileSystemRights & accessRights) > 0) { var ntAccount = rule.IdentityReference as System.Security.Principal.NTAccount; if (ntAccount == null) { continue; } if (principal.IsInRole(ntAccount.Value)) { if (fsAccessRule.AccessControlType == System.Security.AccessControl.AccessControlType.Deny) { bldr.AppendLine($"current user is denied write access to {filePath} by {ntAccount.Value}{(rule.IsInherited ? " (inherited)":"")}"); accessDenied = true; } if (fsAccessRule.AccessControlType == System.Security.AccessControl.AccessControlType.Allow) { bldr.AppendLine($"current user is allowed write access to {filePath} by {ntAccount.Value}{(rule.IsInherited ? " (inherited)":"")}"); accessAllowed = true; } isInRoleWithAccess = true; } } } if (isInRoleWithAccess) { if (!accessAllowed) { bldr.AppendLine($"current user is not explicitly allowed write access to {filePath}"); } if (!accessDenied) { bldr.AppendLine($"current user is not explicitly denied write access to {filePath}"); } } else { bldr.AppendLine($"current user is not explicitly given access to {filePath}"); } } else { var folder = Path.GetDirectoryName(filePath); var fileInfo = new Mono.Unix.UnixFileInfo(filePath); var dirInfo = new Mono.Unix.UnixDirectoryInfo(folder); var userInfo = Mono.Unix.UnixUserInfo.GetRealUser(); bldr.AppendLine($"current user is {userInfo.UserName}"); bldr.AppendLine($"owner of \"{filePath}\" is {fileInfo.OwnerUser.UserName}"); bldr.AppendLine($"permissions of \"{filePath}\" = {fileInfo.FileAccessPermissions.ToString()}"); bldr.AppendLine($"owner of \"{folder}\" is {dirInfo.OwnerUser.UserName}"); bldr.AppendLine($"permissions of \"{folder}\" = {dirInfo.FileAccessPermissions.ToString()}"); } } catch (Exception e) { bldr.AppendLine($"Caught exception {e} while trying to collect information about {filePath}"); } return(bldr.ToString()); }
public static bool BuildPackage(IProgressMonitor monitor, MonoMacProject project, ConfigurationSelector conf, MonoMacPackagingSettings settings, FilePath target) { string bundleKey = settings.BundleSigningKey; string packageKey = settings.PackageSigningKey; if (settings.SignBundle || (settings.CreatePackage && settings.SignPackage)) { var identities = Keychain.GetAllSigningIdentities(); if (string.IsNullOrEmpty(bundleKey)) { bundleKey = identities.FirstOrDefault(k => k.StartsWith(MonoMacPackagingSettingsWidget.APPLICATION_PREFIX)); if (string.IsNullOrEmpty(bundleKey)) { monitor.ReportError("Did not find default app signing key", null); return(false); } else if (!identities.Any(k => k == bundleKey)) { monitor.ReportError("Did not find app signing key in keychain", null); return(false); } } if (string.IsNullOrEmpty(packageKey)) { packageKey = identities.FirstOrDefault(k => k.StartsWith(MonoMacPackagingSettingsWidget.INSTALLER_PREFIX)); if (string.IsNullOrEmpty(packageKey)) { monitor.ReportError("Did not find default package signing key", null); return(false); } else if (!identities.Any(k => k == packageKey)) { monitor.ReportError("Did not find package signing key in keychain", null); return(false); } } } if (project.NeedsBuilding(conf)) { BuildResult res = project.Build(monitor, conf); if (res.ErrorCount > 0) { foreach (BuildError e in res.Errors) { monitor.ReportError(e.ToString(), null); } monitor.ReportError(GettextCatalog.GetString("The project failed to build."), null); return(false); } } var cfg = (MonoMacProjectConfiguration)project.GetConfiguration(conf); FilePath tempDir = "/tmp/monomac-build-" + DateTime.Now.Ticks; FilePath workingApp = tempDir.Combine(cfg.AppDirectory.FileName); try { //user will have agreed to overwrite when they picked the target if (Directory.Exists(target)) { Directory.Delete(target); } else if (File.Exists(target)) { File.Delete(target); } monitor.BeginTask(GettextCatalog.GetString("Creating app bundle"), 0); var files = Directory.GetFiles(cfg.AppDirectory, "*", SearchOption.AllDirectories); HashSet <string> createdDirs = new HashSet <string> (); foreach (FilePath f in files) { var rel = f.ToRelative(cfg.AppDirectory); var parentDir = rel.ParentDirectory; if (settings.IncludeMono) { if (parentDir.IsNullOrEmpty || parentDir == "." || parentDir == "Contents/MacOS") { continue; } var ext = rel.Extension; if (ext == ".mdb" || ext == ".exe" || ext == ".dll") { continue; } } if (monitor.IsCancelRequested) { return(false); } if (createdDirs.Add(parentDir)) { Directory.CreateDirectory(workingApp.Combine(parentDir)); } monitor.Log.WriteLine(rel); File.Copy(f, workingApp.Combine(rel)); } monitor.EndTask(); if (settings.IncludeMono) { monitor.BeginTask(GettextCatalog.GetString("Merging Mono into app bundle"), 0); var args = new ProcessArgumentBuilder(); switch (settings.LinkerMode) { case MonoMacLinkerMode.LinkNone: args.Add("--nolink"); break; case MonoMacLinkerMode.LinkFramework: args.Add("--linksdkonly"); break; case MonoMacLinkerMode.LinkAll: // nothing break; } args.Add("-o"); args.AddQuoted(tempDir); args.Add("-n"); args.AddQuoted(cfg.AppName); var assemblies = project.GetReferencedAssemblies(conf, true); foreach (var a in assemblies) { args.Add("-a"); args.AddQuoted(a); } args.AddQuoted(cfg.CompiledOutputName); string mmpPath = Mono.Addins.AddinManager.CurrentAddin.GetFilePath("mmp"); //FIXME: workaround for Mono.Addins losing the executable bit during packaging var mmpInfo = new Mono.Unix.UnixFileInfo(mmpPath); if ((mmpInfo.FileAccessPermissions & Mono.Unix.FileAccessPermissions.UserExecute) == 0) { mmpInfo.FileAccessPermissions |= Mono.Unix.FileAccessPermissions.UserExecute; } var psi = new ProcessStartInfo(mmpPath, args.ToString()); if (MacBuildUtilities.ExecuteBuildCommand(monitor, psi) != 0) { monitor.ReportError("Merging Mono failed", null); return(false); } var plistFile = workingApp.Combine("Contents", "Info.plist"); var plistDoc = new PlistDocument(); plistDoc.LoadFromXmlFile(plistFile); ((PlistDictionary)plistDoc.Root)["MonoBundleExecutable"] = cfg.CompiledOutputName.FileName; plistDoc.WriteToFile(plistFile); monitor.EndTask(); } //TODO: verify bundle details if for app store? if (settings.SignBundle) { monitor.BeginTask(GettextCatalog.GetString("Signing app bundle"), 0); // Sign any dynamic libraries, before we sign the bundle var dylibs = Directory.GetFiles(workingApp, "*.dylib", SearchOption.AllDirectories); foreach (var dylib in dylibs) { if (!Sign(monitor, bundleKey, dylib)) { return(false); } } if (!Sign(monitor, bundleKey, workingApp)) { return(false); } monitor.EndTask(); } if (settings.CreatePackage) { monitor.BeginTask(GettextCatalog.GetString("Creating installer"), 0); var args = new ProcessArgumentBuilder(); args.Add("--component"); args.AddQuoted(workingApp); args.Add("/Applications"); if (settings.SignPackage) { args.Add("--sign"); args.AddQuoted(packageKey); } if (!settings.ProductDefinition.IsNullOrEmpty) { args.Add("--product"); args.AddQuoted(settings.ProductDefinition); } args.AddQuoted(target); var psi = new ProcessStartInfo("productbuild", args.ToString()); try { if (MacBuildUtilities.ExecuteBuildCommand(monitor, psi) != 0) { monitor.ReportError("Package creation failed", null); return(false); } } catch (System.ComponentModel.Win32Exception) { monitor.ReportError("productbuild not found", null); return(false); } monitor.EndTask(); } else { Directory.Move(workingApp, target); } } finally { try { if (Directory.Exists(tempDir)) { Directory.Delete(tempDir, true); } } catch (Exception ex) { LoggingService.LogError("Error removing temp directory", ex); } } return(true); }