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

cms_srv.cc

Go to the documentation of this file.
00001 /*************************************************************************
00002 * File:cms_srv.cc                                                        *
00003 * Authors: Fred Proctor, Will Shackleford                                *
00004 * Purpose: C++ file for RPC server that reads and writes to a local      *
00005 *          CMS buffer for remote processes.                              *
00006 * Includes:                                                              *
00007 *          1. member functions for class CMS_SERVER                      *
00008 *          2. CMS_SERVER friend functions cms_server_dispatch and        *
00009 *             cms_server_clean.                                          *
00010 *************************************************************************/
00011 
00012 #include "rcs_defs.hh"          /* EXTERN_C_STD_HEADERS  */
00013 
00014 #ifdef EXTERN_C_STD_HEADERS
00015 extern "C"
00016 {
00017 #endif
00018 
00019 #ifndef UNDER_CE
00020 #include <stdio.h>              /* sscanf(),NULL */
00021   /* FILE, fopen(), fgets() */
00022 #endif
00023 #include <string.h>             /* strchr(), memcpy() */
00024 #include <stdlib.h>             /* malloc(), free(), exit() */
00025 #include <ctype.h>              // isgraph()
00026 #ifndef irix6
00027 #include <math.h>               /* fmod() */
00028 #else
00029 // Work around for the conflict between the gcc includes and /usr/includes
00030 // on some of our SGI's regarding the definition of initstate()
00031   extern double fmod (double, double);
00032 #endif
00033 
00034 #if defined(WIN32)
00035 #if defined(WIN32) && !defined(USE_OLD_WINSOCK)
00036 // Lame problem if windows.h is included before winsock2.h many redefined
00037 // compiler errors result.
00038 #include <winsock2.h>
00039 #endif
00040 #include <windows.h>            /* InitializeSecurityDescriptor(), CreateThread() */
00041 #else
00042 
00043 #ifdef VXWORKS
00044 #include <taskLib.h>            /* taskLock(), taskUnlock(), taskIdSelf() */
00045 #else
00046 #include <sys/types.h>
00047 #include <unistd.h>             /* getpid() */
00048 #include <sys/wait.h>           /* waitpid() */
00049 #endif
00050 #endif
00051 
00052 #ifndef UNDER_CE
00053 #include <signal.h>             /* sigvec(), struct sigvec,  SIGINT */
00054   /* kill() */
00055 #endif
00056 
00057 #ifdef WIN32
00058 #ifdef MULTITHREADED
00059 #ifndef UNDER_CE
00060 #include <process.h>            // _beginthread
00061 #else
00062 #include <Winbase.h>            // CreateThread
00063 #endif
00064 #endif
00065 #endif
00066 
00067 
00068 #ifdef EXTERN_C_STD_HEADERS
00069 }
00070 #endif
00071 
00072 
00073 #include "cms.hh"               /* class CMS */
00074 #include "rem_msg.hh"           /* struct REMOTE_READ_REQUEST, */
00075                                 /* struct REMOTE_WRITE_REQUEST, */
00076 #include "cms_srv.hh"           /* class CMS_SERVER  */
00077 #include "cms_cfg.hh"           /* cms_config() */
00078 #include "rcs_prnt.hh"          /* rcs_print_error() */
00079 
00080 
00081 #ifndef NO_DCE_RPC
00082 #define NO_DCE_RPC
00083 #endif
00084 
00085 #ifndef NO_DCE_RPC
00086 #ifndef WIN32
00087 #include "rpc_srv.hh"           /* CMS_SERVER_RPC_PORT */
00088 #endif
00089 #endif
00090 #include "tcp_srv.hh"           /* CMS_SERVER_TCP_PORT */
00091 #ifndef UNDER_CE
00092 #include "stcpsvr.hh"           /* CMS_SERVER_STCP_PORT */
00093 #endif
00094 
00095 #if !defined(VXWORKS) && (!defined(__MSDOS__) || defined(WIN32)) && !defined(UNDER_CE) && !defined(DARWIN) && !defined(qnx)
00096 #include "tty_srv.hh"
00097 #endif
00098 
00099 #include "udp_srv.hh"           /* CMS_SERVER_UDP_PORT */
00100 #include "inetfile.hh"          // INET_FILE, inet_file_open(), . . .
00101 #include "timer.hh"             // etime()
00102 #include "crypt2.hh"            // crypt()
00103 
00104 #include "dbg_mem.h"            /* DEBUG_FREE,DEBUG_MALLOC,DEBUG_CALLOC */
00105 #include "cmsdiag.hh"
00106 
00107 
00108 int cms_server_count = 0;
00109 int cms_server_task_priority = 100;
00110 int cms_server_task_stack_size = 32768;
00111 
00112 void
00113 wait_for_servers (int count_to_waitfor)
00114 {
00115   do
00116     {
00117       esleep (0.1);
00118     }
00119   while (cms_server_count < count_to_waitfor);
00120 
00121 }
00122 
00123 
00124 
00125 class CMS_USER_INFO
00126 {
00127 public:
00128   CMS_USER_INFO ();
00129 private:
00130   char passwd[16];
00131   char epasswd[16];
00132   char name[16];
00133   char passwd_file_line[256];
00134   char key1[8];
00135   char key2[8];
00136   int has_passwd;
00137   int user_number;
00138   int allow_read;
00139   int allow_write;
00140   friend class CMS_SERVER;
00141 };
00142 
00143 
00144 CMS_USER_INFO::CMS_USER_INFO ()
00145 {
00146   memset (passwd, 0, 16);
00147   memset (epasswd, 0, 16);
00148   memset (name, 0, 16);
00149   memset (passwd_file_line, 0, 256);
00150   memset (key1, 0, 8);
00151   memset (key2, 0, 8);
00152   has_passwd = 0;
00153   user_number = 0;
00154   allow_read = 0;
00155   allow_write = 0;
00156 }
00157 
00158 CMS_USER_CONNECT_STRUCT::CMS_USER_CONNECT_STRUCT ()
00159 {
00160   user_info = NULL;
00161   fd = -1;
00162 }
00163 
00164 /* CMS_SERVER Global  Variables */
00165 RCS_LINKED_LIST *cms_server_list = NULL;
00166 
00167 #ifdef VXWORKS
00168 SEM_ID cms_server_list_mutex = 0;
00169 #endif
00170 
00171 CMS_SERVER_LOCAL_PORT::CMS_SERVER_LOCAL_PORT (CMS * _cms)
00172 {
00173   local_channel_reused = 1;
00174   security_enabled = 0;
00175   cms = _cms;
00176   orig_info = NULL;
00177   if (NULL != cms)
00178     {
00179       buffer_number = cms->buffer_number;
00180     }
00181   else
00182     {
00183       buffer_number = 0;
00184     }
00185   list_id = 0;
00186 };
00187 
00188 CMS_SERVER_LOCAL_PORT::~CMS_SERVER_LOCAL_PORT ()
00189 {
00190   if (NULL != orig_info)
00191     {
00192       delete orig_info;
00193       orig_info = NULL;
00194     }
00195 }
00196 
00197 /* local_port function for reads */
00198 REMOTE_READ_REPLY *
00199 CMS_SERVER_LOCAL_PORT::reader (REMOTE_READ_REQUEST * _req)
00200 {
00201   return (NULL);
00202 }
00203 
00204 REMOTE_READ_REPLY *
00205 CMS_SERVER_LOCAL_PORT::blocking_read (REMOTE_READ_REQUEST * _req)
00206 {
00207   return (NULL);
00208 }
00209 
00210 /* local_port function for writes */
00211 REMOTE_WRITE_REPLY *
00212 CMS_SERVER_LOCAL_PORT::writer (REMOTE_WRITE_REQUEST * _req)
00213 {
00214   return (NULL);
00215 }
00216 
00217 
00218 REMOTE_SET_DIAG_INFO_REPLY *
00219 CMS_SERVER_LOCAL_PORT::set_diag_info (REMOTE_SET_DIAG_INFO_REQUEST * _req)
00220 {
00221   return (NULL);
00222 }
00223 
00224 REMOTE_GET_DIAG_INFO_REPLY *
00225 CMS_SERVER_LOCAL_PORT::get_diag_info (REMOTE_GET_DIAG_INFO_REQUEST * _req)
00226 {
00227   get_diag_info_reply.cdi = cms->get_diagnostics_info ();
00228   get_diag_info_reply.status = cms->status;
00229   return (&get_diag_info_reply);
00230 }
00231 
00232 REMOTE_GET_MSG_COUNT_REPLY *
00233 CMS_SERVER_LOCAL_PORT::get_msg_count (REMOTE_GET_DIAG_INFO_REQUEST * _req)
00234 {
00235   return (NULL);
00236 }
00237 
00238 void
00239 CMS_SERVER_LOCAL_PORT::reset_diag_info ()
00240 {
00241 }
00242 
00243 
00244 CMS_SERVER_REMOTE_PORT::CMS_SERVER_REMOTE_PORT (CMS_SERVER *
00245                                                 _cms_server_parent)
00246 {
00247   current_clients = 0;
00248   max_clients = 0;
00249   port_registered = 0;
00250   cms_server_parent = _cms_server_parent;
00251   connected_users = NULL;
00252   security_enabled = 0;
00253   confirm_write = 0;
00254   min_compatible_version = 0.0;
00255   current_user_info = NULL;
00256   running = 0;
00257   max_total_subdivisions = _cms_server_parent->max_total_subdivisions;
00258 }
00259 
00260 CMS_SERVER_REMOTE_PORT::~CMS_SERVER_REMOTE_PORT ()
00261 {
00262   if (NULL != connected_users)
00263     {
00264       CMS_USER_CONNECT_STRUCT *connected_user_struct =
00265         (CMS_USER_CONNECT_STRUCT *) connected_users->get_head ();
00266       while (NULL != connected_user_struct)
00267         {
00268           delete connected_user_struct;
00269           connected_user_struct = NULL;
00270           connected_users->delete_current_node ();
00271           connected_user_struct =
00272             (CMS_USER_CONNECT_STRUCT *) connected_users->get_next ();
00273         }
00274       delete connected_users;
00275     }
00276   current_connected_user_struct = NULL;
00277 }
00278 
00279 void
00280 CMS_SERVER_REMOTE_PORT::add_connected_user (int _fd)
00281 {
00282   current_connected_user_struct = NULL;
00283   rcs_print_debug (PRINT_SOCKET_CONNECT, "Adding connected user %d\n", _fd);
00284   CMS_USER_CONNECT_STRUCT *connected_user_struct =
00285     new CMS_USER_CONNECT_STRUCT ();
00286   if (NULL == connected_user_struct)
00287     {
00288       return;
00289     }
00290   connected_user_struct->fd = _fd;
00291   if (NULL == connected_users)
00292     {
00293       connected_users = new RCS_LINKED_LIST ();
00294     }
00295   if (NULL == connected_users)
00296     {
00297       return;
00298     }
00299   connected_users->store_at_tail (connected_user_struct,
00300                                   sizeof (connected_user_struct), 0);
00301   current_connected_user_struct = connected_user_struct;
00302   //delete connected_user_struct;
00303 }
00304 
00305 CMS_USER_INFO *
00306 CMS_SERVER_REMOTE_PORT::get_connected_user (int _fd)
00307 {
00308   current_connected_user_struct = NULL;
00309   if (NULL == connected_users)
00310     {
00311       connected_users = new RCS_LINKED_LIST ();
00312     }
00313   if (NULL == connected_users)
00314     {
00315       return NULL;
00316     }
00317   CMS_USER_CONNECT_STRUCT *connected_user_struct =
00318     (CMS_USER_CONNECT_STRUCT *) connected_users->get_head ();
00319   while (NULL != connected_user_struct)
00320     {
00321       if (connected_user_struct->fd == _fd)
00322         {
00323           current_connected_user_struct = connected_user_struct;
00324           return connected_user_struct->user_info;
00325         }
00326       connected_user_struct =
00327         (CMS_USER_CONNECT_STRUCT *) connected_users->get_next ();
00328     }
00329   add_connected_user (_fd);
00330   return NULL;
00331 }
00332 
00333 
00334 void
00335 CMS_SERVER_REMOTE_PORT::register_port ()
00336 {
00337   return;
00338 }
00339 
00340 void
00341 CMS_SERVER_REMOTE_PORT::unregister_port ()
00342 {
00343   return;
00344 }
00345 
00346 int
00347 CMS_SERVER_REMOTE_PORT::accept_local_port_cms (CMS * _cms)
00348 {
00349   if (NULL != _cms)
00350     {
00351       if (min_compatible_version < 1e-6 ||
00352           (min_compatible_version > _cms->min_compatible_version &&
00353            _cms->min_compatible_version > 1e-6))
00354         {
00355           min_compatible_version = _cms->min_compatible_version;
00356         }
00357     }
00358   if (_cms->total_subdivisions > max_total_subdivisions)
00359     {
00360       max_total_subdivisions = _cms->total_subdivisions;
00361     }
00362   return 1;
00363 }
00364 
00365 
00366 CMS_SERVER *
00367 CMS_SERVER_REMOTE_PORT::find_server (long _pid, long _tid /* =0 */ )
00368 {
00369   CMS_SERVER *cms_server;
00370 #ifdef VXWORKS
00371   if (NULL != cms_server_list_mutex)
00372     {
00373       semTake (cms_server_list_mutex, WAIT_FOREVER);
00374     }
00375   else
00376     {
00377       taskLock ();
00378     }
00379 #endif
00380 
00381   if (NULL == cms_server_list)
00382     {
00383       return NULL;
00384     }
00385 
00386   cms_server = (CMS_SERVER *) cms_server_list->get_head ();
00387   while (NULL != cms_server)
00388     {
00389 #ifdef WIN32
00390       if (cms_server->server_pid == ((DWORD) _pid)
00391           && cms_server->server_tid == ((DWORD) _tid))
00392 #else
00393       if (cms_server->server_pid == _pid && cms_server->server_tid == _tid)
00394 #endif
00395         {
00396           break;
00397         }
00398       cms_server = (CMS_SERVER *) cms_server_list->get_next ();
00399     }
00400 
00401 #ifdef VXWORKS
00402   if (NULL != cms_server_list_mutex)
00403     {
00404       semGive (cms_server_list_mutex);
00405     }
00406   else
00407     {
00408       taskUnlock ();
00409     }
00410 #endif
00411   return (cms_server);
00412 }
00413 
00414 void
00415 CMS_SERVER_REMOTE_PORT::print_servers ()
00416 {
00417   CMS_SERVER *cms_server;
00418 
00419   if (NULL == cms_server_list)
00420     {
00421       rcs_print ("cms_server_list is NULL.\n");
00422       return;
00423     }
00424 
00425   cms_server = (CMS_SERVER *) cms_server_list->get_head ();
00426   rcs_print ("Server Tasks for this remote port.\n");
00427   while (NULL != cms_server)
00428     {
00429       rcs_print (" \t(%d (0x%X), %d (0x%X))\n",
00430                  cms_server->server_pid, cms_server->server_pid,
00431                  cms_server->server_tid, cms_server->server_tid);
00432 
00433       cms_server = (CMS_SERVER *) cms_server_list->get_next ();
00434     }
00435 }
00436 
00437 #ifndef UNDER_CE
00438 
00439 void
00440 CMS_SERVER::read_passwd_file ()
00441 {
00442   using_passwd_file = 1;
00443   int user_name_length;
00444   int passwd_length;
00445   if (NULL == known_users)
00446     {
00447       known_users = new RCS_LINKED_LIST ();
00448     }
00449   srand ((int) ((2 ^ 32) * etime ()));
00450   char buf[256];
00451   INET_FILE *ifp = NULL;
00452   rcs_print ("Reading passwd file %s.\n", passwd_file);
00453   ifp = inet_file_open (passwd_file, "r");
00454   if (NULL == ifp)
00455     {
00456       rcs_print_error ("Can not open passwd file %s.\n", passwd_file);
00457       return;
00458     }
00459   CMS_USER_INFO *user_info = NULL;
00460 
00461   while (!inet_file_eof (ifp))
00462     {
00463       memset (buf, 0, 256);
00464       inet_file_gets (buf, 256, ifp);
00465       user_name_length = strcspn (buf, "\n\r \t:");
00466       if (user_name_length > 16)
00467         {
00468           rcs_print_error ("CMS_SERVER: user name is too long.\n");
00469           continue;
00470         }
00471       if (user_name_length < 2)
00472         {
00473           continue;
00474         }
00475       user_info = new CMS_USER_INFO ();
00476       if (NULL == user_info)
00477         {
00478           break;
00479         }
00480       strcpy (user_info->passwd_file_line, buf);
00481       memcpy (user_info->name, buf, user_name_length);
00482       passwd_length = strcspn (buf + user_name_length + 1, "\n\r \t:");
00483       if (passwd_length > 16)
00484         {
00485           rcs_print_error ("CMS_SERVER: password is too long.\n");
00486           continue;
00487         }
00488       if (passwd_length > 16)
00489         {
00490           rcs_print_error ("CMS_SERVER: password is too long.\n");
00491         }
00492       if (passwd_length > 2)
00493         {
00494           memcpy (user_info->passwd, buf + user_name_length + 1,
00495                   passwd_length);
00496           memcpy (user_info->key1, buf + user_name_length + 1, 2);
00497           user_info->has_passwd = 1;
00498         }
00499       else
00500         {
00501           user_info->has_passwd = 0;
00502         }
00503       gen_random_key (user_info->key2, 2);
00504       strcpy (user_info->epasswd,
00505               rcs_crypt (user_info->passwd, user_info->key2));
00506       user_info->allow_read = (NULL != strstr (buf, "read=true"));
00507       user_info->allow_write = (NULL != strstr (buf, "write=true"));
00508       user_info->user_number =
00509         known_users->store_at_tail (user_info, sizeof (user_info), 0);
00510       rcs_print ("Storing info for user (%s).\n", user_info->name);
00511       //delete user_info;
00512       if (!strcmp (user_info->name, "guest"))
00513         {
00514           guest_can_read = user_info->allow_read;
00515           guest_can_write = user_info->allow_write;
00516         }
00517       user_info = NULL;
00518     }
00519 }
00520 
00521 void
00522 CMS_SERVER::gen_random_key (char key[], int len)
00523 {
00524   for (int i = 0; i < len; i++)
00525     {
00526       while (!isgraph (key[i]) || !key[i])
00527         {
00528           key[i] = (char) ((rand () % 128));
00529         }
00530     }
00531 }
00532 
00533 CMS_USER_INFO *
00534 CMS_SERVER::find_user (const char *name)
00535 {
00536   if (NULL == known_users)
00537     {
00538       return NULL;
00539     }
00540   CMS_USER_INFO *user_info = (CMS_USER_INFO *) known_users->get_head ();
00541   while (NULL != user_info)
00542     {
00543       rcs_print ("CMS_SERVER::find_user: strcmp(%s,%s)\n", name,
00544                  user_info->name);
00545       if (!strcmp (name, user_info->name))
00546         {
00547           return user_info;
00548         }
00549       user_info = (CMS_USER_INFO *) known_users->get_next ();
00550     }
00551   rcs_print_error ("CMS_SERVER: Can't find entry for user %s.\n", name);
00552   return NULL;
00553 }
00554 
00555 int
00556 CMS_SERVER::get_user_keys (const char *name, char *key1, char *key2)
00557 {
00558   if (NULL == known_users)
00559     {
00560       gen_random_key (key1, 2);
00561       gen_random_key (key2, 2);
00562       return -1;
00563     }
00564   CMS_USER_INFO *user_info = find_user (name);
00565   if (NULL == user_info)
00566     {
00567       gen_random_key (key1, 2);
00568       gen_random_key (key2, 2);
00569       return -1;
00570     }
00571   strcpy (key1, user_info->key1);
00572   if (fabs (etime () - time_of_last_key_request) > 30.0)
00573     {
00574       memset (user_info->key2, 0, 8);
00575       memset (user_info->epasswd, 0, 16);
00576       gen_random_key (user_info->key2, 2);
00577       strcpy (user_info->epasswd,
00578               rcs_crypt (user_info->passwd, user_info->key2));
00579     }
00580   strcpy (key2, user_info->key2);
00581   time_of_last_key_request = etime ();
00582   return 0;
00583 }
00584 
00585 CMS_USER_INFO *
00586 CMS_SERVER::get_user_info (const char *name, const char *epasswd)
00587 {
00588   if (NULL == known_users)
00589     {
00590       return NULL;
00591     }
00592   CMS_USER_INFO *user_info = find_user (name);
00593   if (NULL == user_info)
00594     {
00595       return NULL;
00596     }
00597   if (!strcmp (user_info->epasswd, epasswd) || !user_info->has_passwd)
00598     {
00599       return user_info;
00600     }
00601   rcs_print_error ("CMS_SERVER: %s gave the wrong passwd.\n", name);
00602   rcs_print_error ("CMS_SERVER: user_info->passwd = %s\n", user_info->passwd);
00603   rcs_print_error ("CMS_SERVER: user_info->epasswd = %s\n",
00604                    user_info->epasswd);
00605   rcs_print_error ("CMS_SERVER: epasswd = %s\n", epasswd);
00606 
00607   return NULL;
00608 }
00609 
00610 #endif
00611 
00612 
00613 void
00614 CMS_SERVER::add_local_port (CMS_SERVER_LOCAL_PORT * _local_port)
00615 {
00616   if (NULL == _local_port)
00617     {
00618       rcs_print_error ("CMS_SERVER: Attempt to add NULL local port.\n");
00619       return;
00620     }
00621   if (NULL == _local_port->cms)
00622     {
00623       rcs_print_error
00624         ("CMS_SERVER: Attempt to add local port with NULL cms object.\n");
00625       return;
00626     }
00627   if (NULL == cms_local_ports)
00628     {
00629       rcs_print_error
00630         ("CMS_SERVER: Attempt to add local port when local ports list is NULL.\n");
00631       return;
00632     }
00633 
00634   if (NULL == remote_port)
00635     {
00636       switch (_local_port->cms->remote_port_type)
00637         {
00638 #ifndef NO_DCE_RPC
00639 #ifndef WIN32
00640         case CMS_RPC_REMOTE_PORT_TYPE:
00641           remote_port = new CMS_SERVER_REMOTE_RPC_PORT (this);
00642           break;
00643 #endif
00644 #endif
00645         case CMS_TCP_REMOTE_PORT_TYPE:
00646           remote_port = new CMS_SERVER_REMOTE_TCP_PORT (this);
00647           break;
00648 #ifndef UNDER_CE
00649         case CMS_STCP_REMOTE_PORT_TYPE:
00650           remote_port = new CMS_SERVER_REMOTE_STCP_PORT (this);
00651           break;
00652 #endif
00653 
00654 
00655 #if !defined(VXWORKS) && (!defined(__MSDOS__) || defined(WIN32)) && !defined(UNDER_CE) && !defined(DARWIN) && !defined(qnx)
00656         case CMS_TTY_REMOTE_PORT_TYPE:
00657           remote_port = new CMS_SERVER_REMOTE_TTY_PORT (this);
00658           break;
00659 #endif
00660 
00661         case CMS_UDP_REMOTE_PORT_TYPE:
00662           remote_port = new CMS_SERVER_REMOTE_UDP_PORT (this);
00663           break;
00664         default:
00665           rcs_print_error ("CMS_SERVER: Invalid remote port type. (%d)\n",
00666                            _local_port->cms->remote_port_type);
00667           return;
00668         }
00669     }
00670   if (NULL == remote_port)
00671     {
00672       rcs_print_error ("CMS_SERVER: couldn't create remote port object.\n");
00673       return;
00674     }
00675   if (!accept_local_port_cms (_local_port->cms))
00676     {
00677       rcs_print_error
00678         ("CMS_SERVER: Attempt to add local port failed because the port was of an incompatible type.\n");
00679     }
00680   char *passwd_eq = strstr (_local_port->cms->BufferLine, "passwd=");
00681   if (NULL != passwd_eq)
00682     {
00683 #ifndef UNDER_CE
00684       if (!using_passwd_file)
00685         {
00686           memset (passwd_file, 0, 256);
00687           for (int i = 0; i < 256 && passwd_eq[i + 7]; i++)
00688             {
00689               if (passwd_eq[i + 7] == ' ' || passwd_eq[i + 7] == '\t'
00690                   || passwd_eq[i + 7] == '\n' || passwd_eq[i + 7] == '\r')
00691                 {
00692                   break;
00693                 }
00694               passwd_file[i] = passwd_eq[i + 7];
00695             }
00696           if (strlen (passwd_file) > 0)
00697             {
00698               read_passwd_file ();
00699             }
00700         }
00701       _local_port->security_enabled = 1;
00702       remote_port->security_enabled = 1;
00703 #else
00704       rcs_print_error
00705         ("CMS_SVR: Passwd control not supported under Windows CE.\n");
00706 #endif
00707     }
00708 
00709 
00710   _local_port->list_id =
00711     cms_local_ports->store_at_tail (_local_port,
00712                                     sizeof (CMS_SERVER_LOCAL_PORT), 0);
00713   if (-1 == _local_port->list_id)
00714     {
00715       rcs_print_error
00716         ("CMS_SERVER: Can not store local port on linked list.\n");
00717     }
00718 }
00719 
00720 int
00721 CMS_SERVER::accept_local_port_cms (CMS * _cms)
00722 {
00723   if (NULL == remote_port || NULL == _cms)
00724     {
00725       return (0);
00726     }
00727 
00728   return (remote_port->accept_local_port_cms (_cms));
00729 }
00730 
00731 CMS_SERVER_LOCAL_PORT *
00732 CMS_SERVER::find_local_port (long _buffer_number)
00733 {
00734   CMS_SERVER_LOCAL_PORT *cms_local_port;
00735   cms_local_port = (CMS_SERVER_LOCAL_PORT *) cms_local_ports->get_head ();
00736   while (NULL != cms_local_port)
00737     {
00738       if (cms_local_port->buffer_number == _buffer_number)
00739         {
00740           break;
00741         }
00742       cms_local_port = (CMS_SERVER_LOCAL_PORT *) cms_local_ports->get_next ();
00743     }
00744   return (cms_local_port);
00745 }
00746 
00747 
00748 int
00749 CMS_SERVER::get_total_subdivisions (long _buffer_number)
00750 {
00751   CMS_SERVER_LOCAL_PORT *cms_local_port = find_local_port (_buffer_number);
00752   if (NULL == cms_local_port)
00753     {
00754       return 1;
00755     }
00756   if (NULL == cms_local_port->cms)
00757     {
00758       return 1;
00759     }
00760   return cms_local_port->cms->total_subdivisions;
00761 }
00762 
00763 
00764 void
00765 CMS_SERVER::set_diag_info (REMOTE_SET_DIAG_INFO_REQUEST * _diag_info)
00766 {
00767   diag_enabled = 1;
00768   CMS_SERVER_LOCAL_PORT *local_port =
00769     find_local_port (_diag_info->buffer_number);
00770   if (NULL == local_port)
00771     {
00772       rcs_print_error
00773         ("CMS_SERVER: Cannot find local port for buffer number %ld\n",
00774          _diag_info->buffer_number);
00775       return;
00776     }
00777   local_port->set_diag_info (_diag_info);
00778   last_local_port_used = local_port;
00779 }
00780 
00781 void
00782 CMS_SERVER::reset_diag_info (int buffer_number)
00783 {
00784   diag_enabled = 0;
00785   CMS_SERVER_LOCAL_PORT *local_port = find_local_port (buffer_number);
00786   if (NULL == local_port)
00787     {
00788       rcs_print_error
00789         ("CMS_SERVER: Cannot find local port for buffer number %ld\n",
00790          buffer_number);
00791       return;
00792     }
00793   local_port->reset_diag_info ();
00794   last_local_port_used = NULL;
00795 }
00796 
00797 
00798 REMOTE_CMS_REPLY *
00799 CMS_SERVER::process_request (REMOTE_CMS_REQUEST * _request)
00800 {
00801   CMS_SERVER_LOCAL_PORT *local_port;
00802 
00803   requests_processed++;
00804 
00805   request = _request;
00806   if (NULL == request)
00807     {
00808       rcs_print_error ("CMS_SERVER: Request is NULL.\n");
00809       return NULL;
00810     }
00811 
00812   local_port = find_local_port (request->buffer_number);
00813   last_local_port_used = local_port;
00814   if (NULL == local_port)
00815     {
00816       rcs_print_error
00817         ("CMS_SERVER: Cannot find local port for buffer number %ld\n",
00818          request->buffer_number);
00819       return (NULL);
00820     }
00821 
00822 #ifndef UNDER_CE
00823   if (!security_check
00824       (remote_port->current_user_info, request->buffer_number))
00825     {
00826       return NULL;
00827     }
00828 #endif
00829 
00830   local_port->cms->set_subdivision (_request->subdiv);
00831   _request->subdiv = 0;
00832 
00833   switch (request->type)
00834     {
00835     case REMOTE_CMS_GET_BUF_NAME_REQUEST_TYPE:
00836       {
00837         REMOTE_GET_BUF_NAME_REPLY *namereply = &local_port->namereply;
00838         const char *name = get_buffer_name (request->buffer_number);
00839         if (0 == name)
00840           {
00841             return NULL;
00842           }
00843         strncpy (namereply->name, name, 31);
00844         return namereply;
00845       }
00846 
00847     case REMOTE_CMS_READ_REQUEST_TYPE:
00848       return (local_port->reader ((REMOTE_READ_REQUEST *) request));
00849     case REMOTE_CMS_GET_DIAG_INFO_REQUEST_TYPE:
00850       return (local_port->get_diag_info
00851               ((REMOTE_GET_DIAG_INFO_REQUEST *) request));
00852     case REMOTE_CMS_BLOCKING_READ_REQUEST_TYPE:
00853       return (local_port->blocking_read ((REMOTE_READ_REQUEST *) request));
00854     case REMOTE_CMS_WRITE_REQUEST_TYPE:
00855       return (local_port->writer ((REMOTE_WRITE_REQUEST *) request));
00856     case REMOTE_CMS_CHECK_IF_READ_REQUEST_TYPE:
00857       if (NULL == local_port->cms)
00858         {
00859           rcs_print_error
00860             ("CMS_SERVER: cms object associated with local port is NULL.\n");
00861           return (NULL);
00862         }
00863       cir_reply.was_read = local_port->cms->check_if_read ();
00864       cir_reply.status = local_port->cms->status;
00865       return (&cir_reply);
00866 
00867     case REMOTE_CMS_CLEAR_REQUEST_TYPE:
00868       if (NULL == local_port->cms)
00869         {
00870           rcs_print_error
00871             ("CMS_SERVER: cms object associated with local port is NULL.\n");
00872           return (NULL);
00873         }
00874       local_port->cms->clear ();
00875       clear_reply_struct.status = local_port->cms->status;
00876       return (&clear_reply_struct);
00877 
00878 #ifndef UNDER_CE
00879     case REMOTE_CMS_GET_KEYS_REQUEST_TYPE:
00880       get_keys_reply = &perm_get_keys_reply;
00881       get_user_keys (
00882                      ((REMOTE_GET_KEYS_REQUEST *) request)->name,
00883                      get_keys_reply->key1, get_keys_reply->key2);
00884       return (&perm_get_keys_reply);
00885 
00886     case REMOTE_CMS_LOGIN_REQUEST_TYPE:
00887       login_reply = &perm_login_reply;
00888       if (NULL == remote_port->current_connected_user_struct)
00889         {
00890           login_reply->success = 0;
00891           return (&perm_login_reply);
00892         }
00893       remote_port->current_connected_user_struct->user_info =
00894         get_user_info (
00895                        ((REMOTE_LOGIN_REQUEST *) request)->name,
00896                        ((REMOTE_LOGIN_REQUEST *) request)->passwd);
00897       login_reply->success =
00898         (NULL != remote_port->current_connected_user_struct->user_info);
00899       if (login_reply->success)
00900         {
00901           rcs_print ("%s logged in.\n",
00902                      remote_port->current_connected_user_struct->user_info->
00903                      name);
00904         }
00905       return (&perm_login_reply);
00906 #endif
00907 
00908     case REMOTE_CMS_SET_SUBSCRIPTION_REQUEST_TYPE:
00909       set_subscription_reply = &perm_set_subscription_reply;
00910       set_subscription_reply->success = 1;
00911       return (&perm_set_subscription_reply);
00912 
00913     default:
00914       rcs_print_error ("CMS_SERVER: Invalid request type (%d)\n",
00915                        request->type);
00916       return (NULL);
00917     }
00918 }
00919 
00920 #if defined(WIN32) && !defined(gnuwin32)
00921 DWORD
00922 CMS_ServerRun (LPVOID svr)
00923 {
00924   if (NULL == svr)
00925     {
00926       return FALSE;
00927     }
00928   ((CMS_SERVER *) svr)->run ();
00929   return FALSE;
00930 }
00931 #endif
00932 
00933 /* Spawning Routine. */
00934 int
00935 CMS_SERVER::spawn ()
00936 {
00937   if (0 == server_spawned)
00938     {
00939       if (NULL != remote_port)
00940         {
00941           remote_port->running = 0;
00942         }
00943       server_spawned = 1;
00944 #if defined(WIN32) && !defined(gnuwin32) && defined(MULTITHREADED)
00945       server_pid = current_pid = spawner_pid = GetCurrentProcessId ();
00946       current_tid = spawner_tid = GetCurrentThreadId ();
00947       server_thread_handle = (HANDLE) _beginthread (
00948                                                     (void (__cdecl *)
00949                                                      (void *)) CMS_ServerRun,
00950                                                     0, (LPVOID) this);
00951       if (((int) server_thread_handle) < 0)
00952         {
00953           rcs_print_sys_error (ERRNO_ERROR_SOURCE, "CreateThread failed.");
00954           return -1;
00955         }
00956 #else
00957 #ifndef VXWORKS
00958       current_pid = spawner_pid = getpid ();
00959       if (0 == (server_pid = fork ()))
00960         {
00961           /* Child */
00962           run ();               /* This will only return if an error occurs. */
00963           clean (2);
00964           exit (-1);
00965         }
00966       else
00967         {
00968           /* Parent */
00969         }
00970 #else
00971       spawner_pid = taskIdSelf ();
00972       if (spawner_pid == creator_pid)
00973         {
00974           server_pid =
00975             taskSpawn (NULL, cms_server_task_priority, VX_FP_TASK,
00976                        cms_server_task_stack_size,
00977                        (FUNCPTR) (&CMS_SERVER::run), (int) this, 0, 0, 0, 0,
00978                        0, 0, 0, 0, 0);
00979         }
00980       else
00981         {
00982           spawner_pid = 0;
00983           return 0;
00984         }
00985 #endif
00986 #endif
00987       int waits = 0;
00988       while (waits < 20)
00989         {
00990           esleep (0.01);
00991           if (NULL == remote_port)
00992             {
00993               break;
00994             }
00995           if (remote_port->running)
00996             {
00997               break;
00998             }
00999           waits++;
01000         }
01001       return 1;
01002     }
01003   return 0;
01004 }
01005 
01006 void
01007 CMS_SERVER::kill_server ()
01008 {
01009 #ifdef VXWORKS
01010   current_pid = taskIdSelf ();
01011   if (current_pid != spawner_pid)
01012     {
01013       return;
01014     }
01015 #endif
01016   if (0 != server_pid)
01017     {
01018 #if defined(WIN32) && !defined(gnuwin32)
01019 #ifndef UNDER_CE
01020       if (server_pid != current_pid)
01021         {
01022           GenerateConsoleCtrlEvent (CTRL_C_EVENT, server_pid);
01023         }
01024 #else
01025       TerminateProcess ((HANDLE) server_pid, 0);
01026 #endif
01027 #else
01028       signal (SIGINT, SIG_DFL);
01029       cms_server_count--;
01030       kill (server_pid, SIGINT);
01031 #ifdef VXWORKS
01032       int count = 0;
01033       while (OK == taskIdVerify (server_pid) && count < 100)
01034         {
01035           taskDelay (1);
01036           count++;
01037         }
01038       if (OK == taskIdVerify (server_pid))
01039         {
01040           taskDelete (server_pid);
01041         }
01042 #else
01043       waitpid (server_pid, NULL, 0);
01044 #endif
01045 #endif
01046       server_pid = 0;
01047     }
01048 }
01049 
01050 
01051 
01052 /* MAIN ROUTINE */
01053 void
01054 CMS_SERVER::register_server (int setup_CC_signal_local_port)
01055 {
01056   last_local_port_used = NULL;
01057   server_registered = 1;
01058 #ifdef VXWORKS
01059   taskLock ();
01060   if (NULL == cms_server_list_mutex)
01061     {
01062       cms_server_list_mutex =
01063         semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
01064     }
01065 
01066   if (NULL == cms_server_list_mutex)
01067     {
01068       taskUnlock ();
01069       return;
01070     }
01071   int sem_take_succeeded = 0;
01072   if (OK == semTake (cms_server_list_mutex, NO_WAIT))
01073     {
01074       sem_take_succeeded = 1;
01075       taskUnlock ();
01076     }
01077 
01078 #endif
01079 
01080   if (NULL == cms_server_list)
01081     {
01082       cms_server_list = new RCS_LINKED_LIST;
01083     }
01084   list_id = cms_server_list->store_at_tail (this, sizeof (CMS_SERVER), 0);
01085 
01086 #ifdef VXWORKS
01087   if (sem_take_succeeded)
01088     {
01089       semGive (cms_server_list_mutex);
01090     }
01091   else
01092     {
01093       taskUnlock ();
01094     }
01095 #endif
01096 
01097 
01098   /* Set up interrupt local_port. */
01099   if (setup_CC_signal_local_port)
01100     {
01101 #ifndef UNDER_CE
01102 #if defined(WIN32) && !defined(gnuwin32)
01103       SetConsoleCtrlHandler ((PHANDLER_ROUTINE) clean, TRUE);
01104 #else
01105 #ifdef sparcworks_sun4
01106       signal (SIGINT, (void (*)(int,...)) clean);       /* Set up interrupt local_port. */
01107 #else
01108       signal (SIGINT, clean);   /* Set up interrupt local_port. */
01109 #endif
01110 #endif
01111 #endif
01112     }
01113 
01114   if (NULL == remote_port)
01115     {
01116       rcs_print_error ("CMS_SERVER: Can't register with NULL remote port.\n");
01117       return;
01118     }
01119   remote_port->register_port ();
01120 
01121 }
01122 
01123 
01124 void
01125 CMS_SERVER::run (int setup_CC_signal_local_port)
01126 {
01127 #if  defined(WIN32) && !defined(gnuwin32)
01128   server_pid = current_pid = GetCurrentProcessId ();
01129   server_tid = current_tid = GetCurrentThreadId ();
01130 #else
01131   server_tid = current_tid = 0;
01132 #ifdef VXWORKS
01133   server_pid = taskIdSelf ();
01134 #else
01135   current_pid = server_pid = getpid ();
01136 #endif
01137 #endif
01138   if (!server_registered)
01139     {
01140       register_server (setup_CC_signal_local_port);
01141     }
01142   initialize_write_request_space ();
01143   if (NULL == remote_port)
01144     {
01145       rcs_print_error
01146         ("CMS_SERVER: Cannot run with remote port equal to NULL.\n");
01147       return;
01148     }
01149   remote_port->running = 1;
01150   if (remote_port->port_registered)
01151     {
01152       remote_port->run ();
01153     }
01154 }
01155 
01156 void
01157 CMS_SERVER::initialize_write_request_space ()
01158 {
01159   max_total_subdivisions = 1;
01160   maximum_cms_size = 0;
01161   CMS_SERVER_LOCAL_PORT *local_port;
01162   if (NULL == cms_local_ports)
01163     {
01164       rcs_print_error
01165         ("CMS_SERVER: Can not search list of local ports to determine the size of space needed for the write request\n"
01166          "because the list is NULL.\n");
01167       return;
01168     }
01169   local_port = (CMS_SERVER_LOCAL_PORT *) cms_local_ports->get_head ();
01170   while (NULL != local_port)
01171     {
01172       if (NULL != local_port->cms)
01173         {
01174           if (local_port->cms->size > maximum_cms_size)
01175             {
01176               maximum_cms_size = local_port->cms->size;
01177             }
01178           if (local_port->cms->total_subdivisions > max_total_subdivisions)
01179             {
01180               max_total_subdivisions = local_port->cms->total_subdivisions;
01181             }
01182           if (NULL != remote_port)
01183             {
01184               if (local_port->cms->total_subdivisions >
01185                   remote_port->max_total_subdivisions)
01186                 {
01187                   remote_port->max_total_subdivisions =
01188                     local_port->cms->total_subdivisions;
01189                 }
01190             }
01191           if (local_port->cms->max_encoded_message_size > maximum_cms_size)
01192             {
01193               maximum_cms_size = local_port->cms->max_encoded_message_size;
01194             }
01195         }
01196       local_port = (CMS_SERVER_LOCAL_PORT *) cms_local_ports->get_next ();
01197     }
01198   if (NULL != write_req.data)
01199     {
01200 #ifdef sparcworks_sun4          /* free is defined as int free(char *)
01201                                    for this platform
01202                                    it should be void free(void *); */
01203       DEBUG_FREE ((char *) write_req.data);
01204 #else
01205       DEBUG_FREE (write_req.data);
01206 #endif
01207       write_req.data = NULL;
01208     }
01209   write_req.data = DEBUG_MALLOC (maximum_cms_size);
01210   if (NULL == write_req.data)
01211     {
01212       rcs_print_error ("malloc(%d) failed.\n", maximum_cms_size);
01213     }
01214   local_port = (CMS_SERVER_LOCAL_PORT *) cms_local_ports->get_head ();
01215   while (NULL != local_port)
01216     {
01217       if (NULL != local_port->cms)
01218         {
01219           local_port->cms->set_encoded_data (write_req.data,
01220                                              maximum_cms_size);
01221         }
01222       local_port = (CMS_SERVER_LOCAL_PORT *) cms_local_ports->get_next ();
01223     }
01224 }
01225 
01226 CMS_SERVER::CMS_SERVER ()
01227 {
01228   last_local_port_used = NULL;
01229   diag_enabled = 0;
01230   using_passwd_file = 0;
01231   current_pid = 0;
01232   server_pid = 0;
01233   spawner_pid = 0;
01234   server_registered = 0;
01235   guest_can_read = 0;
01236   guest_can_write = 0;
01237   server_spawned = 0;
01238   list_id = 0;
01239   requests_processed = 0;
01240   read_reply = NULL;
01241   write_reply = NULL;
01242   check_if_read_reply = NULL;
01243   clear_reply = NULL;
01244   remote_port = NULL;
01245   request = NULL;
01246   write_req.data = NULL;
01247   cms_local_ports = new RCS_LINKED_LIST;
01248   known_users = NULL;
01249   max_total_subdivisions = 1;
01250   memset (passwd_file, 0, 256);
01251 #if defined(WIN32) && !defined(gnuwin32)
01252   creator_pid = GetCurrentProcessId ();
01253   creator_tid = GetCurrentThreadId ();
01254 #else
01255 #ifndef VXWORKS
01256   creator_pid = getpid ();
01257 #else
01258   creator_pid = taskIdSelf ();
01259 #endif
01260 #endif
01261 
01262 }
01263 
01264 CMS_SERVER::~CMS_SERVER ()
01265 {
01266   last_local_port_used = NULL;
01267 #ifdef VXWORKS
01268   current_pid = taskIdSelf ();
01269 #endif
01270   if (server_registered && (!server_spawned || current_pid == server_pid))
01271     {
01272       unregister_server ();
01273     }
01274   else if (server_spawned && current_pid == spawner_pid)
01275     {
01276       kill_server ();
01277     }
01278   delete_all_local_ports ();
01279   if (NULL != remote_port)
01280     {
01281       delete remote_port;
01282       remote_port = NULL;
01283     }
01284   if (NULL != cms_local_ports)
01285     {
01286       delete cms_local_ports;
01287       cms_local_ports = NULL;
01288     }
01289 
01290   // Leave this to NML_SERVER destructor.
01291   // delete_from_list();
01292 
01293   if (NULL != write_req.data)
01294     {
01295 #ifdef sparcworks_sun4          /* free is defined as int free(char *)
01296                                    for this platform
01297                                    it should be void free(void *); */
01298       DEBUG_FREE ((char *) write_req.data);
01299 #else
01300       DEBUG_FREE (write_req.data);
01301 #endif
01302       write_req.data = NULL;
01303     }
01304 }
01305 
01306 void
01307 CMS_SERVER::delete_all_local_ports ()
01308 {
01309   if (NULL != cms_local_ports)
01310     {
01311       CMS_SERVER_LOCAL_PORT *local_port;
01312       local_port = (CMS_SERVER_LOCAL_PORT *) cms_local_ports->get_head ();
01313       while (NULL != local_port)
01314         {
01315           delete local_port;
01316           cms_local_ports->delete_current_node ();
01317           local_port = (CMS_SERVER_LOCAL_PORT *) cms_local_ports->get_next ();
01318         }
01319     }
01320 }
01321 
01322 static int last_cms_server_signum = 0;
01323 
01324 void
01325 CMS_SERVER::clean (int signum)
01326 {
01327   last_cms_server_signum = signum;
01328 #if defined(WIN32) && !defined(gnuwin32)
01329   DWORD current_pid = GetCurrentProcessId ();
01330   DWORD current_tid = GetCurrentThreadId ();
01331 #else
01332 #ifdef VXWORKS
01333   int current_pid;
01334   int current_tid = 0;
01335   current_pid = taskIdSelf ();
01336 #else
01337   pid_t current_pid;
01338   pid_t current_tid = 0;
01339   current_pid = getpid ();
01340 #endif
01341 #endif
01342   CMS_SERVER *cms_server = NULL;
01343 
01344 
01345 #ifdef VXWORKS
01346   if (NULL != cms_server_list_mutex)
01347     {
01348       semTake (cms_server_list_mutex, WAIT_FOREVER);
01349     }
01350   else
01351     {
01352       taskLock ();
01353     }
01354 #endif
01355   cms_server = (CMS_SERVER *) cms_server_list->get_head ();
01356   while (NULL != cms_server)
01357     {
01358       if (cms_server->server_pid == current_pid
01359           && cms_server->server_tid == current_tid)
01360         {
01361           cms_server->unregister_server ();
01362           delete cms_server;
01363           cms_server = NULL;
01364         }
01365       cms_server = (CMS_SERVER *) cms_server_list->get_next ();
01366     }
01367 
01368 #ifdef VXWORKS
01369   if (NULL != cms_server_list_mutex)
01370     {
01371       semGive (cms_server_list_mutex);
01372     }
01373   else
01374     {
01375       taskUnlock ();
01376     }
01377 #endif
01378 #ifndef UNDER_CE
01379   exit (0);
01380 #else
01381   ExitThread (0);
01382 #endif
01383 }
01384 
01385 void
01386 CMS_SERVER::unregister_server ()
01387 {
01388   if (server_registered)
01389     {
01390       server_registered = 0;
01391       if (NULL != remote_port)
01392         {
01393           remote_port->unregister_port ();
01394         }
01395     }
01396 }
01397 
01398 void
01399 CMS_SERVER::delete_from_list ()
01400 {
01401 #ifdef VXWORKS
01402   if (NULL != cms_server_list_mutex)
01403     {
01404       semTake (cms_server_list_mutex, WAIT_FOREVER);
01405     }
01406   else
01407     {
01408       taskLock ();
01409     }
01410 #endif
01411 
01412 #if defined(WIN32) && !defined(gnuwin32)
01413   current_pid = GetCurrentProcessId ();
01414   current_tid = GetCurrentThreadId ();
01415 #else
01416 #ifndef VXWORKS
01417   current_pid = getpid ();
01418   current_tid = 0;
01419 #else
01420   current_pid = taskIdSelf ();
01421   current_tid = 0;
01422 #endif
01423 #endif
01424 
01425   if (current_pid == server_pid && current_tid == server_tid)
01426     {
01427       if (NULL != cms_server_list && list_id > 0)
01428         {
01429           cms_server_list->delete_node (list_id);
01430           list_id = -1;
01431         }
01432     }
01433 
01434 #ifdef VXWORKS
01435   if (NULL != cms_server_list_mutex)
01436     {
01437       semGive (cms_server_list_mutex);
01438     }
01439   else
01440     {
01441       taskUnlock ();
01442     }
01443 #endif
01444 }
01445 
01446 const char *
01447 CMS_SERVER::get_buffer_name (int buffer_number)
01448 {
01449   CMS_SERVER_LOCAL_PORT *local_port;
01450   local_port = find_local_port (buffer_number);
01451   if (NULL == local_port)
01452     {
01453       return NULL;
01454     }
01455   return (const char *) local_port->cms->BufferName;
01456 }
01457 
01458 long
01459 CMS_SERVER::get_message_type ()
01460 {
01461   return -1;
01462   // I need to be overloaded.
01463 }
01464 
01465 int
01466 CMS_SERVER::get_access_type ()
01467 {
01468   if (NULL == request)
01469     {
01470       return -1;
01471     }
01472   return request->type;
01473 }
01474 
01475 
01476 #ifndef UNDER_CE
01477 int
01478 CMS_SERVER::security_check (CMS_USER_INFO * user_info, int buffer_number)
01479 {
01480   CMS_SERVER_LOCAL_PORT *local_port;
01481   local_port = find_local_port (buffer_number);
01482   if (!using_passwd_file)
01483     {
01484       return 1;
01485     }
01486   if (!local_port->security_enabled)
01487     {
01488       return 1;
01489     }
01490   if (request->type == REMOTE_CMS_GET_KEYS_REQUEST_TYPE ||
01491       request->type == REMOTE_CMS_LOGIN_REQUEST_TYPE)
01492     {
01493       return 1;
01494     }
01495 
01496 
01497   if (NULL == user_info)
01498     {
01499 
01500       if (guest_can_read && (request->type == REMOTE_CMS_READ_REQUEST_TYPE ||
01501                              request->type ==
01502                              REMOTE_CMS_SET_SUBSCRIPTION_REQUEST_TYPE))
01503         {
01504           return 1;
01505         }
01506 
01507       if (guest_can_write && request->type == REMOTE_CMS_WRITE_REQUEST_TYPE)
01508         {
01509           return 1;
01510         }
01511       rcs_print_error
01512         ("CMS_SERVER: Refusing to process request of unknown user.\n");
01513       return 0;
01514     }
01515 
01516   if (user_info->allow_read
01517       && (request->type == REMOTE_CMS_READ_REQUEST_TYPE
01518           || request->type == REMOTE_CMS_SET_SUBSCRIPTION_REQUEST_TYPE))
01519     {
01520       return 1;
01521     }
01522 
01523   if (user_info->allow_write
01524       && request->type == REMOTE_CMS_WRITE_REQUEST_TYPE)
01525     {
01526       return 1;
01527     }
01528 
01529   if (NULL != detailed_security_check)
01530     {
01531       return detailed_security_check (user_info->name,
01532                                       get_buffer_name (buffer_number),
01533                                       get_message_type (),
01534                                       get_access_type ());
01535     }
01536 
01537   if (!user_info->allow_read && request->type == REMOTE_CMS_READ_REQUEST_TYPE)
01538     {
01539       rcs_print_error ("CMS_SERVER:: %s does not have read permission.");
01540       return 0;
01541     }
01542 
01543   if (!user_info->allow_write
01544       && request->type == REMOTE_CMS_WRITE_REQUEST_TYPE)
01545     {
01546       rcs_print_error ("CMS_SERVER:: %s does not have write permission.");
01547       return 0;
01548     }
01549   return 1;
01550 
01551 }
01552 
01553 
01554 int (*detailed_security_check) (const char *user_name,
01555                                 const char *buffer_name,
01556                                 long msg_type, int access_type) = NULL;
01557 
01558 #endif

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