/**
 * 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;
}
Exemple #2
0
/**
 * 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;
}