1 /* Loglan82 Compiler&Interpreter
\r
2 Copyright (C) 1981-1993 Institute of Informatics, University of Warsaw
\r
3 Copyright (C) 1993, 1994 LITA, Pau
\r
5 This program is free software; you can redistribute it and/or modify
\r
6 it under the terms of the GNU General Public License as published by
\r
7 the Free Software Foundation; either version 2 of the License, or
\r
8 (at your option) any later version.
\r
10 This program is distributed in the hope that it will be useful,
\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 GNU General Public License for more details.
\r
15 You should have received a copy of the GNU General Public License
\r
16 along with this program; if not, write to the Free Software
\r
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
\r
19 contacts: Andrzej.Salwicki@univ-pau.fr
\r
22 LITA Departement d'Informatique
\r
24 Avenue de l'Universite
\r
26 tel. ++33 59923154 fax. ++33 59841696
\r
28 =======================================================================
\r
34 #include "process.h"
\r
44 static int slaves=0;
\r
45 static struct addr {
\r
47 struct sockaddr_in addr;
\r
51 #define MAX_NODES 256
\r
52 static int node2book[ MAX_NODES ]; /* only 256 nodes - can be changed */
\r
55 static void sock_recv_from( void *, int, struct sockaddr_in * );
\r
56 static void sock_recv_from( buf, buflen, from_addr )
\r
59 struct sockaddr_in *from_addr;
\r
61 struct sockaddr_in addr;
\r
64 if( ( retval = sock_recv( sock, buf, buflen, &addr ) ) < 0 )
\r
65 perror("receive"),abend("no answer from master");
\r
67 from_addr->sin_port != addr.sin_port
\r
69 from_addr->sin_addr.s_addr != addr.sin_addr.s_addr
\r
73 fprintf( stderr, "unexpected message from %s:%d length %d\n",
\r
74 inet_ntoa( from_addr->sin_addr ),
\r
75 (int)ntohs( from_addr->sin_port ),
\r
83 /* nn.nn.nn.nn:port address */
\r
84 void tcpip_connect_to_master( addr ) char *addr; {
\r
89 struct sockaddr_in m_address;
\r
91 for( aux = 0; aux < MAX_NODES; aux++ )
\r
92 node2book[ aux ] = -1;
\r
94 if( host_addr( host, &m_address ) < 0 ){
\r
95 perror("invalid host name:");
\r
99 sock = sock_open( SOCK_DGRAM, "udp", NULL, 0 ); /* any port */
\r
100 if( sock < 0 ) perror("can't open any socket"),exit(10);
\r
103 struct sockaddr_in addr;
\r
104 int namelen = sizeof(struct sockaddr_in);
\r
105 getsockname( sock, &addr, &namelen );
\r
106 fprintf( stderr, "socket opened on %s:%d\n",
\r
107 inet_ntoa(addr.sin_addr),
\r
108 (int)ntohs(addr.sin_port)
\r
112 aux = htonl( console );
\r
113 sock_send( sock, &aux, sizeof(aux), &m_address );
\r
115 stderr, "waiting for acknowledge from %s:%d\n",
\r
116 host, (int)ntohs( m_address.sin_port )
\r
119 sock_recv_from( &aux, sizeof(aux), &m_address );
\r
120 slaves = ntohl( aux );
\r
121 fprintf( stderr, "answer from master: %d interpreters\n", slaves );
\r
123 phone_book = (struct addr *)calloc( slaves, sizeof( struct addr ) );
\r
124 if( phone_book==NULL ) abend("can't allocate table of addresses");
\r
126 sock_recv_from( &aux, sizeof(aux), &m_address );
\r
127 phone_book[0].console = ntohl( aux );
\r
128 phone_book[0].addr = m_address;
\r
130 fprintf( stderr, "master console %d at %s:%d\n",
\r
131 phone_book[0].console,
\r
132 inet_ntoa(phone_book[0].addr.sin_addr),
\r
133 (int)ntohs(phone_book[0].addr.sin_port)
\r
136 node2book[ phone_book[ 0 ].console ] = 0;
\r
140 for( i=1; i<slaves; i++ ){ /* on 0 will be master */
\r
142 sock_recv_from( &aux, sizeof(aux), &m_address );
\r
143 phone_book[i].console = ntohl( aux );
\r
145 &(phone_book[i].addr),
\r
146 sizeof(struct sockaddr_in),
\r
149 fprintf( stderr, "interpreter %d connected at %s:%d\n",
\r
150 phone_book[i].console,
\r
151 inet_ntoa(phone_book[i].addr.sin_addr),
\r
152 (int)ntohs(phone_book[i].addr.sin_port)
\r
154 node2book[ phone_book[ i ].console ] = i;
\r
158 fprintf( stderr, "\nprogram started\n\n" );
\r
164 void tcpip_wait_for_slaves( _slaves ) int _slaves; {
\r
168 struct sockaddr_in slave_address;
\r
169 int namelen = sizeof(struct sockaddr_in);
\r
171 for( aux = 0; aux < MAX_NODES; aux++ )
\r
172 node2book[ aux ] = -1;
\r
174 slaves = _slaves+1;
\r
176 phone_book = (struct addr *)calloc( slaves, sizeof( struct addr ) );
\r
177 if( phone_book==NULL ) abend("can't allocate table of addresses");
\r
179 sock = sock_open( SOCK_DGRAM, "udp", NULL, PORT );
\r
180 if( sock < 0 ) perror("master socket"),abend("can't install master");
\r
182 phone_book[0].console = console;
\r
183 getsockname( sock, &(phone_book[0].addr), &namelen );
\r
184 assert( namelen == sizeof( struct sockaddr_in ) );
\r
186 fprintf( stderr, "waiting for %d slaves on console %d at %s:%d\n",
\r
188 phone_book[0].console,
\r
189 inet_ntoa(phone_book[0].addr.sin_addr),
\r
190 (int)ntohs(phone_book[0].addr.sin_port)
\r
193 node2book[ console ] = 0;
\r
195 while( _slaves > 0 ){
\r
197 if( sock_recv( sock , &slave_console, sizeof(slave_console), &slave_address ) < 0 )
\r
198 perror("server receive"),abend("can't connect slave");
\r
200 fprintf( stderr, "slave %d connected at %s:%d\n",
\r
201 ntohl(slave_console),
\r
202 inet_ntoa(slave_address.sin_addr),
\r
203 (int)ntohs(slave_address.sin_port)
\r
206 slave_console = ntohl( slave_console );
\r
208 phone_book[_slaves].console = slave_console;
\r
209 phone_book[_slaves].addr = slave_address;
\r
211 if( node2book[ slave_console ] != -1 ){
\r
212 fprintf( stderr, "node %d already bound\n", slave_console );
\r
215 node2book[ slave_console ] = _slaves;
\r
221 fprintf( stderr, "all slaves notified - sending acknowledges\n" );
\r
225 for( i=1; i<slaves; i++ ){
\r
227 aux = htonl(slaves);
\r
228 sock_send( sock, &aux, sizeof(aux), &(phone_book[i].addr) );
\r
230 aux = htonl(console);
\r
231 sock_send( sock, &aux, sizeof(aux), &(phone_book[i].addr) );
\r
233 for( j=1; j<slaves; j++ ){
\r
234 aux = htonl(phone_book[j].console);
\r
235 sock_send( sock, &aux, sizeof(aux), &(phone_book[i].addr) );
\r
238 &(phone_book[j].addr),
\r
239 sizeof(struct sockaddr_in),
\r
240 &(phone_book[i].addr)
\r
246 fprintf( stderr, "\nprogram started\n\n" );
\r
250 void tcpip_send( msg ) message *msg; {
\r
251 int node = msg->control.receiver.node;
\r
252 int ix = node2book[ node ];
\r
254 fprintf( stderr, "tcpip send message to not existing node %d\n", node );
\r
258 fprintf( stderr, "tcpip send message to node %d indx %d\n", node, ix );
\r
264 &( phone_book[ ix ].addr )
\r
268 bool tcpip_poll( ms ) int ms; {
\r
269 return sock_poll( sock, ms );
\r
272 bool tcpip_recv( msg ) message *msg; {
\r
274 struct sockaddr_in addr;
\r
275 if( ( retval = sock_recv( sock, msg, sizeof( message ), &addr ) ) < 0 ){
\r
280 if( retval == sizeof( message ) )
\r
281 fprintf(stderr,"tcpip recv message from node %d\n",msg->control.sender.node);
\r
283 fprintf(stderr,"tcpip recv incorrect message from node %d\n",msg->control.sender.node);
\r
285 return ( retval == sizeof( message ) );
\r