ext/etc/etc.c


DEFINITIONS

This source file includes following functions.
  1. etc_getlogin
  2. setup_passwd
  3. etc_getpwuid
  4. etc_getpwnam
  5. passwd_ensure
  6. passwd_iterate
  7. etc_passwd
  8. setup_group
  9. etc_getgrgid
  10. etc_getgrnam
  11. group_ensure
  12. group_iterate
  13. etc_group
  14. Init_etc


   1  /************************************************
   2  
   3    etc.c -
   4  
   5    $Author: eban $
   6    $Date: 2002/09/08 10:00:43 $
   7    created at: Tue Mar 22 18:39:19 JST 1994
   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              /*dummy*/
  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  }