registrar.cpp

00001 /*   
00002  *   (c) Copyright 2008 Philipp Skadorov (philipp_s@users.sourceforge.net)
00003  *
00004  *   This file is part of FREESECS.
00005  *
00006  *   FREESECS is free software: you can redistribute it and/or modify
00007  *   it under the terms of the GNU General Public License as published by
00008  *   the Free Software Foundation, either version 3 of the License, or
00009  *   (at your option) any later version.
00010  *
00011  *   FREESECS is distributed in the hope that it will be useful,
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *   GNU General Public License for more details.
00015  *
00016  *   You should have received a copy of the GNU General Public License
00017  *   along with FREESECS, see COPYING.
00018  *   If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 #include <sys/stat.h>
00021 #include <sys/types.h>
00022 #include <sys/wait.h>
00023 #include <unistd.h>
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <errno.h>
00027 #include <fcntl.h>
00028 #include "log.h"
00029 #include "hsms_signums.h"
00030 #include "hsms_cnx.h"
00031 #include "hsms_factory.h"
00032 #include "hsmsd_interface.h"
00033 #include "user_agent.h"
00034 #include "registrar.h"
00035 
00036 #define REGISTRAR_LOG_LEVEL 20
00037 
00038 
00039 #define DIR_PERMS (S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH)
00040 #define FIFO_PERMS (S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
00041 
00042 using namespace freesecs;
00043 
00044 extern hsms_factory_t hsms_factory;
00045 
00046 hsmsd_client_registrar_t::hsmsd_client_registrar_t()
00047 {
00048     struct stat statbuf;
00049     pid_t childpid;
00050 
00051     if(0 == stat(HSMSD_FIFO_DIR, &statbuf))
00052     {
00053         if(-1 == (childpid = fork()))
00054         {
00055             TRACE_ERROR("HSMSD: failed to fork");
00056             throw;
00057         }
00058 
00059         if(0 == childpid) /*child node*/
00060         {
00061             execl("/bin/rm", "rm", "-rf", HSMSD_FIFO_DIR, NULL);
00062             exit(1);
00063         }
00064         
00065         if(childpid != wait(NULL)) /*parent node*/
00066         {
00067             TRACE_ERROR("HSMSD: failed to wait for child completion");
00068             throw;
00069         }
00070     }
00071 
00072     if(mkdir(HSMSD_FIFO_DIR, DIR_PERMS))
00073     {
00074             TRACE_ERROR("HSMSD: failed to create dir %s", HSMSD_FIFO_DIR);
00075             throw;
00076     }
00077     
00078     mode_t old_umask = umask(~FIFO_PERMS);
00079     
00080 
00081     if(-1 == mkfifo(HSMSD_REGISTER_FIFO_IN, FIFO_PERMS) && (errno != EEXIST))
00082     {
00083         umask(old_umask);
00084         TRACE_ERROR("HSMSD: failed to create registering FIFO %s", HSMSD_REGISTER_FIFO);
00085         throw;
00086     }
00087     if(-1 == mkfifo(HSMSD_REGISTER_FIFO_OUT, FIFO_PERMS) &&(errno != EEXIST))
00088     {
00089         umask(old_umask);
00090         TRACE_ERROR("HSMSD: failed to create registering FIFO %s", HSMSD_REGISTER_FIFO);
00091         throw;
00092     }
00093 
00094     umask(old_umask);
00095 
00096     if(-1 == (_fd_in = open(HSMSD_REGISTER_FIFO_IN, O_RDWR)))
00097     {
00098         TRACE_ERROR("HSMSD: failed to open registering FIFO %s", HSMSD_REGISTER_FIFO);
00099         throw;
00100     }
00101     if(-1 == (_fd_out = open(HSMSD_REGISTER_FIFO_OUT, O_RDWR)))
00102     {
00103         TRACE_ERROR("HSMSD: failed to open registering FIFO %s", HSMSD_REGISTER_FIFO);
00104         throw;
00105     }
00106 
00107     _ar = new async_reception_t(_fd_in, "hsms client registrar");
00108     _ar->data_recvd_signal.add_handler(this, &hsmsd_client_registrar_t::data_rcvd_handler);
00109     _ar->recv_error_signal.add_handler(this, &hsmsd_client_registrar_t::rcv_error_handler);
00110 
00111     TRACE_DEBUG(REGISTRAR_LOG_LEVEL, "HSMSD: start receiving from %s...", HSMSD_REGISTER_FIFO);
00112     _ar->start_recv(&register_req, sizeof(register_req));
00113 }
00114 
00115 hsmsd_client_registrar_t::~hsmsd_client_registrar_t()
00116 {
00117     _ar->stop_recv();
00118     close(_fd_in);
00119     close(_fd_out);
00120 }
00121 
00122 void
00123 hsmsd_client_registrar_t::process()
00124 {
00125     sleep(10);
00126 }
00127 
00128 int 
00129 hsmsd_client_registrar_t::data_rcvd_handler(const size_t& num_received)
00130 {
00131     TRACE_DEBUG(REGISTRAR_LOG_LEVEL, "HSMSD: received %d bytes from %s", num_received, HSMSD_REGISTER_FIFO);
00132     if(num_received == sizeof(register_req))
00133     {
00134         process_user_request();
00135     }
00136     else
00137     {
00138         TRACE_ERROR("HSMSD: received %d bytes from %s. Expected %d bytes.", 
00139                                     num_received, HSMSD_REGISTER_FIFO, sizeof(register_req));
00140     }
00141     _ar->start_recv(&register_req, sizeof(register_req));
00142     return 0;
00143 }
00144 
00145 int 
00146 hsmsd_client_registrar_t::rcv_error_handler(const int& err)
00147 {
00148     TRACE_DEBUG(REGISTRAR_LOG_LEVEL, "HSMSD: received err %d from %s", HSMSD_REGISTER_FIFO);
00149     return 0;
00150 }
00151 
00152 template<typename T>
00153 struct compare_name : public std::binary_function<T, const char*, bool>
00154 {
00155     bool operator()(const T &t, const char *name) const
00156     {
00157         return 0 == strcmp(t->name(), name);
00158     }
00159 };
00160 
00161 
00162 void 
00163 hsmsd_client_registrar_t::process_user_request()
00164 {   
00165     hsmsd_register_rsp_t register_rsp;
00166 
00167     char    client_fifo_name_ctl_in[128],
00168             client_fifo_name_ctl_out[128], 
00169             client_fifo_name_data_in[128],
00170             client_fifo_name_data_out[128];
00171 
00172     register_rsp.rsp_code = hsmsd_register_rsp_t::REG_OK;
00173     snprintf(client_fifo_name_ctl_in, sizeof(client_fifo_name_ctl_in), 
00174                       HSMSD_CLIENT_FIFO_CTL_IN_PATTERN, register_req.cli_pid, rand()&0xff);
00175     snprintf(client_fifo_name_ctl_out, sizeof(client_fifo_name_ctl_out), 
00176                       HSMSD_CLIENT_FIFO_CTL_OUT_PATTERN, register_req.cli_pid, rand()&0xff);
00177     snprintf(client_fifo_name_data_in, sizeof(client_fifo_name_data_in), 
00178                       HSMSD_CLIENT_FIFO_DATA_IN_PATTERN, register_req.cli_pid, rand()&0xff);
00179     snprintf(client_fifo_name_data_out, sizeof(client_fifo_name_data_out), 
00180                       HSMSD_CLIENT_FIFO_DATA_OUT_PATTERN, register_req.cli_pid, rand()&0xff);
00181 
00182 
00183     snprintf(register_rsp.pipe_name_ctl_req, 
00184                       sizeof(register_rsp.pipe_name_ctl_req), client_fifo_name_ctl_in);
00185     snprintf(register_rsp.pipe_name_ctl_rsp, 
00186                       sizeof(register_rsp.pipe_name_ctl_rsp), client_fifo_name_ctl_out);
00187     snprintf(register_rsp.pipe_name_data_req, 
00188                       sizeof(register_rsp.pipe_name_data_req), client_fifo_name_data_in);
00189     snprintf(register_rsp.pipe_name_data_rsp, 
00190                       sizeof(register_rsp.pipe_name_data_rsp), client_fifo_name_data_out);
00191 
00192 
00193     /*TODO: error check according to rsp codes*/
00194     TRACE_DEBUG(REGISTRAR_LOG_LEVEL, "HSMSD: number of active: %d, number of passive: %d", 
00195                       hsms_factory.active.size(), hsms_factory.passive.size());
00196 
00197     std::vector<hsms_factory_t::active_cnx_ptr_t>::iterator it_active =
00198                       find_if(hsms_factory.active.begin(), hsms_factory.active.end(), 
00199                                 std::bind2nd(compare_name<hsms_factory_t::active_cnx_ptr_t>(), 
00200                                 register_req.cnx_name));
00201 
00202     if(hsms_factory.active.end() != it_active)
00203     {
00204         _clients.push_back(pclient_t(new user_agent_t(client_fifo_name_ctl_in
00205                                                         ,client_fifo_name_ctl_out
00206                                                         ,client_fifo_name_data_in
00207                                                         ,client_fifo_name_data_out
00208                                                         ,*((user_agent_t::pcnx_t*)&*it_active))));
00209     }
00210     else
00211     {
00212         std::vector<hsms_factory_t::passive_cnx_ptr_t>::iterator it_passive =
00213                         find_if(hsms_factory.passive.begin(), hsms_factory.passive.end(), 
00214                                 std::bind2nd(compare_name<hsms_factory_t::passive_cnx_ptr_t>(), 
00215                                 register_req.cnx_name));
00216 
00217         if(hsms_factory.passive.end() != it_passive)
00218         {
00219             _clients.push_back(pclient_t(new user_agent_t(client_fifo_name_ctl_in
00220                                                             ,client_fifo_name_ctl_out
00221                                                             ,client_fifo_name_data_in
00222                                                             ,client_fifo_name_data_out
00223                                                             ,*((user_agent_t::pcnx_t*)&*it_passive))));
00224         }
00225         else
00226         {
00227             TRACE_ERROR("HSMSD: process_user_request: invalid cnx name: %s", register_req.cnx_name);
00228             register_rsp.rsp_code = hsmsd_register_rsp_t::REG_INVALID_NAME;
00229         }
00230     }
00231     if(sizeof(register_rsp) != write(_fd_out, &register_rsp, sizeof(register_rsp)))
00232     {
00233         TRACE_ERROR("HSMSD: process_user_request: error responding to register request");
00234     }
00235 }

Generated on Fri Oct 3 15:30:01 2008 for FREESECS hsms by  doxygen 1.5.1