[Mono.Posix] Add wrappers for struct sockaddr_*
[mono.git] / mcs / class / Mono.Posix / Mono.Unix.Native / NativeConvert.cs
1 /*
2  * This file was automatically generated by make-map from Mono.Posix.dll.
3  *
4  * DO NOT MODIFY.
5  */
6
7 using System;
8 using System.IO;
9 using System.Runtime.InteropServices;
10 using Mono.Unix.Native;
11
12 namespace Mono.Unix.Native {
13
14         [CLSCompliant (false)]
15         public sealed /* static */ partial class NativeConvert
16         {
17                 //
18                 // Non-generated exports
19                 //
20 #if !MONODROID
21                 [DllImport (LIB, EntryPoint="Mono_Posix_FromRealTimeSignum")]
22                 private static extern int FromRealTimeSignum (Int32 offset, out Int32 rval);
23 #endif
24                 // convert a realtime signal to os signal
25                 public static int FromRealTimeSignum (RealTimeSignum sig)
26                 {
27                         int sigNum;
28                         if (FromRealTimeSignum (sig.Offset, out sigNum) == -1)
29                                 ThrowArgumentException (sig.Offset);
30                         return sigNum;
31                 }
32
33                 // convert an offset to an rt signum
34                 public static RealTimeSignum ToRealTimeSignum (int offset)
35                 {
36                         return new RealTimeSignum (offset);
37                 }
38
39                 // convert from octal representation.
40                 public static FilePermissions FromOctalPermissionString (string value)
41                 {
42                         uint n = Convert.ToUInt32 (value, 8);
43                         return ToFilePermissions (n);
44                 }
45
46                 public static string ToOctalPermissionString (FilePermissions value)
47                 {
48                         string s = Convert.ToString ((int) (value & ~FilePermissions.S_IFMT), 8);
49                         return new string ('0', 4-s.Length) + s;
50                 }
51
52                 public static FilePermissions FromUnixPermissionString (string value)
53                 {
54                         if (value == null)
55                                 throw new ArgumentNullException ("value");
56                         if (value.Length != 9 && value.Length != 10)
57                                 throw new ArgumentException ("value", "must contain 9 or 10 characters");
58
59                         int i = 0;
60                         FilePermissions perms = new FilePermissions ();
61
62                         if (value.Length == 10) {
63                                 perms |= GetUnixPermissionDevice (value [i]);
64                                 ++i;
65                         }
66
67                         perms |= GetUnixPermissionGroup (
68                                 value [i++], FilePermissions.S_IRUSR,
69                                 value [i++], FilePermissions.S_IWUSR,
70                                 value [i++], FilePermissions.S_IXUSR,
71                                 's', 'S', FilePermissions.S_ISUID);
72
73                         perms |= GetUnixPermissionGroup (
74                                 value [i++], FilePermissions.S_IRGRP,
75                                 value [i++], FilePermissions.S_IWGRP,
76                                 value [i++], FilePermissions.S_IXGRP,
77                                 's', 'S', FilePermissions.S_ISGID);
78
79                         perms |= GetUnixPermissionGroup (
80                                 value [i++], FilePermissions.S_IROTH,
81                                 value [i++], FilePermissions.S_IWOTH,
82                                 value [i++], FilePermissions.S_IXOTH,
83                                 't', 'T', FilePermissions.S_ISVTX);
84
85                         return perms;
86                 }
87
88                 private static FilePermissions GetUnixPermissionDevice (char value)
89                 {
90                         switch (value) {
91                         case 'd': return FilePermissions.S_IFDIR;
92                         case 'c': return FilePermissions.S_IFCHR;
93                         case 'b': return FilePermissions.S_IFBLK;
94                         case '-': return FilePermissions.S_IFREG;
95                         case 'p': return FilePermissions.S_IFIFO;
96                         case 'l': return FilePermissions.S_IFLNK;
97                         case 's': return FilePermissions.S_IFSOCK;
98                         }
99                         throw new ArgumentException ("value", "invalid device specification: " + 
100                                 value);
101                 }
102
103                 private static FilePermissions GetUnixPermissionGroup (
104                         char read, FilePermissions readb, 
105                         char write, FilePermissions writeb, 
106                         char exec, FilePermissions execb,
107                         char xboth, char xbitonly, FilePermissions xbit)
108                 {
109                         FilePermissions perms = new FilePermissions ();
110                         if (read == 'r')
111                                 perms |= readb;
112                         if (write == 'w')
113                                 perms |= writeb;
114                         if (exec == 'x')
115                                 perms |= execb;
116                         else if (exec == xbitonly)
117                                 perms |= xbit;
118                         else if (exec == xboth)
119                                 perms |= (execb | xbit);
120                         return perms;
121                 }
122
123                 // Create ls(1) drwxrwxrwx permissions display
124                 public static string ToUnixPermissionString (FilePermissions value)
125                 {
126                         char [] access = new char[] {
127                                 '-',            // device
128                                 '-', '-', '-',  // owner
129                                 '-', '-', '-',  // group
130                                 '-', '-', '-',  // other
131                         };
132                         bool have_device = true;
133                         switch (value & FilePermissions.S_IFMT) {
134                                 case FilePermissions.S_IFDIR:   access [0] = 'd'; break;
135                                 case FilePermissions.S_IFCHR:   access [0] = 'c'; break;
136                                 case FilePermissions.S_IFBLK:   access [0] = 'b'; break;
137                                 case FilePermissions.S_IFREG:   access [0] = '-'; break;
138                                 case FilePermissions.S_IFIFO:   access [0] = 'p'; break;
139                                 case FilePermissions.S_IFLNK:   access [0] = 'l'; break;
140                                 case FilePermissions.S_IFSOCK:  access [0] = 's'; break;
141                                 default:                        have_device = false; break;
142                         }
143                         SetUnixPermissionGroup (value, access, 1, 
144                                 FilePermissions.S_IRUSR, FilePermissions.S_IWUSR, FilePermissions.S_IXUSR,
145                                 's', 'S', FilePermissions.S_ISUID);
146                         SetUnixPermissionGroup (value, access, 4, 
147                                 FilePermissions.S_IRGRP, FilePermissions.S_IWGRP, FilePermissions.S_IXGRP,
148                                 's', 'S', FilePermissions.S_ISGID);
149                         SetUnixPermissionGroup (value, access, 7, 
150                                 FilePermissions.S_IROTH, FilePermissions.S_IWOTH, FilePermissions.S_IXOTH,
151                                 't', 'T', FilePermissions.S_ISVTX);
152                         return have_device 
153                                 ? new string (access)
154                                 : new string (access, 1, 9);
155                 }
156
157                 private static void SetUnixPermissionGroup (FilePermissions value,
158                         char[] access, int index,
159                         FilePermissions read, FilePermissions write, FilePermissions exec,
160                         char both, char setonly, FilePermissions setxbit)
161                 {
162                         if (UnixFileSystemInfo.IsSet (value, read))
163                                 access [index] = 'r';
164                         if (UnixFileSystemInfo.IsSet (value, write))
165                                 access [index+1] = 'w';
166                         access [index+2] = GetSymbolicMode (value, exec, both, setonly, setxbit);
167                 }
168
169                 // Implement the GNU ls(1) permissions spec; see `info coreutils ls`,
170                 // section 10.1.2, the `-l' argument information.
171                 private static char GetSymbolicMode (FilePermissions value, 
172                         FilePermissions xbit, char both, char setonly, FilePermissions setxbit)
173                 {
174                         bool is_x  = UnixFileSystemInfo.IsSet (value, xbit);
175                         bool is_sx = UnixFileSystemInfo.IsSet (value, setxbit);
176                         
177                         if (is_x && is_sx)
178                                 return both;
179                         if (is_sx)
180                                 return setonly;
181                         if (is_x)
182                                 return 'x';
183                         return '-';
184                 }
185
186                 public static readonly DateTime UnixEpoch =
187                         new DateTime (year:1970, month:1, day:1, hour:0, minute:0, second:0, kind:DateTimeKind.Utc);
188                 public static readonly DateTime LocalUnixEpoch = 
189                         new DateTime (1970, 1, 1);
190                 public static readonly TimeSpan LocalUtcOffset = 
191                         TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.UtcNow);
192
193                 public static DateTime ToDateTime (long time)
194                 {
195                         return FromTimeT (time);
196                 }
197
198                 public static DateTime ToDateTime (long time, long nanoTime)
199                 {
200                         return FromTimeT (time).AddMilliseconds (nanoTime / 1000);
201                 }
202
203                 public static long FromDateTime (DateTime time)
204                 {
205                         return ToTimeT (time);
206                 }
207
208                 public static DateTime FromTimeT (long time)
209                 {
210                         return UnixEpoch.AddSeconds (time).ToLocalTime ();
211                 }
212
213                 public static long ToTimeT (DateTime time)
214                 {
215                         if (time.Kind == DateTimeKind.Unspecified)
216                                 throw new ArgumentException ("DateTimeKind.Unspecified is not supported. Use Local or Utc times.", "time");
217
218                         if (time.Kind == DateTimeKind.Local)
219                                 time = time.ToUniversalTime ();
220
221                         return (long) (time - UnixEpoch).TotalSeconds;
222                 }
223
224                 public static OpenFlags ToOpenFlags (FileMode mode, FileAccess access)
225                 {
226                         OpenFlags flags = 0;
227                         switch (mode) {
228                         case FileMode.CreateNew:
229                                 flags = OpenFlags.O_CREAT | OpenFlags.O_EXCL;
230                                 break;
231                         case FileMode.Create:
232                                 flags = OpenFlags.O_CREAT | OpenFlags.O_TRUNC;
233                                 break;
234                         case FileMode.Open:
235                                 // do nothing
236                                 break;
237                         case FileMode.OpenOrCreate:
238                                 flags = OpenFlags.O_CREAT;
239                                 break;
240                         case FileMode.Truncate:
241                                 flags = OpenFlags.O_TRUNC;
242                                 break;
243                         case FileMode.Append:
244                                 flags = OpenFlags.O_APPEND;
245                                 break;
246                         default:
247                                 throw new ArgumentException (Locale.GetText ("Unsupported mode value"), "mode");
248                         }
249
250                         // Is O_LARGEFILE supported?
251                         int _v;
252                         if (TryFromOpenFlags (OpenFlags.O_LARGEFILE, out _v))
253                                 flags |= OpenFlags.O_LARGEFILE;
254
255                         switch (access) {
256                         case FileAccess.Read:
257                                 flags |= OpenFlags.O_RDONLY;
258                                 break;
259                         case FileAccess.Write:
260                                 flags |= OpenFlags.O_WRONLY;
261                                 break;
262                         case FileAccess.ReadWrite:
263                                 flags |= OpenFlags.O_RDWR;
264                                 break;
265                         default:
266                                 throw new ArgumentOutOfRangeException (Locale.GetText ("Unsupported access value"), "access");
267                         }
268
269                         return flags;
270                 }
271
272                 public static string ToFopenMode (FileAccess access)
273                 {
274                         switch (access) {
275                                 case FileAccess.Read:       return "rb";
276                                 case FileAccess.Write:      return "wb";
277                                 case FileAccess.ReadWrite:  return "r+b";
278                                 default:                    throw new ArgumentOutOfRangeException ("access");
279                         }
280                 }
281
282                 public static string ToFopenMode (FileMode mode)
283                 {
284                         switch (mode) {
285                                 case FileMode.CreateNew: case FileMode.Create:        return "w+b";
286                                 case FileMode.Open:      case FileMode.OpenOrCreate:  return "r+b";
287                                 case FileMode.Truncate: return "w+b";
288                                 case FileMode.Append:   return "a+b";
289                                 default:                throw new ArgumentOutOfRangeException ("mode");
290                         }
291                 }
292
293                 private static readonly string[][] fopen_modes = new string[][]{
294                         //                                         Read                       Write ReadWrite
295                         /*    FileMode.CreateNew: */  new string[]{"Can't Read+Create",       "wb", "w+b"},
296                         /*       FileMode.Create: */  new string[]{"Can't Read+Create",       "wb", "w+b"},
297                         /*         FileMode.Open: */  new string[]{"rb",                      "wb", "r+b"},
298                         /* FileMode.OpenOrCreate: */  new string[]{"rb",                      "wb", "r+b"},
299                         /*     FileMode.Truncate: */  new string[]{"Cannot Truncate and Read","wb", "w+b"},
300                         /*       FileMode.Append: */  new string[]{"Cannot Append and Read",  "ab", "a+b"},
301                 };
302
303                 public static string ToFopenMode (FileMode mode, FileAccess access)
304                 {
305                         int fm = -1, fa = -1;
306                         switch (mode) {
307                                 case FileMode.CreateNew:    fm = 0; break;
308                                 case FileMode.Create:       fm = 1; break;
309                                 case FileMode.Open:         fm = 2; break;
310                                 case FileMode.OpenOrCreate: fm = 3; break;
311                                 case FileMode.Truncate:     fm = 4; break;
312                                 case FileMode.Append:       fm = 5; break;
313                         }
314                         switch (access) {
315                                 case FileAccess.Read:       fa = 0; break;
316                                 case FileAccess.Write:      fa = 1; break;
317                                 case FileAccess.ReadWrite:  fa = 2; break;
318                         }
319
320                         if (fm == -1)
321                                 throw new ArgumentOutOfRangeException ("mode");
322                         if (fa == -1)
323                                 throw new ArgumentOutOfRangeException ("access");
324
325                         string fopen_mode = fopen_modes [fm][fa];
326                         if (fopen_mode [0] != 'r' && fopen_mode [0] != 'w' && fopen_mode [0] != 'a')
327                                 throw new ArgumentException (fopen_mode);
328                         return fopen_mode;
329                 }
330
331                 [DllImport (LIB, EntryPoint="Mono_Posix_FromStat")]
332                 private static extern int FromStat (ref Stat source, IntPtr destination);
333
334                 public static bool TryCopy (ref Stat source, IntPtr destination)
335                 {
336                         return FromStat (ref source, destination) == 0;
337                 }
338
339                 [DllImport (LIB, EntryPoint="Mono_Posix_ToStat")]
340                 private static extern int ToStat (IntPtr source, out Stat destination);
341
342                 public static bool TryCopy (IntPtr source, out Stat destination)
343                 {
344                         return ToStat (source, out destination) == 0;
345                 }
346
347                 [DllImport (LIB, EntryPoint="Mono_Posix_FromStatvfs")]
348                 private static extern int FromStatvfs (ref Statvfs source, IntPtr destination);
349
350                 public static bool TryCopy (ref Statvfs source, IntPtr destination)
351                 {
352                         return FromStatvfs (ref source, destination) == 0;
353                 }
354
355                 [DllImport (LIB, EntryPoint="Mono_Posix_ToStatvfs")]
356                 private static extern int ToStatvfs (IntPtr source, out Statvfs destination);
357
358                 public static bool TryCopy (IntPtr source, out Statvfs destination)
359                 {
360                         return ToStatvfs (source, out destination) == 0;
361                 }
362
363                 [DllImport (LIB, EntryPoint="Mono_Posix_FromInAddr")]
364                 private static extern int FromInAddr (ref InAddr source, IntPtr destination);
365
366                 public static bool TryCopy (ref InAddr source, IntPtr destination)
367                 {
368                         return FromInAddr (ref source, destination) == 0;
369                 }
370
371                 [DllImport (LIB, EntryPoint="Mono_Posix_ToInAddr")]
372                 private static extern int ToInAddr (IntPtr source, out InAddr destination);
373
374                 public static bool TryCopy (IntPtr source, out InAddr destination)
375                 {
376                         return ToInAddr (source, out destination) == 0;
377                 }
378
379                 [DllImport (LIB, EntryPoint="Mono_Posix_FromIn6Addr")]
380                 private static extern int FromIn6Addr (ref In6Addr source, IntPtr destination);
381
382                 public static bool TryCopy (ref In6Addr source, IntPtr destination)
383                 {
384                         return FromIn6Addr (ref source, destination) == 0;
385                 }
386
387                 [DllImport (LIB, EntryPoint="Mono_Posix_ToIn6Addr")]
388                 private static extern int ToIn6Addr (IntPtr source, out In6Addr destination);
389
390                 public static bool TryCopy (IntPtr source, out In6Addr destination)
391                 {
392                         return ToIn6Addr (source, out destination) == 0;
393                 }
394
395                 public static InAddr ToInAddr (System.Net.IPAddress address)
396                 {
397                         if (address == null)
398                                 throw new ArgumentNullException ("address");
399                         if (address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork)
400                                 throw new ArgumentException ("address", "address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork");
401                         return new InAddr (address.GetAddressBytes ());
402                 }
403
404                 public static System.Net.IPAddress ToIPAddress (InAddr address)
405                 {
406                         var bytes = new byte[4];
407                         address.CopyTo (bytes, 0);
408                         return new System.Net.IPAddress (bytes);
409                 }
410
411                 public static In6Addr ToIn6Addr (System.Net.IPAddress address)
412                 {
413                         if (address == null)
414                                 throw new ArgumentNullException ("address");
415                         if (address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6)
416                                 throw new ArgumentException ("address", "address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6");
417                         return new In6Addr (address.GetAddressBytes ());
418                 }
419
420                 public static System.Net.IPAddress ToIPAddress (In6Addr address)
421                 {
422                         var bytes = new byte[16];
423                         address.CopyTo (bytes, 0);
424                         return new System.Net.IPAddress (bytes);
425                 }
426
427                 [DllImport (LIB, EntryPoint="Mono_Posix_FromSockaddr")]
428                 private static extern unsafe int FromSockaddr (_SockaddrHeader* source, IntPtr destination);
429
430                 public static unsafe bool TryCopy (Sockaddr source, IntPtr destination)
431                 {
432                         if (source == null)
433                                 throw new ArgumentNullException ("source");
434                         byte[] array = Sockaddr.GetDynamicData (source);
435                         // SockaddrStorage has to be handled extra because the native code assumes that SockaddrStorage input is used in-place
436                         if (source.type == (SockaddrType.SockaddrStorage | SockaddrType.MustBeWrapped)) {
437                                 Marshal.Copy (array, 0, destination, (int) source.GetDynamicLength ());
438                                 return true;
439                         }
440                         fixed (SockaddrType* addr = &Sockaddr.GetAddress (source).type)
441                         fixed (byte* data = array) {
442                                 var dyn = new _SockaddrDynamic (source, data, useMaxLength: false);
443                                 return FromSockaddr (Sockaddr.GetNative (&dyn, addr), destination) == 0;
444                         }
445                 }
446
447                 [DllImport (LIB, EntryPoint="Mono_Posix_ToSockaddr")]
448                 private static extern unsafe int ToSockaddr (IntPtr source, long size, _SockaddrHeader* destination);
449
450                 public static unsafe bool TryCopy (IntPtr source, long size, Sockaddr destination)
451                 {
452                         if (destination == null)
453                                 throw new ArgumentNullException ("destination");
454                         byte[] array = Sockaddr.GetDynamicData (destination);
455                         fixed (SockaddrType* addr = &Sockaddr.GetAddress (destination).type)
456                         fixed (byte* data = Sockaddr.GetDynamicData (destination)) {
457                                 var dyn = new _SockaddrDynamic (destination, data, useMaxLength: true);
458                                 var r = ToSockaddr (source, size, Sockaddr.GetNative (&dyn, addr));
459                                 dyn.Update (destination);
460                                 // SockaddrStorage has to be handled extra because the native code assumes that SockaddrStorage input is used in-place
461                                 if (r == 0 && destination.type == (SockaddrType.SockaddrStorage | SockaddrType.MustBeWrapped)) {
462                                         Marshal.Copy (source, array, 0, (int) destination.GetDynamicLength ());
463                                 }
464                                 return r == 0;
465                         }
466                 }
467         }
468 }
469
470 // vim: noexpandtab
471 // Local Variables: 
472 // tab-width: 4
473 // c-basic-offset: 4
474 // indent-tabs-mode: t
475 // End: