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