1 /*
2 * Copyright (C) 2002-2009, Edmundo Albuquerque de Souza e Silva.
3 *
4 * This file may be distributed under the terms of the Q Public License
5 * as defined by Trolltech AS of Norway and appearing in the file
6 * LICENSE.QPL included in the packaging of this file.
7 *
8 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
9 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
10 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
11 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
12 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
13 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
14 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 *
16 */
17
18 /***************************************************************************
19 rmtcp.c
20 -------------------
21 begin : 2002
22 Authors : Jorge Allyson Azevedo
23 Milena Scanferla
24 Daniel Sadoc
25 email : {allyson,milena,sadoc}@land.ufrj.br
26 ***************************************************************************/
27
28 #include "rmtcp.h"
29 #include "rminternals.h"
30
31 #include <ctype.h>
32 #include <signal.h>
33
34 #ifndef TRUE
35 #define TRUE 1
36 #define FALSE 0
37 #endif
38
39 extern USER_INFO local_user_info;
40 extern sigset_t alrmset;
41 extern FILE *logfile;
42
43 /*
44 extern char rmcast_tcp_ip[IP_STRING_SIZE];
45 extern int *rmcast_pipe;
46 extern int rmcast_tcp_port;
47 */
48
49 extern GLOBAL_OPTIONS rmcast_options;
50
51 extern CACHE *cache;
52
53 extern int errno;
54
55 #ifdef SOLARIS
56 #include <sys/types.h>
57 #include <sys/socket.h>
58 #include <netinet/in.h>
59 #include <arpa/inet.h>
60 #endif
61
62 #include <pthread.h>
63
64 #define min(a,b) ((a<b)?a:b)
65
66 #ifdef SOLARIS
67 int
inet_pton(int family,const char * strptr,void * addrptr)68 inet_pton(int family, const char *strptr, void *addrptr)
69 {
70 if (family == AF_INET)
71 {
72 unsigned long int in_val;
73
74 if ( ( (long int) (in_val = inet_addr(strptr)) ) != -1 ) {
75 memcpy(addrptr, &in_val, sizeof(struct in_addr));
76 return (1);
77 }
78 return (0);
79 }
80 errno = EAFNOSUPPORT;
81 return (-1);
82 }
83 #endif
84
rmcastReceiveTCPStatus(char * ip,int port,CurStatus * cur_status)85 int rmcastReceiveTCPStatus(char *ip, int port, CurStatus *cur_status)
86 {
87 int sockfd;
88 int retval = 1;
89 struct sockaddr_in servaddr;
90 char buffer[MAXLINE];
91 CurStatus cs_cache;
92
93
94 if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
95 perror( "socket error ");
96
97 bzero(&servaddr, sizeof(servaddr));
98 servaddr.sin_family = AF_INET;
99
100 #ifdef DEBUG_TCP
101 fprintf(stderr,"Trying to connect port %d\n",port);
102 #endif
103
104 servaddr.sin_port = htons(port);
105
106 if (inet_pton(AF_INET, ip, &servaddr.sin_addr) <= 0)
107 {
108 sprintf( buffer, "inet_pton error for %s", ip);
109 perror ( buffer );
110 }
111 #ifndef SOLARIS
112 if ((retval=connect(sockfd, (const struct sockaddr *) &servaddr, sizeof(servaddr))) < 0)
113 #else
114 if ((retval=connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0)
115 #endif
116 {
117 perror("connect error on rmcastSendTCPStatus");
118 return FALSE;
119 }
120 else
121 {
122 #ifdef DEBUG_TCP
123 fprintf( stderr, "connect ok!!\n");
124 #endif
125 }
126
127
128 read(sockfd, &(cur_status->size), sizeof(int));
129
130 cur_status->data = (char*)malloc((cur_status->size)+1);
131
132 retval = read(sockfd, cur_status->data, cur_status->size);
133
134 #ifdef DEBUG_TCP
135 {
136 int auxi;
137 for(auxi=0; auxi<retval; auxi++)
138 {
139 fprintf(stderr,"[(%d) %c]", cur_status->data[(int)auxi], isalnum((int)cur_status->data[(int)auxi])?cur_status->data[(int)auxi]:'-');
140 }
141 }
142
143 fprintf(stderr,"\n");
144 #endif
145
146 /* Now, we will read the cache */
147
148
149 read(sockfd, &(cs_cache.size), sizeof(int));
150
151 cs_cache.data = (char*)malloc((cs_cache.size)+1);
152
153 retval = read(sockfd, cs_cache.data, cs_cache.size);
154
155 cacheUnpack(&cache, cs_cache.data, cs_cache.size);
156
157 cacheShow(cache);
158
159 close(sockfd);
160
161 return TRUE;
162 }
163
164 #ifndef SOLARIS
165
166 #include <sys/types.h>
167 #include <sys/socket.h>
168
169 typedef socklen_t SOCKLEN_DECL_TYPE;
170 #else
171 typedef int SOCKLEN_DECL_TYPE;
172 #endif
173
rmcastSendTCPStatus(void * arg)174 void * rmcastSendTCPStatus(void *arg)
175 {
176 int retval;
177 int listenfd, connfd;
178 SOCKLEN_DECL_TYPE len;
179 struct sockaddr_in servaddr, cliaddr;
180
181 #ifdef DEBUG_TCP
182 char buff[10000];
183 #endif
184
185 int cont = 0;
186
187 /*
188 * #ifdef SOLARIS
189 *
190 * sigset_t alrmset;
191 *
192 * sigfillset(&alrmset);
193 *
194 *
195 *
196 * pthread_sigmask(SIG_BLOCK, &alrmset, NULL);
197 *
198 * #endif
199 */
200
201 #ifdef DEBUG_TCP
202 fprintf(stderr,"Initializing the 'current status server'\n");
203 #endif
204
205 if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
206 {
207 perror("socket error");
208 return FALSE;
209 }
210
211 bzero(&servaddr, sizeof(servaddr));
212 servaddr.sin_family = AF_INET;
213 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
214 servaddr.sin_port = htons(10013); /* 271d hexa */
215
216 retval = -1;
217
218 while (retval==-1)
219 {
220 #ifndef SOLARIS
221 if ((retval = bind(listenfd, (const struct sockaddr *) &servaddr, sizeof(servaddr)))==-1)
222 #else
223 if ((retval = bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)))==-1)
224 #endif
225 {
226 #ifdef DEBUG_TCP
227 fprintf(stderr,"bind error: %s (%d)\n",strerror(errno),retval);
228 #endif
229 cont ++;
230
231 servaddr.sin_port = htons(10013 + cont); /* trying next port */
232 }
233 }
234
235 rmcast_options.tcp_port = 10013 + cont;
236
237 #ifdef DEBUG_TCP
238 fprintf(stderr,"Using tcp port %d\nWaiting listen... \n", rmcast_options.tcp_port);
239 #endif
240
241 if ((retval = listen(listenfd, LISTENQ)))
242 {
243 fprintf(stderr,"listen error: %s\n",strerror(errno));
244
245 close (listenfd);
246
247 return FALSE;
248 }
249
250 len = sizeof(cliaddr);
251
252 while (1)
253 {
254 char tmp_buf[80];
255
256 #ifdef DEBUG_TCP
257 fprintf(stderr,"Waiting for tcp connection... \n");
258 #endif
259
260
261 connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &len);
262
263 #ifdef DEBUG_TCP
264 #ifndef SOLARIS
265 fprintf(stderr,"Connection from %s, port %d\n",
266 inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
267 ntohs(cliaddr.sin_port));
268 #endif
269 #endif
270
271 /* write connfd to pipe */
272
273 sprintf(tmp_buf, "c%1d", connfd);
274 write(rmcast_options.pipe[1], (const void *)tmp_buf, (size_t)(strlen(tmp_buf)+1));
275
276 }
277
278 close (listenfd);
279
280 return NULL;
281 }
282
283
284
285