]> git.evergreen-ils.org Git - Evergreen.git/blob - OpenSRF/src/libtransport/transport_socket.c
changed some of the debug lines
[Evergreen.git] / OpenSRF / src / libtransport / transport_socket.c
1 #include "opensrf/transport_socket.h"
2
3
4 /*
5 int main( char* argc, char** argv ) {
6
7         transport_socket sock_obj;
8         sock_obj.port = 5222;
9         sock_obj.server = "10.0.0.4";
10         sock_obj.data_received_callback = &print_stuff;
11
12         printf("connecting...\n");
13         if( (tcp_connect( &sock_obj )) < 0 ) {
14                 printf( "error connecting" );
15         }
16
17         printf("sending...\n");
18         if( tcp_send( &sock_obj, "<stream>\n" ) < 0 ) {
19                 printf( "error sending" );
20         }
21         
22         printf("waiting...\n");
23         if( tcp_wait( &sock_obj, 15 ) < 0 ) {
24                 printf( "error receiving" );
25         }
26
27         printf("disconnecting...\n");
28         tcp_disconnect( &sock_obj );
29
30 }
31 */
32
33
34 // returns the socket fd, -1 on error
35 int tcp_connect( transport_socket* sock_obj ){
36
37         if( sock_obj == NULL ) {
38                 fatal_handler( "connect(): null sock_obj" );
39                 return -1;
40         }
41         struct sockaddr_in remoteAddr, localAddr;
42         struct hostent *hptr;
43         int sock_fd;
44
45         #ifdef WIN32
46         WSADATA data;
47         char bfr;
48         if( WSAStartup(MAKEWORD(1,1), &data) ) {
49                 fatal_handler( "somethin's broke with windows socket startup" );
50                 return -1;
51         }
52         #endif
53
54
55
56         // ------------------------------------------------------------------
57         // Create the socket
58         // ------------------------------------------------------------------
59         if( (sock_fd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
60                 fatal_handler( "tcp_connect(): Cannot create socket" );
61                 return -1;
62         }
63
64         // ------------------------------------------------------------------
65         // Get the hostname
66         // ------------------------------------------------------------------
67         if( (hptr = gethostbyname( sock_obj->server ) ) == NULL ) {
68                 fatal_handler( "tcp_connect(): Unknown Host" );
69                 return -1;
70         }
71
72         // ------------------------------------------------------------------
73         // Construct server info struct
74         // ------------------------------------------------------------------
75         memset( &remoteAddr, 0, sizeof(remoteAddr));
76         remoteAddr.sin_family = AF_INET;
77         remoteAddr.sin_port = htons( sock_obj->port );
78         memcpy( (char*) &remoteAddr.sin_addr.s_addr,
79                         hptr->h_addr_list[0], hptr->h_length );
80
81         // ------------------------------------------------------------------
82         // Construct local info struct
83         // ------------------------------------------------------------------
84         memset( &localAddr, 0, sizeof( localAddr ) );
85         localAddr.sin_family = AF_INET;
86         localAddr.sin_addr.s_addr = htonl( INADDR_ANY );
87         localAddr.sin_port = htons(0);
88
89         // ------------------------------------------------------------------
90         // Bind to a local port
91         // ------------------------------------------------------------------
92         if( bind( sock_fd, (struct sockaddr *) &localAddr, sizeof( localAddr ) ) < 0 ) {
93                 fatal_handler( "tcp_connect(): Cannot bind to local port" );
94                 return -1;
95         }
96
97         // ------------------------------------------------------------------
98         // Connect to server
99         // ------------------------------------------------------------------
100         if( connect( sock_fd, (struct sockaddr*) &remoteAddr, sizeof( struct sockaddr_in ) ) < 0 ) {
101                 fatal_handler( "tcp_connect(): Cannot connect to server %s", sock_obj->server );
102                 return -1;
103         }
104
105         sock_obj->sock_fd = sock_fd;
106         sock_obj->connected = 1;
107         return sock_fd;
108
109 }
110
111
112 int tcp_send( transport_socket* sock_obj, const char* data ){
113
114         if( sock_obj == NULL ) {
115                 fatal_handler( "tcp_send(): null sock_obj" );
116                 return 0;
117         }
118
119         //fprintf( stderr, "TCP Sending: \n%s\n", data );
120
121         // ------------------------------------------------------------------
122         // Send the data down the TCP pipe
123         // ------------------------------------------------------------------
124         debug_handler( "Sending Data At %f Seconds", get_timestamp_millis() );
125         if( send( sock_obj->sock_fd, data, strlen(data), 0 ) < 0 ) {
126                 fatal_handler( "tcp_send(): Error sending data" );
127                 return 0;
128         }
129         return 1;
130 }
131
132
133 int tcp_disconnect( transport_socket* sock_obj ){
134
135         if( sock_obj == NULL ) {
136                 fatal_handler( "tcp_disconnect(): null sock_obj" );
137                 return -1;
138         }
139
140         if( close( sock_obj->sock_fd ) == -1 ) {
141
142                 // ------------------------------------------------------------------
143                 // Not really worth throwing an exception for... should be logged.
144                 // ------------------------------------------------------------------
145                 warning_handler( "tcp_disconnect(): Error closing socket" );
146                 return -1;
147         } 
148
149         return 0;
150 }
151
152 // ------------------------------------------------------------------
153 // And now for the gory C socket code.
154 // Returns 0 on failure, 1 otherwise
155 // ------------------------------------------------------------------
156 int tcp_wait( transport_socket* sock_obj, int timeout ){
157
158         if( sock_obj == NULL ) {
159                 fatal_handler( "tcp_wait(): null sock_obj" );
160                 return 0;
161         }
162
163         int n = 0; 
164         int retval = 0;
165         char buf[BUFSIZE];
166         int sock_fd = sock_obj->sock_fd;
167
168
169         fd_set read_set;
170
171         FD_ZERO( &read_set );
172         FD_SET( sock_fd, &read_set );
173
174         // ------------------------------------------------------------------
175         // Build the timeval struct
176         // ------------------------------------------------------------------
177         struct timeval tv;
178         tv.tv_sec = timeout;
179         tv.tv_usec = 0;
180
181         if( timeout == -1 ) {  
182
183                 // ------------------------------------------------------------------
184                 // If timeout is -1, there is no timeout passed to the call to select
185                 // ------------------------------------------------------------------
186                 if( (retval = select( sock_fd + 1 , &read_set, NULL, NULL, NULL)) == -1 ) {
187                         warning_handler( "Call to select interrupted" );
188                         return 0;
189                 }
190
191         } else if( timeout != 0 ) { /* timeout of 0 means don't block */
192
193                 if( (retval = select( sock_fd + 1 , &read_set, NULL, NULL, &tv)) == -1 ) {
194                         warning_handler( "Call to select interrupted" );
195                         return 0;
196                 }
197         }
198
199         memset( &buf, 0, BUFSIZE );
200
201         if( set_fl( sock_fd, O_NONBLOCK ) < 0 ) 
202                 return 0;
203
204 #ifdef _ROUTER // just read one buffer full of data
205
206         n = recv(sock_fd, buf, BUFSIZE-1, 0);
207         sock_obj->data_received_callback( sock_obj->user_data, buf );
208         if( n == 0 )
209                 n = -1;
210
211 #else // read everything we can
212
213         debug_handler( "Leaving Socket Select At %f Seconds", get_timestamp_millis() );
214         while( (n = recv(sock_fd, buf, BUFSIZE-1, 0) ) > 0 ) {
215                 debug_handler("SOCKET Read:  \n%s\n", buf);
216                 sock_obj->data_received_callback( sock_obj->user_data, buf );
217                 memset( &buf, 0, BUFSIZE );
218         }
219
220 #endif
221
222         if( clr_fl( sock_fd, O_NONBLOCK ) < 0 ) {
223                 return 0;
224         }
225
226         if( n < 0 ) { 
227                 if( errno != EAGAIN ) { 
228                         warning_handler( " * Error reading socket with errno %d", errno );
229                         return 0;
230                 }
231         }
232
233 #ifdef _ROUTER
234         return n;
235 #else
236         return 1;
237 #endif
238
239 }
240
241 int set_fl( int fd, int flags ) {
242         
243         int val;
244
245         if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) {
246                 fatal_handler("fcntl F_GETFL error");
247                 return -1;
248         }
249
250         val |= flags;
251
252         if( fcntl( fd, F_SETFL, val ) < 0 ) {
253                 fatal_handler( "fcntl F_SETFL error" );
254                 return -1;
255         }
256         return 0;
257 }
258         
259 int clr_fl( int fd, int flags ) {
260         
261         int val;
262
263         if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) {
264                 fatal_handler("fcntl F_GETFL error" );
265                 return -1;
266         }
267
268         val &= ~flags;
269
270         if( fcntl( fd, F_SETFL, val ) < 0 ) {
271                 fatal_handler( "fcntl F_SETFL error" );
272                 return -1;
273         }
274         return 0;
275 }
276         
277
278 /*
279 int tcp_connected( transport_socket* obj ) {
280
281         int ret;
282         if( ! obj->sock_fd ) { return 0; }
283
284         ret = read( obj->sock_fd  , NULL,0 );
285         if( ret <= 0 ) {
286                 return 0;
287         }
288         return 1;
289 }
290 */
291