github.com/remobjects/goldbaselibrary@v0.0.0-20230924164425-d458680a936b/Source/Gold/os.cs (about)

     1  using go.builtin;
     2  #if ECHOES
     3  using System.Security.Cryptography.X509Certificates;
     4  using System.IO;
     5  #endif
     6  
     7  
     8  namespace go.math {
     9  	namespace rand {
    10  		partial class rngSource: global::go.math.rand.Source {}
    11  		partial class lockedSource: global::go.math.rand.Source {}
    12  	}
    13  }
    14  
    15  namespace go.net {
    16  	public partial interface Conn: go.io.ReadWriteCloser, go.io.Reader, go.io.Writer {}
    17  
    18  	//public partial class pipe: net.Conn { }
    19  
    20  }
    21  namespace go.crypto {
    22  	namespace x509 {
    23  		#if ECHOES || (ISLAND && WINDOWS)
    24  		public partial class __Global {
    25  			public static (Memory<CertPool>, go.builtin.error) loadSystemRoots()
    26  			{
    27  				#if ECHOES
    28  				var lRoots = go.crypto.x509.NewCertPool();
    29  				X509Store lStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
    30  				lStore.Open(OpenFlags.ReadOnly);
    31  				foreach(var lCertificate in lStore.Certificates)
    32  				{
    33  					var lRawCert = lCertificate.RawData;
    34  					var lNewData = new byte[lRawCert.Length];
    35  					Array.Copy(lRawCert, lNewData, lRawCert.Length);
    36  					var (lNewCert, lErr) = go.crypto.x509.ParseCertificate(lRawCert);
    37  					if (lErr == null)
    38  					{
    39  						//lRoots.AddCert(lNewCert);
    40  						CertPool.AddCert(lRoots, lNewCert);
    41  					}
    42  				}
    43  				lStore.Close();
    44  
    45  				return (lRoots, null);
    46  				#else
    47  				return (null, null);
    48  				#endif
    49  			}
    50  		}
    51  		public partial class Certificate {
    52  			public (Slice<Slice<Memory<crypto.x509.Certificate>>>, go.builtin.error) systemVerify(Memory<go.crypto.x509.VerifyOptions> opts)
    53  			{
    54  				#if ECHOES
    55  				var lHasDNSName = (opts != null) && (opts.DNSName.Length > 0);
    56  				X509Certificate2 lCert = new X509Certificate2(this.Raw);
    57  				X509Chain lChain = new X509Chain();
    58  				lChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
    59  				if (lChain.Build(lCert))
    60  				{
    61  					var lResult = new Slice<Slice<Memory<go.crypto.x509.Certificate>>>(1);
    62  					var lNewChain = new Slice<Memory<go.crypto.x509.Certificate>>(lChain.ChainElements.Count);
    63  					for (var i = 0; i < lChain.ChainElements.Count; i++)
    64  					{
    65  						var lCertificate = lChain.ChainElements[i].Certificate;
    66  						var lRawCert = lCertificate.RawData;
    67  						var lNewData = new byte[lRawCert.Length];
    68  						Array.Copy(lRawCert, lNewData, lRawCert.Length);
    69  						var (lNewCert, lErr) = go.crypto.x509.ParseCertificate(lRawCert);
    70  						if (lErr == null)
    71  						{
    72  							lNewChain[i] = lNewCert;
    73  						}
    74  					}
    75  					lResult[0] = lNewChain;
    76  					return(lResult, null);
    77  				}
    78  				else
    79  				{
    80  					return(null, go.errors.New("Wrong certificate"));
    81  				}
    82  				#else
    83  				return (null, null);
    84  				#endif
    85  			}
    86  		}
    87  		#endif
    88  	}
    89  	namespace tls {
    90  		public partial class Conn: go.net.Conn { }
    91  	}
    92  }
    93  
    94  
    95  namespace go.image {
    96  	namespace png {
    97  		public partial class encoder: go.io.Writer {}
    98  	}
    99  }
   100  
   101  
   102  namespace go.path
   103  {
   104  	namespace filepath {
   105  
   106  		static Slice<go.builtin.string> splitList(string s) {
   107  			#if ECHOES
   108  			return go.builtin.string.PlatformStringArrayToGoSlice(s.Split(new[] {go.os.PathListSeparator}, StringSplitOptions.RemoveEmptyEntries));
   109  			#else
   110  			return go.builtin.string.PlatformStringArrayToGoSlice(s.Split(go.os.PathListSeparator, true));
   111  			#endif
   112  		}
   113  
   114  		static (string, error) evalSymlinks(string s) {
   115  			return (null, go.errors.New("Not supported"));
   116  		}
   117  
   118  		static go.builtin.string join(Slice<go.builtin.string> s) {
   119  			return String.Join(go.os.PathSeparator.ToString(), s.ToArray());
   120  		}
   121  
   122  		static (string, error) abs(string s) {
   123  			try {
   124  				#if ECHOES
   125  				return (System.IO.Path.GetFullPath(s), null);
   126  				#else
   127  				return (Path.GetFullPath(s), null);
   128  				#endif
   129  			} catch(Exception e) {
   130  				return (null, go.errors.New(e.Message));
   131  			}
   132  		}
   133  
   134  		public static bool IsAbs(string s) {
   135  			return abs(s)[0] == s;
   136  		}
   137  	}
   138  
   139  }
   140  
   141  namespace go.os {
   142  
   143  	public go.builtin.error Rename(go.builtin.string oldpath, go.builtin.string newpath)
   144  	{
   145  		try
   146  		{
   147  			#if ECHOES
   148  			global::System.IO.File.Move(oldpath, newpath);
   149  			#else
   150  			new global::System.File(oldpath).Rename(newpath);
   151  			#endif
   152  		} catch(Exception e) {
   153  			return go.errors.New(e.Message);
   154  		}
   155  	}
   156  
   157  	bool isExist(error err){
   158  		throw new NotImplementedException();
   159  	}
   160  
   161  	bool isNotExist(error err){
   162  		throw new NotImplementedException();
   163  	}
   164  
   165  
   166  	bool isPermission(error err) {
   167  		throw new NotImplementedException();
   168  	}
   169  
   170  	public (string, go.builtin.error) UserHomeDir() {
   171  		#if ECHOES
   172  		return (System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile), null);
   173  		#else
   174  		return (Environment.UserHomeFolder().FullName, null);
   175  		#endif
   176  	}
   177  
   178  
   179  	[ValueTypeSemantics]
   180  	public class ProcessState {
   181  		private ProcessType fProc;
   182  
   183  		public ProcessState() {}
   184  		public ProcessState(
   185  		ProcessType         proc) {
   186  			fProc = proc;
   187  		}
   188  
   189  		public
   190  		int Pid()
   191  		{
   192  			return fProc.Id;
   193  		}
   194  
   195  		public bool exited()
   196  		{
   197  			#if ECHOES
   198  			return fProc.HasExited;
   199  			#else
   200  			return !fProc.IsRunning;
   201  			#endif
   202  		}
   203  
   204  		public bool success() { return exited() && (fProc.ExitCode == 0); }
   205  
   206  		public object sys() { return fProc; }
   207  		public object sysUsage() { return fProc; }
   208  		public string String()
   209  		{
   210  			#if ECHOES
   211  			return fProc.StartInfo.FileName;
   212  			#else
   213  			return fProc.Command;
   214  			#endif
   215  		}
   216  
   217  		public int ExitCode(){ return fProc.ExitCode; }
   218  		public time.Duration userTime() {
   219  			#if ECHOES
   220  			return (time.Duration)fProc.UserProcessorTime.Ticks * 100;
   221  			#else
   222  			throw new NotImplementedException();
   223  			#endif
   224  		}
   225  
   226  		public time.Duration systemTime() {
   227  			#if ECHOES
   228  			return (time.Duration)fProc.TotalProcessorTime.Ticks * 100;
   229  			#else
   230  			throw new NotImplementedException();
   231  			#endif
   232  		}
   233  
   234  	}
   235  
   236  	namespace exec {
   237  		public partial class __Global {
   238  			public static (go.builtin.string, builtin.error) LookPath(go.builtin.string file) {
   239  				#if ECHOES
   240  				if (System.IO.File.Exists(file)) return (file, null);
   241  				foreach (var el in go.strings.Split(go.os.Getenv("PATH"), System.IO.Path.PathSeparator)) {
   242  					var p = System.IO.Path.Combine(el[1], file);
   243  					if (System.IO.File.Exists(p)) return (p, null);
   244  				}
   245  				#else
   246  				if (new RemObjects.Elements.System.File(file).Exists()) return (file, null);
   247  				foreach (var el in go.strings.Split(go.os.Getenv("PATH"), Path.DirectorySeparatorChar)) {
   248  					var p = RemObjects.Elements.System.Path.Combine(el[1], file);
   249  					if (new RemObjects.Elements.System.File(p).Exists()) return (p, null);
   250  				}
   251  				#endif
   252  				return ("", go.errors.New("Could not find file"));
   253  			}
   254  			public static Memory<Cmd> Command(string name, params go.builtin.string[] args) {
   255  				return new Cmd {
   256  					Path = name,
   257  					Args = args
   258  				};
   259  			}
   260  		}
   261  
   262  		[ValueTypeSemantics]
   263  		public partial class Cmd {
   264  			public go.builtin.string Path;
   265  			public Slice<go.builtin.string> Args;
   266  			public Slice<go.builtin.string> Env;
   267  			public go.builtin.string Dir;
   268  			public io.Reader Stdin;
   269  			public io.Writer Stdout;
   270  			public io.Writer Stderr;
   271  
   272  			public Slice<Memory<os.File>> ExtraFiles; // not used!
   273  			public Memory<os.Process> Process;
   274  			public Memory<os.ProcessState> ProcessState;
   275  
   276  			public builtin.error Start() {
   277  				var pp = StartProcess(Path, Args, (Memory<ProcAttr>)new ProcAttr {
   278  					Dir = Dir,
   279  					Env = Env
   280  				});
   281  				if (pp.Item2 != null) return pp.Item2;
   282  				Process = pp.Item1;
   283  				ProcessState = new Memory<os.ProcessState>(new os.ProcessState(pp.Item1.Process));
   284  				return null;
   285  			}
   286  
   287  			public builtin.error Run() {
   288  				var lRes = Start();
   289  				if (lRes != null)
   290  					return lRes;
   291  
   292  				return Wait();
   293  			}
   294  
   295  			public builtin.error Wait() {
   296  				try {
   297  					Process.Wait();
   298  				} catch(Exception e){
   299  					return go.errors.New(e.Message);
   300  				}
   301  			}
   302  
   303  			public (go.io.ReadCloser, go.builtin.error) StdoutPipe() {
   304  				#if ECHOES
   305  				return (new ReadCloserImpl(Process.Process.StandardOutput.BaseStream), null);
   306  				#else
   307  				return (new ReadCloserImpl(Process.Process.StandardOutputStream), null);
   308  				#endif
   309  			}
   310  
   311  			public (go.io.WriteCloser, go.builtin.error) StdinPipe() {
   312  				return (null, go.errors.New("not implemented"));
   313  			}
   314  
   315  			public (Slice<byte>, go.builtin.error) Output() {
   316  				var lRes = Run();
   317  				if (lRes != null)
   318  					return (null, lRes);
   319  
   320  				#if ECHOES
   321  				var lOutput = System.Text.Encoding.UTF8.GetBytes(Process.Process.StandardOutput.ReadToEnd());
   322  				#else
   323  				var lOutput = Encoding.UTF8.GetBytes(Process.Process.StandardOutput);
   324  				#endif
   325  
   326  				return (lOutput, null);
   327  			}
   328  		}
   329  
   330  		partial class ReadCloserImpl: go.io.ReadCloser {
   331  			private Stream fs;
   332  
   333  			public ReadCloserImpl(Stream newFs) {
   334  				fs = newFs;
   335  			}
   336  
   337  			public (go.builtin.int, go.builtin.error) Read(Slice<go.builtin.byte> p) {
   338  				return (fs.Read(p.fArray, p.fStart, p.fCount), null);
   339  			}
   340  
   341  			public go.builtin.error Close() {
   342  				fs.Close();
   343  				return null;
   344  			}
   345  		}
   346  
   347  
   348  		partial class WriteCloserImpl: go.io.WriteCloser {
   349  			private Stream fs;
   350  
   351  			public WriteCloserImpl(Stream newFs) {
   352  				fs = newFs;
   353  			}
   354  
   355  			public (go.builtin.int, go.builtin.error) Write(Slice<go.builtin.byte> p) {
   356  				fs.Write(p.fArray, p.fStart, p.fCount);
   357  				return (p.fCount, null);
   358  			}
   359  
   360  			public go.builtin.error Close() {
   361  				fs.Close();
   362  				return null;
   363  			}
   364  		}
   365  	}
   366  }