home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 September / PCWorld_2000-09_cd.bin / Komunik / sambar / _setup.1 / general.c < prev    next >
C/C++ Source or Header  |  2000-01-06  |  10KB  |  411 lines

  1. /*
  2. ** GENERAL
  3. **
  4. **      HTTP Wrapper for General utility RPCs and Scalars.
  5. **        Scalars are executed using the <RC@scalar...> scripting
  6. **        functionality.
  7. **
  8. **
  9. **        Confidential Property of Tod Sambar
  10. **        (c) Copyright Tod Sambar 1997
  11. **        All rights reserved.
  12. **
  13. **
  14. ** Public Functions:
  15. **
  16. **        pagecount_rpc
  17. **        pagecount_scalar
  18. **
  19. **
  20. ** History:
  21. ** Chg#    Date    Description                                                Resp
  22. ** ----    -------    -------------------------------------------------------    ----
  23. **         10JUN97    Created                                                    sambar
  24. **         12JUL98    Added pragma-no cache to page counter                    sambar
  25. **         10JAN00    Added scalar sample                                        sambar
  26. */
  27.  
  28. #include    <stdio.h>
  29. #include    <stdlib.h>
  30. #include    <memory.h>
  31. #include    <string.h>
  32. #include    <general.h>
  33.  
  34. /*
  35. ** General RPC Commands
  36. */
  37. typedef struct general__rpcs
  38. {
  39.     SA_CHAR            *name;
  40.     SA_RPCPARAM        *params;
  41.     SA_INT            numparams;
  42.     SA_INT            auth;
  43.     SA_VOID            *func;
  44.     SA_CHAR            *descr;
  45. } GENERAL__RPCS;
  46.  
  47. static SA_RPCPARAM    pagep [] =
  48. {
  49.     { "page",     1,    "Page associated with the row counter." },
  50.     { "style",     0,    "Page style: standard | plain" }
  51. };
  52.  
  53. static GENERAL__RPCS    general_rpcs [] =
  54. {
  55.     { "pagecount",    pagep,         sizeof(pagep)/sizeof(SA_RPCPARAM),
  56.       SA_AUTHORIZATION_ALL,        (SA_VOID *)pagecount_rpc,
  57.       "Retrieve the number of hits for a page." }
  58. };
  59.  
  60. /*
  61. ** General Scalar Methods
  62. */
  63. typedef struct general__scalars
  64. {
  65.     SA_CHAR            *name;
  66.     SA_SCALARARG    *args;
  67.     SA_INT            numargs;
  68.     SA_VOID            *func;
  69.     SA_CHAR            *descr;
  70. } GENERAL__SCALARS;
  71.  
  72. static SA_SCALARARG    pagecountp [] =
  73. {
  74.     { "page",     "Page associated with the row counter." }
  75. };
  76.  
  77. static GENERAL__SCALARS    general_scalars [] =
  78. {
  79.     { "pagecount",    pagecountp,        sizeof(pagecountp)/sizeof(SA_SCALARARG),
  80.       (SA_VOID *)pagecount_scalar,
  81.       "Retrieve the number of hits for a page." }
  82. };
  83.  
  84.  
  85. /*
  86. **  GENERAL_INIT
  87. **
  88. **    Initialize the General Utility RPCS use by the Sambar Server plugins.
  89. **
  90. **
  91. **  Parameters:
  92. **    sactx        Sambar Server context
  93. **
  94. **  Returns:
  95. **    SA_SUCCEED | SA_FAIL
  96. */
  97. SA_RETCODE SA_PUBLIC
  98. general_init(sactx)
  99. SA_CTX        *sactx;
  100. {
  101.     int            i;
  102.  
  103.     /* Register the RPCs with the server                                */
  104.     for (i = 0; i < sizeof(general_rpcs) / sizeof(GENERAL__RPCS); i++)
  105.     {
  106.         if (sa_cmd_init(sactx, general_rpcs[i].name, general_rpcs[i].params,
  107.             general_rpcs[i].numparams, general_rpcs[i].auth, 
  108.             general_rpcs[i].descr, general_rpcs[i].func) != SA_SUCCEED)
  109.         {
  110.             sa_log(sactx, "Unable to initialize General Utility RPCs");
  111.             return (SA_FAIL);
  112.         } 
  113.     }
  114.  
  115.     /* Register the Scalar methods with the server                        */
  116.     for (i = 0; i < sizeof(general_scalars) / sizeof(GENERAL__SCALARS); i++)
  117.     {
  118.         if (sa_scalar_init(sactx, general_scalars[i].name, 
  119.             general_scalars[i].args, general_scalars[i].numargs, 
  120.             general_scalars[i].descr, general_scalars[i].func) != SA_SUCCEED)
  121.         {
  122.             sa_log(sactx, "Unable to initialize General Utility Scalars");
  123.             return (SA_FAIL);
  124.         } 
  125.     }
  126.  
  127.     sa_log(sactx, "General RPC and Scalar Utilities Initialized");
  128.  
  129.     return (SA_SUCCEED);
  130. }
  131.  
  132. /*
  133. **  PAGECOUNT_RPC
  134. **
  135. **    RPC to retrieve the count associated with a page.
  136. **
  137. **  Parameters:
  138. **    sactx        Sambar Server context
  139. **    saconn        Sambar Server connection
  140. **    saparams    RPC Parameters
  141. **    infop        Error parameters
  142. **
  143. **  Returns:
  144. **    SA_SUCCEED | SA_FAIL
  145. */
  146. SA_RETCODE SA_PUBLIC
  147. pagecount_rpc(sactx, saconn, saparams, infop)
  148. SA_CTX        *sactx;
  149. SA_CONN        *saconn;
  150. SA_PARAMS    *saparams;
  151. SA_INT        *infop;
  152. {
  153.     int            fh;
  154.     SA_INT        head;
  155.     SA_INT        datalen;
  156.       SA_INT         num, i, j;
  157.     SA_BOOL        plain;
  158.     SA_CHAR        *data;
  159.       SA_INT         count[INT_WIDTH + 1];
  160.     SA_CHAR     pagename[1024];
  161.     SA_CHAR        dirname[512];
  162.     SA_CHAR        buffer[256];
  163.  
  164.     plain = 0;
  165.     if (sa_param(sactx, saparams, "style", &data, &datalen) == SA_SUCCEED)
  166.     {
  167.         if ((datalen == 5) && (stricmp(data, "plain") == 0))
  168.             plain = 1;
  169.     }
  170.     
  171.     if (sa_param(sactx, saparams, "page", &data, &datalen) != SA_SUCCEED)
  172.     {
  173.         *infop = SA_E_INVALIDDATA;
  174.         sa_log(sactx, "pagecount_rpc(): Expected parameter 'page'!");
  175.         return (SA_FAIL);
  176.     }
  177.     
  178.     if ((datalen == 0) || (datalen > 40))
  179.     {
  180.         *infop = SA_E_INVALIDDATA;
  181.         sa_log(sactx, "pagecount_rpc(): 'page' field is NULL!");
  182.         return (SA_FAIL);
  183.     }
  184.  
  185.  
  186.     /*
  187.     ** Open the file with the current count.
  188.     ** The file must exist or we return 0.
  189.     */
  190.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_HOMEDIR, pagename,
  191.         900, &i) != SA_SUCCEED)
  192.     {
  193.         sa_log(sactx, "pagecount_rpc(): Failure getting SA_CTXPROP_HOMEDIR!");
  194.         return (SA_FAIL);
  195.     }
  196.  
  197.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_APPLICDIR, dirname,
  198.         512, &j) != SA_SUCCEED)
  199.     {
  200.         sa_log(sactx, "pagecount_rpc(): Failure getting SA_CTXPROP_APPLICDIR!");
  201.         return (SA_FAIL);
  202.     }
  203.  
  204.     sprintf(&pagename[i], "\\%s\\%s", j > 0 ? dirname : "tmp", data);
  205.  
  206.     num = 0;
  207.     if ((fh = _sopen(pagename, _O_RDWR, _SH_DENYNO, _S_IREAD|_S_IWRITE)) != -1)
  208.     {
  209.         if (_locking(fh, _LK_LOCK, 1) != -1)
  210.         {
  211.             buffer[0] = '\0';
  212.             _read(fh, buffer, INT_WIDTH);
  213.             num = atol(buffer) + 1;
  214.             lseek(fh, 0L, SEEK_SET);
  215.             sprintf(buffer, "%d\n", num);
  216.             _write(fh, buffer, strlen(buffer));
  217.             _locking(fh, _LK_UNLCK, 1);
  218.         }
  219.  
  220.         _close(fh);
  221.     }
  222.  
  223.     /* Convert the current count to an array of numbers. */
  224.     count[INT_WIDTH] = '\0';
  225.     for (i = 0; i < INT_WIDTH; ++i) 
  226.     {
  227.         j = num % 10;
  228.         count[INT_WIDTH - 1 - i] = j;
  229.         num /= 10;
  230.     }
  231.  
  232.     /* Send HTTP header */
  233.     if (sa_send_header(saconn, "HTTP/1.0 200 OK\r\n", SA_NULLTERM) 
  234.         != SA_SUCCEED)
  235.     {
  236.         return (SA_FAIL);
  237.     }
  238.  
  239.     if (sa_conn_send(saconn, "Expires: Thu, 01 Jan 1995 01:00:00:00 GMT\r\n", 
  240.         SA_NULLTERM) != SA_SUCCEED)
  241.     {
  242.         return (SA_FAIL);
  243.     }
  244.  
  245.     if (sa_conn_send(saconn, "Pragma: no-cache\r\n", SA_NULLTERM) != SA_SUCCEED)
  246.         return (SA_FAIL);
  247.  
  248.     /* MIME type is x bitmap */
  249.     if (sa_conn_send(saconn, "Content-Type: image/x-xbitmap\r\n\r\n", 
  250.         SA_NULLTERM) != SA_SUCCEED)
  251.     {
  252.         return (SA_FAIL);
  253.     }
  254.  
  255.     /* Strip leading zeros from the 'plain' display. */
  256.     head = 0;
  257.     if (plain)
  258.     {
  259.         while ((count[head] == 0) && (head < INT_WIDTH - 1))
  260.             head++;
  261.     }
  262.  
  263.        /* print the counter definitions */
  264.        sprintf(buffer, "#define counter_width %d\r\n", 
  265.         (INT_WIDTH - head) * COUNT_WIDTH);
  266.     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  267.         return (SA_FAIL);
  268.  
  269.        sprintf(buffer, "#define counter_height %d\r\n", COUNT_HEIGHT);
  270.     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  271.         return (SA_FAIL);
  272.  
  273.        /* print out the bitmap itself */
  274.     if (sa_conn_send(saconn, "static unsigned char counter_bits[] = {\r\n", 
  275.         SA_NULLTERM) != SA_SUCCEED)
  276.     {
  277.         return (SA_FAIL);
  278.     }
  279.  
  280.     if (plain)
  281.     {
  282.            for (i = 0; i < COUNT_HEIGHT; ++i) 
  283.         {
  284.             for (j = head; j < INT_WIDTH; ++j) 
  285.             {
  286.                    sprintf(buffer, "0x%02X, ", bitmap2[count[j]][i]);
  287.                 if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  288.                     return (SA_FAIL);
  289.             }
  290.         }
  291.     }
  292.     else
  293.     {
  294.            for (i = 0; i < COUNT_HEIGHT; ++i) 
  295.         {
  296.             for (j = 0; j < INT_WIDTH; ++j) 
  297.             {
  298.                    sprintf(buffer, "%s", bitmap[(count[j] * COUNT_HEIGHT) + i]);
  299.                 if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  300.                     return (SA_FAIL);
  301.     
  302.                    if (( i < COUNT_HEIGHT - 1) || (j < INT_WIDTH - 1)) 
  303.                 {
  304.                     if (sa_conn_send(saconn, ", ", SA_NULLTERM) != SA_SUCCEED)
  305.                         return (SA_FAIL);
  306.                 }
  307.             }
  308.         }
  309.  
  310.         if (sa_conn_send(saconn, "\r\n", SA_NULLTERM) != SA_SUCCEED)
  311.             return (SA_FAIL);
  312.     }
  313.  
  314.     if (sa_conn_send(saconn, "};\r\n", SA_NULLTERM) != SA_SUCCEED)
  315.         return (SA_FAIL);
  316.  
  317.     if (sa_conn_flush(saconn) != SA_SUCCEED)
  318.         return (SA_FAIL);
  319.  
  320.     return (SA_SUCCEED);
  321. }
  322.  
  323. /*
  324. **  PAGECOUNT_SCALAR
  325. **
  326. **    Scalar to retrieve the count associated with a page.
  327. **    Operates identically to the pagecount RPC except only
  328. **    ASCII text is output.
  329. **
  330. **    Usage:    <RC@pagecount(index)>
  331. **
  332. **  Parameters:
  333. **    sactx        Sambar Server context
  334. **    saconn        Sambar Server connection
  335. **    saargs        Scalar arguments
  336. **    value        Result buffer (maximum 1000 bytes).
  337. **
  338. **  Returns:
  339. **    SA_SUCCEED | SA_FAIL
  340. */
  341. SA_RETCODE SA_PUBLIC
  342. pagecount_scalar(sactx, saconn, saargs, value)
  343. SA_CTX        *sactx;
  344. SA_CONN        *saconn;
  345. SA_ARG        *saargs;
  346. SA_CHAR        *value;
  347. {
  348.     int            fh;
  349.       SA_INT         num, i, j;
  350.     SA_INT        datalen;
  351.     SA_CHAR        *data;
  352.     SA_CHAR     pagename[1024];
  353.     SA_CHAR        dirname[512];
  354.     SA_CHAR        buffer[256];
  355.  
  356.     data = saargs->value;
  357.     if (data != NULL)
  358.         datalen = strlen(data);
  359.     else
  360.         datalen = 0;
  361.  
  362.     if ((datalen == 0) || (datalen > 40))
  363.     {
  364.         sa_log(sactx, "pagecount_scalar(): 'page' field is NULL!");
  365.         return (SA_FAIL);
  366.     }
  367.  
  368.     /*
  369.     ** Open the file with the current count.
  370.     ** The file must exist or we return 0.
  371.     */
  372.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_HOMEDIR, pagename,
  373.         900, &i) != SA_SUCCEED)
  374.     {
  375.         sa_log(sactx, 
  376.             "pagecount_scalar(): Failure getting SA_CTXPROP_HOMEDIR!");
  377.         return (SA_FAIL);
  378.     }
  379.  
  380.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_APPLICDIR, dirname,
  381.         512, &j) != SA_SUCCEED)
  382.     {
  383.         sa_log(sactx, 
  384.             "pagecount_scalar(): Failure getting SA_CTXPROP_APPLICDIR!");
  385.         return (SA_FAIL);
  386.     }
  387.  
  388.     sprintf(&pagename[i], "\\%s\\%s", j > 0 ? dirname : "tmp", data);
  389.  
  390.     num = 0;
  391.     if ((fh = _sopen(pagename, _O_RDWR, _SH_DENYNO, _S_IREAD|_S_IWRITE)) != -1)
  392.     {
  393.         if (_locking(fh, _LK_LOCK, 1) != -1)
  394.         {
  395.             buffer[0] = '\0';
  396.             _read(fh, buffer, INT_WIDTH);
  397.             num = atol(buffer) + 1;
  398.             lseek(fh, 0L, SEEK_SET);
  399.             sprintf(buffer, "%d\n", num);
  400.             _write(fh, buffer, strlen(buffer));
  401.             _locking(fh, _LK_UNLCK, 1);
  402.         }
  403.  
  404.         _close(fh);
  405.     }
  406.  
  407.     /* Return the count in the scalar 'value' output buffer            */
  408.     sprintf(value, "%d", num);
  409.     return (SA_SUCCEED);
  410. }
  411.