DABC (Data Acquisition Backbone Core)  2.9.9
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  * 4. 9.2012, H.G.: printf -> fprintf(fLogFile, ...)
24  *********************************************************************
25  */
26 
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30 
31 #ifdef WIN32 /* Windows */
32 #include <sys\types.h>
33 #include <winsock.h>
34 #include <windows.h>
35 #include <process.h>
36 #else /* all Unix */
37 #include <sys/types.h>
38 #include <errno.h>
39 #include <unistd.h>
40 #include <netdb.h>
41 
42 #ifdef Lynx /* Lynx */
43 #include <netinet/in.h>
44 #include <socket.h>
45 #elif Linux /* Linux */
46 #include <arpa/inet.h>
47 #include <sys/socket.h>
48 #else /* AIX */
49 #include <netinet/in.h>
50 #include <sys/socket.h>
51 #endif
52 
53 #endif /* all Unix */
54 
55 extern int imySigS; /* if = 1: CTL C specified */
56 extern FILE *fLogFile;
57 
58 /********************************************************************/
59 
60 int rconnect( char *cNode, /* input: name of remote host */
61  int iPort, /* input: port number */
62  int *piMaxTime, /* input: max time for connect */
63  /* = -1: try only once */
64  /* = 0: try until success */
65  /* > 0: try at most *piMaxTime s */
66  /* output: time needed for connect */
67  int *piSocket) /* output: socket number */
68 {
69  char cModule[32] = "rconnect";
70  int iDebug = 0;
71  int iSocket = 0;
72  int iMaxTime = *piMaxTime;
73  int iTime = 0;
74  int iError;
75  int iSleep = 0;
76  int iMaxSleep = 10; /* max sleep time */
77 
78  struct hostent *pHE = NULL;
79  struct hostent sHE;
80  struct sockaddr_in sSockAddr;
81  unsigned long lAddr;
82 
83  if (iDebug)
84  {
85  fprintf(fLogFile, "\n-D- begin %s: try connection to %s:%d",
86  cModule, cNode, iPort);
87  if (iMaxTime < 0)
88  fprintf(fLogFile, " (1 trial)\n");
89  else if (iMaxTime == 0)
90  fprintf(fLogFile, " (until success)\n");
91  else
92  fprintf(fLogFile, " (for %d sec)\n", iMaxTime);
93  }
94 
95  if ( ( pHE = gethostbyname(cNode) ) == NULL )
96  {
97  lAddr = inet_addr(cNode);
98  if ( ( pHE = gethostbyaddr(
99  (char *)&lAddr, sizeof(lAddr), AF_INET ) ) == NULL )
100  {
101  fprintf(fLogFile, "-E- %s: unknown host %s\n", cModule, cNode );
102  if (errno)
103  {
104  fprintf(fLogFile, " %s\n", strerror(errno));
105  errno = 0;
106  }
107 
108  iError = -1;
109  goto gError;
110  }
111  if (iDebug)
112  fprintf(fLogFile, " %s: gethostbyaddr succeeded\n", cModule);
113  }
114  else if (iDebug)
115  fprintf(fLogFile, " %s: gethostbyname succeeded\n", cModule);
116  sHE = *pHE; /* safe copy */
117 
118 gRetryConnect:;
119  /* create the socket */
120  if ( ( iSocket = socket(
121  AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) == -1 )
122  {
123  fprintf(fLogFile, "-E- %s: socket failed\n", cModule);
124  if (errno)
125  {
126  fprintf(fLogFile, " %s\n", strerror(errno));
127  errno = 0;
128  }
129 
130  iError = -1;
131  goto gError;
132  }
133 
134  sSockAddr.sin_family = AF_INET;
135  sSockAddr.sin_port = 0;
136  sSockAddr.sin_addr.s_addr = INADDR_ANY;
137  /* bind a socket */
138  if ( bind ( iSocket,
139  (struct sockaddr *) &sSockAddr,
140  sizeof(sSockAddr) ) == -1 )
141  {
142  fprintf(fLogFile, "-E- %s: bind failed\n", cModule);
143  if (errno)
144  {
145  fprintf(fLogFile, " %s\n", strerror(errno));
146  errno = 0;
147  }
148 
149  iError = -1;
150  goto gError;
151  }
152 
153  sSockAddr.sin_family = AF_INET;
154  sSockAddr.sin_port = htons( (short) iPort );
155  sSockAddr.sin_addr = * ( (struct in_addr *) sHE.h_addr );
156  /* contact remote server */
157  if ( connect( iSocket,
158  (struct sockaddr *) &sSockAddr,
159  sizeof(sSockAddr) ) == -1 )
160  {
161 #ifdef WIN32
162  iError = -1; /* errno, perror indicate NO error! */
163 #else
164  fprintf(fLogFile, "-E- %s: connect to %s:%d failed\n",
165  cModule, cNode, iPort);
166  if (errno)
167  {
168  fprintf(fLogFile, " %s\n", strerror(errno));
169  errno = 0;
170  }
171 #endif
172 
173  /* if not successful, retry. Possibly server not yet up. */
174  if ( (iTime < iMaxTime) || (iMaxTime == -1) )
175  {
176 #ifdef WIN32
177  closesocket(iSocket);
178  iSocket = -1;
179 #else
180  close(iSocket);
181  iSocket = -1;
182  if (imySigS) /* CTL C specified */
183  goto gError;
184 #endif
185 
186  if (iMaxTime == -1) /* only one trial */
187  goto gError;
188 
189  if (iSleep < iMaxSleep)
190  iSleep++;
191  iTime += iSleep;
192 
193  if (iDebug) fprintf(fLogFile,
194  " time %d of %d, sleep %d\n",
195  iTime, iMaxTime, iSleep);
196 #ifdef WIN32
197  Sleep(iSleep*1000);
198 #else
199  sleep((unsigned) iSleep);
200 #endif
201  goto gRetryConnect;
202  }
203 
204  goto gError;
205  }
206 
207  *piMaxTime = iTime; /* return time needed for connect */
208  *piSocket = iSocket; /* return socket number */
209  if (iDebug)
210  fprintf(fLogFile, "-D- end %s (success after %d sec)\n\n",
211  cModule, *piMaxTime);
212 
213  return(0); /* no error */
214 
215 gError:
216  if (iSocket)
217  {
218  shutdown(iSocket, 2);
219 #ifdef WIN32
220  closesocket(iSocket);
221 #else
222  close(iSocket);
223 #endif
224  }
225 
226  *piSocket = -1;
227  if (iMaxTime >= 0)
228  *piMaxTime = iTime; /* return time needed for trials */
229  else
230  *piMaxTime = 0;
231 
232  if (iDebug)
233  {
234  fprintf(fLogFile, "-D- end %s", cModule);
235  if (iMaxTime >= 0)
236  fprintf(fLogFile, " (after %d sec)\n\n", iTime);
237  else
238  fprintf(fLogFile, "\n\n");
239  }
240 
241  return iError;
242 }
void Sleep(double tm)
Definition: timing.cxx:129
FILE * fLogFile
Definition: rawapin.c:217
int rconnect(char *cNode, int iPort, int *piMaxTime, int *piSocket)
Definition: rconnect.c:60
int imySigS
Definition: rawapin.c:216