Net-SNMP-XS
view release on metacpan or search on metacpan
|| AvARRAY (av_type)[type] == 0
|| AvARRAY (av_type)[type] == &PL_sv_undef)
{
error ("Unknown ASN.1 type");
return &PL_sv_undef;
}
dSP;
PUSHMARK (SP);
EXTEND (SP, 2);
PUSHs (msg);
PUSHs (sv_2mortal (newSViv (type)));
PUTBACK;
int count = call_sv (AvARRAY (av_type)[type], G_SCALAR);
SPAGAIN;
res = count ? SvREFCNT_inc (TOPs) : &PL_sv_undef;
}
}
return errflag ? &PL_sv_undef : res;
}
/////////////////////////////////////////////////////////////////////////////
#if HAVE_VERSIONSORT
static int
oid_lex_cmp (const void *a_, const void *b_)
{
const char *a = SvPVX (*(SV **)a_);
const char *b = SvPVX (*(SV **)b_);
a += *a == '.';
b += *b == '.';
return strverscmp (a, b);
}
#endif
MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::XS
PROTOTYPES: ENABLE
BOOT:
av_type = newAV ();
void
set_type (int type, SV *cv)
CODE:
cv = x_get_cv (cv);
assert (SvTYPE (cv) == SVt_PVCV);
av_store (av_type, type, SvREFCNT_inc_NN (cv));
MODULE = Net::SNMP::XS PACKAGE = Net::SNMP::Message
void
_buffer_append (BUFOBJ self, SV *value)
ALIAS:
_buffer_put = 1
PPCODE:
{
STRLEN vlen;
const char *vstr = SvPVbyte (value, vlen);
if (ix)
sv_insert (bufsv, 0, 0, vstr, vlen);
else
sv_catpvn (bufsv, vstr, vlen);
buf = SvPVbyte (bufsv, len);
cur = buf;
rem = len;
SV *len_sv = *hv_fetch ((HV *)cur_bufobj, "_length", sizeof ("_length") - 1, 1);
sv_setiv (len_sv, len);
// some callers test for defined'ness of the returnvalue. *sigh*
XPUSHs (&PL_sv_yes);
}
void
_buffer_get (BUFOBJ self, int count = -1)
PPCODE:
{
// grrr.
if (count < 0)
{
hv_delete ((HV *)SvRV (self), "_index" , 6, G_DISCARD);
hv_delete ((HV *)SvRV (self), "_length", 7, G_DISCARD);
XPUSHs (sv_2mortal (newSVsv (bufsv)));
sv_setpvn (bufsv, "", 0);
buf = "";
cur = buf;
rem = 0;
XSRETURN (1);
}
char *data = getn (count, 0);
if (data)
XPUSHs (sv_2mortal (newSVpvn (data, count)));
}
U32
index (BUFOBJ self, int ndx = -1)
CODE:
{
if (ndx >= 0 && ndx < len)
{
cur = buf + ndx;
rem = len - ndx;
}
RETVAL = cur - buf;
}
OUTPUT: RETVAL
U32
_process_length (BUFOBJ self, ...)
ALIAS:
_process_sequence = 0
CODE:
RETVAL = process_length ();
OUTPUT: RETVAL
SV *
_process_integer32 (BUFOBJ self, ...)
CODE:
RETVAL = process_integer32_sv ();
OUTPUT: RETVAL
SV *
_process_counter (BUFOBJ self, ...)
ALIAS:
_process_gauge = 0
_process_timeticks = 0
CODE:
RETVAL = process_unsigned32_sv ();
OUTPUT: RETVAL
#if IVSIZE >= 8
SV *
_process_var_bind_list (BUFOBJ self)
CODE:
{
if (get8 () != (ASN_SEQUENCE | ASN_CONSTRUCTED))
error ("SEQUENCE expected at beginning of VarBindList");
int seqlen = process_length ();
U8 *end = cur + seqlen;
HV *list = newHV ();
AV *names = newAV ();
HV *types = newHV ();
hv_store ((HV *)cur_bufobj, "_var_bind_list" , sizeof ("_var_bind_list" ) - 1, newRV_noinc ((SV *)list ), 0);
hv_store ((HV *)cur_bufobj, "_var_bind_names", sizeof ("_var_bind_names") - 1, newRV_noinc ((SV *)names), 0);
hv_store ((HV *)cur_bufobj, "_var_bind_types", sizeof ("_var_bind_types") - 1, newRV_noinc ((SV *)types), 0);
while (cur < end && !errflag)
{
// SEQUENCE ObjectName ObjectSyntax
if (get8 () != (ASN_SEQUENCE | ASN_CONSTRUCTED))
error ("SEQUENCE expected at beginning of VarBind");
process_length ();
if (get8 () != ASN_OBJECT_IDENTIFIER)
error ("OBJECT IDENTIFIER expected at beginning of VarBind");
int type, oidlen;
SV *oid = process_object_identifier_sv ();
SV *val = process_sv (&type);
hv_store_ent (types, oid, newSViv (type), 0);
hv_store_ent (list , oid, val, 0);
av_push (names, oid);
}
// sigh - great design to do it here
SV *pdu_type = *hv_fetch ((HV *)cur_bufobj, "_pdu_type" , sizeof ("_pdu_type" ) - 1, 1);
if (SvIV (pdu_type) == 0xa8) // REPORT
{
PUSHMARK (SP);
XPUSHs (msg);
PUTBACK;
call_method ("_report_pdu_error", G_VOID | G_DISCARD);
SPAGAIN;
XSRETURN_EMPTY;
}
RETVAL = newRV_inc ((SV *)list);
}
OUTPUT: RETVAL
MODULE = Net::SNMP::XS PACKAGE = Net::SNMP
void
oid_base_match (SV *base_, SV *oid_)
PROTOTYPE: $$
ALIAS:
oid_context_match = 0
PPCODE:
{
if (!SvOK (base_) || !SvOK (oid_))
XSRETURN_NO;
STRLEN blen, olen;
char *base = SvPVbyte (base_, blen);
char *oid = SvPVbyte (oid_ , olen);
blen -= *base == '.'; base += *base == '.';
olen -= *base == '.'; oid += *oid == '.';
if (olen < blen)
XSRETURN_NO;
if (memcmp (base, oid, blen))
XSRETURN_NO;
if (oid [blen] && oid [blen] != '.')
XSRETURN_NO;
XSRETURN_YES;
}
#if HAVE_VERSIONSORT
void
oid_lex_sort (...)
PROTOTYPE: @
PPCODE:
{
// make sure SvPVX is valid
int i;
for (i = items; i--; )
{
SV *sv = ST (i);
if (SvTYPE (sv) < SVt_PV || SvTYPE (sv) == SVt_PVAV && SvTYPE (sv) == SVt_PVHV)
SvPV_force_nolen (sv);
}
qsort (&ST (0), items, sizeof (SV *), oid_lex_cmp);
EXTEND (SP, items);
// we cheat somewhat by not returning copies here
for (i = 0; i < items; ++i)
PUSHs (sv_2mortal (SvREFCNT_inc (ST (i))));
}
int
_index_cmp (const char *a, const char *b)
PROTOTYPE: $$
CODE:
RETVAL = strverscmp (a, b);
OUTPUT: RETVAL
#endif
( run in 2.259 seconds using v1.01-cache-2.11-cpan-71847e10f99 )