home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gdb-4.16-base.tgz / gdb-4.16-base.tar / fsf / gdb / utils / amd-udi / udi / udip2soc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-23  |  39.1 KB  |  1,196 lines

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