GSI Object Oriented Online Offline (Go4)  GO4-5.3.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
rconnect.c
Go to the documentation of this file.
1 /*********************************************************************
2  * Copyright:
3  * GSI, Gesellschaft fuer Schwerionenforschung mbH
4  * Planckstr. 1
5  * D-64291 Darmstadt
6  * Germany
7  * created 26. 1.1996 by Horst Goeringer
8  *********************************************************************
9  * rconnect.c
10  * open connection to specified server
11  *********************************************************************
12  * 7. 4.1999, H.G.: return error number in case of failure
13  * pass max time for retries of connect()
14  * 3. 3.2000, H.G.: rename iExit to imySigS
15  * *piMaxTime: meaning of values -1 and 0 exchanged
16  * 7. 3.2000, H.G.: renamed form rawConnect to rconnect
17  * 31.10.2001, H.G.: ported to W2000
18  * 14.10.2002, H.G.: ported to Lynx
19  * 1. 2.2005, H.G.: ported to Linux and gcc322
20  * 7.10.2008, H.G.: improved retry loops
21  * 3.11.2008, H.G.: correct include files for AIX
22  * 5.11.2010, H.G.: replace perror by strerror(errno)
23  *********************************************************************
24  */
25 
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 
30 #ifdef WIN32 /* Windows */
31 #include <sys\types.h>
32 #include <winsock.h>
33 #include <windows.h>
34 #include <process.h>
35 #else /* all Unix */
36 #include <sys/types.h>
37 #include <errno.h>
38 #include <unistd.h>
39 #include <netdb.h>
40 
41 #ifdef Lynx /* Lynx */
42 #include <netinet/in.h>
43 #include <socket.h>
44 #elif Linux /* Linux */
45 #include <arpa/inet.h>
46 #include <sys/socket.h>
47 #else /* AIX */
48 #include <netinet/in.h>
49 #include <sys/socket.h>
50 #endif
51 
52 #endif /* all Unix */
53 
54 extern int imySigS; /* if = 1: CTL C specified */
55 
56 /********************************************************************/
57 
58 int rconnect( char *cNode, /* input: name of remote host */
59  int iPort, /* input: port number */
60  int *piMaxTime, /* input: max time for connect */
61  /* = -1: try only once */
62  /* = 0: try until success */
63  /* > 0: try at most *piMaxTime s */
64  /* output: time needed for connect */
65  int *piSocket) /* output: socket number */
66 {
67  char cModule[32] = "rconnect";
68  int iDebug = 0;
69  int iSocket = 0;
70  int iMaxTime = *piMaxTime;
71  int iTime = 0;
72  int iError;
73  int iSleep = 0;
74  int iMaxSleep = 10; /* max sleep time */
75 
76  struct hostent *pHE = NULL;
77  struct hostent sHE;
78  struct sockaddr_in sSockAddr;
79  unsigned long lAddr;
80 
81  if (iDebug)
82  {
83  printf("\n-D- begin %s: try connection to %s:%d",
84  cModule, cNode, iPort);
85  if (iMaxTime < 0)
86  printf(" (1 trial)\n");
87  else if (iMaxTime == 0)
88  printf(" (until success)\n");
89  else
90  printf(" (for %d sec)\n", iMaxTime);
91  }
92 
93  if ( ( pHE = gethostbyname(cNode) ) == NULL )
94  {
95  lAddr = inet_addr(cNode);
96  if ( ( pHE = gethostbyaddr(
97  (char *)&lAddr, sizeof(lAddr), AF_INET ) ) == NULL )
98  {
99  printf("-E- %s: unknown host %s\n", cModule, cNode );
100  iError = -1;
101  goto gError;
102  }
103  if (iDebug)
104  printf(" %s: gethostbyaddr succeeded\n", cModule);
105  }
106  else if (iDebug)
107  printf(" %s: gethostbyname succeeded\n", cModule);
108  sHE = *pHE; /* safe copy */
109 
110 gRetryConnect:;
111  /* create the socket */
112  if ( ( iSocket = socket(
113  AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) == -1 )
114  {
115  printf("-E- %s: socket failed\n", cModule);
116  if (errno)
117  {
118  printf(" %s\n", strerror(errno));
119  errno = 0;
120  }
121 
122  iError = -1;
123  goto gError;
124  }
125 
126  sSockAddr.sin_family = AF_INET;
127  sSockAddr.sin_port = 0;
128  sSockAddr.sin_addr.s_addr = INADDR_ANY;
129  /* bind a socket */
130  if ( bind ( iSocket,
131  (struct sockaddr *) &sSockAddr,
132  sizeof(sSockAddr) ) == -1 )
133  {
134  printf("-E- %s: bind failed\n", cModule);
135  if (errno)
136  {
137  printf(" %s\n", strerror(errno));
138  errno = 0;
139  }
140 
141  iError = -1;
142  goto gError;
143  }
144 
145  sSockAddr.sin_family = AF_INET;
146  sSockAddr.sin_port = htons( (short) iPort );
147  sSockAddr.sin_addr = * ( (struct in_addr *) sHE.h_addr );
148  /* contact remote server */
149  if ( connect( iSocket,
150  (struct sockaddr *) &sSockAddr,
151  sizeof(sSockAddr) ) == -1 )
152  {
153 #ifdef WIN32
154  iError = -1; /* errno, perror indicate NO error! */
155 #else
156  printf("-E- %s: connect to %s:%d failed\n", cModule, cNode, iPort);
157  if (errno)
158  {
159  printf(" %s\n", strerror(errno));
160  errno = 0;
161  }
162 #endif
163 
164  /* if not successful, retry. Possibly server not yet up. */
165  if ( (iTime < iMaxTime) || (iMaxTime == -1) )
166  {
167 #ifdef WIN32
168  closesocket(iSocket);
169  iSocket = -1;
170 #else
171  close(iSocket);
172  iSocket = -1;
173  if (imySigS) /* CTL C specified */
174  goto gError;
175 #endif
176 
177  if (iMaxTime == -1) /* only one trial */
178  goto gError;
179 
180  if (iSleep < iMaxSleep)
181  iSleep++;
182  iTime += iSleep;
183 
184  if (iDebug) printf(
185  " time %d of %d, sleep %d\n",
186  iTime, iMaxTime, iSleep);
187 #ifdef WIN32
188  Sleep(iSleep*1000);
189 #else
190  sleep((unsigned) iSleep);
191 #endif
192  goto gRetryConnect;
193  }
194 
195  goto gError;
196  }
197 
198  *piMaxTime = iTime; /* return time needed for connect */
199  *piSocket = iSocket; /* return socket number */
200  if (iDebug)
201  printf("-D- end %s (success after %d sec)\n\n", cModule, *piMaxTime);
202 
203  return(0); /* no error */
204 
205 gError:
206  if (iSocket)
207  {
208  shutdown(iSocket, 2);
209 #ifdef WIN32
210  closesocket(iSocket);
211 #else
212  close(iSocket);
213 #endif
214  }
215 
216  *piSocket = -1;
217  if (iMaxTime >= 0)
218  *piMaxTime = iTime; /* return time needed for trials */
219  else
220  *piMaxTime = 0;
221 
222  if (iDebug)
223  {
224  printf("-D- end %s", cModule);
225  if (iMaxTime >= 0)
226  printf(" (after %d sec)\n\n", iTime);
227  else
228  printf("\n\n");
229  }
230 
231  return iError;
232 }
int rconnect(char *cNode, int iPort, int *piMaxTime, int *piSocket)
Definition: rconnect.c:58
int imySigS
Definition: rawapin.c:184