Hi all,

I whipped this up today.  My eyes must be glazing over again, because I'm getting this error:

test.rb:3:in `require': identifier Proto::ProtoStruct needs to be constant (NameError) from 
test.rb:3

where line 3 is simply 'require "net/proto"'

Any ideas?  I think I've just been staring at the computer screen too long.  Thanks.

Dan

Source:

#include "ruby.h"
#include <netdb.h>
#include <string.h>

#ifdef __cplusplus
extern "C"
{
#endif

#define BUF_SIZE 8192

VALUE cNetProto, sProto;

static VALUE np_getprotobyname(VALUE obj, VALUE proto_name)
{
   struct protoent p;
   char buffer[BUF_SIZE];
   getprotobyname_r(STR2CSTR(proto_name),&p,buffer,BUF_SIZE);
   return INT2NUM(p.p_proto);
}

static VALUE np_getprotobynumber(VALUE obj, VALUE proto_number)
{
   struct protoent p;
   char buffer[BUF_SIZE];
   getprotobynumber_r(NUM2INT(proto_number),&p,buffer,BUF_SIZE);
   return rb_str_new2(p.p_name);
}

static VALUE np_getprotoent()
{
   VALUE alias_array = rb_ary_new();
   struct protoent p;
   char buffer[BUF_SIZE];

   while(getprotoent_r(&p,buffer,BUF_SIZE))
   {
      for(; *p.p_aliases != NULL; p.p_aliases++)
      {
         rb_ary_push(alias_array,rb_str_new2(*p.p_aliases));
      }

      rb_yield(rb_struct_new(sProto,
         rb_new_str2(p.p_name),
         alias_array,
         INT2NUM(p.p_proto)
      ));
   }
}

void Init_proto()
{
   VALUE np_mNet;
   np_mNet = rb_define_module("Net");
   cNetProto = rb_define_class_under(np_mNet,"Proto",rb_cObject);

   sProto = rb_struct_define("Proto::ProtoStruct","name","aliases","number",0);
   rb_global_variable(&sProto);

   rb_define_singleton_method(cNetProto,"getprotobyname",np_getprotobyname,1);
   rb_define_singleton_method(cNetProto,"getprotobynumber",np_getprotobynumber,1);
   rb_define_singleton_method(cNetProto,"getprotoent",np_getprotoent,0);
}

#ifdef __cplusplus
}
#endif

# Sample test script

require "net/proto"

puts Net::Proto.getprotobyname("tcp").to_s
puts Net::Proto.getprotobynumber(7)

Net::Proto.getprotoent{ |p|
   puts p.name
   puts p.proto
}