home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2001 August
/
PCWorld_2001-08_cd.bin
/
Komunikace
/
sambar
/
_setup.1
/
general.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-07-01
|
12KB
|
511 lines
/*
** 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_log(sactx, "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_log(sactx, "Unable to initialize General Utility Scalars");
return (SA_FAIL);
}
}
sa_log(sactx, "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_log(sactx, "pagecount_rpc(): Expected parameter 'page'!");
return (SA_FAIL);
}
if ((datalen == 0) || (datalen > 40))
{
*infop = SA_E_INVALIDDATA;
sa_log(sactx, "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_log(sactx,
"pagecount_rpc(): 'page' contains invalid characters!");
return (SA_FAIL);
}
if ((i > 0) && (data[i] == '.') && (data[i - 1] == '.'))
{
*infop = SA_E_INVALIDDATA;
sa_log(sactx,
"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_log(sactx, "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_log(sactx, "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);
/* 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_log(sactx, "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_log(sactx,
"pagecount_rpc(): 'page' contains invalid characters!");
return (SA_FAIL);
}
if ((i > 0) && (data[i] == '.') && (data[i - 1] == '.'))
{
sa_log(sactx,
"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_log(sactx,
"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_log(sactx,
"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);
}