Example #1
0
        static StatFileHelper()
        {
            StatMethod = null;

            // Try to load the Mono Posix assembly. If it doesn't exist, we're on Windows.
            Assembly MonoPosix;

            try
            {
                MonoPosix = Assembly.Load("Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756");
            }
            catch (FileNotFoundException)
            {
                return;
            }
            Type SyscallType = MonoPosix.GetType("Mono.Unix.Native.Syscall");

            if (SyscallType == null)
            {
                throw new InvalidOperationException("Couldn't find Syscall type");
            }
            StatMethod = SyscallType.GetMethod("stat");
            if (StatMethod == null)
            {
                throw new InvalidOperationException("Couldn't find Mono.Unix.Native.Syscall.stat method");
            }
            Type StatType = MonoPosix.GetType("Mono.Unix.Native.Stat");

            if (StatType == null)
            {
                throw new InvalidOperationException("Couldn't find Mono.Unix.Native.Stat type");
            }
            StatModeField = StatType.GetField("st_mode");
            if (StatModeField == null)
            {
                throw new InvalidOperationException("Couldn't find Mono.Unix.Native.Stat.st_mode field");
            }
        }
Example #2
0
        static bool SetExecutablePermissions(string RootDir, IEnumerable <DependencyFile> Files)
        {
            // Try to load the Mono Posix assembly. If it doesn't exist, we're on Windows.
            Assembly MonoPosix;

            try
            {
                MonoPosix = Assembly.Load("Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756");
            }
            catch (FileNotFoundException)
            {
                return(true);
            }

            // Dynamically find all the types and methods for Syscall.stat and Syscall.chmod
            Type SyscallType = MonoPosix.GetType("Mono.Unix.Native.Syscall");

            if (SyscallType == null)
            {
                Log.WriteError("Couldn't find Syscall type");
                return(false);
            }
            MethodInfo StatMethod = SyscallType.GetMethod("stat");

            if (StatMethod == null)
            {
                Log.WriteError("Couldn't find Mono.Unix.Native.Syscall.stat method");
                return(false);
            }
            MethodInfo ChmodMethod = SyscallType.GetMethod("chmod");

            if (ChmodMethod == null)
            {
                Log.WriteError("Couldn't find Mono.Unix.Native.Syscall.chmod method");
                return(false);
            }
            Type StatType = MonoPosix.GetType("Mono.Unix.Native.Stat");

            if (StatType == null)
            {
                Log.WriteError("Couldn't find Mono.Unix.Native.Stat type");
                return(false);
            }
            FieldInfo StatModeField = StatType.GetField("st_mode");

            if (StatModeField == null)
            {
                Log.WriteError("Couldn't find Mono.Unix.Native.Stat.st_mode field");
                return(false);
            }

            // Update all the executable permissions
            const uint ExecutableBits = (1 << 0) | (1 << 3) | (1 << 6);

            foreach (DependencyFile File in Files)
            {
                if (File.IsExecutable)
                {
                    string FileName = Path.Combine(RootDir, File.Name);

                    // Call Syscall.stat(Filename, out Stat)
                    object[] StatArgs   = new object[] { FileName, null };
                    int      StatResult = (int)StatMethod.Invoke(null, StatArgs);
                    if (StatResult != 0)
                    {
                        Log.WriteError("Stat() call for {0} failed with error {1}", File.Name, StatResult);
                        return(false);
                    }

                    // Get the current permissions
                    uint CurrentPermissions = (uint)StatModeField.GetValue(StatArgs[1]);

                    // The desired permissions should be executable for every read group
                    uint NewPermissions = CurrentPermissions | ((CurrentPermissions >> 2) & ExecutableBits);

                    // Update them if they don't match
                    if (CurrentPermissions != NewPermissions)
                    {
                        int ChmodResult = (int)ChmodMethod.Invoke(null, new object[] { FileName, NewPermissions });
                        if (ChmodResult != 0)
                        {
                            Log.WriteError("Chmod() call for {0} failed with error {1}", File.Name, ChmodResult);
                            return(false);
                        }
                    }
                }
            }
            return(true);
        }