1f08c3bdfSopenharmony_ci/* -*- linux-c -*- */
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci *
4f08c3bdfSopenharmony_ci *
5f08c3bdfSopenharmony_ci *   Copyright (c) International Business Machines  Corp., 2000
6f08c3bdfSopenharmony_ci *
7f08c3bdfSopenharmony_ci *   This program is free software;  you can redistribute it and/or modify
8f08c3bdfSopenharmony_ci *   it under the terms of the GNU General Public License as published by
9f08c3bdfSopenharmony_ci *   the Free Software Foundation; either version 2 of the License, or
10f08c3bdfSopenharmony_ci *   (at your option) any later version.
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci *   This program is distributed in the hope that it will be useful,
13f08c3bdfSopenharmony_ci *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
14f08c3bdfSopenharmony_ci *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15f08c3bdfSopenharmony_ci *   the GNU General Public License for more details.
16f08c3bdfSopenharmony_ci *
17f08c3bdfSopenharmony_ci *   You should have received a copy of the GNU General Public License
18f08c3bdfSopenharmony_ci *   along with this program;  if not, write to the Free Software
19f08c3bdfSopenharmony_ci *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20f08c3bdfSopenharmony_ci *
21f08c3bdfSopenharmony_ci *
22f08c3bdfSopenharmony_ci */
23f08c3bdfSopenharmony_ci/*
24f08c3bdfSopenharmony_ci * ltpServer.c
25f08c3bdfSopenharmony_ci *
26f08c3bdfSopenharmony_ci * LTP Network Socket Test Server
27f08c3bdfSopenharmony_ci *
28f08c3bdfSopenharmony_ci *
29f08c3bdfSopenharmony_ci */
30f08c3bdfSopenharmony_ci#include <sys/types.h>
31f08c3bdfSopenharmony_ci#include <sys/socket.h>
32f08c3bdfSopenharmony_ci#include <netinet/in.h>
33f08c3bdfSopenharmony_ci#include <arpa/inet.h>
34f08c3bdfSopenharmony_ci#include <netdb.h>
35f08c3bdfSopenharmony_ci#include <stdio.h>
36f08c3bdfSopenharmony_ci#include <stdlib.h>
37f08c3bdfSopenharmony_ci#include <string.h>
38f08c3bdfSopenharmony_ci#include <pthread.h>
39f08c3bdfSopenharmony_ci#include <unistd.h>
40f08c3bdfSopenharmony_ci
41f08c3bdfSopenharmony_ci#define LOCAL_UDP_SERVER_PORT   10000
42f08c3bdfSopenharmony_ci#define LOCAL_TCP_SERVER_PORT   10001
43f08c3bdfSopenharmony_ci#define LOCAL_MULTI_SERVER_PORT 10002
44f08c3bdfSopenharmony_ci#define MAX_MSG_LEN             256
45f08c3bdfSopenharmony_ci#define MAX_HOSTNAME_LEN        256
46f08c3bdfSopenharmony_ci#define ERROR -1
47f08c3bdfSopenharmony_ci#define END_LINE                0x0A
48f08c3bdfSopenharmony_ci
49f08c3bdfSopenharmony_ciint udpSocketHandle,
50f08c3bdfSopenharmony_ci    rc, msg_bytes, tcpSocketHandle, newTcpSocketHandle, multiSocketHandle;
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_cisocklen_t udpClientLen, tcpClientLen, multiClientLen;
53f08c3bdfSopenharmony_ci
54f08c3bdfSopenharmony_cistruct sockaddr_in udpClientAddr,
55f08c3bdfSopenharmony_ci    udpServerAddr,
56f08c3bdfSopenharmony_ci    tcpClientAddr, tcpServerAddr, multiClientAddr, multiServerAddr;
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_cistruct ip_mreq multiCastReq;
59f08c3bdfSopenharmony_cistruct in_addr multiCastAddr;
60f08c3bdfSopenharmony_cistruct hostent *hostEntry;
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_cichar message[MAX_MSG_LEN];
63f08c3bdfSopenharmony_cichar hostname[MAX_HOSTNAME_LEN];
64f08c3bdfSopenharmony_cichar ServerProg[MAX_HOSTNAME_LEN];
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_civoid *ltp_udp_server_queue(void *);
67f08c3bdfSopenharmony_civoid *ltp_tcp_server_queue(void *);
68f08c3bdfSopenharmony_civoid *ltp_multi_server_queue(void *);
69f08c3bdfSopenharmony_ciint tcp_receive_buffer(int, char *);
70f08c3bdfSopenharmony_ci
71f08c3bdfSopenharmony_ciint main(int argc, char *argv[])
72f08c3bdfSopenharmony_ci{
73f08c3bdfSopenharmony_ci
74f08c3bdfSopenharmony_ci	pthread_t udp_server_queue, tcp_server_queue, multi_server_queue;
75f08c3bdfSopenharmony_ci
76f08c3bdfSopenharmony_ci	pthread_attr_t udpthread_attr, tcpthread_attr, multithread_attr;
77f08c3bdfSopenharmony_ci
78f08c3bdfSopenharmony_ci	if (argc != 2) {
79f08c3bdfSopenharmony_ci		printf
80f08c3bdfSopenharmony_ci		    ("Server arguments : %s <multiCast I.P.address/hostname>\n",
81f08c3bdfSopenharmony_ci		     argv[0]);
82f08c3bdfSopenharmony_ci		exit(0);
83f08c3bdfSopenharmony_ci	}
84f08c3bdfSopenharmony_ci
85f08c3bdfSopenharmony_ci	strncpy(hostname, argv[1], 255);
86f08c3bdfSopenharmony_ci	strncpy(ServerProg, argv[0], 255);
87f08c3bdfSopenharmony_ci
88f08c3bdfSopenharmony_ci	/* get mcast address to listen to */
89f08c3bdfSopenharmony_ci
90f08c3bdfSopenharmony_ci	hostEntry = gethostbyname(argv[1]);
91f08c3bdfSopenharmony_ci
92f08c3bdfSopenharmony_ci	if (hostEntry == NULL) {
93f08c3bdfSopenharmony_ci		printf("Server %s : You need to pass a multiCast group '%s'\n",
94f08c3bdfSopenharmony_ci		       argv[0], argv[1]);
95f08c3bdfSopenharmony_ci		exit(1);
96f08c3bdfSopenharmony_ci	}
97f08c3bdfSopenharmony_ci
98f08c3bdfSopenharmony_ci	memcpy(&multiCastAddr, hostEntry->h_addr_list[0], hostEntry->h_length);
99f08c3bdfSopenharmony_ci
100f08c3bdfSopenharmony_ci	/* check given address is multicast */
101f08c3bdfSopenharmony_ci	if (!IN_MULTICAST(ntohl(multiCastAddr.s_addr))) {
102f08c3bdfSopenharmony_ci		printf
103f08c3bdfSopenharmony_ci		    ("%s : Hostname [%s] passed [%s] is not a multicast server\n",
104f08c3bdfSopenharmony_ci		     argv[0], hostname, inet_ntoa(multiCastAddr));
105f08c3bdfSopenharmony_ci		printf("The multiCast Server will not be started \n");
106f08c3bdfSopenharmony_ci	} else {
107f08c3bdfSopenharmony_ci
108f08c3bdfSopenharmony_ci		/* create multiCast socket */
109f08c3bdfSopenharmony_ci		multiSocketHandle = socket(AF_INET, SOCK_DGRAM, 0);
110f08c3bdfSopenharmony_ci
111f08c3bdfSopenharmony_ci		if (multiSocketHandle < 0) {
112f08c3bdfSopenharmony_ci			printf("%s : cannot create multiCast socket\n",
113f08c3bdfSopenharmony_ci			       argv[0]);
114f08c3bdfSopenharmony_ci		} else {
115f08c3bdfSopenharmony_ci			/* bind multiCast port */
116f08c3bdfSopenharmony_ci			multiServerAddr.sin_family = AF_INET;
117f08c3bdfSopenharmony_ci			multiServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
118f08c3bdfSopenharmony_ci			multiServerAddr.sin_port =
119f08c3bdfSopenharmony_ci			    htons(LOCAL_MULTI_SERVER_PORT);
120f08c3bdfSopenharmony_ci
121f08c3bdfSopenharmony_ci			if (bind
122f08c3bdfSopenharmony_ci			    (multiSocketHandle,
123f08c3bdfSopenharmony_ci			     (struct sockaddr *)&multiServerAddr,
124f08c3bdfSopenharmony_ci			     sizeof(multiServerAddr)) < 0) {
125f08c3bdfSopenharmony_ci				printf("%s : cannot bind Multicast port %d \n",
126f08c3bdfSopenharmony_ci				       argv[0], LOCAL_MULTI_SERVER_PORT);
127f08c3bdfSopenharmony_ci			} else {
128f08c3bdfSopenharmony_ci				/* join multicast group */
129f08c3bdfSopenharmony_ci				multiCastReq.imr_multiaddr.s_addr =
130f08c3bdfSopenharmony_ci				    multiCastAddr.s_addr;
131f08c3bdfSopenharmony_ci				multiCastReq.imr_interface.s_addr =
132f08c3bdfSopenharmony_ci				    htonl(INADDR_ANY);
133f08c3bdfSopenharmony_ci
134f08c3bdfSopenharmony_ci				rc = setsockopt(multiSocketHandle, IPPROTO_IP,
135f08c3bdfSopenharmony_ci						IP_ADD_MEMBERSHIP,
136f08c3bdfSopenharmony_ci						(void *)&multiCastReq,
137f08c3bdfSopenharmony_ci						sizeof(multiCastReq));
138f08c3bdfSopenharmony_ci				if (rc < 0) {
139f08c3bdfSopenharmony_ci					printf
140f08c3bdfSopenharmony_ci					    ("%s : cannot join multicast group '%s'",
141f08c3bdfSopenharmony_ci					     argv[0], inet_ntoa(multiCastAddr));
142f08c3bdfSopenharmony_ci				} else {
143f08c3bdfSopenharmony_ci					printf
144f08c3bdfSopenharmony_ci					    ("%s : listening to mgroup %s:%d\n",
145f08c3bdfSopenharmony_ci					     argv[0], inet_ntoa(multiCastAddr),
146f08c3bdfSopenharmony_ci					     LOCAL_MULTI_SERVER_PORT);
147f08c3bdfSopenharmony_ci				}
148f08c3bdfSopenharmony_ci			}
149f08c3bdfSopenharmony_ci		}
150f08c3bdfSopenharmony_ci
151f08c3bdfSopenharmony_ci		rc = pthread_attr_init(&multithread_attr);
152f08c3bdfSopenharmony_ci		rc = pthread_create(&multi_server_queue, &multithread_attr,
153f08c3bdfSopenharmony_ci				    ltp_multi_server_queue, NULL);
154f08c3bdfSopenharmony_ci	}
155f08c3bdfSopenharmony_ci
156f08c3bdfSopenharmony_ci	/* udp socket creation */
157f08c3bdfSopenharmony_ci	udpSocketHandle = socket(AF_INET, SOCK_DGRAM, 0);
158f08c3bdfSopenharmony_ci
159f08c3bdfSopenharmony_ci	if (udpSocketHandle < 0) {
160f08c3bdfSopenharmony_ci		printf("%s: cannot open socket \n", argv[0]);
161f08c3bdfSopenharmony_ci		exit(1);
162f08c3bdfSopenharmony_ci	}
163f08c3bdfSopenharmony_ci
164f08c3bdfSopenharmony_ci	/* tcp socket creation */
165f08c3bdfSopenharmony_ci	tcpSocketHandle = socket(AF_INET, SOCK_STREAM, 0);
166f08c3bdfSopenharmony_ci
167f08c3bdfSopenharmony_ci	if (tcpSocketHandle < 0) {
168f08c3bdfSopenharmony_ci		printf("Error: cannot open socket %d \n", tcpSocketHandle);
169f08c3bdfSopenharmony_ci		return ERROR;
170f08c3bdfSopenharmony_ci	}
171f08c3bdfSopenharmony_ci
172f08c3bdfSopenharmony_ci	/* bind local udp server port */
173f08c3bdfSopenharmony_ci	udpServerAddr.sin_family = AF_INET;
174f08c3bdfSopenharmony_ci	udpServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
175f08c3bdfSopenharmony_ci	udpServerAddr.sin_port = htons(LOCAL_UDP_SERVER_PORT);
176f08c3bdfSopenharmony_ci
177f08c3bdfSopenharmony_ci	rc = bind(udpSocketHandle, (struct sockaddr *)&udpServerAddr,
178f08c3bdfSopenharmony_ci		  sizeof(udpServerAddr));
179f08c3bdfSopenharmony_ci
180f08c3bdfSopenharmony_ci	if (rc < 0) {
181f08c3bdfSopenharmony_ci		printf("%s: Error binding port number %d \n",
182f08c3bdfSopenharmony_ci		       argv[0], LOCAL_UDP_SERVER_PORT);
183f08c3bdfSopenharmony_ci		exit(1);
184f08c3bdfSopenharmony_ci	} else {
185f08c3bdfSopenharmony_ci		printf("%s: bound port number %d \n",
186f08c3bdfSopenharmony_ci		       argv[0], LOCAL_UDP_SERVER_PORT);
187f08c3bdfSopenharmony_ci	}
188f08c3bdfSopenharmony_ci
189f08c3bdfSopenharmony_ci	/* bind local tcp server port */
190f08c3bdfSopenharmony_ci	tcpServerAddr.sin_family = AF_INET;
191f08c3bdfSopenharmony_ci	tcpServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
192f08c3bdfSopenharmony_ci	tcpServerAddr.sin_port = htons(LOCAL_TCP_SERVER_PORT);
193f08c3bdfSopenharmony_ci
194f08c3bdfSopenharmony_ci	rc = bind(tcpSocketHandle, (struct sockaddr *)&tcpServerAddr,
195f08c3bdfSopenharmony_ci		  sizeof(tcpServerAddr));
196f08c3bdfSopenharmony_ci
197f08c3bdfSopenharmony_ci	if (rc < 0) {
198f08c3bdfSopenharmony_ci		printf("%s: Error binding port number %d \n",
199f08c3bdfSopenharmony_ci		       argv[0], LOCAL_TCP_SERVER_PORT);
200f08c3bdfSopenharmony_ci		exit(1);
201f08c3bdfSopenharmony_ci	} else {
202f08c3bdfSopenharmony_ci		printf("%s: bound port number %d \n",
203f08c3bdfSopenharmony_ci		       argv[0], LOCAL_TCP_SERVER_PORT);
204f08c3bdfSopenharmony_ci	}
205f08c3bdfSopenharmony_ci
206f08c3bdfSopenharmony_ci	rc = pthread_attr_init(&udpthread_attr);
207f08c3bdfSopenharmony_ci	rc = pthread_create(&udp_server_queue, &udpthread_attr,
208f08c3bdfSopenharmony_ci			    ltp_udp_server_queue, NULL);
209f08c3bdfSopenharmony_ci
210f08c3bdfSopenharmony_ci	rc = pthread_attr_init(&tcpthread_attr);
211f08c3bdfSopenharmony_ci	rc = pthread_create(&tcp_server_queue, &tcpthread_attr,
212f08c3bdfSopenharmony_ci			    ltp_tcp_server_queue, NULL);
213f08c3bdfSopenharmony_ci
214f08c3bdfSopenharmony_ci	while (1) ;
215f08c3bdfSopenharmony_ci
216f08c3bdfSopenharmony_ci	return 0;
217f08c3bdfSopenharmony_ci}
218f08c3bdfSopenharmony_ci
219f08c3bdfSopenharmony_ci/*
220f08c3bdfSopenharmony_ci * Function:     ltp_udp_server_queue
221f08c3bdfSopenharmony_ci * Description:  This function grabs the udp message from the queue and outputs to stdio
222f08c3bdfSopenharmony_ci */
223f08c3bdfSopenharmony_civoid *ltp_udp_server_queue(void *junk)
224f08c3bdfSopenharmony_ci{
225f08c3bdfSopenharmony_ci
226f08c3bdfSopenharmony_ci	printf("%s: waiting for data on port UDP %u\n",
227f08c3bdfSopenharmony_ci	       hostname, LOCAL_UDP_SERVER_PORT);
228f08c3bdfSopenharmony_ci
229f08c3bdfSopenharmony_ci	/* server infinite loop */
230f08c3bdfSopenharmony_ci	while (1) {
231f08c3bdfSopenharmony_ci
232f08c3bdfSopenharmony_ci		/* init buffer */
233f08c3bdfSopenharmony_ci		memset(message, 0, MAX_MSG_LEN);
234f08c3bdfSopenharmony_ci
235f08c3bdfSopenharmony_ci		/* receive message */
236f08c3bdfSopenharmony_ci		udpClientLen = sizeof(udpClientAddr);
237f08c3bdfSopenharmony_ci
238f08c3bdfSopenharmony_ci		msg_bytes =
239f08c3bdfSopenharmony_ci		    recvfrom(udpSocketHandle, message, MAX_MSG_LEN, 0,
240f08c3bdfSopenharmony_ci			     (struct sockaddr *)&udpClientAddr, &udpClientLen);
241f08c3bdfSopenharmony_ci
242f08c3bdfSopenharmony_ci		printf("msg_bytes:%d \n", msg_bytes);
243f08c3bdfSopenharmony_ci
244f08c3bdfSopenharmony_ci		if (msg_bytes < 0) {
245f08c3bdfSopenharmony_ci			printf("%s: Error receiving data \n", hostname);
246f08c3bdfSopenharmony_ci		} else {
247f08c3bdfSopenharmony_ci			/* print message */
248f08c3bdfSopenharmony_ci			printf("%s: from %s:UDP%u : %s \n",
249f08c3bdfSopenharmony_ci			       hostname, inet_ntoa(udpClientAddr.sin_addr),
250f08c3bdfSopenharmony_ci			       ntohs(udpClientAddr.sin_port), message);
251f08c3bdfSopenharmony_ci		}
252f08c3bdfSopenharmony_ci
253f08c3bdfSopenharmony_ci	}			/* end of server infinite loop */
254f08c3bdfSopenharmony_ci
255f08c3bdfSopenharmony_ci	return NULL;
256f08c3bdfSopenharmony_ci
257f08c3bdfSopenharmony_ci}
258f08c3bdfSopenharmony_ci
259f08c3bdfSopenharmony_ci/*
260f08c3bdfSopenharmony_ci * Function:     ltp_tcp_server_queue
261f08c3bdfSopenharmony_ci * Description:  This function grabs the tcp message from the queue and outputs to stdio
262f08c3bdfSopenharmony_ci */
263f08c3bdfSopenharmony_civoid *ltp_tcp_server_queue(void *junk)
264f08c3bdfSopenharmony_ci{
265f08c3bdfSopenharmony_ci
266f08c3bdfSopenharmony_ci	listen(tcpSocketHandle, 5);
267f08c3bdfSopenharmony_ci
268f08c3bdfSopenharmony_ci	while (1) {
269f08c3bdfSopenharmony_ci
270f08c3bdfSopenharmony_ci		printf("%s: waiting for data on port TCP %u\n", hostname,
271f08c3bdfSopenharmony_ci		       LOCAL_TCP_SERVER_PORT);
272f08c3bdfSopenharmony_ci
273f08c3bdfSopenharmony_ci		tcpClientLen = sizeof(tcpClientAddr);
274f08c3bdfSopenharmony_ci		newTcpSocketHandle =
275f08c3bdfSopenharmony_ci		    accept(tcpSocketHandle, (struct sockaddr *)&tcpClientAddr,
276f08c3bdfSopenharmony_ci			   &tcpClientLen);
277f08c3bdfSopenharmony_ci
278f08c3bdfSopenharmony_ci		if (newTcpSocketHandle < 0) {
279f08c3bdfSopenharmony_ci			printf("cannot accept TCP connection ");
280f08c3bdfSopenharmony_ci			break;
281f08c3bdfSopenharmony_ci		}
282f08c3bdfSopenharmony_ci
283f08c3bdfSopenharmony_ci		/* init line */
284f08c3bdfSopenharmony_ci		memset(message, 0x0, MAX_MSG_LEN);
285f08c3bdfSopenharmony_ci
286f08c3bdfSopenharmony_ci		/* receive segments */
287f08c3bdfSopenharmony_ci		while (tcp_receive_buffer(newTcpSocketHandle, message) != ERROR) {
288f08c3bdfSopenharmony_ci
289f08c3bdfSopenharmony_ci			printf("%s: received from %s:TCP%d : %s\n", hostname,
290f08c3bdfSopenharmony_ci			       inet_ntoa(tcpClientAddr.sin_addr),
291f08c3bdfSopenharmony_ci			       ntohs(tcpClientAddr.sin_port), message);
292f08c3bdfSopenharmony_ci
293f08c3bdfSopenharmony_ci			/* init line */
294f08c3bdfSopenharmony_ci			memset(message, 0x0, MAX_MSG_LEN);
295f08c3bdfSopenharmony_ci
296f08c3bdfSopenharmony_ci		}		/* while (read_line) */
297f08c3bdfSopenharmony_ci		printf("looping in TCP \n");
298f08c3bdfSopenharmony_ci
299f08c3bdfSopenharmony_ci	}			/* while (1) */
300f08c3bdfSopenharmony_ci
301f08c3bdfSopenharmony_ci	return NULL;
302f08c3bdfSopenharmony_ci
303f08c3bdfSopenharmony_ci}
304f08c3bdfSopenharmony_ci
305f08c3bdfSopenharmony_ci/*
306f08c3bdfSopenharmony_ci * Function:     tcp_receive_buffer
307f08c3bdfSopenharmony_ci * Description:  This function grabs the message from the tcp queue and
308f08c3bdfSopenharmony_ci *               returns it to the calling function in the buffer.
309f08c3bdfSopenharmony_ci */
310f08c3bdfSopenharmony_ciint tcp_receive_buffer(int newSocket, char *return_buffer)
311f08c3bdfSopenharmony_ci{
312f08c3bdfSopenharmony_ci
313f08c3bdfSopenharmony_ci	static int bytes_received = 0;
314f08c3bdfSopenharmony_ci	static char message_received[MAX_MSG_LEN];
315f08c3bdfSopenharmony_ci	static int count = 0;
316f08c3bdfSopenharmony_ci	int offset;
317f08c3bdfSopenharmony_ci
318f08c3bdfSopenharmony_ci	offset = 0;
319f08c3bdfSopenharmony_ci
320f08c3bdfSopenharmony_ci	while (1) {
321f08c3bdfSopenharmony_ci
322f08c3bdfSopenharmony_ci		if (bytes_received == 0) {
323f08c3bdfSopenharmony_ci			/* read data from socket */
324f08c3bdfSopenharmony_ci
325f08c3bdfSopenharmony_ci			memset(message_received, 0x0, MAX_MSG_LEN);	/* init buffer */
326f08c3bdfSopenharmony_ci
327f08c3bdfSopenharmony_ci			count =
328f08c3bdfSopenharmony_ci			    recvfrom(newSocket, message_received, MAX_MSG_LEN,
329f08c3bdfSopenharmony_ci				     0, (struct sockaddr *)&tcpClientAddr,
330f08c3bdfSopenharmony_ci				     &tcpClientLen);
331f08c3bdfSopenharmony_ci
332f08c3bdfSopenharmony_ci			if (count < 0) {
333f08c3bdfSopenharmony_ci				perror(" cannot receive data ");
334f08c3bdfSopenharmony_ci				return ERROR;
335f08c3bdfSopenharmony_ci			} else if (count == 0) {
336f08c3bdfSopenharmony_ci				printf(" connection closed by client\n");
337f08c3bdfSopenharmony_ci				close(newSocket);
338f08c3bdfSopenharmony_ci				if (count) {
339f08c3bdfSopenharmony_ci				}
340f08c3bdfSopenharmony_ci				return ERROR;
341f08c3bdfSopenharmony_ci			}
342f08c3bdfSopenharmony_ci		}
343f08c3bdfSopenharmony_ci
344f08c3bdfSopenharmony_ci		/* Check for new data read on socket or */
345f08c3bdfSopenharmony_ci		/* if still more data in buffer       */
346f08c3bdfSopenharmony_ci
347f08c3bdfSopenharmony_ci		/* copy line into 'return_buffer' */
348f08c3bdfSopenharmony_ci		while (*(message_received + bytes_received) != END_LINE
349f08c3bdfSopenharmony_ci		       && bytes_received < count) {
350f08c3bdfSopenharmony_ci			memcpy(return_buffer + offset,
351f08c3bdfSopenharmony_ci			       message_received + bytes_received, 1);
352f08c3bdfSopenharmony_ci			offset++;
353f08c3bdfSopenharmony_ci			bytes_received++;
354f08c3bdfSopenharmony_ci		}
355f08c3bdfSopenharmony_ci
356f08c3bdfSopenharmony_ci		/* end of line + end of buffer => return line */
357f08c3bdfSopenharmony_ci		if (bytes_received == count - 1) {
358f08c3bdfSopenharmony_ci			/* set last byte to END_LINE */
359f08c3bdfSopenharmony_ci			*(return_buffer + offset) = END_LINE;
360f08c3bdfSopenharmony_ci			bytes_received = 0;
361f08c3bdfSopenharmony_ci			return ++offset;
362f08c3bdfSopenharmony_ci		}
363f08c3bdfSopenharmony_ci
364f08c3bdfSopenharmony_ci		/* end of line but still some data in buffer => return line */
365f08c3bdfSopenharmony_ci		if (bytes_received < count - 1) {
366f08c3bdfSopenharmony_ci			/* set last byte to END_LINE */
367f08c3bdfSopenharmony_ci			*(return_buffer + offset) = END_LINE;
368f08c3bdfSopenharmony_ci			bytes_received++;
369f08c3bdfSopenharmony_ci			return ++offset;
370f08c3bdfSopenharmony_ci		}
371f08c3bdfSopenharmony_ci
372f08c3bdfSopenharmony_ci		/* end of buffer but line is not ended => */
373f08c3bdfSopenharmony_ci		/*  wait for more data to arrive on socket */
374f08c3bdfSopenharmony_ci		if (bytes_received == count) {
375f08c3bdfSopenharmony_ci			bytes_received = 0;
376f08c3bdfSopenharmony_ci			return offset;
377f08c3bdfSopenharmony_ci		}
378f08c3bdfSopenharmony_ci
379f08c3bdfSopenharmony_ci	}			/* while */
380f08c3bdfSopenharmony_ci
381f08c3bdfSopenharmony_ci}
382f08c3bdfSopenharmony_ci
383f08c3bdfSopenharmony_ci/*
384f08c3bdfSopenharmony_ci * Function:     ltp_multi_server_queue
385f08c3bdfSopenharmony_ci * Description:  This function grabs the multiCast message from the queue and outputs to stdio
386f08c3bdfSopenharmony_ci */
387f08c3bdfSopenharmony_civoid *ltp_multi_server_queue(void *junk)
388f08c3bdfSopenharmony_ci{
389f08c3bdfSopenharmony_ci
390f08c3bdfSopenharmony_ci	printf("%s: waiting for data on port Multicast %u\n",
391f08c3bdfSopenharmony_ci	       hostname, LOCAL_MULTI_SERVER_PORT);
392f08c3bdfSopenharmony_ci
393f08c3bdfSopenharmony_ci	/* infinite server loop */
394f08c3bdfSopenharmony_ci	while (1) {
395f08c3bdfSopenharmony_ci
396f08c3bdfSopenharmony_ci		multiClientLen = sizeof(multiClientAddr);
397f08c3bdfSopenharmony_ci
398f08c3bdfSopenharmony_ci		msg_bytes =
399f08c3bdfSopenharmony_ci		    recvfrom(multiSocketHandle, message, MAX_MSG_LEN, 0,
400f08c3bdfSopenharmony_ci			     (struct sockaddr *)&multiClientAddr,
401f08c3bdfSopenharmony_ci			     &multiClientLen);
402f08c3bdfSopenharmony_ci
403f08c3bdfSopenharmony_ci		if (msg_bytes < 0) {
404f08c3bdfSopenharmony_ci			printf("%s : cannot receive data\n", hostname);
405f08c3bdfSopenharmony_ci			continue;
406f08c3bdfSopenharmony_ci		}
407f08c3bdfSopenharmony_ci
408f08c3bdfSopenharmony_ci		printf("%s : from %s:%d on %s : %s\n", ServerProg,
409f08c3bdfSopenharmony_ci		       inet_ntoa(multiClientAddr.sin_addr),
410f08c3bdfSopenharmony_ci		       ntohs(multiClientAddr.sin_port), hostname, message);
411f08c3bdfSopenharmony_ci
412f08c3bdfSopenharmony_ci	}			/* end of infinite server loop */
413f08c3bdfSopenharmony_ci
414f08c3bdfSopenharmony_ci	return NULL;
415f08c3bdfSopenharmony_ci
416f08c3bdfSopenharmony_ci}
417