Example #1
0
/*
 * Update some rows in the specified table
 * _h: structure representing database connection
 * _k: key names
 * _o: operators
 * _v: values of the keys that must match
 * _uk: updated columns
 * _uv: updated values of the columns
 * _n: number of key=value pairs
 * _un: number of columns to update
 */
int perlvdb_db_update(db_con_t* h, db_key_t* k, db_op_t* o, db_val_t* v,
	      db_key_t* uk, db_val_t* uv, int n, int un) {

	AV *condarr;
	AV *updatearr;

	SV *condarrref;
	SV *updatearrref;

	SV *ret;

	condarr = conds2perlarray(k, o, v, n);
	updatearr = pairs2perlarray(uk, uv, un);

	condarrref = newRV_noinc((SV*)condarr);
	updatearrref = newRV_noinc((SV*)updatearr);

	ret = perlvdb_perlmethod(getobj(h), PERL_VDB_UPDATEMETHOD,
			condarrref, updatearrref, NULL, NULL);

	av_undef(condarr);
	av_undef(updatearr);

	return IV2int(ret);
}
Example #2
0
/*
 * Query table for specified rows
 * h: structure representing database connection
 * k: key names
 * op: operators
 * v: values of the keys that must match
 * c: column names to return
 * n: number of key=values pairs to compare
 * nc: number of columns to return
 * o: order by the specified column
 */
int perlvdb_db_query(db_con_t* h, db_key_t* k, db_op_t* op, db_val_t* v,
			db_key_t* c, int n, int nc,
			db_key_t o, db_res_t** r) {


	AV *condarr;
	AV *retkeysarr;
	SV *order;

	SV *condarrref;
	SV *retkeysref;

	SV *resultset;

	int retval = 0;

	/* Create parameter set */
	condarr = conds2perlarray(k, op, v, n);
	retkeysarr = keys2perlarray(c, nc);

	if (o) order = newSVpv(o, 0);
	else order = &PL_sv_undef;


	condarrref = newRV_noinc((SV*)condarr);
	retkeysref = newRV_noinc((SV*)retkeysarr);

	/* Call perl method */
	resultset = perlvdb_perlmethod(getobj(h), PERL_VDB_QUERYMETHOD,
			condarrref, retkeysref, order, NULL);

	av_undef(condarr);
	av_undef(retkeysarr);

	/* Transform perl result set to OpenSER result set */
	if (!resultset) {
		/* No results. */
		LM_ERR("no perl result set.\n");
		retval = -1;
	} else {
		if (sv_isa(resultset, "OpenSER::VDB::Result")) {
			retval = perlresult2dbres(resultset, r);
		/* Nested refs are decreased/deleted inside the routine */
			SvREFCNT_dec(resultset);
		} else {
			LM_ERR("invalid result set retrieved from perl call.\n");
			retval = -1;
		}
	}

	return retval;
}
Example #3
0
/*
 * Delete a row from the specified table
 * h: structure representing database connection
 * k: key names
 * o: operators
 * v: values of the keys that must match
 * n: number of key=value pairs
 */
int perlvdb_db_delete(db_con_t* h, db_key_t* k, db_op_t* o, db_val_t* v,
		int n) {
	AV *arr;
	SV *arrref;
	SV *ret;

	arr = conds2perlarray(k, o, v, n);
	arrref = newRV_noinc((SV*)arr);
	ret = perlvdb_perlmethod(getobj(h), PERL_VDB_DELETEMETHOD,
			arrref, NULL, NULL, NULL);

	av_undef(arr);

	return IV2int(ret);
}
Example #4
0
/*
 * Insert a row into specified table
 * h: structure representing database connection
 * k: key names
 * v: values of the keys
 * n: number of key=value pairs
 */
int perlvdb_db_insertreplace(db_con_t* h, db_key_t* k, db_val_t* v,
		int n, char *insertreplace) {
	AV *arr;
	SV *arrref;
	SV *ret;

	arr = pairs2perlarray(k, v, n);
	arrref = newRV_noinc((SV*)arr);
	ret = perlvdb_perlmethod(getobj(h), insertreplace,
			arrref, NULL, NULL, NULL);

	av_undef(arr);

	return IV2int(ret);
}
Example #5
0
bool KviPerlInterpreter::execute(
		const QString &szCode,
		QStringList &args,
		QString &szRetVal,
		QString &szError,
		QStringList &lWarnings)
{
	if(!m_pInterpreter)
	{
		szError = __tr2qs_ctx("Internal error: perl interpreter not initialized","perl");
		return false;
	}

	g_lWarningList.clear();

	QByteArray szUtf8 = szCode.toUtf8();
	PERL_SET_CONTEXT(m_pInterpreter);

	// clear the _ array
	AV * pArgs = get_av("_",1);
	SV * pArg = av_shift(pArgs);
	while(SvOK(pArg))
	{
		SvREFCNT_dec(pArg);
		pArg = av_shift(pArgs);
	}

	if(args.count() > 0)
	{
		// set the args in the _ arry
		av_unshift(pArgs,(I32)args.count());
		int idx = 0;
		for(QStringList::Iterator it = args.begin();it != args.end();++it)
		{
			QString tmp = *it;
			const char * val = tmp.toUtf8().data();
			if(val)
			{
				pArg = newSVpv(val,tmp.length());
				if(!av_store(pArgs,idx,pArg))
					SvREFCNT_dec(pArg);
			}
			idx++;
		}
	}

	// call the code
	SV * pRet = eval_pv(szUtf8.data(),false);

	// clear the _ array again
	pArgs = get_av("_",1);
	pArg = av_shift(pArgs);
	while(SvOK(pArg))
	{
		SvREFCNT_dec(pArg);
		pArg = av_shift(pArgs);
	}
	av_undef(pArgs);

	// get the ret value
	if(pRet)
	{
		if(SvOK(pRet))
			szRetVal = svToQString(pRet);
	}

	if(!g_lWarningList.isEmpty())
		lWarnings = g_lWarningList;

	// and the eventual error string
	pRet = get_sv("@",false);
	if(pRet)
	{
		if(SvOK(pRet))
		{
			szError = svToQString(pRet);
			if(!szError.isEmpty())return false;
		}
	}

	return true;
}
Example #6
0
int perlresult2dbres(SV *perlres, db1_res_t **r) {

	SV *colarrayref = NULL;
	AV *colarray = NULL;
	SV *acol = NULL;
	int colcount = 0;


	SV *rowarrayref = NULL;
	AV *rowarray = NULL;
	int rowcount = 0;

	SV *arowref = NULL;
	AV *arow = NULL;
	int arowlen = 0;

	SV *aelement = NULL;
	SV *atypesv = 0;
	int atype = 0;
	SV *aval = NULL;

	char *charbuf;
	char *currentstring;

	int i, j;
	
	int retval = 0;
	STRLEN len;

	SV *d1; /* helper variables */

	/*db_val_t cur_val;*/ /* Abbreviation in "switch" below. The currently
			     modified db result value. */

	if (!(SvROK(perlres) &&
		(sv_derived_from(perlres, "Kamailio::VDB::Result")))) {
		goto error;
	}
	/* Memory allocation for C side result structure */
	*r = (db1_res_t *)pkg_malloc(sizeof(db1_res_t));
	if (!(*r)) {
		LM_ERR("no pkg memory left\n");
		return -1;
	}
	memset(*r, 0, sizeof(db1_res_t));
	
	/* Fetch column definitions */
	colarrayref = perlvdb_perlmethod(perlres, PERL_VDB_COLDEFSMETHOD,
			NULL, NULL, NULL, NULL);
	if (!(SvROK(colarrayref))) goto error;
	colarray = (AV *)SvRV(colarrayref);
	if (!(SvTYPE(colarray) == SVt_PVAV)) goto error;

	colcount = av_len(colarray) + 1;

	/* Allocate col def memory */
	(*r)->col.n = colcount;
	(*r)->col.types = (db_type_t*)pkg_malloc(colcount*sizeof(db_type_t));
	(*r)->col.names = (db_key_t*)pkg_malloc(colcount*sizeof(db_key_t));
	
	 /* reverse direction, as elements are removed by "SvREFCNT_dec" */
	for (i = colcount-1; i >= 0; i--) {
		acol = *av_fetch(colarray, i, 0);
		d1 = perlvdb_perlmethod(acol, PERL_VDB_TYPEMETHOD,
				NULL, NULL, NULL, NULL);
		if (!SvIOK(d1)) goto error;
		(*r)->col.types[i] = SvIV(d1);

		SvREFCNT_dec(d1);
		
		d1 = perlvdb_perlmethod(acol, PERL_VDB_NAMEMETHOD,
				NULL, NULL, NULL, NULL);
		if (!SvPOK(d1)) goto error;
		currentstring = SvPV(d1, len);
		charbuf = pkg_malloc(len+1);
		strncpy(charbuf, currentstring, len+1);
		(*r)->col.names[i]->s = charbuf;
		(*r)->col.names[i]->len = strlen(charbuf);

		SvREFCNT_dec(d1);

	}

	rowarrayref = perlvdb_perlmethod(perlres, PERL_VDB_ROWSMETHOD,
			NULL, NULL, NULL, NULL);
	if (!(SvROK(rowarrayref))) { /* Empty result set */
		(*r)->n = 0;
		(*r)->res_rows = 0;
		(*r)->last_row = 0;
		goto end;
	}

	rowarray = (AV *)SvRV(rowarrayref);
	if (!(SvTYPE(rowarray) == SVt_PVAV)) goto error;

	rowcount = av_len(rowarray) + 1;

	(*r)->n = rowcount;
	(*r)->res_rows = rowcount;
	(*r)->last_row = rowcount;
	
	(*r)->rows = (db_row_t *)pkg_malloc(rowcount*sizeof(db_row_t));

	for (i = 0; i < rowcount; i++) {
		arowref = *av_fetch(rowarray, 0, 0);
		if (!SvROK(arowref)) goto error;
		arow = (AV *)SvRV(arowref);
		if (!(SvTYPE(colarray) == SVt_PVAV)) goto error;
		arowlen = av_len(arow) + 1;

		(*r)->rows[i].n = arowlen;
		(*r)->rows[i].values =
			(db_val_t *)pkg_malloc(arowlen*sizeof(db_val_t));


		for (j = 0; j < arowlen; j++) {
			aelement = *av_fetch(arow, j, 0);
#define cur_val (((*r)->rows)[i].values)[j]
			/*cur_val = (((*r)->rows)[i].values)[j];*/
			  /* cur_val is just an "abbreviation" */
			if (!(sv_isobject(aelement) && 
				sv_derived_from(aelement, PERL_CLASS_VALUE))) {
				cur_val.nul = 1;
				continue;
			}
			atype = SvIV(atypesv = perlvdb_perlmethod(aelement,
						PERL_VDB_TYPEMETHOD,
						NULL, NULL, NULL, NULL));
			aval = perlvdb_perlmethod(aelement, PERL_VDB_DATAMETHOD,
					NULL, NULL, NULL, NULL);

			(*r)->rows[i].values[j].type = atype;
			if (!SvOK(aval)) {
				cur_val.nul = 1;
			} else {
				switch (atype) {
					case DB1_INT:
						cur_val.val.int_val = 
							SvIV(aval);
						cur_val.nul = 0;
						break;
					case DB1_DOUBLE:
						cur_val.val.double_val = 
							SvNV(aval);
						cur_val.nul = 0;
						break;
					case DB1_STRING:
					case DB1_STR:
				/* We dont support DB1_STR for now.
				 * Set DB1_STRING instead */
						cur_val.type = DB1_STRING;
						currentstring = SvPV(aval, len);
						charbuf = pkg_malloc(len+1);
						strncpy(charbuf, currentstring,
								len+1);
						cur_val.val.string_val =
							charbuf;
						cur_val.nul = 0;
						break;
					case DB1_DATETIME:
						cur_val.val.time_val =
							(time_t)SvIV(aval);
						cur_val.nul = 0;
						break;
					case DB1_BLOB:
						currentstring = SvPV(aval, len);
						charbuf = pkg_malloc(len+1);
						strncpy(charbuf, currentstring,
								len+1);
						cur_val.val.blob_val.s =
							charbuf;
						cur_val.val.blob_val.len = len;
						cur_val.nul = 0;
						break;
					case DB1_BITMAP:
						cur_val.val.bitmap_val =
							SvIV(aval);
						cur_val.nul = 0;
						break;
					default:
						LM_CRIT("cannot handle this data type.\n");
						return -1;
						break;
				}
			}
			SvREFCNT_dec(atypesv);
			SvREFCNT_dec(aval);
		}
	}

end:
	av_undef(colarray);
	av_undef(rowarray);
	return retval;
error:
	LM_CRIT("broken result set. Exiting, leaving Kamailio in unknown state.\n");
	return -1;
}
Example #7
0
int   perl_trapd_handler( netsnmp_pdu           *pdu,
                          netsnmp_transport     *transport,
                          netsnmp_trapd_handler *handler)
{
    trapd_cb_data *cb_data;
    SV *pcallback;
    netsnmp_variable_list *vb;
    netsnmp_oid *o;
    SV *arg;
    SV *rarg;
    SV **tmparray;
    int i, c = 0;
    u_char *outbuf;
    size_t ob_len = 0, oo_len = 0;
    AV *varbinds;
    HV *pduinfo;

    dSP;
    ENTER;
    SAVETMPS;

    if (!pdu || !handler)
        return 0;

    /* nuke v1 PDUs */
    if (pdu->command == SNMP_MSG_TRAP)
        pdu = convert_v1pdu_to_v2(pdu);

    cb_data = handler->handler_data;
    if (!cb_data || !cb_data->perl_cb)
        return 0;

    pcallback = cb_data->perl_cb;

    /* get PDU related info */
    pduinfo = newHV();
#define STOREPDU(n, v) hv_store(pduinfo, n, strlen(n), v, 0)
#define STOREPDUi(n, v) STOREPDU(n, newSViv(v))
#define STOREPDUs(n, v) STOREPDU(n, newSVpv(v, 0))
    STOREPDUi("version", pdu->version);
    STOREPDUs("notificationtype", ((pdu->command == SNMP_MSG_INFORM) ? "INFORM":"TRAP"));
    STOREPDUi("requestid", pdu->reqid);
    STOREPDUi("messageid", pdu->msgid);
    STOREPDUi("transactionid", pdu->transid);
    STOREPDUi("errorstatus", pdu->errstat);
    STOREPDUi("errorindex", pdu->errindex);
    if (pdu->version == 3) {
        STOREPDUi("securitymodel", pdu->securityModel);
        STOREPDUi("securitylevel", pdu->securityLevel);
        STOREPDU("contextName",
                 newSVpv(pdu->contextName, pdu->contextNameLen));
        STOREPDU("contextEngineID",
                 newSVpv(pdu->contextEngineID,
                                    pdu->contextEngineIDLen));
        STOREPDU("securityEngineID",
                 newSVpv(pdu->securityEngineID,
                                    pdu->securityEngineIDLen));
        STOREPDU("securityName",
                 newSVpv(pdu->securityName, pdu->securityNameLen));
    } else {
        STOREPDU("community",
                 newSVpv(pdu->community, pdu->community_len));
    }

    if (transport && transport->f_fmtaddr) {
        char *tstr = transport->f_fmtaddr(transport, pdu->transport_data,
                                          pdu->transport_data_length);
        STOREPDUs("receivedfrom", tstr);
        free(tstr);
    }


    /*
     * collect OID objects in a temp array first
     */
    /* get VARBIND related info */
    i = count_varbinds(pdu->variables);
    tmparray = malloc(sizeof(*tmparray) * i);

    for(vb = pdu->variables; vb; vb = vb->next_variable) {

        /* get the oid */
        o = SNMP_MALLOC_TYPEDEF(netsnmp_oid);
        o->name = o->namebuf;
        o->len = vb->name_length;
        memcpy(o->name, vb->name, vb->name_length * sizeof(oid));

#undef CALL_EXTERNAL_OID_NEW

#ifdef CALL_EXTERNAL_OID_NEW
        PUSHMARK(sp);

        rarg = sv_2mortal(newSViv((IV) 0));
        arg = sv_2mortal(newSVrv(rarg, "netsnmp_oidPtr"));
        sv_setiv(arg, (IV) o);
        XPUSHs(rarg);

        PUTBACK;
        i = perl_call_pv("NetSNMP::OID::newwithptr", G_SCALAR);
        SPAGAIN;

        if (i != 1) {
            snmp_log(LOG_ERR, "unhandled OID error.\n");
            /* ack XXX */
        }
        /* get the value */
        tmparray[c++] = POPs;
        SvREFCNT_inc(tmparray[c-1]);
        PUTBACK;
#else /* build it and bless ourselves */
        {
            HV *hv = newHV();
            SV *rv = newRV_noinc((SV *) hv);
            SV *rvsub = newRV_noinc((SV *) newSViv((UV) o));
            SV *sv;
            rvsub = sv_bless(rvsub, gv_stashpv("netsnmp_oidPtr", 1));
            hv_store(hv, "oidptr", 6,  rvsub, 0);
            rv = sv_bless(rv, gv_stashpv("NetSNMP::OID", 1));
            tmparray[c++] = rv;
        }
        
#endif /* build oid ourselves */
    }

    /*
     * build the varbind lists
     */
    varbinds = newAV();
    for(vb = pdu->variables, i = 0; vb; vb = vb->next_variable, i++) {
        /* push the oid */
        AV *vba;
        vba = newAV();


        /* get the value */
        outbuf = NULL;
        ob_len = 0;
        oo_len = 0;
	sprint_realloc_by_type(&outbuf, &ob_len, &oo_len, 1,
                               vb, 0, 0, 0);

        av_push(vba,tmparray[i]);
        av_push(vba,newSVpvn(outbuf, oo_len));
        free(outbuf);
        av_push(vba,newSViv(vb->type));
        av_push(varbinds, (SV *) newRV_noinc((SV *) vba));
    }

    PUSHMARK(sp);

    /* store the collected information on the stack */
    XPUSHs(sv_2mortal(newRV_noinc((SV*) pduinfo)));
    XPUSHs(sv_2mortal(newRV_noinc((SV*) varbinds)));

    /* put the stack back in order */
    PUTBACK;

    /* actually call the callback function */
    if (SvTYPE(pcallback) == SVt_PVCV) {
        perl_call_sv(pcallback, G_DISCARD);
        /* XXX: it discards the results, which isn't right */
    } else if (SvROK(pcallback) && SvTYPE(SvRV(pcallback)) == SVt_PVCV) {
        /* reference to code */
        perl_call_sv(SvRV(pcallback), G_DISCARD);
    } else {
        snmp_log(LOG_ERR, " tried to call a perl function but failed to understand its type: (ref = %x, svrok: %lu, SVTYPE: %lu)\n", (uintptr_t)pcallback, SvROK(pcallback), SvTYPE(pcallback));
    }

#ifdef DUMPIT
    fprintf(stderr, "DUMPDUMPDUMPDUMPDUMPDUMP\n");
    sv_dump(pduinfo);
    fprintf(stderr, "--------------------\n");
    sv_dump(varbinds);
#endif
    
    /* svREFCNT_dec((SV *) pduinfo); */
#ifdef NOT_THIS
    {
        SV *vba;
        while(vba = av_pop(varbinds)) {
            av_undef((AV *) vba);
        }
    }
    av_undef(varbinds);
#endif    
    free(tmparray);

    /* Not needed because of the G_DISCARD flag (I think) */
    /* SPAGAIN; */
    /* PUTBACK; */
#ifndef __x86_64__
    FREETMPS; /* FIXME: known to cause a segfault on x86-64 */
#endif
    LEAVE;
    return NETSNMPTRAPD_HANDLER_OK;
}