Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

cms.cc

Go to the documentation of this file.
00001 /*************************************************************************
00002 * File: cms.cc
00003 * Authors: Fred Proctor, Will Shackleford
00004 * Purpose: C++ file for the  Communication Management System (CMS).
00005 *          Includes:
00006 *                    1. Member functions for class CMS.
00007 * NOTES:
00008 * See cms_in.cc for the internal interface member functions and cms_up.cc
00009 * for the update functions.
00010 *************************************************************************/
00011 
00012 /* SCCS identification. (Used by what. See UNIX man pages section 1.) */
00013 
00014 /* Include Files */
00015 #include "rcs_defs.hh"          /* __MSDOS__, _Windows, EXTERN_C_STD_HEADERS */
00016 
00017 #include "rcsvers.hh"           // rcs_version_printed, print_rcs_version()
00018 
00019 #ifdef EXTERN_C_STD_HEADERS
00020 extern "C"
00021 {
00022 #endif
00023 
00024 #include <stdlib.h>             /* malloc(), free() */
00025 
00026 #ifndef UNDER_CE
00027 #include <stddef.h>             /* size_t */
00028 #endif
00029 
00030 #include <string.h>             /* strcpy(), strlen(),memcpy() */
00031   /* strcmp(),strchr() */
00032 #include <ctype.h>              // tolower(), toupper()
00033 
00034 #ifndef UNDER_CE
00035 #include <errno.h>              /* errno, ERANGE */
00036 #endif
00037 
00038 #if defined(__MSDOS__) && defined(USE_PCNFS)
00039 /* PC-NFS 5.0 Programmer`s Toolkit Header files */
00040 #include <tklib.h>              /* tkdll_cleanup(), tkdll_init(), */
00041   /* rtm_install() */
00042 #endif
00043 
00044 #ifdef UNDER_CE
00045 #include "rcs_ce.h"
00046 #endif
00047 
00048 #ifdef EXTERN_C_STD_HEADERS
00049 }
00050 #endif
00051 
00052 
00053 
00054 #include "cms.hh"               /* class CMS */
00055 #include "cms_up.hh"            /* class CMS_UPDATER */
00056 
00057 #include "cms_xup.hh"           /* class CMS_XDR_UPDATER */
00058 
00059 #ifndef UNDER_CE
00060 #include "cms_aup.hh"           /* class CMS_ASCII_UPDATER  */
00061 #include "cms_dup.hh"           /* class CMS_DISPLAY_ASCII_UPDATER  */
00062 #endif
00063 
00064 #include "rcs_prnt.hh"          /* rcs_print_error(), separate_words() */
00065                                 /* rcs_print_debug() */
00066 
00067 #include "dbg_mem.h"            /* DEBUG_FREE,DEBUG_MALLOC,DEBUG_CALLOC */
00068 #include "cmsdiag.hh"
00069 
00070 
00071 RCS_LINKED_LIST *cmsHostAliases = NULL;
00072 CMS_CONNECTION_MODE cms_connection_mode = CMS_NORMAL_CONNECTION_MODE;
00073 
00074 /* Static Class Data Members. */
00075 int
00076   CMS::number_of_cms_objects = 0;
00077 int
00078   cms_encoded_data_explosion_factor = 4;
00079 
00080 #if 0
00081 static int
00082 convert2lower (char *dest, char *src, int len)
00083 {
00084   int
00085     i;
00086   for (i = 0; i < len; i++)
00087     {
00088       if (src[i] == 0)
00089         {
00090           dest[i] = 0;
00091           return i;
00092         }
00093       dest[i] = tolower (src[i]);
00094     }
00095   return i;
00096 }
00097 #endif
00098 
00099 static int
00100 convert2upper (char *dest, char *src, int len)
00101 {
00102   int
00103     i;
00104   for (i = 0; i < len; i++)
00105     {
00106       if (src[i] == 0)
00107         {
00108           dest[i] = 0;
00109           return i;
00110         }
00111 #ifndef UNDER_CE
00112       dest[i] = toupper (src[i]);
00113 #else
00114       if (src[i] >= 'a' && src[i] <= 'z')
00115         {
00116           dest[i] = (src[i] - 'a') + 'A';
00117         }
00118       else
00119         {
00120           dest[i] = src[i];
00121         }
00122 #endif
00123     }
00124   return i;
00125 }
00126 
00127 
00128 /* Class CMS Member Functions */
00129 
00130 void *
00131 CMS::operator new (size_t size)
00132 {
00133   if (size < sizeof (CMS))
00134     {
00135       rcs_print_error
00136         ("CMS::operator new -- The size requested %d is less than the mininimum size of CMS %d.\n",
00137          size, sizeof (CMS));
00138       rcs_print_error ("This could indicate a version mismatch problem.\n");
00139       size = sizeof (CMS);
00140     }
00141   void *space = (void *) DEBUG_MALLOC (size);
00142   if (NULL != space)
00143     {
00144       memset (space, 0, size);
00145     }
00146   rcs_print_debug (PRINT_CMS_CONSTRUCTORS, "%X = CMS::new(%d)\n", space,
00147                    size);
00148   return space;
00149 }
00150 
00151 
00152 void
00153 CMS::operator delete (void *space)
00154 {
00155   rcs_print_debug (PRINT_CMS_DESTRUCTORS, " CMS::delete(%X)\n", space);
00156   DEBUG_FREE (space);
00157   rcs_print_debug (PRINT_CMS_DESTRUCTORS, " CMS::delete successful.\n");
00158 }
00159 
00160 
00161 
00162 /* Constructor used for hard coded tests. */
00163 /* Parameters: */
00164  /* n - Name of the buffer. */
00165  /* s - Size of the buffer. */
00166  /* nt - 0 buffer is not neutrally encoded, 1 buffer is neutrally encoded */
00167  /* set_to_server - 0 do NOT be a server, 1 be a server */
00168 CMS::CMS (long s)
00169 {
00170   /* Print a message if the PRINT_CMS_CONSTUCTORS */
00171   /* member of the print flags is set. */
00172   rcs_print_debug (PRINT_CMS_CONSTRUCTORS, "new CMS (%d)", s);
00173 
00174   /* Init string buffers */
00175   memset (BufferName, 0, CMS_CONFIG_LINELEN);
00176   memset (BufferHost, 0, CMS_CONFIG_LINELEN);
00177   memset (ProcessName, 0, CMS_CONFIG_LINELEN);
00178   memset (BufferLine, 0, CMS_CONFIG_LINELEN);
00179   memset (ProcessLine, 0, CMS_CONFIG_LINELEN);
00180   memset (ProcessHost, 0, CMS_CONFIG_LINELEN);
00181   memset (buflineupper, 0, CMS_CONFIG_LINELEN);
00182   memset (proclineupper, 0, CMS_CONFIG_LINELEN);
00183   memset (PermissionString, 0, CMS_CONFIG_LINELEN);
00184 
00185   /* save constructor args */
00186   size = s;
00187   force_raw = 0;
00188   neutral = 0;
00189   isserver = 0;
00190   last_im = CMS_NOT_A_MODE;
00191   min_compatible_version = 0;
00192   confirm_write = 0;
00193   disable_final_write_raw_for_dma = 0;
00194   subdiv_data = 0;
00195   enable_diagnostics = 0;
00196   dpi = NULL;
00197   di = NULL;
00198   skip_area = 0;
00199   half_offset = s / 2;
00200   half_size = s / 2;
00201   fast_mode = 0;
00202   disable_diag_store = 0;
00203   diag_offset = 0;
00204 
00205 
00206   /* Initailize some variables. */
00207   read_permission_flag = 0;     /* Allow both read and write by default.  */
00208   write_permission_flag = 0;
00209   queuing_enabled = 0;
00210   fatal_error_occurred = 0;
00211   write_just_completed = 0;
00212   neutral_encoding_method = CMS_XDR_ENCODING;
00213   sizeof_message_header = 0;
00214   blocking_timeout = 0;
00215   total_subdivisions = 1;
00216   subdiv_size = size;
00217   current_subdivision = 0;
00218   enc_max_size = s;
00219   max_encoded_message_size = s;
00220   last_id_side0 = 0;
00221   last_id_side1 = 0;
00222   handle_to_global_data = NULL;
00223   dummy_handle = (PHYSMEM_HANDLE *) NULL;       /* Set pointers to NULL */
00224   /* so we'll know whether it really */
00225   /* points to something */
00226 
00227   delete_totally = 0;           /* If this object is deleted only do */
00228   /* normal delete instead of deleting totally. */
00229 
00230   mode = CMS_NOT_A_MODE;        /* Force user to set the mode before using. */
00231 
00232   open ();                      /* Allocate memory and intialize XDR streams */
00233 }
00234 
00235 
00236 /* Constructor used by cms_config. */
00237 /* Parameters:  */
00238 /*  bufline - The buffer line from a CMS configuration file. */
00239 /* procline - The process line from a CMS configuration file. */
00240 /* set_to_server - */
00241  /* -1 force this CMS object NOT to be in server mode. */
00242  /* 0 allow the parameter in the procline to set whether server mode is used */
00243  /* 1 force this CMS object to be in server mode. */
00244 CMS::CMS (char *bufline, char *procline, int set_to_server)
00245 {
00246   char *word[32];               /* Array of pointers to strings.  */
00247   char *buffer_type_name;       /* pointer to buffer type name from bufline */
00248   char *proc_type_name;         /* pointer to process type  from procline */
00249   int i;
00250   sizeof_message_header = 0;
00251   min_compatible_version = 0;
00252   force_raw = 0;
00253   confirm_write = 0;
00254   disable_final_write_raw_for_dma = 0;
00255   /* Init string buffers */
00256   memset (BufferName, 0, CMS_CONFIG_LINELEN);
00257   memset (BufferHost, 0, CMS_CONFIG_LINELEN);
00258   memset (ProcessName, 0, CMS_CONFIG_LINELEN);
00259   memset (BufferLine, 0, CMS_CONFIG_LINELEN);
00260   memset (ProcessLine, 0, CMS_CONFIG_LINELEN);
00261   memset (ProcessHost, 0, CMS_CONFIG_LINELEN);
00262   memset (buflineupper, 0, CMS_CONFIG_LINELEN);
00263   memset (proclineupper, 0, CMS_CONFIG_LINELEN);
00264   memset (PermissionString, 0, CMS_CONFIG_LINELEN);
00265 
00266   /* Initailize some variables. */
00267   read_permission_flag = 0;     /* Allow both read and write by default.  */
00268   write_permission_flag = 0;
00269   queuing_enabled = 0;
00270   fatal_error_occurred = 0;
00271   write_just_completed = 0;
00272   neutral_encoding_method = CMS_XDR_ENCODING;
00273   sizeof_message_header = 0;
00274   blocking_timeout = 0;
00275   min_compatible_version = 0;
00276   enc_max_size = -1;
00277   max_encoded_message_size = 0;
00278   enable_diagnostics = 0;
00279   dpi = NULL;
00280   di = NULL;
00281   disable_diag_store = 0;
00282   diag_offset = 0;
00283   use_autokey_for_connection_number = 0;
00284 
00285   if ((NULL == bufline) || (NULL == procline))
00286     {
00287       rcs_print_error ("CMS: Pointer to bufline or procline is NULL.\n");
00288       return;
00289     }
00290 
00291   convert2upper (buflineupper, bufline, CMS_CONFIG_LINELEN);
00292   convert2upper (proclineupper, procline, CMS_CONFIG_LINELEN);
00293 
00294   is_phantom = 0;
00295   max_message_size = 0;
00296   using_external_encoded_data = 0;
00297   in_buffer_id = 0;
00298   last_id_side0 = 0;
00299   last_id_side1 = 0;
00300   delete_totally = 0;
00301   queuing_enabled = 0;
00302   split_buffer = 0;
00303   fatal_error_occurred = 0;
00304   consecutive_timeouts = 0;
00305   write_just_completed = 0;
00306   pointer_check_disabled = 0;
00307   blocking_timeout = 0;
00308   last_im = CMS_NOT_A_MODE;
00309   total_subdivisions = 1;
00310   size = 0;
00311   subdiv_size = 0;
00312   current_subdivision = 0;
00313   max_encoded_message_size = 0;
00314   skip_area = 0;
00315   half_offset = 0;
00316   half_size = 0;
00317   fast_mode = 0;
00318   last_id_side0 = 0;
00319   last_id_side1 = 0;
00320   handle_to_global_data = NULL;
00321 
00322 
00323   dummy_handle = (PHYSMEM_HANDLE *) NULL;
00324   remote_port_type = CMS_NO_REMOTE_PORT_TYPE;
00325   for (i = 0; i < 10; i++)
00326     {
00327       word[i] = (char *) NULL;
00328     }
00329 
00330   /* Store the bufline and procline for debugging later. */
00331   strcpy (BufferLine, bufline);
00332   strcpy (ProcessLine, procline);
00333 
00334   /* Get parameters from the buffer's line in the config file. */
00335   if (separate_words (word, 9, bufline) != 9)
00336     {
00337       rcs_print_error ("CMS: Error in buffer line from config file.\n");
00338       rcs_print_error ("%s\n", bufline);
00339       status = CMS_CONFIG_ERROR;
00340       return;
00341     }
00342 
00343   /* Use the words from the buffer line to initialize some class variables. */
00344   strcpy (BufferName, word[1]);
00345   rcs_print_debug (PRINT_CMS_CONSTRUCTORS, "new CMS (%s)\n", BufferName);
00346 
00347   /* Clear errno so we can determine if all of the parameters in the */
00348   /* buffer line were in an acceptable form. */
00349 #ifndef UNDER_CE
00350   if (errno == ERANGE)
00351     {
00352       errno = 0;
00353     }
00354 #endif
00355   char *realname = cms_check_for_host_alias (word[3]);
00356   if (realname == NULL)
00357     {
00358       strcpy (BufferHost, word[3]);
00359     }
00360   else
00361     {
00362       strcpy (BufferHost, realname);
00363     }
00364 
00365   buffer_type_name = word[2];
00366 
00367 
00368   /* strtol should allow us to use the C syntax for specifying the radix of */
00369   /* the numbers in the configuration file. */
00370   /* (i.e. 0x???? for hexidecimal, 0??? for octal and ???? for decimal.) */
00371 #ifndef UNDER_CE
00372   size = (long) strtol (word[4], (char **) NULL, 0);
00373   neutral = (int) strtol (word[5], (char **) NULL, 0);
00374   rpc_program_number = strtol (word[6], (char **) NULL, 0);
00375   buffer_number = strtol (word[7], (char **) NULL, 0);
00376   total_connections = strtol (word[8], (char **) NULL, 0);
00377 #else
00378   size = (long) atol (word[4]);
00379   neutral = (int) atol (word[5]);
00380   rpc_program_number = atol (word[6]);
00381   buffer_number = atol (word[7]);
00382   total_connections = atol (word[8]);
00383 #endif
00384 
00385 #ifndef UNDER_CE
00386   /* Check errno to see if all of the strtol's were sucessful. */
00387   if (ERANGE == errno)
00388     {
00389       rcs_print_error ("CMS: Error in buffer line from config file.\n");
00390       rcs_print_error ("%s\n", bufline);
00391       status = CMS_CONFIG_ERROR;
00392       return;
00393     }
00394 #endif
00395 
00396   /* Determine the BufferType. */
00397   if (!strcmp (buffer_type_name, "SHMEM"))
00398     {
00399       BufferType = CMS_SHMEM_TYPE;
00400     }
00401   else if (!strcmp (buffer_type_name, "GLOBMEM"))
00402     {
00403       BufferType = CMS_GLOBMEM_TYPE;
00404     }
00405   else if (!strcmp (buffer_type_name, "BBDMEM"))
00406     {
00407       BufferType = CMS_BBDMEM_TYPE;
00408     }
00409   else if (!strcmp (buffer_type_name, "PHANTOM"))
00410     {
00411       BufferType = CMS_PHANTOM_BUFFER;
00412       is_phantom = 1;
00413     }
00414   else if (!strcmp (buffer_type_name, "LOCMEM"))
00415     {
00416       BufferType = CMS_LOCMEM_TYPE;
00417     }
00418   else if (!strcmp (buffer_type_name, "FILEMEM"))
00419     {
00420       BufferType = CMS_FILEMEM_TYPE;
00421     }
00422   else if (!strcmp (buffer_type_name, "RTLMEM"))
00423     {
00424       BufferType = CMS_RTLMEM_TYPE;
00425     }
00426   else
00427     {
00428       rcs_print_error ("CMS: invalid buffer type (%s)\n", buffer_type_name);
00429       status = CMS_CONFIG_ERROR;
00430       return;
00431     }
00432 
00433   int num_words = separate_words (word, 32, buflineupper);
00434   if (num_words < 8)
00435     {
00436       rcs_print_error ("CMS: Error in buffer line from config file.\n");
00437       rcs_print_error ("%s\n", bufline);
00438       status = CMS_CONFIG_ERROR;
00439       return;
00440     }
00441   for (i = 8; i < num_words && i < 32; i++)
00442     {
00443       if (word[i] == NULL)
00444         {
00445           break;
00446         }
00447 
00448       if (!strcmp (word[i], "QUEUE"))
00449         {
00450           queuing_enabled = 1;
00451           continue;
00452         }
00453 
00454 
00455       if (!strcmp (word[i], "DIAG"))
00456         {
00457           enable_diagnostics = 1;
00458           continue;
00459         }
00460 
00461       if (!strcmp (word[i], "SPLIT"))
00462         {
00463           split_buffer = 1;
00464           continue;
00465         }
00466       if (!strcmp (word[i], "DISP"))
00467         {
00468           neutral_encoding_method = CMS_DISPLAY_ASCII_ENCODING;
00469           continue;
00470         }
00471       if (!strcmp (buflineupper, "ASCII"))
00472         {
00473           neutral_encoding_method = CMS_ASCII_ENCODING;
00474           continue;
00475         }
00476       if (!strcmp (buflineupper, "XDR"))
00477         {
00478           neutral_encoding_method = CMS_XDR_ENCODING;
00479           continue;
00480         }
00481 
00482       char *port_string;
00483       if (NULL != (port_string = strstr (word[i], "STCP=")))
00484         {
00485           remote_port_type = CMS_STCP_REMOTE_PORT_TYPE;
00486 #ifndef UNDER_CE
00487           stcp_port_number =
00488             (int) strtol (port_string + 5, (char **) NULL, 0);
00489 #else
00490           rcs_print_error ("STCP not supported in Windows CE.\n");
00491           stcp_port_number = atoi (port_string + 5);
00492 #endif
00493           continue;
00494         }
00495       else if (NULL != (port_string = strstr (word[i], "TCP=")))
00496         {
00497           remote_port_type = CMS_TCP_REMOTE_PORT_TYPE;
00498 #ifndef UNDER_CE
00499           tcp_port_number = (int) strtol (port_string + 4, (char **) NULL, 0);
00500 #else
00501           tcp_port_number = atoi (port_string + 4);
00502 #endif
00503           continue;
00504         }
00505       else if (NULL != (port_string = strstr (word[i], "UDP=")))
00506         {
00507           remote_port_type = CMS_UDP_REMOTE_PORT_TYPE;
00508 #ifndef UNDER_CE
00509           udp_port_number = (int) strtol (port_string + 4, (char **) NULL, 0);
00510 #else
00511           udp_port_number = atoi (port_string + 4);
00512 #endif
00513           continue;
00514         }
00515 
00516       char *version_string;
00517       if (NULL != (version_string = strstr (word[i], "VERSION=")))
00518         {
00519 #ifndef UNDER_CE
00520           min_compatible_version =
00521             strtod (version_string + 8, (char **) NULL);
00522 #else
00523           min_compatible_version = RCS_CE_ATOF (version_string + 8);
00524 #endif
00525           continue;
00526         }
00527 
00528       char *subdiv_string;
00529       if (NULL != (subdiv_string = strstr (word[i], "SUBDIV=")))
00530         {
00531 #ifndef UNDER_CE
00532           total_subdivisions = strtol (subdiv_string + 7, (char **) NULL, 0);
00533 #else
00534           total_subdivisions = atol (subdiv_string + 7);
00535 #endif
00536           subdiv_size = size / total_subdivisions;
00537           subdiv_size -= subdiv_size % 4;
00538           continue;
00539         }
00540 
00541       char *enc_max_string;
00542       if (NULL != (enc_max_string = strstr (word[i], "ENC_MAX_SIZE=")))
00543         {
00544 #ifndef UNDER_CE
00545           enc_max_size = strtoul (enc_max_string + 13, (char **) NULL, 0);
00546 #else
00547           enc_max_size = atol (enc_max_string + 13);
00548 #endif
00549           continue;
00550         }
00551 
00552       if (!strcmp (word[i], "CONFIRM_WRITE"))
00553         {
00554           confirm_write = 1;
00555           continue;
00556         }
00557       if (!strcmp (word[i], "FORCE_RAW"))
00558         {
00559           force_raw = 1;
00560           continue;
00561         }
00562       if (!strcmp (word[i], "AUTOCNUM"))
00563         {
00564           use_autokey_for_connection_number = 1;
00565           continue;
00566         }
00567     }
00568 
00569   /* Get parameters from the process's line in the config file. */
00570   if (use_autokey_for_connection_number)
00571     {
00572       if (separate_words (word, 9, procline) != 9)
00573         {
00574           rcs_print_error
00575             ("CMS: Error parsing process line from config file.\n");
00576           rcs_print_error ("%s\n", procline);
00577           status = CMS_CONFIG_ERROR;
00578           return;
00579         }
00580     }
00581   else
00582     {
00583       if (separate_words (word, 10, procline) != 10)
00584         {
00585           rcs_print_error
00586             ("CMS: Error parsing process line from config file.\n");
00587           rcs_print_error ("%s\n", procline);
00588           status = CMS_CONFIG_ERROR;
00589           return;
00590         }
00591     }
00592 #ifndef UNDER_CE
00593   /* Clear errno so we can determine if all of the parameters in the */
00594   /* buffer line were in an acceptable form. */
00595   if (errno == ERANGE)
00596     {
00597       errno = 0;
00598     }
00599 #endif
00600 
00601   strcpy (ProcessName, word[1]);
00602   strcpy (ProcessHost, word[4]);
00603 
00604 #ifndef UNDER_CE
00605   /* Clear errno so we can determine if all of the parameters in the */
00606   /* buffer line were in an acceptable form. */
00607   if (errno == ERANGE)
00608     {
00609       errno = 0;
00610     }
00611 #endif
00612 
00613   proc_type_name = word[3];
00614   strcpy (PermissionString, word[5]);
00615   spawn_server = atoi (word[6]);
00616 
00617   /* Compute timeout. */
00618   if (!strcmp (word[7], "INF")) /* Never Time Out. */
00619     {
00620       timeout = -1;
00621     }
00622   else
00623     {
00624 #ifndef UNDER_CE
00625       timeout = strtod (word[7], (char **) NULL);
00626 #else
00627       timeout = RCS_CE_ATOF (word[7]);
00628 #endif
00629     }
00630 
00631 
00632 #ifndef UNDER_CE
00633   is_local_master = (int) atol (word[8]);
00634 #else
00635   is_local_master = (int) atol (word[8]);
00636 #endif
00637 
00638   if (!use_autokey_for_connection_number)
00639     {
00640 
00641 #ifndef UNDER_CE
00642       connection_number = atol (word[9]);
00643 #else
00644       connection_number = atol (word[9]);
00645 #endif
00646 
00647       if (total_connections <= connection_number)
00648         {
00649           rcs_print_error
00650             ("CMS: connection number(%d) must be less than total connections (%d).\n",
00651              connection_number, total_connections);
00652           status = CMS_CONFIG_ERROR;
00653           return;
00654         }
00655     }
00656 
00657 
00658 #ifndef UNDER_CE
00659   /* Check errno to see if all of the strtol's were sucessful. */
00660   if (ERANGE == errno)
00661     {
00662       rcs_print_error ("CMS: Error in proc line from config file.\n");
00663       rcs_print_error ("%s\n", procline);
00664       status = CMS_CONFIG_ERROR;
00665       return;
00666     }
00667 #endif
00668 
00669 
00670   if (set_to_server < 0)
00671     {
00672       isserver = 0;
00673     }
00674   else if (set_to_server > 0)
00675     {
00676       isserver = 1;
00677     }
00678   else
00679     {
00680       isserver = (spawn_server == 1);
00681     }
00682 
00683   /* Determine the ProcessType. */
00684   switch (cms_connection_mode)
00685     {
00686     case CMS_NORMAL_CONNECTION_MODE:
00687       if (!strcmp (proc_type_name, "REMOTE"))
00688         {
00689           ProcessType = CMS_REMOTE_TYPE;
00690           spawn_server = 0;
00691         }
00692       else if (!strcmp (proc_type_name, "LOCAL"))
00693         {
00694           ProcessType = CMS_LOCAL_TYPE;
00695         }
00696       else if (!strcmp (proc_type_name, "AUTO"))
00697         {
00698           if (hostname_matches_bufferline (BufferLine))
00699             {
00700               ProcessType = CMS_LOCAL_TYPE;
00701             }
00702           else
00703             {
00704               ProcessType = CMS_REMOTE_TYPE;
00705               spawn_server = 0;
00706             }
00707         }
00708       else if (!strcmp (proc_type_name, "PHANTOM"))
00709         {
00710           ProcessType = CMS_PHANTOM_USER;
00711           spawn_server = 0;
00712           is_phantom = 1;
00713         }
00714       else
00715         {
00716           rcs_print_error ("CMS: invalid process type (%s)/n",
00717                            proc_type_name);
00718           status = CMS_CONFIG_ERROR;
00719           return;
00720         }
00721       break;
00722 
00723     case CMS_FORCE_LOCAL_CONNECTION_MODE:
00724       ProcessType = CMS_LOCAL_TYPE;
00725       break;
00726 
00727     case CMS_FORCE_REMOTE_CONNECTION_MODE:
00728       ProcessType = CMS_REMOTE_TYPE;
00729       break;
00730 
00731 
00732     }
00733 
00734   /* Set flags to make sure ops section of config file is correct. */
00735   if (NULL != strchr (PermissionString, 'R'))
00736     {
00737       read_permission_flag = 1;
00738     }
00739   else
00740     {
00741       read_permission_flag = 0;
00742     }
00743 
00744   if (NULL != strchr (PermissionString, 'W'))
00745     {
00746       write_permission_flag = 1;
00747     }
00748   else
00749     {
00750       write_permission_flag = 0;
00751     }
00752   if (isserver && BufferType != CMS_BBDMEM_TYPE)
00753     {
00754       read_permission_flag = 1;
00755       write_permission_flag = 1;
00756     }
00757 
00758   mode = CMS_NOT_A_MODE;        /* Make sure user sets the mode before using. */
00759 
00760   // Search the end of the bufferline for key words.
00761 
00762   if (NULL != strstr (ProcessLine, "serialPortDevName="))
00763     {
00764       remote_port_type = CMS_TTY_REMOTE_PORT_TYPE;
00765     }
00766   if (min_compatible_version < 3.44 && min_compatible_version > 0)
00767     {
00768       total_subdivisions = 1;
00769     }
00770   if (queuing_enabled && split_buffer)
00771     {
00772       rcs_print_error ("CMS: Can not split buffer with queuing enabled.\n");
00773       status = CMS_CONFIG_ERROR;
00774       return;
00775     }
00776   if (min_compatible_version > 3.39 || min_compatible_version <= 0.0)
00777     {
00778       if (neutral_encoding_method == CMS_ASCII_ENCODING)
00779         {
00780           neutral_encoding_method = CMS_DISPLAY_ASCII_ENCODING;
00781         }
00782     }
00783 
00784   if (min_compatible_version <= 3.71 && min_compatible_version >= 1e-6)
00785     {
00786       enable_diagnostics = 0;
00787     }
00788 
00789   open ();                      /* Allocate memory and intialize XDR streams */
00790   if (enable_diagnostics)
00791     {
00792       setup_diag_proc_info ();
00793     }
00794 }
00795 
00796 /* Function for allocating memory and initializing XDR streams, which */
00797 /*    is called from both CMS constructors.                           */
00798 void
00799 CMS::open (void)
00800 {
00801   int encode_header_ret;
00802   int encode_queuing_header_ret;
00803 
00804   /* Clear some status checking variables. */
00805   status = CMS_STATUS_NOT_SET;
00806 
00807   /* Set all the pointers to null before requesting memory so that we only */
00808   /* free successfully allocated memory. */
00809   data = NULL;
00810   subdiv_data = NULL;
00811   encoded_data = NULL;
00812   encoded_header = NULL;
00813   encoded_queuing_header = NULL;
00814   encoded_header_size = 0;
00815   updater = (CMS_UPDATER *) NULL;
00816   normal_updater = (CMS_UPDATER *) NULL;
00817   temp_updater = (CMS_UPDATER *) NULL;
00818   last_im = CMS_NOT_A_MODE;
00819   pointer_check_disabled = 0;
00820 
00821   dummy_handle = (PHYSMEM_HANDLE *) NULL;
00822 
00823   /* Initialize some debug variables. */
00824   first_read_done = 0;
00825   first_write_done = 0;
00826   total_messages_missed = 0;
00827   messages_missed_on_last_read = 0;
00828   format_low_ptr = (char *) NULL;
00829   format_high_ptr = (char *) NULL;
00830   header.was_read = 0;
00831   header.write_id = 0;
00832   header.in_buffer_size = 0;
00833   sizeof_message_header = 0;
00834 
00835   number_of_cms_objects++;      /* Increment the static variable.  */
00836   /* Save some memory and time if this is a PHANTOMMEM object. */
00837   if (!is_phantom)
00838     {
00839       /* Allocate memory for the local copy of global buffer. */
00840       data = DEBUG_MALLOC (size);
00841       memset (data, 0, size);
00842       subdiv_data = data;
00843       if (force_raw)
00844         {
00845           encoded_data = data;
00846         }
00847       rcs_print_debug (PRINT_CMS_CONSTRUCTORS, "%X = data = calloc(%d,1);\n",
00848                        data, size);
00849       /* Check to see if allocating memory was successful. */
00850       if (data == NULL)
00851         {
00852           rcs_print_error ("CMS: Can't allocate memory for local buffer.\n");
00853           status = CMS_CREATE_ERROR;
00854           return;
00855         }
00856     }
00857   if (isserver || neutral || ProcessType == CMS_REMOTE_TYPE && !force_raw)
00858     {
00859       switch (neutral_encoding_method)
00860         {
00861         case CMS_XDR_ENCODING:
00862           updater = new CMS_XDR_UPDATER (this);
00863           break;
00864 
00865 #ifndef UNDER_CE
00866         case CMS_ASCII_ENCODING:
00867           updater = new CMS_ASCII_UPDATER (this);
00868           break;
00869 
00870         case CMS_DISPLAY_ASCII_ENCODING:
00871           updater = new CMS_DISPLAY_ASCII_UPDATER (this);
00872           break;
00873 #endif
00874 
00875         default:
00876           updater = (CMS_UPDATER *) NULL;
00877           status = CMS_UPDATE_ERROR;
00878           rcs_print_error ("CMS: Invalid encoding method(%d)\n",
00879                            neutral_encoding_method);
00880           break;
00881         }
00882       normal_updater = updater;
00883       if (((int) status) < 0)
00884         {
00885           return;
00886         }
00887       /* Find out what size the header is after it has been encoded. */
00888       if ((encode_header_ret = encode_header ()) == -1)
00889         {
00890           rcs_print_error ("CMS:Error encoding CMS header.\n");
00891           status = CMS_MISC_ERROR;
00892           return;
00893         }
00894       encoded_header_size = (long) encode_header_ret;
00895       if (min_compatible_version <= 0.0 || min_compatible_version > 3.29)
00896         {
00897           if (neutral_encoding_method == CMS_DISPLAY_ASCII_ENCODING)
00898             {
00899               encoded_header_size = 16;
00900             }
00901         }
00902 
00903       if (queuing_enabled)
00904         {
00905           /* Initialize queuing header to avoid test center error message. */
00906           memset (&queuing_header, 0, sizeof (queuing_header));
00907 
00908           /* Find out what size the queuing_header is after being encoded. */
00909           if ((encode_queuing_header_ret = encode_queuing_header ()) == -1)
00910             {
00911               rcs_print_error ("CMS:Error encoding CMS queuing_header.\n");
00912               status = CMS_MISC_ERROR;
00913               return;
00914             }
00915           encoded_queuing_header_size = (long) encode_queuing_header_ret;
00916         }
00917     }
00918 
00919   if (split_buffer && total_subdivisions > 1)
00920     {
00921       rcs_print_error
00922         ("Can't split buffer and use subdivisions. (total_subsivisions=%d)",
00923          total_subdivisions);
00924       status = CMS_MISC_ERROR;
00925       return;
00926     }
00927 
00928   int nfactor = 4;
00929   if (NULL != updater)
00930     {
00931       nfactor = updater->neutral_size_factor;
00932     }
00933 
00934   /* Set some varaibles to let the user know how much space is left. */
00935   size_without_diagnostics = size;
00936   diag_offset = 0;
00937   if (enable_diagnostics)
00938     {
00939       diag_offset = (sizeof (CMS_DIAG_HEADER) +
00940                      (total_connections * sizeof (CMS_DIAG_PROC_INFO)));
00941       size_without_diagnostics -= diag_offset;
00942     }
00943   skip_area = 0;
00944   half_offset = (size_without_diagnostics / 2);
00945   half_size = (size_without_diagnostics / 2);
00946   fast_mode = 0;
00947   if (split_buffer)
00948     {
00949       if (neutral)
00950         {
00951           subdiv_size = (size_without_diagnostics / 2) - total_connections;
00952           subdiv_size -= (subdiv_size % 4);
00953           max_message_size =
00954             (size_without_diagnostics / 2) - total_connections -
00955             encoded_header_size - 2;
00956           max_encoded_message_size =
00957             size_without_diagnostics - total_connections -
00958             encoded_header_size;
00959           guaranteed_message_space =
00960             max_message_size / cms_encoded_data_explosion_factor;
00961         }
00962       else
00963         {
00964           if (ProcessType == CMS_REMOTE_TYPE)
00965             {
00966               subdiv_size =
00967                 (size_without_diagnostics / 2) - total_connections;
00968               subdiv_size -= (subdiv_size % 4);
00969               max_message_size =
00970                 (size_without_diagnostics / 2) - total_connections -
00971                 sizeof (CMS_HEADER) - 2;
00972               max_encoded_message_size = nfactor * max_message_size;
00973               guaranteed_message_space = max_message_size / nfactor;
00974             }
00975           else
00976             {
00977               subdiv_size =
00978                 (size_without_diagnostics / 2) - total_connections;
00979               subdiv_size -= (subdiv_size % 4);
00980               max_message_size =
00981                 (size_without_diagnostics / 2) - total_connections -
00982                 sizeof (CMS_HEADER) - 2;
00983               max_encoded_message_size = nfactor * max_message_size;
00984               guaranteed_message_space = max_message_size;
00985             }
00986         }
00987     }
00988   else
00989     {
00990       if (neutral)
00991         {
00992           subdiv_size =
00993             (size_without_diagnostics -
00994              total_connections) / total_subdivisions;
00995           subdiv_size -= (subdiv_size % 4);
00996           max_message_size = subdiv_size - encoded_header_size;
00997           max_encoded_message_size = subdiv_size - encoded_header_size;
00998           guaranteed_message_space = max_message_size / nfactor;
00999         }
01000       else
01001         {
01002           if (ProcessType == CMS_REMOTE_TYPE)
01003             {
01004               subdiv_size =
01005                 (size_without_diagnostics -
01006                  total_connections) / total_subdivisions;
01007               subdiv_size -= (subdiv_size % 4);
01008               max_message_size = subdiv_size - sizeof (CMS_HEADER);
01009               max_encoded_message_size = nfactor * max_message_size;
01010               guaranteed_message_space = max_message_size / nfactor;
01011             }
01012           else
01013             {
01014               subdiv_size =
01015                 (size_without_diagnostics -
01016                  total_connections) / total_subdivisions;
01017               subdiv_size -= (subdiv_size % 4);
01018               max_message_size = subdiv_size - sizeof (CMS_HEADER);
01019               max_encoded_message_size = nfactor * max_message_size;
01020               guaranteed_message_space = max_message_size;
01021             }
01022         }
01023     }
01024   if (enc_max_size > 0 && enc_max_size < max_encoded_message_size)
01025     {
01026       max_encoded_message_size = enc_max_size;
01027     }
01028 
01029   if ((neutral || ProcessType == CMS_REMOTE_TYPE) && !isserver)
01030     {
01031       /* Local processes that are use a neutral buffer and */
01032       /*  All remote processes. */
01033       read_mode = CMS_DECODE;
01034       read_updater_mode = CMS_DECODE_DATA;
01035       write_mode = CMS_ENCODE;
01036       write_updater_mode = CMS_ENCODE_DATA;
01037     }
01038   else if (!neutral && isserver && !force_raw)
01039     {
01040       /* Servers. */
01041       read_mode = CMS_ENCODE;
01042       read_updater_mode = CMS_ENCODE_DATA;
01043       write_mode = CMS_DECODE;
01044       write_updater_mode = CMS_DECODE_DATA;
01045     }
01046   else
01047     {
01048       /* Everybody else. */
01049       read_mode = CMS_RAW_OUT;
01050       read_updater_mode = CMS_NO_UPDATE;
01051       write_mode = CMS_RAW_IN;
01052       write_updater_mode = CMS_NO_UPDATE;
01053     }
01054 }
01055 
01056 /* Set the area used for the encoded data buffer, and initialize the */
01057  /* XDR streams to use this area. */
01058 /* This function is called from open, which is called by the constructor */
01059  /* and by one of the CMS_SERVER functions. */
01060 /* _encoded_data should point to an area of memory at least cms_encoded_data_explosion_factor*size .*/
01061 void
01062 CMS::set_encoded_data (void *_encoded_data, long _encoded_data_size)
01063 {
01064   if (force_raw)
01065     {
01066       if (NULL != data && data != _encoded_data)
01067         {
01068           DEBUG_FREE (data);
01069         }
01070       data = encoded_data = _encoded_data;
01071       encoded_data_size = size;
01072       subdiv_data = data;
01073       using_external_encoded_data = 1;
01074     }
01075   else
01076     {
01077       if (max_encoded_message_size > _encoded_data_size)
01078         {
01079           max_encoded_message_size = _encoded_data_size;
01080         }
01081       if (NULL != updater)
01082         {
01083           updater->set_encoded_data (_encoded_data, _encoded_data_size);
01084         }
01085       if (NULL != _encoded_data)
01086         {
01087           memset (_encoded_data, 0, max_encoded_message_size);
01088         }
01089       using_external_encoded_data = 1;
01090     }
01091 }
01092 
01093 /* Destructor */
01094 CMS::~CMS ()
01095 {
01096   rcs_print_debug (PRINT_CMS_DESTRUCTORS, "deleting CMS (%s)\n", BufferName);
01097 
01098   if (NULL != updater)
01099     {
01100       delete updater;
01101       updater = (CMS_UPDATER *) NULL;
01102     }
01103 
01104   /* Free the memory used for the local copy of the global buffer. */
01105   if (NULL != data && (!force_raw || !using_external_encoded_data))
01106     {
01107       rcs_print_debug (PRINT_CMS_DESTRUCTORS, "free( data = %X);\n", data);
01108 #ifdef sparcworks_sun4          /* free is defined as int free(char *)
01109                                    for this platform
01110                                    it should be void free(void *); */
01111       DEBUG_FREE ((char *) data);
01112 #else
01113       DEBUG_FREE (data);
01114 #endif
01115       data = NULL;
01116       if (force_raw)
01117         {
01118           encoded_data = NULL;
01119         }
01120     }
01121   number_of_cms_objects--;
01122 
01123   if (NULL != dummy_handle)
01124     {
01125       delete dummy_handle;
01126       dummy_handle = (PHYSMEM_HANDLE *) NULL;
01127     }
01128   rcs_print_debug (PRINT_CMS_DESTRUCTORS, "Leaving ~CMS()\n");
01129 }
01130 
01131 /* This function should never be called. It exists so that classes  which */
01132  /* overload read, write etc don't have to bother creating it. */
01133 CMS_STATUS CMS::main_access (void *_local)
01134 {
01135   rcs_print_error ("CMS::main_access called by %s for %s.\n",
01136                    ProcessName, BufferName);
01137   rcs_print_error ("This should never happen.\n");
01138   rcs_print_error
01139     ("Derived classes should either override main_access() or\n");
01140   rcs_print_error ("the functions that call it.(read(), write(), etc.)\n");
01141   rcs_print_error ("_local = %p\n", _local);
01142   return (CMS_MISC_ERROR);
01143 }
01144 
01145 /* General Utility Functions. */
01146 
01147 /* Check the buffer id against in_buffer_id to see if it is new. */
01148 CMS_STATUS CMS::check_id (CMSID id)
01149 {
01150   if (status < 0)
01151     {
01152       return (status);
01153     }
01154 
01155 
01156   if (0 == id)
01157     {
01158       messages_missed_on_last_read = 0;
01159       in_buffer_id = 0;
01160       return (status = CMS_READ_OLD);
01161     }
01162 
01163 
01164   if (id == in_buffer_id)
01165     {
01166       status = CMS_READ_OLD;
01167       messages_missed_on_last_read = 0;
01168     }
01169   else
01170     {
01171       if (split_buffer)
01172         {
01173           if (id == last_id_side0 || id == last_id_side1)
01174             {
01175               status = CMS_READ_OLD;
01176               messages_missed_on_last_read = 0;
01177               return (status);
01178             }
01179           if (toggle_bit)
01180             {
01181               last_id_side0 = id;
01182             }
01183           else
01184             {
01185               last_id_side1 = id;
01186             }
01187         }
01188       status = CMS_READ_OK;
01189       messages_missed_on_last_read = id - in_buffer_id - 1;
01190       if (messages_missed_on_last_read < 0)
01191         {
01192           messages_missed_on_last_read = 0;
01193         }
01194       total_messages_missed += messages_missed_on_last_read;
01195       in_buffer_id = id;
01196     }
01197   return (status);
01198 }
01199 
01200 void
01201 CMS::clean_buffers ()
01202 {
01203   in_buffer_id = 0;
01204   last_id_side0 = 0;
01205   last_id_side1 = 0;
01206   if (NULL != data)
01207     {
01208       memset (data, 0, size);
01209     }
01210   if (NULL != encoded_data)
01211     {
01212       memset (encoded_data, 0, max_encoded_message_size);
01213     }
01214 }
01215 
01216 
01217 /* Read and Write interface functions call appropriate virtual function. */
01218 CMS_STATUS CMS::clear ()
01219 {
01220   in_buffer_id = 0;
01221   last_id_side0 = 0;
01222   last_id_side1 = 0;
01223   status = CMS_STATUS_NOT_SET;
01224   internal_access_type = CMS_CLEAR_ACCESS;
01225   main_access (data);
01226   return (status);
01227 }
01228 
01229 int
01230 CMS::check_if_read ()
01231 {
01232   internal_access_type = CMS_CHECK_IF_READ_ACCESS;
01233   status = CMS_STATUS_NOT_SET;
01234   main_access (data);
01235   return ((int) header.was_read);
01236 }
01237 
01238 int
01239 CMS::check_if_transfers_complete ()
01240 {
01241   return 1;
01242 }
01243 
01244 CMS_STATUS CMS::read ()
01245 {
01246   internal_access_type = CMS_READ_ACCESS;
01247   status = CMS_STATUS_NOT_SET;
01248   blocking_timeout = 0;
01249   main_access (data);
01250   return (status);
01251 }
01252 
01253 CMS_STATUS CMS::blocking_read (double _blocking_timeout)
01254 {
01255   status = CMS_STATUS_NOT_SET;
01256   internal_access_type = CMS_READ_ACCESS;
01257   blocking_timeout = _blocking_timeout;
01258   main_access (data);
01259   return (status);
01260 }
01261 
01262 void
01263 CMS::disconnect ()
01264 {
01265 }
01266 
01267 void
01268 CMS::reconnect ()
01269 {
01270 }
01271 
01272 CMS_STATUS CMS::peek ()
01273 {
01274   internal_access_type = CMS_PEEK_ACCESS;
01275   status = CMS_STATUS_NOT_SET;
01276   blocking_timeout = 0;
01277   main_access (data);
01278   return (status);
01279 }
01280 
01281 CMS_STATUS CMS::write (void *user_data)
01282 {
01283   internal_access_type = CMS_WRITE_ACCESS;
01284   status = CMS_STATUS_NOT_SET;
01285   main_access (user_data);
01286   return (status);
01287 }
01288 
01289 CMS_STATUS CMS::write_if_read (void *user_data)
01290 {
01291   internal_access_type = CMS_WRITE_IF_READ_ACCESS;
01292   status = CMS_STATUS_NOT_SET;
01293   main_access (user_data);
01294   return (status);
01295 }
01296 
01297 // For protocols that provide No security, tell the
01298 // application the login was successful.
01299 // This method needs to be overloaded to have any security.
01300 int
01301 CMS::login (const char *name, const char *passwd)
01302 {
01303   return 1;
01304 }
01305 
01306 /* Function to set the mode to appropriate read or write mode. */
01307 void
01308 CMS::set_mode (CMSMODE im)
01309 {
01310   status = CMS_STATUS_NOT_SET;
01311   if (last_im == im)
01312     {
01313       return;
01314     }
01315   if (!force_raw)
01316     {
01317       if (CMS_WRITE == im)
01318         {
01319           mode = write_mode;
01320           if (NULL != updater)
01321             {
01322               updater->set_mode ((CMS_UPDATER_MODE) write_updater_mode);
01323             }
01324           last_im = im;
01325           return;
01326         }
01327       if (CMS_READ == im)
01328         {
01329           mode = read_mode;
01330           if (NULL != updater)
01331             {
01332               updater->set_mode ((CMS_UPDATER_MODE) read_updater_mode);
01333             }
01334           last_im = im;
01335           return;
01336         }
01337       if (CMS_DECODE == im)
01338         {
01339           mode = CMS_DECODE;
01340           if (NULL != updater)
01341             {
01342               updater->set_mode (CMS_DECODE_DATA);
01343             }
01344         }
01345       if (CMS_ENCODE == im)
01346         {
01347           mode = CMS_ENCODE;
01348           if (NULL != updater)
01349             {
01350               updater->set_mode (CMS_ENCODE_DATA);
01351             }
01352         }
01353     }
01354   last_im = im;
01355   mode = im;
01356 }
01357 
01358 /* Functions for changing/restoring the updator type. */
01359 void
01360 CMS::set_temp_updater (CMS_NEUTRAL_ENCODING_METHOD temp_encoding_method)
01361 {
01362   if (force_raw)
01363     {
01364       return;
01365     }
01366   if (temp_updater_encoding_method != temp_encoding_method &&
01367       NULL != temp_updater)
01368     {
01369       delete temp_updater;
01370       temp_updater = (CMS_UPDATER *) NULL;
01371     }
01372   if (NULL == temp_updater)
01373     {
01374       switch (temp_encoding_method)
01375         {
01376         case CMS_XDR_ENCODING:
01377           temp_updater = new CMS_XDR_UPDATER (this);
01378           break;
01379 
01380 #ifndef UNDER_CE
01381         case CMS_ASCII_ENCODING:
01382           temp_updater = new CMS_ASCII_UPDATER (this);
01383           break;
01384 
01385         case CMS_DISPLAY_ASCII_ENCODING:
01386           temp_updater = new CMS_DISPLAY_ASCII_UPDATER (this);
01387           break;
01388 #endif
01389 
01390         default:
01391           temp_updater = (CMS_UPDATER *) NULL;
01392           status = CMS_UPDATE_ERROR;
01393           rcs_print_error ("CMS: Invalid encoding method(%d)\n",
01394                            neutral_encoding_method);
01395           break;
01396         }
01397     }
01398   if (NULL != temp_updater)
01399     {
01400       updater = temp_updater;
01401       temp_updater_encoding_method = temp_encoding_method;
01402     }
01403 }
01404 
01405 void
01406 CMS::restore_normal_updater ()
01407 {
01408   updater = normal_updater;
01409 }
01410 
01411 /* Updater Positioning Functions. */
01412 void
01413 CMS::rewind ()
01414 {
01415   if (force_raw)
01416     {
01417       return;
01418     }
01419   if (NULL != updater)
01420     {
01421       updater->rewind ();
01422     }
01423 }
01424 
01425 #ifdef CMS_SUPPORT_POINTERS
01426 
01427 CMS_STATUS
01428   CMS::update_ptr (int (*_update_ptr_func) (void *, CMS *), void **_x,
01429                    long _xsize)
01430 {
01431   if (NULL != updater)
01432     {
01433       return updater->update_ptr (_update_ptr_func, _x, _xsize);
01434     }
01435   return (status = CMS_UPDATE_ERROR);
01436 }
01437 
01438 CMS_STATUS CMS::set_pointer_buffer (char *_buf, long _bufsize)
01439 {
01440   if (NULL != updater)
01441     {
01442       return updater->set_pointer_buffer (_buf, _bufsize);
01443     }
01444   return (status = CMS_UPDATE_ERROR);
01445 }
01446 
01447 #endif
01448   // CMS_SUPPORT_POINTERS
01449 
01450 /* XDR routines for accessing an encoded header. */
01451 
01452 int
01453 CMS::encode_header ()
01454 {
01455   if (force_raw)
01456     {
01457       return 0;
01458     }
01459   if (NULL == updater)
01460     {
01461       return -1;
01462     }
01463   CMS_UPDATER_MODE original_mode;
01464   original_mode = updater->get_mode ();
01465   format_low_ptr = (char RCS_HUGE *) &header;
01466   format_high_ptr = ((char RCS_HUGE *) &header) + sizeof (CMS_HEADER);
01467   updater->set_mode (CMS_ENCODE_HEADER);
01468   updater->rewind ();
01469   updater->update (header.was_read);
01470   updater->update (header.write_id);
01471   updater->update (header.in_buffer_size);
01472   if (status == CMS_UPDATE_ERROR || status == CMS_MISC_ERROR)
01473     {
01474       return (-1);
01475     }
01476   encoded_header_size = updater->get_encoded_msg_size ();
01477   if (min_compatible_version <= 0.0 || min_compatible_version > 3.29)
01478     {
01479       if (neutral_encoding_method == CMS_DISPLAY_ASCII_ENCODING)
01480         {
01481           encoded_header_size = 16;
01482         }
01483     }
01484   updater->set_mode (original_mode);
01485   return (encoded_header_size);
01486 }
01487 
01488 int
01489 CMS::decode_header ()
01490 {
01491   if (force_raw)
01492     {
01493       return 0;
01494     }
01495   if (NULL == updater)
01496     {
01497       return -1;
01498     }
01499   CMS_UPDATER_MODE original_mode = updater->get_mode ();
01500   format_low_ptr = (char RCS_HUGE *) &header;
01501   format_high_ptr = ((char RCS_HUGE *) &header) + sizeof (CMS_HEADER);
01502   updater->set_mode (CMS_DECODE_HEADER);
01503   updater->rewind ();
01504   updater->update (header.was_read);
01505   updater->update (header.write_id);
01506   updater->update (header.in_buffer_size);
01507   updater->set_mode (original_mode);
01508   return ((int) (status != CMS_UPDATE_ERROR && status != CMS_MISC_ERROR) ? 0 :
01509           -1);
01510 }
01511 
01512 int
01513 CMS::encode_queuing_header ()
01514 {
01515   if (force_raw)
01516     {
01517       return 0;
01518     }
01519   if (NULL == updater)
01520     {
01521       return -1;
01522     }
01523   CMS_UPDATER_MODE original_mode = updater->get_mode ();
01524   format_low_ptr = (char RCS_HUGE *) &queuing_header;
01525   format_high_ptr =
01526     ((char RCS_HUGE *) &queuing_header) + sizeof (CMS_QUEUING_HEADER);
01527   updater->set_mode (CMS_ENCODE_QUEUING_HEADER);
01528   updater->rewind ();
01529   updater->update (queuing_header.head);
01530   updater->update (queuing_header.tail);
01531   updater->update (queuing_header.queue_length);
01532   updater->update (queuing_header.end_queue_space);
01533   updater->update (queuing_header.write_id);
01534   if (status == CMS_UPDATE_ERROR || status == CMS_MISC_ERROR)
01535     {
01536       return (-1);
01537     }
01538   encoded_queuing_header_size = updater->get_encoded_msg_size ();
01539   if (min_compatible_version <= 0.0 || min_compatible_version > 3.29)
01540     {
01541       if (neutral_encoding_method == CMS_DISPLAY_ASCII_ENCODING)
01542         {
01543           encoded_queuing_header_size = 24;
01544         }
01545     }
01546   updater->set_mode (original_mode);
01547   return (encoded_queuing_header_size);
01548 }
01549 
01550 int
01551 CMS::decode_queuing_header ()
01552 {
01553   if (force_raw)
01554     {
01555       return 0;
01556     }
01557   if (NULL == updater)
01558     {
01559       return -1;
01560     }
01561   CMS_UPDATER_MODE original_mode = updater->get_mode ();
01562   format_low_ptr = (char RCS_HUGE *) &queuing_header;
01563   format_high_ptr =
01564     ((char RCS_HUGE *) &queuing_header) + sizeof (CMS_QUEUING_HEADER);
01565   updater->set_mode (CMS_DECODE_QUEUING_HEADER);
01566   updater->rewind ();
01567   updater->update (queuing_header.head);
01568   updater->update (queuing_header.tail);
01569   updater->update (queuing_header.queue_length);
01570   updater->update (queuing_header.end_queue_space);
01571   updater->update (queuing_header.write_id);
01572   updater->set_mode (original_mode);
01573   return ((int) (status != CMS_UPDATE_ERROR && status != CMS_MISC_ERROR) ? 0 :
01574           -1);
01575 }
01576 
01577 int
01578 CMS::get_encoded_msg_size ()
01579 {
01580   if (force_raw)
01581     {
01582       return 0;
01583     }
01584   if (NULL == updater)
01585     {
01586       return (-1);
01587     }
01588   return (header.in_buffer_size = updater->get_encoded_msg_size ());
01589 }
01590 
01591 int
01592 CMS::check_pointer (char RCS_HUGE * ptr, long bytes)
01593 {
01594   if (force_raw)
01595     {
01596       return 0;
01597     }
01598   if (NULL == format_low_ptr || NULL == format_high_ptr
01599       || pointer_check_disabled)
01600     {
01601       return 0;
01602     }
01603   if (ptr < format_low_ptr || ptr > (format_high_ptr - bytes))
01604     {
01605       rcs_print_error ("CMS: pointer %p to %d bytes out of range %p to %p\n",
01606                        ptr, bytes, format_low_ptr, format_high_ptr);
01607       rcs_print_error ("CMS: Check buffer and message sizes.\n");
01608       status = CMS_UPDATE_ERROR;
01609       return -1;
01610     }
01611   format_size = (long) (ptr - format_low_ptr) + bytes;
01612   return 0;
01613 }
01614 
01615 void
01616 CMS::set_cms_status (CMS_STATUS new_status)
01617 {
01618   status = new_status;
01619 }
01620 
01621   /* Access functions for primitive C language data types */
01622 CMS_STATUS CMS::update (char &x)
01623 {
01624   if (NULL != updater)
01625     {
01626       return (updater->update (x));
01627     }
01628   else
01629     {
01630       return (status = CMS_UPDATE_ERROR);
01631     }
01632 }
01633 
01634 CMS_STATUS CMS::update (unsigned char &x)
01635 {
01636   if (NULL != updater)
01637     {
01638       return (updater->update (x));
01639     }
01640   else
01641     {
01642       return (status = CMS_UPDATE_ERROR);
01643     }
01644 }
01645 
01646 CMS_STATUS CMS::update (short int &x)
01647 {
01648   if (NULL != updater)
01649     {
01650       return (updater->update (x));
01651     }
01652   else
01653     {
01654       return (status = CMS_UPDATE_ERROR);
01655     }
01656 }
01657 
01658 CMS_STATUS CMS::update (unsigned short int &x)
01659 {
01660   if (NULL != updater)
01661     {
01662       return (updater->update (x));
01663     }
01664   else
01665     {
01666       return (status = CMS_UPDATE_ERROR);
01667     }
01668 }
01669 
01670 CMS_STATUS CMS::update (int &x)
01671 {
01672   if (NULL != updater)
01673     {
01674       return (updater->update (x));
01675     }
01676   else
01677     {
01678       return (status = CMS_UPDATE_ERROR);
01679     }
01680 }
01681 
01682 CMS_STATUS CMS::update (unsigned int &x)
01683 {
01684   if (NULL != updater)
01685     {
01686       return (updater->update (x));
01687     }
01688   else
01689     {
01690       return (status = CMS_UPDATE_ERROR);
01691     }
01692 }
01693 
01694 CMS_STATUS CMS::update (long int &x)
01695 {
01696   if (NULL != updater)
01697     {
01698       return (updater->update (x));
01699     }
01700   else
01701     {
01702       return (status = CMS_UPDATE_ERROR);
01703     }
01704 }
01705 
01706 CMS_STATUS CMS::update (unsigned long int &x)
01707 {
01708   if (NULL != updater)
01709     {
01710       return (updater->update (x));
01711     }
01712   else
01713     {
01714       return (status = CMS_UPDATE_ERROR);
01715     }
01716 }
01717 
01718 CMS_STATUS CMS::update (float &x)
01719 {
01720   if (NULL != updater)
01721     {
01722       return (updater->update (x));
01723     }
01724   else
01725     {
01726       return (status = CMS_UPDATE_ERROR);
01727     }
01728 }
01729 
01730 CMS_STATUS CMS::update (double &x)
01731 {
01732   if (NULL != updater)
01733     {
01734       return (updater->update (x));
01735     }
01736   else
01737     {
01738       return (status = CMS_UPDATE_ERROR);
01739     }
01740 }
01741 
01742 CMS_STATUS CMS::update (long double &x)
01743 {
01744   if (NULL != updater)
01745     {
01746       return (updater->update (x));
01747     }
01748   else
01749     {
01750       return (status = CMS_UPDATE_ERROR);
01751     }
01752 }
01753 
01754 CMS_STATUS CMS::update (char *x, unsigned int len)
01755 {
01756   if (NULL != updater)
01757     {
01758       return (updater->update (x, len));
01759     }
01760   else
01761     {
01762       return (status = CMS_UPDATE_ERROR);
01763     }
01764 }
01765 
01766 CMS_STATUS CMS::update (unsigned char *x, unsigned int len)
01767 {
01768   if (NULL != updater)
01769     {
01770       return (updater->update (x, len));
01771     }
01772   else
01773     {
01774       return (status = CMS_UPDATE_ERROR);
01775     }
01776 }
01777 
01778 CMS_STATUS CMS::update (short *x, unsigned int len)
01779 {
01780   if (NULL != updater)
01781     {
01782       return (updater->update (x, len));
01783     }
01784   else
01785     {
01786       return (status = CMS_UPDATE_ERROR);
01787     }
01788 }
01789 
01790 CMS_STATUS CMS::update (unsigned short *x, unsigned int len)
01791 {
01792   if (NULL != updater)
01793     {
01794       return (updater->update (x, len));
01795     }
01796   else
01797     {
01798       return (status = CMS_UPDATE_ERROR);
01799     }
01800 }
01801 
01802 CMS_STATUS CMS::update (int *x, unsigned int len)
01803 {
01804   if (NULL != updater)
01805     {
01806       return (updater->update (x, len));
01807     }
01808   else
01809     {
01810       return (status = CMS_UPDATE_ERROR);
01811     }
01812 }
01813 
01814 CMS_STATUS CMS::update (unsigned int *x, unsigned int len)
01815 {
01816   if (NULL != updater)
01817     {
01818       return (updater->update (x, len));
01819     }
01820   else
01821     {
01822       return (status = CMS_UPDATE_ERROR);
01823     }
01824 }
01825 
01826 CMS_STATUS CMS::update (long *x, unsigned int len)
01827 {
01828   if (NULL != updater)
01829     {
01830       return (updater->update (x, len));
01831     }
01832   else
01833     {
01834       return (status = CMS_UPDATE_ERROR);
01835     }
01836 }
01837 
01838 CMS_STATUS CMS::update (unsigned long *x, unsigned int len)
01839 {
01840   if (NULL != updater)
01841     {
01842       return (updater->update (x, len));
01843     }
01844   else
01845     {
01846       return (status = CMS_UPDATE_ERROR);
01847     }
01848 }
01849 
01850 CMS_STATUS CMS::update (float *x, unsigned int len)
01851 {
01852   if (NULL != updater)
01853     {
01854       return (updater->update (x, len));
01855     }
01856   else
01857     {
01858       return (status = CMS_UPDATE_ERROR);
01859     }
01860 }
01861 
01862 CMS_STATUS CMS::update (double *x, unsigned int len)
01863 {
01864   if (NULL != updater)
01865     {
01866       return (updater->update (x, len));
01867     }
01868   else
01869     {
01870       return (status = CMS_UPDATE_ERROR);
01871     }
01872 }
01873 
01874 CMS_STATUS CMS::update (long double *x, unsigned int len)
01875 {
01876   if (NULL != updater)
01877     {
01878       return (updater->update (x, len));
01879     }
01880   else
01881     {
01882       return (status = CMS_UPDATE_ERROR);
01883     }
01884 }
01885 
01886 const char *
01887 CMS::status_string (int status_type)
01888 {
01889   switch (status_type)
01890     {
01891       /* ERROR conditions */
01892     case CMS_MISC_ERROR:
01893       return ("CMS_MISC_ERROR:   A miscellaneous  error occured.");
01894 
01895     case CMS_UPDATE_ERROR:
01896       return ("CMS_UPDATE_ERROR: An error occured during an update. ");
01897 
01898     case CMS_INTERNAL_ACCESS_ERROR:
01899       return
01900         ("CMS_INTERNAL_ACCESS_ERROR: An error occured during an internal access function. ");
01901 
01902     case CMS_NO_MASTER_ERROR:
01903       return
01904         ("CMS_NO_MASTER_ERROR: An error occured becouse the master was not started.");
01905 
01906     case CMS_CONFIG_ERROR:
01907       return ("CMS_CONFIG_ERROR: There was an error in the configuration.");
01908 
01909     case CMS_TIMED_OUT:
01910       return ("CMS_TIMED_OUT: operation timed out.");
01911 
01912     case CMS_QUEUE_FULL:
01913       return
01914         ("CMS_QUEUE_FULL:=  A write failed because queuing was enabled but there was no room to add to the queue. ");
01915 
01916     case CMS_CREATE_ERROR:
01917       return
01918         ("CMS_CREATE_ERROR: Something could not be created because we were out of memory or another system resource.");
01919 
01920     case CMS_PERMISSIONS_ERROR:
01921       return ("CMS_PERMISSIONS_ERROR: Problem with permissions.");
01922 
01923       /* NON Error Conditions. */
01924     case CMS_STATUS_NOT_SET:
01925       return
01926         ("CMS_STATUS_NOT_SET: The status variable has not been set yet.");
01927 
01928     case CMS_READ_OLD:
01929       return ("CMS_READ_OLD:  Read successful, but data is old. \n");
01930 
01931     case CMS_READ_OK:
01932       return ("CMS_READ_OK: Read successful so far.");
01933 
01934     case CMS_WRITE_OK:
01935       return ("CMS_WRITE_OK:  Write successful so far. ");
01936 
01937     case CMS_WRITE_WAS_BLOCKED:
01938       return
01939         ("CMS_WRITE_WAS_BLOCKED: Write if read did not succeed, because the buffer had not been read yet.");
01940 
01941     case CMS_CLEAR_OK:
01942       return ("CMS_CLEAR_OK: A clear operation was successful.");
01943 
01944     case CMS_CLOSED:
01945       return ("CMS_CLOSED: The channel has been closed.");
01946 
01947     case CMS_NO_SERVER_ERROR:
01948       return
01949         (" CMS_NO_SERVER_ERROR: The server has not been started or could not be contacted.");
01950 
01951     case CMS_RESOURCE_CONFLICT_ERROR:
01952       return
01953         ("CMS_RESOURCE_CONFLICT_ERROR: Two or more CMS buffers are trying to use the same resource.");
01954 
01955     case CMS_NO_IMPLEMENTATION_ERROR:
01956       return
01957         ("CMS_NO_IMPLEMENTATION_ERROR: An operation was attempted which has not yet been implemented for the current platform or protocol.");
01958 
01959     case CMS_INSUFFICIENT_SPACE_ERROR:
01960       return
01961         ("CMS_INSUFFICIENT_SPACE_ERROR: The size of the buffer was insufficient for the requested operation.");
01962 
01963     case CMS_LIBRARY_UNAVAILABLE_ERROR:
01964       return
01965         ("CMS_LIBRARY_UNAVAILABLE_ERROR: A DLL or Shared Object library needed for the current protocol could not be found or initialized.");
01966 
01967     case CMS_SERVER_SIDE_ERROR:
01968       return ("CMS_SERVER_SIDE_ERROR: The server reported an error.");
01969 
01970     case CMS_NO_BLOCKING_SEM_ERROR:
01971       return
01972         ("CMS_NO_BLOCKING_SEM_ERROR: A blocking_read operartion was tried but no semaphore for the blocking was configured or available.");
01973 
01974     default:
01975       return ("UNKNOWN");
01976     }
01977 }
01978 
01979 
01980 int
01981 CMS::set_subdivision (int _subdiv)
01982 {
01983   if (_subdiv < 0 || _subdiv > total_subdivisions)
01984     {
01985       return -1;
01986     }
01987   current_subdivision = _subdiv;
01988   subdiv_data = ((char *) data) + _subdiv * (subdiv_size);
01989   return (0);
01990 }
01991 
01992 // This constructor declared private to prevent copying.
01993 CMS::CMS (CMS & cms)
01994 {
01995 }
01996 
01997 
01998 int
01999 CMS::get_msg_count ()
02000 {
02001   if (!enable_diagnostics)
02002     {
02003       return (0);
02004     }
02005 
02006   internal_access_type = CMS_GET_MSG_COUNT_ACCESS;
02007   status = CMS_STATUS_NOT_SET;
02008   blocking_timeout = 0;
02009   main_access (data);
02010   return (header.write_id);
02011 }
02012 
02013 
02014 char *
02015 cms_check_for_host_alias (char *in)
02016 {
02017   if (NULL == in)
02018     {
02019       return NULL;
02020     }
02021   if (NULL == cmsHostAliases)
02022     {
02023       return NULL;
02024     }
02025   CMS_HOST_ALIAS_ENTRY *entry =
02026     (CMS_HOST_ALIAS_ENTRY *) cmsHostAliases->get_head ();
02027   while (NULL != entry)
02028     {
02029       if (!strncmp (entry->alias, in, 64))
02030         {
02031           return entry->host;
02032         }
02033     }
02034   return NULL;
02035 }

Generated on Sun Dec 2 15:56:48 2001 for rcslib by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001