📄 udip2soc.c
字号:
/** Copyright 1991 Advanced Micro Devices, Inc.* * This software is the property of Advanced Micro Devices, Inc (AMD) which* specifically grants the user the right to modify, use and distribute this* software provided this notice is not removed or altered. All other rights* are reserved by AMD.** AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS* SOFTWARE. IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL* DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR* USE OF THIS SOFTWARE.** So that all may benefit from your experience, please report any problems* or suggestions about this software to the 29K Technical Support Center at* 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131 in the UK, or* 0031-11-1129 in Japan, toll free. The direct dial number is 512-462-4118.** Advanced Micro Devices, Inc.* 29K Support Products* Mail Stop 573* 5900 E. Ben White Blvd.* Austin, TX 78741* 800-292-9263******************************************************************************/static char udip2soc_c[]="@(#)udip2soc.c 2.13 Daniel Mann";static char udip2soc_c_AMD[]="@(#)udip2soc.c 2.11, AMD";/* * This module converts UDI Procedural calls into* UDI socket messages for UNIX. * It is used by DFE client processes********************************************************************** HISTORY*/#include <stdio.h>#include <string.h>#include <sys/file.h>#include <sys/fcntl.h>#include <sys/wait.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <signal.h>#include <sys/errno.h>#include "udiproc.h"#include "udisoc.h"extern int errno;extern int sys_nerr;extern char* sys_errlist[];extern int udr_errno;extern char* getenv();/* local type decs. and macro defs. not in a .h file ************* MACRO/TYPE*/#define version_c 0x121 /* DFE-IPC version id */#define TRUE -1#define FALSE 0#define PORT_NUM 7000#define MAX_SESSIONS 5 /* maximum DFE-TIP connections */#define SOC_BUF_SIZE 4* 1024 /* size of socket comms buffer */#define SBUF_SIZE 500 /* size of string buffer */#define ERRMSG_SIZE 500 /* size of error message buffer */#define errmsg_m {int ii; for(ii=0; ii<ERRMSG_SIZE; ii++) dfe_errmsg[ii]=0;}typedef struct connection_str /* record of connect session */{ int in_use; char connect_id[20]; /* connection identifier */ char domain_string[20]; /* dommaing for conection */ char tip_string[30]; /* TIP host name for AF_INET */ char tip_exe[80]; /* TIP exe name */ int dfe_sd; /* associated DFE socket */ int tip_pid; /* pid of TIP process */ struct sockaddr_in dfe_sockaddr; struct sockaddr_in tip_sockaddr_in; struct sockaddr tip_sockaddr;} connection_t;typedef struct session_str{ int in_use; connection_t* soc_con_p; /* associated connection */ UDISessionId tip_id; /* associated TIP session ID */} session_t;/* global dec/defs. which are not in a .h file ************* EXPORT DEC/DEFS*/UDIError dfe_errno;char dfe_errmsg[ERRMSG_SIZE];/* error string *//* local dec/defs. which are not in a .h file *************** LOCAL DEC/DEFS*/LOCAL connection_t soc_con[MAX_SESSIONS]; LOCAL session_t session[MAX_SESSIONS]; LOCAL UDR udr;LOCAL UDR* udrs = &udr; /* UDR for current session */LOCAL int current; /* int-id for current session */LOCAL char sbuf[SBUF_SIZE]; /* String handler buffer */LOCAL char config_file[80]; /* path/name for config file *//***************************************************************** UDI_CONNECT* Establish a new FDE to TIP conection. The file "./udi_soc" or* "/etc/udi_soc" may be examined to obtain the conection information* if the "Config" parameter is not a completd "line entry".** NOTE: the Session string must not start whith white-space characters.* Format of string is:* <session> <domain> <soc_name|host_name> <tip_exe|port> <pass to UDIconnect>* soc2cayman AF_INET cayman 7000 <not supported>* soc2tip AF_UNIX astring tip.exe ...*/UDIConnect(Config, Session)char* Config; /* in -- identification string */UDISessionId *Session; /* out -- session ID */{ UDIInt32 service_id = UDIConnect_c; int domain; int cnt=0; int rcnt, pos, fd, params_pos=0; char *tip_main_string; char *env_p; struct hostent *tip_info_p; FILE *f_p; UDIUInt32 TIPIPCId; UDIUInt32 DFEIPCId; sprintf(sbuf, "which udi_soc"); f_p = popen(sbuf, "r"); if(f_p) { while( (sbuf[cnt++]=getc(f_p)) != EOF); sbuf[cnt-2]=0; } pclose(f_p); errmsg_m; for (rcnt=0; rcnt < MAX_SESSIONS; rcnt++) if(!session[rcnt].in_use) break; if(rcnt >= MAX_SESSIONS) { sprintf(dfe_errmsg, "DFE-ipc ERROR: Too many sessions already open"); return UDIErrorIPCLimitation; } /* One connection can be multiplexed between several sessions. */ for (cnt=0; cnt < MAX_SESSIONS; cnt++) if(!soc_con[cnt].in_use) break; if(cnt >= MAX_SESSIONS) { sprintf(dfe_errmsg, "DFE-ipc ERROR: Too many connections already open"); return UDIErrorIPCLimitation; } *Session = rcnt; session[rcnt].soc_con_p = &soc_con[cnt]; if(strchr(Config, ' ')) /* test if file entry given */ { soc_con[cnt].in_use = TRUE; sscanf(Config, "%s %s %s %s %n", soc_con[cnt].connect_id, soc_con[cnt].domain_string, soc_con[cnt].tip_string, soc_con[cnt].tip_exe, ¶ms_pos); tip_main_string = Config + params_pos; } else /* here if need to read udi_soc file */ { fd = -1; env_p = getenv("UDICONF"); if(env_p) { sprintf(config_file, "%s", env_p); /* path includes file name */ fd = open(config_file, O_RDONLY); } if(fd == -1) { fd = open("udi_soc", O_RDONLY); strcpy(config_file, "udi_soc"); } if(fd == -1) { fd = open(sbuf, O_RDONLY); strcpy(config_file, sbuf); } if(fd == -1) { sprintf(dfe_errmsg, "UDIConnect, can't open udi_soc file:\n%s ", sys_errlist[errno]); return UDIErrorCantOpenConfigFile; } while(1) { pos = 0; while((rcnt = read(fd, &sbuf[pos], 1)) != -1)/* read a line */ { if (sbuf[pos] == '\n' || rcnt == 0 ) break; pos += 1; } sbuf[pos] = 0; /* terminate string */ sscanf(sbuf, "%s %s %s %s %n", soc_con[cnt].connect_id, soc_con[cnt].domain_string, soc_con[cnt].tip_string, soc_con[cnt].tip_exe, ¶ms_pos); if( strcmp(Config, soc_con[cnt].connect_id) || rcnt == -1 || rcnt == 0) if(rcnt == -1 || rcnt == 0) { sprintf(dfe_errmsg, "UDIConnect, can't find entry in udi_soc file"); return UDIErrorNoSuchConfiguration; } else continue; soc_con[cnt].in_use = TRUE; /* here if entry found */ tip_main_string = sbuf + params_pos; break; } close(fd); }/*-------------------------------------------------------------- '*' SOC_ID */ if( *soc_con[cnt].tip_string == '*' && *soc_con[cnt+1].tip_string == 0) { rcnt = 0; pos = getpid(); do { sprintf(soc_con[cnt].tip_string,"/tmp/udi%.5d", pos++); fd = open(soc_con[cnt].tip_string, O_CREAT); if(rcnt++ > 20) { sprintf(dfe_errmsg, "DFE-ipc ERROR, can't create random socket name\n"); return UDIErrorCantConnect; } } while(fd == -1); close(fd); unlink(soc_con[cnt].tip_string); }/*----------------------------------------------------------- SELECT DOMAIN */ if(!strcmp(soc_con[cnt].domain_string, "AF_UNIX")) domain = AF_UNIX; else if(!strcmp(soc_con[cnt].domain_string, "AF_INET")) domain = AF_INET; else { errmsg_m; sprintf(dfe_errmsg, "DFE-ipc ERROR: socket address family not known"); return UDIErrorBadConfigFileEntry; }/*---------------------------------------------------- MULTIPLEXED SOCKET ? *//* If the requested session requires communication with a TIP which already has a socket connection established, then we do not create a new socket but multiplex the existing one. A TIP is said to use the same socket if socket-name/host-name and the domain are the same. */ for (rcnt=0; rcnt < MAX_SESSIONS; rcnt++) { if( soc_con[rcnt].in_use && !strcmp(soc_con[cnt].domain_string, soc_con[rcnt].domain_string) && !strcmp(soc_con[cnt].tip_string, soc_con[rcnt].tip_string) && rcnt != cnt ) { session[*Session].soc_con_p = &soc_con[rcnt]; soc_con[cnt].in_use = FALSE; /* don't need new connect */ goto tip_connect; } }/*------------------------------------------------------------------ SOCKET */ soc_con[cnt].dfe_sd = socket(domain, SOCK_STREAM, 0); if (soc_con[cnt].dfe_sd == -1 ) { errmsg_m; sprintf(dfe_errmsg, "DFE-ipc ERROR, socket() call failed %s ", sys_errlist[errno]); UDIKill(cnt); }/*--------------------------------------------------------- AF_UNIX CONNECT */ if(domain == AF_UNIX) { memset( (char*)&soc_con[cnt].tip_sockaddr, 0, sizeof(soc_con[cnt].tip_sockaddr)); soc_con[cnt].tip_sockaddr.sa_family = domain; bcopy(soc_con[cnt].tip_string, soc_con[cnt].tip_sockaddr.sa_data, sizeof(soc_con[cnt].tip_sockaddr.sa_data) ); if(connect(soc_con[cnt].dfe_sd, &soc_con[cnt].tip_sockaddr, sizeof(soc_con[cnt].tip_sockaddr)) == -1) { /* if connect() fails assume TIP not yet started *//*------------------------------------------------------------ AF_UNIX EXEC */ int pid;#ifdef __hpux int statusp;#else union wait statusp;#endif char* arg0 = strrchr(soc_con[cnt].tip_exe,'/'); if(!arg0) arg0 = soc_con[cnt].tip_exe; else arg0++; if((pid = fork()) == 0) { execlp( soc_con[cnt].tip_exe, arg0, soc_con[cnt].domain_string, soc_con[cnt].tip_string, NULL); exit(1); }#ifdef __hpux if(waitpid(pid, &statusp, WNOHANG))#else if(wait4(pid, &statusp, WNOHANG, NULL))#endif { sprintf(dfe_errmsg, "DFE-ipc ERROR: can't exec the TIP\n"); return UDIErrorCantStartTIP; } sleep(2); /* not TIP is running, try conect() again */ if(connect(soc_con[cnt].dfe_sd, &soc_con[cnt].tip_sockaddr, sizeof(soc_con[cnt].tip_sockaddr)) == -1) { sprintf(dfe_errmsg, "DFE-ipc ERROR, connect() call failed: %s", sys_errlist[errno]); return UDIErrorCantConnect; } } }/*--------------------------------------------------------- AF_INET CONNECT */ if(domain == AF_INET) { fprintf(stderr,"DFE-ipc WARNING, need to have first started remote TIP\n"); memset( (char*)&soc_con[cnt].tip_sockaddr_in, 0, sizeof(soc_con[cnt].tip_sockaddr_in)); soc_con[cnt].tip_sockaddr_in.sin_family = domain; soc_con[cnt].tip_sockaddr_in.sin_addr.s_addr = inet_addr(soc_con[cnt].tip_string); if( soc_con[cnt].tip_sockaddr_in.sin_addr.s_addr == -1) { tip_info_p = gethostbyname(soc_con[cnt].tip_string); if( tip_info_p == NULL) { errmsg_m; sprintf(dfe_errmsg,"DFE-ipc ERROR, %s not found in /etc/hosts", soc_con[cnt].tip_string); return UDIErrorNoSuchConnection; } bcopy(tip_info_p->h_addr, (char *)&soc_con[cnt].tip_sockaddr_in.sin_addr, tip_info_p->h_length); } soc_con[cnt].tip_sockaddr_in.sin_port=htons(atoi(soc_con[cnt].tip_exe)); if(connect(soc_con[cnt].dfe_sd, &soc_con[cnt].tip_sockaddr_in, sizeof(soc_con[cnt].tip_sockaddr_in)) == -1) { errmsg_m; sprintf(dfe_errmsg, "DFE-ipc ERROR, connect() call failed %s ", sys_errlist[errno]); return UDIErrorCantConnect; } }/*------------------------------------------------------------- TIP CONNECT */ if(cnt ==0) udr_create(udrs, soc_con[cnt].dfe_sd, SOC_BUF_SIZE);tip_connect: current = cnt; session[*Session].in_use = TRUE; /* session id is now in use*/ udr_errno = 0; udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ udr_UDIInt32(udrs, &service_id); DFEIPCId = (company_c << 16) + (product_c << 12) + version_c; udr_UDIUInt32(udrs, &DFEIPCId); udr_string(udrs, tip_main_string); udr_sendnow(udrs); udrs->udr_op = UDR_DECODE; /* recv all "out" parameters */ udr_UDIUInt32(udrs, &TIPIPCId); if ((TIPIPCId & 0xfff) < version_c) { fprintf(stderr, "DFE-ipc: Obsolete TIP Specified\n"); return(UDIErrorExecutableNotTIP); } udr_UDIInt32(udrs, &soc_con[cnt].tip_pid); udr_UDISessionId(udrs, &session[*Session].tip_id); udr_UDIError(udrs, &dfe_errno); if(dfe_errno > 0) UDIKill(Session, 0); return dfe_errno;}/************************************************************** UDI_Disconnect* UDIDisconnect() should be called before exiting the* DFE to ensure proper shut down of the TIP.*/UDIError UDIDisconnect(Session, Terminate)UDISessionId Session;UDIBool Terminate;{ int cnt; UDIInt32 service_id = UDIDisconnect_c; if(Session < 0 || Session > MAX_SESSIONS) { errmsg_m;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -