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