Пример #1
0
static void
check_dirname(volatile VALUE *dir)
{
    char *path, *pend;

    rb_secure(2);
    FilePathValue(*dir);
    path = RSTRING_PTR(*dir);
    if (path && *(pend = rb_path_end(rb_path_skip_prefix(path)))) {
	*dir = rb_str_new(path, pend - path);
    }
}
Пример #2
0
/*
 * Document-method: setsockopt
 * call-seq:
 *   setsockopt(level, optname, optval)
 *   setsockopt(socketoption)
 *
 * Sets a socket option. These are protocol and system specific, see your
 * local system documentation for details.
 *
 * === Parameters
 * * +level+ is an integer, usually one of the SOL_ constants such as
 *   Socket::SOL_SOCKET, or a protocol level.
 *   A string or symbol of the name, possibly without prefix, is also
 *   accepted.
 * * +optname+ is an integer, usually one of the SO_ constants, such
 *   as Socket::SO_REUSEADDR.
 *   A string or symbol of the name, possibly without prefix, is also
 *   accepted.
 * * +optval+ is the value of the option, it is passed to the underlying
 *   setsockopt() as a pointer to a certain number of bytes. How this is
 *   done depends on the type:
 *   - Fixnum: value is assigned to an int, and a pointer to the int is
 *     passed, with length of sizeof(int).
 *   - true or false: 1 or 0 (respectively) is assigned to an int, and the
 *     int is passed as for a Fixnum. Note that +false+ must be passed,
 *     not +nil+.
 *   - String: the string's data and length is passed to the socket.
 * * +socketoption+ is an instance of Socket::Option
 *
 * === Examples
 *
 * Some socket options are integers with boolean values, in this case
 * #setsockopt could be called like this:
 *   sock.setsockopt(:SOCKET, :REUSEADDR, true)
 *   sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
 *   sock.setsockopt(Socket::Option.bool(:INET, :SOCKET, :REUSEADDR, true))
 *
 * Some socket options are integers with numeric values, in this case
 * #setsockopt could be called like this:
 *   sock.setsockopt(:IP, :TTL, 255)
 *   sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, 255)
 *   sock.setsockopt(Socket::Option.int(:INET, :IP, :TTL, 255))
 *
 * Option values may be structs. Passing them can be complex as it involves
 * examining your system headers to determine the correct definition. An
 * example is an +ip_mreq+, which may be defined in your system headers as:
 *   struct ip_mreq {
 *     struct  in_addr imr_multiaddr;
 *     struct  in_addr imr_interface;
 *   };
 *
 * In this case #setsockopt could be called like this:
 *   optval = IPAddr.new("224.0.0.251").hton +
 *            IPAddr.new(Socket::INADDR_ANY, Socket::AF_INET).hton
 *   sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, optval)
 *
*/
static VALUE
bsock_setsockopt(int argc, VALUE *argv, VALUE sock)
{
UNRUBBY_SOCKET_HACK;
    VALUE lev, optname, val;
    int family, level, option;
    rb_io_t *fptr;
    int i;
    char *v;
    int vlen;

    if (argc == 1) {
        lev = rb_funcall(argv[0], rb_intern("level"), 0);
        optname = rb_funcall(argv[0], rb_intern("optname"), 0);
        val = rb_funcall(argv[0], rb_intern("data"), 0);
    }
    else {
        rb_scan_args(argc, argv, "30", &lev, &optname, &val);
    }

    rb_secure(2);
    GetOpenFile(sock, fptr);
    family = rsock_getfamily(fptr->fd);
    level = rsock_level_arg(family, lev);
    option = rsock_optname_arg(family, level, optname);

    switch (TYPE(val)) {
      case T_FIXNUM:
	i = FIX2INT(val);
	goto numval;
      case T_FALSE:
	i = 0;
	goto numval;
      case T_TRUE:
	i = 1;
      numval:
	v = (char*)&i; vlen = (int)sizeof(i);
	break;
      default:
	StringValue(val);
	v = RSTRING_PTR(val);
	vlen = RSTRING_LENINT(val);
	break;
    }

#define rb_sys_fail_path(path) rb_sys_fail(NIL_P(path) ? 0 : RSTRING_PTR(path))

    rb_io_check_closed(fptr);
    if (setsockopt(fptr->fd, level, option, v, vlen) < 0)
	rb_sys_fail_path(fptr->pathv);

    return INT2FIX(0);
}
Пример #3
0
static VALUE
env_size(VALUE rcv, SEL sel)
{
    rb_secure(4);

    char **env = GET_ENVIRON();
    int i = 0;
    while (env[i] != NULL) {
	i++;
    }
    return INT2FIX(i);
}
Пример #4
0
static VALUE fcgi_stream_write(VALUE self, VALUE str)
{
  FCGX_Stream *stream;
  int len;

  rb_secure(4);
  Data_Get_Struct(self, FCGX_Stream, stream);
  str = rb_obj_as_string(str);
  len = FCGX_PutStr(RSTRING_PTR(str), RSTRING_LEN(str), stream);
  if (len == EOF) CHECK_STREAM_ERROR(stream);
  return INT2NUM(len);
}
Пример #5
0
/*
 *  call-seq:
 *     Dir.getwd => string
 *     Dir.pwd => string
 *
 *  Returns the path to the current working directory of this process as
 *  a string.
 *
 *     Dir.chdir("/tmp")   #=> 0
 *     Dir.getwd           #=> "/tmp"
 */
static VALUE
dir_s_getwd(VALUE dir)
{
    char *path;
    VALUE cwd;

    rb_secure(4);
    path = my_getcwd();
    cwd = rb_tainted_str_new2(path);

    xfree(path);
    return cwd;
}
Пример #6
0
static VALUE Surface_s_load(VALUE klass, VALUE filename)
{
  SDL_Surface *surface;
  
  rb_secure(4);
  ExportFilenameStringValue(filename);

  surface = IMG_Load(RSTRING_PTR(filename));
  if(surface == NULL)
    rb_raise(eSDLError,"Couldn't load %s: %s",
             RSTRING_PTR(filename), SDL_GetError());
  return Surface_create(surface);
}
Пример #7
0
static VALUE
env_has_key(VALUE env, SEL sel, VALUE key)
{
    rb_secure(4);

    const char *s = StringValuePtr(key);
    if (strlen(s) != RSTRING_LEN(key)) {
	rb_raise(rb_eArgError, "bad environment variable name");
    }
    if (getenv(s) != NULL) {
	return Qtrue;
    }
    return Qfalse;
}
Пример #8
0
static VALUE
__rho_compile( VALUE obj, VALUE src)
{
    VALUE result;
    rb_thread_t *th = GET_THREAD();

    rb_secure(1);

    th->parse_in_eval++;
    result = rb_iseq_compile(src, rb_str_new2("(eval)"), INT2FIX(1));
    th->parse_in_eval--;

    return result;
}
Пример #9
0
void
rb_undef(VALUE klass, ID id)
{
    VALUE origin;
    NODE *body;

    if (rb_vm_cbase() == rb_cObject && klass == rb_cObject) {
	rb_secure(4);
    }
    if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
	rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'",
		 rb_id2name(id));
    }
    rb_frozen_class_p(klass);
    if (id == object_id || id == __send__ || id == idInitialize) {
	rb_warn("undefining `%s' may cause serious problem", rb_id2name(id));
    }
    body = search_method(klass, id, &origin);
    if (!body || !body->nd_body) {
	const char *s0 = " class";
	VALUE c = klass;

	if (FL_TEST(c, FL_SINGLETON)) {
	    VALUE obj = rb_iv_get(klass, "__attached__");

	    switch (TYPE(obj)) {
	      case T_MODULE:
	      case T_CLASS:
		c = obj;
		s0 = "";
	    }
	}
	else if (TYPE(c) == T_MODULE) {
	    s0 = " module";
	}
	rb_name_error(id, "undefined method `%s' for%s `%s'",
		      rb_id2name(id), s0, rb_class2name(c));
    }

    rb_add_method(klass, id, 0, NOEX_PUBLIC);

    if (FL_TEST(klass, FL_SINGLETON)) {
	rb_funcall(rb_iv_get(klass, "__attached__"),
		   singleton_undefined, 1, ID2SYM(id));
    }
    else {
	rb_funcall(klass, undefined, 1, ID2SYM(id));
    }
}
Пример #10
0
/*
 * call-seq:
 *   basicsocket.do_not_reverse_lookup = bool
 *
 * Sets the do_not_reverse_lookup flag of _basicsocket_.
 *
 *   BasicSocket.do_not_reverse_lookup = false
 *   p TCPSocket.new("127.0.0.1", 80).do_not_reverse_lookup #=> false
 *   BasicSocket.do_not_reverse_lookup = true
 *   p TCPSocket.new("127.0.0.1", 80).do_not_reverse_lookup #=> true
 *
 */
static VALUE
bsock_do_not_reverse_lookup_set(VALUE sock, VALUE state)
{
    rb_io_t *fptr;

    rb_secure(4);
    GetOpenFile(sock, fptr);
    if (RTEST(state)) {
	fptr->mode |= FMODE_NOREVLOOKUP;
    }
    else {
	fptr->mode &= ~FMODE_NOREVLOOKUP;
    }
    return sock;
}
Пример #11
0
/* Returns information about the group with specified String name, as found 
 * in /etc/group.
 *
 * The information is returned as a Struct::Group; see getgrent above for
 * details.
 *
 * e.g.  Etc.getgrnam('users') -> #<struct Struct::Group name="users",
 * passwd="x", gid=100, mem=["meta", "root"]>
 *
 */
static VALUE
etc_getgrnam(VALUE obj, VALUE nam)
{
#ifdef HAVE_GETGRENT
    struct group *grp;

    rb_secure(4);
    SafeStringValue(nam);
    grp = getgrnam(RSTRING_PTR(nam));
    if (grp == 0) rb_raise(rb_eArgError, "can't find group for %s", RSTRING_PTR(nam));
    return setup_group(grp);
#else
    return Qnil;
#endif
}
Пример #12
0
static VALUE
top_include(VALUE self, SEL sel, int argc, VALUE *argv)
{
#if 0
    rb_thread_t *th = GET_THREAD();

    rb_secure(4);
    if (th->top_wrapper) {
	rb_warning
	    ("main#include in the wrapped load is effective only in wrapper module");
	return rb_mod_include(argc, argv, th->top_wrapper);
    }
#endif
    return rb_mod_include(rb_cObject, 0, argc, argv);
}
Пример #13
0
static VALUE
env_assoc(VALUE env, SEL sel, VALUE key)
{
    rb_secure(4);

    const char *s = StringValuePtr(key);
    if (strlen(s) != RSTRING_LEN(key)) {
	rb_raise(rb_eArgError, "bad environment variable name");
    }
    const char *e = getenv(s);
    if (e != NULL) {
	return rb_assoc_new(key, rb_tainted_str_new2(e));
    }
    return Qnil;
}
Пример #14
0
VALUE
rb_dlcfunc_new(void (*func)(), int type, const char *name, ID calltype)
{
    VALUE val;
    struct cfunc_data *data;

    rb_secure(4);
    if( func ){
	val = TypedData_Make_Struct(rb_cDLCFunc, struct cfunc_data, &dlcfunc_data_type, data);
	data->ptr  = func;
	data->name = name ? strdup(name) : NULL;
	data->type = type;
	data->calltype = calltype;
    }
    else{
Пример #15
0
VALUE
rb_dlptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
{
    struct ptr_data *data;
    VALUE val;

    rb_secure(4);
    val = TypedData_Make_Struct(klass, struct ptr_data, &dlptr_data_type, data);
    data->ptr = ptr;
    data->free = func;
    data->size = size;
    OBJ_TAINT(val);

    return val;
}
Пример #16
0
/* Provides a convenient Ruby iterator which executes a block for each entry
 * in the /etc/passwd file.
 *
 * The code block is passed an Struct::Passwd struct; see getpwent above for
 * details.
 *
 * Example:
 *
 *     require 'etc'
 *
 *     Etc.passwd {|u|
 *       puts u.name + " = " + u.gecos
 *     }
 *
 */
static VALUE
etc_passwd(VALUE obj)
{
#ifdef HAVE_GETPWENT
    struct passwd *pw;

    rb_secure(4);
    if (rb_block_given_p()) {
        each_passwd();
    }
    else if (pw = getpwent()) {
        return setup_passwd(pw);
    }
#endif
    return Qnil;
}
Пример #17
0
/*
 * call-seq:
 *   udpsocket.connect(host, port) => 0
 *
 * Connects _udpsocket_ to _host_:_port_.
 *
 * This makes possible to send without destination address.
 *
 *   u1 = UDPSocket.new
 *   u1.bind("127.0.0.1", 4913)
 *   u2 = UDPSocket.new
 *   u2.connect("127.0.0.1", 4913)
 *   u2.send "uuuu", 0
 *   p u1.recvfrom(10) #=> ["uuuu", ["AF_INET", 33230, "localhost", "127.0.0.1"]]
 *
 */
static VALUE
udp_connect(VALUE sock, VALUE host, VALUE port)
{
    rb_io_t *fptr;
    struct udp_arg arg;
    VALUE ret;

    rb_secure(3);
    arg.res = rsock_addrinfo(host, port, SOCK_DGRAM, 0);
    GetOpenFile(sock, fptr);
    arg.fd = fptr->fd;
    ret = rb_ensure(udp_connect_internal, (VALUE)&arg,
		    rsock_freeaddrinfo, (VALUE)arg.res);
    if (!ret) rsock_sys_fail_host_port("connect(2)", host, port);
    return INT2FIX(0);
}
Пример #18
0
/* Closes the syslog facility.
 * Raises a runtime exception if it is not open.
 */
static VALUE mSyslog_close(VALUE self)
{
    rb_secure(4);
    if (!syslog_opened) {
        rb_raise(rb_eRuntimeError, "syslog not opened");
    }

    closelog();

    free((void *)syslog_ident);
    syslog_ident = NULL;
    syslog_options = syslog_facility = syslog_mask = -1;
    syslog_opened = 0;

    return Qnil;
}
Пример #19
0
/* Provides a convenient Ruby iterator which executes a block for each entry
 * in the /etc/group file.
 *
 * The code block is passed an Struct::Group struct; see getgrent above for
 * details.
 *
 * Example:
 *
 *     require 'etc'
 *
 *     Etc.group {|g|
 *       puts g.name + ": " + g.mem.join(', ')
 *     }
 *
 */
static VALUE
etc_group(VALUE obj)
{
#ifdef HAVE_GETGRENT
    struct group *grp;

    rb_secure(4);
    if (rb_block_given_p()) {
        each_group();
    }
    else if (grp = getgrent()) {
        return setup_group(grp);
    }
#endif
    return Qnil;
}
Пример #20
0
static VALUE
env_values(VALUE rcv, SEL sel)
{
    rb_secure(4);

    VALUE ary = rb_ary_new();
    char **env = GET_ENVIRON();
    while (*env != NULL) {
	const char *s = strchr(*env, '=');
	if (s != NULL) {
	    rb_ary_push(ary, env_str_new2(s + 1));
	}
	env++;
    }
    return ary;
}
Пример #21
0
static VALUE
thread_set_trace_func_m(VALUE obj, VALUE trace)
{
    rb_thread_t *th;

    rb_secure(4);
    GetThreadPtr(obj, th);
    rb_threadptr_remove_event_hook(th, call_trace_func, Qundef);

    if (NIL_P(trace)) {
	return Qnil;
    }

    thread_add_trace_func(th, trace);
    return trace;
}
Пример #22
0
static void
rb_export_method(VALUE klass, ID name, ID noex)
{
    rb_vm_method_node_t *node;
    SEL sel;

    if (klass == rb_cObject) {
	rb_secure(4);
    }

    if (!rb_vm_lookup_method2((Class)klass, name, &sel, NULL, &node)) {
	if (TYPE(klass) != T_MODULE
		|| !rb_vm_lookup_method2((Class)rb_cObject, name, &sel, NULL,
		    &node)) {
	    rb_print_undef(klass, name, 0);
	}
    }

    if (node == NULL) {
	rb_raise(rb_eRuntimeError,
		"can't change visibility of non Ruby method `%s'",
		sel_getName(sel));
    }

    long flags = (node->flags & ~VM_METHOD_PRIVATE) & ~VM_METHOD_PROTECTED;
    switch (noex) {
	case NOEX_PRIVATE:
	    flags |= VM_METHOD_PRIVATE;
	    break;

	case NOEX_PROTECTED:
	    flags |= VM_METHOD_PROTECTED;
	    break;

	default:
	    break;
    }

    if (node->flags != flags) {
	if (node->klass == (Class)klass) {
	    node->flags = flags;
	}
	else {
	    rb_vm_define_method2((Class)klass, sel, node, flags, false);
	}
    }
}
Пример #23
0
/* Package helper routines */
static void syslog_write(int pri, int argc, VALUE *argv)
{
    VALUE str;

    rb_secure(4);
    if (argc < 1) {
        rb_raise(rb_eArgError, "no log message supplied");
    }

    if (!syslog_opened) {
        rb_raise(rb_eRuntimeError, "must open syslog before write");
    }

    str = rb_f_sprintf(argc, argv);

    syslog(pri, "%s", RSTRING_PTR(str));
}
Пример #24
0
void
rb_undef(VALUE klass, ID id)
{
    if (klass == rb_cObject) {
	rb_secure(4);
    }
    if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(klass)) {
	rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'",
		rb_id2name(id));
    }
    rb_frozen_class_p(klass);
    if (id == object_id || id == __send__ || id == idInitialize) {
	rb_warn("undefining `%s' may cause serious problem", rb_id2name(id));
    }

    rb_vm_undef_method((Class)klass, id, true);
}
Пример #25
0
VALUE
rb_tracepoint_disable(VALUE tpval)
{
    rb_tp_t *tp;

    rb_secure(4);
    tp = tpptr(tpval);

    if (tp->target_th) {
	rb_thread_remove_event_hook_with_data(tp->target_th->self, (rb_event_hook_func_t)tp_call_trace, tpval);
    }
    else {
	rb_remove_event_hook_with_data((rb_event_hook_func_t)tp_call_trace, tpval);
    }
    tp->tracing = 0;
    return Qundef;
}
Пример #26
0
/* 
 * call-seq:
 *   remove_features(mod) => mod
 *
 * When this module is unincluded from another, Ruby Internal calls
 * remove_features in this module.  The default behavior is to remove
 * the constants, methods, and module variables of this module from
 * _mod_.  If this module has not been included by _mod_, an exception
 * will be raised.
 */
static VALUE module_remove_features(VALUE module, VALUE uninclude)
{
  VALUE prev, mod;

  if(TYPE(uninclude) != T_CLASS && TYPE(uninclude) != T_MODULE)
  {
    Check_Type(uninclude, T_CLASS);
  }

  rb_frozen_class_p(uninclude);
  if(!OBJ_TAINTED(uninclude))
  {
    rb_secure(4);
  }

  OBJ_INFECT(uninclude, module);

  if(RCLASS(uninclude)->m_tbl == RCLASS(module)->m_tbl)
  {
    rb_raise(rb_eArgError, "Cannot remove module from itself");
  }

  prev = uninclude;
  mod = RCLASS_SUPER(uninclude);

  while(mod)
  {
    if(RCLASS(module)->m_tbl == RCLASS(mod)->m_tbl)
    {
      RCLASS_SUPER(prev) = RCLASS_SUPER(mod);
      rb_clear_cache();
      return module;
    }

    if(BUILTIN_TYPE(mod) == T_CLASS)
    {
      break;
    }

    prev = mod;
    mod = RCLASS_SUPER(mod);
  }

  rb_raise(rb_eArgError, "Could not find included module");
  return module;
}
Пример #27
0
/* Returns the short user name of the currently logged in user.
 * Unfortunately, it is often rather easy to fool getlogin().
 * Avoid getlogin() for security-related purposes.
 *
 * e.g.
 *   Etc.getlogin -> 'guest'
 */
static VALUE
etc_getlogin(VALUE obj)
{
    char *login;

    rb_secure(4);
#ifdef HAVE_GETLOGIN
    login = getlogin();
    if (!login) login = getenv("USER");
#else
    login = getenv("USER");
#endif

    if (login)
	return rb_tainted_str_new2(login);
    return Qnil;
}
Пример #28
0
static VALUE readline_buffer_ext(VALUE self, VALUE str){
  rb_secure(4);
  StringValue(str);

  if(rl_line_buffer == NULL)
    return Qnil;

#ifdef HAVE_RL_DELETE_TEXT
  rl_delete_text(0, rl_end);
#else
  rl_line_buffer[rl_end = 0] = '\0';
#endif
  rl_insert_text(RSTRING_PTR(str));
  rl_redisplay();

  return rb_str_new(rl_line_buffer, strlen(rl_line_buffer));
}
Пример #29
0
VALUE
rb_dlhandle_sym(VALUE self, VALUE sym)
{
    struct dl_handle *dlhandle;
    const char *name;

    rb_secure(2);

    name = StringValuePtr(sym);

    TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle);
    if( ! dlhandle->open ){
	rb_raise(rb_eDLError, "closed handle");
    }

    return dlhandle_sym(dlhandle->ptr, StringValueCStr(sym));
}
Пример #30
0
Файл: class.c Проект: fi8on/ruby
void
rb_include_module(VALUE klass, VALUE module)
{
    VALUE p, c;
    int changed = 0;

    rb_frozen_class_p(klass);
    if (!OBJ_UNTRUSTED(klass)) {
	rb_secure(4);
    }

    if (TYPE(module) != T_MODULE) {
	Check_Type(module, T_MODULE);
    }

    OBJ_INFECT(klass, module);
    c = klass;
    while (module) {
	int superclass_seen = FALSE;

	if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
	    rb_raise(rb_eArgError, "cyclic include detected");
	/* ignore if the module included already in superclasses */
	for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
	    switch (BUILTIN_TYPE(p)) {
	      case T_ICLASS:
		if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
		    if (!superclass_seen) {
			c = p;  /* move insertion point */
		    }
		    goto skip;
		}
		break;
	      case T_CLASS:
		superclass_seen = TRUE;
		break;
	    }
	}
	c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
	if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
	    changed = 1;
      skip:
	module = RCLASS_SUPER(module);
    }
    if (changed) rb_clear_cache();
}