home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / shmserve.zip / SHMCLIEN.C < prev    next >
C/C++ Source or Header  |  1998-12-04  |  23KB  |  773 lines

  1. /*  shmclien.c        v1.1
  2.  
  3.     This code sample illustrates the usage of suballocated shared memory
  4.     between two or more processes.
  5.  
  6.     shmserve.exe is the Server Process and should be running at all times.
  7.     shmclien.exe is the Client Process and can be run multiple times.
  8.  
  9.     This client sample presumes that a Server Process is already running.
  10.  
  11.     You can use the Client Process to Add, Delete, Read, or List
  12.     application (GLOM) data to/from the Shared memory area.
  13.  
  14.     You can also inquire the values in the Server Control record.
  15.  
  16.     Client Commands:
  17.        To add GLOM Data (Name and value):
  18.           SHMCLIEN A Glom_name glom_value
  19.        To delete 1st occurence of GLOM Data (Name):
  20.           SHMCLIEN D Glom_name
  21.        To list GLOM Data (Names and values):
  22.           SHMCLIEN L
  23.        To Inquire the contents of the Server Control Record
  24.           SHMCLIEN I
  25.  
  26.     You should be able to notice that Suballocation usage will
  27.        increase/decrease, as GLOM items are added/removed.
  28.     Each time you reach a certain threshold, additional memory
  29.        is allocated.
  30.  
  31. */
  32.  
  33. /* (c) Copyright IBM Corp. 1998  All rights reserved.
  34.  
  35. This sample program is owned by International Business Machines
  36. Corporation or one of its subsidiaries ("IBM") and is copyrighted
  37. and licensed, not sold.
  38.  
  39. You may copy, modify, and distribute this sample program in any
  40. form without payment to IBM,  for any purpose including developing,
  41. using, marketing or distributing programs that include or are
  42. derivative works of the sample program.
  43.  
  44. The sample program is provided to you on an "AS IS" basis, without
  45. warranty of any kind.  IBM HEREBY  EXPRESSLY DISCLAIMS ALL
  46. WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED
  47. TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  48. PARTICULAR PURPOSE.
  49.  
  50. Some jurisdictions do not allow for the exclusion or limitation of
  51. implied warranties, so the above limitations or exclusions may not
  52. apply to you.  IBM shall not be liable for any damages you suffer
  53. as a result of using, modifying or distributing the sample program
  54. or its derivatives.
  55.  
  56. Each copy of any portion of this sample program or any derivative
  57. work,  must include a the above copyright notice and disclaimer of
  58. warranty.
  59. */
  60.  
  61. /************************************
  62.  * Define Constants
  63.  ************************************/
  64.  
  65. #define TRACE                      0
  66.  
  67.  
  68. /************************************
  69.  * Include Files
  70.  ************************************/
  71.  
  72. #define INCL_DOSSEMAPHORES
  73. #define INCL_DOSMEMMGR
  74. #define INCL_DOS
  75. #define INCL_BASE
  76. #include <os2.h>
  77. #include <stdio.h>
  78. #include <stddef.h>
  79. #include <string.h>
  80. #include <stdlib.h>
  81.  
  82. #include <shmserve.h>
  83.  
  84. /************************************
  85.  * Define Statics (data and private functions)
  86.  ************************************/
  87. SERVERCONTROLREC        *servercontrol;
  88.  
  89. ULONG client_init      (SERVERCONTROLREC **pSrvCtlRec);
  90. ULONG client_term      (SERVERCONTROLREC **pSrvCtlRec);
  91. ULONG process_data     (int argc, char *argv[], char *envp[],
  92.                         SERVERCONTROLREC *pSrvCtlRec);
  93. ULONG GrowServerCtlSuballoc (SERVERCONTROLREC *serverctl);
  94. ULONG AddGLOMItem      (UCHAR  *glomname, UCHAR  *glomvalue);
  95. ULONG DeleteGLOMItem   (UCHAR  *glomname);
  96. ULONG GetGLOMItem      (UCHAR  *glomname, UCHAR  *glomvalue);
  97. ULONG ListGLOMItems    (void);
  98.  
  99. /************************************
  100.  * Source Code Instructions
  101.  ************************************/
  102.  
  103. int main(argc, argv, envp)
  104.    int argc;
  105.    char *argv[];
  106.    char *envp[];
  107.   {
  108.     APIRET                rc        = NO_ERROR;   /* Return code */
  109.     CHAR                  tempch;
  110.  
  111.     printf("Shared-Memory Client\n");
  112.  
  113. #if TRACE > 1
  114.     printf("\nGetting Shared Memory from Server...\n");
  115. #endif
  116.  
  117.     rc = client_init(&servercontrol);
  118.     if (rc != 0)
  119.       {
  120.         return(1);
  121.       }
  122.  
  123. #if TRACE > 1
  124.     printf("\nClient Processing data...\n");
  125. #endif
  126.  
  127.     rc = process_data(argc, argv, envp, servercontrol);
  128.  
  129.     rc = client_term(&servercontrol);
  130.  
  131.     return NO_ERROR;
  132.  
  133.  }
  134.  
  135. /* =====================================================================
  136.  *
  137.  * FUNCTION NAME:    client_init
  138.  *
  139.  * DESCRIPTIVE NAME: Initialize server internal memory
  140.  *
  141.  * DESCRIPTION:
  142.  *
  143.  * INPUT:
  144.  *
  145.  * OUTPUT:           Address to Server Control Record (Shared Memory)
  146.  *
  147.  * RETURN CODES:     OK - normal return
  148.  *
  149. ** ================================================================== */
  150. ULONG client_init      (SERVERCONTROLREC **pSrvCtlRec)
  151.   {
  152.     APIRET            ret;
  153.     PVOID             pSubBaseOffset;
  154.     SERVERCONTROLREC *SrvCtlRec;
  155.  
  156. #if TRACE > 1
  157.     printf("client_init starting\n");
  158. #endif
  159.  
  160.     // Get Shared Memory used for Server Control Record
  161.     ret = DosGetNamedSharedMem((PVOID *) pSrvCtlRec, SERVER_CONTROL_MEM_NAME,
  162.                                PAG_WRITE | PAG_READ);
  163.     if (ret != 0)
  164.       {
  165. #if TRACE > 1
  166.         printf("DosGetNamedSharedMem ret= %d\n", ret);
  167. #endif
  168.         if (ret == ERROR_FILE_NOT_FOUND)
  169.           {
  170.             printf("Server Process is not running\n");
  171.           }
  172.         return(ret);
  173.       }
  174.  
  175.     SrvCtlRec = *pSrvCtlRec;
  176.  
  177.     if (SrvCtlRec->Server_Status != 0)
  178.       {
  179.         printf("Server memory is not ready.  An old client may be running!\n");
  180.         return(1);
  181.       }
  182.  
  183.     // Create the Semaphores used to access Service Control Record
  184.     ret = DosOpenMutexSem((PSZ)NULL, &(SrvCtlRec->SubAlloc_Lock));
  185.     if (ret != 0)
  186.       {
  187.         printf("Unable to open SubAlloc_Lock semaphone %d\n", ret);
  188.         return(ret);
  189.       }
  190.  
  191.     // Create the Semaphores used to access Service Control Record
  192.     ret = DosOpenMutexSem((PSZ)NULL, &(SrvCtlRec->GLOM_List_Lock));
  193.     if (ret != 0)
  194.       {
  195.         printf("Unable to open GLOM_List_Lock semaphone %d\n", ret);
  196.         return(ret);
  197.       }
  198.  
  199. #if TRACE > 1
  200.     printf("client_init ending\n");
  201. #endif
  202.  
  203.     return(NO_ERROR);
  204.   }
  205.  
  206. /* =====================================================================
  207.  *
  208.  * FUNCTION NAME:    client_term
  209.  *
  210.  * DESCRIPTIVE NAME: Terminate server internal memory
  211.  *
  212.  * DESCRIPTION:      Free memory resources
  213.  *
  214.  * INPUT:
  215.  *
  216.  * OUTPUT:           Address to Server Control Record (Shared Memory)
  217.  *
  218.  * RETURN CODES:     OK - normal return
  219.  *
  220. ** ================================================================== */
  221. ULONG client_term      (SERVERCONTROLREC **pSrvCtlRec)
  222.   {
  223.     APIRET            ret;
  224.     PVOID             pSubBaseOffset;
  225.     SERVERCONTROLREC *SrvCtlRec;
  226.  
  227. #if TRACE > 1
  228.     printf("client_term starting\n");
  229. #endif
  230.  
  231.     SrvCtlRec = *pSrvCtlRec;
  232.  
  233.     // Close the Semaphores used to access Service Control Record
  234.     ret = DosCloseMutexSem(SrvCtlRec->SubAlloc_Lock);
  235.  
  236.     // Close the Semaphores used to access Service Control Record
  237.     ret = DosCloseMutexSem(SrvCtlRec->GLOM_List_Lock);
  238.  
  239.     ret = DosFreeMem((PVOID) SrvCtlRec);
  240.     if (ret != 0)
  241.       {
  242.         printf("DosFreeMem  ret= %d\n", ret);
  243.         return(1);
  244.       }
  245.  
  246.     *pSrvCtlRec = (PVOID) 0L;
  247.  
  248. #if TRACE > 1
  249.     printf("client_term ending\n");
  250. #endif
  251.  
  252.     return(NO_ERROR);
  253.   }
  254.  
  255. /* =====================================================================
  256.  *
  257.  * FUNCTION NAME:    GrowServerCtlSuballoc
  258.  *
  259.  * DESCRIPTIVE NAME: Increase the Sub-allocatable shared memory
  260.  *                   in the server control record.
  261.  *
  262.  * DESCRIPTION:
  263.  *
  264.  * INPUT:            Address of server control record
  265.  *
  266.  * OUTPUT:           <none>
  267.  *
  268.  * RETURN CODES:     0        - normal return
  269.  *
  270. ** ================================================================== */
  271. ULONG GrowServerCtlSuballoc (SERVERCONTROLREC *serverctl)
  272.   {
  273.     APIRET              ret;
  274.  
  275.     ret = DosSubSetMem(serverctl->SubAllocPool,
  276.                        DOSSUB_GROW | DOSSUB_SPARSE_OBJ,
  277.                        serverctl->SubAllocAvail + GROW_SUBALLOC_MEM_SIZE);
  278.     if (ret != 0)
  279.       {
  280.         printf("DosSubSetMem (Grow) ret= %d\n", ret);
  281.         return(1);
  282.       }
  283.  
  284.     (serverctl->SubAllocAvail) += GROW_SUBALLOC_MEM_SIZE;
  285.  
  286.     return(NO_ERROR);
  287.   }
  288.  
  289. /* =====================================================================
  290.  *
  291.  * FUNCTION NAME:    process_data
  292.  *
  293.  * DESCRIPTIVE NAME: Add, Delete, Read, or List Data, and Inquire Server
  294.  *
  295.  * DESCRIPTION:
  296.  *
  297.  * INPUT:            parameters from commandline
  298.  *
  299.  * OUTPUT:           <none>
  300.  *
  301.  * RETURN CODES:     0        - normal return
  302.  *
  303. ** ================================================================== */
  304. ULONG process_data     (int argc, char *argv[], char *envp[],
  305.                         SERVERCONTROLREC *pSrvCtlRec)
  306.   {
  307.     APIRET              ret;
  308.     GLOM                glom_in;
  309.  
  310.     if (argc < 2)
  311.       {
  312.         printf(
  313.             "Missing Command:  A=Add, D=Delete, R=Read, L=List, I=Inquire\n");
  314.         return(1);
  315.       }
  316.  
  317.     if (argc == 2)
  318.       {
  319.         if (argv[1][0] == 'L' ||
  320.             argv[1][0] == 'l'   )
  321.           {
  322.             /* List of GLOMs requested: */
  323.             printf("\nList of GLOM data:\n");
  324.             ret = ListGLOMItems();
  325.             if (ret != NO_ERROR)
  326.               {
  327.                 printf("NO RECORDS FOUND\n");
  328.               }
  329.             return(ret);
  330.           }
  331.         if (argv[1][0] == 'I' ||
  332.             argv[1][0] == 'i'   )
  333.           {
  334.             /* Inquire contents of servercontrol record: */
  335.             printf("\n\nServer Control Record:\n");
  336.             printf("ServerControl Address   0x%08lX\n",
  337.                    pSrvCtlRec);
  338.             printf("SubAllocPool Address    0x%08lX\n",
  339.                    pSrvCtlRec->SubAllocPool);
  340.             printf("SubAlloc Usage   %lu\n",
  341.                    pSrvCtlRec->SubAllocUsage);
  342.             printf("SubAlloc Avail   %lu\n",
  343.                    pSrvCtlRec->SubAllocAvail);
  344.             printf("Server Status    %u\n",
  345.                    pSrvCtlRec->Server_Status);
  346.             return(NO_ERROR);
  347.           }
  348.       }
  349.  
  350.     if (argc == 3)
  351.       {
  352.         if (argv[1][0] == 'D' ||
  353.             argv[1][0] == 'd'   )
  354.           {
  355.             /* Delete a GLOM record: */
  356. #if TRACE > 0
  357.             printf("Delete GLOM record:\n");
  358. #endif
  359.             memset(&glom_in, 0, sizeof(GLOM));
  360.             strncpy(glom_in.GLOMName, argv[2], GLOMNameLen);
  361.             glom_in.GLOMName[GLOMNameLen] = (UCHAR) 0;
  362.             ret = DeleteGLOMItem(glom_in.GLOMName);
  363.             return(ret);
  364.           }
  365.         if (argv[1][0] == 'R' ||
  366.             argv[1][0] == 'r'   )
  367.           {
  368.             /* Read a GLOM record: */
  369. #if TRACE > 0
  370.             printf("Read GLOM record:\n");
  371. #endif
  372.             memset(&glom_in, 0, sizeof(GLOM));
  373.             strncpy(glom_in.GLOMName, argv[2], GLOMNameLen);
  374.             glom_in.GLOMName[GLOMNameLen] = (UCHAR) 0;
  375.             ret = GetGLOMItem(glom_in.GLOMName, glom_in.GLOMValue);
  376.             if (ret == NO_ERROR)
  377.               {
  378.                 printf("Value of %s = %s\n",
  379.                        glom_in.GLOMName,
  380.                        glom_in.GLOMValue);
  381.               }
  382.             else
  383.               {
  384.                 printf("GLOM record: NOT FOUND\n");
  385.               }
  386.             return(ret);
  387.           }
  388.       }
  389.  
  390.     if (argc == 4)
  391.       {
  392.         if (argv[1][0] == 'A' ||
  393.             argv[1][0] == 'a'   )
  394.           {
  395.             /* Add a GLOM record: */
  396. #if TRACE > 0
  397.             printf("Add GLOM record:\n");
  398. #endif
  399.             memset(&glom_in, 0, sizeof(GLOM));
  400.             strncpy(glom_in.GLOMName, argv[2], GLOMNameLen);
  401.             glom_in.GLOMName[GLOMNameLen] = (UCHAR) 0;
  402.             strncpy(glom_in.GLOMValue, argv[3], GLOMValueLen);
  403.             glom_in.GLOMValue[GLOMValueLen] = (UCHAR) 0;
  404.             ret = AddGLOMItem(glom_in.GLOMName, glom_in.GLOMValue);
  405.             return(ret);
  406.           }
  407.       }
  408.  
  409.     printf("Invalid Client command\n");
  410.     return(1);
  411.   }
  412.  
  413. /* =====================================================================
  414.  *
  415.  * FUNCTION NAME:    AddGLOMItem
  416.  *
  417.  * DESCRIPTIVE NAME: Add item to GLOM-list in Server Control record.
  418.  *
  419.  * DESCRIPTION:
  420.  *
  421.  * INPUT:            glomname (up to GLOMNameLen characters)
  422.  *                   glom data (up to GLOMVAlueLen characters)
  423.  *
  424.  * OUTPUT:           <none>  (record added to linked list)
  425.  *
  426.  * RETURN CODES:     NO_ERROR        - normal return
  427.  *                   1    - failure
  428.  *                   2    - glomname item already exists
  429.  *
  430. ** ================================================================== */
  431. ULONG AddGLOMItem          (UCHAR  *glomname,
  432.                             UCHAR  *glomvalue)
  433.   {
  434.     APIRET                ret;
  435.     USHORT                i;
  436.     GLOM                 *GLOMitem;
  437.     GLOM                 *newGLOMitem = 0L;
  438.  
  439. #if TRACE > 9
  440.     printf("AddGLOMItem called\n");
  441. #endif
  442.  
  443.     /* Hold up the GLOM list, to insert new one: */
  444.     ret = DosRequestMutexSem(servercontrol->GLOM_List_Lock,
  445.                              SEM_INDEFINITE_WAIT);
  446.     if (ret != NO_ERROR)
  447.       {
  448. #if TRACE > 0
  449.         printf("DosRequestMutexSem AddGLOMItem failed ret=%d\n", ret);
  450. #endif
  451.       }
  452.  
  453.     /* Check to see if GLOM item for this dataserver is already present: */
  454.     GLOMitem = servercontrol->GLOM_List_ll_ptr;
  455.     while (GLOMitem != 0L)
  456.       {
  457.         if ((i=strcmp(GLOMitem->GLOMName, glomname)) == 0)
  458.           {
  459.             DosReleaseMutexSem(servercontrol->GLOM_List_Lock);
  460.             printf("Duplicate GLOM name.  Not Added\n");
  461.             return(2); /* duplicate */
  462.           }
  463.         GLOMitem = GLOMitem->next_ptr;
  464.       }
  465.  
  466.     if (newGLOMitem == 0L)
  467.       {
  468.         /* Need to Sub Alloc some shared memory: (block while doing) */
  469.         ret = DosRequestMutexSem(servercontrol->SubAlloc_Lock,
  470.                                  SEM_INDEFINITE_WAIT);
  471. get_some_memory:
  472.         ret = DosSubAllocMem(servercontrol->SubAllocPool, (PPVOID) &newGLOMitem,
  473.                              sizeof(GLOM));
  474.         if (ret != NO_ERROR)
  475.           {
  476. #if TRACE > 1
  477.             printf("AddGLOMItem DosSubAllocMem ret= %d\n", ret);
  478. #endif
  479.             /* Try to Grow Suballoc memory: */
  480.             ret = GrowServerCtlSuballoc(servercontrol);
  481.             if (ret == NO_ERROR)
  482.               {
  483.                 goto get_some_memory;
  484.               }
  485.             ret = DosReleaseMutexSem(servercontrol->SubAlloc_Lock);
  486.             ret = DosReleaseMutexSem(servercontrol->GLOM_List_Lock);
  487.             printf("Unable to add item, suballocation error\n");
  488.             return(1);
  489.           }
  490.  
  491.         (servercontrol->SubAllocUsage) += (ULONG) sizeof(GLOM);
  492. #if TRACE > 1
  493.         printf("AddGLOMItem() SubAllocUsage=%8ld\n",
  494.                 servercontrol->SubAllocUsage);
  495. #endif
  496.  
  497.         /* Suballoc done, now unblock: */
  498.         ret = DosReleaseMutexSem(servercontrol->SubAlloc_Lock);
  499.         memset(newGLOMitem, 0, sizeof(GLOM));
  500.         strcpy(newGLOMitem->GLOMName, glomname);
  501.         strcpy(newGLOMitem->GLOMValue, glomvalue);
  502.       }
  503.     else   /* re-use item */
  504.       {
  505.         strcpy(newGLOMitem->GLOMValue, glomvalue);
  506.         ret = DosReleaseMutexSem(servercontrol->GLOM_List_Lock);
  507.         return(NO_ERROR);
  508.       }
  509.  
  510.     if (servercontrol->GLOM_List_ll_ptr == 0L)
  511.       {
  512.         servercontrol->GLOM_List_ll_ptr = newGLOMitem;
  513.         ret = DosReleaseMutexSem(servercontrol->GLOM_List_Lock);
  514.         return(NO_ERROR);
  515.       }
  516.  
  517.     GLOMitem = servercontrol->GLOM_List_ll_ptr;
  518.     while (GLOMitem->next_ptr != 0L)
  519.       {
  520.         GLOMitem = GLOMitem->next_ptr;
  521.       }
  522.     GLOMitem->next_ptr = newGLOMitem;
  523.     newGLOMitem->prev_ptr = GLOMitem;
  524.  
  525.     ret = DosReleaseMutexSem(servercontrol->GLOM_List_Lock);
  526.  
  527. #if TRACE > 9
  528.     printf("AddGLOMItem done\n");
  529. #endif
  530.  
  531.     return(NO_ERROR);
  532.   }
  533.  
  534. /* =====================================================================
  535.  *
  536.  * FUNCTION NAME:    DeleteGLOMItem
  537.  *
  538.  * DESCRIPTIVE NAME: Remove GLOMed item from GLOMed-list in Server Control
  539.  *                   record.
  540.  *
  541.  * DESCRIPTION:
  542.  *
  543.  * INPUT:            glomname
  544.  *
  545.  * OUTPUT:           <none>  (record removed from linked list)
  546.  *
  547.  * RETURN CODES:     NO_ERROR - normal return
  548.  *
  549. ** ================================================================== */
  550. ULONG DeleteGLOMItem       (UCHAR  *glomname)
  551.   {
  552.     ULONG                     rc = ERROR_FILE_NOT_FOUND;
  553.     USHORT                    i;
  554.     APIRET                    ret;
  555.     GLOM                     *GLOMitem, *xGLOMitem;
  556.     GLOM                     *delGLOMitem = 0L;
  557.     UCHAR                     deleted_flag = 0;
  558.  
  559. #if TRACE > 9
  560.     printf("DeleteGLOMItem called\n");
  561. #endif
  562.  
  563.     /* Hold up the GLOM list, to delete old one: */
  564.     ret = DosRequestMutexSem(servercontrol->GLOM_List_Lock,
  565.                              SEM_INDEFINITE_WAIT);
  566.     if (ret != NO_ERROR)
  567.       {
  568. #if TRACE > 0
  569.         printf("DosRequestMutexSem DelGLOMItem failed ret=%d\n", ret);
  570. #endif
  571.       }
  572.  
  573.     /* Scan thru linked list, locate GLOM item to delete: */
  574.     GLOMitem = servercontrol->GLOM_List_ll_ptr;
  575.     while (GLOMitem != 0L)
  576.       {
  577.         if ((i=strcmp(GLOMitem->GLOMName, glomname)) == 0)
  578.           {
  579.             rc = NO_ERROR;
  580.             deleted_flag = 1;
  581.             delGLOMitem = GLOMitem;
  582.             GLOMitem = GLOMitem->next_ptr;
  583.             /* delete the item out of the chain: */
  584.             /* bust the linkages: */
  585.             if (delGLOMitem->prev_ptr != 0L)
  586.               {
  587.                 /* change the linkage of the previous item in list: */
  588.                 xGLOMitem = delGLOMitem->prev_ptr;
  589.                 xGLOMitem->next_ptr = delGLOMitem->next_ptr;
  590.                 /* change the linkage of the following item in list, if any: */
  591.                 xGLOMitem = delGLOMitem->next_ptr;
  592.                 if (xGLOMitem != 0L)
  593.                   {
  594.                     xGLOMitem->prev_ptr = delGLOMitem->prev_ptr;
  595.                   }
  596.               }
  597.             else /* This is the first item in the list. */
  598.               {
  599.                 /* Hit the starting pointer: */
  600.                 servercontrol->GLOM_List_ll_ptr = delGLOMitem->next_ptr;
  601.                 /* Hit the next item, make it the first one: */
  602.                 xGLOMitem = delGLOMitem->next_ptr;
  603.                 if (xGLOMitem != 0L)
  604.                   {        /* Is there at least 1 more item in list? */
  605.                     /* make it the first list entry: */
  606.                     xGLOMitem->prev_ptr = 0L;
  607.                   }
  608.               }
  609.             /* Need to Free Sub Alloc shared memory: (block while doing) */
  610.             ret = DosRequestMutexSem(servercontrol->SubAlloc_Lock,
  611.                                      SEM_INDEFINITE_WAIT);
  612.             ret = DosSubFreeMem(servercontrol->SubAllocPool,
  613.                               (PVOID) delGLOMitem, sizeof(GLOM));
  614.             if (ret != NO_ERROR)
  615.               {
  616. #if TRACE > 0
  617.                 printf("DeleteGLOMItem DosSubFreeMem ret= %d\n", ret);
  618. #endif
  619.               }
  620.            (servercontrol->SubAllocUsage) -= (ULONG) sizeof(GLOM);
  621. #if TRACE > 1
  622.             printf("DeleteGLOMItem() SubAllocUsage=%8ld\n",
  623.                    servercontrol->SubAllocUsage);
  624. #endif
  625.             /* Suballoc done, now unblock suballoc: */
  626.             ret = DosReleaseMutexSem(servercontrol->SubAlloc_Lock);
  627.             break;
  628.           }
  629.         else
  630.           {
  631.             GLOMitem = GLOMitem->next_ptr;
  632.           }
  633.       }
  634.  
  635.     if (deleted_flag == 0)
  636.       {
  637.         printf("Item NOT FOUND\n");
  638.       }
  639.  
  640.     ret = DosReleaseMutexSem(servercontrol->GLOM_List_Lock);
  641.  
  642. #if TRACE > 9
  643.     printf("DeleteGLOMItem done\n");
  644. #endif
  645.  
  646.     return(rc);
  647.   }
  648.  
  649. /* =====================================================================
  650.  *
  651.  * FUNCTION NAME:    GetGLOMItem
  652.  *
  653.  * DESCRIPTIVE NAME: Get GLOM item info from list in Server Control record
  654.  *
  655.  * DESCRIPTION:
  656.  *
  657.  * INPUT:            glomname
  658.  *
  659.  * OUTPUT:           glomvalue (caller allocates memory)
  660.  *                      (maxsize of DirValue)
  661.  *
  662.  * RETURN CODES:     NO_ERROR        - normal return
  663.  *                   1    - failure
  664.  *                   ERROR_FILE_NOT_FOUND - glomname not found in list
  665.  *
  666.  *
  667. ** ================================================================== */
  668. ULONG GetGLOMItem          (UCHAR        *glomname,
  669.                             UCHAR        *glomvalue)
  670.   {
  671.     APIRET                  ret;
  672.     USHORT                  i;
  673.     ULONG                   rc = ERROR_FILE_NOT_FOUND;
  674.     GLOM                   *GLOMitem;
  675.  
  676. #if TRACE > 9
  677.     printf("GetGLOMItem called\n");
  678. #endif
  679.  
  680.     if (glomvalue == 0L)
  681.       {
  682.         return(1);
  683.       }
  684.  
  685.     glomvalue[0] = (UCHAR) 0;
  686.  
  687.     /* Hold up the GLOM list, to scan list: */
  688.     ret = DosRequestMutexSem(servercontrol->GLOM_List_Lock,
  689.                              SEM_INDEFINITE_WAIT);
  690.     if (ret != NO_ERROR)
  691.       {
  692. #if TRACE > 0
  693.         printf("DosRequestMutexSem GetGLOMItem failed ret=%d\n", ret);
  694. #endif
  695.       }
  696.  
  697.     /* Scan thru linked list, locate GLOM item to return a copy of: */
  698.     GLOMitem = servercontrol->GLOM_List_ll_ptr;
  699.     while (GLOMitem != 0L)
  700.       {
  701.         if ((i=strcmp(GLOMitem->GLOMName, glomname)) == 0)
  702.           {
  703.             strcpy(glomvalue, GLOMitem->GLOMValue);
  704.             rc = NO_ERROR;
  705.             break;
  706.           }
  707.         GLOMitem = GLOMitem->next_ptr;
  708.       }
  709.  
  710.     ret = DosReleaseMutexSem(servercontrol->GLOM_List_Lock);
  711.  
  712. #if TRACE > 9
  713.     printf("GetGLOMItem done\n");
  714. #endif
  715.  
  716.     return(rc);
  717.   }
  718.  
  719. /* =====================================================================
  720.  *
  721.  * FUNCTION NAME:    ListGLOMItems
  722.  *
  723.  * DESCRIPTIVE NAME: List GLOM items from list in Server Control record
  724.  *
  725.  * DESCRIPTION:
  726.  *
  727.  * INPUT:
  728.  *
  729.  * OUTPUT:
  730.  *
  731.  * RETURN CODES:     NO_ERROR        - normal return
  732.  *                   1    - failure
  733.  *
  734.  *
  735. ** ================================================================== */
  736. ULONG ListGLOMItems        (void)
  737.   {
  738.     APIRET                  ret;
  739.     USHORT                  i;
  740.     ULONG                   rc = ERROR_FILE_NOT_FOUND;
  741.     GLOM                   *GLOMitem;
  742.  
  743. #if TRACE > 9
  744.     printf("ListGLOMItems called\n");
  745. #endif
  746.  
  747.     /* Hold up the GLOM list, to scan list: */
  748.     ret = DosRequestMutexSem(servercontrol->GLOM_List_Lock,
  749.                              SEM_INDEFINITE_WAIT);
  750.     if (ret != NO_ERROR)
  751.       {
  752. #if TRACE > 0
  753.         printf("DosRequestMutexSem GetGLOMItem failed ret=%d\n", ret);
  754. #endif
  755.       }
  756.  
  757.     /* Scan thru linked list, locate GLOM item to return a copy of: */
  758.     GLOMitem = servercontrol->GLOM_List_ll_ptr;
  759.     while (GLOMitem != 0L)
  760.       {
  761.         printf("%s: %s\n", GLOMitem->GLOMName, GLOMitem->GLOMValue);
  762.         rc = NO_ERROR;
  763.         GLOMitem = GLOMitem->next_ptr;
  764.       }
  765.  
  766.     ret = DosReleaseMutexSem(servercontrol->GLOM_List_Lock);
  767.  
  768. #if TRACE > 9
  769.     printf("ListGLOMItems done\n");
  770. #endif
  771.  
  772.     return(rc);
  773.   }