home *** CD-ROM | disk | FTP | other *** search
- /*
- ** GENERAL
- **
- ** HTTP Wrapper for General utility RPCs and Scalars.
- ** Scalars are executed using the <RC@scalar...> scripting
- ** functionality.
- **
- **
- ** Confidential Property of Tod Sambar
- ** (c) Copyright Tod Sambar 1997
- ** All rights reserved.
- **
- **
- ** Public Functions:
- **
- ** pagecount_rpc
- ** pagecount_scalar
- **
- **
- ** History:
- ** Chg# Date Description Resp
- ** ---- ------- ------------------------------------------------------- ----
- ** 10JUN97 Created sambar
- ** 12JUL98 Added pragma-no cache to page counter sambar
- ** 10JAN00 Added scalar sample sambar
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <memory.h>
- #include <ctype.h>
- #include <string.h>
- #include <general.h>
- #ifndef WIN32
- #include <unistd.h>
- #include <sys/file.h>
- #define stricmp strcasecmp
- #endif
-
- /*
- ** General RPC Commands
- */
- typedef struct general__rpcs
- {
- SA_CHAR *name;
- SA_RPCPARAM *params;
- SA_INT numparams;
- SA_INT auth;
- SA_VOID *func;
- SA_CHAR *descr;
- } GENERAL__RPCS;
-
- static SA_RPCPARAM pagep [] =
- {
- { "page", 1, "Page associated with the row counter." },
- { "style", 0, "Page style: standard | plain" }
- };
-
- static GENERAL__RPCS general_rpcs [] =
- {
- { "pagecount", pagep, sizeof(pagep)/sizeof(SA_RPCPARAM),
- SA_AUTHORIZATION_ALL, (SA_VOID *)pagecount_rpc,
- "Retrieve the number of hits for a page." }
- };
-
- /*
- ** General Scalar Methods
- */
- typedef struct general__scalars
- {
- SA_CHAR *name;
- SA_SCALARARG *args;
- SA_INT numargs;
- SA_VOID *func;
- SA_CHAR *descr;
- } GENERAL__SCALARS;
-
- static SA_SCALARARG pagecountp [] =
- {
- { "page", "Page associated with the row counter." }
- };
-
- static GENERAL__SCALARS general_scalars [] =
- {
- { "pagecount", pagecountp, sizeof(pagecountp)/sizeof(SA_SCALARARG),
- (SA_VOID *)pagecount_scalar,
- "Retrieve the number of hits for a page." }
- };
-
-
- /*
- ** GENERAL_INIT
- **
- ** Initialize the General Utility RPCS use by the Sambar Server plugins.
- **
- **
- ** Parameters:
- ** sactx Sambar Server context
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- general_init(sactx)
- SA_CTX *sactx;
- {
- int i;
-
- /* Register the RPCs with the server */
- for (i = 0; i < sizeof(general_rpcs) / sizeof(GENERAL__RPCS); i++)
- {
- if (sa_cmd_init(sactx, general_rpcs[i].name, general_rpcs[i].params,
- general_rpcs[i].numparams, general_rpcs[i].auth,
- general_rpcs[i].descr, general_rpcs[i].func) != SA_SUCCEED)
- {
- sa_log2(sactx, SA_LOG_ERROR,
- "Unable to initialize General Utility RPCs");
- return (SA_FAIL);
- }
- }
-
- /* Register the Scalar methods with the server */
- for (i = 0; i < sizeof(general_scalars) / sizeof(GENERAL__SCALARS); i++)
- {
- if (sa_scalar_init(sactx, general_scalars[i].name,
- general_scalars[i].args, general_scalars[i].numargs,
- general_scalars[i].descr, general_scalars[i].func) != SA_SUCCEED)
- {
- sa_log2(sactx, SA_LOG_ERROR,
- "Unable to initialize General Utility Scalars");
- return (SA_FAIL);
- }
- }
-
- sa_log2(sactx, SA_LOG_TRACE,
- "General RPC and Scalar Utilities Initialized");
-
- return (SA_SUCCEED);
- }
-
- /*
- ** PAGECOUNT_RPC
- **
- ** RPC to retrieve the count associated with a page.
- **
- ** Parameters:
- ** sactx Sambar Server context
- ** saconn Sambar Server connection
- ** saparams RPC Parameters
- ** infop Error parameters
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- pagecount_rpc(sactx, saconn, saparams, infop)
- SA_CTX *sactx;
- SA_CONN *saconn;
- SA_PARAMS *saparams;
- SA_INT *infop;
- {
- int fh;
- SA_INT head;
- SA_INT datalen;
- SA_INT num, i, j;
- SA_BOOL plain;
- SA_CHAR *data;
- SA_INT count[INT_WIDTH + 1];
- SA_CHAR pagename[1024];
- SA_CHAR dirname[512];
- SA_CHAR buffer[256];
-
- plain = 0;
- if (sa_param(sactx, saparams, "style", &data, &datalen) == SA_SUCCEED)
- {
- if ((datalen == 5) && (stricmp(data, "plain") == 0))
- plain = 1;
- }
-
- if (sa_param(sactx, saparams, "page", &data, &datalen) != SA_SUCCEED)
- {
- *infop = SA_E_INVALIDDATA;
- sa_log2(sactx, SA_LOG_WARN,
- "pagecount_rpc(): Expected parameter 'page'!");
- return (SA_FAIL);
- }
-
- if ((datalen == 0) || (datalen > 40))
- {
- *infop = SA_E_INVALIDDATA;
- sa_log2(sactx, SA_LOG_WARN, "pagecount_rpc(): 'page' field is NULL!");
- return (SA_FAIL);
- }
-
- /* Disallow pathed names (i.e. .. / ~ etc.) */
- for (i = 0; i < datalen; i++)
- {
- if (!(isalnum(data[i]) || (data[i] == '_') ||
- (data[i] == '-') || (data[i] == '.')))
- {
- *infop = SA_E_INVALIDDATA;
- sa_log2(sactx, SA_LOG_WARN,
- "pagecount_rpc(): 'page' contains invalid characters!");
- return (SA_FAIL);
- }
-
- if ((i > 0) && (data[i] == '.') && (data[i - 1] == '.'))
- {
- *infop = SA_E_INVALIDDATA;
- sa_log2(sactx, SA_LOG_WARN,
- "pagecount_rpc(): 'page' contains invalid characters!");
- return (SA_FAIL);
- }
- }
-
-
- /*
- ** Open the file with the current count.
- ** The file must exist or we return 0.
- */
- if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_HOMEDIR, pagename,
- 900, &i) != SA_SUCCEED)
- {
- sa_log2(sactx, SA_LOG_WARN,
- "pagecount_rpc(): Failure getting SA_CTXPROP_HOMEDIR!");
- return (SA_FAIL);
- }
-
- if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_APPLICDIR, dirname,
- 512, &j) != SA_SUCCEED)
- {
- sa_log2(sactx, SA_LOG_WARN,
- "pagecount_rpc(): Failure getting SA_CTXPROP_APPLICDIR!");
- return (SA_FAIL);
- }
-
- #ifdef WIN32
- sprintf(&pagename[i], "\\%s\\%s", (j > 0 ? dirname : "tmp"), data);
- #else
- if (j > 0)
- sprintf(&pagename[i], "/%s/%s", dirname, data);
- else
- sprintf(&pagename[i], "/%s/tmp", data);
- #endif /* WIN32 */
-
- num = 0;
-
- #ifdef WIN32
- if ((fh = _sopen(pagename, _O_RDWR, _SH_DENYNO, _S_IREAD|_S_IWRITE)) != -1)
- {
- if (_locking(fh, _LK_LOCK, 1) != -1)
- {
- buffer[0] = '\0';
- _read(fh, buffer, INT_WIDTH);
- num = atol(buffer) + 1;
- lseek(fh, 0L, SEEK_SET);
- sprintf(buffer, "%ld\n", num);
- _write(fh, buffer, strlen(buffer));
- _locking(fh, _LK_UNLCK, 1);
- }
-
- _close(fh);
- }
- #else /* LINUX */
- /* FIX THIS sambar - need locking! */
- if ((fh = open(pagename, O_RDWR)) != -1)
- {
- if (flock(fh, LOCK_EX) != -1)
- {
- buffer[0] = '\0';
- read(fh, buffer, INT_WIDTH);
- num = atol(buffer) + 1;
- lseek(fh, 0L, SEEK_SET);
- sprintf(buffer, "%ld\n", num);
- write(fh, buffer, strlen(buffer));
- flock(fh, LOCK_UN);
- }
-
- close(fh);
- }
- #endif
-
- /* Convert the current count to an array of numbers. */
- count[INT_WIDTH] = '\0';
- for (i = 0; i < INT_WIDTH; ++i)
- {
- j = num % 10;
- count[INT_WIDTH - 1 - i] = j;
- num /= 10;
- }
-
- /* Send HTTP header */
- if (sa_send_header(saconn, "HTTP/1.0 200 OK\r\n", SA_NULLTERM)
- != SA_SUCCEED)
- {
- return (SA_FAIL);
- }
-
- if (sa_conn_send(saconn, "Expires: Thu, 01 Jan 1995 01:00:00:00 GMT\r\n",
- SA_NULLTERM) != SA_SUCCEED)
- {
- return (SA_FAIL);
- }
-
- if (sa_conn_send(saconn, "Pragma: no-cache\r\n", SA_NULLTERM)
- != SA_SUCCEED)
- {
- return (SA_FAIL);
- }
-
- if (sa_conn_send(saconn, "Connection: close\r\n", SA_NULLTERM)
- != SA_SUCCEED)
- {
- return (SA_FAIL);
- }
-
- /* MIME type is x bitmap */
- if (sa_conn_send(saconn, "Content-Type: image/x-xbitmap\r\n\r\n",
- SA_NULLTERM) != SA_SUCCEED)
- {
- return (SA_FAIL);
- }
-
- /* Strip leading zeros from the 'plain' display. */
- head = 0;
- if (plain)
- {
- while ((count[head] == 0) && (head < INT_WIDTH - 1))
- head++;
- }
-
- /* print the counter definitions */
- sprintf(buffer, "#define counter_width %ld\r\n",
- (INT_WIDTH - head) * COUNT_WIDTH);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- sprintf(buffer, "#define counter_height %d\r\n", COUNT_HEIGHT);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- /* print out the bitmap itself */
- if (sa_conn_send(saconn, "static unsigned char counter_bits[] = {\r\n",
- SA_NULLTERM) != SA_SUCCEED)
- {
- return (SA_FAIL);
- }
-
- if (plain)
- {
- for (i = 0; i < COUNT_HEIGHT; ++i)
- {
- for (j = head; j < INT_WIDTH; ++j)
- {
- sprintf(buffer, "0x%02X, ", bitmap2[count[j]][i]);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
- }
- }
- }
- else
- {
- for (i = 0; i < COUNT_HEIGHT; ++i)
- {
- for (j = 0; j < INT_WIDTH; ++j)
- {
- sprintf(buffer, "%s", bitmap[(count[j] * COUNT_HEIGHT) + i]);
- if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- if (( i < COUNT_HEIGHT - 1) || (j < INT_WIDTH - 1))
- {
- if (sa_conn_send(saconn, ", ", SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
- }
- }
- }
-
- if (sa_conn_send(saconn, "\r\n", SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
- }
-
- if (sa_conn_send(saconn, "};\r\n", SA_NULLTERM) != SA_SUCCEED)
- return (SA_FAIL);
-
- if (sa_conn_flush(saconn) != SA_SUCCEED)
- return (SA_FAIL);
-
- return (SA_SUCCEED);
- }
-
- /*
- ** PAGECOUNT_SCALAR
- **
- ** Scalar to retrieve the count associated with a page.
- ** Operates identically to the pagecount RPC except only
- ** ASCII text is output.
- **
- ** Usage: <RC@pagecount(index)>
- **
- ** Parameters:
- ** sactx Sambar Server context
- ** saconn Sambar Server connection
- ** saargs Scalar arguments
- ** value Result buffer (maximum 1000 bytes).
- **
- ** Returns:
- ** SA_SUCCEED | SA_FAIL
- */
- SA_RETCODE SA_PUBLIC
- pagecount_scalar(sactx, saconn, saargs, value)
- SA_CTX *sactx;
- SA_CONN *saconn;
- SA_ARG *saargs;
- SA_CHAR *value;
- {
- int fh;
- SA_INT num, i, j;
- SA_INT datalen;
- SA_CHAR *data;
- SA_CHAR pagename[1024];
- SA_CHAR dirname[512];
- SA_CHAR buffer[256];
-
- data = saargs->value;
- if (data != NULL)
- datalen = strlen(data);
- else
- datalen = 0;
-
- if ((datalen == 0) || (datalen > 40))
- {
- sa_log2(sactx, SA_LOG_WARN,
- "pagecount_scalar(): 'page' field is NULL!");
- return (SA_FAIL);
- }
-
- /* Disallow pathed names (i.e. .. / ~ etc.) */
- for (i = 0; i < datalen; i++)
- {
- if (!(isalnum(data[i]) || (data[i] == '_') ||
- (data[i] == '-') || (data[i] == '.')))
- {
- sa_log2(sactx, SA_LOG_WARN,
- "pagecount_rpc(): 'page' contains invalid characters!");
- return (SA_FAIL);
- }
-
- if ((i > 0) && (data[i] == '.') && (data[i - 1] == '.'))
- {
- sa_log2(sactx, SA_LOG_WARN,
- "pagecount_rpc(): 'page' contains invalid characters!");
- return (SA_FAIL);
- }
- }
-
- /*
- ** Open the file with the current count.
- ** The file must exist or we return 0.
- */
- if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_HOMEDIR, pagename,
- 900, &i) != SA_SUCCEED)
- {
- sa_log2(sactx, SA_LOG_WARN,
- "pagecount_scalar(): Failure getting SA_CTXPROP_HOMEDIR!");
- return (SA_FAIL);
- }
-
- if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_APPLICDIR, dirname,
- 512, &j) != SA_SUCCEED)
- {
- sa_log2(sactx, SA_LOG_WARN,
- "pagecount_scalar(): Failure getting SA_CTXPROP_APPLICDIR!");
- return (SA_FAIL);
- }
-
- #ifdef WIN32
- sprintf(&pagename[i], "\\%s\\%s", (j > 0 ? dirname : "tmp"), data);
- #else
- if (j > 0)
- sprintf(&pagename[i], "/%s/%s", dirname, data);
- else
- sprintf(&pagename[i], "/%s/tmp", data);
- #endif /* WIN32 */
-
- num = 0;
-
- #ifdef WIN32
- if ((fh = _sopen(pagename, _O_RDWR, _SH_DENYNO, _S_IREAD|_S_IWRITE)) != -1)
- {
- if (_locking(fh, _LK_LOCK, 1) != -1)
- {
- buffer[0] = '\0';
- _read(fh, buffer, INT_WIDTH);
- num = atol(buffer) + 1;
- lseek(fh, 0L, SEEK_SET);
- sprintf(buffer, "%ld\n", num);
- _write(fh, buffer, strlen(buffer));
- _locking(fh, _LK_UNLCK, 1);
- }
-
- _close(fh);
- }
- #else /* LINUX */
- /* FIX THIS sambar - need locking! */
- if ((fh = open(pagename, O_RDWR)) != -1)
- {
- if (flock(fh, LOCK_EX) != -1)
- {
- buffer[0] = '\0';
- read(fh, buffer, INT_WIDTH);
- num = atol(buffer) + 1;
- lseek(fh, 0L, SEEK_SET);
- sprintf(buffer, "%ld\n", num);
- write(fh, buffer, strlen(buffer));
- flock(fh, LOCK_UN);
- }
-
- close(fh);
- }
- #endif
-
- /* Return the count in the scalar 'value' output buffer */
- sprintf(value, "%ld", num);
- return (SA_SUCCEED);
- }
-