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

            Line data    Source code
       1              : /********************************************************************\
       2              : 
       3              :   Name:         MRPC.C
       4              :   Created by:   Stefan Ritt
       5              : 
       6              :   Contents:     List of MSCB RPC functions with parameters
       7              : 
       8              :   $Id$
       9              : 
      10              : \********************************************************************/
      11              : 
      12              : #include "mscb.h"
      13              : 
      14              : #ifdef OS_WINNT
      15              : 
      16              : #pragma warning(disable:4996)
      17              : 
      18              : #include <windows.h>
      19              : #include <io.h>
      20              : #include <fcntl.h>
      21              : #include <time.h>
      22              : #include <sys/timeb.h>
      23              : 
      24              : #elif defined(OS_LINUX)
      25              : 
      26              : #include <unistd.h>
      27              : #include <stdarg.h>
      28              : #include <stdlib.h>
      29              : #include <sys/types.h>
      30              : #include <sys/time.h>
      31              : #include <sys/socket.h>
      32              : #include <sys/timeb.h>
      33              : #include <netdb.h>
      34              : #include <netinet/in.h>
      35              : #include <arpa/inet.h>
      36              : #include <string.h>
      37              : #include <fcntl.h>
      38              : #include <time.h>
      39              : #include <errno.h>
      40              : 
      41              : #define closesocket(s) close(s)
      42              : 
      43              : #endif
      44              : 
      45              : #include <stdio.h>
      46              : #include <assert.h>
      47              : #include "mscbrpc.h"
      48              : 
      49              : #ifdef HAVE_USB
      50              : #include "musbstd.h"
      51              : #endif
      52              : 
      53              : typedef int INT;
      54              : 
      55              : /* functions defined in mscb.c */
      56              : extern int _debug_flag;
      57              : extern void debug_log(const char *format, int start, ...);
      58              : 
      59              : /*------------------------------------------------------------------*/
      60              : 
      61              : static RPC_LIST rpc_list[] = {
      62              : 
      63              :    /* common functions */
      64              :    {RPC_MSCB_INIT, "mscb_init",
      65              :     {{TID_STRING, RPC_IN | RPC_OUT},
      66              :      {TID_INT, RPC_IN},
      67              :      {TID_STRING, RPC_IN},
      68              :      {TID_INT, RPC_IN},
      69              :      {0}}},
      70              : 
      71              :    {RPC_MSCB_EXIT, "mscb_exit",
      72              :     {{TID_INT, RPC_IN},
      73              :      {0}}},
      74              : 
      75              :    {RPC_MSCB_GET_DEVICE, "mscb_get_device",
      76              :     {{TID_INT, RPC_IN},
      77              :      {TID_STRING, RPC_OUT},
      78              :      {TID_INT, RPC_IN},
      79              :      {0}}},
      80              : 
      81              :    {RPC_MSCB_REBOOT, "mscb_reboot",
      82              :     {{TID_INT, RPC_IN},
      83              :      {TID_INT, RPC_IN},
      84              :      {TID_INT, RPC_IN},
      85              :      {TID_INT, RPC_IN},
      86              :      {0}}},
      87              : 
      88              :    {RPC_MSCB_SUBM_RESET, "mscb_subm_reset",
      89              :     {{TID_INT, RPC_IN},
      90              :      {0}}},
      91              : 
      92              :    {RPC_MSCB_PING, "mscb_ping",
      93              :     {{TID_INT, RPC_IN},
      94              :      {TID_INT, RPC_IN},
      95              :      {TID_INT, RPC_IN},
      96              :      {0}}},
      97              : 
      98              :    {RPC_MSCB_INFO, "mscb_info",
      99              :     {{TID_INT, RPC_IN},
     100              :      {TID_INT, RPC_IN},
     101              :      {TID_STRUCT, RPC_OUT, sizeof(MSCB_INFO)},
     102              :      {0}}},
     103              : 
     104              :    {RPC_MSCB_UPTIME, "mscb_uptime",
     105              :     {{TID_INT, RPC_IN},
     106              :      {TID_INT, RPC_IN},
     107              :      {TID_DWORD, RPC_OUT},
     108              :      {0}}},
     109              : 
     110              :    {RPC_MSCB_INFO_VARIABLE, "mscb_info_variable",
     111              :     {{TID_INT, RPC_IN},
     112              :      {TID_INT, RPC_IN},
     113              :      {TID_INT, RPC_IN},
     114              :      {TID_STRUCT, RPC_OUT, sizeof(MSCB_INFO_VAR)},
     115              :      {0}}},
     116              : 
     117              :    {RPC_MSCB_SET_NODE_ADDR, "mscb_set_node_addr",
     118              :     {{TID_INT, RPC_IN},
     119              :      {TID_INT, RPC_IN},
     120              :      {TID_INT, RPC_IN},
     121              :      {TID_INT, RPC_IN},
     122              :      {TID_SHORT, RPC_IN},
     123              :      {0}}},
     124              : 
     125              :    {RPC_MSCB_SET_GROUP_ADDR, "mscb_set_group_addr",
     126              :     {{TID_INT, RPC_IN},
     127              :      {TID_INT, RPC_IN},
     128              :      {TID_INT, RPC_IN},
     129              :      {TID_INT, RPC_IN},
     130              :      {TID_SHORT, RPC_IN},
     131              :      {0}}},
     132              : 
     133              :    {RPC_MSCB_SET_NAME, "mscb_set_name",
     134              :     {{TID_INT, RPC_IN},
     135              :      {TID_INT, RPC_IN},
     136              :      {TID_STRING, RPC_IN},
     137              :      {0}}},
     138              : 
     139              :    {RPC_MSCB_WRITE_GROUP, "mscb_write_group",
     140              :     {{TID_INT, RPC_IN},
     141              :      {TID_INT, RPC_IN},
     142              :      {TID_BYTE, RPC_IN},
     143              :      {TID_ARRAY, RPC_IN | RPC_VARARRAY},
     144              :      {TID_INT, RPC_IN},
     145              :      {TID_INT, RPC_IN},
     146              :      {0}}},
     147              : 
     148              :    {RPC_MSCB_WRITE, "mscb_write",
     149              :     {{TID_INT, RPC_IN},
     150              :      {TID_INT, RPC_IN},
     151              :      {TID_BYTE, RPC_IN},
     152              :      {TID_ARRAY, RPC_IN | RPC_VARARRAY},
     153              :      {TID_INT, RPC_IN},
     154              :      {0}}},
     155              : 
     156              :    {RPC_MSCB_WRITE_RANGE, "mscb_write_range",
     157              :     {{TID_INT, RPC_IN},
     158              :      {TID_INT, RPC_IN},
     159              :      {TID_BYTE, RPC_IN},
     160              :      {TID_BYTE, RPC_IN},
     161              :      {TID_ARRAY, RPC_IN | RPC_VARARRAY},
     162              :      {TID_INT, RPC_IN},
     163              :      {0}}},
     164              : 
     165              :    {RPC_MSCB_FLASH, "mscb_flash",
     166              :     {{TID_INT, RPC_IN},
     167              :      {TID_INT, RPC_IN},
     168              :      {TID_INT, RPC_IN},
     169              :      {TID_INT, RPC_IN},
     170              :      {0}}},
     171              : 
     172              :    {RPC_MSCB_UPLOAD, "mscb_upload",
     173              :     {{TID_INT, RPC_IN},
     174              :      {TID_INT, RPC_IN},
     175              :      {TID_ARRAY, RPC_IN | RPC_VARARRAY},
     176              :      {TID_INT, RPC_IN},
     177              :      {TID_INT, RPC_IN},
     178              :      {0}}},
     179              : 
     180              :    {RPC_MSCB_VERIFY, "mscb_verify",
     181              :     {{TID_INT, RPC_IN},
     182              :      {TID_INT, RPC_IN},
     183              :      {TID_ARRAY, RPC_IN | RPC_VARARRAY},
     184              :      {TID_INT, RPC_IN},
     185              :      {0}}},
     186              : 
     187              :    {RPC_MSCB_READ, "mscb_read",
     188              :     {{TID_INT, RPC_IN},
     189              :      {TID_INT, RPC_IN},
     190              :      {TID_BYTE, RPC_IN},
     191              :      {TID_ARRAY, RPC_OUT | RPC_VARARRAY},
     192              :      {TID_INT, RPC_IN | RPC_OUT},
     193              :      {TID_INT, RPC_IN},
     194              :      {0}}},
     195              : 
     196              :    {RPC_MSCB_READ_RANGE, "mscb_read_range",
     197              :     {{TID_INT, RPC_IN},
     198              :      {TID_INT, RPC_IN},
     199              :      {TID_BYTE, RPC_IN},
     200              :      {TID_BYTE, RPC_IN},
     201              :      {TID_ARRAY, RPC_OUT | RPC_VARARRAY},
     202              :      {TID_INT, RPC_IN | RPC_OUT},
     203              :      {0}}},
     204              : 
     205              :    {RPC_MSCB_USER, "mscb_user",
     206              :     {{TID_INT, RPC_IN},
     207              :      {TID_INT, RPC_IN},
     208              :      {TID_ARRAY, RPC_IN | RPC_VARARRAY},
     209              :      {TID_INT, RPC_IN},
     210              :      {TID_ARRAY, RPC_OUT | RPC_VARARRAY},
     211              :      {TID_INT, RPC_IN | RPC_OUT},
     212              :      {0}}},
     213              : 
     214              :    {RPC_MSCB_ECHO, "mscb_echo",
     215              :     {{TID_INT, RPC_IN},
     216              :      {TID_INT, RPC_IN},
     217              :      {TID_BYTE, RPC_IN},
     218              :      {TID_BYTE, RPC_OUT},
     219              :      {0}}},
     220              : 
     221              :    {RPC_MSCB_ADDR, "mscb_addr",
     222              :     {{TID_INT, RPC_IN},
     223              :      {TID_INT, RPC_IN},
     224              :      {TID_INT, RPC_IN},
     225              :      {TID_INT, RPC_IN},
     226              :      {0}}},
     227              : 
     228              :    {RPC_MSCB_SET_TIME, "mscb_set_time",
     229              :     {{TID_INT, RPC_IN},
     230              :      {TID_INT, RPC_IN},
     231              :      {TID_INT, RPC_IN},
     232              :      {TID_INT, RPC_IN},
     233              :      {0}}},
     234              : 
     235              :    {0}
     236              : 
     237              : };
     238              : 
     239              : /*------------------------------------------------------------------*/
     240              : 
     241              : /* data type sizes */
     242              : INT mtid_size[] = {
     243              :    0,                           /* tid == 0 not defined                               */
     244              :    1,                           /* TID_BYTE      unsigned byte         0       255    */
     245              :    1,                           /* TID_SBYTE     signed byte         -128      127    */
     246              :    1,                           /* TID_CHAR      single character      0       255    */
     247              :    2,                           /* TID_WORD      two bytes             0      65535   */
     248              :    2,                           /* TID_SHORT     signed word        -32768    32767   */
     249              :    4,                           /* TID_DWORD     four bytes            0      2^32-1  */
     250              :    4,                           /* TID_INT       signed dword        -2^31    2^31-1  */
     251              :    4,                           /* TID_BOOL      four bytes bool       0        1     */
     252              :    4,                           /* TID_FLOAT     4 Byte float format                  */
     253              :    8,                           /* TID_DOUBLE    8 Byte float format                  */
     254              :    1,                           /* TID_BITFIELD  8 Bits Bitfield    00000000 11111111 */
     255              :    0,                           /* TID_STRING    zero terminated string               */
     256              :    0,                           /* TID_ARRAY     variable length array of unkown type */
     257              :    0,                           /* TID_STRUCT    C structure                          */
     258              :    0,                           /* TID_KEY       key in online database               */
     259              :    0                            /* TID_LINK      link in online database              */
     260              : };
     261              : 
     262              : /*------------------------------------------------------------------*/
     263              : 
     264              : #define N_MAX_CONNECTION      10
     265              : #define NET_BUFFER_SIZE   100000
     266              : 
     267              : static int  rpc_sock[N_MAX_CONNECTION];
     268              : static char rpc_net_buffer[NET_BUFFER_SIZE];
     269              : 
     270              : /*------------------------------------------------------------------*/
     271              : 
     272            0 : void mdrain_tcp(int sock)
     273              : /* drain socket connection from any old data */
     274              : {
     275              :    char buffer[100];
     276              : 
     277              :    fd_set readfds;
     278              :    struct timeval timeout;
     279              :    int status;
     280              : 
     281              : 
     282              :    /* first receive header */
     283              :    do {
     284            0 :       FD_ZERO(&readfds);
     285            0 :       FD_SET(sock, &readfds);
     286              : 
     287            0 :       timeout.tv_sec = 0;
     288            0 :       timeout.tv_usec = 0;
     289              : 
     290              :       do {
     291            0 :          status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
     292            0 :       } while (status == -1);   /* dont return if an alarm signal was cought */
     293              : 
     294            0 :       if (!FD_ISSET(sock, &readfds))
     295            0 :          return;
     296              : 
     297            0 :       status = recv(sock, buffer, sizeof(buffer), 0);
     298              : 
     299            0 :       if (status <= 0)
     300            0 :          return ;
     301              : 
     302            0 :    } while (1);
     303              : }
     304              : 
     305              : /*------------------------------------------------------------------*/
     306              : 
     307            0 : int mrecv_tcp(int sock, char *buffer, int buffer_size)
     308              : {
     309              :    INT param_size, n_received, n;
     310              :    NET_COMMAND *nc;
     311              : 
     312              :    fd_set readfds;
     313              :    struct timeval timeout;
     314              :    int status;
     315              :    int millisec;
     316              : 
     317            0 :    if (buffer_size < (int)sizeof(NET_COMMAND_HEADER)) {
     318            0 :       printf("mrecv_tcp_server: buffer too small\n");
     319            0 :       return -1;
     320              :    }
     321              : 
     322              :    /* fixed timeout of 2 sec for the moment */
     323            0 :    millisec = 2000;
     324              : 
     325              :    /* first receive header */
     326            0 :    n_received = 0;
     327              :    do {
     328            0 :       FD_ZERO(&readfds);
     329            0 :       FD_SET(sock, &readfds);
     330              : 
     331            0 :       timeout.tv_sec = millisec / 1000;
     332            0 :       timeout.tv_usec = (millisec % 1000) * 1000;
     333              : 
     334              :       do {
     335            0 :          status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
     336            0 :       } while (status == -1);   /* dont return if an alarm signal was cought */
     337              : 
     338            0 :       if (!FD_ISSET(sock, &readfds))
     339            0 :          return n_received;
     340              : 
     341            0 :       n = recv(sock, buffer + n_received, sizeof(NET_COMMAND_HEADER), 0);
     342              : 
     343            0 :       if (n <= 0)
     344            0 :          return n;
     345              : 
     346            0 :       n_received += n;
     347              : 
     348            0 :    } while (n_received < (int)sizeof(NET_COMMAND_HEADER));
     349              : 
     350              :    /* now receive parameters */
     351              : 
     352            0 :    nc = (NET_COMMAND *) buffer;
     353            0 :    param_size = nc->header.param_size;
     354            0 :    n_received = 0;
     355              : 
     356            0 :    if (param_size == 0)
     357            0 :       return sizeof(NET_COMMAND_HEADER);
     358              : 
     359              :    do {
     360            0 :       FD_ZERO(&readfds);
     361            0 :       FD_SET(sock, &readfds);
     362              : 
     363            0 :       timeout.tv_sec = millisec / 1000;
     364            0 :       timeout.tv_usec = (millisec % 1000) * 1000;
     365              : 
     366              :       do {
     367            0 :          status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
     368            0 :       } while (status == -1);   /* dont return if an alarm signal was cought */
     369              : 
     370            0 :       if (!FD_ISSET(sock, &readfds))
     371            0 :          return n_received;
     372              : 
     373            0 :       n = recv(sock, buffer + sizeof(NET_COMMAND_HEADER) + n_received,
     374            0 :                param_size - n_received, 0);
     375              : 
     376            0 :       if (n <= 0)
     377            0 :          return n;
     378              : 
     379            0 :       n_received += n;
     380            0 :    } while (n_received < param_size);
     381              : 
     382            0 :    return sizeof(NET_COMMAND_HEADER) + param_size;
     383              : }
     384              : 
     385              : /*------------------------------------------------------------------*/
     386              : 
     387            0 : int msend_tcp(int sock, char *buffer, int buffer_size)
     388              : {
     389              :    int count, status;
     390              : 
     391              :    /* drain receive queue if any late packet arrived in meantime */
     392            0 :    mdrain_tcp(sock);
     393              : 
     394              :    /* transfer fragments until complete buffer is transferred */
     395              : 
     396            0 :    for (count = 0; (int) count < (int) buffer_size - NET_TCP_SIZE;) {
     397            0 :       status = send(sock, buffer + count, NET_TCP_SIZE, 0);
     398            0 :       if (status != -1)
     399            0 :          count += status;
     400              :       else
     401            0 :          return status;
     402              :    }
     403              : 
     404            0 :    while (count < buffer_size) {
     405            0 :       status = send(sock, buffer + count, buffer_size - count, 0);
     406            0 :       if (status != -1)
     407            0 :          count += status;
     408              :       else
     409            0 :          return status;
     410              :    }
     411              : 
     412            0 :    return count;
     413              : }
     414              : 
     415              : /*------------------------------------------------------------------*/
     416              : 
     417            0 : int server_execute(int index, void *prpc_param[])
     418              : {
     419              :    int status;
     420              : 
     421            0 :    switch (index) {
     422            0 :    default:
     423            0 :       abort();
     424              :       break;
     425              : 
     426            0 :    case RPC_MSCB_INIT:
     427            0 :       status = mscb_init(CSTRING(0), CINT(1), CSTRING(2), CINT(3));
     428            0 :       break;
     429              : 
     430            0 :    case RPC_MSCB_EXIT:
     431            0 :       status = mscb_exit(CINT(0));
     432            0 :       break;
     433              : 
     434            0 :    case RPC_MSCB_REBOOT:
     435            0 :       status = mscb_reboot(CINT(0), CINT(1), CINT(2), CINT(3));
     436            0 :       break;
     437              : 
     438            0 :    case RPC_MSCB_SUBM_RESET:
     439            0 :       status = mscb_subm_reset(CINT(0));
     440            0 :       break;
     441              : 
     442            0 :    case RPC_MSCB_PING:
     443            0 :       status = mscb_ping(CINT(0), CWORD(1), CINT(2), CINT(3));
     444            0 :       break;
     445              : 
     446            0 :    case RPC_MSCB_INFO:
     447            0 :       status = mscb_info(CINT(0), CWORD(1), (MSCB_INFO*)CARRAY(2));
     448            0 :       break;
     449              : 
     450            0 :    case RPC_MSCB_INFO_VARIABLE:
     451            0 :       status = mscb_info_variable(CINT(0), CSHORT(1), CBYTE(2), (MSCB_INFO_VAR*)CARRAY(3));
     452            0 :       break;
     453              : 
     454            0 :    case RPC_MSCB_UPTIME:
     455            0 :       status = mscb_uptime(CINT(0), CWORD(1), CPDWORD(2));
     456            0 :       break;
     457              : 
     458            0 :    case RPC_MSCB_SET_NODE_ADDR:
     459            0 :       status = mscb_set_node_addr(CINT(0), CINT(1), CINT(2), CINT(3), CSHORT(4));
     460            0 :       break;
     461              : 
     462            0 :    case RPC_MSCB_SET_GROUP_ADDR:
     463            0 :       status = mscb_set_group_addr(CINT(0), CINT(1), CINT(2), CINT(3), CSHORT(4));
     464            0 :       break;
     465              : 
     466            0 :    case RPC_MSCB_SET_NAME:
     467            0 :       status = mscb_set_name(CINT(0), CSHORT(1), CSTRING(2));
     468            0 :       break;
     469              : 
     470            0 :    case RPC_MSCB_WRITE_GROUP:
     471            0 :       status = mscb_write_group(CINT(0), CSHORT(1), CBYTE(2), CARRAY(3), CINT(4));
     472            0 :       break;
     473              : 
     474            0 :    case RPC_MSCB_WRITE:
     475            0 :       status = mscb_write(CINT(0), CSHORT(1), CBYTE(2), CARRAY(3), CINT(4));
     476            0 :       break;
     477              : 
     478            0 :    case RPC_MSCB_WRITE_NO_RETRIES:
     479            0 :       status = mscb_write(CINT(0), CSHORT(1), CBYTE(2), CARRAY(3), CINT(4));
     480            0 :       break;
     481              : 
     482            0 :    case RPC_MSCB_WRITE_RANGE:
     483            0 :       status = mscb_write_range(CINT(0), CSHORT(1), CBYTE(2), CBYTE(3), CARRAY(4), CINT(5));
     484            0 :       break;
     485              : 
     486            0 :    case RPC_MSCB_FLASH:
     487            0 :       status = mscb_flash(CINT(0), CINT(1), CINT(2), CINT(3));
     488            0 :       break;
     489              : 
     490            0 :    case RPC_MSCB_SET_BAUD:
     491            0 :       status = mscb_set_baud(CINT(0), CINT(1));
     492            0 :       break;
     493              : 
     494            0 :    case RPC_MSCB_UPLOAD:
     495            0 :       status = mscb_upload(CINT(0), CSHORT(1), CSHORT(2), CSTRING(3), CINT(4));
     496            0 :       break;
     497              : 
     498            0 :    case RPC_MSCB_READ:
     499            0 :       status = mscb_read(CINT(0), CSHORT(1), CBYTE(2), CARRAY(3), CPINT(4));
     500            0 :       break;
     501              : 
     502            0 :    case RPC_MSCB_READ_NO_RETRIES:
     503            0 :       status = mscb_read_no_retries(CINT(0), CSHORT(1), CBYTE(2), CARRAY(3), CPINT(4));
     504            0 :       break;
     505              : 
     506            0 :    case RPC_MSCB_READ_RANGE:
     507              :       status =
     508            0 :           mscb_read_range(CINT(0), CSHORT(1), CBYTE(2), CBYTE(3), CARRAY(4), CPINT(5));
     509            0 :       break;
     510              : 
     511            0 :    case RPC_MSCB_ECHO:
     512            0 :       status = mscb_echo(CINT(0), CSHORT(1), CBYTE(2), CPBYTE(3));
     513            0 :       break;
     514              : 
     515            0 :    case RPC_MSCB_USER:
     516            0 :       status = mscb_user(CINT(0), CSHORT(1), CARRAY(2), CINT(3), CARRAY(4), CPINT(5));
     517            0 :       break;
     518              : 
     519            0 :    case RPC_MSCB_ADDR:
     520            0 :       status = mscb_addr(CINT(0), CINT(1), CSHORT(2), CINT(3), CINT(4));
     521            0 :       break;
     522              : 
     523            0 :    case RPC_MSCB_SET_TIME:
     524            0 :       status = mscb_set_time(CINT(0), CINT(1), CINT(2), CINT(3));
     525            0 :       break;
     526              :    }
     527              : 
     528            0 :    return status;
     529              : }
     530              : 
     531              : /*------------------------------------------------------------------*/
     532              : 
     533            0 : int mrpc_execute(int sock, char *buffer)
     534              : {
     535              :    INT i, index, routine_id, status;
     536              :    char *in_param_ptr, *out_param_ptr, *last_param_ptr;
     537              :    INT tid, flags;
     538              :    NET_COMMAND *nc_in, *nc_out;
     539              :    INT param_size, max_size;
     540              :    void *prpc_param[20];
     541              :    char return_buffer[NET_BUFFER_SIZE];
     542              : 
     543              :    /* extract pointer array to parameters */
     544            0 :    nc_in = (NET_COMMAND *) buffer;
     545            0 :    nc_out = (NET_COMMAND *) return_buffer;
     546              : 
     547              :    /* find entry in rpc_list */
     548            0 :    routine_id = nc_in->header.routine_id;
     549              : 
     550            0 :    for (i = 0;; i++)
     551            0 :       if (rpc_list[i].id == 0 || rpc_list[i].id == routine_id)
     552              :          break;
     553            0 :    index = i;
     554            0 :    if (rpc_list[i].id == 0) {
     555            0 :       printf("mrpc_execute: Invalid rpc ID (%d)\n", routine_id);
     556            0 :       return RPC_INVALID_ID;
     557              :    }
     558              : 
     559            0 :    in_param_ptr = nc_in->param;
     560            0 :    out_param_ptr = nc_out->param;
     561              : 
     562            0 :    for (i = 0; rpc_list[index].param[i].tid != 0; i++) {
     563            0 :       tid = rpc_list[index].param[i].tid;
     564            0 :       flags = rpc_list[index].param[i].flags;
     565              : 
     566            0 :       if (flags & RPC_IN) {
     567            0 :          param_size = ALIGN8(mtid_size[tid]);
     568              : 
     569            0 :          if (tid == TID_STRING || tid == TID_LINK)
     570            0 :             param_size = ALIGN8(1 + strlen((char *) (in_param_ptr)));
     571              : 
     572            0 :          if (flags & RPC_VARARRAY) {
     573              :             /* for arrays, the size is stored as a INT in front of the array */
     574            0 :             param_size = *((INT *) in_param_ptr);
     575            0 :             param_size = ALIGN8(param_size);
     576              : 
     577            0 :             in_param_ptr += ALIGN8(sizeof(INT));
     578              :          }
     579              : 
     580            0 :          if (tid == TID_STRUCT)
     581            0 :             param_size = ALIGN8(rpc_list[index].param[i].n);
     582              : 
     583            0 :          prpc_param[i] = in_param_ptr;
     584              : 
     585            0 :          in_param_ptr += param_size;
     586              :       }
     587              : 
     588            0 :       if (flags & RPC_OUT) {
     589            0 :          param_size = ALIGN8(mtid_size[tid]);
     590              : 
     591            0 :          if (flags & RPC_VARARRAY || tid == TID_STRING) {
     592              :             /* save maximum array length */
     593            0 :             max_size = *((INT *) in_param_ptr);
     594            0 :             max_size = ALIGN8(max_size);
     595              : 
     596            0 :             *((INT *) out_param_ptr) = max_size;
     597              : 
     598              :             /* save space for return array length */
     599            0 :             out_param_ptr += ALIGN8(sizeof(INT));
     600              : 
     601              :             /* use maximum array length from input */
     602            0 :             param_size += max_size;
     603              :          }
     604              : 
     605            0 :          if (rpc_list[index].param[i].tid == TID_STRUCT)
     606            0 :             param_size = ALIGN8(rpc_list[index].param[i].n);
     607              : 
     608            0 :          if ((POINTER_T) out_param_ptr - (POINTER_T) nc_out + param_size > NET_BUFFER_SIZE) {
     609              :             printf
     610            0 :                 ("mrpc_execute: return parameters (%d) too large for network buffer (%d)\n",
     611            0 :                  (int)((POINTER_T) out_param_ptr - (POINTER_T) nc_out + param_size), NET_BUFFER_SIZE);
     612            0 :             return RPC_EXCEED_BUFFER;
     613              :          }
     614              : 
     615              :          /* if parameter goes both directions, copy input to output */
     616            0 :          if (rpc_list[index].param[i].flags & RPC_IN)
     617            0 :             memcpy(out_param_ptr, prpc_param[i], param_size);
     618              : 
     619            0 :          prpc_param[i] = out_param_ptr;
     620            0 :          out_param_ptr += param_size;
     621              :       }
     622              : 
     623              :    }
     624              : 
     625            0 :    last_param_ptr = out_param_ptr;
     626              : 
     627              :   /*********************************\
     628              :   *   call dispatch function        *
     629              :   \*********************************/
     630            0 :    status = server_execute(routine_id, prpc_param);
     631              : 
     632              :    /* compress variable length arrays */
     633            0 :    out_param_ptr = nc_out->param;
     634            0 :    for (i = 0; rpc_list[index].param[i].tid != 0; i++)
     635            0 :       if (rpc_list[index].param[i].flags & RPC_OUT) {
     636            0 :          tid = rpc_list[index].param[i].tid;
     637            0 :          flags = rpc_list[index].param[i].flags;
     638            0 :          param_size = ALIGN8(mtid_size[tid]);
     639              : 
     640            0 :          if (tid == TID_STRING) {
     641            0 :             max_size = *((INT *) out_param_ptr);
     642            0 :             param_size = strlen((char *) prpc_param[i]) + 1;
     643            0 :             param_size = ALIGN8(param_size);
     644              : 
     645              :             /* move string ALIGN8(sizeof(INT)) left */
     646            0 :             memcpy(out_param_ptr, out_param_ptr + ALIGN8(sizeof(INT)), param_size);
     647              : 
     648              :             /* move remaining parameters to end of string */
     649            0 :             memcpy(out_param_ptr + param_size,
     650            0 :                    out_param_ptr + max_size + ALIGN8(sizeof(INT)),
     651            0 :                    (POINTER_T) last_param_ptr -
     652            0 :                    ((POINTER_T) out_param_ptr + max_size + ALIGN8(sizeof(INT))));
     653              :          }
     654              : 
     655            0 :          if (flags & RPC_VARARRAY) {
     656              :             /* store array length at current out_param_ptr */
     657            0 :             max_size = *((INT *) out_param_ptr);
     658            0 :             param_size = *((INT *) prpc_param[i + 1]);
     659            0 :             *((INT *) out_param_ptr) = param_size;
     660              : 
     661            0 :             out_param_ptr += ALIGN8(sizeof(INT));
     662              : 
     663            0 :             param_size = ALIGN8(param_size);
     664              : 
     665              :             /* move remaining parameters to end of array */
     666            0 :             memcpy(out_param_ptr + param_size,
     667            0 :                    out_param_ptr + max_size + ALIGN8(sizeof(INT)),
     668            0 :                    (POINTER_T) last_param_ptr -
     669            0 :                    ((POINTER_T) out_param_ptr + max_size + ALIGN8(sizeof(INT))));
     670              :          }
     671              : 
     672            0 :          if (tid == TID_STRUCT)
     673            0 :             param_size = ALIGN8(rpc_list[index].param[i].n);
     674              : 
     675            0 :          out_param_ptr += param_size;
     676              :       }
     677              : 
     678              :    /* send return parameters */
     679            0 :    param_size = (POINTER_T) out_param_ptr - (POINTER_T) nc_out->param;
     680            0 :    nc_out->header.routine_id = status;
     681            0 :    nc_out->header.param_size = param_size;
     682              : 
     683            0 :    status = msend_tcp(sock, return_buffer, sizeof(NET_COMMAND_HEADER) + param_size);
     684              : 
     685            0 :    if (status < 0) {
     686            0 :       printf("mrpc_execute: msend_tcp() failed\n");
     687            0 :       return RPC_NET_ERROR;
     688              :    }
     689              : 
     690            0 :    return RPC_SUCCESS;
     691              : }
     692              : 
     693              : /*------------------------------------------------------------------*/
     694              : 
     695            0 : int mrpc_connect(char *host_name, int port)
     696              : {
     697              :    INT status, sock;
     698              :    struct sockaddr_in bind_addr;
     699              :    struct hostent *phe;
     700              : 
     701              : #ifdef _MSC_VER
     702              :    {
     703              :       WSADATA WSAData;
     704              : 
     705              :       /* Start windows sockets */
     706              :       if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
     707              :          return -1;
     708              :    }
     709              : #endif
     710              : 
     711              :    /* create a new socket for connecting to remote server */
     712            0 :    sock = socket(AF_INET, SOCK_STREAM, 0);
     713            0 :    if (sock == -1) {
     714            0 :       perror("mrpc_connect,socket");
     715            0 :       return -1;
     716              :    }
     717              : 
     718              :    /* let OS choose any port number */
     719            0 :    memset(&bind_addr, 0, sizeof(bind_addr));
     720            0 :    bind_addr.sin_family = AF_INET;
     721            0 :    bind_addr.sin_addr.s_addr = 0;
     722            0 :    bind_addr.sin_port = 0;
     723              : 
     724            0 :    status = bind(sock, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
     725            0 :    if (status < 0) {
     726            0 :       perror("mrpc_connect,bind");
     727            0 :       return -1;
     728              :    }
     729              : 
     730              :    /* connect to remote node */
     731            0 :    memset(&bind_addr, 0, sizeof(bind_addr));
     732            0 :    bind_addr.sin_family = AF_INET;
     733            0 :    bind_addr.sin_addr.s_addr = 0;
     734            0 :    bind_addr.sin_port = htons((short) port);
     735              : 
     736            0 :    phe = gethostbyname(host_name);
     737            0 :    if (phe == NULL) {
     738            0 :       printf("Cannot find host name \"%s\"\n", host_name);
     739            0 :       return -1;
     740              :    }
     741              : 
     742            0 :    memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
     743              : 
     744            0 :    status = connect(sock, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
     745            0 :    if (status != 0) {
     746            0 :       if (errno)
     747            0 :          perror("mrpc_connect,connect");
     748            0 :       return -1;
     749              :    }
     750              : 
     751            0 :    return sock;
     752              : }
     753              : 
     754              : /*------------------------------------------------------------------*/
     755              : 
     756            0 : int mrpc_disconnect(int sock)
     757              : {
     758            0 :    closesocket(sock);
     759            0 :    return RPC_SUCCESS;
     760              : }
     761              : 
     762              : /*------------------------------------------------------------------*/
     763              : 
     764            0 : void mrpc_va_arg(va_list * arg_ptr, int arg_type, void *arg)
     765              : {
     766            0 :    switch (arg_type) {
     767              :       /* On the stack, the minimum parameter size is sizeof(int).
     768              :          To avoid problems on little endian systems, treat all
     769              :          smaller parameters as int's */
     770            0 :    case TID_BYTE:
     771              :    case TID_SBYTE:
     772              :    case TID_CHAR:
     773              :    case TID_WORD:
     774              :    case TID_SHORT:
     775            0 :       *((int *) arg) = va_arg(*arg_ptr, int);
     776            0 :       break;
     777              : 
     778            0 :    case TID_INT:
     779              :    case TID_BOOL:
     780            0 :       *((INT *) arg) = va_arg(*arg_ptr, INT);
     781            0 :       break;
     782              : 
     783            0 :    case TID_DWORD:
     784            0 :       *((unsigned int *) arg) = va_arg(*arg_ptr, unsigned int);
     785            0 :       break;
     786              : 
     787              :       /* float variables are passed as double by the compiler */
     788            0 :    case TID_FLOAT:
     789            0 :       *((float *) arg) = (float) va_arg(*arg_ptr, double);
     790            0 :       break;
     791              : 
     792            0 :    case TID_DOUBLE:
     793            0 :       *((double *) arg) = va_arg(*arg_ptr, double);
     794            0 :       break;
     795              : 
     796            0 :    case TID_ARRAY:
     797            0 :       *((char **) arg) = va_arg(*arg_ptr, char *);
     798            0 :       break;
     799              :    }
     800            0 : }
     801              : 
     802              : /*------------------------------------------------------------------*/
     803              : 
     804            0 : int mrpc_call(int sock, const int routine_id, ...)
     805              : {
     806              :    va_list ap, aptmp;
     807              :    char str[256], arg[8], arg_tmp[8];
     808              :    INT arg_type;
     809              :    INT i, index, status;
     810              :    INT param_size, arg_size, send_size;
     811              :    INT tid, flags;
     812              :    fd_set readfds;
     813              :    struct timeval timeout;
     814              :    char *param_ptr;
     815              :    int bpointer;
     816              :    NET_COMMAND *nc;
     817              :    time_t now;
     818              : 
     819            0 :    nc = (NET_COMMAND *) rpc_net_buffer;
     820            0 :    nc->header.routine_id = routine_id;
     821              : 
     822            0 :    for (i = 0;; i++)
     823            0 :       if (rpc_list[i].id == routine_id || rpc_list[i].id == 0)
     824              :          break;
     825            0 :    index = i;
     826            0 :    if (rpc_list[i].id == 0) {
     827            0 :       printf("mrpc_call: invalid rpc ID (%d)\n", routine_id);
     828            0 :       return RPC_INVALID_ID;
     829              :    }
     830              : 
     831            0 :    time(&now);
     832            0 :    strcpy(str, ctime(&now));
     833            0 :    str[19] = 0;
     834            0 :    debug_log("%s %s (", 0, str + 4, rpc_list[i].name);
     835              : 
     836              :    /* examine variable argument list and convert it to parameter array */
     837            0 :    va_start(ap, routine_id);
     838              : 
     839            0 :    for (i = 0, param_ptr = nc->param; rpc_list[index].param[i].tid != 0; i++) {
     840            0 :       tid = rpc_list[index].param[i].tid;
     841            0 :       flags = rpc_list[index].param[i].flags;
     842              : 
     843            0 :       bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
     844            0 :           (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
     845            0 :           tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
     846              : 
     847            0 :       if (bpointer)
     848            0 :          arg_type = TID_ARRAY;
     849              :       else
     850            0 :          arg_type = tid;
     851              : 
     852              :       /* floats are passed as doubles, at least under NT */
     853            0 :       if (tid == TID_FLOAT && !bpointer)
     854            0 :          arg_type = TID_DOUBLE;
     855              : 
     856              :       /* get pointer to argument */
     857            0 :       mrpc_va_arg(&ap, arg_type, arg);
     858              : 
     859            0 :       if (flags & RPC_IN) {
     860            0 :          if (bpointer)
     861            0 :             arg_size = mtid_size[tid];
     862              :          else
     863            0 :             arg_size = mtid_size[arg_type];
     864              : 
     865              :          /* for strings, the argument size depends on the string length */
     866            0 :          if (tid == TID_STRING || tid == TID_LINK)
     867            0 :             arg_size = 1 + strlen((char *) *((char **) arg));
     868              : 
     869              :          /* for varibale length arrays, the size is given by
     870              :             the next parameter on the stack */
     871            0 :          if (flags & RPC_VARARRAY) {
     872            0 :             memcpy(&aptmp, &ap, sizeof(ap));
     873            0 :             mrpc_va_arg(&aptmp, TID_ARRAY, arg_tmp);
     874              : 
     875            0 :             if (flags & RPC_OUT)
     876            0 :                arg_size = *((INT *) * ((void **) arg_tmp));
     877              :             else
     878            0 :                arg_size = *((INT *) arg_tmp);
     879              : 
     880            0 :             *((INT *) param_ptr) = ALIGN8(arg_size);
     881            0 :             param_ptr += ALIGN8(sizeof(INT));
     882              :          }
     883              : 
     884            0 :          if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
     885            0 :             arg_size = rpc_list[index].param[i].n;
     886              : 
     887              :          /* always align parameter size */
     888            0 :          param_size = ALIGN8(arg_size);
     889              : 
     890            0 :          if ((POINTER_T) param_ptr - (POINTER_T) nc + param_size > NET_BUFFER_SIZE) {
     891              :             printf
     892            0 :                 ("mrpc_call: parameters (%d) too large for network buffer (%d)\n",
     893            0 :                 (int)((POINTER_T) param_ptr - (POINTER_T) nc + param_size), NET_BUFFER_SIZE);
     894            0 :             return RPC_EXCEED_BUFFER;
     895              :          }
     896              : 
     897            0 :          if (bpointer)
     898            0 :             memcpy(param_ptr, (void *) *((void **) arg), arg_size);
     899              :          else {
     900              :             /* floats are passed as doubles on most systems */
     901            0 :             if (tid != TID_FLOAT)
     902            0 :                memcpy(param_ptr, arg, arg_size);
     903              :             else
     904            0 :                *((float *) param_ptr) = (float) *((double *) arg);
     905              :          }
     906              : 
     907            0 :          switch (tid) {
     908            0 :          case TID_BYTE:
     909            0 :             debug_log(" %d", 0, *((unsigned char *) param_ptr));
     910            0 :             break;
     911            0 :          case TID_SBYTE:
     912            0 :             debug_log(" %d", 0, *((char *) param_ptr));
     913            0 :             break;
     914            0 :          case TID_CHAR:
     915            0 :             debug_log(" %c", 0, *((char *) param_ptr));
     916            0 :             break;
     917            0 :          case TID_WORD:
     918            0 :             debug_log(" %d", 0, *((unsigned short *) param_ptr));
     919            0 :             break;
     920            0 :          case TID_SHORT:
     921            0 :             debug_log(" %d", 0, *((short *) param_ptr));
     922            0 :             break;
     923            0 :          case TID_DWORD:
     924            0 :             debug_log(" %d", 0, *((unsigned int *) param_ptr));
     925            0 :             break;
     926            0 :          case TID_INT:
     927            0 :             debug_log(" %d", 0, *((int *) param_ptr));
     928            0 :             break;
     929            0 :          case TID_BOOL:
     930            0 :             debug_log(" %d", 0, *((int *) param_ptr));
     931            0 :             break;
     932            0 :          case TID_FLOAT:
     933            0 :             debug_log(" %f", 0, *((float *) param_ptr));
     934            0 :             break;
     935            0 :          case TID_DOUBLE:
     936            0 :             debug_log(" %lf", 0, *((double *) param_ptr));
     937            0 :             break;
     938            0 :          case TID_STRING:
     939            0 :             debug_log(" %s", 0, (char *) param_ptr);
     940            0 :             break;
     941              : 
     942            0 :          default:
     943            0 :             debug_log(" *", 0);
     944            0 :             break;
     945              :          }
     946              : 
     947            0 :          param_ptr += param_size;
     948              : 
     949              :       }
     950              :    }
     951              : 
     952            0 :    debug_log(" ) : (", 0);
     953              : 
     954            0 :    va_end(ap);
     955              : 
     956            0 :    nc->header.param_size = (POINTER_T) param_ptr - (POINTER_T) nc->param;
     957              : 
     958            0 :    send_size = nc->header.param_size + sizeof(NET_COMMAND_HEADER);
     959              : 
     960              :    /* send and wait for reply on send socket */
     961            0 :    i = msend_tcp(sock, (char *) nc, send_size);
     962            0 :    if (i != send_size) {
     963            0 :       printf("mrpc_call: msend_tcp() failed\n");
     964            0 :       return RPC_NET_ERROR;
     965              :    }
     966              : 
     967              :    /* make some timeout checking */
     968            0 :    FD_ZERO(&readfds);
     969            0 :    FD_SET(sock, &readfds);
     970              : 
     971            0 :    timeout.tv_sec = RPC_TIMEOUT / 1000;
     972            0 :    timeout.tv_usec = (RPC_TIMEOUT % 1000) * 1000;
     973              : 
     974            0 :    select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
     975              : 
     976            0 :    if (!FD_ISSET(sock, &readfds)) {
     977            0 :       printf("mrpc_call: rpc timeout, routine = \"%s\"\n", rpc_list[index].name);
     978              : 
     979              :       /* disconnect to avoid that the reply to this mrpc_call comes at
     980              :          the next mrpc_call */
     981            0 :       closesocket(sock);
     982              : 
     983            0 :       return RPC_ERR_TIMEOUT;
     984              :    }
     985              : 
     986              :    /* receive result on send socket */
     987            0 :    i = mrecv_tcp(sock, rpc_net_buffer, NET_BUFFER_SIZE);
     988              : 
     989            0 :    if (i <= 0) {
     990            0 :       printf("mrpc_call: mrecv_tcp() failed, routine = \"%s\"\n", rpc_list[index].name);
     991            0 :       return RPC_NET_ERROR;
     992              :    }
     993              : 
     994              :    /* extract result variables and place it to argument list */
     995            0 :    status = nc->header.routine_id;
     996              : 
     997            0 :    va_start(ap, routine_id);
     998              : 
     999            0 :    for (i = 0, param_ptr = nc->param; rpc_list[index].param[i].tid != 0; i++) {
    1000            0 :       tid = rpc_list[index].param[i].tid;
    1001            0 :       flags = rpc_list[index].param[i].flags;
    1002              : 
    1003            0 :       bpointer = (flags & RPC_POINTER) || (flags & RPC_OUT) ||
    1004            0 :           (flags & RPC_FIXARRAY) || (flags & RPC_VARARRAY) ||
    1005            0 :           tid == TID_STRING || tid == TID_ARRAY || tid == TID_STRUCT || tid == TID_LINK;
    1006              : 
    1007            0 :       if (bpointer)
    1008            0 :          arg_type = TID_ARRAY;
    1009              :       else
    1010            0 :          arg_type = rpc_list[index].param[i].tid;
    1011              : 
    1012            0 :       if (tid == TID_FLOAT && !bpointer)
    1013            0 :          arg_type = TID_DOUBLE;
    1014              : 
    1015            0 :       mrpc_va_arg(&ap, arg_type, arg);
    1016              : 
    1017            0 :       if (rpc_list[index].param[i].flags & RPC_OUT) {
    1018            0 :          tid = rpc_list[index].param[i].tid;
    1019            0 :          arg_size = mtid_size[tid];
    1020              : 
    1021            0 :          if (tid == TID_STRING || tid == TID_LINK)
    1022            0 :             arg_size = strlen((char *) (param_ptr)) + 1;
    1023              : 
    1024            0 :          if (flags & RPC_VARARRAY) {
    1025            0 :             arg_size = *((INT *) param_ptr);
    1026            0 :             param_ptr += ALIGN8(sizeof(INT));
    1027              :          }
    1028              : 
    1029            0 :          if (tid == TID_STRUCT || (flags & RPC_FIXARRAY))
    1030            0 :             arg_size = rpc_list[index].param[i].n;
    1031              : 
    1032              :          /* return parameters are always pointers */
    1033            0 :          if (*((char **) arg))
    1034            0 :             memcpy((void *) *((char **) arg), param_ptr, arg_size);
    1035              : 
    1036              :          /* parameter size is always aligned */
    1037            0 :          param_size = ALIGN8(arg_size);
    1038              : 
    1039            0 :          switch (tid) {
    1040            0 :          case TID_BYTE:
    1041            0 :             debug_log(" %d", 0, *((unsigned char *) param_ptr));
    1042            0 :             break;
    1043            0 :          case TID_SBYTE:
    1044            0 :             debug_log(" %d", 0, *((char *) param_ptr));
    1045            0 :             break;
    1046            0 :          case TID_CHAR:
    1047            0 :             debug_log(" %c", 0, *((char *) param_ptr));
    1048            0 :             break;
    1049            0 :          case TID_WORD:
    1050            0 :             debug_log(" %d", 0, *((unsigned short *) param_ptr));
    1051            0 :             break;
    1052            0 :          case TID_SHORT:
    1053            0 :             debug_log(" %d", 0, *((short *) param_ptr));
    1054            0 :             break;
    1055            0 :          case TID_DWORD:
    1056            0 :             debug_log(" %d", 0, *((unsigned int *) param_ptr));
    1057            0 :             break;
    1058            0 :          case TID_INT:
    1059            0 :             debug_log(" %d", 0, *((int *) param_ptr));
    1060            0 :             break;
    1061            0 :          case TID_BOOL:
    1062            0 :             debug_log(" %d", 0, *((int *) param_ptr));
    1063            0 :             break;
    1064            0 :          case TID_FLOAT:
    1065            0 :             debug_log(" %f", 0, *((float *) param_ptr));
    1066            0 :             break;
    1067            0 :          case TID_DOUBLE:
    1068            0 :             debug_log(" %lf", 0, *((double *) param_ptr));
    1069            0 :             break;
    1070            0 :          case TID_STRING:
    1071            0 :             debug_log(" %s", 0, (char *) param_ptr);
    1072            0 :             break;
    1073              : 
    1074            0 :          default:
    1075            0 :             debug_log(" *", 0);
    1076            0 :             break;
    1077              :          }
    1078              : 
    1079            0 :          param_ptr += param_size;
    1080              :       }
    1081              :    }
    1082              : 
    1083            0 :    debug_log(" ) : %d\n", 0, status);
    1084              : 
    1085            0 :    va_end(ap);
    1086              : 
    1087            0 :    return status;
    1088              : }
    1089              : 
    1090              : /*------------------------------------------------------------------*/
    1091              : 
    1092              : extern void mscb_cleanup(int sock);
    1093              : int _server_sock = 0;
    1094              : 
    1095            0 : void mrpc_server_loop(void)
    1096              : {
    1097              :    int i, status, sock, lsock, len, flag;
    1098              :    struct sockaddr_in serv_addr, acc_addr;
    1099              :    char str[256];
    1100              :    struct hostent *phe;
    1101              :    fd_set readfds;
    1102              :    struct timeval timeout;
    1103              : 
    1104              : #ifdef _MSC_VER
    1105              :    {
    1106              :       WSADATA WSAData;
    1107              : 
    1108              :       /* Start windows sockets */
    1109              :       if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
    1110              :          return;
    1111              :    }
    1112              : #endif
    1113              : 
    1114              :    /* create a new socket */
    1115            0 :    lsock = socket(AF_INET, SOCK_STREAM, 0);
    1116              : 
    1117            0 :    if (lsock == -1) {
    1118            0 :       perror("mrpc_server_loop");
    1119            0 :       return;
    1120              :    }
    1121              : 
    1122              :    /* bind local node name and port to socket */
    1123            0 :    memset(&serv_addr, 0, sizeof(serv_addr));
    1124            0 :    serv_addr.sin_family = AF_INET;
    1125              : 
    1126            0 :    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    1127            0 :    serv_addr.sin_port = htons((short) MSCB_RPC_PORT);
    1128              : 
    1129              :    /* try reusing address */
    1130            0 :    flag = 1;
    1131            0 :    setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, (char *) &flag, sizeof(INT));
    1132              : 
    1133            0 :    status = bind(lsock, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    1134            0 :    if (status < 0) {
    1135            0 :       perror("mrpc_server_loop");
    1136            0 :       return;
    1137              :    }
    1138              : 
    1139              :    /* listen for connection */
    1140            0 :    status = listen(lsock, SOMAXCONN);
    1141            0 :    if (status < 0) {
    1142            0 :       perror("mrpc_server_loop");
    1143            0 :       return;
    1144              :    }
    1145              : 
    1146            0 :    printf("Server listening...\n");
    1147              :    do {
    1148            0 :       FD_ZERO(&readfds);
    1149            0 :       FD_SET(lsock, &readfds);
    1150              : 
    1151            0 :       for (i = 0; i < N_MAX_CONNECTION; i++)
    1152            0 :          if (rpc_sock[i] > 0)
    1153            0 :             FD_SET(rpc_sock[i], &readfds);
    1154              : 
    1155            0 :       timeout.tv_sec = 0;
    1156            0 :       timeout.tv_usec = 100000;
    1157              : 
    1158            0 :       status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
    1159              : 
    1160            0 :       if (FD_ISSET(lsock, &readfds)) {
    1161            0 :          len = sizeof(acc_addr);
    1162              : #ifdef _MSC_VER
    1163              :          sock = accept(lsock, (struct sockaddr *) &acc_addr, (int *) &len);
    1164              : #else
    1165            0 :          sock = accept(lsock, (struct sockaddr *) &acc_addr, (socklen_t *) &len);
    1166              : #endif
    1167              : 
    1168              :          /* find new entry in socket table */
    1169            0 :          for (i = 0; i < N_MAX_CONNECTION; i++)
    1170            0 :             if (rpc_sock[i] == 0)
    1171            0 :                break;
    1172              : 
    1173            0 :          if (i == N_MAX_CONNECTION) {
    1174            0 :             printf("Maximum number of connections exceeded\n");
    1175            0 :             closesocket(sock);
    1176              :          } else {
    1177            0 :             rpc_sock[i] = sock;
    1178              : 
    1179            0 :             phe = gethostbyaddr((char *) &acc_addr.sin_addr, 4, AF_INET);
    1180            0 :             if (phe != NULL)
    1181            0 :                strcpy(str, phe->h_name);
    1182              :             else
    1183            0 :                strcpy(str, (char *) inet_ntoa(acc_addr.sin_addr));
    1184              : 
    1185            0 :             printf("Open new connection from %s\n", str);
    1186              :          }
    1187              :       } else {
    1188              :          /* check if open connection received data */
    1189            0 :          for (i = 0; i < N_MAX_CONNECTION; i++)
    1190            0 :             if (rpc_sock[i] > 0 && FD_ISSET(rpc_sock[i], &readfds)) {
    1191            0 :                len = mrecv_tcp(rpc_sock[i], rpc_net_buffer, NET_BUFFER_SIZE);
    1192            0 :                if (len < 0) {
    1193              :                   /* remove stale fd */
    1194            0 :                   mscb_cleanup(rpc_sock[i]);
    1195              : 
    1196              :                   /* close broken connection */
    1197            0 :                   printf("Close connection\n");
    1198            0 :                   closesocket(rpc_sock[i]);
    1199            0 :                   rpc_sock[i] = 0;
    1200              :                } else {
    1201            0 :                   _server_sock = rpc_sock[i];
    1202            0 :                   mrpc_execute(rpc_sock[i], rpc_net_buffer);
    1203              :                }
    1204              :             }
    1205              :       }
    1206              : 
    1207            0 :    } while (1);
    1208              : }
        

Generated by: LCOV version 2.0-1