home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / gnu / gdb-4.14-src.lha / gdb-4.14 / gdb / 29k-share / udi / udip2soc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-04  |  39.0 KB  |  1,252 lines

  1. /* Copyright 1993 Free Software Foundation, Inc.
  2.    
  3.    This file is part of GDB.
  4.    
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2 of the License, or
  8.    (at your option) any later version.
  9.    
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.    
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. static     char udip2soc_c[]="@(#)udip2soc.c    2.11  Daniel Mann";
  20. static  char udip2soc_c_AMD[]="@(#)udip2soc.c    2.8, AMD";
  21. /* 
  22. *       This module converts UDI Procedural calls into
  23. *    UDI socket messages for UNIX. 
  24. *    It is used by DFE client processes
  25. ********************************************************************** HISTORY
  26. */
  27. /* This is all unneeded on DOS machines.  */
  28. #ifndef __GO32__
  29.  
  30. #include <stdio.h>
  31. #include <string.h>
  32.  
  33. /* Before sys/file.h for Unixware.  */
  34. #include <sys/types.h>
  35.  
  36. #include <sys/file.h>
  37.  
  38. /* This used to say sys/fcntl.h, but the only systems I know of that
  39.    require that are old (pre-4.3, at least) BSD systems, which we
  40.    probably don't need to worry about.  */
  41. #include <fcntl.h>
  42.  
  43. #include <sys/wait.h>
  44. #include <sys/time.h>
  45. #include <sys/resource.h>
  46. #include <sys/socket.h>
  47. #include <netinet/in.h>
  48. #include <netdb.h>
  49. #include <signal.h>
  50. #include <sys/errno.h>
  51. #include "udiproc.h"
  52. #include "udisoc.h"
  53.  
  54. extern    int        errno;
  55. extern    int        sys_nerr;
  56. extern    char*        sys_errlist[];
  57. extern    int        udr_errno;
  58. extern    char*        getenv();
  59.  
  60. /* local type decs. and macro defs. not in a .h  file ************* MACRO/TYPE
  61. */
  62. #define        version_c 0x121        /* DFE-IPC version id */
  63. #define        TRUE -1
  64. #define        FALSE 0
  65. #define        PORT_NUM 7000
  66. #define        MAX_SESSIONS 5        /* maximum DFE-TIP connections */
  67. #define        SOC_BUF_SIZE 4* 1024    /* size of socket comms buffer */
  68. #define        SBUF_SIZE 500        /* size of string buffer */
  69. #define        ERRMSG_SIZE 500        /* size of error message buffer */
  70.  
  71. typedef struct connection_str        /* record of connect session */
  72. {
  73.     int        in_use;
  74.     char    connect_id[20];        /* connection identifier */
  75.     char    domain_string[20];    /* dommaing for conection */
  76.     char    tip_string[30];        /* TIP host name for AF_INET */
  77.     char    tip_exe[80];        /* TIP exe name */
  78.     int        dfe_sd;            /* associated DFE socket */
  79.     int        tip_pid;        /* pid of TIP process */
  80.     struct sockaddr_in dfe_sockaddr;
  81.     struct sockaddr_in tip_sockaddr_in;
  82.     struct sockaddr    tip_sockaddr;
  83. } connection_t;
  84.  
  85. typedef struct session_str
  86. {
  87.     int          in_use;
  88.     connection_t* soc_con_p;        /* associated connection */
  89.     UDISessionId  tip_id;        /* associated TIP session ID */
  90. } session_t;
  91.  
  92. /* global dec/defs. which are not in a .h   file ************* EXPORT DEC/DEFS
  93. */
  94. UDIError    dfe_errno;
  95. char    dfe_errmsg[ERRMSG_SIZE];/* error string */
  96.  
  97. /* local dec/defs. which are not in a .h   file *************** LOCAL DEC/DEFS
  98. */
  99. LOCAL connection_t    soc_con[MAX_SESSIONS];    
  100. LOCAL session_t    session[MAX_SESSIONS];    
  101. LOCAL UDR    udr;
  102. LOCAL UDR*    udrs = &udr;        /* UDR for current session */
  103. LOCAL int    current;        /* int-id for current session */
  104. LOCAL char    sbuf[SBUF_SIZE];    /* String handler buffer */
  105. LOCAL char    config_file[80];    /* path/name for config file */
  106.  
  107. /***************************************************************** UDI_CONNECT
  108. * Establish a new FDE to TIP conection. The file "./udi_soc" or
  109. * "/etc/udi_soc" may be examined to obtain the conection information
  110. * if the "Config" parameter is not a completd "line entry".
  111. *
  112. * NOTE: the Session string must not start whith white-space characters.
  113. * Format of string is:
  114. * <session>   <domain> <soc_name|host_name> <tip_exe|port> <pass to UDIconnect>
  115. * soc2cayman  AF_INET            cayman      7000           <not supported>
  116. * soc2tip     AF_UNIX   astring              tip.exe        ...
  117. */
  118. UDIError
  119. UDIConnect(Config, Session)
  120.      char *Config;        /* in  -- identification string */
  121.      UDISessionId *Session;    /* out -- session ID */
  122. {
  123.     UDIInt32    service_id = UDIConnect_c;
  124.     int        domain;
  125.     int        cnt=0;
  126.     int        rcnt, pos, params_pos=0;
  127.     char    *tip_main_string;
  128.     char    *env_p;
  129.     struct hostent    *tip_info_p;
  130.     FILE    *fd;
  131. #if 0
  132.     FILE    *f_p;
  133. #endif
  134.     UDIUInt32    TIPIPCId;
  135.     UDIUInt32    DFEIPCId;
  136.  
  137. #if 0 /* This is crap.  It assumes that udi_soc is executable! */
  138.     sprintf(sbuf, "which udi_soc");
  139.     f_p = popen(sbuf, "r");
  140.     if(f_p)
  141.     {   while( (sbuf[cnt++]=getc(f_p)) != EOF);
  142.     sbuf[cnt-2]=0;
  143.     }
  144.     pclose(f_p);
  145. #endif
  146.  
  147.     for (rcnt=0;
  148.      rcnt < MAX_SESSIONS && session[rcnt].in_use;
  149.      rcnt++);
  150.  
  151.     if (rcnt >= MAX_SESSIONS)
  152.       {
  153.     sprintf(dfe_errmsg, "DFE-ipc ERROR: Too many sessions already open");
  154.     return UDIErrorIPCLimitation;
  155.       }
  156.  
  157.     /* One connection can be multiplexed between several sessions. */
  158.  
  159.     for (cnt=0;
  160.      cnt < MAX_SESSIONS && soc_con[cnt].in_use;
  161.      cnt++);
  162.  
  163.     if (cnt >= MAX_SESSIONS)
  164.       {
  165.         sprintf(dfe_errmsg,
  166.         "DFE-ipc ERROR: Too many connections already open");
  167.         return UDIErrorIPCLimitation;
  168.       }
  169.  
  170.     *Session = rcnt;
  171.     session[rcnt].soc_con_p = &soc_con[cnt];
  172.  
  173.     if (strchr(Config, ' '))        /* test if file entry given */
  174.       {
  175.         soc_con[cnt].in_use = TRUE;
  176.         sscanf(Config, "%s %s %s %s %n",
  177.            soc_con[cnt].connect_id,
  178.            soc_con[cnt].domain_string,
  179.            soc_con[cnt].tip_string,
  180.            soc_con[cnt].tip_exe,
  181.            ¶ms_pos);
  182.     tip_main_string = Config + params_pos;
  183.       }
  184.     else                /* here if need to read udi_soc file */
  185.       {
  186.     strcpy(config_file, "udi_soc");
  187.     env_p = getenv("UDICONF");
  188.     if (env_p)
  189.       strcpy(config_file, env_p);
  190.  
  191.     fd = fopen(config_file, "r");
  192.  
  193.     if (!fd)
  194.       {
  195.         sprintf(dfe_errmsg, "UDIConnect, can't open udi_soc file:\n%s ",
  196.             sys_errlist[errno]);
  197.         dfe_errno = UDIErrorCantOpenConfigFile;
  198.         goto tip_failure;
  199.       }
  200.  
  201.     while (1)
  202.       {
  203.         if (fscanf(fd, "%s %s %s %s %[^\n]\n",
  204.                soc_con[cnt].connect_id,
  205.                soc_con[cnt].domain_string,
  206.                soc_con[cnt].tip_string,
  207.                soc_con[cnt].tip_exe,
  208.                sbuf) == EOF)
  209.           break;
  210.  
  211.         if (strcmp(Config, soc_con[cnt].connect_id) != 0)
  212.           continue;
  213.  
  214.         soc_con[cnt].in_use = TRUE; /* here if entry found */
  215.  
  216.         tip_main_string = sbuf;
  217.         break;
  218.       }
  219.  
  220.     fclose(fd);
  221.     if (!soc_con[cnt].in_use)
  222.       {
  223.         sprintf(dfe_errmsg,
  224.             "UDIConnect, can't find `%s' entry in udi_soc file",
  225.             Config);
  226.         dfe_errno = UDIErrorNoSuchConfiguration;
  227.         goto tip_failure;
  228.       }
  229.       }
  230. /*----------------------------------------------------------- SELECT DOMAIN */
  231.     if (strcmp(soc_con[cnt].domain_string, "AF_UNIX") == 0)
  232.       domain = AF_UNIX;
  233.     else if (strcmp(soc_con[cnt].domain_string, "AF_INET") == 0)
  234.       domain = AF_INET;
  235.     else
  236.       {
  237.         sprintf(dfe_errmsg, "DFE-ipc ERROR: socket address family not known");
  238.     dfe_errno = UDIErrorBadConfigFileEntry;
  239.     goto tip_failure;
  240.       }
  241.  
  242. /*---------------------------------------------------- MULTIPLEXED SOCKET ? */
  243. /* If the requested session requires communication with
  244.    a TIP which already has a socket connection established,
  245.    then we do not create a new socket but multiplex the
  246.    existing one. A TIP is said to use the same socket if
  247.    socket-name/host-name and the domain are the same.
  248.  */
  249.     for (rcnt=0; rcnt < MAX_SESSIONS; rcnt++)
  250.       {
  251.     if (soc_con[rcnt].in_use
  252.         && rcnt != cnt
  253.         && strcmp(soc_con[cnt].domain_string,
  254.               soc_con[rcnt].domain_string) == 0
  255.         && strcmp(soc_con[cnt].tip_string,
  256.               soc_con[rcnt].tip_string) == 0)
  257.       {
  258.         session[*Session].soc_con_p = &soc_con[rcnt];
  259.         soc_con[cnt].in_use = FALSE;    /* don't need new connect */
  260.         goto tip_connect; 
  261.     }
  262.       }
  263. /*------------------------------------------------------------------ SOCKET */
  264.     soc_con[cnt].dfe_sd = socket(domain, SOCK_STREAM, 0);
  265.     if (soc_con[cnt].dfe_sd == -1)
  266.       {
  267.         sprintf(dfe_errmsg, "DFE-ipc ERROR, socket() call failed %s ",
  268.         sys_errlist[errno]);
  269.     dfe_errno = UDIErrorUnknownError;
  270.     goto tip_failure;
  271.       }
  272.  
  273. /*--------------------------------------------------------- AF_UNIX CONNECT */
  274.     if (domain == AF_UNIX)
  275.       {
  276.     if (strcmp(soc_con[cnt].tip_string, "*") == 0)
  277.       {
  278.         for (pos = 0; pos < 20; pos++)
  279.           {
  280.         int f;
  281.  
  282.         sprintf(soc_con[cnt].tip_string,"/tmp/U%d", getpid() + pos);
  283.         f = open(soc_con[cnt].tip_string, O_CREAT);
  284.         if (f == -1)
  285.           continue;
  286.  
  287.         close(f);
  288.         unlink(soc_con[cnt].tip_string);
  289.         break;
  290.           }
  291.  
  292.         if (pos >= 20)
  293.           {
  294.         sprintf(dfe_errmsg,
  295.             "DFE-ipc ERROR, can't create random socket name");
  296.         dfe_errno = UDIErrorCantConnect;
  297.         goto tip_failure;
  298.           }
  299.       }
  300.  
  301.         soc_con[cnt].tip_sockaddr.sa_family = domain;
  302.         memcpy(soc_con[cnt].tip_sockaddr.sa_data,
  303.           soc_con[cnt].tip_string,
  304.           sizeof(soc_con[cnt].tip_sockaddr.sa_data));
  305.         if (connect(soc_con[cnt].dfe_sd,
  306.             &soc_con[cnt].tip_sockaddr,
  307.             sizeof(soc_con[cnt].tip_sockaddr)))
  308.       { /* if connect() fails assume TIP not yet started */
  309. /*------------------------------------------------------------ AF_UNIX EXEC */
  310.         int    pid;
  311.         int statusp;
  312.         char *arg0;
  313.  
  314.         arg0 = strrchr(soc_con[cnt].tip_exe,'/');
  315.  
  316.         if (arg0)
  317.           arg0++;
  318.         else
  319.           arg0 = soc_con[cnt].tip_exe;
  320.     
  321.         pid = vfork();
  322.  
  323.         if (pid == 0)    /* Child */
  324.           {
  325.         execlp(soc_con[cnt].tip_exe,
  326.                arg0,
  327.                soc_con[cnt].domain_string,
  328.                soc_con[cnt].tip_string,
  329.                NULL);
  330.             _exit(1);
  331.           }
  332.  
  333.             if (waitpid(pid, &statusp, WNOHANG))
  334.           {
  335.             sprintf(dfe_errmsg, "DFE-ipc ERROR: can't exec the TIP");
  336.             dfe_errno = UDIErrorCantStartTIP;
  337.         goto tip_failure;
  338.           }
  339.  
  340.         pos = 3;
  341.             for (pos = 3; pos > 0; pos--)
  342.           {
  343.         if (!connect(soc_con[cnt].dfe_sd, 
  344.                  &soc_con[cnt].tip_sockaddr,
  345.                  sizeof(soc_con[cnt].tip_sockaddr)))
  346.           break;
  347.         sleep(1);
  348.           }
  349.  
  350.         if (pos == 0)
  351.           {
  352.         sprintf(dfe_errmsg, "DFE-ipc ERROR, connect() call failed: %s",
  353.                 sys_errlist[errno]);
  354.             dfe_errno = UDIErrorCantConnect;
  355.         goto tip_failure;
  356.           }
  357.       }
  358.       }
  359. /*--------------------------------------------------------- AF_INET CONNECT */
  360.     else if (domain == AF_INET)
  361.       {
  362.     fprintf(stderr,
  363.         "DFE-ipc WARNING, need to have first started remote TIP");
  364.  
  365.     soc_con[cnt].tip_sockaddr_in.sin_family = domain;
  366.     soc_con[cnt].tip_sockaddr_in.sin_addr.s_addr =
  367.         inet_addr(soc_con[cnt].tip_string);
  368.     if (soc_con[cnt].tip_sockaddr_in.sin_addr.s_addr == -1)
  369.       {
  370.         tip_info_p = gethostbyname(soc_con[cnt].tip_string);
  371.         if (tip_info_p == NULL)
  372.           {
  373.         sprintf(dfe_errmsg,"DFE-ipc ERROR, No such host %s",
  374.             soc_con[cnt].tip_string);
  375.             dfe_errno = UDIErrorNoSuchConnection;
  376.         goto tip_failure;
  377.           }
  378.         memcpy((char *)&soc_con[cnt].tip_sockaddr_in.sin_addr,
  379.           tip_info_p->h_addr,
  380.           tip_info_p->h_length);
  381.       }
  382.     soc_con[cnt].tip_sockaddr_in.sin_port
  383.       = htons(atoi(soc_con[cnt].tip_exe));
  384.  
  385.         if (connect(soc_con[cnt].dfe_sd,
  386.             (struct sockaddr *) &soc_con[cnt].tip_sockaddr_in,
  387.             sizeof(soc_con[cnt].tip_sockaddr_in)))
  388.       {
  389.             sprintf(dfe_errmsg, "DFE-ipc ERROR, connect() call failed %s ",
  390.             sys_errlist[errno]);
  391.         dfe_errno = UDIErrorCantConnect;
  392.         goto tip_failure;
  393.       }
  394.       }
  395. /*------------------------------------------------------------- TIP CONNECT */
  396.     if (cnt == 0) udr_create(udrs, soc_con[cnt].dfe_sd, SOC_BUF_SIZE);
  397.  
  398. tip_connect:
  399.     current = cnt;
  400.     session[*Session].in_use = TRUE;    /* session id is now in use */
  401.  
  402.     udr_errno = 0;
  403.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  404.     udr_UDIInt32(udrs, &service_id);
  405.  
  406.     DFEIPCId = (company_c << 16) + (product_c << 12) + version_c;
  407.     udr_UDIUInt32(udrs, &DFEIPCId);
  408.  
  409.     udr_string(udrs, tip_main_string);
  410.  
  411.     udr_sendnow(udrs);
  412.  
  413.     udrs->udr_op = UDR_DECODE;        /* recv all "out" parameters */
  414.     udr_UDIUInt32(udrs, &TIPIPCId);
  415.     if ((TIPIPCId & 0xfff) < version_c)
  416.       sprintf(dfe_errmsg, "DFE-ipc: Obsolete TIP Specified");
  417.  
  418.     udr_UDIInt32(udrs, &soc_con[cnt].tip_pid);
  419.  
  420.     udr_UDISessionId(udrs, &session[*Session].tip_id);
  421.  
  422.     udr_UDIError(udrs, &dfe_errno);
  423.     if (dfe_errno > 0) UDIKill(*Session, 0);
  424.  
  425.     return dfe_errno;
  426.  
  427. tip_failure:
  428.  
  429.     soc_con[cnt].in_use = FALSE;
  430.     session[*Session].in_use = FALSE;
  431. /* XXX - Should also close dfe_sd, but not sure what to do if muxed */
  432.     return dfe_errno;
  433. }
  434.  
  435. /************************************************************** UDI_Disconnect
  436. * UDIDisconnect() should be called before exiting the
  437. * DFE to ensure proper shut down of the TIP.
  438. */
  439. UDIError UDIDisconnect(Session,  Terminate)
  440. UDISessionId    Session;
  441. UDIBool        Terminate;
  442. {
  443.     int    cnt;
  444.     UDIInt32    service_id = UDIDisconnect_c;
  445.     if(Session < 0 || Session > MAX_SESSIONS)
  446.     {
  447.     sprintf(dfe_errmsg," SessionId not valid (%d)", Session);
  448.     return UDIErrorNoSuchConfiguration;
  449.     }
  450.     udr_errno = 0;
  451.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  452.     udr_UDIInt32(udrs, &service_id);
  453.     udr_UDISessionId(udrs, &session[Session].tip_id);
  454.     udr_UDIBool(udrs, &Terminate);
  455.     udr_sendnow(udrs);
  456.  
  457.     session[Session].in_use = FALSE;    /* session id is now free */
  458.     for (cnt=0; cnt < MAX_SESSIONS; cnt++)
  459.         if(session[cnt].in_use
  460.     && session[cnt].soc_con_p == session[Session].soc_con_p
  461.         ) break;
  462.     if(cnt >= MAX_SESSIONS)    /* test if socket not multiplexed */
  463.         if(shutdown(session[Session].soc_con_p->dfe_sd, 2))
  464.         {
  465.              sprintf(dfe_errmsg, "DFE-ipc WARNING: socket shutdown failed");
  466.         return UDIErrorIPCInternal;
  467.         }
  468.     else
  469.       session[Session].soc_con_p->in_use = 0;
  470.  
  471.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  472.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  473.     return dfe_errno;
  474. }
  475.  
  476. /******************************************************************** UDI_KILL
  477. * UDIKill() is used to send a signal to the TIP.
  478. * This is a private IPC call.
  479. */
  480. UDIError UDIKill(Session,  Signal)
  481. UDISessionId    Session;
  482. UDIInt32    Signal;
  483. {
  484.     int    cnt;
  485.     UDIInt32    service_id = UDIKill_c;
  486.     if(Session < 0 || Session > MAX_SESSIONS)
  487.     {
  488.     sprintf(dfe_errmsg," SessionId not valid (%d)", Session);
  489.     return UDIErrorNoSuchConfiguration;
  490.     }
  491.     udr_errno = 0;
  492.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  493.     udr_UDIInt32(udrs, &service_id);
  494.     udr_UDISessionId(udrs, &session[Session].tip_id);
  495.     udr_UDIInt32(udrs, &Signal);
  496.     udr_sendnow(udrs);
  497.  
  498.     session[Session].in_use = FALSE;    /* session id is now free */
  499.     for (cnt=0; cnt < MAX_SESSIONS; cnt++)
  500.         if(session[cnt].in_use
  501.     && session[cnt].soc_con_p == session[Session].soc_con_p
  502.         ) break;
  503.     if(cnt < MAX_SESSIONS)    /* test if socket not multiplexed */
  504.         if(shutdown(session[Session].soc_con_p->dfe_sd, 2))
  505.         {
  506.              sprintf(dfe_errmsg, "DFE-ipc WARNING: socket shutdown failed");
  507.         return UDIErrorIPCInternal;
  508.         }
  509.     else
  510.       session[Session].soc_con_p->in_use = 0;
  511.  
  512.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  513.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  514.     return dfe_errno;
  515. }
  516.  
  517. /************************************************** UDI_Set_Current_Connection
  518. * If you are connected to multiple TIPs, you can change
  519. * TIPs using UDISetCurrentConnection().
  520. */
  521. UDIError UDISetCurrentConnection(Session)
  522. UDISessionId    Session;
  523. {
  524.     UDIInt32    service_id = UDISetCurrentConnection_c;
  525.  
  526.     if(Session < 0 || Session > MAX_SESSIONS)
  527.     return UDIErrorNoSuchConfiguration;
  528.     if(!session[Session].in_use)         /* test if not in use yet */
  529.     return UDIErrorNoSuchConnection;
  530.  
  531.     current = Session;
  532.     /* change socket or multiplex the same socket  */
  533.     udrs->sd = session[Session].soc_con_p->dfe_sd;
  534.  
  535.     udr_errno = 0;
  536.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  537.     udr_UDIInt32(udrs, &service_id);
  538.     udr_UDISessionId(udrs, &session[Session].tip_id);
  539.     udr_sendnow(udrs);
  540.     if(udr_errno) return udr_errno;
  541.  
  542.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  543.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  544.     return dfe_errno;
  545. }
  546.  
  547. /************************************************************ UDI_Capabilities
  548. * The DFE uses UDICapabilities() to both inform the TIP
  549. * of what services the DFE offers and to inquire of the
  550. * TIP what services the TIP offers.
  551. */
  552. UDIError UDICapabilities(TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId,
  553.         TIPIPCId, TIPString)
  554. UDIUInt32    *TIPId;        /* out */
  555. UDIUInt32    *TargetId;    /* out */
  556. UDIUInt32    DFEId;        /* in */
  557. UDIUInt32    DFE;        /* in */
  558. UDIUInt32    *TIP;        /* out */
  559. UDIUInt32    *DFEIPCId;    /* out */
  560. UDIUInt32    *TIPIPCId;    /* out */
  561. char        *TIPString;    /* out */
  562. {
  563.     UDIInt32    service_id = UDICapabilities_c;
  564.     int        size;
  565.  
  566.     udr_errno = 0;
  567.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  568.     udr_UDIInt32(udrs, &service_id);
  569.     udr_UDIInt32(udrs, &DFEId);
  570.     udr_UDIInt32(udrs, &DFE);
  571.     udr_sendnow(udrs);
  572.     if(udr_errno) return udr_errno;
  573.  
  574.     udrs->udr_op = UDR_DECODE;        /* receive all "out" paramters */
  575.     udr_UDIInt32(udrs, TIPId);
  576.     udr_UDIInt32(udrs, TargetId);
  577.     udr_UDIInt32(udrs, TIP);
  578.     udr_UDIInt32(udrs, DFEIPCId);
  579.     *DFEIPCId = (company_c << 16) + (product_c << 12) + version_c;
  580.     udr_UDIInt32(udrs, TIPIPCId);
  581.     udr_string(udrs, sbuf);
  582.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  583.     size = strlen(sbuf);
  584.     if(size +1 > 80) return -1;        /* test if sufficient space */
  585.     strcpy(TIPString, sbuf);
  586.     return dfe_errno;
  587. }
  588.  
  589. /********************************************************** UDI_Enumerate_TIPs
  590. * Used by the DFE to enquire about available TIP
  591. * connections.
  592. */
  593. UDIError UDIEnumerateTIPs(UDIETCallback)
  594.   int (*UDIETCallback)();        /* In -- function to callback */
  595. {
  596.     FILE    *fp;
  597.  
  598.     fp = fopen(config_file, "r");
  599.     if(fp == NULL)
  600.     return UDIErrorCantOpenConfigFile;
  601.     while(fgets( sbuf, SBUF_SIZE, fp))
  602.     if(UDIETCallback( sbuf) == UDITerminateEnumeration)
  603.         break;
  604.     fclose( fp);
  605.     return UDINoError;            /* return success */
  606. }
  607.  
  608. /*********************************************************** UDI_GET_ERROR_MSG
  609. * Some errors are target specific. They are indicated
  610. * by a negative error return value. The DFE uses
  611. * UDIGetErrorMsg() to get the descriptive text for
  612. * the error message which can then  be  displayed  to
  613. * the user.
  614. */
  615. UDIError UDIGetErrorMsg(error_code, msg_len, msg, CountDone)
  616. UDIError    error_code;        /* In */
  617. UDISizeT    msg_len;        /* In  -- allowed message space */
  618. char*        msg;            /* Out -- length of message*/
  619. UDISizeT    *CountDone;        /* Out -- number of characters */
  620. {
  621.     UDIInt32    service_id = UDIGetErrorMsg_c;
  622.     int        size;
  623.  
  624.     udr_errno = 0;
  625.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  626.     udr_UDIInt32(udrs, &service_id);
  627.     udr_UDIError(udrs, &error_code);
  628.     udr_UDISizeT(udrs, &msg_len);
  629.     udr_sendnow(udrs);
  630.     if(udr_errno) return udr_errno;
  631.  
  632.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  633.     udr_string(udrs, sbuf);
  634.     udr_UDISizeT(udrs, CountDone);
  635.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  636.     size = strlen(sbuf);
  637.     if(size +1 > msg_len) return -1;    /* test if sufficient space */
  638.     strcpy(msg, sbuf);
  639.     return dfe_errno;
  640. }
  641.  
  642. /******************************************************* UDI_GET_TARGET_CONFIG
  643. * UDIGetTargetConfig() gets information about the target.
  644. */
  645. UDIError UDIGetTargetConfig(KnownMemory, NumberOfRanges, ChipVersions,
  646.         NumberOfChips)
  647. UDIMemoryRange    KnownMemory[];        /* Out */
  648. UDIInt        *NumberOfRanges;    /* In and Out */
  649. UDIUInt32    ChipVersions[];        /* Out */
  650. UDIInt        *NumberOfChips;        /* In and Out */
  651. {
  652.     UDIInt32    service_id = UDIGetTargetConfig_c;
  653.     int        cnt;
  654.     int        MaxOfRanges = *NumberOfRanges;
  655.  
  656.     udr_errno = 0;
  657.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  658.     udr_UDIInt32(udrs, &service_id);
  659.     udr_UDIInt(udrs, NumberOfRanges);
  660.     udr_UDIInt(udrs, NumberOfChips);
  661.     udr_sendnow(udrs);
  662.     if(udr_errno) return udr_errno;
  663.  
  664.     udrs->udr_op = UDR_DECODE;        /* receive all "out" paramters */
  665.     for(cnt=1; cnt <= MaxOfRanges; cnt++)
  666.         udr_UDIMemoryRange(udrs, &KnownMemory[cnt-1]);
  667.     udr_UDIInt(udrs, NumberOfRanges);
  668.     udr_UDIInt(udrs, NumberOfChips);
  669.     for(cnt=1; cnt <= *NumberOfChips; cnt++)
  670.         udr_UDIUInt32(udrs, &ChipVersions[cnt -1]);
  671.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  672.     return dfe_errno;
  673. }
  674.  
  675. /********************************************************** UDI_CREATE_PRCOESS
  676. * UDICreateProcess() tells the  target  OS  that  a
  677. * process is to be created and gets a PID back unless
  678. * there is some error.
  679. */
  680. UDIError UDICreateProcess(pid)
  681. UDIPId    *pid;    /* out */
  682. {
  683.     UDIInt32    service_id = UDICreateProcess_c;
  684.  
  685.     udr_errno = 0;
  686.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  687.     udr_UDIInt32(udrs, &service_id);
  688.     udr_sendnow(udrs);
  689.     if(udr_errno) return udr_errno;
  690.  
  691.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  692.     udr_UDIPId(udrs, pid);
  693.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  694.     return dfe_errno;
  695. }
  696.  
  697. /***************************************************** UDI_Set_Current_Process
  698. * UDISetCurrentProcess  uses   a   pid   supplied   by
  699. * UDICreateProcess  and  sets it as the default for all
  700. * udi calls until a new one is set.  A user of  a
  701. */
  702. UDIError UDISetCurrentProcess (pid)
  703. UDIPId    pid;            /* In */
  704. {
  705.     UDIInt32    service_id = UDISetCurrentProcess_c;
  706.  
  707.     udr_errno = 0;
  708.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  709.     udr_UDIInt32(udrs, &service_id);
  710.     udr_UDIPId(udrs, &pid);
  711.     udr_sendnow(udrs);
  712.     if(udr_errno) return udr_errno;
  713.  
  714.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  715.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  716.     return dfe_errno;
  717. }
  718.  
  719. /****************************************************** UDI_INITIALISE_PROCESS
  720. * UDIInitializeProcess() prepare process for
  721. * execution. (Reset processor if process os processor).
  722. */
  723. UDIError UDIInitializeProcess( ProcessMemory, NumberOfRanges, EntryPoint,
  724.         StackSizes, NumberOfStacks, ArgString)
  725. UDIMemoryRange    ProcessMemory[];    /* In */
  726. UDIInt        NumberOfRanges;        /* In */
  727. UDIResource    EntryPoint;        /* In */
  728. CPUSizeT    *StackSizes;        /* In */
  729. UDIInt        NumberOfStacks;        /* In */
  730. char        *ArgString;        /* In */
  731. {
  732.     UDIInt32    service_id = UDIInitializeProcess_c;
  733.     int        cnt;
  734.  
  735.     udr_errno = 0;
  736.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  737.     udr_UDIInt32(udrs, &service_id);
  738.     udr_UDIInt(udrs, &NumberOfRanges);
  739.     for(cnt = 0; cnt < NumberOfRanges; cnt++)
  740.     udr_UDIMemoryRange(udrs, &ProcessMemory[cnt] );
  741.     udr_UDIResource(udrs, &EntryPoint);
  742.     udr_UDIInt(udrs, &NumberOfStacks);
  743.     for(cnt = 0; cnt < NumberOfStacks; cnt++)
  744.     udr_CPUSizeT(udrs, &StackSizes[cnt]);
  745.     udr_string(udrs, ArgString);
  746.     udr_sendnow(udrs);
  747.     if(udr_errno) return udr_errno;
  748.  
  749.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  750.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  751.     return dfe_errno;
  752. }
  753.  
  754. /********************************************************* UDI_DESTROY_PROCESS
  755. * UDIDestroyProcess() frees a process resource
  756. * previously created by UDICreateProcess().
  757. */
  758. UDIError UDIDestroyProcess(pid)
  759. UDIPId   pid;    /* in */
  760. {
  761.     UDIInt32    service_id = UDIDestroyProcess_c;
  762.  
  763.     udr_errno = 0;
  764.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  765.     udr_UDIInt32(udrs, &service_id);
  766.     udr_UDIPId(udrs, &pid);
  767.     udr_sendnow(udrs);
  768.     if(udr_errno) return udr_errno;
  769.  
  770.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  771.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  772.     return dfe_errno;
  773. }
  774.  
  775. /****************************************************************** UDI_READ
  776. * UDIRead() reads a block of objects from  a  target
  777. * address space  to host space.
  778. */
  779.  
  780. UDIError UDIRead (from, to, count, size, count_done, host_endian)
  781. UDIResource    from;        /* in - source address on target */
  782. UDIHostMemPtr    to;        /* out - destination address on host */
  783. UDICount    count;        /* in -- count of objects to be transferred */
  784. UDISizeT    size;        /* in -- size of each object */
  785. UDICount    *count_done;    /* out - count actually transferred */
  786. UDIBool        host_endian;    /* in -- flag for endian information */
  787. {
  788.     UDIInt32    service_id = UDIRead_c;
  789.     int        byte_count;
  790.  
  791.     udr_errno = 0;
  792.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  793.     udr_UDIInt32(udrs, &service_id);
  794.     udr_UDIResource(udrs, &from);
  795.     udr_UDICount(udrs, &count);
  796.     udr_UDISizeT(udrs, &size);
  797.     udr_UDIBool(udrs, &host_endian);
  798.     udr_sendnow(udrs);
  799.     if(udr_errno) return udr_errno;
  800.  
  801.     udrs->udr_op = UDR_DECODE;        /* receive all "out" paramters */
  802.     udr_UDICount(udrs, count_done);
  803.     byte_count = (*count_done) * size;
  804.     if(*count_done > 0 && *count_done <= count)
  805.         udr_bytes(udrs, to, byte_count);
  806.     if(udr_errno) return udr_errno;
  807.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  808.     return dfe_errno;
  809. }
  810.  
  811. /****************************************************************** UDI_WRITE
  812. * UDIWrite() writes a block  of  objects  from  host
  813. * space  to  a  target  address+space.
  814. */
  815. UDIError UDIWrite( from, to, count, size, count_done, host_endian )
  816. UDIHostMemPtr    from;        /* in -- source address on host */
  817. UDIResource    to;        /* in -- destination address on target */
  818. UDICount    count;        /* in -- count of objects to be transferred */
  819. UDISizeT    size;        /* in -- size of each object */
  820. UDICount    *count_done;    /* out - count actually transferred */
  821. UDIBool        host_endian;    /* in -- flag for endian information */
  822. {
  823.     UDIInt32    service_id = UDIWrite_c;
  824.     int        byte_count = count * size;
  825.  
  826.     udr_errno = 0;
  827.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  828.     udr_UDIInt32(udrs, &service_id);
  829.     udr_UDIResource(udrs, &to);
  830.     udr_UDICount(udrs, &count);
  831.     udr_UDISizeT(udrs, &size);
  832.     udr_UDIBool(udrs, &host_endian);
  833.     udr_bytes(udrs, from, byte_count);
  834.     udr_sendnow(udrs);
  835.     if(udr_errno) return udr_errno;
  836.  
  837.     udrs->udr_op = UDR_DECODE;        /* receive all "out" paramters */
  838.     udr_UDICount(udrs, count_done);
  839.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  840.     return dfe_errno;
  841. }
  842.  
  843. /******************************************************************** UDI_COPY
  844. * UDICopy() copies a block of objects from one  target
  845. * get  address/space to another target address/space.
  846. */
  847. UDIError UDICopy(from, to, count, size, count_done, direction )
  848. UDIResource    from;        /* in -- destination address on target */
  849. UDIResource    to;        /* in -- source address on target */
  850. UDICount    count;        /* in -- count of objects to be transferred */
  851. UDISizeT    size;        /* in -- size of each object */
  852. UDICount    *count_done;    /* out - count actually transferred */
  853. UDIBool        direction;    /* in -- high-to-low or reverse */
  854. {
  855.     UDIInt32    service_id = UDICopy_c;
  856.  
  857.     udr_errno = 0;
  858.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  859.     udr_UDIInt32(udrs, &service_id);
  860.     udr_UDIResource(udrs, &from);
  861.     udr_UDIResource(udrs, &to);
  862.     udr_UDICount(udrs, &count);
  863.     udr_UDISizeT(udrs, &size);
  864.     udr_UDIBool(udrs, &direction);
  865.     udr_sendnow(udrs);
  866.     if(udr_errno) return udr_errno;
  867.  
  868.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  869.     udr_UDICount(udrs, count_done);
  870.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  871.     return dfe_errno;
  872. }
  873.  
  874. /***************************************************************** UDI_EXECUTE
  875. * UDIExecute() continues execution  of  the  default
  876. * process from the current PC.
  877. */
  878. UDIError UDIExecute()
  879. {
  880.     UDIInt32    service_id = UDIExecute_c;
  881.  
  882.     udr_errno = 0;
  883.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  884.     udr_UDIInt32(udrs, &service_id);
  885.     udr_sendnow(udrs);
  886.     if(udr_errno) return udr_errno;
  887.  
  888.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  889.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  890.     return dfe_errno;
  891. }
  892.  
  893. /******************************************************************** UDI_STEP
  894. * UDIStep()  specifies  a  number  of  "instruction"
  895. * steps  to  make.
  896. */
  897. UDIError UDIStep(steps, steptype, range)
  898. UDIUInt32    steps;        /* in -- number of steps */
  899. UDIStepType    steptype;       /* in -- type of stepping to be done */
  900. UDIRange    range;          /* in -- range if StepInRange is TRUE */
  901. {
  902.     UDIInt32    service_id = UDIStep_c;
  903.  
  904.     udr_errno = 0;
  905.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  906.     udr_UDIInt32(udrs, &service_id);
  907.     udr_UDIInt32(udrs, &steps);
  908.     udr_UDIStepType(udrs, &steptype);
  909.     udr_UDIRange(udrs, &range);
  910.     udr_sendnow(udrs);
  911.     if(udr_errno) return udr_errno;
  912.  
  913.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  914.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  915.     return dfe_errno;
  916. }
  917.  
  918. /******************************************************************** UDI_STOP
  919. * UDIStop() stops the default process
  920. */
  921. UDIVoid UDIStop()
  922. {
  923.     if (strcmp(session[current].soc_con_p->domain_string, "AF_UNIX") == 0)
  924.       kill(session[current].soc_con_p->tip_pid, SIGINT);
  925.     else
  926.       udr_signal(udrs);
  927.  
  928. /* XXX - should clean up session[] and soc_con[] structs here as well... */
  929.  
  930.     return;
  931. }
  932.  
  933. /******************************************************************** UDI_WAIT
  934. * UDIWait() returns the state of the target  procesor.
  935. */
  936. UDIError UDIWait(maxtime, pid, stop_reason)
  937. UDIInt32   maxtime;        /* in -- maximum time to wait for completion */
  938. UDIPId     *pid;           /* out -- pid of process which stopped if any */
  939. UDIUInt32  *stop_reason;   /* out -- PC where process stopped */
  940. {
  941.     UDIInt32    service_id = UDIWait_c;
  942.  
  943.     udr_errno = 0;
  944.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  945.     udr_UDIInt32(udrs, &service_id);
  946.     udr_UDIInt32(udrs, &maxtime);
  947.     udr_sendnow(udrs);
  948.     if(udr_errno) return udr_errno;
  949.  
  950.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  951.     udr_UDIPId(udrs, pid);
  952.     udr_UDIUInt32(udrs, stop_reason);
  953.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  954.     return dfe_errno;
  955. }
  956.  
  957. /********************************************************** UDI_SET_BREAKPOINT
  958. * UDISetBreakpoint() sets a breakpoint  at  an  adress
  959. * and  uses  the  passcount  to state how many
  960. * times that instruction should  be  hit  before  the
  961. * break  occurs.
  962. */
  963. UDIError UDISetBreakpoint (addr, passcount, type, break_id)
  964. UDIResource    addr;        /* in -- where breakpoint gets set */
  965. UDIInt32    passcount;    /* in -- passcount for breakpoint  */
  966. UDIBreakType    type;        /* in -- breakpoint type */
  967. UDIBreakId    *break_id;    /* out - assigned break id */
  968. {
  969.     UDIInt32    service_id = UDISetBreakpoint_c;
  970.  
  971.     udr_errno = 0;
  972.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  973.     udr_UDIInt32(udrs, &service_id);
  974.     udr_UDIResource(udrs, &addr);
  975.     udr_UDIInt32(udrs, &passcount);
  976.     udr_UDIBreakType(udrs, &type);
  977.     udr_sendnow(udrs);
  978.     if(udr_errno) return udr_errno;
  979.  
  980.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  981.     udr_UDIBreakId(udrs, break_id);
  982.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  983.     return dfe_errno;
  984. }
  985.  
  986. /******************************************************** UDI_QUERY_BREAKPOINT
  987. */
  988. UDIError UDIQueryBreakpoint (break_id, addr, passcount, type, current_count)
  989. UDIBreakId    break_id;    /* in -- assigned break id */
  990. UDIResource    *addr;        /* out - where breakpoint was set */
  991. UDIInt32    *passcount;    /* out - trigger passcount for breakpoint  */
  992. UDIBreakType    *type;        /* out - breakpoint type */
  993. UDIInt32    *current_count;    /* out - current count for breakpoint  */
  994. {
  995.     UDIInt32    service_id = UDIQueryBreakpoint_c;
  996.  
  997.     udr_errno = 0;
  998.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  999.     udr_UDIInt32(udrs, &service_id);
  1000.     udr_UDIBreakId(udrs, &break_id);
  1001.     udr_sendnow(udrs);
  1002.     if(udr_errno) return udr_errno;
  1003.  
  1004.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  1005.     udr_UDIResource(udrs, addr);
  1006.     udr_UDIInt32(udrs, passcount);
  1007.     udr_UDIBreakType(udrs, type);
  1008.     udr_UDIInt32(udrs, current_count);
  1009.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  1010.     return dfe_errno;
  1011. }
  1012.  
  1013. /******************************************************** UDI_CLEAR_BREAKPOINT
  1014. * UDIClearBreakpoint() is used to  clear  a  breakpoint.
  1015. */
  1016. UDIError UDIClearBreakpoint (break_id)
  1017. UDIBreakId    break_id;    /* in -- assigned break id */
  1018. {
  1019.     UDIInt32    service_id = UDIClearBreakpoint_c;
  1020.  
  1021.     udr_errno = 0;
  1022.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  1023.     udr_UDIInt32(udrs, &service_id);
  1024.     udr_UDIBreakId(udrs, &break_id);
  1025.     udr_sendnow(udrs);
  1026.     if(udr_errno) return udr_errno;
  1027.  
  1028.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  1029.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  1030.     return dfe_errno;
  1031. }
  1032.  
  1033. /************************************************************** UDI_GET_STDOUT
  1034. * UDIGetStdout()  is  called   when   a   call   to
  1035. * UDIWait() indicates there is STD output data ready. 
  1036. */
  1037. UDIError UDIGetStdout(buf, bufsize, count_done)
  1038. UDIHostMemPtr    buf;        /* out -- buffer to be filled */
  1039. UDISizeT    bufsize;    /* in  -- buffer size in bytes */
  1040. UDISizeT    *count_done;    /* out -- number of bytes written to buf */
  1041. {
  1042.     UDIInt32    service_id = UDIGetStdout_c;
  1043.  
  1044.     udr_errno = 0;
  1045.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  1046.     udr_UDIInt32(udrs, &service_id);
  1047.     udr_UDISizeT(udrs, &bufsize);
  1048.     udr_sendnow(udrs);
  1049.     if(udr_errno) return udr_errno;
  1050.  
  1051.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  1052.     udr_UDISizeT(udrs, count_done);
  1053.     udr_bytes(udrs, buf, *count_done);
  1054.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  1055.     return dfe_errno;
  1056. }
  1057.  
  1058. /************************************************************** UDI_GET_STDERR
  1059. * UDIGetStderr()  is  called   when   a   call   to
  1060. * UDIWait() indicates there is STDERR output data ready
  1061. */
  1062. UDIError UDIGetStderr(buf, bufsize, count_done)
  1063. UDIHostMemPtr    buf;        /* out -- buffer to be filled */
  1064. UDISizeT    bufsize;    /* in  -- buffer size in bytes */
  1065. UDISizeT    *count_done;    /* out -- number of bytes written to buf */
  1066. {
  1067.     UDIInt32    service_id = UDIGetStderr_c;
  1068.  
  1069.     udr_errno = 0;
  1070.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  1071.     udr_UDIInt32(udrs, &service_id);
  1072.     udr_UDISizeT(udrs, &bufsize);
  1073.     udr_sendnow(udrs);
  1074.     if(udr_errno) return udr_errno;
  1075.  
  1076.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  1077.     udr_UDISizeT(udrs, count_done);
  1078.     udr_bytes(udrs, buf, *count_done);
  1079.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  1080.     return dfe_errno;
  1081. }
  1082.  
  1083. /*************************************************************** UDI_PUT_STDIN
  1084. * UDIPutStdin() is called whenever the DFE wants to
  1085. * deliver an input character to the TIP.
  1086. */
  1087. UDIError UDIPutStdin (buf, count, count_done)
  1088. UDIHostMemPtr    buf;        /* in -- buffer to be filled */
  1089. UDISizeT    count;        /* in -- buffer size in bytes */
  1090. UDISizeT    *count_done;    /* out - number of bytes written to buf */
  1091. {
  1092.     UDIInt32    service_id = UDIPutStdin_c;
  1093.  
  1094.     udr_errno = 0;
  1095.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  1096.     udr_UDIInt32(udrs, &service_id);
  1097.     udr_UDISizeT(udrs, &count);
  1098.     udr_bytes(udrs, buf, count);
  1099.     udr_sendnow(udrs);
  1100.     if(udr_errno) return udr_errno;
  1101.  
  1102.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  1103.     udr_UDISizeT(udrs, count_done);
  1104.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  1105.     return dfe_errno;
  1106. }
  1107.  
  1108. /************************************************************** UDI_STDIN_MODE
  1109. * UDIStdinMode() is used to change the mode that chazcters
  1110. * are fetched from the user.
  1111. */
  1112. UDIError    UDIStdinMode(mode)
  1113. UDIMode        *mode;        /* out - */
  1114. {
  1115.     UDIInt32    service_id = UDIStdinMode_c;
  1116.  
  1117.     udr_errno = 0;
  1118.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  1119.     udr_UDIInt32(udrs, &service_id);
  1120.     udr_sendnow(udrs);
  1121.     if(udr_errno) return udr_errno;
  1122.  
  1123.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  1124.     udr_UDIMode(udrs, mode);
  1125.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  1126.     return dfe_errno;
  1127. }
  1128.  
  1129. /*************************************************************** UDI_PUT_TRANS
  1130. * UDIPutTrans() is used to feed input to  the  passthru  mode.
  1131. */
  1132. UDIError    UDIPutTrans (buf, count, count_done)
  1133. UDIHostMemPtr    buf;        /* in -- buffer address containing input data */
  1134. UDISizeT    count;        /* in -- number of bytes in buf */
  1135. UDISizeT    *count_done;    /* out-- number of bytes transfered */
  1136. {
  1137.     UDIInt32    service_id = UDIPutTrans_c;
  1138.  
  1139.     udr_errno = 0;
  1140.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  1141.     udr_UDIInt32(udrs, &service_id);
  1142.     udr_UDISizeT(udrs, &count);
  1143.     udr_bytes(udrs, buf, count);
  1144.     udr_sendnow(udrs);
  1145.     if(udr_errno) return udr_errno;
  1146.  
  1147.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  1148.     udr_UDISizeT(udrs, count_done);
  1149.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  1150.     return dfe_errno;
  1151. }
  1152.  
  1153. /*************************************************************** UDI_GET_TRANS
  1154. * UDIGetTrans() is used to get output lines from the
  1155. * passthru mode.
  1156. */
  1157. UDIError    UDIGetTrans (buf, bufsize, count_done)
  1158. UDIHostMemPtr    buf;        /* out -- buffer to be filled */
  1159. UDISizeT    bufsize;    /* in  -- size of buf */
  1160. UDISizeT    *count_done;    /* out -- number of bytes in buf */
  1161. {
  1162.     UDIInt32    service_id = UDIGetTrans_c;
  1163.  
  1164.     udr_errno = 0;
  1165.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  1166.     udr_UDIInt32(udrs, &service_id);
  1167.     udr_UDISizeT(udrs, &bufsize);
  1168.     udr_sendnow(udrs);
  1169.     if(udr_errno) return udr_errno;
  1170.  
  1171.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  1172.     udr_UDISizeT(udrs, count_done);
  1173.     udr_bytes(udrs, buf, *count_done);
  1174.     udr_UDIError(udrs, &dfe_errno);    /* get any TIP error */
  1175.     return dfe_errno;
  1176. }
  1177.  
  1178. /************************************************************** UDI_Trans_Mode
  1179. * UDITransMode() is used to change the mode that the
  1180. * transparent routines operate in.
  1181. */
  1182. UDIError UDITransMode(mode)
  1183. UDIMode        *mode;        /* out  -- selected mode */
  1184. {
  1185.     UDIInt32    service_id = UDITransMode_c;
  1186.  
  1187.     udr_errno = 0;
  1188.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  1189.     udr_UDIInt32(udrs, &service_id);
  1190.     udr_UDIMode(udrs, mode);
  1191.     udr_sendnow(udrs);
  1192.     if(udr_errno) return udr_errno;
  1193.  
  1194.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  1195.     udr_UDIError(udrs, &dfe_errno);
  1196.     return dfe_errno;
  1197. }
  1198.  
  1199. /******************************************************************** UDI_TEST
  1200. */
  1201. UDIError UDITest( cnt, str_p, array)
  1202. UDISizeT    cnt;
  1203. UDIHostMemPtr    str_p;
  1204. UDIInt32    array[];
  1205. {
  1206.     UDIInt32    service_id = UDITest_c;
  1207.     UDIInt16    scnt = cnt;
  1208.     UDISizeT    r_cnt;
  1209.     char    buf[256];
  1210.  
  1211.     udr_errno = 0;
  1212.     udrs->udr_op = UDR_ENCODE;        /* send all "in" parameters */
  1213.     udr_UDIInt32(udrs, &service_id);
  1214.  
  1215.     printf("send    cnt=%d scnt=%d\n", cnt, scnt);
  1216.     udr_UDISizeT(udrs, &cnt);
  1217.     udr_UDIInt16(udrs, &scnt);
  1218.     printf("    array[0]=0x%x array[1]=0x%x array[2]=0x%x array[3]=0x%x\n",
  1219.         array[0], array[1], array[2], array[3]);
  1220.     udr_bytes(udrs, (char*)array, 4*sizeof(UDIInt32));
  1221.     printf("    string=%s\n", str_p);
  1222.     udr_string(udrs, str_p);
  1223.     udr_sendnow(udrs);
  1224.     if(udr_errno)
  1225.     {    fprintf(stderr, " DFE-ipc Send ERROR\n");
  1226.     return udr_errno;
  1227.     }
  1228.  
  1229.     udrs->udr_op = UDR_DECODE;        /* receive all "out" parameters */
  1230.     printf("recv    ");
  1231.     udr_UDISizeT(udrs, &r_cnt);
  1232.     udr_UDIInt16(udrs, &scnt);
  1233.     printf("    rcnt=%d scnt=%d\n", r_cnt, scnt);
  1234.     udr_bytes(udrs, (char*)array, 4*sizeof(UDIInt32));
  1235.  
  1236.     printf("    array[0]=0x%x array[1]=0x%x array[2]=0x%x array[3]=0x%x\n",
  1237.         array[0], array[1], array[2], array[3]);
  1238.     udr_string(udrs, str_p);
  1239.     printf("    string=%s\n", str_p);
  1240.  
  1241.     udr_UDIError(udrs, &dfe_errno);
  1242.     return dfe_errno;
  1243. }
  1244.  
  1245.  
  1246.  
  1247. UDIUInt32 UDIGetDFEIPCId()
  1248. {
  1249.     return ((company_c << 16) + (product_c << 12) + version_c);
  1250. }
  1251. #endif /* __GO32__ */
  1252.