* UnixMarshal.cs: Errno.EBADF should also trigger a ArgumentException.
[mono.git] / mcs / class / Mono.Posix / Mono.Unix / UnixUserInfo.cs
1 //
2 // Mono.Unix/UnixUserInfo.cs
3 //
4 // Authors:
5 //   Jonathan Pryor (jonpryor@vt.edu)
6 //
7 // (C) 2004-2005 Jonathan Pryor
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Collections;
31 using System.Text;
32 using Mono.Unix;
33
34 namespace Mono.Unix {
35
36         public sealed class UnixUserInfo
37         {
38                 private Native.Passwd passwd;
39
40                 public UnixUserInfo (string user)
41                 {
42                         passwd = new Native.Passwd ();
43                         Native.Passwd pw;
44                         int r = Native.Syscall.getpwnam_r (user, passwd, out pw);
45                         if (r != 0 || pw == null)
46                                 throw new ArgumentException (Locale.GetText ("invalid username"), "user");
47                 }
48
49                 [CLSCompliant (false)]
50                 public UnixUserInfo (uint user)
51                 {
52                         passwd = new Native.Passwd ();
53                         Native.Passwd pw;
54                         int r = Native.Syscall.getpwuid_r (user, passwd, out pw);
55                         if (r != 0 || pw == null)
56                                 throw new ArgumentException (Locale.GetText ("invalid user id"), "user");
57                 }
58
59                 public UnixUserInfo (long user)
60                 {
61                         passwd = new Native.Passwd ();
62                         Native.Passwd pw;
63                         int r = Native.Syscall.getpwuid_r (Convert.ToUInt32 (user), passwd, out pw);
64                         if (r != 0 || pw == null)
65                                 throw new ArgumentException (Locale.GetText ("invalid user id"), "user");
66                 }
67
68                 [Obsolete ("Use UnixUserInfo (Mono.Unix.Native.Passwd)", true)]
69                 public UnixUserInfo (Passwd passwd)
70                 {
71                         this.passwd = new Native.Passwd ();
72                         this.passwd.pw_name   = passwd.pw_name;
73                         this.passwd.pw_passwd = passwd.pw_passwd;
74                         this.passwd.pw_uid    = passwd.pw_uid;
75                         this.passwd.pw_gid    = passwd.pw_gid;
76                         this.passwd.pw_gecos  = passwd.pw_gecos;
77                         this.passwd.pw_dir    = passwd.pw_dir;
78                         this.passwd.pw_shell  = passwd.pw_shell;
79                 }
80
81                 public UnixUserInfo (Native.Passwd passwd)
82                 {
83                         this.passwd = passwd;
84                 }
85
86                 public string UserName {
87                         get {return passwd.pw_name;}
88                 }
89
90                 public string Password {
91                         get {return passwd.pw_passwd;}
92                 }
93
94                 public long UserId {
95                         get {return passwd.pw_uid;}
96                 }
97
98                 public UnixGroupInfo Group {
99                         get {return new UnixGroupInfo (passwd.pw_gid);}
100                 }
101
102                 public long GroupId {
103                         get {return passwd.pw_gid;}
104                 }
105
106                 public string GroupName {
107                         get {return Group.GroupName;}
108                 }
109
110                 public string RealName {
111                         get {return passwd.pw_gecos;}
112                 }
113
114                 public string HomeDirectory {
115                         get {return passwd.pw_dir;}
116                 }
117
118                 public string ShellProgram {
119                         get {return passwd.pw_shell;}
120                 }
121
122                 public override int GetHashCode ()
123                 {
124                         return passwd.GetHashCode ();
125                 }
126
127                 public override bool Equals (object obj)
128                 {
129                         if (obj == null || GetType () != obj.GetType())
130                                 return false;
131                         return passwd.Equals (((UnixUserInfo) obj).passwd);
132                 }
133
134                 public override string ToString ()
135                 {
136                         return passwd.ToString ();
137                 }
138
139                 public static UnixUserInfo GetRealUser ()
140                 {
141                         return new UnixUserInfo (GetRealUserId ());
142                 }
143
144                 public static long GetRealUserId ()
145                 {
146                         return Native.Syscall.getuid ();
147                 }
148
149                 // I would hope that this is the same as GetCurrentUserName, but it is a
150                 // different syscall, so who knows.
151                 public static string GetLoginName ()
152                 {
153                         StringBuilder buf = new StringBuilder (4);
154                         int r;
155                         do {
156                                 buf.Capacity *= 2;
157                                 r = Native.Syscall.getlogin_r (buf, (ulong) buf.Capacity);
158                         } while (r == (-1) && Native.Stdlib.GetLastError() == Native.Errno.ERANGE);
159                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
160                         return buf.ToString ();
161                 }
162
163                 public Native.Passwd ToPasswd ()
164                 {
165                         return passwd;
166                 }
167
168                 public static UnixUserInfo[] GetLocalUsers ()
169                 {
170                         ArrayList entries = new ArrayList ();
171                         lock (Native.Syscall.pwd_lock) {
172                                 if (Native.Syscall.setpwent () != 0) {
173                                         UnixMarshal.ThrowExceptionForLastError ();
174                                 }
175                                 try {
176                                         Native.Passwd p;
177                                         while ((p = Native.Syscall.getpwent()) != null)
178                                                 entries.Add (new UnixUserInfo (p));
179                                         if (Native.Syscall.GetLastError () != (Native.Errno) 0)
180                                                 UnixMarshal.ThrowExceptionForLastError ();
181                                 }
182                                 finally {
183                                         Native.Syscall.endpwent ();
184                                 }
185                         }
186                         return (UnixUserInfo[]) entries.ToArray (typeof(UnixUserInfo));
187                 }
188         }
189 }
190
191 // vim: noexpandtab