xp_echo.c has an ESP that accepts a user-supplied input parameter and echoes it to the ESP client, which is the process invoking the ESP. This example includes the xp_message function, which sends messages and status, and the xp_echo function which processes the input parameter and performs the echoing. You can use this example as a template for building your own ESP functions. The source is in $SYBASE/$SYBASE_ASE/sample/esp.
/* ** xp_echo.c ** ** Description: ** The following sample program is generic in ** nature. It echoes an input string which is ** passed as the first parameter to the xp_echo ** ESP. This string is retrieved into a buffer ** and then sent back (echoed) to the ESP client. */
#include <string.h> #include <stdlib.h> #include <malloc.h>
/* Required Open Server include files.*/ #include <ospublic.h> #include <oserror.h>
/* ** Constant defining the length of the buffer that receives the ** input string. All of the Adaptive Server parameters related ** to ESP may not exceed 255 char long. */
#define ECHO_BUF_LEN 255
/* ** Function: ** xp_message ** Purpose: Sends information, status and completion of the ** command to the server. ** Input: ** SRV_PROC * ** char * a message string. ** Output: ** void */
void xp_message
(
SRV_PROC *srvproc, /* Pointer to Open Server thread
control structure */
char *message_string /* Input message string */
)
{
/*
** Declare a variable that will contain information
** about the message being sent to the SQL client.
*/
CS_SERVERMSG *errmsgp;
/*
** Allocate memory for this variable.
*/
errmsgp = (CS_SERVERMSG *) malloc((CS_INT
sizeof(CS_SERVERMSG));
if (errmsgp == NULL)
return;
/*
** clean the structure */
*/
memset(errmsgp,(CS_INT)0,(CS_INT) sizeof(CS_SERVERMSG));
/*
** Put you rnumber in as the message number.
*/
errmsgp->msgnumber = 25000;
errmsgp->state = 0;
/*
**The message is fatal.
*/
errmsgp->severity = SRV_FATAL_SERVER;
/*
** Let’s copy the string over.
*/
errmsgp->textlen = strlen(message_string);
if (errmsgp->textlen >= CS_MAX_MSG )
return;
strncpy(errmsgp->text, message_string, errmsgp->textlen);
errmsgp->status = (CS_FIRST_CHUNK | CS_LAST_CHUNK);
srv_sendinfo(srvproc, errmsgp, CS_TRAN_UNDEFINED);
/* Send the status to the client. */
srv_sendstatus(srvproc, 1);
/*
** A SRV_DONE_MORE instead of a SRV_DONE_FINAL must
** complete the result set of an Extended Stored
** Procedure.
*/
srv_senddone(srvproc, SRV_DONE_MORE, 0, 0);
free(errmsgp);
}
/* ** Function: xp_echo ** Purpose: ** Given an input string, this string is echoed as an output ** string to the corresponding SQL (ESP) client. ** Input: ** SRV_PROC * ** Output ** SUCCESS or FAILURE */
CS_RETCODE xp_echo
(
SRV_PROC *srvproc
)
{
CS_INT paramnum; /* number of parameters */
CS_CHAR echo_str_buf[ECHO_BUF_LEN + 1];
/* buffer to hold input string */
CS_RETCODE result = CS_SUCCEED;
CS_DATAFMT paramfmt; /* input/output param format */
CS_INT len; /* Length of input param */
CS_SMALLINT outlen;
/*
** Get number of input parameters.*/
*/
srv_numparams(srvproc, ¶mnum);
/*
** Only one parameter is expected.*/
*/
if (paramnum != 1)
{
/*
** Send a usage error message.*/
*/
xp_message(srvproc, "Invalid number of
parameters");
result = CS_FAIL;
}
else
{
/*
** Perform initializations.
*/
outlen = CS_GOODDATA;
memset(¶mfmt, (CS_INT)0,
(CS_INT)sizeof(CS_DATAFMT));
/*
** We are receiving data through an ESP as the
** first parameter. So describe this expected
** parameter.
*/
if ((result == CS_SUCCEED) &&
srv_descfmt(srvproc, CS_GET
SRV_RPCDATA, 1, ¶mfmt) != CS_SUCCEED)
{
result = CS_FAIL;
}
/*
** Describe and bind the buffer to receive the
** parameter.
*/
if ((result == CS_SUCCEED) &&
(srv_bind(srvproc, CS_GET, SRV_RPCDATA,
1, ¶mfmt,(CS_BYTE *) echo_str_buf,
&len, &outlen) != CS_SUCCEED))
{
result = CS_FAIL;
}
/* Receive the expected data.*/
if ((result == CS_SUCCEED) &&
srv_xferdata(srvproc,CS_GET,SRV_RPCDATA)
!= CS_SUCCEED)
{
result = CS_FAIL;
}
/*
** Now we have the input info and are ready to
** send the output info.
*/
if (result == CS_SUCCEED)
{
/*
** Perform initialization.
*/
if (len == 0)
outlen = CS_NULLDATA;
else
outlen = CS_GOODDATA;
memset(¶mfmt, (CS_INT)0,
(CS_INT)sizeof(CS_DATAFMT));
strcpy(paramfmt.name, "xp_echo");
paramfmt.namelen = CS_NULLTERM;
paramfmt.datatype = CS_CHAR_TYPE;
paramfmt.format = CS_FMT_NULLTERM;
paramfmt.maxlength = ECHO_BUF_LEN;
paramfmt.locale = (CS_LOCALE *) NULL;
paramfmt.status |= CS_CANBENULL;
/*
** Describe the data being sent.
*/
if ((result == CS_SUCCEED) &&
srv_descfmt(srvproc, CS_SET,
SRV_ROWDATA, 1, ¶mfmt)
!= CS_SUCCEED)
{
result = CS_FAIL;
}
/*
** Describe and bind the buffer that
** contains the data to be sent.
*/
if ((result == CS_SUCCEED) &&
(srv_bind(srvproc, CS_SET,
SRV_ROWDATA, 1,
¶mfmt, (CS_BYTE *)
echo_str_buf, &len, &outlen)
!= CS_SUCCEED))
{
result = CS_FAIL;
}
/*
** Send the actual data.
*/
if ((result == CS_SUCCEED) &&
srv_xferdata(srvproc, CS_SET,
SRV_ROWDATA)!= CS_SUCCEED)
{
result = CS_FAIL;
}
}
/*
** Indicate to the ESP client how the
** transaction was performed.
*/
if (result == CS_FAIL)
srv_sendstatus(srvproc, 1);
else
srv_sendstatus(srvproc, 0);
/*
** Send a count of the number of rows sent to
** the client.
*/
srv_senddone(srvproc,(SRV_DONE_COUNT |
SRV_DONE_MORE), 0, 1);
}
return result;
}