home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 October / PCWorld_2000-10_cd1.bin / Komunik / sambar / _setup.1 / general.c < prev    next >
C/C++ Source or Header  |  2000-06-26  |  11KB  |  470 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. #ifndef    WIN32
  34. #include    <unistd.h>
  35. #include    <sys/file.h>
  36. #define    stricmp        strcasecmp
  37. #endif
  38.  
  39. /*
  40. ** General RPC Commands
  41. */
  42. typedef struct general__rpcs
  43. {
  44.     SA_CHAR            *name;
  45.     SA_RPCPARAM        *params;
  46.     SA_INT            numparams;
  47.     SA_INT            auth;
  48.     SA_VOID            *func;
  49.     SA_CHAR            *descr;
  50. } GENERAL__RPCS;
  51.  
  52. static SA_RPCPARAM    pagep [] =
  53. {
  54.     { "page",     1,    "Page associated with the row counter." },
  55.     { "style",     0,    "Page style: standard | plain" }
  56. };
  57.  
  58. static GENERAL__RPCS    general_rpcs [] =
  59. {
  60.     { "pagecount",    pagep,         sizeof(pagep)/sizeof(SA_RPCPARAM),
  61.       SA_AUTHORIZATION_ALL,        (SA_VOID *)pagecount_rpc,
  62.       "Retrieve the number of hits for a page." }
  63. };
  64.  
  65. /*
  66. ** General Scalar Methods
  67. */
  68. typedef struct general__scalars
  69. {
  70.     SA_CHAR            *name;
  71.     SA_SCALARARG    *args;
  72.     SA_INT            numargs;
  73.     SA_VOID            *func;
  74.     SA_CHAR            *descr;
  75. } GENERAL__SCALARS;
  76.  
  77. static SA_SCALARARG    pagecountp [] =
  78. {
  79.     { "page",     "Page associated with the row counter." }
  80. };
  81.  
  82. static GENERAL__SCALARS    general_scalars [] =
  83. {
  84.     { "pagecount",    pagecountp,        sizeof(pagecountp)/sizeof(SA_SCALARARG),
  85.       (SA_VOID *)pagecount_scalar,
  86.       "Retrieve the number of hits for a page." }
  87. };
  88.  
  89.  
  90. /*
  91. **  GENERAL_INIT
  92. **
  93. **    Initialize the General Utility RPCS use by the Sambar Server plugins.
  94. **
  95. **
  96. **  Parameters:
  97. **    sactx        Sambar Server context
  98. **
  99. **  Returns:
  100. **    SA_SUCCEED | SA_FAIL
  101. */
  102. SA_RETCODE SA_PUBLIC
  103. general_init(sactx)
  104. SA_CTX        *sactx;
  105. {
  106.     int            i;
  107.  
  108.     /* Register the RPCs with the server                                */
  109.     for (i = 0; i < sizeof(general_rpcs) / sizeof(GENERAL__RPCS); i++)
  110.     {
  111.         if (sa_cmd_init(sactx, general_rpcs[i].name, general_rpcs[i].params,
  112.             general_rpcs[i].numparams, general_rpcs[i].auth, 
  113.             general_rpcs[i].descr, general_rpcs[i].func) != SA_SUCCEED)
  114.         {
  115.             sa_log(sactx, "Unable to initialize General Utility RPCs");
  116.             return (SA_FAIL);
  117.         } 
  118.     }
  119.  
  120.     /* Register the Scalar methods with the server                        */
  121.     for (i = 0; i < sizeof(general_scalars) / sizeof(GENERAL__SCALARS); i++)
  122.     {
  123.         if (sa_scalar_init(sactx, general_scalars[i].name, 
  124.             general_scalars[i].args, general_scalars[i].numargs, 
  125.             general_scalars[i].descr, general_scalars[i].func) != SA_SUCCEED)
  126.         {
  127.             sa_log(sactx, "Unable to initialize General Utility Scalars");
  128.             return (SA_FAIL);
  129.         } 
  130.     }
  131.  
  132.     sa_log(sactx, "General RPC and Scalar Utilities Initialized");
  133.  
  134.     return (SA_SUCCEED);
  135. }
  136.  
  137. /*
  138. **  PAGECOUNT_RPC
  139. **
  140. **    RPC to retrieve the count associated with a page.
  141. **
  142. **  Parameters:
  143. **    sactx        Sambar Server context
  144. **    saconn        Sambar Server connection
  145. **    saparams    RPC Parameters
  146. **    infop        Error parameters
  147. **
  148. **  Returns:
  149. **    SA_SUCCEED | SA_FAIL
  150. */
  151. SA_RETCODE SA_PUBLIC
  152. pagecount_rpc(sactx, saconn, saparams, infop)
  153. SA_CTX        *sactx;
  154. SA_CONN        *saconn;
  155. SA_PARAMS    *saparams;
  156. SA_INT        *infop;
  157. {
  158.     int            fh;
  159.     SA_INT        head;
  160.     SA_INT        datalen;
  161.       SA_INT         num, i, j;
  162.     SA_BOOL        plain;
  163.     SA_CHAR        *data;
  164.       SA_INT         count[INT_WIDTH + 1];
  165.     SA_CHAR     pagename[1024];
  166.     SA_CHAR        dirname[512];
  167.     SA_CHAR        buffer[256];
  168.  
  169.     plain = 0;
  170.     if (sa_param(sactx, saparams, "style", &data, &datalen) == SA_SUCCEED)
  171.     {
  172.         if ((datalen == 5) && (stricmp(data, "plain") == 0))
  173.             plain = 1;
  174.     }
  175.     
  176.     if (sa_param(sactx, saparams, "page", &data, &datalen) != SA_SUCCEED)
  177.     {
  178.         *infop = SA_E_INVALIDDATA;
  179.         sa_log(sactx, "pagecount_rpc(): Expected parameter 'page'!");
  180.         return (SA_FAIL);
  181.     }
  182.     
  183.     if ((datalen == 0) || (datalen > 40))
  184.     {
  185.         *infop = SA_E_INVALIDDATA;
  186.         sa_log(sactx, "pagecount_rpc(): 'page' field is NULL!");
  187.         return (SA_FAIL);
  188.     }
  189.  
  190.  
  191.     /*
  192.     ** Open the file with the current count.
  193.     ** The file must exist or we return 0.
  194.     */
  195.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_HOMEDIR, pagename,
  196.         900, &i) != SA_SUCCEED)
  197.     {
  198.         sa_log(sactx, "pagecount_rpc(): Failure getting SA_CTXPROP_HOMEDIR!");
  199.         return (SA_FAIL);
  200.     }
  201.  
  202.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_APPLICDIR, dirname,
  203.         512, &j) != SA_SUCCEED)
  204.     {
  205.         sa_log(sactx, "pagecount_rpc(): Failure getting SA_CTXPROP_APPLICDIR!");
  206.         return (SA_FAIL);
  207.     }
  208.  
  209. #ifdef    WIN32
  210.     sprintf(&pagename[i], "\\%s\\%s", (j > 0 ? dirname : "tmp"), data);
  211. #else
  212.     if (j > 0)
  213.         sprintf(&pagename[i], "/%s/%s", dirname, data);
  214.     else
  215.         sprintf(&pagename[i], "/%s/tmp", data);
  216. #endif    /* WIN32 */
  217.  
  218.     num = 0;
  219.  
  220. #ifdef    WIN32
  221.     if ((fh = _sopen(pagename, _O_RDWR, _SH_DENYNO, _S_IREAD|_S_IWRITE)) != -1)
  222.     {
  223.         if (_locking(fh, _LK_LOCK, 1) != -1)
  224.         {
  225.             buffer[0] = '\0';
  226.             _read(fh, buffer, INT_WIDTH);
  227.             num = atol(buffer) + 1;
  228.             lseek(fh, 0L, SEEK_SET);
  229.             sprintf(buffer, "%ld\n", num);
  230.             _write(fh, buffer, strlen(buffer));
  231.             _locking(fh, _LK_UNLCK, 1);
  232.         }
  233.  
  234.         _close(fh);
  235.     }
  236. #else    /* LINUX */
  237.     /* FIX THIS sambar - need locking! */
  238.     if ((fh = open(pagename, O_RDWR)) != -1)
  239.     {
  240.         if (flock(fh, LOCK_EX) != -1)
  241.         {
  242.             buffer[0] = '\0';
  243.             read(fh, buffer, INT_WIDTH);
  244.             num = atol(buffer) + 1;
  245.             lseek(fh, 0L, SEEK_SET);
  246.             sprintf(buffer, "%ld\n", num);
  247.             write(fh, buffer, strlen(buffer));
  248.             flock(fh, LOCK_UN);
  249.         }
  250.  
  251.         close(fh);
  252.     }
  253. #endif
  254.  
  255.     /* Convert the current count to an array of numbers. */
  256.     count[INT_WIDTH] = '\0';
  257.     for (i = 0; i < INT_WIDTH; ++i) 
  258.     {
  259.         j = num % 10;
  260.         count[INT_WIDTH - 1 - i] = j;
  261.         num /= 10;
  262.     }
  263.  
  264.     /* Send HTTP header */
  265.     if (sa_send_header(saconn, "HTTP/1.0 200 OK\r\n", SA_NULLTERM) 
  266.         != SA_SUCCEED)
  267.     {
  268.         return (SA_FAIL);
  269.     }
  270.  
  271.     if (sa_conn_send(saconn, "Expires: Thu, 01 Jan 1995 01:00:00:00 GMT\r\n", 
  272.         SA_NULLTERM) != SA_SUCCEED)
  273.     {
  274.         return (SA_FAIL);
  275.     }
  276.  
  277.     if (sa_conn_send(saconn, "Pragma: no-cache\r\n", SA_NULLTERM) != SA_SUCCEED)
  278.         return (SA_FAIL);
  279.  
  280.     /* MIME type is x bitmap */
  281.     if (sa_conn_send(saconn, "Content-Type: image/x-xbitmap\r\n\r\n", 
  282.         SA_NULLTERM) != SA_SUCCEED)
  283.     {
  284.         return (SA_FAIL);
  285.     }
  286.  
  287.     /* Strip leading zeros from the 'plain' display. */
  288.     head = 0;
  289.     if (plain)
  290.     {
  291.         while ((count[head] == 0) && (head < INT_WIDTH - 1))
  292.             head++;
  293.     }
  294.  
  295.        /* print the counter definitions */
  296.        sprintf(buffer, "#define counter_width %ld\r\n", 
  297.         (INT_WIDTH - head) * COUNT_WIDTH);
  298.     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  299.         return (SA_FAIL);
  300.  
  301.        sprintf(buffer, "#define counter_height %d\r\n", COUNT_HEIGHT);
  302.     if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  303.         return (SA_FAIL);
  304.  
  305.        /* print out the bitmap itself */
  306.     if (sa_conn_send(saconn, "static unsigned char counter_bits[] = {\r\n", 
  307.         SA_NULLTERM) != SA_SUCCEED)
  308.     {
  309.         return (SA_FAIL);
  310.     }
  311.  
  312.     if (plain)
  313.     {
  314.            for (i = 0; i < COUNT_HEIGHT; ++i) 
  315.         {
  316.             for (j = head; j < INT_WIDTH; ++j) 
  317.             {
  318.                    sprintf(buffer, "0x%02X, ", bitmap2[count[j]][i]);
  319.                 if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  320.                     return (SA_FAIL);
  321.             }
  322.         }
  323.     }
  324.     else
  325.     {
  326.            for (i = 0; i < COUNT_HEIGHT; ++i) 
  327.         {
  328.             for (j = 0; j < INT_WIDTH; ++j) 
  329.             {
  330.                    sprintf(buffer, "%s", bitmap[(count[j] * COUNT_HEIGHT) + i]);
  331.                 if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  332.                     return (SA_FAIL);
  333.     
  334.                    if (( i < COUNT_HEIGHT - 1) || (j < INT_WIDTH - 1)) 
  335.                 {
  336.                     if (sa_conn_send(saconn, ", ", SA_NULLTERM) != SA_SUCCEED)
  337.                         return (SA_FAIL);
  338.                 }
  339.             }
  340.         }
  341.  
  342.         if (sa_conn_send(saconn, "\r\n", SA_NULLTERM) != SA_SUCCEED)
  343.             return (SA_FAIL);
  344.     }
  345.  
  346.     if (sa_conn_send(saconn, "};\r\n", SA_NULLTERM) != SA_SUCCEED)
  347.         return (SA_FAIL);
  348.  
  349.     if (sa_conn_flush(saconn) != SA_SUCCEED)
  350.         return (SA_FAIL);
  351.  
  352.     return (SA_SUCCEED);
  353. }
  354.  
  355. /*
  356. **  PAGECOUNT_SCALAR
  357. **
  358. **    Scalar to retrieve the count associated with a page.
  359. **    Operates identically to the pagecount RPC except only
  360. **    ASCII text is output.
  361. **
  362. **    Usage:    <RC@pagecount(index)>
  363. **
  364. **  Parameters:
  365. **    sactx        Sambar Server context
  366. **    saconn        Sambar Server connection
  367. **    saargs        Scalar arguments
  368. **    value        Result buffer (maximum 1000 bytes).
  369. **
  370. **  Returns:
  371. **    SA_SUCCEED | SA_FAIL
  372. */
  373. SA_RETCODE SA_PUBLIC
  374. pagecount_scalar(sactx, saconn, saargs, value)
  375. SA_CTX        *sactx;
  376. SA_CONN        *saconn;
  377. SA_ARG        *saargs;
  378. SA_CHAR        *value;
  379. {
  380.     int            fh;
  381.       SA_INT         num, i, j;
  382.     SA_INT        datalen;
  383.     SA_CHAR        *data;
  384.     SA_CHAR     pagename[1024];
  385.     SA_CHAR        dirname[512];
  386.     SA_CHAR        buffer[256];
  387.  
  388.     data = saargs->value;
  389.     if (data != NULL)
  390.         datalen = strlen(data);
  391.     else
  392.         datalen = 0;
  393.  
  394.     if ((datalen == 0) || (datalen > 40))
  395.     {
  396.         sa_log(sactx, "pagecount_scalar(): 'page' field is NULL!");
  397.         return (SA_FAIL);
  398.     }
  399.  
  400.     /*
  401.     ** Open the file with the current count.
  402.     ** The file must exist or we return 0.
  403.     */
  404.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_HOMEDIR, pagename,
  405.         900, &i) != SA_SUCCEED)
  406.     {
  407.         sa_log(sactx, 
  408.             "pagecount_scalar(): Failure getting SA_CTXPROP_HOMEDIR!");
  409.         return (SA_FAIL);
  410.     }
  411.  
  412.     if (sa_ctx_props(sactx, SA_GET, SA_CTXPROP_APPLICDIR, dirname,
  413.         512, &j) != SA_SUCCEED)
  414.     {
  415.         sa_log(sactx, 
  416.             "pagecount_scalar(): Failure getting SA_CTXPROP_APPLICDIR!");
  417.         return (SA_FAIL);
  418.     }
  419.  
  420. #ifdef    WIN32
  421.     sprintf(&pagename[i], "\\%s\\%s", (j > 0 ? dirname : "tmp"), data);
  422. #else
  423.     if (j > 0)
  424.         sprintf(&pagename[i], "/%s/%s", dirname, data);
  425.     else
  426.         sprintf(&pagename[i], "/%s/tmp", data);
  427. #endif    /* WIN32 */
  428.  
  429.     num = 0;
  430.  
  431. #ifdef    WIN32
  432.     if ((fh = _sopen(pagename, _O_RDWR, _SH_DENYNO, _S_IREAD|_S_IWRITE)) != -1)
  433.     {
  434.         if (_locking(fh, _LK_LOCK, 1) != -1)
  435.         {
  436.             buffer[0] = '\0';
  437.             _read(fh, buffer, INT_WIDTH);
  438.             num = atol(buffer) + 1;
  439.             lseek(fh, 0L, SEEK_SET);
  440.             sprintf(buffer, "%ld\n", num);
  441.             _write(fh, buffer, strlen(buffer));
  442.             _locking(fh, _LK_UNLCK, 1);
  443.         }
  444.  
  445.         _close(fh);
  446.     }
  447. #else    /* LINUX */
  448.     /* FIX THIS sambar - need locking! */
  449.     if ((fh = open(pagename, O_RDWR)) != -1)
  450.     {
  451.         if (flock(fh, LOCK_EX) != -1)
  452.         {
  453.             buffer[0] = '\0';
  454.             read(fh, buffer, INT_WIDTH);
  455.             num = atol(buffer) + 1;
  456.             lseek(fh, 0L, SEEK_SET);
  457.             sprintf(buffer, "%ld\n", num);
  458.             write(fh, buffer, strlen(buffer));
  459.             flock(fh, LOCK_UN);
  460.         }
  461.  
  462.         close(fh);
  463.     }
  464. #endif
  465.  
  466.     /* Return the count in the scalar 'value' output buffer            */
  467.     sprintf(value, "%ld", num);
  468.     return (SA_SUCCEED);
  469. }
  470.