etcutils 0.1.5-x86-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.md +322 -0
- data/Rakefile +15 -0
- data/etcutils.gemspec +24 -0
- data/ext/etcutils/etcutils.c +1182 -0
- data/ext/etcutils/etcutils.h +98 -0
- data/ext/etcutils/extconf.rb +45 -0
- data/tests/etcutils_test_helper.rb +4 -0
- data/tests/test_etc_utils.rb +71 -0
- metadata +86 -0
@@ -0,0 +1,1182 @@
|
|
1
|
+
/********************************************************************
|
2
|
+
|
3
|
+
Ruby C Extension for read write access to the Linux user database
|
4
|
+
|
5
|
+
Copyright (C) 2013 David Campbell
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
8
|
+
a copy of this software and associated documentation files (the
|
9
|
+
"Software"), to deal in the Software without restriction, including
|
10
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
11
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
12
|
+
permit persons to whom the Software is furnished to do so, subject to
|
13
|
+
the following conditions:
|
14
|
+
|
15
|
+
The above copyright notice and this permission notice shall be
|
16
|
+
included in all copies or substantial portions of the Software.
|
17
|
+
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
20
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
22
|
+
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
23
|
+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
24
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
25
|
+
SOFTWARE.
|
26
|
+
|
27
|
+
********************************************************************/
|
28
|
+
|
29
|
+
#include "etcutils.h"
|
30
|
+
uid_t uid_global = 0;
|
31
|
+
gid_t gid_global = 0;
|
32
|
+
|
33
|
+
|
34
|
+
/* Start of helper functions */
|
35
|
+
static VALUE
|
36
|
+
next_uid(int argc, VALUE *argv, VALUE self)
|
37
|
+
{
|
38
|
+
uid_t req;
|
39
|
+
VALUE i;
|
40
|
+
|
41
|
+
rb_scan_args(argc, argv, "01", &i);
|
42
|
+
if (NIL_P(i))
|
43
|
+
req = uid_global;
|
44
|
+
else
|
45
|
+
req = NUM2UIDT(i);
|
46
|
+
|
47
|
+
if ((req < 0) || (req > 65533))
|
48
|
+
rb_raise(rb_eArgError, "UID must be between 0 and 65533");
|
49
|
+
while ( getpwuid(req) ) req++;
|
50
|
+
|
51
|
+
if (NIL_P(i))
|
52
|
+
uid_global = req + 1;
|
53
|
+
else
|
54
|
+
uid_global = req;
|
55
|
+
|
56
|
+
return UIDT2NUM(req);
|
57
|
+
}
|
58
|
+
|
59
|
+
static VALUE
|
60
|
+
next_gid(int argc, VALUE *argv, VALUE self)
|
61
|
+
{
|
62
|
+
gid_t req;
|
63
|
+
VALUE i;
|
64
|
+
|
65
|
+
rb_scan_args(argc, argv, "01", &i);
|
66
|
+
if (NIL_P(i))
|
67
|
+
req = gid_global;
|
68
|
+
else
|
69
|
+
req = NUM2GIDT(i);
|
70
|
+
|
71
|
+
if ((req < 0) || (req > 65533))
|
72
|
+
rb_raise(rb_eArgError, "GID must be between 0 and 65533");
|
73
|
+
while ( getgrgid(req) ) req++;
|
74
|
+
|
75
|
+
if (NIL_P(i))
|
76
|
+
gid_global = req +1;
|
77
|
+
else
|
78
|
+
gid_global = req;
|
79
|
+
|
80
|
+
return GIDT2NUM(req);
|
81
|
+
}
|
82
|
+
|
83
|
+
static void
|
84
|
+
etcutils_errno(VALUE str)
|
85
|
+
{
|
86
|
+
// SafeStringValue(str);
|
87
|
+
// if ( (errno) && ( !(errno == ENOTTY) || !(errno == ENOENT) ) )
|
88
|
+
// rb_sys_fail( StringValuePtr(str) );
|
89
|
+
/*
|
90
|
+
Errno::ENOTTY: Inappropriate ioctl for device
|
91
|
+
https://bugs.ruby-lang.org/issues/6127
|
92
|
+
ioctl range error in 1.9.3
|
93
|
+
Fixed in 1.9.3-p194 (REVISION r37138)
|
94
|
+
Ubuntu System Ruby (via APT) - 1.9.3-p0 (REVISION 33570)
|
95
|
+
*/
|
96
|
+
//errno = 0;
|
97
|
+
}
|
98
|
+
|
99
|
+
static void
|
100
|
+
ensure_file(VALUE io)
|
101
|
+
{
|
102
|
+
rb_io_check_initialized(RFILE(io)->fptr);
|
103
|
+
}
|
104
|
+
|
105
|
+
static void
|
106
|
+
free_char_members(char ** mem, int c)
|
107
|
+
{
|
108
|
+
if (NULL != mem) {
|
109
|
+
int i=0;
|
110
|
+
for (i=0; i<c+1 ; i++) free(mem[i]);
|
111
|
+
free(mem);
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
static char**
|
116
|
+
setup_char_members(VALUE ary)
|
117
|
+
{
|
118
|
+
char ** mem;
|
119
|
+
VALUE temp;
|
120
|
+
long i;
|
121
|
+
Check_Type(ary,T_ARRAY);
|
122
|
+
|
123
|
+
mem = malloc((RARRAY_LEN(ary) + 1)*sizeof(char**));
|
124
|
+
if (mem == NULL)
|
125
|
+
rb_memerror();
|
126
|
+
|
127
|
+
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
128
|
+
temp = rb_obj_as_string(RARRAY_PTR(ary)[i]);
|
129
|
+
StringValueCStr(temp);
|
130
|
+
mem[i] = malloc((RSTRING_LEN(temp))*sizeof(char*));;
|
131
|
+
|
132
|
+
if (mem[i] == NULL) rb_memerror();
|
133
|
+
strcpy(mem[i], RSTRING_PTR(temp));
|
134
|
+
}
|
135
|
+
mem[i] = NULL;
|
136
|
+
|
137
|
+
return mem;
|
138
|
+
}
|
139
|
+
|
140
|
+
static VALUE
|
141
|
+
setup_safe_str(const char *str)
|
142
|
+
{
|
143
|
+
return rb_tainted_str_new2(str); // this already handles characters >= 0
|
144
|
+
}
|
145
|
+
|
146
|
+
static VALUE
|
147
|
+
setup_safe_array(char **arr)
|
148
|
+
{
|
149
|
+
VALUE mem = rb_ary_new();
|
150
|
+
|
151
|
+
while (*arr)
|
152
|
+
rb_ary_push(mem, setup_safe_str(*arr++));
|
153
|
+
return mem;
|
154
|
+
}
|
155
|
+
|
156
|
+
static VALUE
|
157
|
+
setup_gshadow(struct sgrp *sgroup)
|
158
|
+
{
|
159
|
+
if (!sgroup) errno || (errno = 61); // ENODATA
|
160
|
+
etcutils_errno( setup_safe_str ( "Error setting up GShadow instance." ) );
|
161
|
+
return rb_struct_new(cGShadow,
|
162
|
+
setup_safe_str(SGRP_NAME(sgroup)),
|
163
|
+
setup_safe_str(sgroup->sg_passwd),
|
164
|
+
setup_safe_array(sgroup->sg_adm),
|
165
|
+
setup_safe_array(sgroup->sg_mem),
|
166
|
+
NULL);
|
167
|
+
}
|
168
|
+
|
169
|
+
static VALUE
|
170
|
+
setup_shadow(struct spwd *shadow)
|
171
|
+
{
|
172
|
+
if (!shadow) errno || (errno = 61); // ENODATA
|
173
|
+
etcutils_errno( setup_safe_str ( "Error setting up Shadow instance." ) );
|
174
|
+
return rb_struct_new(cShadow,
|
175
|
+
setup_safe_str(shadow->sp_namp),
|
176
|
+
setup_safe_str(shadow->sp_pwdp),
|
177
|
+
INT2FIX(shadow->sp_lstchg),
|
178
|
+
INT2FIX(shadow->sp_min),
|
179
|
+
INT2FIX(shadow->sp_max),
|
180
|
+
INT2FIX(shadow->sp_warn),
|
181
|
+
INT2FIX(shadow->sp_inact),
|
182
|
+
INT2FIX(shadow->sp_expire),
|
183
|
+
INT2FIX(shadow->sp_flag),
|
184
|
+
NULL);
|
185
|
+
}
|
186
|
+
|
187
|
+
static VALUE
|
188
|
+
setup_group(struct group *grp)
|
189
|
+
{
|
190
|
+
if (!grp) errno || (errno = 61); // ENODATA
|
191
|
+
etcutils_errno( setup_safe_str ( "Error setting up Group instance." ) );
|
192
|
+
return rb_struct_new(cGroup,
|
193
|
+
setup_safe_str(grp->gr_name),
|
194
|
+
setup_safe_str(grp->gr_passwd),
|
195
|
+
GIDT2NUM(grp->gr_gid),
|
196
|
+
setup_safe_array(grp->gr_mem),
|
197
|
+
NULL);
|
198
|
+
}
|
199
|
+
|
200
|
+
static VALUE
|
201
|
+
setup_passwd(struct passwd *pwd)
|
202
|
+
{
|
203
|
+
if (!pwd) errno || (errno = 61); // ENODATA
|
204
|
+
etcutils_errno( setup_safe_str ( "Error setting up Password instance." ) );
|
205
|
+
return rb_struct_new(cPasswd,
|
206
|
+
setup_safe_str(pwd->pw_name),
|
207
|
+
setup_safe_str(pwd->pw_passwd),
|
208
|
+
UIDT2NUM(pwd->pw_uid),
|
209
|
+
GIDT2NUM(pwd->pw_gid),
|
210
|
+
setup_safe_str(pwd->pw_gecos),
|
211
|
+
setup_safe_str(pwd->pw_dir),
|
212
|
+
setup_safe_str(pwd->pw_shell),
|
213
|
+
NULL);
|
214
|
+
}
|
215
|
+
/* End of helper functions */
|
216
|
+
|
217
|
+
static VALUE
|
218
|
+
etcutils_setsgent(VALUE self)
|
219
|
+
{
|
220
|
+
#ifdef HAVE_SETSGENT
|
221
|
+
setsgent();
|
222
|
+
#endif
|
223
|
+
return Qnil;
|
224
|
+
}
|
225
|
+
|
226
|
+
static VALUE
|
227
|
+
etcutils_endsgent(VALUE self)
|
228
|
+
{
|
229
|
+
#ifdef HAVE_ENDSGENT
|
230
|
+
endsgent();
|
231
|
+
#endif
|
232
|
+
return Qnil;
|
233
|
+
}
|
234
|
+
|
235
|
+
static VALUE
|
236
|
+
etcutils_setgrent(VALUE self)
|
237
|
+
{
|
238
|
+
#ifdef HAVE_SETGRENT
|
239
|
+
setgrent();
|
240
|
+
#endif
|
241
|
+
return Qnil;
|
242
|
+
}
|
243
|
+
|
244
|
+
static VALUE
|
245
|
+
etcutils_endgrent(VALUE self)
|
246
|
+
{
|
247
|
+
#ifdef HAVE_ENDGRENT
|
248
|
+
endgrent();
|
249
|
+
#endif
|
250
|
+
return Qnil;
|
251
|
+
}
|
252
|
+
|
253
|
+
static VALUE
|
254
|
+
etcutils_setspent(VALUE self)
|
255
|
+
{
|
256
|
+
#ifdef HAVE_SETSPENT
|
257
|
+
setspent();
|
258
|
+
#endif
|
259
|
+
return Qnil;
|
260
|
+
}
|
261
|
+
|
262
|
+
static VALUE
|
263
|
+
etcutils_setpwent(VALUE self)
|
264
|
+
{
|
265
|
+
#ifdef HAVE_SETPWENT
|
266
|
+
setpwent();
|
267
|
+
#endif
|
268
|
+
return Qnil;
|
269
|
+
}
|
270
|
+
|
271
|
+
static VALUE
|
272
|
+
etcutils_endpwent(VALUE self)
|
273
|
+
{
|
274
|
+
#ifdef HAVE_ENDPWENT
|
275
|
+
endpwent();
|
276
|
+
#endif
|
277
|
+
return Qnil;
|
278
|
+
}
|
279
|
+
|
280
|
+
static VALUE
|
281
|
+
etcutils_endspent(VALUE self)
|
282
|
+
{
|
283
|
+
#ifdef HAVE_ENDSPENT
|
284
|
+
endspent();
|
285
|
+
#endif
|
286
|
+
return Qnil;
|
287
|
+
}
|
288
|
+
|
289
|
+
static VALUE
|
290
|
+
etcutils_sgetpwent(VALUE self, VALUE nam)
|
291
|
+
{
|
292
|
+
VALUE ary, uid, gid, tmp;
|
293
|
+
struct passwd *pwd;
|
294
|
+
struct group *grp;
|
295
|
+
|
296
|
+
SafeStringValue(nam);
|
297
|
+
ary = rb_str_split(nam,":");
|
298
|
+
|
299
|
+
etcutils_setpwent(self);
|
300
|
+
etcutils_setgrent(self);
|
301
|
+
|
302
|
+
nam = rb_ary_entry(ary,0);
|
303
|
+
SafeStringValue(nam);
|
304
|
+
if (pwd = getpwnam( StringValuePtr(nam) )) {
|
305
|
+
rb_ary_store(ary, 2, UIDT2NUM(pwd->pw_uid) );
|
306
|
+
rb_ary_store(ary, 3, UIDT2NUM(pwd->pw_gid) );
|
307
|
+
} else {
|
308
|
+
uid = rb_ary_entry(ary,2);
|
309
|
+
// If there actually is a UID and that UID isn't already assigned
|
310
|
+
if ( (!( NIL_P(uid) || RSTRING_LEN(uid) == 0 )) && (getpwuid( NUM2UIDT( rb_Integer( uid ) ) )) ) {
|
311
|
+
tmp = rb_Integer( uid );
|
312
|
+
next_uid(1, &tmp, self);
|
313
|
+
}
|
314
|
+
uid = next_uid(0, 0, self);
|
315
|
+
|
316
|
+
gid = rb_ary_entry(ary,3);
|
317
|
+
if ( NIL_P(gid) || RSTRING_LEN(gid) == 0 )
|
318
|
+
if ( (grp = getgrnam( StringValuePtr(nam) )) ) { // Found a group with the same name
|
319
|
+
gid = GIDT2NUM(grp->gr_gid);
|
320
|
+
// See if the UID with value GID is available
|
321
|
+
// If so, we can keep a little sanity and match the GID and UID
|
322
|
+
tmp = uid;
|
323
|
+
next_uid(1, &gid, self);
|
324
|
+
uid = next_uid(0, 0, self);
|
325
|
+
if (! uid == gid)
|
326
|
+
uid = tmp;
|
327
|
+
} else {
|
328
|
+
next_gid(1, &uid, self);
|
329
|
+
gid = next_gid(0, 0, self);
|
330
|
+
}
|
331
|
+
else if ( (grp = getgrgid( NUM2GIDT( rb_Integer(gid) ) )) )
|
332
|
+
gid = GIDT2NUM(grp->gr_gid);
|
333
|
+
else
|
334
|
+
rb_raise(rb_eArgError,
|
335
|
+
"Group ID %ld does not exist!", gid);
|
336
|
+
|
337
|
+
rb_ary_store(ary, 2, rb_Integer( uid ) );
|
338
|
+
rb_ary_store(ary, 3, rb_Integer( gid ) );
|
339
|
+
}
|
340
|
+
|
341
|
+
return rb_struct_alloc( self, ary );
|
342
|
+
}
|
343
|
+
|
344
|
+
static VALUE
|
345
|
+
etcutils_sgetspent(VALUE self, VALUE nam)
|
346
|
+
{
|
347
|
+
struct spwd *shadow;
|
348
|
+
|
349
|
+
SafeStringValue(nam);
|
350
|
+
if ( !(shadow = sgetspent(StringValuePtr(nam))) )
|
351
|
+
rb_raise(rb_eArgError,
|
352
|
+
"can't parse %s into EtcUtils::Shadow", StringValuePtr(nam));
|
353
|
+
|
354
|
+
return setup_shadow(shadow);
|
355
|
+
}
|
356
|
+
|
357
|
+
static VALUE
|
358
|
+
etcutils_sgetgrent(VALUE self, VALUE nam)
|
359
|
+
{
|
360
|
+
VALUE ary, gid, mem;
|
361
|
+
struct group *grp;
|
362
|
+
struct passwd *pwd;
|
363
|
+
|
364
|
+
SafeStringValue(nam);
|
365
|
+
ary = rb_str_split(nam,":");
|
366
|
+
|
367
|
+
etcutils_setgrent(self);
|
368
|
+
etcutils_setpwent(self);
|
369
|
+
nam = rb_ary_entry(ary,0);
|
370
|
+
SafeStringValue(nam);
|
371
|
+
if (grp = getgrnam( StringValuePtr(nam) ))
|
372
|
+
rb_ary_store(ary, 2, GIDT2NUM(grp->gr_gid) );
|
373
|
+
else if (pwd = getpwnam( StringValuePtr(nam) ))
|
374
|
+
rb_ary_store(ary, 2, GIDT2NUM(pwd->pw_gid) );
|
375
|
+
else {
|
376
|
+
gid = rb_ary_entry(ary,2);
|
377
|
+
if ( NIL_P(gid) || RSTRING_LEN(gid) == 0 )
|
378
|
+
gid = next_gid(0, 0, self);
|
379
|
+
rb_ary_store(ary, 2, rb_Integer( gid ) );
|
380
|
+
}
|
381
|
+
|
382
|
+
if (NIL_P(mem = rb_ary_entry(ary,3)))
|
383
|
+
mem = rb_ary_new();
|
384
|
+
else
|
385
|
+
mem = rb_str_split(mem,",");
|
386
|
+
|
387
|
+
rb_ary_store(ary, 3, mem);
|
388
|
+
|
389
|
+
return rb_struct_alloc(self, ary);
|
390
|
+
}
|
391
|
+
|
392
|
+
static VALUE
|
393
|
+
etcutils_sgetsgent(VALUE self, VALUE nam)
|
394
|
+
{
|
395
|
+
struct sgrp *gshadow;
|
396
|
+
|
397
|
+
SafeStringValue(nam);
|
398
|
+
if ( !(gshadow = sgetsgent(StringValuePtr(nam))) )
|
399
|
+
rb_raise(rb_eArgError,
|
400
|
+
"can't parse %s into EtcUtils::GShadow", StringValuePtr(nam));
|
401
|
+
|
402
|
+
return setup_gshadow(gshadow);
|
403
|
+
}
|
404
|
+
|
405
|
+
static VALUE
|
406
|
+
etc_fgetgrent(VALUE self, VALUE io)
|
407
|
+
{
|
408
|
+
struct group *grp;
|
409
|
+
|
410
|
+
ensure_file(io);
|
411
|
+
if ( (grp = fgetgrent(RFILE_FPTR(io))) == NULL )
|
412
|
+
return Qnil;
|
413
|
+
|
414
|
+
return setup_group(grp);
|
415
|
+
}
|
416
|
+
|
417
|
+
static VALUE
|
418
|
+
etc_fgetpwent(VALUE self, VALUE io)
|
419
|
+
{
|
420
|
+
struct passwd *pwd;
|
421
|
+
|
422
|
+
ensure_file(io);
|
423
|
+
if ( (pwd = fgetpwent(RFILE_FPTR(io))) == NULL )
|
424
|
+
return Qnil;
|
425
|
+
|
426
|
+
return setup_passwd(pwd);
|
427
|
+
}
|
428
|
+
|
429
|
+
static VALUE
|
430
|
+
etcutils_fgetspent(VALUE self, VALUE io)
|
431
|
+
{
|
432
|
+
struct spwd *spasswd;
|
433
|
+
|
434
|
+
ensure_file(io);
|
435
|
+
if ( (spasswd = fgetspent(RFILE_FPTR(io))) == NULL )
|
436
|
+
return Qnil;
|
437
|
+
|
438
|
+
return setup_shadow(spasswd);
|
439
|
+
}
|
440
|
+
|
441
|
+
static VALUE
|
442
|
+
etcutils_fgetsgent(VALUE self, VALUE io)
|
443
|
+
{
|
444
|
+
struct sgrp *sgroup;
|
445
|
+
|
446
|
+
ensure_file(io);
|
447
|
+
if ( (sgroup = fgetsgent(RFILE_FPTR(io))) == NULL )
|
448
|
+
return Qnil;
|
449
|
+
|
450
|
+
return setup_gshadow(sgroup);
|
451
|
+
}
|
452
|
+
|
453
|
+
static VALUE
|
454
|
+
etcutils_getpwXXX(VALUE self, VALUE v)
|
455
|
+
{
|
456
|
+
struct passwd *strt;
|
457
|
+
etcutils_setpwent(self);
|
458
|
+
|
459
|
+
if (FIXNUM_P(v))
|
460
|
+
strt = getpwuid(NUM2UIDT(v));
|
461
|
+
else {
|
462
|
+
SafeStringValue(v);
|
463
|
+
strt = getpwnam(StringValuePtr(v));
|
464
|
+
}
|
465
|
+
|
466
|
+
if (!strt)
|
467
|
+
return Qnil;
|
468
|
+
|
469
|
+
return setup_passwd(strt);
|
470
|
+
}
|
471
|
+
|
472
|
+
static VALUE
|
473
|
+
etcutils_getspXXX(VALUE self, VALUE v)
|
474
|
+
{
|
475
|
+
struct spwd *strt;
|
476
|
+
etcutils_setspent(self);
|
477
|
+
|
478
|
+
if (FIXNUM_P(v)) {
|
479
|
+
struct passwd *s;
|
480
|
+
if ( (s = getpwuid(NUM2UIDT(v))) )
|
481
|
+
v = rb_str_new2(s->pw_name);
|
482
|
+
else
|
483
|
+
return Qnil;
|
484
|
+
}
|
485
|
+
|
486
|
+
SafeStringValue(v);
|
487
|
+
strt = getspnam(StringValuePtr(v));
|
488
|
+
|
489
|
+
if (!strt)
|
490
|
+
return Qnil;
|
491
|
+
|
492
|
+
return setup_shadow(strt);
|
493
|
+
}
|
494
|
+
|
495
|
+
static VALUE
|
496
|
+
etcutils_getsgXXX(VALUE self, VALUE v)
|
497
|
+
{
|
498
|
+
struct sgrp *strt;
|
499
|
+
etcutils_setsgent(self);
|
500
|
+
|
501
|
+
if (FIXNUM_P(v)) {
|
502
|
+
struct group *s;
|
503
|
+
if ( (s = getgrgid(NUM2UIDT(v))) )
|
504
|
+
v = setup_safe_str(s->gr_name);
|
505
|
+
}
|
506
|
+
|
507
|
+
SafeStringValue(v);
|
508
|
+
strt = getsgnam(StringValuePtr(v));
|
509
|
+
|
510
|
+
if (!strt)
|
511
|
+
return Qnil;
|
512
|
+
|
513
|
+
return setup_gshadow(strt);
|
514
|
+
}
|
515
|
+
|
516
|
+
static VALUE
|
517
|
+
etcutils_getgrXXX(VALUE self, VALUE v)
|
518
|
+
{
|
519
|
+
struct group *strt;
|
520
|
+
etcutils_setgrent(self);
|
521
|
+
|
522
|
+
if (FIXNUM_P(v))
|
523
|
+
strt = getgrgid(NUM2UIDT(v));
|
524
|
+
else {
|
525
|
+
SafeStringValue(v);
|
526
|
+
strt = getgrnam(StringValuePtr(v));
|
527
|
+
}
|
528
|
+
|
529
|
+
if (!strt)
|
530
|
+
return Qnil;
|
531
|
+
return setup_group(strt);
|
532
|
+
}
|
533
|
+
|
534
|
+
/**
|
535
|
+
* EtcUtils putXXent functions
|
536
|
+
*
|
537
|
+
*/
|
538
|
+
|
539
|
+
static VALUE
|
540
|
+
pwd_putpwent(VALUE self, VALUE io)
|
541
|
+
{
|
542
|
+
struct passwd pwd, *tmp_str;
|
543
|
+
VALUE name = rb_struct_getmember(self,rb_intern("name"));
|
544
|
+
VALUE passwd = rb_struct_getmember(self,rb_intern("passwd"));
|
545
|
+
VALUE gecos = rb_struct_getmember(self,rb_intern("gecos"));
|
546
|
+
VALUE dir = rb_struct_getmember(self,rb_intern("dir"));
|
547
|
+
VALUE shell = rb_struct_getmember(self,rb_intern("shell"));
|
548
|
+
VALUE path = RFILE_PATH(io);
|
549
|
+
long i;
|
550
|
+
|
551
|
+
ensure_file(io);
|
552
|
+
|
553
|
+
rewind(RFILE_FPTR(io));
|
554
|
+
i = 0;
|
555
|
+
while ( (tmp_str = fgetpwent(RFILE_FPTR(io))) ) {
|
556
|
+
i++;
|
557
|
+
if ( !strcmp(tmp_str->pw_name, StringValuePtr( name ) ) )
|
558
|
+
rb_raise(rb_eArgError, "%s is already mentioned in %s:%ld",
|
559
|
+
tmp_str->pw_name, StringValuePtr(path), i );
|
560
|
+
}
|
561
|
+
|
562
|
+
pwd.pw_name = StringValueCStr( name );
|
563
|
+
pwd.pw_passwd = StringValueCStr( passwd );
|
564
|
+
pwd.pw_uid = NUM2UIDT( rb_struct_getmember(self,rb_intern("uid")) );
|
565
|
+
pwd.pw_gid = NUM2GIDT( rb_struct_getmember(self,rb_intern("gid")) );
|
566
|
+
pwd.pw_gecos = StringValueCStr( gecos );
|
567
|
+
pwd.pw_dir = StringValueCStr( dir );
|
568
|
+
pwd.pw_shell = StringValueCStr( shell );
|
569
|
+
|
570
|
+
if ( (putpwent(&pwd, RFILE_FPTR(io))) )
|
571
|
+
etcutils_errno(path);
|
572
|
+
|
573
|
+
return Qtrue;
|
574
|
+
}
|
575
|
+
|
576
|
+
static VALUE
|
577
|
+
etc_putpwent(VALUE klass, VALUE entry, VALUE io)
|
578
|
+
{
|
579
|
+
return pwd_putpwent(entry,io);
|
580
|
+
}
|
581
|
+
|
582
|
+
|
583
|
+
static VALUE
|
584
|
+
spwd_putspent(VALUE self, VALUE io)
|
585
|
+
{
|
586
|
+
struct spwd spasswd, *tmp_str;
|
587
|
+
VALUE name = rb_struct_getmember(self,rb_intern("name"));
|
588
|
+
VALUE passwd = rb_struct_getmember(self,rb_intern("passwd"));
|
589
|
+
VALUE path = RFILE_PATH(io);
|
590
|
+
long i;
|
591
|
+
|
592
|
+
ensure_file(io);
|
593
|
+
|
594
|
+
rewind(RFILE_FPTR(io));
|
595
|
+
i = 0;
|
596
|
+
while ( (tmp_str = fgetspent(RFILE_FPTR(io))) ) {
|
597
|
+
i++;
|
598
|
+
if ( !strcmp(tmp_str->sp_namp,StringValuePtr( name )) )
|
599
|
+
rb_raise(rb_eArgError, "%s is already mentioned in %s:%ld",
|
600
|
+
tmp_str->sp_namp, StringValuePtr(path), i );
|
601
|
+
}
|
602
|
+
|
603
|
+
spasswd.sp_namp = StringValueCStr( name );
|
604
|
+
spasswd.sp_pwdp = StringValueCStr( passwd );
|
605
|
+
spasswd.sp_lstchg = FIX2INT( rb_struct_getmember(self,rb_intern("last_change")) );
|
606
|
+
spasswd.sp_min = FIX2INT( rb_struct_getmember(self,rb_intern("min_change")) );
|
607
|
+
spasswd.sp_max = FIX2INT( rb_struct_getmember(self,rb_intern("max_change")) );
|
608
|
+
spasswd.sp_warn = FIX2INT( rb_struct_getmember(self,rb_intern("warn")) );
|
609
|
+
spasswd.sp_inact = FIX2INT( rb_struct_getmember(self,rb_intern("inactive")) );
|
610
|
+
spasswd.sp_expire = FIX2INT( rb_struct_getmember(self,rb_intern("expire")) );
|
611
|
+
spasswd.sp_flag = FIX2INT( rb_struct_getmember(self,rb_intern("flag")) );
|
612
|
+
|
613
|
+
if ( (putspent(&spasswd, RFILE_FPTR(io))) )
|
614
|
+
etcutils_errno(path);
|
615
|
+
|
616
|
+
return Qtrue;
|
617
|
+
}
|
618
|
+
|
619
|
+
static VALUE
|
620
|
+
etcutils_putspent(VALUE klass, VALUE entry, VALUE io)
|
621
|
+
{
|
622
|
+
return spwd_putspent(entry,io);
|
623
|
+
}
|
624
|
+
|
625
|
+
static VALUE
|
626
|
+
grp_putgrent(VALUE self, VALUE io)
|
627
|
+
{
|
628
|
+
struct group grp, *tmp_str;
|
629
|
+
VALUE name = rb_struct_getmember(self,rb_intern("name"));
|
630
|
+
VALUE passwd = rb_struct_getmember(self,rb_intern("passwd"));
|
631
|
+
VALUE path = RFILE_PATH(io);
|
632
|
+
long i;
|
633
|
+
|
634
|
+
ensure_file(io);
|
635
|
+
|
636
|
+
rewind(RFILE_FPTR(io));
|
637
|
+
i = 0;
|
638
|
+
while ( (tmp_str = fgetgrent(RFILE_FPTR(io))) ) {
|
639
|
+
i++;
|
640
|
+
if ( !strcmp(tmp_str->gr_name,StringValuePtr( name ) ) )
|
641
|
+
rb_raise(rb_eArgError, "%s is already mentioned in %s:%ld",
|
642
|
+
tmp_str->gr_name, StringValuePtr(path), i );
|
643
|
+
}
|
644
|
+
|
645
|
+
grp.gr_name = StringValueCStr( name );
|
646
|
+
grp.gr_passwd = StringValueCStr( passwd );
|
647
|
+
grp.gr_gid = NUM2GIDT( rb_struct_getmember(self,rb_intern("gid")) );
|
648
|
+
grp.gr_mem = setup_char_members( rb_struct_getmember(self,rb_intern("members")) );
|
649
|
+
|
650
|
+
if ( putgrent(&grp,RFILE_FPTR(io)) )
|
651
|
+
etcutils_errno(RFILE_PATH(io));
|
652
|
+
|
653
|
+
free_char_members(grp.gr_mem, RARRAY_LEN( rb_struct_getmember(self,rb_intern("members")) ));
|
654
|
+
|
655
|
+
return Qtrue;
|
656
|
+
}
|
657
|
+
|
658
|
+
static VALUE
|
659
|
+
etc_putgrent(VALUE klass, VALUE entry, VALUE io)
|
660
|
+
{
|
661
|
+
return grp_putgrent(entry,io);
|
662
|
+
}
|
663
|
+
|
664
|
+
|
665
|
+
static VALUE
|
666
|
+
sgrp_putsgent(VALUE self, VALUE io)
|
667
|
+
{
|
668
|
+
struct sgrp sgroup, *tmp_str;
|
669
|
+
VALUE name = rb_struct_getmember(self,rb_intern("name"));
|
670
|
+
VALUE passwd = rb_struct_getmember(self,rb_intern("passwd"));
|
671
|
+
VALUE path = RFILE_PATH(io);
|
672
|
+
long i;
|
673
|
+
|
674
|
+
rewind(RFILE_FPTR(io));
|
675
|
+
i = 0;
|
676
|
+
while ( (tmp_str = fgetsgent(RFILE_FPTR(io))) ) {
|
677
|
+
i++;
|
678
|
+
if ( !strcmp(SGRP_NAME(tmp_str),StringValuePtr( name ) ) )
|
679
|
+
rb_raise(rb_eArgError, "%s is already mentioned in %s:%ld",
|
680
|
+
SGRP_NAME(tmp_str), StringValuePtr(path), i );
|
681
|
+
}
|
682
|
+
|
683
|
+
#ifdef HAVE_ST_SG_NAMP
|
684
|
+
sgroup.sg_namp = StringValueCStr( name );
|
685
|
+
#endif
|
686
|
+
#if HAVE_ST_SG_NAME
|
687
|
+
sgroup.sg_name = StringValueCStr( name );
|
688
|
+
#endif
|
689
|
+
|
690
|
+
sgroup.sg_passwd = StringValueCStr( passwd );
|
691
|
+
// char** members start here
|
692
|
+
sgroup.sg_adm = setup_char_members( rb_struct_getmember(self,rb_intern("admins")) );
|
693
|
+
sgroup.sg_mem = setup_char_members( rb_struct_getmember(self,rb_intern("members")) );
|
694
|
+
|
695
|
+
if ( putsgent(&sgroup,RFILE_FPTR(io)) )
|
696
|
+
etcutils_errno(RFILE_PATH(io));
|
697
|
+
|
698
|
+
free_char_members(sgroup.sg_adm, RARRAY_LEN( rb_struct_getmember(self,rb_intern("admins")) ) );
|
699
|
+
free_char_members(sgroup.sg_mem, RARRAY_LEN( rb_struct_getmember(self,rb_intern("members")) ) );
|
700
|
+
|
701
|
+
return Qtrue;
|
702
|
+
}
|
703
|
+
|
704
|
+
static VALUE
|
705
|
+
etcutils_putsgent(VALUE klass, VALUE entry, VALUE io)
|
706
|
+
{
|
707
|
+
return sgrp_putsgent(entry,io);
|
708
|
+
}
|
709
|
+
|
710
|
+
static VALUE
|
711
|
+
etcutils_locked_p(VALUE self)
|
712
|
+
{
|
713
|
+
if (lckpwdf())
|
714
|
+
return Qtrue;
|
715
|
+
else if (!ulckpwdf())
|
716
|
+
return Qfalse;
|
717
|
+
else
|
718
|
+
rb_raise(rb_eIOError,"Unable to determine the locked state of password files");
|
719
|
+
}
|
720
|
+
|
721
|
+
static VALUE
|
722
|
+
etcutils_lckpwdf(VALUE self)
|
723
|
+
{
|
724
|
+
VALUE r;
|
725
|
+
if ( !(r = etcutils_locked_p(self)) ) {
|
726
|
+
if ( !(lckpwdf()) )
|
727
|
+
r = Qtrue;
|
728
|
+
}
|
729
|
+
return r;
|
730
|
+
}
|
731
|
+
|
732
|
+
static VALUE
|
733
|
+
etcutils_ulckpwdf(VALUE self)
|
734
|
+
{
|
735
|
+
VALUE r;
|
736
|
+
if ( (r = etcutils_locked_p(self)) )
|
737
|
+
if ( !(ulckpwdf()) )
|
738
|
+
r = Qtrue;
|
739
|
+
return r;
|
740
|
+
}
|
741
|
+
|
742
|
+
static int in_lock = 0;
|
743
|
+
static int spwd_block = 0;
|
744
|
+
static int pwd_block = 0;
|
745
|
+
static int sgrp_block = 0;
|
746
|
+
static int grp_block = 0;
|
747
|
+
|
748
|
+
static VALUE
|
749
|
+
lock_ensure(void)
|
750
|
+
{
|
751
|
+
ulckpwdf();
|
752
|
+
in_lock = (int)Qfalse;
|
753
|
+
return Qnil;
|
754
|
+
}
|
755
|
+
|
756
|
+
static VALUE
|
757
|
+
etcutils_lock(VALUE self)
|
758
|
+
{
|
759
|
+
if (etcutils_lckpwdf(self)) {
|
760
|
+
if (rb_block_given_p()) {
|
761
|
+
if (in_lock)
|
762
|
+
rb_raise(rb_eRuntimeError, "parallel lock iteration");
|
763
|
+
rb_ensure(rb_yield, Qnil, lock_ensure, 0);
|
764
|
+
return Qnil;
|
765
|
+
}
|
766
|
+
return Qtrue;
|
767
|
+
} else
|
768
|
+
rb_raise(rb_eIOError, "unable to create file lock");
|
769
|
+
}
|
770
|
+
|
771
|
+
static VALUE
|
772
|
+
etcutils_unlock(VALUE self)
|
773
|
+
{
|
774
|
+
return etcutils_ulckpwdf(self);
|
775
|
+
}
|
776
|
+
|
777
|
+
static VALUE
|
778
|
+
shadow_iterate(void)
|
779
|
+
{
|
780
|
+
struct spwd *shadow;
|
781
|
+
|
782
|
+
setspent();
|
783
|
+
while ( (shadow = getspent()) ) {
|
784
|
+
rb_yield(setup_shadow(shadow));
|
785
|
+
}
|
786
|
+
return Qnil;
|
787
|
+
}
|
788
|
+
|
789
|
+
static VALUE
|
790
|
+
shadow_ensure(void)
|
791
|
+
{
|
792
|
+
endspent();
|
793
|
+
spwd_block = (int)Qfalse;
|
794
|
+
return Qnil;
|
795
|
+
}
|
796
|
+
|
797
|
+
static void
|
798
|
+
each_shadow(void)
|
799
|
+
{
|
800
|
+
if (spwd_block)
|
801
|
+
rb_raise(rb_eRuntimeError, "parallel shadow iteration");
|
802
|
+
spwd_block = (int)Qtrue;
|
803
|
+
rb_ensure(shadow_iterate, 0, shadow_ensure, 0);
|
804
|
+
}
|
805
|
+
|
806
|
+
static VALUE
|
807
|
+
pwd_iterate(void)
|
808
|
+
{
|
809
|
+
struct passwd *pwd;
|
810
|
+
|
811
|
+
setspent();
|
812
|
+
while ( (pwd = getpwent()) ) {
|
813
|
+
rb_yield(setup_passwd(pwd));
|
814
|
+
}
|
815
|
+
return Qnil;
|
816
|
+
}
|
817
|
+
|
818
|
+
static VALUE
|
819
|
+
pwd_ensure(void)
|
820
|
+
{
|
821
|
+
endpwent();
|
822
|
+
pwd_block = (int)Qfalse;
|
823
|
+
return Qnil;
|
824
|
+
}
|
825
|
+
|
826
|
+
static void
|
827
|
+
each_passwd(void)
|
828
|
+
{
|
829
|
+
if (pwd_block)
|
830
|
+
rb_raise(rb_eRuntimeError, "parallel passwd iteration");
|
831
|
+
pwd_block = (int)Qtrue;
|
832
|
+
rb_ensure(pwd_iterate, 0, pwd_ensure, 0);
|
833
|
+
}
|
834
|
+
|
835
|
+
|
836
|
+
static VALUE
|
837
|
+
etcutils_getpwent(VALUE self)
|
838
|
+
{
|
839
|
+
struct passwd *pwd;
|
840
|
+
|
841
|
+
if (rb_block_given_p())
|
842
|
+
each_passwd();
|
843
|
+
else if ( (pwd = getpwent()) )
|
844
|
+
return setup_passwd(pwd);
|
845
|
+
return Qnil;
|
846
|
+
}
|
847
|
+
|
848
|
+
|
849
|
+
static VALUE
|
850
|
+
grp_iterate(void)
|
851
|
+
{
|
852
|
+
struct group *grp;
|
853
|
+
|
854
|
+
setgrent();
|
855
|
+
while ( (grp = getgrent()) ) {
|
856
|
+
rb_yield(setup_group(grp));
|
857
|
+
}
|
858
|
+
return Qnil;
|
859
|
+
}
|
860
|
+
|
861
|
+
static VALUE
|
862
|
+
grp_ensure(void)
|
863
|
+
{
|
864
|
+
endgrent();
|
865
|
+
grp_block = (int)Qfalse;
|
866
|
+
return Qnil;
|
867
|
+
}
|
868
|
+
|
869
|
+
static void
|
870
|
+
each_group(void)
|
871
|
+
{
|
872
|
+
if (grp_block)
|
873
|
+
rb_raise(rb_eRuntimeError, "parallel group iteration");
|
874
|
+
grp_block = (int)Qtrue;
|
875
|
+
rb_ensure(grp_iterate, 0, grp_ensure, 0);
|
876
|
+
}
|
877
|
+
|
878
|
+
|
879
|
+
static VALUE
|
880
|
+
etcutils_getgrent(VALUE self)
|
881
|
+
{
|
882
|
+
struct group *grp;
|
883
|
+
|
884
|
+
if (rb_block_given_p())
|
885
|
+
each_group();
|
886
|
+
else if ( (grp = getgrent()) )
|
887
|
+
return setup_group(grp);
|
888
|
+
return Qnil;
|
889
|
+
}
|
890
|
+
|
891
|
+
|
892
|
+
static VALUE
|
893
|
+
etcutils_getspent(VALUE self)
|
894
|
+
{
|
895
|
+
struct spwd *shadow;
|
896
|
+
|
897
|
+
if (rb_block_given_p())
|
898
|
+
each_shadow();
|
899
|
+
else if ( (shadow = getspent()) )
|
900
|
+
return setup_shadow(shadow);
|
901
|
+
return Qnil;
|
902
|
+
}
|
903
|
+
|
904
|
+
static VALUE
|
905
|
+
sgrp_iterate(void)
|
906
|
+
{
|
907
|
+
struct sgrp *sgroup;
|
908
|
+
|
909
|
+
setsgent();
|
910
|
+
while ( (sgroup = getsgent()) ) {
|
911
|
+
rb_yield(setup_gshadow(sgroup));
|
912
|
+
}
|
913
|
+
return Qnil;
|
914
|
+
}
|
915
|
+
|
916
|
+
static VALUE
|
917
|
+
sgrp_ensure(void)
|
918
|
+
{
|
919
|
+
endsgent();
|
920
|
+
sgrp_block = (int)Qfalse;
|
921
|
+
return Qnil;
|
922
|
+
}
|
923
|
+
|
924
|
+
static void
|
925
|
+
each_sgrp(void)
|
926
|
+
{
|
927
|
+
if (sgrp_block)
|
928
|
+
rb_raise(rb_eRuntimeError, "parallel gshadow iteration");
|
929
|
+
sgrp_block = (int)Qtrue;
|
930
|
+
rb_ensure(sgrp_iterate, 0, sgrp_ensure, 0);
|
931
|
+
}
|
932
|
+
|
933
|
+
|
934
|
+
static VALUE
|
935
|
+
etcutils_getsgent(VALUE self)
|
936
|
+
{
|
937
|
+
struct sgrp *sgroup;
|
938
|
+
|
939
|
+
if (rb_block_given_p())
|
940
|
+
each_sgrp();
|
941
|
+
else if ( (sgroup = getsgent()) )
|
942
|
+
return setup_gshadow(sgroup);
|
943
|
+
return Qnil;
|
944
|
+
|
945
|
+
}
|
946
|
+
|
947
|
+
static VALUE
|
948
|
+
strt_to_entry(VALUE self)
|
949
|
+
{
|
950
|
+
VALUE v, ary = rb_ary_new();
|
951
|
+
long i;
|
952
|
+
|
953
|
+
for (i=0; i<RSTRUCT_LEN(self); i++) {
|
954
|
+
v = RSTRUCT_PTR(self)[i];
|
955
|
+
if (NIL_P(v))
|
956
|
+
v = setup_safe_str("");
|
957
|
+
|
958
|
+
if (TYPE(v) == T_ARRAY)
|
959
|
+
rb_ary_push(ary, rb_ary_join( (v), setup_safe_str(",") ));
|
960
|
+
else if (TYPE(v) == T_STRING)
|
961
|
+
rb_ary_push(ary,v);
|
962
|
+
else if (FIXNUM_P(v)) {
|
963
|
+
if (FIX2INT(v) < 0 )
|
964
|
+
v = setup_safe_str("");
|
965
|
+
rb_ary_push(ary,v);
|
966
|
+
} else
|
967
|
+
Check_Type(v, T_STRING);
|
968
|
+
}
|
969
|
+
|
970
|
+
return rb_ary_join(ary, setup_safe_str(":"));
|
971
|
+
}
|
972
|
+
|
973
|
+
static VALUE
|
974
|
+
etcutils_setXXent(VALUE self)
|
975
|
+
{
|
976
|
+
etcutils_setpwent(self);
|
977
|
+
etcutils_setgrent(self);
|
978
|
+
etcutils_setspent(self);
|
979
|
+
etcutils_setsgent(self);
|
980
|
+
return Qnil;
|
981
|
+
}
|
982
|
+
|
983
|
+
static VALUE
|
984
|
+
etcutils_endXXent(VALUE self)
|
985
|
+
{
|
986
|
+
etcutils_endpwent(self);
|
987
|
+
etcutils_endgrent(self);
|
988
|
+
etcutils_endspent(self);
|
989
|
+
etcutils_endsgent(self);
|
990
|
+
return Qnil;
|
991
|
+
}
|
992
|
+
|
993
|
+
void Init_etcutils()
|
994
|
+
{
|
995
|
+
VALUE mEtcUtils = rb_define_module("EtcUtils");
|
996
|
+
rb_extend_object(mEtcUtils, rb_mEnumerable);
|
997
|
+
rb_define_const(mEtcUtils,"VERSION", setup_safe_str(EUVERSION));
|
998
|
+
|
999
|
+
// EtcUtils Constants
|
1000
|
+
rb_define_global_const("PASSWD", setup_safe_str(PASSWD));
|
1001
|
+
rb_define_global_const("SHADOW", setup_safe_str(SHADOW));
|
1002
|
+
rb_define_global_const("GROUP", setup_safe_str(GROUP));
|
1003
|
+
rb_define_global_const("GSHADOW", setup_safe_str(GSHADOW));
|
1004
|
+
|
1005
|
+
// EtcUtils Functions
|
1006
|
+
rb_define_module_function(mEtcUtils,"next_uid",next_uid,-1);
|
1007
|
+
rb_define_module_function(mEtcUtils,"next_gid",next_gid,-1);
|
1008
|
+
rb_define_module_function(mEtcUtils,"next_uid=",next_uid,-1);
|
1009
|
+
rb_define_module_function(mEtcUtils,"next_gid=",next_gid,-1);
|
1010
|
+
rb_define_module_function(mEtcUtils,"setXXent",etcutils_setXXent,0);
|
1011
|
+
rb_define_module_function(mEtcUtils,"endXXent",etcutils_endXXent,0);
|
1012
|
+
|
1013
|
+
// Shadow Functions
|
1014
|
+
rb_define_module_function(mEtcUtils,"getspent",etcutils_getspent,0);
|
1015
|
+
rb_define_module_function(mEtcUtils,"find_spwd",etcutils_getspXXX,1);
|
1016
|
+
rb_define_module_function(mEtcUtils,"setspent",etcutils_setspent,0);
|
1017
|
+
rb_define_module_function(mEtcUtils,"endspent",etcutils_endspent,0);
|
1018
|
+
rb_define_module_function(mEtcUtils,"sgetspent",etcutils_sgetspent,1);
|
1019
|
+
rb_define_module_function(mEtcUtils,"fgetspent",etcutils_fgetspent,1);
|
1020
|
+
rb_define_module_function(mEtcUtils,"putspent",etcutils_putspent,2);
|
1021
|
+
// Backward compatibility
|
1022
|
+
rb_define_module_function(mEtcUtils, "getspnam",etcutils_getspXXX,1);
|
1023
|
+
|
1024
|
+
// Password Functions
|
1025
|
+
rb_define_module_function(mEtcUtils,"getpwent",etcutils_getpwent,0);
|
1026
|
+
rb_define_module_function(mEtcUtils,"find_pwd",etcutils_getpwXXX,1);
|
1027
|
+
rb_define_module_function(mEtcUtils,"setpwent",etcutils_setpwent,0);
|
1028
|
+
rb_define_module_function(mEtcUtils,"endpwent",etcutils_endpwent,0);
|
1029
|
+
rb_define_module_function(mEtcUtils,"fgetpwent",etc_fgetpwent,1);
|
1030
|
+
rb_define_module_function(mEtcUtils,"putpwent",etc_putpwent,2);
|
1031
|
+
// Backward compatibility
|
1032
|
+
rb_define_module_function(mEtcUtils,"getpwnam",etcutils_getpwXXX,1);
|
1033
|
+
|
1034
|
+
// GShadow Functions
|
1035
|
+
rb_define_module_function(mEtcUtils,"getsgent",etcutils_getsgent,0);
|
1036
|
+
rb_define_module_function(mEtcUtils,"find_sgrp",etcutils_getsgXXX,1);
|
1037
|
+
rb_define_module_function(mEtcUtils,"setsgent",etcutils_setsgent,0);
|
1038
|
+
rb_define_module_function(mEtcUtils,"endsgent",etcutils_endsgent,0);
|
1039
|
+
rb_define_module_function(mEtcUtils,"sgetsgent",etcutils_sgetsgent,1);
|
1040
|
+
rb_define_module_function(mEtcUtils,"fgetsgent",etcutils_fgetsgent,1);
|
1041
|
+
rb_define_module_function(mEtcUtils,"putsgent",etcutils_putsgent,2);
|
1042
|
+
// Backward compatibility
|
1043
|
+
rb_define_module_function(mEtcUtils,"getsgnam",etcutils_getsgXXX,1);
|
1044
|
+
|
1045
|
+
// Group Functions
|
1046
|
+
rb_define_module_function(mEtcUtils,"getgrent",etcutils_getgrent,0);
|
1047
|
+
rb_define_module_function(mEtcUtils,"find_grp",etcutils_getgrXXX,1);
|
1048
|
+
rb_define_module_function(mEtcUtils,"setgrent",etcutils_setgrent,0);
|
1049
|
+
rb_define_module_function(mEtcUtils,"endgrent",etcutils_endgrent,0);
|
1050
|
+
rb_define_module_function(mEtcUtils,"fgetgrent",etc_fgetgrent,1);
|
1051
|
+
rb_define_module_function(mEtcUtils,"putgrent",etc_putgrent,2);
|
1052
|
+
// Backward compatibility
|
1053
|
+
rb_define_module_function(mEtcUtils,"getgrnam",etcutils_getgrXXX,1);
|
1054
|
+
|
1055
|
+
// Lock Functions
|
1056
|
+
rb_define_module_function(mEtcUtils,"lckpwdf",etcutils_lckpwdf,0);
|
1057
|
+
rb_define_module_function(mEtcUtils,"ulckpwdf",etcutils_ulckpwdf,0);
|
1058
|
+
rb_define_module_function(mEtcUtils,"lock",etcutils_lock,0);
|
1059
|
+
rb_define_module_function(mEtcUtils,"unlock",etcutils_unlock,0);
|
1060
|
+
rb_define_module_function(mEtcUtils,"locked?",etcutils_locked_p,0);
|
1061
|
+
|
1062
|
+
cPasswd = rb_struct_define(NULL,
|
1063
|
+
"name",
|
1064
|
+
"passwd",
|
1065
|
+
"uid",
|
1066
|
+
"gid",
|
1067
|
+
"gecos",
|
1068
|
+
"dir",
|
1069
|
+
"shell",
|
1070
|
+
NULL);
|
1071
|
+
/* Define-const: Passwd
|
1072
|
+
*
|
1073
|
+
* Passwd is a Struct that contains the following members:
|
1074
|
+
*
|
1075
|
+
* name::
|
1076
|
+
* contains the short login name of the user as a String.
|
1077
|
+
* passwd::
|
1078
|
+
* contains the encrypted password of the user as a String.
|
1079
|
+
* an 'x' is returned if shadow passwords are in use. An '*' is returned
|
1080
|
+
* if the user cannot log in using a password.
|
1081
|
+
* uid::
|
1082
|
+
* contains the integer user ID (uid) of the user.
|
1083
|
+
* gid::
|
1084
|
+
* contains the integer group ID (gid) of the user's primary group.
|
1085
|
+
* dir::
|
1086
|
+
* contains the path to the home directory of the user as a String.
|
1087
|
+
* gecos::
|
1088
|
+
* contains a longer String description of the user, such as a
|
1089
|
+
* full name. Some Unix systems provide structured information
|
1090
|
+
* in the gecos field, but this is system-dependent.
|
1091
|
+
* shell::
|
1092
|
+
* contains the path to the login shell of the user as a String.
|
1093
|
+
*/
|
1094
|
+
rb_define_const(mEtcUtils,"Passwd",cPasswd);
|
1095
|
+
rb_set_class_path(cPasswd, mEtcUtils, "Passwd");
|
1096
|
+
rb_define_singleton_method(cPasswd,"get",etcutils_getpwent,0);
|
1097
|
+
rb_define_singleton_method(cPasswd,"find",etcutils_getpwXXX,1); // -1 return array
|
1098
|
+
rb_define_singleton_method(cPasswd,"parse",etcutils_sgetpwent,1);
|
1099
|
+
rb_define_singleton_method(cPasswd,"set",etcutils_setpwent,0);
|
1100
|
+
rb_define_singleton_method(cPasswd,"end",etcutils_endpwent,0);
|
1101
|
+
rb_define_singleton_method(cPasswd,"each",etcutils_getpwent,0);
|
1102
|
+
rb_define_method(cPasswd, "fputs", pwd_putpwent, 1);
|
1103
|
+
rb_define_method(cPasswd, "to_entry", strt_to_entry,0);
|
1104
|
+
|
1105
|
+
cShadow = rb_struct_define(NULL,
|
1106
|
+
"name",
|
1107
|
+
"passwd",
|
1108
|
+
"last_change",
|
1109
|
+
"min_change",
|
1110
|
+
"max_change",
|
1111
|
+
"warn",
|
1112
|
+
"inactive",
|
1113
|
+
"expire",
|
1114
|
+
"flag",
|
1115
|
+
NULL);
|
1116
|
+
|
1117
|
+
rb_define_const(mEtcUtils,"Shadow",cShadow);
|
1118
|
+
rb_set_class_path(cShadow, mEtcUtils, "Shadow");
|
1119
|
+
rb_define_const(rb_cStruct, "Shadow", cShadow); /* deprecated name */
|
1120
|
+
rb_define_singleton_method(cShadow,"get",etcutils_getspent,0);
|
1121
|
+
rb_define_singleton_method(cShadow,"find",etcutils_getspXXX,1);
|
1122
|
+
rb_define_singleton_method(cShadow,"parse",etcutils_sgetspent,1);
|
1123
|
+
rb_define_singleton_method(cShadow,"set",etcutils_setspent,0);
|
1124
|
+
rb_define_singleton_method(cShadow,"end",etcutils_endspent,0);
|
1125
|
+
rb_define_singleton_method(cShadow,"each",etcutils_getspent,0);
|
1126
|
+
rb_define_method(cShadow, "fputs", spwd_putspent, 1);
|
1127
|
+
rb_define_method(cShadow, "to_entry", strt_to_entry,0);
|
1128
|
+
|
1129
|
+
cGroup = rb_struct_define(NULL,
|
1130
|
+
"name",
|
1131
|
+
"passwd",
|
1132
|
+
"gid",
|
1133
|
+
"members",
|
1134
|
+
NULL);
|
1135
|
+
/* Define-const: Group
|
1136
|
+
*
|
1137
|
+
* The struct contains the following members:
|
1138
|
+
*
|
1139
|
+
* name::
|
1140
|
+
* contains the name of the group as a String.
|
1141
|
+
* passwd::
|
1142
|
+
* contains the encrypted password as a String. An 'x' is
|
1143
|
+
* returned if password access to the group is not available; an empty
|
1144
|
+
* string is returned if no password is needed to obtain membership of
|
1145
|
+
* the group.
|
1146
|
+
* gid::
|
1147
|
+
* contains the group's numeric ID as an integer.
|
1148
|
+
* mem::
|
1149
|
+
* is an Array of Strings containing the short login names of the
|
1150
|
+
* members of the group.
|
1151
|
+
*/
|
1152
|
+
rb_define_class_under(mEtcUtils,"Group",cGroup);
|
1153
|
+
rb_set_class_path(cGroup, mEtcUtils, "Group");
|
1154
|
+
rb_define_singleton_method(cGroup,"get",etcutils_getgrent,0);
|
1155
|
+
rb_define_singleton_method(cGroup,"find",etcutils_getgrXXX,1);
|
1156
|
+
rb_define_singleton_method(cGroup,"parse",etcutils_sgetgrent,1);
|
1157
|
+
rb_define_singleton_method(cGroup,"set",etcutils_setgrent,0);
|
1158
|
+
rb_define_singleton_method(cGroup,"end",etcutils_endgrent,0);
|
1159
|
+
rb_define_singleton_method(cGroup,"each",etcutils_getgrent,0);
|
1160
|
+
rb_define_method(cGroup, "fputs", grp_putgrent, 1);
|
1161
|
+
rb_define_method(cGroup, "to_entry", strt_to_entry,0);
|
1162
|
+
|
1163
|
+
cGShadow = rb_struct_define(NULL,
|
1164
|
+
"name",
|
1165
|
+
"passwd",
|
1166
|
+
"admins",
|
1167
|
+
"members",
|
1168
|
+
NULL);
|
1169
|
+
|
1170
|
+
rb_define_const(mEtcUtils, "GShadow",cGShadow);
|
1171
|
+
rb_define_const(mEtcUtils, "Gshadow",cGShadow);
|
1172
|
+
rb_set_class_path(cGShadow, mEtcUtils, "GShadow");
|
1173
|
+
rb_define_const(rb_cStruct, "GShadow", cGShadow); /* deprecated name */
|
1174
|
+
rb_define_singleton_method(cGShadow,"get",etcutils_getsgent,0);
|
1175
|
+
rb_define_singleton_method(cGShadow,"find",etcutils_getsgXXX,1); //getsgent, getsguid
|
1176
|
+
rb_define_singleton_method(cGShadow,"parse",etcutils_sgetsgent,1);
|
1177
|
+
rb_define_singleton_method(cGShadow,"set",etcutils_setsgent,0);
|
1178
|
+
rb_define_singleton_method(cGShadow,"end",etcutils_endsgent,0);
|
1179
|
+
rb_define_singleton_method(cGShadow,"each",etcutils_getsgent,0);
|
1180
|
+
rb_define_method(cGShadow, "fputs", sgrp_putsgent, 1);
|
1181
|
+
rb_define_method(cGShadow, "to_entry", strt_to_entry,0);
|
1182
|
+
}
|