DEFINITIONS
This source file includes following functions.
- etc_getlogin
- setup_passwd
- etc_getpwuid
- etc_getpwnam
- passwd_ensure
- passwd_iterate
- etc_passwd
- setup_group
- etc_getgrgid
- etc_getgrnam
- group_ensure
- group_iterate
- etc_group
- Init_etc
1
2
3
4
5
6
7
8
9
10
11 #include "ruby.h"
12
13 #include <sys/types.h>
14 #ifdef HAVE_UNISTD_H
15 #include <unistd.h>
16 #endif
17
18 #ifdef HAVE_GETPWENT
19 #include <pwd.h>
20 #endif
21
22 #ifdef HAVE_GETGRENT
23 #include <grp.h>
24 #endif
25
26 static VALUE sPasswd, sGroup;
27
28 char *getenv();
29 char *getlogin();
30
31 static VALUE
32 etc_getlogin(obj)
33 VALUE obj;
34 {
35 char *login;
36
37 rb_secure(4);
38 #ifdef HAVE_GETLOGIN
39 login = getlogin();
40 if (!login) login = getenv("USER");
41 #else
42 login = getenv("USER");
43 #endif
44
45 if (login)
46 return rb_tainted_str_new2(login);
47 return Qnil;
48 }
49
50 #ifdef HAVE_GETPWENT
51 static VALUE
52 setup_passwd(pwd)
53 struct passwd *pwd;
54 {
55 if (pwd == 0) rb_sys_fail("/etc/passwd");
56 return rb_struct_new(sPasswd,
57 rb_tainted_str_new2(pwd->pw_name),
58 rb_tainted_str_new2(pwd->pw_passwd),
59 INT2FIX(pwd->pw_uid),
60 INT2FIX(pwd->pw_gid),
61 #ifdef HAVE_ST_PW_GECOS
62 rb_tainted_str_new2(pwd->pw_gecos),
63 #endif
64 rb_tainted_str_new2(pwd->pw_dir),
65 rb_tainted_str_new2(pwd->pw_shell),
66 #ifdef HAVE_ST_PW_CHANGE
67 INT2FIX(pwd->pw_change),
68 #endif
69 #ifdef HAVE_ST_PW_QUOTA
70 INT2FIX(pwd->pw_quota),
71 #endif
72 #ifdef HAVE_ST_PW_AGE
73 INT2FIX(pwd->pw_age),
74 #endif
75 #ifdef HAVE_ST_PW_CLASS
76 rb_tainted_str_new2(pwd->pw_class),
77 #endif
78 #ifdef HAVE_ST_PW_COMMENT
79 rb_tainted_str_new2(pwd->pw_comment),
80 #endif
81 #ifdef HAVE_ST_PW_EXPIRE
82 INT2FIX(pwd->pw_expire),
83 #endif
84 0
85 );
86 }
87 #endif
88
89 static VALUE
90 etc_getpwuid(argc, argv, obj)
91 int argc;
92 VALUE *argv;
93 VALUE obj;
94 {
95 #if defined(HAVE_GETPWENT)
96 VALUE id, ary;
97 int uid;
98 struct passwd *pwd;
99
100 rb_secure(4);
101 if (rb_scan_args(argc, argv, "01", &id) == 1) {
102 uid = NUM2INT(id);
103 }
104 else {
105 uid = getuid();
106 }
107 pwd = getpwuid(uid);
108 if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %d", uid);
109 return setup_passwd(pwd);
110 #else
111 return Qnil;
112 #endif
113 }
114
115 static VALUE
116 etc_getpwnam(obj, nam)
117 VALUE obj, nam;
118 {
119 #ifdef HAVE_GETPWENT
120 struct passwd *pwd;
121
122 SafeStringValue(nam);
123 pwd = getpwnam(RSTRING(nam)->ptr);
124 if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %s", RSTRING(nam)->ptr);
125 return setup_passwd(pwd);
126 #else
127 return Qnil;
128 #endif
129 }
130
131 #ifdef HAVE_GETPWENT
132 static int passwd_blocking = 0;
133 static VALUE
134 passwd_ensure()
135 {
136 passwd_blocking = Qfalse;
137 return Qnil;
138 }
139
140 static VALUE
141 passwd_iterate()
142 {
143 struct passwd *pw;
144
145 setpwent();
146 while (pw = getpwent()) {
147 rb_yield(setup_passwd(pw));
148 }
149 endpwent();
150 return Qnil;
151 }
152 #endif
153
154 static VALUE
155 etc_passwd(obj)
156 VALUE obj;
157 {
158 #ifdef HAVE_GETPWENT
159 struct passwd *pw;
160
161 rb_secure(4);
162 if (rb_block_given_p()) {
163 if (passwd_blocking) {
164 rb_raise(rb_eRuntimeError, "parallel passwd iteration");
165 }
166 passwd_blocking = Qtrue;
167 rb_ensure(passwd_iterate, 0, passwd_ensure, 0);
168 }
169 if (pw = getpwent()) {
170 return setup_passwd(pw);
171 }
172 #endif
173 return Qnil;
174 }
175
176 #ifdef HAVE_GETGRENT
177 static VALUE
178 setup_group(grp)
179 struct group *grp;
180 {
181 VALUE mem;
182 char **tbl;
183
184 mem = rb_ary_new();
185 tbl = grp->gr_mem;
186 while (*tbl) {
187 rb_ary_push(mem, rb_tainted_str_new2(*tbl));
188 tbl++;
189 }
190 return rb_struct_new(sGroup,
191 rb_tainted_str_new2(grp->gr_name),
192 rb_tainted_str_new2(grp->gr_passwd),
193 INT2FIX(grp->gr_gid),
194 mem);
195 }
196 #endif
197
198 static VALUE
199 etc_getgrgid(obj, id)
200 VALUE obj, id;
201 {
202 #ifdef HAVE_GETGRENT
203 int gid;
204 struct group *grp;
205
206 rb_secure(4);
207 gid = NUM2INT(id);
208 grp = getgrgid(gid);
209 if (grp == 0) rb_raise(rb_eArgError, "can't find group for %d", gid);
210 return setup_group(grp);
211 #else
212 return Qnil;
213 #endif
214 }
215
216 static VALUE
217 etc_getgrnam(obj, nam)
218 VALUE obj, nam;
219 {
220 #ifdef HAVE_GETGRENT
221 struct group *grp;
222
223 rb_secure(4);
224 SafeStringValue(nam);
225 grp = getgrnam(RSTRING(nam)->ptr);
226 if (grp == 0) rb_raise(rb_eArgError, "can't find group for %s", RSTRING(nam)->ptr);
227 return setup_group(grp);
228 #else
229 return Qnil;
230 #endif
231 }
232
233 #ifdef HAVE_GETGRENT
234 static int group_blocking = 0;
235 static VALUE
236 group_ensure()
237 {
238 group_blocking = Qfalse;
239 return Qnil;
240 }
241
242 static VALUE
243 group_iterate()
244 {
245 struct group *pw;
246
247 setpwent();
248 while (pw = getgrent()) {
249 rb_yield(setup_group(pw));
250 }
251 endpwent();
252 return Qnil;
253 }
254 #endif
255
256 static VALUE
257 etc_group(obj)
258 VALUE obj;
259 {
260 #ifdef HAVE_GETGRENT
261 struct group *grp;
262
263 rb_secure(4);
264 if (rb_block_given_p()) {
265 if (group_blocking) {
266 rb_raise(rb_eRuntimeError, "parallel group iteration");
267 }
268 group_blocking = Qtrue;
269 rb_ensure(group_iterate, 0, group_ensure, 0);
270 }
271 if (grp = getgrent()) {
272 return setup_group(grp);
273 }
274 #endif
275 return Qnil;
276 }
277
278 static VALUE mEtc;
279
280 void
281 Init_etc()
282 {
283 mEtc = rb_define_module("Etc");
284
285 rb_define_module_function(mEtc, "getlogin", etc_getlogin, 0);
286
287 rb_define_module_function(mEtc, "getpwuid", etc_getpwuid, -1);
288 rb_define_module_function(mEtc, "getpwnam", etc_getpwnam, 1);
289 rb_define_module_function(mEtc, "passwd", etc_passwd, 0);
290
291 rb_define_module_function(mEtc, "getgrgid", etc_getgrgid, 1);
292 rb_define_module_function(mEtc, "getgrnam", etc_getgrnam, 1);
293 rb_define_module_function(mEtc, "group", etc_group, 0);
294
295 sPasswd = rb_struct_define("Passwd",
296 "name", "passwd", "uid", "gid",
297 #ifdef HAVE_ST_PW_GECOS
298 "gecos",
299 #endif
300 "dir", "shell",
301 #ifdef HAVE_ST_PW_CHANGE
302 "change",
303 #endif
304 #ifdef HAVE_ST_PW_QUOTA
305 "quota",
306 #endif
307 #ifdef HAVE_ST_PW_AGE
308 "age",
309 #endif
310 #ifdef HAVE_ST_PW_CLASS
311 "uclass",
312 #endif
313 #ifdef HAVE_ST_PW_COMMENT
314 "comment",
315 #endif
316 #ifdef HAVE_ST_PW_EXPIRE
317 "expire",
318 #endif
319 0);
320 rb_global_variable(&sPasswd);
321
322 #ifdef HAVE_GETGRENT
323 sGroup = rb_struct_define("Group", "name", "passwd", "gid", "mem", 0);
324 rb_global_variable(&sGroup);
325 #endif
326 }