LCOV - code coverage report
Current view: top level - progs - mserver.cxx (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 551 0
Test Date: 2025-11-11 10:26:08 Functions: 0.0 % 4 0

            Line data    Source code
       1              : /********************************************************************\
       2              : 
       3              :   Name:         mserver.c
       4              :   Created by:   Stefan Ritt
       5              : 
       6              :   Contents:     Server program for midas RPC calls
       7              : 
       8              :   $Id$
       9              : 
      10              : \********************************************************************/
      11              : 
      12              : #undef NDEBUG // midas required assert() to be always enabled
      13              : 
      14              : #include "midas.h"
      15              : #include "msystem.h"
      16              : #include "mstrlcpy.h"
      17              : 
      18              : #ifdef OS_UNIX
      19              : #include <sys/types.h>
      20              : #endif
      21              : 
      22              : struct callback_addr callback;
      23              : 
      24              : BOOL use_callback_addr = TRUE;
      25              : 
      26              : INT rpc_server_dispatch(INT index, void *prpc_param[]);
      27              : 
      28              : /*---- debug_print -------------------------------------------------*/
      29              : 
      30            0 : void debug_print(const char *msg)
      31              : {
      32            0 :    std::string file_name;
      33            0 :    static std::string client_name;
      34              :    static DWORD start_time = 0;
      35              : 
      36            0 :    if (!start_time)
      37            0 :       start_time = ss_millitime();
      38              : 
      39              :    /* print message to file */
      40              : #ifdef OS_LINUX
      41            0 :    file_name = "/tmp/mserver.log";
      42              : #else
      43              :    file_name = ss_getcwd();
      44              :    if (!ends_with_char(file_name, DIR_SEPARATOR)) {
      45              :       file_name += DIR_SEPARATOR_STRING;
      46              :    }
      47              :    file_name += "mserver.log";
      48              : #endif
      49              : 
      50            0 :    FILE *f = fopen(file_name.c_str(), "a");
      51              : 
      52            0 :    if (!f) {
      53            0 :       fprintf(stderr, "Cannot open \"%s\", errno %d (%s)\n", file_name.c_str(), errno, strerror(errno));
      54            0 :       return;
      55              :    }
      56              : 
      57            0 :    if (client_name.empty())
      58            0 :       client_name = cm_get_client_name();
      59              : 
      60            0 :    std::string str = msprintf("%10.3lf [%d,%s,%s] ", (ss_millitime() - start_time) / 1000.0,
      61            0 :            ss_getpid(), callback.host_name.c_str(), client_name.c_str());
      62            0 :    str += msg;
      63            0 :    str += "\n";
      64              : 
      65            0 :    fputs(str.c_str(), f);
      66            0 :    fclose(f);
      67            0 : }
      68              : 
      69              : /*---- main --------------------------------------------------------*/
      70              : 
      71            0 : int main(int argc, char **argv)
      72              : /********************************************************************\
      73              : 
      74              :   Routine: main (server.exe)
      75              : 
      76              :   Purpose: Main routine for MIDAS server process. If called one
      77              :            parameter, it listens for a connection under
      78              :            MIDAS_TCP_PORT. If a connection is requested, the action
      79              :            depends on the parameter:
      80              : 
      81              :            0: Single process server: This process executes RPC calls
      82              :               even if there are several connections.
      83              : 
      84              :            1: Multi thread server (only Windows NT): For each conn-
      85              :               ection, a seperate thread is started which servers this
      86              :               connection.
      87              : 
      88              :            2: Multi process server (Not MS-DOS):  For each conn-
      89              :               ection, a seperate subprocess is started which servers 
      90              :               this connection. The subprocess is again server.exe, now
      91              :               with four parameters: the IP address of the calling 
      92              :               host, the two port numbers used by the calling
      93              :               host and optionally the name of the experiment to connect
      94              :               to. With this information it calles back the client.
      95              : 
      96              :            This technique is necessary since the usual fork() doesn't
      97              :            work on some of the supported systems.
      98              : 
      99              :   Input:
     100              :     int  argc               Number of parameters in command line
     101              :     char **argv             Command line parameters:
     102              : 
     103              :                             ip-addr     callback address as longword
     104              :                             port-no     port number
     105              :                             program     program name as string
     106              :                             experiment  experiment name as string
     107              : 
     108              : 
     109              :   Output:
     110              :     none
     111              : 
     112              :   Function value:
     113              :     BM_SUCCESS              Successful completion
     114              : 
     115              : \********************************************************************/
     116              : {
     117              :    int i, flag;
     118              :    socklen_t size;
     119              :    //char name[256];
     120              :    char str[1000];
     121              :    BOOL inetd, daemon, debug;
     122              : 
     123              : #if defined(SIGPIPE) && defined(SIG_IGN)
     124            0 :    signal(SIGPIPE, SIG_IGN);
     125              : #endif
     126              : 
     127            0 :    setbuf(stdout, NULL);
     128            0 :    setbuf(stderr, NULL);
     129              : 
     130              :    ///* save executable file name */
     131              :    //if (argv[0] == NULL || argv[0][0] == 0)
     132              :    //  mstrlcpy(name, "mserver", sizeof(name));
     133              :    //else
     134              :    //  mstrlcpy(name, argv[0], sizeof(name));
     135              : 
     136              : #ifdef OS_UNIX
     137              :    ///* if no full path given, assume /usr/local/bin */
     138              :    //if (strchr(name, '/') == 0) {
     139              :    //   mstrlcpy(str, "/usr/local/bin/", sizeof(str));
     140              :    //   mstrlcat(str, name, sizeof(str));
     141              :    //   mstrlcpy(name, str, sizeof(name));
     142              :    //}
     143              : #endif
     144              : 
     145              : #if 0
     146              :    printf("mserver main, name [%s]\n", name);
     147              :    for (i=0; i<=argc; i++)
     148              :       printf("argv[%d] is [%s]\n", i, argv[i]);
     149              :    system("/bin/ls -la /proc/self/fd");
     150              : #endif
     151              : 
     152            0 :    if (getenv("MIDAS_MSERVER_DO_NOT_USE_CALLBACK_ADDR"))
     153            0 :       use_callback_addr = FALSE;
     154              : 
     155              :    //rpc_set_mserver_path(name);
     156              : 
     157              :    /* find out if we were started by inetd */
     158            0 :    size = sizeof(int);
     159            0 :    inetd = (getsockopt(0, SOL_SOCKET, SO_TYPE, (void *) &flag, &size) == 0);
     160              : 
     161              :    /* check for debug flag */
     162            0 :    debug = FALSE;
     163            0 :    for (i = 1; i < argc; i++)
     164            0 :       if (argv[i][0] == '-' && argv[i][1] == 'd')
     165            0 :          debug = TRUE;
     166              : 
     167            0 :    if (debug) {
     168            0 :       debug_print("mserver startup");
     169            0 :       for (i = 0; i < argc; i++)
     170            0 :          debug_print(argv[i]);
     171            0 :       rpc_set_debug(debug_print, 1);
     172              :    }
     173              : 
     174            0 :    if (argc < 7 && inetd) {
     175              :       /* accept connection from stdin */
     176            0 :       rpc_server_accept(0);
     177            0 :       return 0;
     178              :    }
     179              : 
     180            0 :    if (!inetd && argc < 7)
     181            0 :       printf("%s started interactively\n", argv[0]);
     182              : 
     183            0 :    debug = daemon = FALSE;
     184              : 
     185            0 :    if (argc < 7 || argv[1][0] == '-') {
     186              :       int status;
     187              :       char expt_name[NAME_LENGTH];
     188            0 :       int port = 0;
     189              : 
     190              :       /* Get if existing the pre-defined experiment */
     191            0 :       expt_name[0] = 0;
     192            0 :       cm_get_environment(NULL, 0, expt_name, sizeof(expt_name));
     193              : 
     194              :       /* parse command line parameters */
     195            0 :       for (i = 1; i < argc; i++) {
     196            0 :          if (strncmp(argv[i], "-e", 2) == 0) {
     197            0 :             mstrlcpy(expt_name, argv[++i], sizeof(expt_name));
     198            0 :          } else if (argv[i][0] == '-' && argv[i][1] == 'd')
     199            0 :             debug = TRUE;
     200            0 :          else if (argv[i][0] == '-' && argv[i][1] == 'D')
     201            0 :             daemon = TRUE;
     202            0 :          else if (argv[i][0] == '-' && argv[i][1] == 'p')
     203            0 :             port = strtoul(argv[++i], NULL, 0);
     204            0 :          else if (argv[i][0] == '-') {
     205            0 :             if (i + 1 >= argc || argv[i + 1][0] == '-')
     206            0 :                goto usage;
     207              :             else {
     208            0 :              usage:
     209            0 :                printf("usage: mserver [-e Experiment] [-s][-t][-m][-d][-p port]\n");
     210            0 :                printf("               -e    experiment to connect to\n");
     211            0 :                printf("               -m    Multi process server (default)\n");
     212            0 :                printf("               -p port Listen for connections on specifed tcp port. Default value is taken from ODB \"/Experiment/midas server port\"\n");
     213              : #ifdef OS_LINUX
     214            0 :                printf("               -D    Become a daemon\n");
     215            0 :                printf("               -d    Write debug info to stdout or to \"/tmp/mserver.log\"\n\n");
     216              : #else
     217              :                printf("               -d    Write debug info\"\n\n");
     218              : #endif
     219            0 :                return 0;
     220              :             }
     221              :          }
     222              :       }
     223              : 
     224              :       /* turn on debugging */
     225            0 :       if (debug) {
     226            0 :          if (daemon || inetd)
     227            0 :             rpc_set_debug(debug_print, 1);
     228              :          else
     229            0 :             rpc_set_debug((void (*)(const char *)) puts, 1);
     230              : 
     231            0 :          sprintf(str, "Arguments: ");
     232            0 :          for (i = 0; i < argc; i++)
     233            0 :             sprintf(str + strlen(str), " %s", argv[i]);
     234            0 :          rpc_debug_printf(str);
     235              : 
     236            0 :          rpc_debug_printf("Debugging mode is on");
     237              :       }
     238              : 
     239              :       /* become a daemon */
     240            0 :       if (daemon) {
     241            0 :          printf("Becoming a daemon...\n");
     242            0 :          ss_daemon_init(FALSE);
     243              :       }
     244              : 
     245              :       /* connect to experiment */
     246            0 :       status = cm_connect_experiment(NULL, expt_name, "mserver", 0);
     247            0 :       if (status != CM_SUCCESS) {
     248            0 :          printf("cannot connect to experiment \"%s\", status %d\n", expt_name, status);
     249            0 :          exit(1);
     250              :       }
     251              :       
     252              :       HNDLE hDB;
     253              :       HNDLE hClient;
     254              : 
     255            0 :       status = cm_get_experiment_database(&hDB, &hClient);
     256            0 :       assert(status == CM_SUCCESS);
     257              :       
     258            0 :       int odb_port = MIDAS_TCP_PORT;
     259            0 :       int size = sizeof(odb_port);
     260              : 
     261            0 :       status = db_get_value(hDB, 0, "/Experiment/Midas server port", &odb_port, &size, TID_DWORD, TRUE);
     262            0 :       assert(status == DB_SUCCESS);
     263              : 
     264            0 :       if (port == 0)
     265            0 :          port = odb_port;
     266              :       
     267            0 :       if (port == 0)
     268            0 :          port = MIDAS_TCP_PORT;
     269              : 
     270            0 :       printf("mserver will listen on TCP port %d\n", port);
     271              : 
     272            0 :       int lsock = 0; // mserver main listener socket
     273            0 :       int lport = 0; // mserver listener port number
     274              : 
     275              :       /* register server */
     276            0 :       status = rpc_register_listener(port, rpc_server_dispatch, &lsock, &lport);
     277            0 :       if (status != RPC_SUCCESS) {
     278            0 :          printf("Cannot start server, rpc_register_server() status %d\n", status);
     279            0 :          return 1;
     280              :       }
     281              : 
     282              :       /* register path of mserver executable */
     283            0 :       rpc_set_mserver_path(argv[0]);
     284              : 
     285              :       /* register MIDAS library functions */
     286            0 :       rpc_register_functions(rpc_get_internal_list(1), rpc_server_dispatch);
     287              : 
     288            0 :       ss_suspend_set_server_listener(lsock);
     289              : 
     290              :       /* run forever */
     291              :       while (1) {
     292            0 :          status = cm_yield(1000);
     293              :          //printf("status %d\n", status);
     294            0 :          if (status == RPC_SHUTDOWN)
     295            0 :             break;
     296              :       }
     297              : 
     298            0 :       closesocket(lsock);
     299              : 
     300            0 :       cm_disconnect_experiment();
     301            0 :    } else {
     302              : 
     303              :       /* here we come if this program is started as a subprocess */
     304              : 
     305            0 :       callback.clear();
     306              : 
     307              :       /* extract callback arguments and start receiver */
     308              : #ifdef OS_VMS
     309              :       mstrlcpy(callback.host_name, argv[2], sizeof(callback.host_name));
     310              :       callback.host_port1 = atoi(argv[3]);
     311              :       callback.host_port2 = atoi(argv[4]);
     312              :       callback.host_port3 = atoi(argv[5]);
     313              :       callback.debug = atoi(argv[6]);
     314              :       if (argc > 7)
     315              :          mstrlcpy(callback.experiment, argv[7], sizeof(callback.experiment));
     316              :       if (argc > 8)
     317              :          mstrlcpy(callback.directory, argv[8], sizeof(callback.directory));
     318              :       if (argc > 9)
     319              :          mstrlcpy(callback.user, argv[9], sizeof(callback.user));
     320              : #else
     321            0 :       callback.host_name = argv[1];
     322            0 :       callback.host_port1 = atoi(argv[2]);
     323            0 :       callback.host_port2 = atoi(argv[3]);
     324            0 :       callback.host_port3 = atoi(argv[4]);
     325            0 :       callback.debug = atoi(argv[5]);
     326            0 :       if (argc > 6)
     327            0 :          callback.experiment = argv[6];
     328            0 :       if (argc > 7)
     329            0 :          callback.directory = argv[7];
     330            0 :       if (argc > 8)
     331            0 :          callback.user = argv[8];
     332              : #endif
     333              :       //callback.index = 0;
     334              : 
     335            0 :       if (callback.debug) {
     336            0 :          rpc_set_debug(debug_print, 1);
     337            0 :          if (callback.directory[0]) {
     338            0 :             if (callback.user[0])
     339            0 :                rpc_debug_printf("Start subprocess in %s under user %s", callback.directory.c_str(), callback.user.c_str());
     340              :             else
     341            0 :                rpc_debug_printf("Start subprocess in %s", callback.directory.c_str());
     342              : 
     343              :          } else
     344            0 :             rpc_debug_printf("Start subprocess in current directory");
     345              :       }
     346              : 
     347              :       /* change the directory and uid */
     348            0 :       if (callback.directory.length() > 0)
     349            0 :          if (chdir(callback.directory.c_str()) != 0)
     350            0 :             rpc_debug_printf("Cannot change to directory \"%s\"", callback.directory.c_str());
     351              : 
     352            0 :       cm_msg_early_init();
     353              : 
     354              :       /* set the experiment name and expt path name */
     355              : 
     356            0 :       if (callback.directory.length() > 0)
     357            0 :          cm_set_path(callback.directory.c_str());
     358              :       
     359            0 :       if (callback.experiment.length() > 0)
     360            0 :          cm_set_experiment_name(callback.experiment.c_str());
     361              : 
     362              :       /* must be done after cm_set_path() */
     363            0 :       ss_suspend_init_odb_port();
     364              : 
     365              :       /* register system functions */
     366            0 :       rpc_register_functions(rpc_get_internal_list(0), rpc_server_dispatch);
     367              : 
     368              :       /* register MIDAS library functions */
     369            0 :       rpc_register_functions(rpc_get_internal_list(1), rpc_server_dispatch);
     370              : 
     371            0 :       int status = rpc_server_callback(&callback);
     372              :       
     373            0 :       if (status != RPC_SUCCESS) {
     374            0 :          cm_msg_flush_buffer();
     375            0 :          printf("Cannot start mserver, rpc_server_callback() status %d\n", status);
     376            0 :          return 1;
     377              :       }
     378              :       
     379              :       /* create alarm and elog semaphores */
     380              :       int semaphore_alarm, semaphore_elog, semaphore_history, semaphore_msg;
     381            0 :       ss_semaphore_create("ALARM", &semaphore_alarm);
     382            0 :       ss_semaphore_create("ELOG", &semaphore_elog);
     383            0 :       ss_semaphore_create("HISTORY", &semaphore_history);
     384            0 :       ss_semaphore_create("MSG", &semaphore_msg);
     385            0 :       cm_set_experiment_semaphore(semaphore_alarm, semaphore_elog, semaphore_history, semaphore_msg);
     386              : 
     387            0 :       rpc_server_loop();
     388            0 :       rpc_server_shutdown();
     389              : 
     390            0 :       ss_suspend_exit();
     391              :    }
     392              : 
     393            0 :    return 0;
     394              : }
     395              : 
     396              : /*------------------------------------------------------------------*/
     397              : 
     398              : /* just a small test routine which doubles numbers */
     399            0 : INT rpc_test(BYTE b, WORD w, INT i, float f, double d, BYTE * b1, WORD * w1, INT * i1, float *f1, double *d1)
     400              : {
     401            0 :    printf("rpc_test: %d %d %d %1.1f %1.1lf\n", b, w, i, f, d);
     402              : 
     403            0 :    *b1 = b * 2;
     404            0 :    *w1 = w * 2;
     405            0 :    *i1 = i * 2;
     406            0 :    *f1 = f * 2;
     407            0 :    *d1 = d * 2;
     408              : 
     409            0 :    return 1;
     410              : }
     411              : 
     412              : /*----- rpc_server_dispatch ----------------------------------------*/
     413              : 
     414            0 : INT rpc_server_dispatch(INT index, void *prpc_param[])
     415              : /********************************************************************\
     416              : 
     417              :   Routine: rpc_server_dispatch
     418              : 
     419              :   Purpose: This routine gets registered as the callback function
     420              :            for all RPC calls via rpc_server_register. It acts as a
     421              :            stub to call the local midas subroutines. It uses the
     422              :            Cxxx(i) macros to cast parameters in prpc_param to
     423              :            their appropriate types.
     424              : 
     425              :   Input:
     426              :     int    index            RPC index defined in RPC.H
     427              :     void   *prpc_param      pointer to rpc parameter array
     428              : 
     429              :   Output:
     430              :     none
     431              : 
     432              :   Function value:
     433              :     status                  status returned from local midas function
     434              : 
     435              : \********************************************************************/
     436              : {
     437            0 :    INT status = 0;
     438              : 
     439            0 :    int convert_flags = rpc_get_convert_flags();
     440              : 
     441            0 :    switch (index) {
     442              :       /* common functions */
     443              : 
     444            0 :    case RPC_CM_SET_CLIENT_INFO:
     445            0 :       status = cm_set_client_info(CHNDLE(0), CPHNDLE(1), (use_callback_addr?callback.host_name.c_str():CSTRING(2)),
     446            0 :                                   CSTRING(3), CINT(4), CSTRING(5), CINT(6));
     447            0 :       break;
     448              : 
     449            0 :    case RPC_CM_CHECK_CLIENT:
     450            0 :       status = cm_check_client(CHNDLE(0), CHNDLE(1));
     451            0 :       break;
     452              : 
     453            0 :    case RPC_CM_SET_WATCHDOG_PARAMS:
     454            0 :       status = cm_set_watchdog_params(CBOOL(0), CINT(1));
     455            0 :       break;
     456              : 
     457            0 :    case RPC_CM_CLEANUP:
     458            0 :       status = cm_cleanup(CSTRING(0), CBOOL(1));
     459            0 :       break;
     460              : 
     461            0 :    case RPC_CM_GET_WATCHDOG_INFO:
     462            0 :       status = cm_get_watchdog_info(CHNDLE(0), CSTRING(1), CPDWORD(2), CPDWORD(3));
     463            0 :       break;
     464              : 
     465            0 :    case RPC_CM_MSG:
     466            0 :       status = cm_msg(CINT(0), CSTRING(1), CINT(2), CSTRING(3), "%s", CSTRING(4));
     467            0 :       break;
     468              : 
     469            0 :    case RPC_CM_MSG_LOG:
     470            0 :       status = cm_msg_log(CINT(0), CSTRING(1), CSTRING(2));
     471            0 :       break;
     472              : 
     473            0 :    case RPC_CM_EXECUTE:
     474            0 :       status = cm_execute(CSTRING(0), CSTRING(1), CINT(2));
     475            0 :       break;
     476              : 
     477            0 :    case RPC_CM_EXIST:
     478            0 :       status = cm_exist(CSTRING(0), CBOOL(1));
     479            0 :       break;
     480              : 
     481            0 :    case RPC_CM_SYNCHRONIZE:
     482            0 :       status = cm_synchronize(CPDWORD(0));
     483            0 :       break;
     484              : 
     485            0 :    case RPC_CM_ASCTIME: {
     486            0 :       std::string now = cm_asctime();
     487            0 :       mstrlcpy(CSTRING(0), now.c_str(), CINT(1));
     488            0 :       status = CM_SUCCESS;
     489            0 :       break;
     490            0 :    }
     491              : 
     492            0 :    case RPC_CM_TIME:
     493            0 :       status = cm_time(CPDWORD(0));
     494            0 :       break;
     495              : 
     496            0 :    case RPC_CM_MSG_RETRIEVE:
     497            0 :       status = cm_msg_retrieve(CINT(0), CSTRING(1), CINT(2));
     498            0 :       break;
     499              : 
     500              :       /* buffer manager functions */
     501              : 
     502            0 :    case RPC_BM_OPEN_BUFFER:
     503            0 :       status = bm_open_buffer(CSTRING(0), CINT(1), CPINT(2));
     504            0 :       break;
     505              : 
     506            0 :    case RPC_BM_CLOSE_BUFFER:
     507              :       //printf("RPC_BM_CLOSE_BUFFER(%d)!\n", CINT(0));
     508            0 :       status = bm_close_buffer(CINT(0));
     509            0 :       break;
     510              : 
     511            0 :    case RPC_BM_CLOSE_ALL_BUFFERS:
     512              :       //printf("RPC_BM_CLOSE_ALL_BUFFERS!\n");
     513            0 :       status = bm_close_all_buffers();
     514            0 :       break;
     515              : 
     516            0 :    case RPC_BM_GET_BUFFER_INFO:
     517            0 :       status = bm_get_buffer_info(CINT(0), (BUFFER_HEADER*)CARRAY(1));
     518            0 :       if (convert_flags) {
     519              :          BUFFER_HEADER *pb;
     520              : 
     521              :          /* convert event header */
     522            0 :          pb = (BUFFER_HEADER *) CARRAY(1);
     523            0 :          rpc_convert_single(&pb->num_clients, TID_INT, RPC_OUTGOING, convert_flags);
     524            0 :          rpc_convert_single(&pb->max_client_index, TID_INT, RPC_OUTGOING, convert_flags);
     525            0 :          rpc_convert_single(&pb->size, TID_INT, RPC_OUTGOING, convert_flags);
     526            0 :          rpc_convert_single(&pb->read_pointer, TID_INT, RPC_OUTGOING, convert_flags);
     527            0 :          rpc_convert_single(&pb->write_pointer, TID_INT, RPC_OUTGOING, convert_flags);
     528            0 :          rpc_convert_single(&pb->num_in_events, TID_INT, RPC_OUTGOING, convert_flags);
     529            0 :          rpc_convert_single(&pb->num_out_events, TID_INT, RPC_OUTGOING, convert_flags);
     530              :       }
     531            0 :       break;
     532              : 
     533            0 :    case RPC_BM_GET_BUFFER_LEVEL:
     534            0 :       status = bm_get_buffer_level(CINT(0), CPINT(1));
     535            0 :       break;
     536              : 
     537            0 :    case RPC_BM_INIT_BUFFER_COUNTERS:
     538            0 :       status = bm_init_buffer_counters(CINT(0));
     539            0 :       break;
     540              : 
     541            0 :    case RPC_BM_SET_CACHE_SIZE:
     542            0 :       status = bm_set_cache_size(CINT(0), CINT(1), CINT(2));
     543            0 :       break;
     544              : 
     545            0 :    case RPC_BM_ADD_EVENT_REQUEST:
     546            0 :       status = bm_add_event_request(CINT(0), CSHORT(1),
     547            0 :                                     CSHORT(2), CINT(3), (void (*)(HNDLE, HNDLE, EVENT_HEADER *, void *))
     548            0 :                                     (POINTER_T)
     549            0 :                                     CINT(4), CINT(5));
     550            0 :       break;
     551              : 
     552            0 :    case RPC_BM_REMOVE_EVENT_REQUEST:
     553            0 :       status = bm_remove_event_request(CINT(0), CINT(1));
     554            0 :       break;
     555              : 
     556            0 :    case RPC_BM_SEND_EVENT:
     557            0 :       if (convert_flags) {
     558              :          EVENT_HEADER *pevent;
     559              : 
     560              :          /* convert event header */
     561            0 :          pevent = (EVENT_HEADER *) CARRAY(1);
     562            0 :          rpc_convert_single(&pevent->event_id, TID_SHORT, 0, convert_flags);
     563            0 :          rpc_convert_single(&pevent->trigger_mask, TID_SHORT, 0, convert_flags);
     564            0 :          rpc_convert_single(&pevent->serial_number, TID_DWORD, 0, convert_flags);
     565            0 :          rpc_convert_single(&pevent->time_stamp, TID_DWORD, 0, convert_flags);
     566            0 :          rpc_convert_single(&pevent->data_size, TID_DWORD, 0, convert_flags);
     567              :       }
     568              : 
     569            0 :       status = bm_send_event(CINT(0), (const EVENT_HEADER*)(CARRAY(1)), CINT(2), CINT(3));
     570            0 :       break;
     571              : 
     572            0 :    case RPC_BM_RECEIVE_EVENT:
     573            0 :       status = bm_receive_event(CINT(0), CARRAY(1), CPINT(2), CINT(3));
     574            0 :       break;
     575              : 
     576            0 :    case RPC_BM_SKIP_EVENT:
     577            0 :       status = bm_skip_event(CINT(0));
     578            0 :       break;
     579              : 
     580            0 :    case RPC_BM_FLUSH_CACHE:
     581              :       //printf("RPC_BM_FLUSH_CACHE(%d,%d)!\n", CINT(0), CINT(1));
     582            0 :       if (CINT(0) == 0) {
     583            0 :          status = rpc_flush_event_socket(CINT(1));
     584              :       } else {
     585            0 :          status = bm_flush_cache(CINT(0), CINT(1));
     586              :       }
     587            0 :       break;
     588              : 
     589            0 :    case RPC_BM_MARK_READ_WAITING:
     590            0 :       status = BM_SUCCESS;
     591            0 :       break;
     592              : 
     593            0 :    case RPC_BM_EMPTY_BUFFERS:
     594            0 :       status = bm_empty_buffers();
     595            0 :       break;
     596              : 
     597              :       /* database functions */
     598              : 
     599            0 :    case RPC_DB_OPEN_DATABASE:
     600            0 :       status = db_open_database(CSTRING(0), CINT(1), CPHNDLE(2), CSTRING(3));
     601            0 :       break;
     602              : 
     603            0 :    case RPC_DB_CLOSE_DATABASE:
     604            0 :       status = db_close_database(CINT(0));
     605            0 :       break;
     606              : 
     607            0 :    case RPC_DB_FLUSH_DATABASE:
     608            0 :       status = db_flush_database(CINT(0));
     609            0 :       break;
     610              : 
     611            0 :    case RPC_DB_CLOSE_ALL_DATABASES:
     612            0 :       status = db_close_all_databases();
     613            0 :       break;
     614              : 
     615            0 :    case RPC_DB_CREATE_KEY:
     616            0 :       status = db_create_key(CHNDLE(0), CHNDLE(1), CSTRING(2), CDWORD(3));
     617            0 :       break;
     618              : 
     619            0 :    case RPC_DB_CREATE_LINK:
     620            0 :       status = db_create_link(CHNDLE(0), CHNDLE(1), CSTRING(2), CSTRING(3));
     621            0 :       break;
     622              : 
     623            0 :    case RPC_DB_SET_VALUE:
     624            0 :       rpc_convert_data(CARRAY(3), CDWORD(6), RPC_FIXARRAY, CINT(4), convert_flags);
     625            0 :       status = db_set_value(CHNDLE(0), CHNDLE(1), CSTRING(2), CARRAY(3), CINT(4), CINT(5), CDWORD(6));
     626            0 :       break;
     627              : 
     628            0 :    case RPC_DB_GET_VALUE:
     629            0 :       rpc_convert_data(CARRAY(3), CDWORD(5), RPC_FIXARRAY, CINT(4), convert_flags);
     630            0 :       status = db_get_value(CHNDLE(0), CHNDLE(1), CSTRING(2), CARRAY(3), CPINT(4), CDWORD(5), CBOOL(6));
     631            0 :       rpc_convert_data(CARRAY(3), CDWORD(5), RPC_FIXARRAY | RPC_OUTGOING, CINT(4), convert_flags);
     632            0 :       break;
     633              : 
     634            0 :    case RPC_DB_FIND_KEY:
     635            0 :       status = db_find_key(CHNDLE(0), CHNDLE(1), CSTRING(2), CPHNDLE(3));
     636            0 :       break;
     637              : 
     638            0 :    case RPC_DB_FIND_LINK:
     639            0 :       status = db_find_link(CHNDLE(0), CHNDLE(1), CSTRING(2), CPHNDLE(3));
     640            0 :       break;
     641              : 
     642            0 :    case RPC_DB_GET_PATH: {
     643            0 :       std::string path = db_get_path(CHNDLE(0), CHNDLE(1));
     644            0 :       mstrlcpy(CSTRING(2), path.c_str(), CINT(3));
     645            0 :       status = DB_SUCCESS;
     646            0 :       break;
     647            0 :    }
     648              : 
     649            0 :    case RPC_DB_GET_PARENT:
     650            0 :       status = db_get_parent(CHNDLE(0), CHNDLE(1), CPHNDLE(2));
     651            0 :       break;
     652              : 
     653            0 :    case RPC_DB_DELETE_KEY:
     654            0 :       status = db_delete_key(CHNDLE(0), CHNDLE(1), CBOOL(2));
     655            0 :       break;
     656              : 
     657            0 :    case RPC_DB_ENUM_KEY:
     658            0 :       status = db_enum_key(CHNDLE(0), CHNDLE(1), CINT(2), CPHNDLE(3));
     659            0 :       break;
     660              : 
     661            0 :    case RPC_DB_ENUM_LINK:
     662            0 :       status = db_enum_link(CHNDLE(0), CHNDLE(1), CINT(2), CPHNDLE(3));
     663            0 :       break;
     664              : 
     665            0 :    case RPC_DB_GET_NEXT_LINK:
     666            0 :       status = db_get_next_link(CHNDLE(0), CHNDLE(1), CPHNDLE(2));
     667            0 :       break;
     668              : 
     669            0 :    case RPC_DB_GET_KEY:
     670            0 :       status = db_get_key(CHNDLE(0), CHNDLE(1), (KEY*)CARRAY(2));
     671            0 :       if (convert_flags) {
     672              :          KEY *pkey;
     673              : 
     674            0 :          pkey = (KEY *) CARRAY(2);
     675            0 :          rpc_convert_single(&pkey->type, TID_DWORD, RPC_OUTGOING, convert_flags);
     676            0 :          rpc_convert_single(&pkey->num_values, TID_INT, RPC_OUTGOING, convert_flags);
     677            0 :          rpc_convert_single(&pkey->data, TID_INT, RPC_OUTGOING, convert_flags);
     678            0 :          rpc_convert_single(&pkey->total_size, TID_INT, RPC_OUTGOING, convert_flags);
     679            0 :          rpc_convert_single(&pkey->item_size, TID_INT, RPC_OUTGOING, convert_flags);
     680            0 :          rpc_convert_single(&pkey->access_mode, TID_WORD, RPC_OUTGOING, convert_flags);
     681            0 :          rpc_convert_single(&pkey->notify_count, TID_WORD, RPC_OUTGOING, convert_flags);
     682            0 :          rpc_convert_single(&pkey->next_key, TID_INT, RPC_OUTGOING, convert_flags);
     683            0 :          rpc_convert_single(&pkey->parent_keylist, TID_INT, RPC_OUTGOING, convert_flags);
     684            0 :          rpc_convert_single(&pkey->last_written, TID_INT, RPC_OUTGOING, convert_flags);
     685              :       }
     686            0 :       break;
     687              : 
     688            0 :    case RPC_DB_GET_LINK:
     689            0 :       status = db_get_link(CHNDLE(0), CHNDLE(1), (KEY*)CARRAY(2));
     690            0 :       if (convert_flags) {
     691              :          KEY *pkey;
     692              : 
     693            0 :          pkey = (KEY *) CARRAY(2);
     694            0 :          rpc_convert_single(&pkey->type, TID_DWORD, RPC_OUTGOING, convert_flags);
     695            0 :          rpc_convert_single(&pkey->num_values, TID_INT, RPC_OUTGOING, convert_flags);
     696            0 :          rpc_convert_single(&pkey->data, TID_INT, RPC_OUTGOING, convert_flags);
     697            0 :          rpc_convert_single(&pkey->total_size, TID_INT, RPC_OUTGOING, convert_flags);
     698            0 :          rpc_convert_single(&pkey->item_size, TID_INT, RPC_OUTGOING, convert_flags);
     699            0 :          rpc_convert_single(&pkey->access_mode, TID_WORD, RPC_OUTGOING, convert_flags);
     700            0 :          rpc_convert_single(&pkey->notify_count, TID_WORD, RPC_OUTGOING, convert_flags);
     701            0 :          rpc_convert_single(&pkey->next_key, TID_INT, RPC_OUTGOING, convert_flags);
     702            0 :          rpc_convert_single(&pkey->parent_keylist, TID_INT, RPC_OUTGOING, convert_flags);
     703            0 :          rpc_convert_single(&pkey->last_written, TID_INT, RPC_OUTGOING, convert_flags);
     704              :       }
     705            0 :       break;
     706              : 
     707            0 :    case RPC_DB_GET_KEY_INFO:
     708            0 :       status = db_get_key_info(CHNDLE(0), CHNDLE(1), CSTRING(2), CINT(3), CPINT(4), CPINT(5), CPINT(6));
     709            0 :       break;
     710              : 
     711            0 :    case RPC_DB_GET_KEY_TIME:
     712            0 :       status = db_get_key_time(CHNDLE(0), CHNDLE(1), CPDWORD(2));
     713            0 :       break;
     714              : 
     715            0 :    case RPC_DB_RENAME_KEY:
     716            0 :       status = db_rename_key(CHNDLE(0), CHNDLE(1), CSTRING(2));
     717            0 :       break;
     718              : 
     719            0 :    case RPC_DB_REORDER_KEY:
     720            0 :       status = db_reorder_key(CHNDLE(0), CHNDLE(1), CINT(2));
     721            0 :       break;
     722              : 
     723            0 :    case RPC_DB_GET_DATA:
     724            0 :       status = db_get_data(CHNDLE(0), CHNDLE(1), CARRAY(2), CPINT(3), CDWORD(4));
     725            0 :       rpc_convert_data(CARRAY(2), CDWORD(4), RPC_FIXARRAY | RPC_OUTGOING, CINT(3), convert_flags);
     726            0 :       break;
     727              : 
     728            0 :    case RPC_DB_GET_LINK_DATA:
     729            0 :       status = db_get_link_data(CHNDLE(0), CHNDLE(1), CARRAY(2), CPINT(3), CDWORD(4));
     730            0 :       rpc_convert_data(CARRAY(2), CDWORD(4), RPC_FIXARRAY | RPC_OUTGOING, CINT(3), convert_flags);
     731            0 :       break;
     732              : 
     733            0 :    case RPC_DB_GET_DATA1:
     734            0 :       status = db_get_data1(CHNDLE(0), CHNDLE(1), CARRAY(2), CPINT(3), CDWORD(4), CPINT(5));
     735            0 :       rpc_convert_data(CARRAY(2), CDWORD(4), RPC_FIXARRAY | RPC_OUTGOING, CINT(3), convert_flags);
     736            0 :       break;
     737              : 
     738            0 :    case RPC_DB_GET_DATA_INDEX:
     739            0 :       status = db_get_data_index(CHNDLE(0), CHNDLE(1), CARRAY(2), CPINT(3), CINT(4), CDWORD(5));
     740            0 :       rpc_convert_single(CARRAY(2), CDWORD(5), RPC_OUTGOING, convert_flags);
     741            0 :       break;
     742              : 
     743            0 :    case RPC_DB_SET_DATA:
     744            0 :       rpc_convert_data(CARRAY(2), CDWORD(5), RPC_FIXARRAY, CINT(3), convert_flags);
     745            0 :       status = db_set_data(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4), CDWORD(5));
     746            0 :       break;
     747              : 
     748            0 :    case RPC_DB_SET_DATA1:
     749            0 :          rpc_convert_data(CARRAY(2), CDWORD(5), RPC_FIXARRAY, CINT(3), convert_flags);
     750            0 :          status = db_set_data1(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4), CDWORD(5));
     751            0 :          break;
     752              : 
     753            0 :    case RPC_DB_NOTIFY_CLIENTS_ARRAY:
     754            0 :          rpc_convert_data(CARRAY(1), CINT(2), RPC_FIXARRAY, TID_DWORD, convert_flags);
     755            0 :          status = db_notify_clients_array(CHNDLE(0), (HNDLE*)CARRAY(1), CINT(2));
     756            0 :          break;
     757              : 
     758            0 :    case RPC_DB_SET_LINK_DATA:
     759            0 :       rpc_convert_data(CARRAY(2), CDWORD(5), RPC_FIXARRAY, CINT(3), convert_flags);
     760            0 :       status = db_set_link_data(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4), CDWORD(5));
     761            0 :       break;
     762              : 
     763            0 :    case RPC_DB_SET_DATA_INDEX:
     764            0 :       rpc_convert_single(CARRAY(2), CDWORD(5), 0, convert_flags);
     765            0 :       status = db_set_data_index(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4), CDWORD(5));
     766            0 :       break;
     767              : 
     768            0 :    case RPC_DB_SET_LINK_DATA_INDEX:
     769            0 :       rpc_convert_single(CARRAY(2), CDWORD(5), 0, convert_flags);
     770            0 :       status = db_set_link_data_index(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4), CDWORD(5));
     771            0 :       break;
     772              : 
     773            0 :    case RPC_DB_SET_DATA_INDEX1:
     774            0 :       rpc_convert_single(CARRAY(2), CDWORD(5), 0, convert_flags);
     775            0 :       status = db_set_data_index1(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4), CDWORD(5), CBOOL(6));
     776            0 :       break;
     777              : 
     778            0 :    case RPC_DB_SET_NUM_VALUES:
     779            0 :       status = db_set_num_values(CHNDLE(0), CHNDLE(1), CINT(2));
     780            0 :       break;
     781              : 
     782            0 :    case RPC_DB_SET_MODE:
     783            0 :       status = db_set_mode(CHNDLE(0), CHNDLE(1), CWORD(2), CBOOL(3));
     784            0 :       break;
     785              : 
     786            0 :    case RPC_DB_GET_RECORD:
     787            0 :       status = db_get_record(CHNDLE(0), CHNDLE(1), CARRAY(2), CPINT(3), CINT(4));
     788            0 :       break;
     789              : 
     790            0 :    case RPC_DB_SET_RECORD:
     791            0 :       status = db_set_record(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4));
     792            0 :       break;
     793              : 
     794            0 :    case RPC_DB_GET_RECORD_SIZE:
     795            0 :       status = db_get_record_size(CHNDLE(0), CHNDLE(1), CINT(2), CPINT(3));
     796            0 :       break;
     797              : 
     798            0 :    case RPC_DB_CREATE_RECORD:
     799            0 :       status = db_create_record(CHNDLE(0), CHNDLE(1), CSTRING(2), CSTRING(3));
     800            0 :       break;
     801              : 
     802            0 :    case RPC_DB_CHECK_RECORD:
     803            0 :       status = db_check_record(CHNDLE(0), CHNDLE(1), CSTRING(2), CSTRING(3), CBOOL(4));
     804            0 :       break;
     805              : 
     806            0 :    case RPC_DB_ADD_OPEN_RECORD:
     807            0 :       status = db_add_open_record(CHNDLE(0), CHNDLE(1), CWORD(2));
     808            0 :       break;
     809              : 
     810            0 :    case RPC_DB_REMOVE_OPEN_RECORD:
     811            0 :       status = db_remove_open_record(CHNDLE(0), CHNDLE(1), CBOOL(2));
     812            0 :       break;
     813              : 
     814            0 :    case RPC_DB_LOAD:
     815            0 :       status = db_load(CHNDLE(0), CHNDLE(1), CSTRING(2), CBOOL(3));
     816            0 :       break;
     817              : 
     818            0 :    case RPC_DB_SAVE:
     819            0 :       status = db_save(CHNDLE(0), CHNDLE(1), CSTRING(2), CBOOL(3));
     820            0 :       break;
     821              : 
     822            0 :    case RPC_DB_SET_CLIENT_NAME:
     823            0 :       status = db_set_client_name(CHNDLE(0), CSTRING(1));
     824            0 :       break;
     825              : 
     826            0 :    case RPC_DB_GET_OPEN_RECORDS:
     827            0 :       status = db_get_open_records(CHNDLE(0), CHNDLE(1), CSTRING(2), CINT(3), CBOOL(4));
     828            0 :       break;
     829              : 
     830            0 :    case RPC_DB_COPY_XML:
     831            0 :       status = db_copy_xml(CHNDLE(0), CHNDLE(1), CSTRING(2), CPINT(3), CBOOL(4));
     832            0 :       break;
     833              : 
     834            0 :    case RPC_EL_SUBMIT:
     835            0 :       status = el_submit(CINT(0), CSTRING(1), CSTRING(2), CSTRING(3), CSTRING(4),
     836            0 :                          CSTRING(5), CSTRING(6), CSTRING(7),
     837            0 :                          CSTRING(8), (char*)CARRAY(9), CINT(10),
     838            0 :                          CSTRING(11), (char*)CARRAY(12), CINT(13),
     839            0 :                          CSTRING(14), (char*)CARRAY(15), CINT(16), CSTRING(17), CINT(18));
     840            0 :       break;
     841              : 
     842            0 :    case RPC_AL_CHECK:
     843            0 :       status = al_check();
     844            0 :       break;
     845              : 
     846            0 :    case RPC_AL_TRIGGER_ALARM:
     847            0 :       status = al_trigger_alarm(CSTRING(0), CSTRING(1), CSTRING(2), CSTRING(3), CINT(4));
     848            0 :       break;
     849              : 
     850              :       /* exit functions */
     851            0 :    case RPC_ID_EXIT:
     852              :       //printf("RPC_ID_EXIT!\n");
     853            0 :       status = RPC_SUCCESS;
     854            0 :       break;
     855              : 
     856            0 :    case RPC_ID_SHUTDOWN:
     857            0 :       status = RPC_SUCCESS;
     858            0 :       break;
     859              : 
     860              :       /* various functions */
     861              : 
     862            0 :    case RPC_TEST:
     863            0 :       status = rpc_test(CBYTE(0), CWORD(1), CINT(2), CFLOAT(3), CDOUBLE(4),
     864            0 :                         CPBYTE(5), CPWORD(6), CPINT(7), CPFLOAT(8), CPDOUBLE(9));
     865            0 :       break;
     866              : 
     867            0 :    case RPC_TEST2: {
     868              : 
     869            0 :       status = RPC_SUCCESS;
     870              : 
     871            0 :       if (CINT(0) != 123) {
     872            0 :          cm_msg(MERROR, "rpc_test2", "CINT(0) mismatch");
     873            0 :          status = 0;
     874              :       }
     875              : 
     876            0 :       CINT(1) = 789;
     877              : 
     878            0 :       if (CINT(2) != 456) {
     879            0 :          cm_msg(MERROR, "rpc_test2", "CINT(2) mismatch");
     880            0 :          status = 0;
     881              :       }
     882              :       
     883            0 :       CINT(2) = 2*CINT(2);
     884              : 
     885            0 :       if (strcmp(CSTRING(3), "test string") != 0) {
     886            0 :          cm_msg(MERROR, "rpc_test2", "CSTRING(3) mismatch");
     887            0 :          status = 0;
     888              :       }
     889              : 
     890            0 :       if (CINT(5) != 32) {
     891            0 :          cm_msg(MERROR, "rpc_test2", "CINT(5) string_out size mismatch");
     892            0 :          status = 0;
     893              :       }
     894              : 
     895            0 :       strcpy(CSTRING(4), "string_out");
     896              : 
     897            0 :       if (CINT(7) != 48) {
     898            0 :          cm_msg(MERROR, "rpc_test2", "CINT(7) string2_out size mismatch");
     899            0 :          status = 0;
     900              :       }
     901              : 
     902            0 :       strcpy(CSTRING(6), "second string_out");
     903              : 
     904            0 :       if (CINT(9) != 25) {
     905            0 :          cm_msg(MERROR, "rpc_test2", "CINT(9) string_inout size mismatch");
     906            0 :          status = 0;
     907              :       }
     908              : 
     909            0 :       if (strcmp(CSTRING(8), "string_inout") != 0) {
     910            0 :          cm_msg(MERROR, "rpc_test2", "CSTRING(8) mismatch");
     911            0 :          status = 0;
     912              :       }
     913              : 
     914            0 :       strcpy(CSTRING(8), "return string_inout");
     915              : 
     916              :       // 10, 11, 12 is TID_STRUCT of type KEY
     917              : 
     918              :       KEY *pkey;
     919              : 
     920            0 :       pkey = (KEY*)CARRAY(10);
     921              : 
     922            0 :       if (pkey->type != 111 || pkey->num_values != 222 || strcmp(pkey->name, "name") || pkey->last_written != 333) {
     923            0 :          printf("CKEY(10): type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
     924              : 
     925            0 :          cm_msg(MERROR, "rpc_test2", "CARRAY(10) KEY mismatch");
     926            0 :          status = 0;
     927              :       }
     928              : 
     929            0 :       pkey = (KEY*)CARRAY(11);
     930              : 
     931            0 :       pkey->type = 444;
     932            0 :       pkey->num_values = 555;
     933            0 :       strcpy(pkey->name, "out_name");
     934            0 :       pkey->last_written = 666;
     935              : 
     936              :       //printf("CKEY(11): type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
     937              : 
     938            0 :       pkey = (KEY*)CARRAY(12);
     939              : 
     940            0 :       if (pkey->type != 111111 || pkey->num_values != 222222 || strcmp(pkey->name, "name_name") || pkey->last_written != 333333) {
     941            0 :          printf("CKEY(10): type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
     942              : 
     943            0 :          cm_msg(MERROR, "rpc_test2", "CARRAY(12) KEY mismatch");
     944            0 :          status = 0;
     945              :       }
     946              : 
     947            0 :       pkey->type = 444444;
     948            0 :       pkey->num_values = 555555;
     949            0 :       strcpy(pkey->name, "inout_name");
     950            0 :       pkey->last_written = 666666;
     951              : 
     952              :       //printf("CKEY(10): type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
     953              : 
     954            0 :       if (CINT(14) != 40) {
     955            0 :          cm_msg(MERROR, "rpc_test2", "CINT(14) array_in size mismatch");
     956            0 :          status = 0;
     957              :       } else {
     958              :          //printf("CARRAY(13): %p, 0x%08x [%s]\n", CARRAY(9), *(uint32_t*)CARRAY(9), (char*)CARRAY(9));
     959              : 
     960            0 :          uint32_t size = CINT(14)/4;
     961            0 :          for (uint32_t i=0; i<size; i++) {
     962            0 :             if (((uint32_t*)CARRAY(13))[i] != i*10) {
     963            0 :                cm_msg(MERROR, "rpc_test2", "CARRAY(13) dwordarray_inout mismatch at %d, %d vs %d", i, ((uint32_t*)CARRAY(13))[i], i*10);
     964            0 :                status = 0;
     965              :             }
     966              :          }
     967              :       }
     968              : 
     969            0 :       for (int i=0; i<5; i++) {
     970            0 :          ((uint32_t*)CARRAY(13))[i] = i*10 + i;
     971              :       }
     972              : 
     973            0 :       CINT(14) = 20;
     974              :       
     975            0 :       if (CINT(16) != 10) {
     976            0 :          cm_msg(MERROR, "rpc_test2", "CINT(16) array_in size mismatch");
     977            0 :          status = 0;
     978              :       } else {
     979              :          //printf("CARRAY(15): %p, 0x%08x [%s]\n", CARRAY(15), *(uint32_t*)CARRAY(15), (char*)CARRAY(15));
     980              : 
     981            0 :          for (int i=0; i<CINT(16); i++) {
     982            0 :             if (((char*)CARRAY(15))[i] != 'a'+i) {
     983            0 :                cm_msg(MERROR, "rpc_test2", "CARRAY(15) array_in data mismatch at %d, %d vs %d", i, ((char*)CARRAY(15))[i], 'a'+i);
     984            0 :                status = 0;
     985              :             }
     986              :          }
     987              :       }
     988              : 
     989            0 :       if (CINT(18) != 16) {
     990            0 :          cm_msg(MERROR, "rpc_test2", "CINT(14) array_out size mismatch");
     991            0 :          status = 0;
     992              :       }
     993              : 
     994            0 :       break;
     995              :    }
     996              : 
     997            0 :    default:
     998            0 :       cm_msg(MERROR, "rpc_server_dispatch", "received unrecognized command %d", index);
     999            0 :       status = RPC_INVALID_ID;
    1000              :    }
    1001              : 
    1002            0 :    return status;
    1003              : }
    1004              : 
    1005              : /* emacs
    1006              :  * Local Variables:
    1007              :  * tab-width: 8
    1008              :  * c-basic-offset: 3
    1009              :  * indent-tabs-mode: nil
    1010              :  * End:
    1011              :  */
        

Generated by: LCOV version 2.0-1