/** * Initialize UDF from tr->udata. It is for internal UDF transactions * * Returns: * 0 on if found * -1 if not found */ int udf_rw_call_init_internal(udf_call * call, as_transaction * tr) { udf_call *ucall = NULL; if (tr->udata.req_type == UDF_SCAN_REQUEST) { ucall = as_scan_get_udf_call(tr->udata.req_udata); } else if (tr->udata.req_type == UDF_QUERY_REQUEST) { ucall = as_query_get_udf_call(tr->udata.req_udata); } if (ucall) { strncpy (call->def.filename, ucall->def.filename, sizeof(ucall->def.filename)); strncpy (call->def.function, ucall->def.function, sizeof(ucall->def.function)); call->tr = tr; call->def.arglist = ucall->def.arglist; call->def.type = ucall->def.type; if (tr->udata.req_type == UDF_SCAN_REQUEST) { cf_atomic_int_incr(&g_config.udf_scan_rec_reqs); } else if (tr->udata.req_type == UDF_QUERY_REQUEST) { cf_atomic_int_incr(&g_config.udf_query_rec_reqs); } return 0; } return -1; }
/** * Initialize a new UDF. This populates the udf_call from information * in the current transaction. If passed in transaction has req_data it is * assumed to be internal and the UDF information is picked from the udata * associated with it. TODO: Do not overload please define flag for this. * * * Parameter: * tr the transaction to build a udf_call from * * Returns" * return a new udf_call (Caller needs to free it up) * NULL in case of failure */ int udf_call_init(udf_call * call, as_transaction * tr) { call->active = false; call->udf_type = AS_SCAN_UDF_NONE; as_msg_field * filename = NULL; as_msg_field * function = NULL; as_msg_field * arglist = NULL; if (tr->udata.req_udata) { udf_call *ucall = NULL; if (tr->udata.req_type == UDF_SCAN_REQUEST) { ucall = &((tscan_job *)(tr->udata.req_udata))->call; } else if (tr->udata.req_type == UDF_QUERY_REQUEST) { ucall = as_query_get_udf_call(tr->udata.req_udata); } if (ucall) { strncpy(call->filename, ucall->filename, sizeof(ucall->filename)); strncpy(call->function, ucall->function, sizeof(ucall->function)); call->transaction = tr; call->active = true; call->arglist = ucall->arglist; call->udf_type = ucall->udf_type; if (tr->udata.req_type == UDF_SCAN_REQUEST) { cf_atomic_int_incr(&g_config.udf_scan_rec_reqs); } else if (tr->udata.req_type == UDF_QUERY_REQUEST) { cf_atomic_int_incr(&g_config.udf_query_rec_reqs); } } // TODO: return proper macros return 0; } // Check the type of udf as_msg_field * op = NULL; op = as_msg_field_get(&tr->msgp->msg, AS_MSG_FIELD_TYPE_UDF_OP); if (!op) { // Normal udf operation, no special type call->udf_type = 0; } else { // We got a udf type from the server byte optype; memcpy(&optype, (byte *)op->data, sizeof(optype)); if(optype == AS_SCAN_UDF_OP_UDF) { cf_debug(AS_UDF, "UDF scan op received"); call->udf_type = AS_SCAN_UDF_OP_UDF; } else if(optype == AS_SCAN_UDF_OP_BACKGROUND) { cf_debug(AS_UDF, "UDF scan background op received"); call->udf_type = AS_SCAN_UDF_OP_BACKGROUND; } else { cf_warning(AS_UDF, "Undefined udf type received over protocol"); goto Cleanup; } } filename = as_msg_field_get(&tr->msgp->msg, AS_MSG_FIELD_TYPE_UDF_FILENAME); if ( filename ) { function = as_msg_field_get(&tr->msgp->msg, AS_MSG_FIELD_TYPE_UDF_FUNCTION); if ( function ) { arglist = as_msg_field_get(&tr->msgp->msg, AS_MSG_FIELD_TYPE_UDF_ARGLIST); if ( arglist ) { call->transaction = tr; as_msg_field_get_strncpy(filename, &call->filename[0], sizeof(call->filename)); as_msg_field_get_strncpy(function, &call->function[0], sizeof(call->function)); call->arglist = arglist; call->active = true; cf_detail(AS_UDF, "UDF Request Unpacked %s %s", call->filename, call->function); return 0; } } } Cleanup: call->transaction = NULL; call->filename[0] = 0; call->function[0] = 0; call->arglist = NULL; return 1; }