Ruby  2.0.0p648(2015-12-16revision53162)
etc.c
Go to the documentation of this file.
1 /************************************************
2 
3  etc.c -
4 
5  $Author: usa $
6  created at: Tue Mar 22 18:39:19 JST 1994
7 
8 ************************************************/
9 
10 #include "ruby.h"
11 #include "ruby/encoding.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;
27 #ifdef HAVE_GETGRENT
28 static VALUE sGroup;
29 #endif
30 
31 #ifdef _WIN32
32 #include <shlobj.h>
33 #ifndef CSIDL_COMMON_APPDATA
34 #define CSIDL_COMMON_APPDATA 35
35 #endif
36 #endif
37 
38 #ifndef _WIN32
39 char *getenv();
40 #endif
41 char *getlogin();
42 
43 /* call-seq:
44  * getlogin -> String
45  *
46  * Returns the short user name of the currently logged in user.
47  * Unfortunately, it is often rather easy to fool ::getlogin.
48  *
49  * Avoid ::getlogin for security-related purposes.
50  *
51  * If ::getlogin fails, try ::getpwuid.
52  *
53  * See the unix manpage for <code>getpwuid(3)</code> for more detail.
54  *
55  * e.g.
56  * Etc.getlogin -> 'guest'
57  */
58 static VALUE
60 {
61  char *login;
62 
63  rb_secure(4);
64 #ifdef HAVE_GETLOGIN
65  login = getlogin();
66  if (!login) login = getenv("USER");
67 #else
68  login = getenv("USER");
69 #endif
70 
71  if (login) {
72 #ifdef _WIN32
73  rb_encoding *extenc = rb_utf8_encoding();
74 #else
75  rb_encoding *extenc = rb_locale_encoding();
76 #endif
77  return rb_external_str_new_with_enc(login, strlen(login), extenc);
78  }
79 
80  return Qnil;
81 }
82 
83 #if defined(HAVE_GETPWENT) || defined(HAVE_GETGRENT)
84 static VALUE
85 safe_setup_str(const char *str)
86 {
87  if (str == 0) str = "";
88  return rb_tainted_str_new2(str);
89 }
90 #endif
91 
92 #ifdef HAVE_GETPWENT
93 static VALUE
94 setup_passwd(struct passwd *pwd)
95 {
96  if (pwd == 0) rb_sys_fail("/etc/passwd");
97  return rb_struct_new(sPasswd,
98  safe_setup_str(pwd->pw_name),
99 #ifdef HAVE_ST_PW_PASSWD
100  safe_setup_str(pwd->pw_passwd),
101 #endif
102  UIDT2NUM(pwd->pw_uid),
103  GIDT2NUM(pwd->pw_gid),
104 #ifdef HAVE_ST_PW_GECOS
105  safe_setup_str(pwd->pw_gecos),
106 #endif
107  safe_setup_str(pwd->pw_dir),
108  safe_setup_str(pwd->pw_shell),
109 #ifdef HAVE_ST_PW_CHANGE
110  INT2NUM(pwd->pw_change),
111 #endif
112 #ifdef HAVE_ST_PW_QUOTA
113  INT2NUM(pwd->pw_quota),
114 #endif
115 #ifdef HAVE_ST_PW_AGE
116  PW_AGE2VAL(pwd->pw_age),
117 #endif
118 #ifdef HAVE_ST_PW_CLASS
119  safe_setup_str(pwd->pw_class),
120 #endif
121 #ifdef HAVE_ST_PW_COMMENT
122  safe_setup_str(pwd->pw_comment),
123 #endif
124 #ifdef HAVE_ST_PW_EXPIRE
125  INT2NUM(pwd->pw_expire),
126 #endif
127  0 /*dummy*/
128  );
129 }
130 #endif
131 
132 /* call-seq:
133  * getpwuid(uid) -> Passwd
134  *
135  * Returns the /etc/passwd information for the user with the given integer +uid+.
136  *
137  * The information is returned as a Passwd struct.
138  *
139  * If +uid+ is omitted, the value from <code>Passwd[:uid]</code> is returned
140  * instead.
141  *
142  * See the unix manpage for <code>getpwuid(3)</code> for more detail.
143  *
144  * === Example:
145  *
146  * Etc.getpwuid(0)
147  * #=> #<struct Struct::Passwd name="root", passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash">
148  */
149 static VALUE
151 {
152 #if defined(HAVE_GETPWENT)
153  VALUE id;
154  rb_uid_t uid;
155  struct passwd *pwd;
156 
157  rb_secure(4);
158  if (rb_scan_args(argc, argv, "01", &id) == 1) {
159  uid = NUM2UIDT(id);
160  }
161  else {
162  uid = getuid();
163  }
164  pwd = getpwuid(uid);
165  if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %d", (int)uid);
166  return setup_passwd(pwd);
167 #else
168  return Qnil;
169 #endif
170 }
171 
172 /* call-seq:
173  * getpwnam(name) -> Passwd
174  *
175  * Returns the /etc/passwd information for the user with specified login
176  * +name+.
177  *
178  * The information is returned as a Passwd struct.
179  *
180  * See the unix manpage for <code>getpwnam(3)</code> for more detail.
181  *
182  * === Example:
183  *
184  * Etc.getpwnam('root')
185  * #=> #<struct Struct::Passwd name="root", passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash">
186  */
187 static VALUE
189 {
190 #ifdef HAVE_GETPWENT
191  struct passwd *pwd;
192 
193  SafeStringValue(nam);
194  pwd = getpwnam(RSTRING_PTR(nam));
195  if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %"PRIsVALUE, nam);
196  return setup_passwd(pwd);
197 #else
198  return Qnil;
199 #endif
200 }
201 
202 #ifdef HAVE_GETPWENT
203 static int passwd_blocking = 0;
204 static VALUE
205 passwd_ensure(void)
206 {
207  endpwent();
208  passwd_blocking = (int)Qfalse;
209  return Qnil;
210 }
211 
212 static VALUE
213 passwd_iterate(void)
214 {
215  struct passwd *pw;
216 
217  setpwent();
218  while (pw = getpwent()) {
219  rb_yield(setup_passwd(pw));
220  }
221  return Qnil;
222 }
223 
224 static void
225 each_passwd(void)
226 {
227  if (passwd_blocking) {
228  rb_raise(rb_eRuntimeError, "parallel passwd iteration");
229  }
230  passwd_blocking = (int)Qtrue;
231  rb_ensure(passwd_iterate, 0, passwd_ensure, 0);
232 }
233 #endif
234 
235 /* call-seq:
236  * Etc.passwd { |struct| block } -> Passwd
237  * Etc.passwd -> Passwd
238  *
239  * Provides a convenient Ruby iterator which executes a block for each entry
240  * in the /etc/passwd file.
241  *
242  * The code block is passed an Passwd struct.
243  *
244  * See ::getpwent above for details.
245  *
246  * Example:
247  *
248  * require 'etc'
249  *
250  * Etc.passwd {|u|
251  * puts u.name + " = " + u.gecos
252  * }
253  *
254  */
255 static VALUE
257 {
258 #ifdef HAVE_GETPWENT
259  struct passwd *pw;
260 
261  rb_secure(4);
262  if (rb_block_given_p()) {
263  each_passwd();
264  }
265  else if (pw = getpwent()) {
266  return setup_passwd(pw);
267  }
268 #endif
269  return Qnil;
270 }
271 
272 /* call-seq:
273  * Etc::Passwd.each { |struct| block } -> Passwd
274  * Etc::Passwd.each -> Enumerator
275  *
276  * Iterates for each entry in the /etc/passwd file if a block is given.
277  *
278  * If no block is given, returns the Enumerator.
279  *
280  * The code block is passed an Passwd struct.
281  *
282  * See ::getpwent above for details.
283  *
284  * Example:
285  *
286  * require 'etc'
287  *
288  * Etc::Passwd.each {|u|
289  * puts u.name + " = " + u.gecos
290  * }
291  *
292  * Etc::Passwd.collect {|u| u.gecos}
293  * Etc::Passwd.collect {|u| u.gecos}
294  *
295  */
296 static VALUE
298 {
299 #ifdef HAVE_GETPWENT
300  RETURN_ENUMERATOR(obj, 0, 0);
301  each_passwd();
302 #endif
303  return obj;
304 }
305 
306 /* Resets the process of reading the /etc/passwd file, so that the next call
307  * to ::getpwent will return the first entry again.
308  */
309 static VALUE
311 {
312 #ifdef HAVE_GETPWENT
313  setpwent();
314 #endif
315  return Qnil;
316 }
317 
318 /* Ends the process of scanning through the /etc/passwd file begun with
319  * ::getpwent, and closes the file.
320  */
321 static VALUE
323 {
324 #ifdef HAVE_GETPWENT
325  endpwent();
326 #endif
327  return Qnil;
328 }
329 
330 /* Returns an entry from the /etc/passwd file.
331  *
332  * The first time it is called it opens the file and returns the first entry;
333  * each successive call returns the next entry, or +nil+ if the end of the file
334  * has been reached.
335  *
336  * To close the file when processing is complete, call ::endpwent.
337  *
338  * Each entry is returned as a Passwd struct.
339  *
340  */
341 static VALUE
343 {
344 #ifdef HAVE_GETPWENT
345  struct passwd *pw;
346 
347  if (pw = getpwent()) {
348  return setup_passwd(pw);
349  }
350 #endif
351  return Qnil;
352 }
353 
354 #ifdef HAVE_GETGRENT
355 static VALUE
356 setup_group(struct group *grp)
357 {
358  VALUE mem;
359  char **tbl;
360 
361  mem = rb_ary_new();
362  tbl = grp->gr_mem;
363  while (*tbl) {
364  rb_ary_push(mem, safe_setup_str(*tbl));
365  tbl++;
366  }
367  return rb_struct_new(sGroup,
368  safe_setup_str(grp->gr_name),
369 #ifdef HAVE_ST_GR_PASSWD
370  safe_setup_str(grp->gr_passwd),
371 #endif
372  GIDT2NUM(grp->gr_gid),
373  mem);
374 }
375 #endif
376 
377 /* call-seq:
378  * getgrgid(group_id) -> Group
379  *
380  * Returns information about the group with specified integer +group_id+,
381  * as found in /etc/group.
382  *
383  * The information is returned as a Group struct.
384  *
385  * See the unix manpage for <code>getgrgid(3)</code> for more detail.
386  *
387  * === Example:
388  *
389  * Etc.getgrgid(100)
390  * #=> #<struct Struct::Group name="users", passwd="x", gid=100, mem=["meta", "root"]>
391  *
392  */
393 static VALUE
395 {
396 #ifdef HAVE_GETGRENT
397  VALUE id;
398  gid_t gid;
399  struct group *grp;
400 
401  rb_secure(4);
402  if (rb_scan_args(argc, argv, "01", &id) == 1) {
403  gid = NUM2GIDT(id);
404  }
405  else {
406  gid = getgid();
407  }
408  grp = getgrgid(gid);
409  if (grp == 0) rb_raise(rb_eArgError, "can't find group for %d", (int)gid);
410  return setup_group(grp);
411 #else
412  return Qnil;
413 #endif
414 }
415 
416 /* call-seq:
417  * getgrnam(name) -> Group
418  *
419  * Returns information about the group with specified +name+, as found in
420  * /etc/group.
421  *
422  * The information is returned as a Group struct.
423  *
424  * See the unix manpage for <code>getgrnam(3)</code> for more detail.
425  *
426  * === Example:
427  *
428  * Etc.getgrnam('users')
429  * #=> #<struct Struct::Group name="users", passwd="x", gid=100, mem=["meta", "root"]>
430  *
431  */
432 static VALUE
434 {
435 #ifdef HAVE_GETGRENT
436  struct group *grp;
437 
438  rb_secure(4);
439  SafeStringValue(nam);
440  grp = getgrnam(RSTRING_PTR(nam));
441  if (grp == 0) rb_raise(rb_eArgError, "can't find group for %"PRIsVALUE, nam);
442  return setup_group(grp);
443 #else
444  return Qnil;
445 #endif
446 }
447 
448 #ifdef HAVE_GETGRENT
449 static int group_blocking = 0;
450 static VALUE
451 group_ensure(void)
452 {
453  endgrent();
454  group_blocking = (int)Qfalse;
455  return Qnil;
456 }
457 
458 
459 static VALUE
460 group_iterate(void)
461 {
462  struct group *pw;
463 
464  setgrent();
465  while (pw = getgrent()) {
466  rb_yield(setup_group(pw));
467  }
468  return Qnil;
469 }
470 
471 static void
472 each_group(void)
473 {
474  if (group_blocking) {
475  rb_raise(rb_eRuntimeError, "parallel group iteration");
476  }
477  group_blocking = (int)Qtrue;
478  rb_ensure(group_iterate, 0, group_ensure, 0);
479 }
480 #endif
481 
482 /* Provides a convenient Ruby iterator which executes a block for each entry
483  * in the /etc/group file.
484  *
485  * The code block is passed an Group struct.
486  *
487  * See ::getgrent above for details.
488  *
489  * Example:
490  *
491  * require 'etc'
492  *
493  * Etc.group {|g|
494  * puts g.name + ": " + g.mem.join(', ')
495  * }
496  *
497  */
498 static VALUE
500 {
501 #ifdef HAVE_GETGRENT
502  struct group *grp;
503 
504  rb_secure(4);
505  if (rb_block_given_p()) {
506  each_group();
507  }
508  else if (grp = getgrent()) {
509  return setup_group(grp);
510  }
511 #endif
512  return Qnil;
513 }
514 
515 #ifdef HAVE_GETGRENT
516 /* call-seq:
517  * Etc::Group.each { |group| block } -> obj
518  * Etc::Group.each -> Enumerator
519  *
520  * Iterates for each entry in the /etc/group file if a block is given.
521  *
522  * If no block is given, returns the Enumerator.
523  *
524  * The code block is passed a Group struct.
525  *
526  * Example:
527  *
528  * require 'etc'
529  *
530  * Etc::Group.each {|g|
531  * puts g.name + ": " + g.mem.join(', ')
532  * }
533  *
534  * Etc::Group.collect {|g| g.name}
535  * Etc::Group.select {|g| !g.mem.empty?}
536  *
537  */
538 static VALUE
539 etc_each_group(VALUE obj)
540 {
541  RETURN_ENUMERATOR(obj, 0, 0);
542  each_group();
543  return obj;
544 }
545 #endif
546 
547 /* Resets the process of reading the /etc/group file, so that the next call
548  * to ::getgrent will return the first entry again.
549  */
550 static VALUE
552 {
553 #ifdef HAVE_GETGRENT
554  setgrent();
555 #endif
556  return Qnil;
557 }
558 
559 /* Ends the process of scanning through the /etc/group file begun by
560  * ::getgrent, and closes the file.
561  */
562 static VALUE
564 {
565 #ifdef HAVE_GETGRENT
566  endgrent();
567 #endif
568  return Qnil;
569 }
570 
571 /* Returns an entry from the /etc/group file.
572  *
573  * The first time it is called it opens the file and returns the first entry;
574  * each successive call returns the next entry, or +nil+ if the end of the file
575  * has been reached.
576  *
577  * To close the file when processing is complete, call ::endgrent.
578  *
579  * Each entry is returned as a Group struct
580  */
581 static VALUE
583 {
584 #ifdef HAVE_GETGRENT
585  struct group *gr;
586 
587  if (gr = getgrent()) {
588  return setup_group(gr);
589  }
590 #endif
591  return Qnil;
592 }
593 
594 #define numberof(array) (sizeof(array) / sizeof(*(array)))
595 
596 #ifdef _WIN32
598 UINT rb_w32_system_tmpdir(WCHAR *path, UINT len);
599 VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc);
600 #endif
601 
602 /*
603  * Returns system configuration directory.
604  *
605  * This is typically "/etc", but is modified by the prefix used when Ruby was
606  * compiled. For example, if Ruby is built and installed in /usr/local, returns
607  * "/usr/local/etc".
608  */
609 static VALUE
611 {
612 #ifdef _WIN32
614 #else
615  return rb_filesystem_str_new_cstr(SYSCONFDIR);
616 #endif
617 }
618 
619 /*
620  * Returns system temporary directory; typically "/tmp".
621  */
622 static VALUE
624 {
625  VALUE tmpdir;
626 #ifdef _WIN32
627  WCHAR path[_MAX_PATH];
628  UINT len = rb_w32_system_tmpdir(path, numberof(path));
629  if (!len) return Qnil;
631 #else
632  tmpdir = rb_filesystem_str_new_cstr("/tmp");
633 #endif
634  FL_UNSET(tmpdir, FL_TAINT|FL_UNTRUSTED);
635  return tmpdir;
636 }
637 
638 /*
639  * The Etc module provides access to information typically stored in
640  * files in the /etc directory on Unix systems.
641  *
642  * The information accessible consists of the information found in the
643  * /etc/passwd and /etc/group files, plus information about the system's
644  * temporary directory (/tmp) and configuration directory (/etc).
645  *
646  * The Etc module provides a more reliable way to access information about
647  * the logged in user than environment variables such as +$USER+.
648  *
649  * == Example:
650  *
651  * require 'etc'
652  *
653  * login = Etc.getlogin
654  * info = Etc.getpwnam(login)
655  * username = info.gecos.split(/,/).first
656  * puts "Hello #{username}, I see your login name is #{login}"
657  *
658  * Note that the methods provided by this module are not always secure.
659  * It should be used for informational purposes, and not for security.
660  *
661  * All operations defined in this module are class methods, so that you can
662  * include the Etc module into your class.
663  */
664 void
665 Init_etc(void)
666 {
667  VALUE mEtc;
668 
669  mEtc = rb_define_module("Etc");
670  rb_define_module_function(mEtc, "getlogin", etc_getlogin, 0);
671 
672  rb_define_module_function(mEtc, "getpwuid", etc_getpwuid, -1);
673  rb_define_module_function(mEtc, "getpwnam", etc_getpwnam, 1);
674  rb_define_module_function(mEtc, "setpwent", etc_setpwent, 0);
675  rb_define_module_function(mEtc, "endpwent", etc_endpwent, 0);
676  rb_define_module_function(mEtc, "getpwent", etc_getpwent, 0);
677  rb_define_module_function(mEtc, "passwd", etc_passwd, 0);
678 
679  rb_define_module_function(mEtc, "getgrgid", etc_getgrgid, -1);
680  rb_define_module_function(mEtc, "getgrnam", etc_getgrnam, 1);
681  rb_define_module_function(mEtc, "group", etc_group, 0);
682  rb_define_module_function(mEtc, "setgrent", etc_setgrent, 0);
683  rb_define_module_function(mEtc, "endgrent", etc_endgrent, 0);
684  rb_define_module_function(mEtc, "getgrent", etc_getgrent, 0);
685  rb_define_module_function(mEtc, "sysconfdir", etc_sysconfdir, 0);
686  rb_define_module_function(mEtc, "systmpdir", etc_systmpdir, 0);
687 
688  sPasswd = rb_struct_define("Passwd",
689  "name", "passwd", "uid", "gid",
690 #ifdef HAVE_ST_PW_GECOS
691  "gecos",
692 #endif
693  "dir", "shell",
694 #ifdef HAVE_ST_PW_CHANGE
695  "change",
696 #endif
697 #ifdef HAVE_ST_PW_QUOTA
698  "quota",
699 #endif
700 #ifdef HAVE_ST_PW_AGE
701  "age",
702 #endif
703 #ifdef HAVE_ST_PW_CLASS
704  "uclass",
705 #endif
706 #ifdef HAVE_ST_PW_COMMENT
707  "comment",
708 #endif
709 #ifdef HAVE_ST_PW_EXPIRE
710  "expire",
711 #endif
712  NULL);
713  /* Define-const: Passwd
714  *
715  * Passwd is a Struct that contains the following members:
716  *
717  * name::
718  * contains the short login name of the user as a String.
719  * passwd::
720  * contains the encrypted password of the user as a String.
721  * an 'x' is returned if shadow passwords are in use. An '*' is returned
722  * if the user cannot log in using a password.
723  * uid::
724  * contains the integer user ID (uid) of the user.
725  * gid::
726  * contains the integer group ID (gid) of the user's primary group.
727  * dir::
728  * contains the path to the home directory of the user as a String.
729  * shell::
730  * contains the path to the login shell of the user as a String.
731  *
732  * === The following members below are optional, and must be compiled with special flags:
733  *
734  * gecos::
735  * contains a longer String description of the user, such as
736  * a full name. Some Unix systems provide structured information in the
737  * gecos field, but this is system-dependent.
738  * must be compiled with +HAVE_ST_PW_GECOS+
739  * change::
740  * password change time(integer) must be compiled with +HAVE_ST_PW_CHANGE+
741  * quota::
742  * quota value(integer) must be compiled with +HAVE_ST_PW_QUOTA+
743  * age::
744  * password age(integer) must be compiled with +HAVE_ST_PW_AGE+
745  * class::
746  * user access class(string) must be compiled with +HAVE_ST_PW_CLASS+
747  * comment::
748  * comment(string) must be compiled with +HAVE_ST_PW_COMMENT+
749  * expire::
750  * account expiration time(integer) must be compiled with +HAVE_ST_PW_EXPIRE+
751  */
752  rb_define_const(mEtc, "Passwd", sPasswd);
755 
756 #ifdef HAVE_GETGRENT
757  sGroup = rb_struct_define("Group", "name",
758 #ifdef HAVE_ST_GR_PASSWD
759  "passwd",
760 #endif
761  "gid", "mem", NULL);
762 
763  /* Define-const: Group
764  *
765  * Group is a Struct that is only available when compiled with +HAVE_GETGRENT+.
766  *
767  * The struct contains the following members:
768  *
769  * name::
770  * contains the name of the group as a String.
771  * passwd::
772  * contains the encrypted password as a String. An 'x' is
773  * returned if password access to the group is not available; an empty
774  * string is returned if no password is needed to obtain membership of
775  * the group.
776  *
777  * Must be compiled with +HAVE_ST_GR_PASSWD+.
778  * gid::
779  * contains the group's numeric ID as an integer.
780  * mem::
781  * is an Array of Strings containing the short login names of the
782  * members of the group.
783  */
784  rb_define_const(mEtc, "Group", sGroup);
786  rb_define_singleton_method(sGroup, "each", etc_each_group, 0);
787 #endif
788 }
#define NUM2UIDT(v)
Definition: ruby.h:338
static VALUE sPasswd
Definition: etc.c:26
static VALUE etc_getpwnam(VALUE obj, VALUE nam)
Definition: etc.c:188
static VALUE etc_endgrent(VALUE obj)
Definition: etc.c:563
size_t strlen(const char *)
#define INT2NUM(x)
Definition: ruby.h:1178
static VALUE etc_group(VALUE obj)
Definition: etc.c:499
rb_uid_t getuid(void)
Definition: win32.c:2398
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1497
#define FL_TAINT
Definition: ruby.h:1115
static VALUE etc_setpwent(VALUE obj)
Definition: etc.c:310
static VALUE etc_getpwent(VALUE obj)
Definition: etc.c:342
#define Qtrue
Definition: ruby.h:434
static VALUE etc_setgrent(VALUE obj)
Definition: etc.c:551
const int id
Definition: nkf.c:209
VALUE rb_external_str_new_with_enc(const char *ptr, long len, rb_encoding *)
Definition: string.c:569
VALUE rb_struct_new(VALUE,...)
Definition: struct.c:448
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
static VALUE etc_getgrnam(VALUE obj, VALUE nam)
Definition: etc.c:433
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1788
static VALUE etc_systmpdir(void)
Definition: etc.c:623
#define CSIDL_COMMON_APPDATA
Definition: win32.c:370
VALUE rb_tainted_str_new2(const char *)
static VALUE etc_getpwuid(int argc, VALUE *argv, VALUE obj)
Definition: etc.c:150
rb_encoding * rb_utf8_encoding(void)
Definition: encoding.c:1166
char * getenv()
#define FL_UNTRUSTED
Definition: ruby.h:1116
static VALUE etc_passwd(VALUE obj)
Definition: etc.c:256
VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc)
Definition: win32.c:1959
void Init_etc(void)
Definition: etc.c:665
int rb_block_given_p(void)
Definition: eval.c:672
VALUE rb_eRuntimeError
Definition: error.c:515
VALUE rb_ary_new(void)
Definition: array.c:424
static VALUE etc_getgrgid(int argc, VALUE *argv, VALUE obj)
Definition: etc.c:394
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2204
int argc
Definition: ruby.c:130
#define Qfalse
Definition: ruby.h:433
UINT rb_w32_system_tmpdir(WCHAR *path, UINT len)
Definition: win32.c:460
#define numberof(array)
Definition: etc.c:594
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1512
VALUE rb_yield(VALUE)
Definition: vm_eval.c:933
VALUE rb_mEnumerable
Definition: enum.c:20
static VALUE etc_getlogin(VALUE obj)
Definition: etc.c:59
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
#define PRIsVALUE
Definition: ruby.h:147
#define Qnil
Definition: ruby.h:435
int type
Definition: tcltklib.c:111
unsigned long VALUE
Definition: ruby.h:104
rb_encoding * rb_locale_encoding(void)
Definition: encoding.c:1212
void rb_extend_object(VALUE obj, VALUE module)
Definition: eval.c:1240
#define NUM2GIDT(v)
Definition: ruby.h:344
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
Definition: eval.c:804
void rb_sys_fail(const char *mesg)
Definition: error.c:1907
#define FL_UNSET(x, f)
Definition: ruby.h:1150
#define RSTRING_PTR(str)
Definition: ruby.h:866
char * getlogin()
Definition: win32.c:776
static VALUE etc_each_passwd(VALUE obj)
Definition: etc.c:297
VALUE rb_w32_special_folder(int type)
Definition: win32.c:449
static VALUE etc_endpwent(VALUE obj)
Definition: etc.c:322
#define GIDT2NUM(v)
Definition: ruby.h:341
rb_encoding * rb_filesystem_encoding(void)
Definition: encoding.c:1246
#define RETURN_ENUMERATOR(obj, argc, argv)
Definition: intern.h:220
#define SafeStringValue(v)
Definition: ruby.h:552
VALUE rb_filesystem_str_new_cstr(const char *)
Definition: string.c:614
#define UIDT2NUM(v)
Definition: ruby.h:335
rb_gid_t getgid(void)
Definition: win32.c:2412
void rb_secure(int)
Definition: safe.c:79
VALUE rb_struct_define(const char *,...)
Definition: struct.c:279
VALUE rb_define_module(const char *name)
Definition: class.c:606
#define NULL
Definition: _sdbm.c:102
static VALUE etc_sysconfdir(VALUE obj)
Definition: etc.c:610
VALUE rb_eArgError
Definition: error.c:517
static VALUE etc_getgrent(VALUE obj)
Definition: etc.c:582
char ** argv
Definition: ruby.c:131