📄 udip2soc.c
字号:
/* Copyright 1993 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */static char udip2soc_c[]="@(#)udip2soc.c 2.11 Daniel Mann";static char udip2soc_c_AMD[]="@(#)udip2soc.c 2.8, AMD";/* * This module converts UDI Procedural calls into* UDI socket messages for UNIX. * It is used by DFE client processes********************************************************************** HISTORY*//* This is all unneeded on DOS machines. */#ifndef __GO32__#include <stdio.h>#include <string.h>/* Before sys/file.h for Unixware. */#include <sys/types.h>#include <sys/file.h>/* This used to say sys/fcntl.h, but the only systems I know of that require that are old (pre-4.3, at least) BSD systems, which we probably don't need to worry about. */#include <fcntl.h>#include <sys/wait.h>#include <sys/time.h>#include <sys/resource.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 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 */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 ...*/UDIErrorUDIConnect(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, params_pos=0; char *tip_main_string; char *env_p; struct hostent *tip_info_p; FILE *fd;#if 0 FILE *f_p;#endif UDIUInt32 TIPIPCId; UDIUInt32 DFEIPCId;#if 0 /* This is crap. It assumes that udi_soc is executable! */ 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);#endif for (rcnt=0; rcnt < MAX_SESSIONS && session[rcnt].in_use; rcnt++); 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 && soc_con[cnt].in_use; cnt++); 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 */ { strcpy(config_file, "udi_soc"); env_p = getenv("UDICONF"); if (env_p) strcpy(config_file, env_p); fd = fopen(config_file, "r"); if (!fd) { sprintf(dfe_errmsg, "UDIConnect, can't open udi_soc file:\n%s ", strerror(errno)); dfe_errno = UDIErrorCantOpenConfigFile; goto tip_failure; } while (1) { if (fscanf(fd, "%s %s %s %s %[^\n]\n", soc_con[cnt].connect_id, soc_con[cnt].domain_string, soc_con[cnt].tip_string, soc_con[cnt].tip_exe, sbuf) == EOF) break; if (strcmp(Config, soc_con[cnt].connect_id) != 0) continue; soc_con[cnt].in_use = TRUE; /* here if entry found */ tip_main_string = sbuf; break; } fclose(fd); if (!soc_con[cnt].in_use) { sprintf(dfe_errmsg, "UDIConnect, can't find `%s' entry in udi_soc file", Config); dfe_errno = UDIErrorNoSuchConfiguration; goto tip_failure; } }/*----------------------------------------------------------- SELECT DOMAIN */ if (strcmp(soc_con[cnt].domain_string, "AF_UNIX") == 0) domain = AF_UNIX; else if (strcmp(soc_con[cnt].domain_string, "AF_INET") == 0) domain = AF_INET; else { sprintf(dfe_errmsg, "DFE-ipc ERROR: socket address family not known"); dfe_errno = UDIErrorBadConfigFileEntry; goto tip_failure; }/*---------------------------------------------------- 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 && rcnt != cnt && strcmp(soc_con[cnt].domain_string, soc_con[rcnt].domain_string) == 0 && strcmp(soc_con[cnt].tip_string, soc_con[rcnt].tip_string) == 0) { 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) { sprintf(dfe_errmsg, "DFE-ipc ERROR, socket() call failed %s ", strerror (errno)); dfe_errno = UDIErrorUnknownError; goto tip_failure; }/*--------------------------------------------------------- AF_UNIX CONNECT */ if (domain == AF_UNIX) { if (strcmp(soc_con[cnt].tip_string, "*") == 0) { for (pos = 0; pos < 20; pos++) { int f; sprintf(soc_con[cnt].tip_string,"/tmp/U%d", getpid() + pos); f = open(soc_con[cnt].tip_string, O_CREAT); if (f == -1) continue; close(f); unlink(soc_con[cnt].tip_string); break; } if (pos >= 20) { sprintf(dfe_errmsg, "DFE-ipc ERROR, can't create random socket name"); dfe_errno = UDIErrorCantConnect; goto tip_failure; } } soc_con[cnt].tip_sockaddr.sa_family = domain; memcpy(soc_con[cnt].tip_sockaddr.sa_data, soc_con[cnt].tip_string, 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))) { /* if connect() fails assume TIP not yet started *//*------------------------------------------------------------ AF_UNIX EXEC */ int pid; int statusp; char *arg0; arg0 = strrchr(soc_con[cnt].tip_exe,'/'); if (arg0) arg0++; else arg0 = soc_con[cnt].tip_exe; pid = vfork(); if (pid == 0) /* Child */ { execlp(soc_con[cnt].tip_exe, arg0, soc_con[cnt].domain_string, soc_con[cnt].tip_string, NULL); _exit(1); } if (waitpid(pid, &statusp, WNOHANG)) { sprintf(dfe_errmsg, "DFE-ipc ERROR: can't exec the TIP"); dfe_errno = UDIErrorCantStartTIP; goto tip_failure; } pos = 3; for (pos = 3; pos > 0; pos--) { if (!connect(soc_con[cnt].dfe_sd, &soc_con[cnt].tip_sockaddr, sizeof(soc_con[cnt].tip_sockaddr))) break; sleep(1); } if (pos == 0) { sprintf(dfe_errmsg, "DFE-ipc ERROR, connect() call failed: %s", strerror (errno)); dfe_errno = UDIErrorCantConnect; goto tip_failure; } } }/*--------------------------------------------------------- AF_INET CONNECT */ else if (domain == AF_INET) { fprintf(stderr, "DFE-ipc WARNING, need to have first started remote TIP"); 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) { sprintf(dfe_errmsg,"DFE-ipc ERROR, No such host %s", soc_con[cnt].tip_string); dfe_errno = UDIErrorNoSuchConnection; goto tip_failure; } memcpy((char *)&soc_con[cnt].tip_sockaddr_in.sin_addr, tip_info_p->h_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, (struct sockaddr *) &soc_con[cnt].tip_sockaddr_in, sizeof(soc_con[cnt].tip_sockaddr_in))) { sprintf(dfe_errmsg, "DFE-ipc ERROR, connect() call failed %s ", strerror (errno)); dfe_errno = UDIErrorCantConnect; goto tip_failure; } }/*------------------------------------------------------------- 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) sprintf(dfe_errmsg, "DFE-ipc: Obsolete TIP Specified"); udr_UDIInt32(udrs, &soc_con[cnt].tip_pid);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -