📄 cms.cc
字号:
/********************************************************************* Description: cms.cc* C++ file for the Communication Management System (CMS).* Includes member functions for class CMS.* See cms_in.cc for the internal interface member functions and* cms_up.cc for the update functions.** Derived from a work by Fred Proctor & Will Shackleford** Author:* License: LGPL Version 2* System: Linux* * Copyright (c) 2004 All rights reserved.** Last change: * $Revision: 1.10 $* $Author: jepler $* $Date: 2007/03/22 22:15:35 $********************************************************************/#include "rcsversion.h"#ifdef __cplusplusextern "C" {#endif#include <stdlib.h> /* malloc(), free() */#include <stddef.h> /* size_t */#include <string.h> /* strcpy(), strlen(),memcpy() */ /* strcmp(),strchr() */#include <ctype.h> // tolower(), toupper()#include <errno.h> /* errno, ERANGE */#ifdef __cplusplus}#endif#include "cms.hh" /* class CMS */#include "cms_up.hh" /* class CMS_UPDATER */#include "cms_xup.hh" /* class CMS_XDR_UPDATER */#include "cms_aup.hh" /* class CMS_ASCII_UPDATER */#include "cms_dup.hh" /* class CMS_DISPLAY_ASCII_UPDATER */#include "rcs_print.hh" /* rcs_print_error(), separate_words() */ /* rcs_print_debug() */#include "cmsdiag.hh"#include "linklist.hh" /* LinkedList */#include "physmem.hh"LinkedList *cmsHostAliases = NULL;CMS_CONNECTION_MODE cms_connection_mode = CMS_NORMAL_CONNECTION_MODE;/* Static Class Data Members. */int CMS::number_of_cms_objects = 0;int cms_encoded_data_explosion_factor = 4;/*! \todo Another #if 0 */#if 0static int convert2lower(char *dest, char *src, int len){ int i; for (i = 0; i < len; i++) { if (src[i] == 0) { dest[i] = 0; return i; } dest[i] = tolower(src[i]); } return i;}#endifstatic int convert2upper(char *dest, char *src, int len){ int i; for (i = 0; i < len; i++) { if (src[i] == 0) { dest[i] = 0; return i; } dest[i] = toupper(src[i]); } return i;}/* Class CMS Member Functions */void *CMS::operator new(size_t size){ if (size < sizeof(CMS)) { rcs_print_error ("CMS::operator new -- The size requested %d is less than the mininimum size of CMS %d.\n", size, sizeof(CMS)); rcs_print_error("This could indicate a version mismatch problem.\n"); size = sizeof(CMS); } void *space = (void *) malloc(size); if (NULL != space) { memset(space, 0, size); } rcs_print_debug(PRINT_CMS_CONSTRUCTORS, "%X = CMS::new(%d)\n", space, size); return space;}void CMS::operator delete(void *space){ rcs_print_debug(PRINT_CMS_DESTRUCTORS, " CMS::delete(%X)\n", space); free(space); rcs_print_debug(PRINT_CMS_DESTRUCTORS, " CMS::delete successful.\n");}/* Constructor used for hard coded tests. *//* Parameters: */ /* n - Name of the buffer. */ /* s - Size of the buffer. */ /* nt - 0 buffer is not neutrally encoded, 1 buffer is neutrally encoded */ /* set_to_server - 0 do NOT be a server, 1 be a server */CMS::CMS(long s){ /* Print a message if the PRINT_CMS_CONSTUCTORS */ /* member of the print flags is set. */ rcs_print_debug(PRINT_CMS_CONSTRUCTORS, "new CMS (%d)", s); /* Init string buffers */ memset(BufferName, 0, CMS_CONFIG_LINELEN); memset(BufferHost, 0, CMS_CONFIG_LINELEN); memset(ProcessName, 0, CMS_CONFIG_LINELEN); memset(BufferLine, 0, CMS_CONFIG_LINELEN); memset(ProcessLine, 0, CMS_CONFIG_LINELEN); memset(ProcessHost, 0, CMS_CONFIG_LINELEN); memset(buflineupper, 0, CMS_CONFIG_LINELEN); memset(proclineupper, 0, CMS_CONFIG_LINELEN); memset(PermissionString, 0, CMS_CONFIG_LINELEN); /* save constructor args */ free_space = size = s; force_raw = 0; neutral = 0; isserver = 0; last_im = CMS_NOT_A_MODE; min_compatible_version = 0; confirm_write = 0; disable_final_write_raw_for_dma = 0; subdiv_data = 0; enable_diagnostics = 0; dpi = NULL; di = NULL; skip_area = 0; half_offset = s / 2; free_space = half_size = s / 2; fast_mode = 0; disable_diag_store = 0; diag_offset = 0; /* Initailize some variables. */ read_permission_flag = 0; /* Allow both read and write by default. */ write_permission_flag = 0; queuing_enabled = 0; fatal_error_occurred = 0; write_just_completed = 0; neutral_encoding_method = CMS_XDR_ENCODING; blocking_timeout = 0; total_subdivisions = 1; subdiv_size = size; current_subdivision = 0; enc_max_size = s; max_encoded_message_size = s; last_id_side0 = 0; last_id_side1 = 0; handle_to_global_data = NULL; dummy_handle = (PHYSMEM_HANDLE *) NULL; /* Set pointers to NULL */ /* so we'll know whether it really */ /* points to something */ delete_totally = 0; /* If this object is deleted only do */ /* normal delete instead of deleting totally. */ mode = CMS_NOT_A_MODE; /* Force user to set the mode before using. */ open(); /* Allocate memory and intialize XDR streams */}/* Constructor used by cms_config. *//* Parameters: *//* bufline - The buffer line from a CMS configuration file. *//* procline - The process line from a CMS configuration file. *//* set_to_server - */ /* -1 force this CMS object NOT to be in server mode. */ /* 0 allow the parameter in the procline to set whether server mode is used */ /* 1 force this CMS object to be in server mode. */CMS::CMS(char *bufline, char *procline, int set_to_server){ char *word[32]; /* Array of pointers to strings. */ char *buffer_type_name; /* pointer to buffer type name from bufline */ char *proc_type_name; /* pointer to process type from procline */ int i; min_compatible_version = 0; force_raw = 0; confirm_write = 0; disable_final_write_raw_for_dma = 0; /* Init string buffers */ memset(BufferName, 0, CMS_CONFIG_LINELEN); memset(BufferHost, 0, CMS_CONFIG_LINELEN); memset(ProcessName, 0, CMS_CONFIG_LINELEN); memset(BufferLine, 0, CMS_CONFIG_LINELEN); memset(ProcessLine, 0, CMS_CONFIG_LINELEN); memset(ProcessHost, 0, CMS_CONFIG_LINELEN); memset(buflineupper, 0, CMS_CONFIG_LINELEN); memset(proclineupper, 0, CMS_CONFIG_LINELEN); memset(PermissionString, 0, CMS_CONFIG_LINELEN); /* Initailize some variables. */ read_permission_flag = 0; /* Allow both read and write by default. */ write_permission_flag = 0; queuing_enabled = 0; fatal_error_occurred = 0; write_just_completed = 0; neutral_encoding_method = CMS_XDR_ENCODING; blocking_timeout = 0; min_compatible_version = 0; enc_max_size = -1; max_encoded_message_size = 0; enable_diagnostics = 0; dpi = NULL; di = NULL; disable_diag_store = 0; diag_offset = 0; use_autokey_for_connection_number = 0; if ((NULL == bufline) || (NULL == procline)) { rcs_print_error("CMS: Pointer to bufline or procline is NULL.\n"); return; } convert2upper(buflineupper, bufline, CMS_CONFIG_LINELEN); convert2upper(proclineupper, procline, CMS_CONFIG_LINELEN); is_phantom = 0; max_message_size = 0; using_external_encoded_data = 0; in_buffer_id = 0; last_id_side0 = 0; last_id_side1 = 0; delete_totally = 0; queuing_enabled = 0; split_buffer = 0; fatal_error_occurred = 0; consecutive_timeouts = 0; write_just_completed = 0; pointer_check_disabled = 0; blocking_timeout = 0; last_im = CMS_NOT_A_MODE; total_subdivisions = 1; size = 0; subdiv_size = 0; current_subdivision = 0; max_encoded_message_size = 0; skip_area = 0; half_offset = 0; half_size = 0; fast_mode = 0; last_id_side0 = 0; last_id_side1 = 0; free_space = 0; handle_to_global_data = NULL; dummy_handle = (PHYSMEM_HANDLE *) NULL; remote_port_type = CMS_NO_REMOTE_PORT_TYPE; for (i = 0; i < 10; i++) { word[i] = (char *) NULL; } /* Store the bufline and procline for debugging later. */ strcpy(BufferLine, bufline); strcpy(ProcessLine, procline); /* Get parameters from the buffer's line in the config file. */ if (separate_words(word, 9, bufline) != 9) { rcs_print_error("CMS: Error in buffer line from config file.\n"); rcs_print_error("%s\n", bufline); status = CMS_CONFIG_ERROR; return; } /* Use the words from the buffer line to initialize some class variables. */ strcpy(BufferName, word[1]); rcs_print_debug(PRINT_CMS_CONSTRUCTORS, "new CMS (%s)\n", BufferName); /* Clear errno so we can determine if all of the parameters in the */ /* buffer line were in an acceptable form. */ if (errno == ERANGE) { errno = 0; } char *realname = cms_check_for_host_alias(word[3]); if (realname == NULL) { strcpy(BufferHost, word[3]); } else { strcpy(BufferHost, realname); } buffer_type_name = word[2]; /* strtol should allow us to use the C syntax for specifying the radix of the numbers in the configuration file. (i.e. 0x???? for hexidecimal, 0??? for octal and ???? for decimal.) */ size = (long) strtol(word[4], (char **) NULL, 0); neutral = (int) strtol(word[5], (char **) NULL, 0); rpc_program_number = strtol(word[6], (char **) NULL, 0); buffer_number = strtol(word[7], (char **) NULL, 0); total_connections = strtol(word[8], (char **) NULL, 0); free_space = size; /* Check errno to see if all of the strtol's were sucessful. */ if (ERANGE == errno) { rcs_print_error("CMS: Error in buffer line from config file.\n"); rcs_print_error("%s\n", bufline); status = CMS_CONFIG_ERROR; return; } /* Determine the BufferType. */ if (!strcmp(buffer_type_name, "SHMEM")) { BufferType = CMS_SHMEM_TYPE; } else if (!strcmp(buffer_type_name, "PHANTOM")) { BufferType = CMS_PHANTOM_BUFFER; is_phantom = 1; } else if (!strcmp(buffer_type_name, "LOCMEM")) { BufferType = CMS_LOCMEM_TYPE; } else if (!strcmp(buffer_type_name, "FILEMEM")) { BufferType = CMS_FILEMEM_TYPE; } else { rcs_print_error("CMS: invalid buffer type (%s)\n", buffer_type_name); status = CMS_CONFIG_ERROR; return; } int num_words = separate_words(word, 32, buflineupper); if (num_words < 8) { rcs_print_error("CMS: Error in buffer line from config file.\n"); rcs_print_error("%s\n", bufline); status = CMS_CONFIG_ERROR; return; } for (i = 8; i < num_words && i < 32; i++) { if (word[i] == NULL) { break; } if (!strcmp(word[i], "QUEUE")) { queuing_enabled = 1; continue; } if (!strcmp(word[i], "DIAG")) { enable_diagnostics = 1; continue; } if (!strcmp(word[i], "SPLIT")) { split_buffer = 1; continue; } if (!strcmp(word[i], "DISP")) { neutral_encoding_method = CMS_DISPLAY_ASCII_ENCODING; continue; } if (!strcmp(buflineupper, "ASCII")) { neutral_encoding_method = CMS_ASCII_ENCODING; continue; } if (!strcmp(buflineupper, "XDR")) { neutral_encoding_method = CMS_XDR_ENCODING; continue; } char *port_string; if (NULL != (port_string = strstr(word[i], "STCP="))) { remote_port_type = CMS_STCP_REMOTE_PORT_TYPE; stcp_port_number = (int) strtol(port_string + 5, (char **) NULL, 0); continue; } else if (NULL != (port_string = strstr(word[i], "TCP="))) { remote_port_type = CMS_TCP_REMOTE_PORT_TYPE; tcp_port_number = (int) strtol(port_string + 4, (char **) NULL, 0); continue; } else if (NULL != (port_string = strstr(word[i], "UDP="))) { remote_port_type = CMS_UDP_REMOTE_PORT_TYPE; udp_port_number = (int) strtol(port_string + 4, (char **) NULL, 0); continue; } char *version_string; if (NULL != (version_string = strstr(word[i], "VERSION="))) { min_compatible_version = strtod(version_string + 8, (char **) NULL); continue; } char *subdiv_string; if (NULL != (subdiv_string = strstr(word[i], "SUBDIV="))) { total_subdivisions = strtol(subdiv_string + 7, (char **) NULL, 0); subdiv_size = size / total_subdivisions; subdiv_size -= subdiv_size % 4; continue; } char *enc_max_string; if (NULL != (enc_max_string = strstr(word[i], "ENC_MAX_SIZE="))) { enc_max_size = strtoul(enc_max_string + 13, (char **) NULL, 0); continue; } if (!strcmp(word[i], "CONFIRM_WRITE")) { confirm_write = 1; continue; } if (!strcmp(word[i], "FORCE_RAW")) { force_raw = 1; continue; } if (!strcmp(word[i], "AUTOCNUM")) { use_autokey_for_connection_number = 1; continue; } } /* Get parameters from the process's line in the config file. */ if (use_autokey_for_connection_number) { if (separate_words(word, 9, procline) != 9) { rcs_print_error ("CMS: Error parsing process line from config file.\n"); rcs_print_error("%s\n", procline); status = CMS_CONFIG_ERROR; return; } } else { if (separate_words(word, 10, procline) != 10) { rcs_print_error ("CMS: Error parsing process line from config file.\n"); rcs_print_error("%s\n", procline); status = CMS_CONFIG_ERROR; return; } } /* Clear errno so we can determine if all of the parameters in the */ /* buffer line were in an acceptable form. */ if (errno == ERANGE) { errno = 0; } strcpy(ProcessName, word[1]); strcpy(ProcessHost, word[4]); /* Clear errno so we can determine if all of the parameters in the */ /* buffer line were in an acceptable form. */ if (errno == ERANGE) { errno = 0; } proc_type_name = word[3]; strcpy(PermissionString, word[5]); spawn_server = atoi(word[6]); /* Compute timeout. */ if (!strcmp(word[7], "INF")) { /* Never Time Out. */ timeout = -1; } else { timeout = strtod(word[7], (char **) NULL); } is_local_master = (int) atol(word[8]); if (!use_autokey_for_connection_number) { connection_number = atol(word[9]); if (total_connections <= connection_number) { rcs_print_error ("CMS: connection number(%d) must be less than total connections (%d).\n", connection_number, total_connections); status = CMS_CONFIG_ERROR; return; } } /* Check errno to see if all of the strtol's were sucessful. */ if (ERANGE == errno) { rcs_print_error("CMS: Error in proc line from config file.\n"); rcs_print_error("%s\n", procline); status = CMS_CONFIG_ERROR; return; } if (set_to_server < 0) { isserver = 0; } else if (set_to_server > 0) { isserver = 1; } else { isserver = (spawn_server == 1); } /* Determine the ProcessType. */ switch (cms_connection_mode) { case CMS_NORMAL_CONNECTION_MODE: if (!strcmp(proc_type_name, "REMOTE")) { ProcessType = CMS_REMOTE_TYPE; spawn_server = 0; } else if (!strcmp(proc_type_name, "LOCAL")) { ProcessType = CMS_LOCAL_TYPE; } else if (!strcmp(proc_type_name, "AUTO")) { if (hostname_matches_bufferline(BufferLine)) { ProcessType = CMS_LOCAL_TYPE; } else { ProcessType = CMS_REMOTE_TYPE; spawn_server = 0; } } else if (!strcmp(proc_type_name, "PHANTOM")) { ProcessType = CMS_PHANTOM_USER; spawn_server = 0; is_phantom = 1; } else { rcs_print_error("CMS: invalid process type (%s)/n", proc_type_name); status = CMS_CONFIG_ERROR; return; } break; case CMS_FORCE_LOCAL_CONNECTION_MODE: ProcessType = CMS_LOCAL_TYPE; break; case CMS_FORCE_REMOTE_CONNECTION_MODE: ProcessType = CMS_REMOTE_TYPE; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -