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