struct hostent * gethostent(void) { struct hostdata *hd; struct hostent *rval; int ret_h_errno; if ((hd = __hostdata_init()) == NULL) return (NULL); if (gethostent_r(&hd->host, hd->data, sizeof(hd->data), &rval, &ret_h_errno) != 0) return (NULL); return (rval); }
static struct hostent *file_find_addr(const char *addr, int len, int type, struct hostent *result, char *buf, int bufsize, int *errval) { FILE *fp = NULL; pthread_mutex_lock(&host_iterate_lock); sethostent(0); while ((result = gethostent_r(result, buf, bufsize, errval)) != NULL) { /* Check the entry against the given address. */ if (result->h_addrtype == type && memcmp(result->h_addr, addr, len) == 0) break; } pthread_mutex_unlock(&host_iterate_lock); if (!result && errno != ERANGE) *errval = HOST_NOT_FOUND; return result; }
/* :call-seq: * Sys::Host.info * * Returns an array of HostInfo structs containing various bits of * information about the local machine for each entry in the hosts * table. * * The Struct::HostInfo struct contains 5 fields: * * * name (String) * * aliases (Array) * * addr_type (Integer) => Typically 2 (AF_INET) or 28 (AF_INET6) * * length (Integer) => Typically 4 (IPv4) or 16 (IPv6) * * addr_list (Array) */ static VALUE host_info(VALUE klass){ char ibuf[INET6_ADDRSTRLEN]; struct hostent* host; VALUE v_hostinfo, v_aliases, v_addr; VALUE v_array = rb_ary_new(); sethostent(0); #ifdef HAVE_GETHOSTENT_R struct hostent temp; char sbuf[HOSTENT_BUF]; int err; #endif #ifdef HAVE_GETHOSTENT_R while(!gethostent_r(&temp, sbuf, HOSTENT_BUF, &host, &err)){ #else while((host = gethostent())){ #endif char **aliases = host->h_aliases; char **addrs = host->h_addr_list; v_aliases = rb_ary_new(); v_addr = rb_ary_new(); while(*aliases){ rb_ary_push(v_aliases, rb_str_new2(*aliases)); *aliases++; } while(*addrs){ if(!inet_ntop(host->h_addrtype, addrs, ibuf, sizeof(ibuf))) rb_raise(cHostError, "inet_ntop() failed: %s", strerror(errno)); rb_ary_push(v_addr, rb_str_new2(ibuf)); *addrs++; } v_hostinfo = rb_struct_new(sHostInfo, rb_str_new2(host->h_name), v_aliases, INT2FIX(host->h_addrtype), INT2FIX(host->h_length), v_addr ); OBJ_FREEZE(v_hostinfo); rb_ary_push(v_array, v_hostinfo); } endhostent(); return v_array; } #ifdef HAVE_GETHOSTID /* * Sys::Host.host_id * * Returns the host id of the current machine. */ static VALUE host_host_id(){ return ULL2NUM(gethostid()); } #endif void Init_host() { VALUE sys_mSys, cHost; /* The Sys module serves as a toplevel namespace, nothing more. */ sys_mSys = rb_define_module("Sys"); /* The Host class encapsulates information about your machine, such as * the host name and IP address. */ cHost = rb_define_class_under(sys_mSys, "Host", rb_cObject); /* This error is raised if any of the Host methods fail. */ cHostError = rb_define_class_under(cHost, "Error", rb_eStandardError); /* 0.6.3: The version of this library. This is a string, not a number. */ rb_define_const(cHost, "VERSION", rb_str_new2(SYS_HOST_VERSION)); /* Structs */ sHostInfo = rb_struct_define("HostInfo", "name", "aliases", "addr_type", "length", "addr_list", NULL ); /* Class Methods */ rb_define_singleton_method(cHost, "hostname", host_hostname, 0); rb_define_singleton_method(cHost, "ip_addr", host_ip_addr, 0); rb_define_singleton_method(cHost, "info", host_info, 0); #ifdef HAVE_GETHOSTID rb_define_singleton_method(cHost, "host_id", host_host_id, 0); #endif }