static void xs_getnameinfo(pTHX_ CV *cv) { dVAR; dXSARGS; SV *addr; int flags; char host[1024]; char serv[256]; char *sa; /* we'll cast to struct sockaddr * when necessary */ STRLEN addr_len; int err; if(items < 1 || items > 2) croak_xs_usage(cv, "addr, flags=0"); SP -= items; addr = ST(0); if(items < 2) flags = 0; else flags = SvIV(ST(1)); if(!SvPOK(addr)) croak("addr is not a string"); addr_len = SvCUR(addr); /* We need to ensure the sockaddr is aligned, because a random SvPV might * not be due to SvOOK */ Newx(sa, addr_len, char); Copy(SvPV_nolen(addr), sa, addr_len, char); #ifdef HAS_SOCKADDR_SA_LEN ((struct sockaddr *)sa)->sa_len = addr_len; #endif err = getnameinfo((struct sockaddr *)sa, addr_len, host, sizeof(host), serv, sizeof(serv), flags); Safefree(sa); XPUSHs(err_to_SV(aTHX_ err)); if(err) XSRETURN(1); XPUSHs(sv_2mortal(newSVpv(host, 0))); XPUSHs(sv_2mortal(newSVpv(serv, 0))); XSRETURN(3); }
void dv( int in ) { dXSARGS; sp = mark; XPUSHs(sv_2mortal(newSViv(in * 2))); PUTBACK; XSRETURN(1); }
static XS (XS_Xchat_unhook) { xchat_hook *hook; HookData *userdata; int retCount = 0; dXSARGS; if (items != 1) { xchat_print (ph, "Usage: Xchat::unhook(hook)"); } else { hook = INT2PTR (xchat_hook *, SvUV (ST (0))); userdata = (HookData *) xchat_unhook (ph, hook); if (userdata != NULL) { if (userdata->callback != NULL) { SvREFCNT_dec (userdata->callback); } if (userdata->userdata != NULL) { XPUSHs (sv_mortalcopy (userdata->userdata)); SvREFCNT_dec (userdata->userdata); retCount = 1; } if (userdata->package != NULL) { SvREFCNT_dec (userdata->package); } free (userdata); } XSRETURN (retCount); } XSRETURN_EMPTY; }
void HRA_fetch_a(SV *self, SV *attr, char *t) { dXSARGS; SP -= 3; if(GIMME_V == G_VOID) { XSRETURN(0); } SV *aobj = attr_get(self, attr, t, 0); if(!aobj) { HR_DEBUG("Can't find attribute!"); XSRETURN_EMPTY; } else { HR_DEBUG("Found aobj=%p", aobj); } hrattr_simple *aptr = attr_from_sv(SvRV(aobj)); HR_DEBUG("Attrhash=%p", aptr->attrhash); int nkeys = hv_iterinit(aptr->attrhash); HR_DEBUG("We have %d keys", nkeys); if(GIMME_V == G_SCALAR) { HR_DEBUG("Scalar return value requested"); XSRETURN_IV(nkeys); } HR_DEBUG("Will do some stack voodoo"); EXTEND(sp, nkeys); HE *cur = hv_iternext(aptr->attrhash); for(; cur != NULL; cur = hv_iternext(aptr->attrhash)) { XPUSHs(sv_mortalcopy(hv_iterval(aptr->attrhash, cur))); } PUTBACK; }
/* * This is a wraper for radius_axlat * Now users are able to get data that is accessible only via xlat * e.g. %{client:...} * Call syntax is radiusd::xlat(string), string will be handled the * same way it is described in EXPANSIONS section of man unlang */ static XS(XS_radiusd_xlat) { dXSARGS; char *in_str; char *expanded; ssize_t slen; SV *rad_requestp_sv; REQUEST *request; if (items != 1) croak("Usage: radiusd::xlat(string)"); rad_requestp_sv = get_sv("RAD___REQUESTP", 0); if (rad_requestp_sv == NULL) croak("Can not evalue xlat, RAD___REQUESTP is not set!"); request = INT2PTR(REQUEST *, SvIV(rad_requestp_sv)); in_str = (char *) SvPV(ST(0), PL_na); expanded = NULL; slen = radius_axlat(&expanded, request, in_str, NULL, NULL); if (slen < 0) { REDEBUG("Error parsing xlat '%s'", in_str); XSRETURN_UNDEF; } XST_mPV(0, expanded); talloc_free(expanded); XSRETURN(1); }
static XS (XS_yell) { int foo; dXSARGS; for (foo=0; foo<items; foo++) { yell("Perl: %s",SvPV_nolen(ST(foo))); } XSRETURN(items); }
static XS (XS_eval) { int foo; dXSARGS; for (foo=0; foo<items; foo++) { runcmds(SvPV_nolen(ST(foo)), ""); } XSRETURN(0); }
static XS (XS_eval) { unsigned foo; dXSARGS; for (foo=0; foo<items; foo++) { parse_line(NULL, SvPV_nolen(ST(foo)), "", 0, 0); } XSRETURN(0); }
static XS (XS_cmd) { int foo; dXSARGS; for (foo=0; foo<items; foo++) { runcmds("$*", SvPV_nolen(ST(foo))); } XSRETURN(0); }
void return_retval(const I32 ax, SV **sp, SV *retval) { if (GIMME_V == G_VOID) { XSRETURN_EMPTY; } if (GIMME_V == G_ARRAY) { AV* const av = (AV*)SvRV(retval); I32 const len = av_len(av) + 1; I32 i; for (i = 0; i < len; i++) { XPUSHs(sv_2mortal(av_shift(av))); } XSRETURN(len); } else { AV* const av = (AV*)SvRV(retval); XPUSHs(sv_2mortal(av_shift(av))); XSRETURN(1); } }
static XS (XS_Xchat_context_info) { const char *const *fields; dXSARGS; if (items > 0 ) { xchat_print (ph, "Usage: Xchat::Internal::context_info()"); } fields = xchat_list_fields (ph, "channels" ); XPUSHs (list_item_to_sv (NULL, fields)); XSRETURN (1); }
static XS(epoc_getcwd) /* more or less stolen from win32.c */ { dXSARGS; /* Make the host for current directory */ char *buffer; int buflen = 256; char *ptr; buffer = (char *) malloc( buflen); if (buffer == NULL) { XSRETURN_UNDEF; } while ((NULL == ( ptr = getcwd( buffer, buflen))) && (errno == ERANGE)) { buflen *= 2; if (NULL == realloc( buffer, buflen)) { XSRETURN_UNDEF; } } /* * If ptr != Nullch * then it worked, set PV valid, * else return 'undef' */ if (ptr) { SV *sv = sv_newmortal(); char *tptr; for (tptr = ptr; *tptr != '\0'; tptr++) { if (*tptr == '\\') { *tptr = '/'; } } sv_setpv(sv, ptr); free( buffer); EXTEND(SP,1); SvPOK_on(sv); ST(0) = sv; #ifndef INCOMPLETE_TAINTS SvTAINTED_on(ST(0)); #endif XSRETURN(1); } free( buffer); XSRETURN_UNDEF; }
static XS (XS_expr) { unsigned foo, food = 0; char* retval=NULL; char* arg=NULL; dXSARGS; for (foo=0; foo<items; foo++) { arg = malloc_strdup((char*)SvPV_nolen(ST(foo))); retval = (char*)parse_inline(arg, "", &food); XST_mPV(foo, retval); new_free(&arg); new_free(&retval); } XSRETURN(items); }
static XS (XS_call) { int foo = 0; char* retval=NULL; char* arg=NULL; dXSARGS; for (foo=0; foo<items; foo++) { arg = malloc_strdup((char*)SvPV_nolen(ST(foo))); retval = (char*)call_function(arg, ""); XST_mPV(foo, retval); new_free(&arg); new_free(&retval); } XSRETURN(items); }
static void _MopMmV_wrapper (pTHX_ CV *cv) { bool has_events; I32 j, count; SV** args; CV* body; SV* object = newRV_noinc((SV*) cv); AV* results = newAV(); dXSARGS; has_events = MopOV_has_events(object); body = (CV*) CvXSUBANY(cv).any_uv; if (has_events) { Newx(args, items, SV*); for (j = 0; j < items; j++) { args[j] = ST(j); } MopOV_fire_event(object, newSVpv("before:EXECUTE", 14), args, items-1); } { ENTER; PUSHMARK(SP); for (j = 0; j < items; j++) { PUSHs(args[j]); } PUTBACK; count = call_sv((SV*) body, GIMME_V); SPAGAIN; while (count-- > 0) { av_push(results, POPs); } LEAVE; } for (j = 0; j < av_len(results) + 1; j++) { ST(j) = *av_fetch(results, av_len(results) - j, 0); } if (has_events) { MopOV_fire_event(object, newSVpv("after:EXECUTE", 13), args, items-1); } XSRETURN(av_len(results) + 1); }
/* * This is a wraper for xlat_aeval * Now users are able to get data that is accessible only via xlat * e.g. %{client:...} * Call syntax is radiusd::xlat(string), string will be handled the * same way it is described in EXPANSIONS section of man unlang */ static XS(XS_radiusd_xlat) { dXSARGS; char *in_str; char *expanded; ssize_t slen; REQUEST *request; if (items != 1) croak("Usage: radiusd::xlat(string)"); request = rlm_perl_request; in_str = (char *) SvPV(ST(0), PL_na); slen = xlat_aeval(request, &expanded, request, in_str, NULL, NULL); if (slen < 0) { REDEBUG("Error parsing xlat '%s'", in_str); XSRETURN_UNDEF; } XST_mPV(0, expanded); talloc_free(expanded); XSRETURN(1); }
void HRA_store_a(SV *self, SV *attr, char *t, SV *value, ...) { SV *vstring = newSVuv((UV)SvRV(value)); //reverse lookup key SV *aobj = NULL; //primary attribute entry, from attr_lookup SV *vref = NULL; //value's entry in attribute hash SV *attrhash_ref = NULL; //reference for attribute hash, for adding actions SV **a_r_ent = NULL; //lval-type HE for looking/storing attr in vhash char *astring = NULL; hrattr_simple *aptr; //our private attribute structure int options = STORE_OPT_O_CREAT; int i; dXSARGS; if ((items-4) % 2) { die("Expected hash options or nothing (got %d)", items-3); } for(i=4;i<items;i+=2) { _chkopt(STRONG_ATTR, i, options); _chkopt(STRONG_VALUE, i, options); } aobj = attr_get(self, attr, t, options); if(!aobj) { die("attr_get() failed to return anything"); } aptr = attr_from_sv(SvRV(aobj)); assert(SvROK(aobj)); astring = attr_strkey(aptr, attr_getsize(aptr)); if(!insert_into_vhash(value, aobj, astring, REF2TABLE(self), NULL)) { goto GT_RET; /*No new insertions*/ } if(!HvKEYS(aptr->attrhash)) { /*First entry and we've already inserted our reverse entry*/ SvREFCNT_dec(SvRV(aobj)); } vref = newSVsv(value); if(hv_store_ent(aptr->attrhash, vstring, vref, 0)) { if( (options & STORE_OPT_STRONG_VALUE) == 0) { sv_rvweaken(vref); } } else { SvREFCNT_dec(vref); } RV_Newtmp(attrhash_ref, (SV*)aptr->attrhash); HR_Action v_actions[] = { HR_DREF_FLDS_ptr_from_hv(SvRV(value), attrhash_ref), HR_ACTION_LIST_TERMINATOR }; HR_add_actions_real(value, v_actions); GT_RET: SvREFCNT_dec(vstring); if(attrhash_ref) { RV_Freetmp(attrhash_ref); } XSRETURN(0); }
static void xs_getaddrinfo(pTHX_ CV *cv) { dVAR; dXSARGS; SV *host; SV *service; SV *hints; char *hostname = NULL; char *servicename = NULL; STRLEN len; struct addrinfo hints_s; struct addrinfo *res; struct addrinfo *res_iter; int err; int n_res; if(items > 3) croak_xs_usage(cv, "host, service, hints"); SP -= items; if(items < 1) host = &PL_sv_undef; else host = ST(0); if(items < 2) service = &PL_sv_undef; else service = ST(1); if(items < 3) hints = NULL; else hints = ST(2); SvGETMAGIC(host); if(SvOK(host)) { hostname = SvPV_nomg(host, len); if (!len) hostname = NULL; } SvGETMAGIC(service); if(SvOK(service)) { servicename = SvPV_nomg(service, len); if (!len) servicename = NULL; } Zero(&hints_s, sizeof hints_s, char); hints_s.ai_family = PF_UNSPEC; if(hints && SvOK(hints)) { HV *hintshash; SV **valp; if(!SvROK(hints) || SvTYPE(SvRV(hints)) != SVt_PVHV) croak("hints is not a HASH reference"); hintshash = (HV*)SvRV(hints); if((valp = hv_fetch(hintshash, "flags", 5, 0)) != NULL) hints_s.ai_flags = SvIV(*valp); if((valp = hv_fetch(hintshash, "family", 6, 0)) != NULL) hints_s.ai_family = SvIV(*valp); if((valp = hv_fetch(hintshash, "socktype", 8, 0)) != NULL) hints_s.ai_socktype = SvIV(*valp); if((valp = hv_fetch(hintshash, "protocol", 8, 0)) != NULL) hints_s.ai_protocol = SvIV(*valp); } err = getaddrinfo(hostname, servicename, &hints_s, &res); XPUSHs(err_to_SV(aTHX_ err)); if(err) XSRETURN(1); n_res = 0; for(res_iter = res; res_iter; res_iter = res_iter->ai_next) { HV *res_hv = newHV(); (void)hv_stores(res_hv, "family", newSViv(res_iter->ai_family)); (void)hv_stores(res_hv, "socktype", newSViv(res_iter->ai_socktype)); (void)hv_stores(res_hv, "protocol", newSViv(res_iter->ai_protocol)); (void)hv_stores(res_hv, "addr", newSVpvn((char*)res_iter->ai_addr, res_iter->ai_addrlen)); if(res_iter->ai_canonname) (void)hv_stores(res_hv, "canonname", newSVpv(res_iter->ai_canonname, 0)); else (void)hv_stores(res_hv, "canonname", newSV(0)); XPUSHs(sv_2mortal(newRV_noinc((SV*)res_hv))); n_res++; } freeaddrinfo(res); XSRETURN(1 + n_res); }